-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.graphql
681 lines (585 loc) · 17.5 KB
/
schema.graphql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
# This file was generated. Do not edit manually.
schema {
query: Query
mutation: Mutation
}
"Indicates an Input Object is a OneOf Input Object."
directive @oneOf on INPUT_OBJECT
interface AccessControlled {
"The object's ACL, which includes its owner and any grants of access."
acl: Acl!
grants: [AccessControlEntry!]!
owner: User!
}
interface CorePlanItem {
childCount: NonNegativeInt!
children: [PlanItem!]!
descendantCount: NonNegativeInt!
descendants: [PlanItem!]!
id: ID!
name: String!
plan: Plan!
}
interface Ingredient {
id: ID!
labels: [String!]
name: String!
}
interface Node {
id: ID!
}
interface Owned {
"The user who owns this object."
owner: User!
}
type AccessControlEntry {
"The level of access the user has been granted."
level: AccessLevel!
"The user who has been granted access to an AccessControlled object."
user: User!
}
type Acl implements Owned {
"""
Users granted access, by the owner. This is conceptually map, so a given
user (the key) uniquely identifies their access level (the value).
"""
grants: [AccessControlEntry!]!
owner: User!
}
type Deletion {
id: ID!
name: String
}
type Favorite implements Node {
id: ID!
"The name/title of the object that is a favorite."
name: String!
"The ID of the object that is a favorite."
objectId: ID!
"The type of object that is a favorite."
objectType: String!
owner: User!
}
type FavoriteMutation {
"""
Add the specified object to the current user's favorites, if not already
present, and return the favorite.
"""
markFavorite(objectId: ID!, objectType: String!): Favorite!
"""
Remove the specified object from the current user's favorites, and return
whether any action was taken to ensure this.
"""
removeFavorite(objectId: ID!, objectType: String!): Boolean!
}
type FavoriteQuery {
"Retrieve the current user's favorites, if any."
all: [Favorite!]!
"Retrieve the current user's favorite of the specified object, if exists."
byObject(objectId: ID!, objectType: String!): Favorite
"Retrieve the current user's favorites for the specified object type, if any."
byType(objectType: String!): [Favorite!]!
}
type IngredientRef {
ingredient: Ingredient
preparation: String
quantity: Quantity
raw: String!
}
type Label implements Node {
id: ID!
"Unique label name."
name: String!
}
type LabelsQuery {
all: [Label!]!
}
type LibraryMutation {
"Create a new recipe in your library, from the passed info."
createRecipe(cookThis: Boolean, info: IngredientInfo!, photo: Upload): Recipe!
"""
Create a new recipe in your library, from the passed info, which is based
on the passed source recipe id.
"""
createRecipeFrom(info: IngredientInfo!, photo: Upload, sourceRecipeId: ID!): Recipe!
"Delete a recipe from your library."
deleteRecipe(id: ID!): Deletion!
history(recipeId: ID!): RecipeHistoryMutation
"""
Set the photo for a recipe in your library, without changing any other
info about the recipe. A photo may be set during create and/or update.
"""
setRecipePhoto(id: ID!, photo: Upload!): Recipe!
"Update a recipe in your library, from the passed info."
updateRecipe(id: ID!, info: IngredientInfo!, photo: Upload): Recipe!
}
type LibraryQuery {
getRecipeById(id: ID!): Recipe
"Search the recipe library."
recipes(
"""
Cursor to find results after. This should be omitted to retrieve the
first page.
"""
after: Cursor,
"""
How many recipes to return in the connection. If not specified, 10
will be returned.
"""
first: NonNegativeInt! = 10,
"Ingredient(s) to include. Missing/empty means \"all\"."
ingredients: [ID!]! = [],
"""
The textual query to filter results by. Can include simple words, as
well as quoted phrases.
"""
query: String! = "",
"The scope to search for recipes within."
scope: LibrarySearchScope! = MINE
): RecipeConnection!
"""
Recognize quantity, unit, and/or ingredient in a raw ingredient ref (aka
item) string, and describe that structure. By default, also provide
suggestions based on partial matches.
"""
recognizeItem(
"""
The position of the cursor in the raw string, used to make contextual
suggestions. If not specified, the end of the raw string is assumed.
"""
cursor: NonNegativeInt,
"The raw string to recognize."
raw: String!
): RecognizedItem
suggestRecipesToCook(after: Cursor, first: NonNegativeInt! = 5): RecipeConnection!
}
type Mutation {
favorite: FavoriteMutation
library: LibraryMutation
pantry: PantryMutation
planner: PlannerMutation
}
type PageInfo {
"The last cursor returned in this page's edges."
endCursor: Cursor
"""
Whether this connection has a next page, or null if included in the
result of a backward paging operation.
"""
hasNextPage: Boolean!
"""
Whether this connection has a previous page, or null if included in the
result of a forward paging operation.
"""
hasPreviousPage: Boolean!
"The first cursor returned in this page's edges."
startCursor: Cursor
}
type PantryItem implements Ingredient & Node {
"""
The number of auto-detected duplicates of this pantry item. Exactly what
"duplicate" means is unspecified and subject to change, excepting that it
will remain consistent with a 'duplicates:12345' search query.
"""
duplicateCount: NonNegativeInt!
"When this pantry item was first used."
firstUse: DateTime!
id: ID!
labels: [String!]
name: String!
"""
The relative order this pantry item will be shown on the shopping view.
The absolute value has no semantic, and may change arbitrarily.
"""
storeOrder: Int
"""
Other names this pantry item can be referred to as. E.g., an "apple" item
may have synonym "pomme".
"""
synonyms: [String!]
"""
The number of times this pantry item is used, including synonyms, in both
library recipes and on a plan.
"""
useCount: NonNegativeInt!
}
type PantryItemConnection {
edges: [PantryItemConnectionEdge!]!
pageInfo: PageInfo!
}
type PantryItemConnectionEdge {
cursor: Cursor!
node: PantryItem!
}
type PantryMutation {
addLabel(id: ID!, label: String!): PantryItem
addSynonym(id: ID!, synonym: String!): PantryItem
"""
Combine two or more pantry items, and return the result, after unifying
synonyms, labels, and references.
"""
combineItems(ids: [ID!]!): PantryItem
"Delete a pantry item, which MUST be unreferenced."
deleteItem(id: ID!): Deletion!
removeLabel(id: ID!, label: String!): PantryItem
removeSynonym(id: ID!, synonym: String!): PantryItem
renameItem(id: ID!, name: String!): PantryItem
setLabels(id: ID!, labels: [String!]!): PantryItem
setSynonyms(id: ID!, synonyms: [String!]!): PantryItem
}
type PantryQuery {
"Search available pantry items."
search(
"""
Cursor to find results after. This should be omitted to retrieve the
first page.
"""
after: Cursor,
"How many items to return in the connection."
first: NonNegativeInt = 25,
"""
Textual query to filter items by. The exact query operation performed
is unspecified, except that 'duplicates:12345' will return auto-detected
duplicates of the item with id '12345'. Exactly what "duplicate" means
is unspecified and subject to change, excepting that it will remain
consistent with results' "duplicateCount".
"""
query: String,
"""
Field to sort the result by. If omitted, the sort will be stable, but
is otherwise unspecified.
"""
sortBy: String,
"Direction to sort the result, ascending by default."
sortDir: SortDir = ASC
): PantryItemConnection!
}
type Photo {
focus: [Float!]
url: String!
}
type Plan implements AccessControlled & CorePlanItem & Node & Owned {
acl: Acl!
bucketCount: NonNegativeInt!
buckets: [PlanBucket!]!
childCount: NonNegativeInt!
children: [PlanItem!]!
"""
The color associated with the plan, expressed as a number sign and six
hex digits (e.g., '#F57F17').
"""
color: String!
descendantCount: NonNegativeInt!
descendants: [PlanItem!]!
grants: [AccessControlEntry!]!
id: ID!
name: String!
"The plan's owner"
owner: User!
"A plan's plan is always itself."
plan: Plan!
share: ShareInfo
"""
Retrieve all items which have been updated since the passed cutoff
(expressed in milliseconds since the UNIX epoch). May include this plan!
"""
updatedSince(cutoff: Long!): [CorePlanItem!]!
}
type PlanBucket {
date: Date
id: ID!
name: String
plan: Plan!
}
"Represents a single item on a plan"
type PlanItem implements CorePlanItem & Node {
aggregate: PlanItem
bucket: PlanBucket
childCount: NonNegativeInt!
children: [PlanItem!]!
componentCount: NonNegativeInt!
components: [PlanItem!]!
descendantCount: NonNegativeInt!
descendants: [PlanItem!]!
id: ID!
ingredient: Ingredient
name: String!
notes: String
"This item's parent; follow enough and you'll always get to the plan."
parent: CorePlanItem
plan: Plan!
preparation: String
quantity: Quantity
status: PlanItemStatus!
}
type PlannedRecipeHistory implements Node {
doneAt: DateTime!
id: ID!
notes: String
"""
The user who owns this history item, which may or may not be the recipe's
owner.
"""
owner: User!
plannedAt: DateTime!
rating: Rating
ratingInt: PositiveInt
"The recipe this history item is for."
recipe: Recipe!
status: PlanItemStatus!
}
type PlannerMutation {
"Assign a plan item to a bucket (in the same plan)."
assignBucket(bucketId: ID!, id: ID!): PlanItem!
"Create a new bucket w/in a plan, with an optional name and date."
createBucket(date: Date, name: String, planId: ID!): PlanBucket!
"""
Create a new item under the specified parent (which may be a plan, for
top-level items), after the specified peer item (null means 'at end'), and with
the specified name.
"""
createItem(afterId: ID, name: String!, parentId: ID!): PlanItem!
"Create a new empty plan, optionally duplicating the specified source plan."
createPlan(name: String!, sourcePlanId: ID): Plan!
"Delete a bucket from a plan."
deleteBucket(bucketId: ID!, planId: ID!): Deletion!
"Delete multiple buckets from a single plan."
deleteBuckets(bucketIds: [ID!]!, planId: ID!): [Deletion!]!
"Deletes an item from a plan. This operation cascades."
deleteItem(id: ID!): Deletion!
"Deletes the given plan, and all its related data."
deletePlan(id: ID!): Deletion!
"Create a new plan by duplicating the specified source plan."
duplicatePlan(name: String!, sourcePlanId: ID!): Plan!
"""
Move the given items under the given parent, in order, optionally after a
specific item already under that parent. The parent's info is returned.
"""
mutateTree(afterId: ID, itemIds: [ID!]!, parentId: ID!): PlanItem!
"Update the name of the given plan or plan item (but not bucket)."
rename(id: ID!, name: String!): CorePlanItem!
"""
Reorder the item/plan subitems in the same order as the passed list. If
there are subitems not included in the list, they will not be reordered. If
an item under a different parent is included in the list, it will be moved
under this item.
"""
reorderSubitems(itemIds: [ID!]!, parentId: ID!): PlanItem
"Revokes the grant for a user w/in a plan, if one exists."
revokeGrant(planId: ID!, userId: ID!): Plan!
"Set the plan's color (e.g., '#F57F17'), or reset it with a null or empty string."
setColor(color: String, planId: ID!): Plan!
"Set the access level granted to a user w/in a plan."
setGrant(accessLevel: AccessLevel, planId: ID!, userId: ID!): Plan!
"""
Sets the status of the given item. This will always return the updated
item, though it may immediately moved to the trash (in the background).
"""
setStatus(doneAt: DateTime, id: ID!, status: PlanItemStatus!): PlanItem!
"Update a bucket w/in a plan, by setting or clearing its name and date."
updateBucket(bucketId: ID!, date: Date, name: String, planId: ID!): PlanBucket!
}
type PlannerQuery {
plan(id: ID!): Plan!
planItem(id: ID!): PlanItem!
plans: [Plan!]!
"""
Retrieve all items on the given plan which have been updated since the
passed cutoff (expressed in milliseconds since the UNIX epoch). May include
the plan itself!
"""
updatedSince(cutoff: Long!, planId: ID!): [CorePlanItem!]!
}
type Quantity {
quantity: Float!
units: UnitOfMeasure
}
type Query {
favorite: FavoriteQuery
getCurrentUser: User
labels: LabelsQuery
library: LibraryQuery
node(id: ID!): Node
pantry: PantryQuery
planner: PlannerQuery
}
type Recipe implements Ingredient & Node & Owned {
calories: Int
directions: String
externalUrl: String
favorite: Boolean!
id: ID!
ingredients(
"Ingredient(s) to include. Missing/empty means \"all\"."
ingredients: [ID!]! = []
): [IngredientRef!]!
labels: [String!]
name: String!
owner: User!
photo: Photo
"""
Number of times this recipe has been sent to any plan, optionally
filtered by the result status (only COMPLETED and DELETED make sense).
"""
plannedCount(status: PlanItemStatus): Int!
"""
History of this recipe being planned, in reverse-chronological order,
optionally filtered by the result status (only COMPLETED and DELETED make
sense). By default, only the five most recent records will be returned.
"""
plannedHistory(last: NonNegativeInt = 5, status: PlanItemStatus): [PlannedRecipeHistory!]!
"""
All subrecipes. Multiple layers of nested recipes are flattened, and the
contextual recipe is not included.
"""
subrecipes: [Recipe!]!
totalTime(unit: ChronoUnit = MINUTES): Int
yield: Int
}
type RecipeConnection {
edges: [RecipeConnectionEdge!]!
pageInfo: PageInfo!
}
type RecipeConnectionEdge {
cursor: Cursor!
node: Recipe!
}
type RecipeHistoryMutation {
recipeId: ID!
"Set/update the notes on this history item."
setNotes(id: ID!, notes: String!): PlannedRecipeHistory!
"""
Set/update the rating on this history item. Either rating OR ratingInt
should be supplied, not both.
"""
setRating(id: ID!, rating: Rating, ratingInt: PositiveInt): PlannedRecipeHistory!
}
"""
A suggestion for what might come next at the cursor position, along with the
target range of the raw string it would replace.
"""
type RecognitionSuggestion {
name: String!
target: RecognizedRange!
}
"The result of recognizing a raw ingredient ref item."
type RecognizedItem {
"The position of the cursor in the raw string."
cursor: NonNegativeInt!
"Recognized ranges within the raw string."
ranges: [RecognizedRange!]!
"The raw string which was recognized."
raw: String!
"""
Suggestions of what the user might wish to insert at the current cursor
position. If more than 'count' suggestions are available, the returned
subset is unspecified, other than pantry items are preferred to recipes.
"""
suggestions(count: PositiveInt! = 10): [RecognitionSuggestion!]!
}
"""
A recognized quantity in the raw string. The type indicates which of the id
or quantity fields will be non-null, if either.
"""
type RecognizedRange {
end: NonNegativeInt!
id: ID
quantity: NonNegativeFloat
start: NonNegativeInt!
type: RecognizedRangeType!
}
type ShareInfo {
id: ID!
secret: String!
slug: String!
}
type UnitOfMeasure implements Node {
id: ID!
name: String!
}
type User implements Node {
email: String!
id: ID!
imageUrl: String
name: String
provider: String!
roles: [String!]!
}
enum AccessLevel {
ADMINISTER
CHANGE
VIEW
}
enum ChronoUnit {
HOURS
MILLIS
MINUTES
SECONDS
}
enum LibrarySearchScope {
EVERYONE
MINE
}
enum PlanItemStatus {
ACQUIRED
COMPLETED
DELETED
NEEDED
}
enum Rating {
FIVE_STARS
FOUR_STARS
ONE_STAR
THREE_STARS
TWO_STARS
}
enum RecognizedRangeType {
ITEM
NEW_ITEM
NEW_UNIT
QUANTITY
UNIT
UNKNOWN
}
enum SortDir {
ASC
DESC
}
"The type of a cursor, an opaque string used for walking connections."
scalar Cursor
"An RFC-3339 compliant Full Date Scalar"
scalar Date
"An RFC-3339 compliant DateTime Scalar"
scalar DateTime
"A 64-bit signed integer"
scalar Long
"An Float scalar that must be greater than or equal to zero"
scalar NonNegativeFloat
"An Int scalar that must be greater than or equal to zero"
scalar NonNegativeInt
"An Int scalar that must be a positive value"
scalar PositiveInt
"A file part in a multipart request"
scalar Upload
input IngredientInfo {
calories: Int
directions: String
externalUrl: String
ingredients: [IngredientRefInfo!]
labels: [String!]
name: String!
photoFocus: [Float!]
storeOrder: Int
totalTime: Int
type: String!
yield: Int
}
input IngredientRefInfo {
ingredient: String
ingredientId: Long
preparation: String
quantity: Float
raw: String!
units: String
uomId: Long
}