@voxgig/sdkgen 3.7.2 → 3.7.3
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.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/helpers/opShape.d.ts +2 -1
- package/dist/helpers/opShape.js +1 -0
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -2
- package/dist/sdkgen.js +3 -2
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +14 -0
- package/package.json +1 -1
- package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +54 -21
- package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +24 -11
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +96 -0
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +47 -1
- package/project/sdkgen-package.json +1 -1
- package/src/helpers/opShape.ts +1 -0
- package/src/sdkgen.ts +2 -1
|
@@ -242,8 +242,15 @@ function seedRecord(e: any, idx: number): Record<string, any> {
|
|
|
242
242
|
else if (e.parents.includes(f.name)) {
|
|
243
243
|
// A nested entity's parent id must match a record the parent seeds, or
|
|
244
244
|
// the offline store answers nothing and every nested test reads as a
|
|
245
|
-
// false pass.
|
|
246
|
-
|
|
245
|
+
// false pass. Reuses parentSeed's fallback rather than f.parentEntity
|
|
246
|
+
// directly: when no entity in the model shares this key's name (the
|
|
247
|
+
// common case for a scoping param like `user_id` with no `user`
|
|
248
|
+
// entity, or a same-named response field that means something else
|
|
249
|
+
// entirely, like GitHub's `owner`), f.parentEntity is '' and seeding
|
|
250
|
+
// '0' desynced the record from every query built against the SAME
|
|
251
|
+
// key via parentSeed (parentPairs, crudTest, ...) — 0 results, or a
|
|
252
|
+
// seeded field asserted against the wrong literal.
|
|
253
|
+
out[f.name] = parentSeed(e, f.name)
|
|
247
254
|
}
|
|
248
255
|
else if ('number' === f.kind) {
|
|
249
256
|
out[f.name] = 100 * (idx + 1)
|
|
@@ -407,11 +414,20 @@ describe('${provider.fileBase}', () => {
|
|
|
407
414
|
|
|
408
415
|
`)
|
|
409
416
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
417
|
+
// Every flat entity (no parent keys), not just one "subject" — a
|
|
418
|
+
// provider with two or more flat siblings used to leave every one
|
|
419
|
+
// but the busiest untested beyond the accessor check above. A bare
|
|
420
|
+
// `list$()`/`load$(id)` call has no way to carry a parent key, so
|
|
421
|
+
// entities that need one are covered by the `nested` block below
|
|
422
|
+
// instead, with their keys filled in.
|
|
423
|
+
const flat = provider.entities.filter((e: any) => 0 === e.parents.length)
|
|
424
|
+
|
|
425
|
+
each(flat, (e: any) => {
|
|
426
|
+
if (e.cmds.includes('list')) {
|
|
427
|
+
Content(`
|
|
428
|
+
it('${e.name}-list', async () => {
|
|
413
429
|
const seneca = await makeSeneca()
|
|
414
|
-
const list = await seneca.entity('provider/${provider.lower}/${
|
|
430
|
+
const list = await seneca.entity('provider/${provider.lower}/${e.name}').list$()
|
|
415
431
|
|
|
416
432
|
assert.equal(list.length, 2)
|
|
417
433
|
|
|
@@ -420,25 +436,25 @@ describe('${provider.fileBase}', () => {
|
|
|
420
436
|
// survive into the Seneca entity.
|
|
421
437
|
assert.equal(
|
|
422
438
|
list[0].canon$({ string: true }),
|
|
423
|
-
'provider/${provider.lower}/${
|
|
439
|
+
'provider/${provider.lower}/${e.name}',
|
|
424
440
|
)
|
|
425
441
|
})
|
|
426
442
|
|
|
427
443
|
`)
|
|
428
|
-
|
|
444
|
+
}
|
|
429
445
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
it('${
|
|
446
|
+
if (e.cmds.includes('load')) {
|
|
447
|
+
Content(`
|
|
448
|
+
it('${e.name}-load', async () => {
|
|
433
449
|
const seneca = await makeSeneca()
|
|
434
450
|
const found = await seneca
|
|
435
|
-
.entity('provider/${provider.lower}/${
|
|
436
|
-
.load$('${
|
|
451
|
+
.entity('provider/${provider.lower}/${e.name}')
|
|
452
|
+
.load$('${e.name}0')
|
|
437
453
|
|
|
438
|
-
assert.equal(found.${
|
|
454
|
+
assert.equal(found.${e.idf || 'id'}, '${e.name}0')
|
|
439
455
|
assert.equal(
|
|
440
456
|
found.canon$({ string: true }),
|
|
441
|
-
'provider/${provider.lower}/${
|
|
457
|
+
'provider/${provider.lower}/${e.name}',
|
|
442
458
|
)
|
|
443
459
|
})
|
|
444
460
|
|
|
@@ -446,17 +462,18 @@ describe('${provider.fileBase}', () => {
|
|
|
446
462
|
// A 404 from a single-item read is an ordinary "not found" answer, not a
|
|
447
463
|
// failure: the provider turns it into null rather than letting the SDK
|
|
448
464
|
// throw.
|
|
449
|
-
it('${
|
|
465
|
+
it('${e.name}-load-missing', async () => {
|
|
450
466
|
const seneca = await makeSeneca()
|
|
451
467
|
const missing = await seneca
|
|
452
|
-
.entity('provider/${provider.lower}/${
|
|
453
|
-
.load$('nosuch${
|
|
468
|
+
.entity('provider/${provider.lower}/${e.name}')
|
|
469
|
+
.load$('nosuch${e.name}')
|
|
454
470
|
|
|
455
471
|
assert.equal(missing, null)
|
|
456
472
|
})
|
|
457
473
|
|
|
458
474
|
`)
|
|
459
|
-
|
|
475
|
+
}
|
|
476
|
+
})
|
|
460
477
|
|
|
461
478
|
// A nested entity cannot build its path without the parent id. That is
|
|
462
479
|
// the mistake this target exists to make impossible, so pin it.
|
|
@@ -469,17 +486,31 @@ describe('${provider.fileBase}', () => {
|
|
|
469
486
|
const pairs = e.parents
|
|
470
487
|
.map((k: string) => `${k}: '${parentSeed(e, k)}'`).join(', ')
|
|
471
488
|
|
|
472
|
-
|
|
489
|
+
// The guard is PER OP (Main's opParents), not a blanket property of
|
|
490
|
+
// the entity, so the op this test calls has to be one that actually
|
|
491
|
+
// requires `key` — hardcoding `list` assumed every nested entity's
|
|
492
|
+
// list is parent-scoped, which fails for e.g. an entity guarded on
|
|
493
|
+
// load/update/remove but whose list is unscoped (GitHub's `repo`:
|
|
494
|
+
// owner guards load, not list).
|
|
495
|
+
const guardOp = ['list', 'load', 'update', 'remove']
|
|
496
|
+
.find((op: string) => (e.opParents[op] || []).includes(key))
|
|
497
|
+
|
|
498
|
+
if (null != guardOp) {
|
|
499
|
+
const call = 'list' === guardOp ?
|
|
500
|
+
`${guardOp}$({})` : `${guardOp}$({ id: '${e.name}0' })`
|
|
501
|
+
|
|
502
|
+
Content(`
|
|
473
503
|
it('${e.name}-needs-${key}', async () => {
|
|
474
504
|
const seneca = await makeSeneca()
|
|
475
505
|
|
|
476
506
|
await assert.rejects(
|
|
477
|
-
() => seneca.entity('provider/${provider.lower}/${e.name}')
|
|
507
|
+
() => seneca.entity('provider/${provider.lower}/${e.name}').${call},
|
|
478
508
|
/${key} is required/,
|
|
479
509
|
)
|
|
480
510
|
})
|
|
481
511
|
|
|
482
512
|
`)
|
|
513
|
+
}
|
|
483
514
|
if (e.cmds.includes('list')) {
|
|
484
515
|
// Assert on the SEEDED RECORDS, not merely that an array came back.
|
|
485
516
|
// `Array.isArray` is true of the empty array, so the nested-list
|
|
@@ -4024,4 +4055,6 @@ export {
|
|
|
4024
4055
|
Workflow,
|
|
4025
4056
|
Readme,
|
|
4026
4057
|
Docs,
|
|
4058
|
+
seedRecord,
|
|
4059
|
+
parentSeed,
|
|
4027
4060
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
cmp, each,
|
|
3
3
|
File, Content, Copy, Folder,
|
|
4
4
|
entityCollection, entityOps, entityIdField, entityClassName,
|
|
5
|
-
opRequestShape, opParams, entityPath,
|
|
5
|
+
opRequestShape, opParams, ownPoint, entityPath,
|
|
6
6
|
collectDeps, repoInfo, packageName, packageVersion, apiName, envName,
|
|
7
7
|
authorInfo, contributorList, isAuthActive, jsKey, jsProp,
|
|
8
8
|
SdkGenError,
|
|
@@ -74,12 +74,19 @@ function requiredKeys(ent: any, opname: string): string[] {
|
|
|
74
74
|
// `<entity>_id` path param to `id` besides, which is why most APIs never reach
|
|
75
75
|
// the fallback.
|
|
76
76
|
//
|
|
77
|
-
// When it does NOT answer, the record key is the LAST
|
|
78
|
-
//
|
|
79
|
-
// construction. Without this the key was simply unknown,
|
|
80
|
-
// `code` failed the `!== idf` test in opParentKeys and
|
|
81
|
-
// PARENT — `load$('SAVE20')` threw "coupon load: code
|
|
82
|
-
// loading anything, and the entity was treated as
|
|
77
|
+
// When it does NOT answer, the record key is the LAST path param of the
|
|
78
|
+
// op's own point, in PATH order — a route addresses parents first and the
|
|
79
|
+
// record last, by construction. Without this the key was simply unknown,
|
|
80
|
+
// so a param named `code` failed the `!== idf` test in opParentKeys and
|
|
81
|
+
// was classified as a PARENT — `load$('SAVE20')` threw "coupon load: code
|
|
82
|
+
// is required" instead of loading anything, and the entity was treated as
|
|
83
|
+
// nested throughout.
|
|
84
|
+
//
|
|
85
|
+
// opParams(op) is NOT the source here: it alphabetizes params for output
|
|
86
|
+
// stability, which loses path order on a 3+-param route — Airtable's
|
|
87
|
+
// record (base_id, table_id, record_id) alphabetizes with table_id last,
|
|
88
|
+
// so the old `params[params.length - 1]` picked the wrong parent as the
|
|
89
|
+
// record's own key. The point's own `parts` still has the true order.
|
|
83
90
|
function recordKey(ent: any): string {
|
|
84
91
|
const idf = entityIdField(ent)
|
|
85
92
|
if (null != idf && '' !== idf) {
|
|
@@ -88,13 +95,18 @@ function recordKey(ent: any): string {
|
|
|
88
95
|
|
|
89
96
|
for (const opname of ['load', 'remove', 'update']) {
|
|
90
97
|
const op = (ent.op || {})[opname]
|
|
91
|
-
if (null == op) {
|
|
98
|
+
if (null == op || 0 === (op.points || []).length) {
|
|
92
99
|
continue
|
|
93
100
|
}
|
|
94
101
|
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
const canonical = op.points.filter((pt: any) =>
|
|
103
|
+
null == (pt && pt.select && pt.select['$action']))
|
|
104
|
+
const point = ownPoint(0 < canonical.length ? canonical : op.points)
|
|
105
|
+
const parts: string[] = (point && point.parts) || []
|
|
106
|
+
const lastParam = [...parts].reverse().find((p: string) => p.startsWith('{'))
|
|
107
|
+
|
|
108
|
+
if (null != lastParam) {
|
|
109
|
+
return lastParam.slice(1, -1)
|
|
98
110
|
}
|
|
99
111
|
}
|
|
100
112
|
|
|
@@ -966,4 +978,5 @@ if ('undefined' !== typeof module) {
|
|
|
966
978
|
|
|
967
979
|
export {
|
|
968
980
|
Main,
|
|
981
|
+
recordKey,
|
|
969
982
|
}
|
|
@@ -153,6 +153,92 @@ function unwrapListData(data: any): any[] | null {
|
|
|
153
153
|
})
|
|
154
154
|
|
|
155
155
|
|
|
156
|
+
// GraphQL-backed op: a REST-shaped direct() call (GET, params in the URL)
|
|
157
|
+
// cannot reach it — every op, including list, synthesizes POST with the
|
|
158
|
+
// query/variables as a JSON body, not URL params (see
|
|
159
|
+
// MakeFetchDefUtility: spec.body only ever comes from an explicit `body`
|
|
160
|
+
// field, never derived from `params`). apidef already built a real, valid
|
|
161
|
+
// query or mutation document per point (point.graphql.doc, with variables
|
|
162
|
+
// declared to match), so reuse that verbatim through the SDK's own
|
|
163
|
+
// graphql() escape hatch instead of re-deriving a REST-shaped call that
|
|
164
|
+
// cannot represent one.
|
|
165
|
+
function generateDirectGraphql(
|
|
166
|
+
opname: 'load' | 'list',
|
|
167
|
+
entity: ModelEntity,
|
|
168
|
+
point: any,
|
|
169
|
+
strict: boolean,
|
|
170
|
+
) {
|
|
171
|
+
const doc: string = point.graphql.doc
|
|
172
|
+
const vars: any[] = point.graphql.vars || []
|
|
173
|
+
|
|
174
|
+
const varLine = (target: string, key: string, v: any) =>
|
|
175
|
+
` ${target}[${JSON.stringify(v.name)}] = ${key}`
|
|
176
|
+
|
|
177
|
+
const mockVarLines = vars.map((v: any, i: number) =>
|
|
178
|
+
varLine('variables', `'direct0${i + 1}'`, v)).join('\n')
|
|
179
|
+
|
|
180
|
+
const liveVarLines = vars.map((v: any) => {
|
|
181
|
+
const from = v.from || v.name
|
|
182
|
+
const key = ('id' === from ? entity.name : from.replace(/_id$/, '')) + '01'
|
|
183
|
+
return varLine('variables', `setup.idmap['${key}']`, v)
|
|
184
|
+
}).join('\n')
|
|
185
|
+
|
|
186
|
+
const liveIdKeys = vars.map((v: any) => {
|
|
187
|
+
const from = v.from || v.name
|
|
188
|
+
return ('id' === from ? entity.name : from.replace(/_id$/, '')) + '01'
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
const skipMissingLine = 0 < liveIdKeys.length
|
|
192
|
+
? ` if (skipIfMissingIds(t, setup, ${JSON.stringify(liveIdKeys)})) return\n`
|
|
193
|
+
: ''
|
|
194
|
+
|
|
195
|
+
// Asserted against the OUTGOING request body (what we sent), not the
|
|
196
|
+
// mocked response — response-shape correctness is the entity-level
|
|
197
|
+
// load/list tests' job; direct/graphql only has to prove the raw path
|
|
198
|
+
// reaches the endpoint with the right method and payload.
|
|
199
|
+
const varAsserts = vars.map((_v: any, i: number) =>
|
|
200
|
+
' assert(calls[0].init.body.includes(\'direct0' + (i + 1) + '\'))\n').join('')
|
|
201
|
+
|
|
202
|
+
const offlineChecks = ` assert(result.ok === true)
|
|
203
|
+
assert(result.status === 200)
|
|
204
|
+
assert(null != result.data)
|
|
205
|
+
assert(calls.length === 1)
|
|
206
|
+
assert(calls[0].init.method === 'POST')
|
|
207
|
+
${varAsserts}`
|
|
208
|
+
|
|
209
|
+
const checks = strict ?
|
|
210
|
+
offlineChecks.replace(/^ {6}/gm, ' ').replace(/^ {4}$/gm, '') :
|
|
211
|
+
` if (setup.live) {
|
|
212
|
+
// Live mode is lenient: synthetic ids frequently fail server-side
|
|
213
|
+
// validation. Skip rather than fail when the call doesn't come back
|
|
214
|
+
// clean.
|
|
215
|
+
if (!result.ok || result.status < 200 || result.status >= 300) {
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
${offlineChecks} }`
|
|
220
|
+
|
|
221
|
+
Content(`
|
|
222
|
+
test('direct-${opname}-${entity.name}', async (t: any) => {
|
|
223
|
+
const setup = directSetup()
|
|
224
|
+
if (maybeSkipControl(t, 'direct', 'direct-${opname}-${entity.name}', setup.live)) return
|
|
225
|
+
${skipMissingLine} const { client, calls } = setup
|
|
226
|
+
|
|
227
|
+
const variables: any = {}
|
|
228
|
+
if (setup.live) {
|
|
229
|
+
${liveVarLines || ' // no variables'}
|
|
230
|
+
} else {
|
|
231
|
+
${mockVarLines || ' // no variables'}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const result: any = await client.graphql(${JSON.stringify(doc)}, variables)
|
|
235
|
+
|
|
236
|
+
${checks}
|
|
237
|
+
})
|
|
238
|
+
`)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
156
242
|
function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean) {
|
|
157
243
|
const loadOp = entity.op?.load
|
|
158
244
|
const loadPoint: ModelPoint | undefined = loadOp?.points?.[0]
|
|
@@ -161,6 +247,11 @@ function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
161
247
|
return
|
|
162
248
|
}
|
|
163
249
|
|
|
250
|
+
if ('graphql' === (loadPoint as any).kind) {
|
|
251
|
+
generateDirectGraphql('load', entity, loadPoint, strict)
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
|
|
164
255
|
const allLoadParams = loadPoint.args?.params || []
|
|
165
256
|
const loadPath = normalizePathParams(loadPoint.parts || [], allLoadParams, loadPoint.rename?.param)
|
|
166
257
|
|
|
@@ -377,6 +468,11 @@ function generateDirectList(model: Model, entity: ModelEntity, strict: boolean)
|
|
|
377
468
|
return
|
|
378
469
|
}
|
|
379
470
|
|
|
471
|
+
if ('graphql' === (listPoint as any).kind) {
|
|
472
|
+
generateDirectGraphql('list', entity, listPoint, strict)
|
|
473
|
+
return
|
|
474
|
+
}
|
|
475
|
+
|
|
380
476
|
const listParams = listPoint.args?.params || []
|
|
381
477
|
const listPath = normalizePathParams(listPoint.parts || [], listParams, listPoint.rename?.param)
|
|
382
478
|
|
|
@@ -8,6 +8,35 @@ import { BaseFeature } from '../base/BaseFeature'
|
|
|
8
8
|
const S_NOT_FOUND = 'Not found'
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
// Which param is entity X's own identifier, as opposed to a parent key —
|
|
12
|
+
// the load op's canonical point's LAST path segment, by construction (a
|
|
13
|
+
// route addresses parents first, the record last). Mirrors recordKey in
|
|
14
|
+
// sdkgen's Main_seneca-provider.ts; written again here because a template
|
|
15
|
+
// ships standalone, outside that package. A renamed id (e.g. Airtable's
|
|
16
|
+
// record_id) needs its own seeded field: matching only ever happens
|
|
17
|
+
// against the API's real param names, never a bare 'id' the API itself
|
|
18
|
+
// does not use.
|
|
19
|
+
function ownIdField(config: any, getpath: any, entityName: string): string {
|
|
20
|
+
for (const opname of ['load', 'remove', 'update']) {
|
|
21
|
+
const points = getpath(config, ['entity', entityName, 'op', opname, 'points']) || []
|
|
22
|
+
const canonical = points.filter((pt: any) =>
|
|
23
|
+
null == (pt && pt.select && pt.select['$action']))
|
|
24
|
+
const use = 0 < canonical.length ? canonical : points
|
|
25
|
+
let best = use[0]
|
|
26
|
+
for (const pt of use) {
|
|
27
|
+
if (null == pt || null == pt.parts || null == best || null == best.parts) continue
|
|
28
|
+
const ptterm = 0 < pt.parts.length && String(pt.parts[pt.parts.length - 1]).startsWith('{')
|
|
29
|
+
const bestterm = 0 < best.parts.length && String(best.parts[best.parts.length - 1]).startsWith('{')
|
|
30
|
+
if (ptterm !== bestterm ? ptterm : pt.parts.length < best.parts.length) best = pt
|
|
31
|
+
}
|
|
32
|
+
const parts: string[] = (best && best.parts) || []
|
|
33
|
+
const last = [...parts].reverse().find((p: string) => p.startsWith('{'))
|
|
34
|
+
if (null != last) return last.slice(1, -1)
|
|
35
|
+
}
|
|
36
|
+
return 'id'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
11
40
|
class TestFeature extends BaseFeature {
|
|
12
41
|
version = '0.0.1'
|
|
13
42
|
name = 'test'
|
|
@@ -30,10 +59,16 @@ class TestFeature extends BaseFeature {
|
|
|
30
59
|
|
|
31
60
|
this._client._mode = 'test'
|
|
32
61
|
|
|
62
|
+
const getpath = struct.getpath
|
|
63
|
+
|
|
33
64
|
// Ensure entity ids are correct.
|
|
34
65
|
walk(entity, (k: any, v: any, _parent: any, path: any) => {
|
|
35
66
|
if (2 === size(path)) {
|
|
36
67
|
setprop(v, 'id', k)
|
|
68
|
+
const idField = ownIdField(ctx.config, getpath, String(path[0]))
|
|
69
|
+
if ('id' !== idField) {
|
|
70
|
+
setprop(v, idField, k)
|
|
71
|
+
}
|
|
37
72
|
}
|
|
38
73
|
return v
|
|
39
74
|
})
|
|
@@ -172,6 +207,16 @@ class TestFeature extends BaseFeature {
|
|
|
172
207
|
|
|
173
208
|
const ent = clone(ctx.reqdata)
|
|
174
209
|
setprop(ent, 'id', id)
|
|
210
|
+
|
|
211
|
+
// A record created during the run needs the same real-key seeding
|
|
212
|
+
// the initial walk gives seed data (see ownIdField above) — without
|
|
213
|
+
// it, only `id` is set, and a load by the entity's own key right
|
|
214
|
+
// after create (recordKey !== 'id') finds nothing.
|
|
215
|
+
const idField = ownIdField(ctx.config, struct.getpath, getprop(op, 'entity'))
|
|
216
|
+
if ('id' !== idField && null == getprop(ent, idField)) {
|
|
217
|
+
setprop(ent, idField, id)
|
|
218
|
+
}
|
|
219
|
+
|
|
175
220
|
setprop(entmap, id, ent)
|
|
176
221
|
delprop(ent, '$KEY')
|
|
177
222
|
const out = clone(ent)
|
|
@@ -310,7 +355,8 @@ class TestFeature extends BaseFeature {
|
|
|
310
355
|
|
|
311
356
|
|
|
312
357
|
export {
|
|
313
|
-
TestFeature
|
|
358
|
+
TestFeature,
|
|
359
|
+
ownIdField,
|
|
314
360
|
}
|
|
315
361
|
|
|
316
362
|
|
package/src/helpers/opShape.ts
CHANGED
package/src/sdkgen.ts
CHANGED
|
@@ -58,7 +58,7 @@ import { getMatchEntries } from './helpers/getMatchEntries'
|
|
|
58
58
|
import { collectDeps } from './helpers/collectDeps'
|
|
59
59
|
import type { DepEntry } from './helpers/collectDeps'
|
|
60
60
|
import { canonToType, canonToDtype, canonKey } from './helpers/canonType'
|
|
61
|
-
import { OP_SUFFIX, opTypeName, opParams, opActions, entityActions, entityPath, opRequestShape, entityIdField, entityDataIdField, entityOps, entityPrimaryOp, pickExampleEntity, entityClassName, entityTypeCollisions, warnEntityTypeCollisions, deriveEntityNames, entityCollection } from './helpers/opShape'
|
|
61
|
+
import { OP_SUFFIX, opTypeName, opParams, ownPoint, opActions, entityActions, entityPath, opRequestShape, entityIdField, entityDataIdField, entityOps, entityPrimaryOp, pickExampleEntity, entityClassName, entityTypeCollisions, warnEntityTypeCollisions, deriveEntityNames, entityCollection } from './helpers/opShape'
|
|
62
62
|
import { isReservedName, safeVarName, exampleVarName, phpEntityAccessor, entityCacheField, isRbCoreConstant, isRbSdkConstant, rbSafeTypeName, isSwiftSdkType, swiftSafeTypeName, isPhpReservedType, phpSafeTypeName, isTsReservedType, tsSafeTypeName, jsProp, jsOptProp, jsKey } from './helpers/naming'
|
|
63
63
|
import { serverVariables, hasServerVariables } from './helpers/serverVars'
|
|
64
64
|
import { primaryOpCall, idLiteral, matchArg, dataArg, litFor } from './helpers/opExample'
|
|
@@ -1063,6 +1063,7 @@ export {
|
|
|
1063
1063
|
OP_SUFFIX,
|
|
1064
1064
|
opTypeName,
|
|
1065
1065
|
opParams,
|
|
1066
|
+
ownPoint,
|
|
1066
1067
|
opActions,
|
|
1067
1068
|
entityActions,
|
|
1068
1069
|
entityPath,
|