@codecks/fetch 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +317 -10
  2. package/dist/_exploration/api-requester.d.ts +4 -4
  3. package/dist/_exploration/api-requester.js +5 -4
  4. package/dist/_exploration/create-hooks.d.ts +47 -5
  5. package/dist/_exploration/create-hooks.js +193 -88
  6. package/dist/_exploration/loader.d.ts +2 -2
  7. package/dist/_exploration/loader.js +7 -2
  8. package/dist/_exploration/store.d.ts +4 -4
  9. package/dist/_exploration/store.js +76 -73
  10. package/dist/{_root-D1Faf8cg.d.ts → _root-BW9uzB79.d.ts} +1 -1
  11. package/dist/immediate-cache-DiH8tpJM.js +237 -0
  12. package/dist/{index-DUBsesYl.d.ts → index-k-KPWV9R.d.ts} +8 -1
  13. package/dist/index.d.ts +4 -4
  14. package/dist/index.js +6 -5
  15. package/dist/{loader-types-Dp0CSVTf.d.ts → loader-types-fd5tV0FD.d.ts} +4 -8
  16. package/dist/{loader-utils-Du-CTKH-.d.ts → loader-utils-BqZKAn_v.d.ts} +2 -2
  17. package/dist/{query-helpers-DsMMOtSO.js → query-helpers-iX1fiqLv.js} +41 -16
  18. package/dist/{query-type-Dx5ZCv5N.d.ts → query-type-BqQ9oX_U.d.ts} +55 -10
  19. package/dist/{store-B6JWZnAO.d.ts → store-BvEJzUVp.d.ts} +104 -6
  20. package/package.json +4 -3
  21. package/schema/models/account.md +104 -0
  22. package/schema/models/accountOnboarding.md +15 -0
  23. package/schema/models/accountOnboardingStep.md +14 -0
  24. package/schema/models/accountRole.md +19 -0
  25. package/schema/models/accountUserAchievement.md +17 -0
  26. package/schema/models/accountUserSetting.md +20 -0
  27. package/schema/models/activeTimeTracker.md +19 -0
  28. package/schema/models/activity.md +30 -0
  29. package/schema/models/affiliateCode.md +30 -0
  30. package/schema/models/affiliateCodeStat.md +19 -0
  31. package/schema/models/app.md +10 -0
  32. package/schema/models/appInstallation.md +19 -0
  33. package/schema/models/assigneeAssignment.md +18 -0
  34. package/schema/models/assigneeDeckAssignment.md +20 -0
  35. package/schema/models/attachment.md +23 -0
  36. package/schema/models/autoFinishedTimeTrackingSegment.md +20 -0
  37. package/schema/models/card.md +82 -0
  38. package/schema/models/cardDiffNotification.md +22 -0
  39. package/schema/models/cardHistory.md +20 -0
  40. package/schema/models/cardOrder.md +17 -0
  41. package/schema/models/cardOrderInDeck.md +18 -0
  42. package/schema/models/cardPreset.md +19 -0
  43. package/schema/models/cardSubscription.md +19 -0
  44. package/schema/models/cardUpvote.md +21 -0
  45. package/schema/models/cardsEffortHistory.md +9 -0
  46. package/schema/models/cardsFinishedHistory.md +16 -0
  47. package/schema/models/cardsStatusHistory.md +9 -0
  48. package/schema/models/cardsTimeToFinished.md +18 -0
  49. package/schema/models/dailyDiscordGuildVoteMembership.md +15 -0
  50. package/schema/models/dailyPublicProjectMembership.md +15 -0
  51. package/schema/models/deck.md +53 -0
  52. package/schema/models/deckAssignment.md +18 -0
  53. package/schema/models/deckGuardian.md +17 -0
  54. package/schema/models/deckSubscription.md +18 -0
  55. package/schema/models/discordGuild.md +30 -0
  56. package/schema/models/discordMember.md +21 -0
  57. package/schema/models/discordProjectNotification.md +19 -0
  58. package/schema/models/discordSlashCommand.md +28 -0
  59. package/schema/models/dueCard.md +18 -0
  60. package/schema/models/file.md +26 -0
  61. package/schema/models/handCard.md +18 -0
  62. package/schema/models/integration.md +23 -0
  63. package/schema/models/invoice.md +21 -0
  64. package/schema/models/lastSeenCardUpvote.md +17 -0
  65. package/schema/models/milestone.md +39 -0
  66. package/schema/models/milestoneProgress.md +14 -0
  67. package/schema/models/milestoneProject.md +17 -0
  68. package/schema/models/pinnedMilestone.md +22 -0
  69. package/schema/models/project.md +58 -0
  70. package/schema/models/projectOrder.md +18 -0
  71. package/schema/models/projectSelection.md +18 -0
  72. package/schema/models/projectTag.md +19 -0
  73. package/schema/models/projectUser.md +18 -0
  74. package/schema/models/projectUserSetting.md +15 -0
  75. package/schema/models/publicProjectInfo.md +20 -0
  76. package/schema/models/publicProjectMembership.md +17 -0
  77. package/schema/models/publicProjectVisit.md +16 -0
  78. package/schema/models/queueEntry.md +21 -0
  79. package/schema/models/queueSelection.md +19 -0
  80. package/schema/models/release.md +12 -0
  81. package/schema/models/resolvable.md +32 -0
  82. package/schema/models/resolvableEntry.md +28 -0
  83. package/schema/models/resolvableEntryHistory.md +20 -0
  84. package/schema/models/resolvableEntryReaction.md +23 -0
  85. package/schema/models/resolvableNotification.md +30 -0
  86. package/schema/models/resolvableParticipant.md +25 -0
  87. package/schema/models/resolvableParticipantHistory.md +23 -0
  88. package/schema/models/savedSearch.md +18 -0
  89. package/schema/models/sprint.md +42 -0
  90. package/schema/models/sprintConfig.md +38 -0
  91. package/schema/models/sprintConfigProgress.md +14 -0
  92. package/schema/models/sprintProgress.md +14 -0
  93. package/schema/models/sprintProject.md +17 -0
  94. package/schema/models/stripeAccountSync.md +29 -0
  95. package/schema/models/timeTrackingSegment.md +24 -0
  96. package/schema/models/timeTrackingSum.md +18 -0
  97. package/schema/models/user.md +67 -0
  98. package/schema/models/userDismissedHint.md +16 -0
  99. package/schema/models/userEmail.md +18 -0
  100. package/schema/models/userInvitation.md +20 -0
  101. package/schema/models/userInviteCode.md +23 -0
  102. package/schema/models/userOnboarding.md +14 -0
  103. package/schema/models/userProjectAccess.md +17 -0
  104. package/schema/models/userReportEmail.md +19 -0
  105. package/schema/models/userReportSetting.md +23 -0
  106. package/schema/models/userReportToken.md +18 -0
  107. package/schema/models/userTag.md +18 -0
  108. package/schema/models/visionBoard.md +21 -0
  109. package/schema/models/visionBoardQuery.md +22 -0
  110. package/schema/models/wizard.md +19 -0
  111. package/schema/models/workflowItem.md +45 -0
  112. package/schema/models/workflowItemHistory.md +18 -0
  113. package/schema/overview.md +110 -0
  114. package/schema/query-syntax.md +184 -0
package/README.md CHANGED
@@ -1,28 +1,335 @@
1
1
  # @codecks/fetch
2
2
 
3
- ## Usage
3
+ A type-safe query SDK for the [Codecks](https://www.codecks.io) API. Describe nested queries in a declarative DSL and get fully inferred TypeScript response types.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @codecks/fetch
9
+ ```
10
+
11
+ ## Getting started
4
12
 
5
13
  ```ts
6
14
  import {buildFetchersWithSimpleLoader} from "@codecks/fetch";
7
15
 
8
- const {fetchFromRoot, fetchInstance} = buildFetchersWithSimpleLoader({
9
- baseUrl: "https://api.codecks.io/",
10
- subdomain: "my-org",
16
+ const {fetchFromRoot, fetchInstance, fetchInstances, fetchFromInstance} =
17
+ buildFetchersWithSimpleLoader({
18
+ baseUrl: "https://api.codecks.io/",
19
+ subdomain: "my-org",
20
+ accessToken: "your-token",
21
+ });
22
+ ```
23
+
24
+ ### Configuration options
25
+
26
+ | Option | Type | Description |
27
+ | ------------- | ------------------------ | ------------------------------ |
28
+ | `baseUrl` | `string` | API base URL |
29
+ | `subdomain` | `string` | Sets the `X-Account` header |
30
+ | `accessToken` | `string` | Sets the `X-Auth-Token` header |
31
+ | `headers` | `Record<string, string>` | Additional request headers |
32
+ | `timeout` | `number` | Request timeout in ms |
33
+ | `fetch` | `typeof fetch` | Custom fetch implementation |
34
+
35
+ ## Fetching data
36
+
37
+ ### `fetchFromRoot` — query top-level relations
38
+
39
+ Use this to query entry points like `account`, `loggedInUser`, or `releases`.
40
+
41
+ ```ts
42
+ const result = await fetchFromRoot({
43
+ account: {
44
+ fields: ["name", "subdomain"],
45
+ },
46
+ });
47
+
48
+ console.log(result.account.name);
49
+ // ^ fully typed as string
50
+ ```
51
+
52
+ ### `fetchInstance` — fetch a single instance by model name and ID
53
+
54
+ ```ts
55
+ const card = await fetchInstance("card", "card-123", {
56
+ fields: ["title", "status"],
57
+ });
58
+
59
+ console.log(card.title);
60
+ ```
61
+
62
+ ### `fetchInstances` — fetch multiple instances
63
+
64
+ Returns a `Record<Id, Result>`.
65
+
66
+ ```ts
67
+ const cards = await fetchInstances("card", ["card-1", "card-2"], {
68
+ fields: ["title"],
69
+ });
70
+
71
+ console.log(cards["card-1"].title);
72
+ ```
73
+
74
+ ### `fetchFromInstance` — fetch from an existing instance reference
75
+
76
+ Any previously fetched instance can be passed to query more data from it.
77
+
78
+ ```ts
79
+ const account = result.account;
80
+ // account has { ~model: "account", ~key: "1" }
81
+
82
+ const details = await fetchFromInstance(account, {
83
+ fields: ["seats", "activeProjectCount"],
84
+ relations: {
85
+ roles: {fields: ["role"]},
86
+ },
11
87
  });
88
+ ```
12
89
 
13
- const rootResponse = await fetchFromRoot({
90
+ ## Querying relations
91
+
92
+ Relations are fetched by nesting them under `relations`. They can be nested to any depth.
93
+
94
+ ```ts
95
+ const result = await fetchFromRoot({
14
96
  account: {
15
97
  fields: ["name"],
98
+ relations: {
99
+ // belongsTo — returns a single object (or null if optional)
100
+ disabledBy: {fields: ["name"]},
101
+
102
+ // hasMany — returns an array
103
+ roles: {
104
+ fields: ["role"],
105
+ relations: {
106
+ user: {fields: ["name", "fullName"]},
107
+ },
108
+ },
109
+ },
16
110
  },
17
111
  });
18
112
 
19
- console.log(rootResponse);
20
- // > {account: {id: 1, name: "myOrg"}}
113
+ // result.account.disabledBy?.name
114
+ // result.account.roles[0].user.name
115
+ ```
116
+
117
+ ## hasMany variants
118
+
119
+ hasMany relations support several query modes. Non-default variants require an `as` alias.
120
+
121
+ ### Default (array)
122
+
123
+ ```ts
124
+ relations: {
125
+ roles: {
126
+ fields: ["role"],
127
+ orderBy: "-accountId",
128
+ limit: 10,
129
+ offset: 0,
130
+ },
131
+ }
132
+ // result.roles: Array<{role: string, ...}>
133
+ ```
134
+
135
+ ### Count
136
+
137
+ ```ts
138
+ relations: {
139
+ roles: {type: "count", as: "roleCount"},
140
+ }
141
+ // result.roleCount: number
142
+ ```
143
+
144
+ ### Exists
145
+
146
+ ```ts
147
+ relations: {
148
+ releases: {type: "exists", as: "hasReleases"},
149
+ }
150
+ // result.hasReleases: boolean
151
+ ```
152
+
153
+ ### First
154
+
155
+ Returns a single result or `null`. Requires `orderBy`.
156
+
157
+ ```ts
158
+ relations: {
159
+ roles: {
160
+ type: "first",
161
+ as: "firstRole",
162
+ orderBy: "-accountId",
163
+ fields: ["role"],
164
+ },
165
+ }
166
+ // result.firstRole: {role: string, ...} | null
167
+ ```
168
+
169
+ ### Multiple queries on the same relation
170
+
171
+ Pass an array of aliased queries to query the same relation in different ways:
21
172
 
22
- const card = await fetchInstance("card", 1, {
173
+ ```ts
174
+ relations: {
175
+ roles: [
176
+ {as: "adminRoles", fields: ["role"], filter: {role: "admin"}},
177
+ {as: "roleCount", type: "count"},
178
+ ],
179
+ }
180
+ // result.adminRoles: Array<...>
181
+ // result.roleCount: number
182
+ ```
183
+
184
+ ## Filtering
185
+
186
+ Filters are available on all hasMany variants.
187
+
188
+ ### Simple equality
189
+
190
+ ```ts
191
+ filter: {
192
+ status: "done";
193
+ }
194
+ // shorthand for {status: {op: "eq", value: "open"}}
195
+ ```
196
+
197
+ ### Null checks
198
+
199
+ ```ts
200
+ filter: {
201
+ assigneeId: null;
202
+ }
203
+ ```
204
+
205
+ ### Comparison operators
206
+
207
+ ```ts
208
+ filter: {
209
+ createdAt: {op: "gt", value: "2025-01-01"},
210
+ effort: {op: "lte", value: 5},
211
+ }
212
+ ```
213
+
214
+ Available operators: `eq`, `neq`, `lt`, `lte`, `gt`, `gte`.
215
+
216
+ ### Set operators
217
+
218
+ ```ts
219
+ filter: {
220
+ derivedStatus: {op: "in", value: ["review", "blocked"]},
221
+ }
222
+ ```
223
+
224
+ Also available: `notIn`.
225
+
226
+ ### String operators
227
+
228
+ ```ts
229
+ filter: {
230
+ title: {op: "contains", value: "bug"},
231
+ }
232
+ ```
233
+
234
+ ### Array operators
235
+
236
+ ```ts
237
+ filter: {
238
+ tags: {op: "has", value: "urgent"},
239
+ masterTags: {op: "overlaps", value: ["frontend", "backend"]},
240
+ }
241
+ ```
242
+
243
+ ### Logical combinators
244
+
245
+ ```ts
246
+ filter: {
247
+ $or: [
248
+ {status: "open"},
249
+ {status: "started"},
250
+ ],
251
+ }
252
+ ```
253
+
254
+ Also available: `$and`.
255
+
256
+ ### Relation filters and negation
257
+
258
+ ```ts
259
+ filter: {
260
+ // cards that have an assignee named "Alice"
261
+ assignee: {name: "Alice"},
262
+ // cards that do NOT belong to deck "Backlog"
263
+ "!deck": {title: "Backlog"},
264
+ }
265
+ ```
266
+
267
+ ## Ordering
268
+
269
+ ```ts
270
+ // ascending
271
+ orderBy: "createdAt"
272
+
273
+ // descending (prefix with -)
274
+ orderBy: "-createdAt"
275
+
276
+ // multiple
277
+ orderBy: ["status", "-createdAt"]
278
+
279
+ // object syntax
280
+ orderBy: {field: "createdAt", dir: "desc"}
281
+ ```
282
+
283
+ ## Response shape
284
+
285
+ Every returned instance includes:
286
+
287
+ - **Requested fields** — only the fields you asked for
288
+ - **Key fields** — always included (e.g. `cardId` for cards, `id` for accounts)
289
+ - **`~model`** — the model name (e.g. `"card"`)
290
+ - **`~key`** — the instance's unique key
291
+
292
+ ```ts
293
+ const card = await fetchInstance("card", "card-123", {
23
294
  fields: ["title"],
24
295
  });
296
+ // {
297
+ // cardId: "card-123",
298
+ // title: "My Card",
299
+ // "~model": "card",
300
+ // "~key": "card-123",
301
+ // }
302
+ ```
303
+
304
+ All response types are fully inferred from your query — TypeScript knows exactly which fields and relations are present.
305
+
306
+ ## Schema reference for LLMs
307
+
308
+ This package ships with generated markdown files describing every API model, its fields, and relations. These are designed for LLM-based tools (Claude Code, Cursor, Copilot, etc.) that need to discover the API schema without relying on TypeScript autocomplete.
309
+
310
+ ```
311
+ node_modules/@codecks/fetch/schema/
312
+ overview.md # Root entry points + index of all models
313
+ query-syntax.md # Query DSL reference with examples
314
+ models/
315
+ card.md # Fields + relations for the card model
316
+ account.md # Fields + relations for the account model
317
+ ... # One file per model
318
+ ```
319
+
320
+ Point your LLM's project instructions (e.g. `CLAUDE.md`) at `schema/overview.md` as a starting point, then let it drill into individual model files as needed.
321
+
322
+ ## Custom loader
323
+
324
+ For advanced use cases (batching, caching, custom transports), you can provide your own `DataLoader`:
25
325
 
26
- console.log(card);
27
- // > {cardId: 1, title: "My Title"}
326
+ ```ts
327
+ import {buildFetchers} from "@codecks/fetch";
328
+
329
+ const {fetchFromRoot} = buildFetchers({
330
+ fetchModel: async (model, ids, query) => {
331
+ // your custom loading logic
332
+ return recordOfResults;
333
+ },
334
+ });
28
335
  ```
@@ -1,7 +1,7 @@
1
- import "../query-type-Dx5ZCv5N.js";
2
- import "../index-DUBsesYl.js";
3
- import { FetchOptions } from "../loader-utils-Du-CTKH-.js";
4
- import { BaseRequester, MissingDataRequest } from "../loader-types-Dp0CSVTf.js";
1
+ import "../query-type-BqQ9oX_U.js";
2
+ import "../index-k-KPWV9R.js";
3
+ import { FetchOptions } from "../loader-utils-BqZKAn_v.js";
4
+ import { BaseRequester, MissingDataRequest } from "../loader-types-fd5tV0FD.js";
5
5
 
6
6
  //#region src/_exploration/api-requester.d.ts
7
7
  declare class ApiRequester implements BaseRequester {
@@ -1,5 +1,5 @@
1
1
  import { configuredFetch, ensureMapValue } from "../collection-utils-CYJaA1a9.js";
2
- import { serializeModel } from "../query-helpers-DsMMOtSO.js";
2
+ import { serializeModel } from "../query-helpers-iX1fiqLv.js";
3
3
 
4
4
  //#region src/_exploration/utils/concurrency-limiter.ts
5
5
  var ConcurrencyLimiter = class {
@@ -82,10 +82,11 @@ var ApiRequester = class {
82
82
  relations: new Map()
83
83
  }));
84
84
  if (req.type === "field") instanceData.fields.add(req.field);
85
- else if (req.type === "relation") {
85
+ else if (req.type === "relation") if (req.contents.asField) instanceData.fields.add(req.relKey);
86
+ else {
86
87
  const existing = instanceData.relations.get(req.relKey);
87
- if (existing && !existing.asField && !req.query.asField) instanceData.relations.set(req.relKey, mergeRelations(existing, req.query));
88
- else instanceData.relations.set(req.relKey, req.query);
88
+ if (existing) instanceData.relations.set(req.relKey, mergeRelations(existing, req.contents));
89
+ else instanceData.relations.set(req.relKey, req.contents);
89
90
  }
90
91
  }
91
92
  const query = {};
@@ -1,8 +1,8 @@
1
- import { InferModelQuery, InferRelQuery, ModelDesc, ModelQuery, RelQuery, RelationEntry, TypedField } from "../query-type-Dx5ZCv5N.js";
2
- import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId } from "../index-DUBsesYl.js";
3
- import "../loader-types-Dp0CSVTf.js";
4
- import { _rootDesc$1 as _rootDesc } from "../_root-D1Faf8cg.js";
5
- import { Store } from "../store-B6JWZnAO.js";
1
+ import { InferModelQuery, InferRelQuery, ModelDesc, ModelQuery, RelQuery, RelationEntry, TypedField } from "../query-type-BqQ9oX_U.js";
2
+ import { AccountId, AccountOnboardingStepId, ActiveTimeTrackerId, ActivityId, AffiliateCodeId, AppId, AppInstallationId, AttachmentId, CardId, CardPresetId, CardSubscriptionId, CardUpvoteId, DeckId, DeckSubscriptionId, DiscordGuildId, DiscordMemberId, DiscordProjectNotificationId, DiscordSlashCommandId, FileId, IntegrationId, InvoiceId, MilestoneId, PinnedMilestoneId, ProjectId, ProjectSelectionId, ProjectTagId, QueueEntryId, QueueSelectionId, ReleaseId, ResolvableEntryId, ResolvableEntryReactionId, ResolvableId, SavedSearchId, SprintConfigId, SprintId, TimeTrackingSegmentId, UserEmailId, UserId, UserInvitationId, UserInviteCodeId, UserReportEmailId, UserReportSettingId, UserReportTokenId, UserTagId, VisionBoardId, VisionBoardQueryId, WizardId, WorkflowItemId } from "../index-k-KPWV9R.js";
3
+ import "../loader-types-fd5tV0FD.js";
4
+ import { _rootDesc$1 as _rootDesc } from "../_root-BW9uzB79.js";
5
+ import { Store } from "../store-BvEJzUVp.js";
6
6
 
7
7
  //#region src/_exploration/create-hooks.d.ts
8
8
  declare const createHooks: (store: Store) => {
@@ -808,6 +808,7 @@ declare const createHooks: (store: Store) => {
808
808
  }>;
809
809
  attachments: RelationEntry<"attachment", {
810
810
  readonly type: "hasMany";
811
+ readonly fkAsArray: true;
811
812
  }>;
812
813
  diffs: RelationEntry<"cardHistory", {
813
814
  readonly type: "hasMany";
@@ -820,15 +821,19 @@ declare const createHooks: (store: Store) => {
820
821
  }>;
821
822
  childCards: RelationEntry<"card", {
822
823
  readonly type: "hasMany";
824
+ readonly fkAsArray: true;
823
825
  }>;
824
826
  inDeps: RelationEntry<"card", {
825
827
  readonly type: "hasMany";
828
+ readonly fkAsArray: true;
826
829
  }>;
827
830
  outDeps: RelationEntry<"card", {
828
831
  readonly type: "hasMany";
832
+ readonly fkAsArray: true;
829
833
  }>;
830
834
  cardReferences: RelationEntry<"card", {
831
835
  readonly type: "hasMany";
836
+ readonly fkAsArray: true;
832
837
  }>;
833
838
  upvotes: RelationEntry<"cardUpvote", {
834
839
  readonly type: "hasMany";
@@ -2524,9 +2529,11 @@ declare const createHooks: (store: Store) => {
2524
2529
  }>;
2525
2530
  inDeps: RelationEntry<"workflowItem", {
2526
2531
  readonly type: "hasMany";
2532
+ readonly fkAsArray: true;
2527
2533
  }>;
2528
2534
  outDeps: RelationEntry<"workflowItem", {
2529
2535
  readonly type: "hasMany";
2536
+ readonly fkAsArray: true;
2530
2537
  }>;
2531
2538
  }, ["itemId"]>;
2532
2539
  }[K], {
@@ -3331,6 +3338,7 @@ declare const createHooks: (store: Store) => {
3331
3338
  }>;
3332
3339
  attachments: RelationEntry<"attachment", {
3333
3340
  readonly type: "hasMany";
3341
+ readonly fkAsArray: true;
3334
3342
  }>;
3335
3343
  diffs: RelationEntry<"cardHistory", {
3336
3344
  readonly type: "hasMany";
@@ -3343,15 +3351,19 @@ declare const createHooks: (store: Store) => {
3343
3351
  }>;
3344
3352
  childCards: RelationEntry<"card", {
3345
3353
  readonly type: "hasMany";
3354
+ readonly fkAsArray: true;
3346
3355
  }>;
3347
3356
  inDeps: RelationEntry<"card", {
3348
3357
  readonly type: "hasMany";
3358
+ readonly fkAsArray: true;
3349
3359
  }>;
3350
3360
  outDeps: RelationEntry<"card", {
3351
3361
  readonly type: "hasMany";
3362
+ readonly fkAsArray: true;
3352
3363
  }>;
3353
3364
  cardReferences: RelationEntry<"card", {
3354
3365
  readonly type: "hasMany";
3366
+ readonly fkAsArray: true;
3355
3367
  }>;
3356
3368
  upvotes: RelationEntry<"cardUpvote", {
3357
3369
  readonly type: "hasMany";
@@ -5047,9 +5059,11 @@ declare const createHooks: (store: Store) => {
5047
5059
  }>;
5048
5060
  inDeps: RelationEntry<"workflowItem", {
5049
5061
  readonly type: "hasMany";
5062
+ readonly fkAsArray: true;
5050
5063
  }>;
5051
5064
  outDeps: RelationEntry<"workflowItem", {
5052
5065
  readonly type: "hasMany";
5066
+ readonly fkAsArray: true;
5053
5067
  }>;
5054
5068
  }, ["itemId"]>;
5055
5069
  }>>(model: K, id: Id, q: Q) => InferModelQuery<{
@@ -5854,6 +5868,7 @@ declare const createHooks: (store: Store) => {
5854
5868
  }>;
5855
5869
  attachments: RelationEntry<"attachment", {
5856
5870
  readonly type: "hasMany";
5871
+ readonly fkAsArray: true;
5857
5872
  }>;
5858
5873
  diffs: RelationEntry<"cardHistory", {
5859
5874
  readonly type: "hasMany";
@@ -5866,15 +5881,19 @@ declare const createHooks: (store: Store) => {
5866
5881
  }>;
5867
5882
  childCards: RelationEntry<"card", {
5868
5883
  readonly type: "hasMany";
5884
+ readonly fkAsArray: true;
5869
5885
  }>;
5870
5886
  inDeps: RelationEntry<"card", {
5871
5887
  readonly type: "hasMany";
5888
+ readonly fkAsArray: true;
5872
5889
  }>;
5873
5890
  outDeps: RelationEntry<"card", {
5874
5891
  readonly type: "hasMany";
5892
+ readonly fkAsArray: true;
5875
5893
  }>;
5876
5894
  cardReferences: RelationEntry<"card", {
5877
5895
  readonly type: "hasMany";
5896
+ readonly fkAsArray: true;
5878
5897
  }>;
5879
5898
  upvotes: RelationEntry<"cardUpvote", {
5880
5899
  readonly type: "hasMany";
@@ -7570,9 +7589,11 @@ declare const createHooks: (store: Store) => {
7570
7589
  }>;
7571
7590
  inDeps: RelationEntry<"workflowItem", {
7572
7591
  readonly type: "hasMany";
7592
+ readonly fkAsArray: true;
7573
7593
  }>;
7574
7594
  outDeps: RelationEntry<"workflowItem", {
7575
7595
  readonly type: "hasMany";
7596
+ readonly fkAsArray: true;
7576
7597
  }>;
7577
7598
  }, ["itemId"]>;
7578
7599
  }[K], Q, {
@@ -8377,6 +8398,7 @@ declare const createHooks: (store: Store) => {
8377
8398
  }>;
8378
8399
  attachments: RelationEntry<"attachment", {
8379
8400
  readonly type: "hasMany";
8401
+ readonly fkAsArray: true;
8380
8402
  }>;
8381
8403
  diffs: RelationEntry<"cardHistory", {
8382
8404
  readonly type: "hasMany";
@@ -8389,15 +8411,19 @@ declare const createHooks: (store: Store) => {
8389
8411
  }>;
8390
8412
  childCards: RelationEntry<"card", {
8391
8413
  readonly type: "hasMany";
8414
+ readonly fkAsArray: true;
8392
8415
  }>;
8393
8416
  inDeps: RelationEntry<"card", {
8394
8417
  readonly type: "hasMany";
8418
+ readonly fkAsArray: true;
8395
8419
  }>;
8396
8420
  outDeps: RelationEntry<"card", {
8397
8421
  readonly type: "hasMany";
8422
+ readonly fkAsArray: true;
8398
8423
  }>;
8399
8424
  cardReferences: RelationEntry<"card", {
8400
8425
  readonly type: "hasMany";
8426
+ readonly fkAsArray: true;
8401
8427
  }>;
8402
8428
  upvotes: RelationEntry<"cardUpvote", {
8403
8429
  readonly type: "hasMany";
@@ -10093,9 +10119,11 @@ declare const createHooks: (store: Store) => {
10093
10119
  }>;
10094
10120
  inDeps: RelationEntry<"workflowItem", {
10095
10121
  readonly type: "hasMany";
10122
+ readonly fkAsArray: true;
10096
10123
  }>;
10097
10124
  outDeps: RelationEntry<"workflowItem", {
10098
10125
  readonly type: "hasMany";
10126
+ readonly fkAsArray: true;
10099
10127
  }>;
10100
10128
  }, ["itemId"]>;
10101
10129
  }>;
@@ -10901,6 +10929,7 @@ declare const createHooks: (store: Store) => {
10901
10929
  }>;
10902
10930
  attachments: RelationEntry<"attachment", {
10903
10931
  readonly type: "hasMany";
10932
+ readonly fkAsArray: true;
10904
10933
  }>;
10905
10934
  diffs: RelationEntry<"cardHistory", {
10906
10935
  readonly type: "hasMany";
@@ -10913,15 +10942,19 @@ declare const createHooks: (store: Store) => {
10913
10942
  }>;
10914
10943
  childCards: RelationEntry<"card", {
10915
10944
  readonly type: "hasMany";
10945
+ readonly fkAsArray: true;
10916
10946
  }>;
10917
10947
  inDeps: RelationEntry<"card", {
10918
10948
  readonly type: "hasMany";
10949
+ readonly fkAsArray: true;
10919
10950
  }>;
10920
10951
  outDeps: RelationEntry<"card", {
10921
10952
  readonly type: "hasMany";
10953
+ readonly fkAsArray: true;
10922
10954
  }>;
10923
10955
  cardReferences: RelationEntry<"card", {
10924
10956
  readonly type: "hasMany";
10957
+ readonly fkAsArray: true;
10925
10958
  }>;
10926
10959
  upvotes: RelationEntry<"cardUpvote", {
10927
10960
  readonly type: "hasMany";
@@ -12617,9 +12650,11 @@ declare const createHooks: (store: Store) => {
12617
12650
  }>;
12618
12651
  inDeps: RelationEntry<"workflowItem", {
12619
12652
  readonly type: "hasMany";
12653
+ readonly fkAsArray: true;
12620
12654
  }>;
12621
12655
  outDeps: RelationEntry<"workflowItem", {
12622
12656
  readonly type: "hasMany";
12657
+ readonly fkAsArray: true;
12623
12658
  }>;
12624
12659
  }, ["itemId"]>;
12625
12660
  }>>(q: Q) => InferRelQuery<typeof _rootDesc, Q, {
@@ -13424,6 +13459,7 @@ declare const createHooks: (store: Store) => {
13424
13459
  }>;
13425
13460
  attachments: RelationEntry<"attachment", {
13426
13461
  readonly type: "hasMany";
13462
+ readonly fkAsArray: true;
13427
13463
  }>;
13428
13464
  diffs: RelationEntry<"cardHistory", {
13429
13465
  readonly type: "hasMany";
@@ -13436,15 +13472,19 @@ declare const createHooks: (store: Store) => {
13436
13472
  }>;
13437
13473
  childCards: RelationEntry<"card", {
13438
13474
  readonly type: "hasMany";
13475
+ readonly fkAsArray: true;
13439
13476
  }>;
13440
13477
  inDeps: RelationEntry<"card", {
13441
13478
  readonly type: "hasMany";
13479
+ readonly fkAsArray: true;
13442
13480
  }>;
13443
13481
  outDeps: RelationEntry<"card", {
13444
13482
  readonly type: "hasMany";
13483
+ readonly fkAsArray: true;
13445
13484
  }>;
13446
13485
  cardReferences: RelationEntry<"card", {
13447
13486
  readonly type: "hasMany";
13487
+ readonly fkAsArray: true;
13448
13488
  }>;
13449
13489
  upvotes: RelationEntry<"cardUpvote", {
13450
13490
  readonly type: "hasMany";
@@ -15140,9 +15180,11 @@ declare const createHooks: (store: Store) => {
15140
15180
  }>;
15141
15181
  inDeps: RelationEntry<"workflowItem", {
15142
15182
  readonly type: "hasMany";
15183
+ readonly fkAsArray: true;
15143
15184
  }>;
15144
15185
  outDeps: RelationEntry<"workflowItem", {
15145
15186
  readonly type: "hasMany";
15187
+ readonly fkAsArray: true;
15146
15188
  }>;
15147
15189
  }, ["itemId"]>;
15148
15190
  }>;