@voxgig/apidef 8.13.0 → 8.15.0

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 (67) hide show
  1. package/bin/voxgig-apidef +1 -174
  2. package/dist/apidef.d.ts +2 -2
  3. package/dist/apidef.js +2 -2
  4. package/dist/apidef.js.map +1 -1
  5. package/dist/builder/entity/entity.d.ts +5 -1
  6. package/dist/builder/entity/entity.js +17 -1
  7. package/dist/builder/entity/entity.js.map +1 -1
  8. package/dist/builder/flow/flowHeuristic01.js +14 -14
  9. package/dist/builder/flow/flowHeuristic01.js.map +1 -1
  10. package/dist/cli.d.ts +38 -0
  11. package/dist/cli.js +279 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/guide/guide.js +8 -5
  14. package/dist/guide/guide.js.map +1 -1
  15. package/dist/model.d.ts +35 -33
  16. package/dist/resolved.d.ts +10 -6
  17. package/dist/resolved.js +65 -15
  18. package/dist/resolved.js.map +1 -1
  19. package/dist/transform/args.js +19 -19
  20. package/dist/transform/args.js.map +1 -1
  21. package/dist/transform/clean.js +4 -0
  22. package/dist/transform/clean.js.map +1 -1
  23. package/dist/transform/contract.d.ts +0 -2
  24. package/dist/transform/contract.js +6 -75
  25. package/dist/transform/contract.js.map +1 -1
  26. package/dist/transform/entity.d.ts +2 -1
  27. package/dist/transform/entity.js +13 -1
  28. package/dist/transform/entity.js.map +1 -1
  29. package/dist/transform/field.js +64 -64
  30. package/dist/transform/field.js.map +1 -1
  31. package/dist/transform/flowstep.js +42 -42
  32. package/dist/transform/flowstep.js.map +1 -1
  33. package/dist/transform/graphql.js +8 -8
  34. package/dist/transform/graphql.js.map +1 -1
  35. package/dist/transform/operation.js +9 -9
  36. package/dist/transform/operation.js.map +1 -1
  37. package/dist/transform/select.js +13 -13
  38. package/dist/transform/select.js.map +1 -1
  39. package/dist/transform/top.js +1 -1
  40. package/dist/transform/top.js.map +1 -1
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/dist/types.d.ts +1 -1
  43. package/dist/utility.d.ts +2 -1
  44. package/dist/utility.js +6 -1
  45. package/dist/utility.js.map +1 -1
  46. package/model/apidef.aon +128 -157
  47. package/model/guide.aon +3 -2
  48. package/package.json +5 -3
  49. package/src/apidef.ts +4 -3
  50. package/src/builder/entity/entity.ts +18 -1
  51. package/src/builder/flow/flowHeuristic01.ts +14 -14
  52. package/src/cli.ts +341 -0
  53. package/src/guide/guide.ts +8 -4
  54. package/src/model.ts +36 -37
  55. package/src/resolved.ts +62 -17
  56. package/src/transform/args.ts +20 -20
  57. package/src/transform/clean.ts +5 -0
  58. package/src/transform/contract.ts +6 -71
  59. package/src/transform/entity.ts +13 -1
  60. package/src/transform/field.ts +66 -69
  61. package/src/transform/flowstep.ts +42 -42
  62. package/src/transform/graphql.ts +8 -8
  63. package/src/transform/operation.ts +9 -9
  64. package/src/transform/select.ts +13 -13
  65. package/src/transform/top.ts +1 -1
  66. package/src/types.ts +1 -1
  67. package/src/utility.ts +8 -1
@@ -7,7 +7,7 @@ import type { TransformResult, Transform } from '../transform'
7
7
  import {
8
8
  validator, canonizeField, inferFieldType, normalizeFieldName, envelopeProp,
9
9
  canonizeCmpName,
10
- scanUntaggedUnion, firstSentence,
10
+ scanUntaggedUnion, firstSentence, humanTitle,
11
11
  } from '../utility'
12
12
 
13
13
  import { KIT } from '../types'
@@ -42,7 +42,6 @@ const fieldTransform: Transform = async function(
42
42
 
43
43
  each(kit.entity, (ment: ModelEntity, _entname: string) => {
44
44
  const fields = ment.fields
45
- const seen: any = {}
46
45
 
47
46
  for (let opname of opFieldPrecedence) {
48
47
  const mop = ment.op[opname]
@@ -53,70 +52,63 @@ const fieldTransform: Transform = async function(
53
52
  const opfields = resolveOpFields(ment, mop, mpoint, def)
54
53
 
55
54
  for (let opfield of opfields) {
56
- if (!seen[opfield.name]) {
57
- fields.push(opfield)
58
- seen[opfield.name] = opfield
55
+ if (!Object.prototype.hasOwnProperty.call(fields, opfield.n)) {
56
+ fields[opfield.n] = opfield
59
57
  }
60
58
  else {
61
- mergeField(mop, seen[opfield.name], opfield)
59
+ mergeField(mop, fields[opfield.n], opfield)
62
60
  }
63
61
  }
64
62
  }
65
63
  }
66
64
  }
67
65
 
68
- fields.sort((a: ModelField, b: ModelField) => {
69
- return a.name < b.name ? -1 : a.name > b.name ? 1 : 0
70
- })
71
66
 
72
67
  const gent = guide?.entity?.[ment.name]
73
68
  const composite = compositeId(ment, gent, def)
74
69
 
75
- const idField = fields.find((f: ModelField) => 'id' === f.name)
70
+ const idField = fields.id
76
71
 
77
72
  if (null != composite.parts && null != idField && !scalarStringField(idField)) {
78
73
  const idf: any = idField
79
74
  const apiname = String((model as any)?.name || 'api')
80
75
  const keep = apiname + '_id'
81
76
 
82
- if (!fields.some((f: ModelField) => f.name === keep)) {
77
+ if (!Object.prototype.hasOwnProperty.call(fields, keep)) {
83
78
  // A DEEP COPY, because the move is followed by deletions on the
84
79
  // original. A spread shares the `op` object, so clearing the stale
85
80
  // per-op `type` off `id` cleared it off the preserved field too —
86
81
  // the preservation preserved nothing for exactly the key it was
87
82
  // added to keep.
88
- fields.push(JSON.parse(JSON.stringify({ ...idf, name: keep })) as any)
83
+ fields[keep] = JSON.parse(JSON.stringify({ ...idf, n: keep }))
89
84
 
90
85
  const alias = ((ment as any).alias = (ment as any).alias || {})
91
86
  alias.field = alias.field || {}
92
87
  alias.field[keep] = 'id'
93
88
  }
94
89
 
95
- idf.type = '`$STRING`'
96
- // The facts that described the moved type go with it: `format: int64`
90
+ idf.t = '`$STRING`'
91
+ // The facts that described the moved type go with it: `fo: int64`
97
92
  // beside a string, or a per-op `type` override still saying integer,
98
93
  // is a model contradicting itself — and the op override is what a
99
94
  // generator reads for that op.
100
- delete idf.format
95
+ delete idf.fo
101
96
  for (const opname of Object.keys(idf.op || {})) {
102
97
  delete idf.op[opname].type
103
98
  }
104
99
 
105
- fields.sort((a: ModelField, b: ModelField) =>
106
- a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
107
100
  }
108
101
 
109
102
  if (null != composite.parts && null == idField) {
110
103
  // The FIELD as well as the descriptor, for the reason the branch below
111
104
  // documents: a model that declares the descriptor without the field
112
105
  // makes the generated type disagree with the generated test.
113
- fields.push({
114
- name: 'id',
115
- type: '`$STRING`',
116
- req: false,
117
- } as any)
118
- fields.sort((a: ModelField, b: ModelField) =>
119
- a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
106
+ fields.id = {
107
+ n: 'id',
108
+ h: humanTitle('id'),
109
+ t: '`$STRING`',
110
+ r: false,
111
+ } as ModelField
120
112
  }
121
113
 
122
114
  const singleKey = (composite as any).single
@@ -126,30 +118,34 @@ const fieldTransform: Transform = async function(
126
118
  // The guide disabled composite; the terminal parameter is the key, and
127
119
  // the entity needs the field to carry it for the same reason the
128
120
  // composite branch above does.
129
- fields.push({
130
- name: 'id',
131
- type: '`$STRING`',
132
- req: false,
133
- } as any)
134
- fields.sort((a: ModelField, b: ModelField) =>
135
- a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
121
+ fields.id = {
122
+ n: 'id',
123
+ h: humanTitle('id'),
124
+ t: '`$STRING`',
125
+ r: false,
126
+ } as ModelField
136
127
  }
137
128
 
138
129
  if (idField || null != composite.parts || null != singleKey) {
139
130
  ment.id = { name: 'id', field: 'id', ...composite }
140
131
  }
141
132
  else if (addressedById(ment)) {
142
- fields.push({
143
- name: 'id',
144
- type: '`$STRING`',
145
- req: false,
146
- } as any)
147
- fields.sort((a: ModelField, b: ModelField) =>
148
- a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
133
+ fields.id = {
134
+ n: 'id',
135
+ h: humanTitle('id'),
136
+ t: '`$STRING`',
137
+ r: false,
138
+ } as ModelField
149
139
 
150
140
  ment.id = { name: 'id', field: 'id', ...composite }
151
141
  }
152
142
 
143
+ ment.fields = Object.fromEntries(Object.keys(fields).sort().map(n => {
144
+ const field = fields[n]
145
+ field.h = humanTitle(field.n)
146
+ return [n, field]
147
+ }))
148
+
153
149
  msg += ment.name + ' '
154
150
  })
155
151
 
@@ -174,7 +170,7 @@ const ID_OPS = ['load', 'update', 'patch', 'remove']
174
170
 
175
171
 
176
172
  function trailingVars(point: any): string[] {
177
- const segs = ((point?.segments || []) as any[]).filter((s: any) => null != s)
173
+ const segs = ((point?.s || []) as any[]).filter((s: any) => null != s)
178
174
  const run: string[] = []
179
175
 
180
176
  for (let i = segs.length - 1; 0 <= i; i--) {
@@ -199,7 +195,7 @@ function identityParams(ment: ModelEntity): string[] {
199
195
 
200
196
  // Action points are verbs dispatched by `$action`, not addresses.
201
197
  for (const pt of (mop.points || [])) {
202
- if (null != pt?.select?.['$action']) {
198
+ if (null != pt?.q?.['$action']) {
203
199
  continue
204
200
  }
205
201
  const run = trailingVars(pt)
@@ -209,7 +205,7 @@ function identityParams(ment: ModelEntity): string[] {
209
205
  cands.push({
210
206
  run,
211
207
  // Segments BEFORE the run: how much parent scope the route needs.
212
- scope: ((pt.segments || []).length - run.length),
208
+ scope: ((pt.s || []).length - run.length),
213
209
  own: 'id' === run[run.length - 1] ||
214
210
  (ment as any).name + '_id' === run[run.length - 1],
215
211
  order: o,
@@ -289,12 +285,12 @@ function responseCandidates(ment: ModelEntity, def: any): any[] {
289
285
 
290
286
  for (const mpoint of (mop?.points || [])) {
291
287
  // An action point's response is not the entity.
292
- if (null != mpoint?.select?.['$action']) {
288
+ if (null != mpoint?.q?.['$action']) {
293
289
  continue
294
290
  }
295
291
 
296
- const path = (def?.paths || {})[mpoint?.orig]
297
- const method = String(mpoint?.method || '').toLowerCase()
292
+ const path = (def?.paths || {})[mpoint?.o]
293
+ const method = String(mpoint?.m || '').toLowerCase()
298
294
  const responses = path?.[method]?.responses || {}
299
295
 
300
296
  for (const code of Object.keys(responses)) {
@@ -384,15 +380,15 @@ function partAliases(ment: ModelEntity, part: string): string[] {
384
380
 
385
381
  each((ment as any).op, (mop: any) => {
386
382
  each(mop?.points, (mpoint: any) => {
387
- const rename = mpoint?.rename?.param || {}
383
+ const rename = mpoint?.r?.param || {}
388
384
  for (const orig of Object.keys(rename)) {
389
385
  if (String(rename[orig]) === part) {
390
386
  names.add(orig)
391
387
  }
392
388
  }
393
- for (const arg of (mpoint?.args?.params || [])) {
394
- if (null != arg && arg.name === part && null != arg.orig) {
395
- names.add(String(arg.orig))
389
+ for (const arg of (mpoint?.g?.params || [])) {
390
+ if (null != arg && arg.n === part && null != arg.or) {
391
+ names.add(String(arg.or))
396
392
  }
397
393
  }
398
394
  })
@@ -482,7 +478,7 @@ function identityFrom(
482
478
  // Is this model field declared as a string? A composite id is the parts
483
479
  // joined, so the field that holds it has to be one.
484
480
  function scalarStringField(f: any): boolean {
485
- return String(f?.type || '').toUpperCase().includes('STRING')
481
+ return String(f?.t || '').toUpperCase().includes('STRING')
486
482
  }
487
483
 
488
484
 
@@ -552,8 +548,8 @@ function addressedById(ment: ModelEntity): boolean {
552
548
  let found = false
553
549
  each((ment as any).op, (mop: any) => {
554
550
  each(mop?.points, (mpoint: any) => {
555
- each(mpoint?.args?.params, (param: any) => {
556
- if (param && 'id' === param.name) {
551
+ each(mpoint?.g?.params, (param: any) => {
552
+ if (param && 'id' === param.n) {
557
553
  found = true
558
554
  }
559
555
  })
@@ -579,22 +575,23 @@ function resolveOpFields(
579
575
  // items -> item, so the SDK read keys the server never sends.
580
576
  const name = canonizeField(normalizeFieldName(fieldname))
581
577
  const mfield: ModelField = {
582
- name,
583
- type: inferFieldType(name, validator(fielddef.type)),
584
- req: !!fielddef.required,
578
+ n: name,
579
+ h: humanTitle(name),
580
+ t: inferFieldType(name, validator(fielddef.type)),
581
+ r: !!fielddef.required,
585
582
  op: {},
586
583
  }
587
584
  const fdesc = (fielddef as any).description
588
585
  if ('string' === typeof fdesc && '' !== fdesc.trim()) {
589
586
  const short = firstSentence(fdesc)
590
587
  if ('' !== short) {
591
- mfield.short = short
588
+ mfield.sh = short
592
589
  }
593
590
  }
594
591
 
595
- for (const flag of ['readOnly', 'writeOnly', 'deprecated'] as const) {
592
+ for (const [flag, attr] of [['readOnly', 'ro'], ['writeOnly', 'wo'], ['deprecated', 'de']] as const) {
596
593
  if (true === (fielddef as any)[flag]) {
597
- mfield[flag] = true
594
+ mfield[attr] = true
598
595
  }
599
596
  }
600
597
 
@@ -603,7 +600,7 @@ function resolveOpFields(
603
600
  // interpreted here. `password` is the one a generator acts on today.
604
601
  const ffmt = (fielddef as any).format
605
602
  if ('string' === typeof ffmt && '' !== ffmt.trim()) {
606
- mfield.format = ffmt.trim()
603
+ mfield.fo = ffmt.trim()
607
604
  }
608
605
 
609
606
  // Record an untagged union under this field. The field is already typed
@@ -631,7 +628,7 @@ function findGraphqlFieldDefs(
631
628
  mpoint: ModelPoint,
632
629
  def: any
633
630
  ): SchemaDef[] {
634
- const typeName = (mpoint.graphql as any)?.entityType$ ??
631
+ const typeName = (mpoint.gq as any)?.entityType$ ??
635
632
  (ment as any).orig$ ?? ''
636
633
  const gtype = def.types?.[typeName]
637
634
 
@@ -698,18 +695,18 @@ function findFieldDefs(
698
695
  mpoint: ModelPoint,
699
696
  def: any
700
697
  ): SchemaDef[] {
701
- if ('graphql' === mpoint.kind) {
698
+ if ('graphql' === mpoint.k) {
702
699
  return findGraphqlFieldDefs(ment, mpoint, def)
703
700
  }
704
701
 
705
702
  // A verb, rather than an address: see the call site in the transform.
706
- const isAction = null != (mpoint as any)?.select?.['$action']
703
+ const isAction = null != (mpoint as any)?.q?.['$action']
707
704
 
708
705
  const fielddefs: SchemaDef[] = []
709
706
 
710
- const pathdef = def.paths[mpoint.orig]
707
+ const pathdef = def.paths[mpoint.o]
711
708
 
712
- const method = mpoint.method.toLowerCase()
709
+ const method = mpoint.m.toLowerCase()
713
710
  const opdef: any = (pathdef as any)?.[method]
714
711
 
715
712
  if (opdef) {
@@ -912,18 +909,18 @@ function mergeField(
912
909
  existingField: ModelField,
913
910
  newField: ModelField
914
911
  ) {
915
- if (newField.req !== existingField.req) {
912
+ if (newField.r !== existingField.r) {
916
913
  existingField.op[mop.name] = {
917
- req: newField.req,
918
- type: newField.type,
914
+ req: newField.r,
915
+ type: newField.t,
919
916
  }
920
917
  }
921
918
 
922
- if (null == existingField.short && null != newField.short) {
923
- existingField.short = newField.short
919
+ if (null == existingField.sh && null != newField.sh) {
920
+ existingField.sh = newField.sh
924
921
  }
925
922
 
926
- for (const flag of ['readOnly', 'writeOnly', 'deprecated', 'format'] as const) {
923
+ for (const flag of ['ro', 'wo', 'de', 'fo'] as const) {
927
924
  if (null == existingField[flag] && null != newField[flag]) {
928
925
  (existingField as any)[flag] = newField[flag]
929
926
  }
@@ -12,19 +12,19 @@ import {
12
12
 
13
13
 
14
14
  function isEntityIdParam(point: any, param: any, opname?: string): boolean {
15
- if ('id' === param?.name) return true
16
- const renameMap = point?.rename?.param
17
- if (renameMap && param?.name) {
18
- const camel = lcf(camelify(param.name))
15
+ if ('id' === param?.n) return true
16
+ const renameMap = point?.r?.param
17
+ if (renameMap && param?.n) {
18
+ const camel = lcf(camelify(param.n))
19
19
  if ('id' === renameMap[camel]) return true
20
20
  }
21
21
  if ('update' === opname || 'load' === opname || 'remove' === opname) {
22
- const segments: any[] = point?.segments || []
22
+ const segments: any[] = point?.s || []
23
23
  let last: string | null = null
24
24
  for (const s of segments) {
25
25
  if (null != s?.var) last = s.var
26
26
  }
27
- if (last && last === param?.name) return true
27
+ if (last && last === param?.n) return true
28
28
  }
29
29
  return false
30
30
  }
@@ -75,7 +75,7 @@ const flowstepTransform: Transform = async function(
75
75
  {
76
76
  input: {
77
77
  ref: ref01,
78
- textfield: firsttf?.name,
78
+ textfield: firsttf?.n,
79
79
  suffix: '_up0',
80
80
  srcdatavar: ref01 + '_data'
81
81
  },
@@ -126,12 +126,12 @@ type MakeFlowStep =
126
126
 
127
127
  function newFlowStep(opname: OpName, args: Record<string, any>): ModelEntityFlowStep {
128
128
  return {
129
- op: opname,
130
- input: args.input ?? {},
131
- match: args.match ?? {},
132
- data: args.data ?? {},
133
- spec: args.spec ?? [],
134
- valid: args.valid ?? [],
129
+ o: opname,
130
+ i: args.input ?? {},
131
+ m: args.match ?? {},
132
+ d: args.data ?? {},
133
+ s: args.spec ?? [],
134
+ v: args.valid ?? [],
135
135
  }
136
136
  }
137
137
 
@@ -142,7 +142,7 @@ function newFlowStep(opname: OpName, args: Record<string, any>): ModelEntityFlow
142
142
  // rename-to-id is recorded — the literal `id` then represents the entity's
143
143
  // own id and createStep should skip it.
144
144
  function originalSnakeNameOfRenamedId(point: any): string | null {
145
- const renameMap = point?.rename?.param || {}
145
+ const renameMap = point?.r?.param || {}
146
146
  for (const [src, dst] of Object.entries(renameMap)) {
147
147
  if ('id' === dst) {
148
148
  const srcStr = String(src)
@@ -165,17 +165,17 @@ const createStep: MakeFlowStep = (
165
165
  const point = getelem(opmap.create.points, -1)
166
166
  const step = newFlowStep('create', args)
167
167
 
168
- each(point.args.params, (param: any) => {
169
- if ('id' === param.name) {
168
+ each(point.g.params, (param: any) => {
169
+ if ('id' === param.n) {
170
170
  const origName = originalSnakeNameOfRenamedId(point)
171
171
  if (origName) {
172
- step.match[origName] = args.input?.[origName] ?? origName.replace(/_id/, '') + '01'
172
+ step.m[origName] = args.input?.[origName] ?? origName.replace(/_id/, '') + '01'
173
173
  }
174
174
  // If there's no rename-from, this is genuinely the entity's id — skip
175
175
  // (the create call generates it).
176
176
  return
177
177
  }
178
- step.match[param.name] = args.input?.[param.name] ?? param.name.replace(/_id/, '') + '01'
178
+ step.m[param.n] = args.input?.[param.n] ?? param.n.replace(/_id/, '') + '01'
179
179
  })
180
180
 
181
181
  seedRelatedOpParams(opmap, point, step)
@@ -191,14 +191,14 @@ function seedRelatedOpParams(opmap: any, createPoint: any, step: ModelEntityFlow
191
191
  const op = opmap[opname]
192
192
  if (!op?.points) continue
193
193
  for (const point of op.points) {
194
- const params: any[] = point?.args?.params || []
194
+ const params: any[] = point?.g?.params || []
195
195
  for (const param of params) {
196
- if (!param?.name) continue
196
+ if (!param?.n) continue
197
197
  if (isEntityIdParam(point, param, opname as any)) continue
198
- if (step.match[param.name] !== undefined) continue
199
- if ('id' === param.name) continue
200
- step.match[param.name] =
201
- param.name.replace(/_id/, '') + '01'
198
+ if (step.m[param.n] !== undefined) continue
199
+ if ('id' === param.n) continue
200
+ step.m[param.n] =
201
+ param.n.replace(/_id/, '') + '01'
202
202
  }
203
203
  }
204
204
  }
@@ -216,15 +216,15 @@ const listStep: MakeFlowStep = (
216
216
  const point = getelem(opmap.list.points, -1)
217
217
  const step = newFlowStep('list', args)
218
218
 
219
- each(point.args.params, (param: any) => {
220
- if ('id' === param.name) {
219
+ each(point.g.params, (param: any) => {
220
+ if ('id' === param.n) {
221
221
  const origName = originalSnakeNameOfRenamedId(point)
222
222
  if (origName) {
223
- step.match[origName] = args.input?.[origName] ?? origName.replace(/_id/, '') + '01'
223
+ step.m[origName] = args.input?.[origName] ?? origName.replace(/_id/, '') + '01'
224
224
  }
225
225
  return
226
226
  }
227
- step.match[param.name] = args.input?.[param.name] ?? param.name.replace(/_id/, '') + '01'
227
+ step.m[param.n] = args.input?.[param.n] ?? param.n.replace(/_id/, '') + '01'
228
228
  })
229
229
 
230
230
  flow.step.push(step)
@@ -243,13 +243,13 @@ const updateStep: MakeFlowStep = (
243
243
  const point = getelem(opmap.update.points, -1)
244
244
  const step = newFlowStep('update', args)
245
245
 
246
- each(point.args.params, (param: any) => {
246
+ each(point.g.params, (param: any) => {
247
247
  if (isEntityIdParam(point, param, 'update')) {
248
248
  // Entity's own id — supplied at test time via the loaded/created
249
249
  // entity's id field, not as a separate body parameter. Skip.
250
250
  return
251
251
  }
252
- step.data[param.name] = args.input?.[param.name] ?? param.name.replace(/_id/, '') + '01'
252
+ step.d[param.n] = args.input?.[param.n] ?? param.n.replace(/_id/, '') + '01'
253
253
  })
254
254
 
255
255
  flow.step.push(step)
@@ -268,12 +268,12 @@ const loadStep: MakeFlowStep = (
268
268
  const point = getelem(opmap.load.points, -1)
269
269
  const step = newFlowStep('load', args)
270
270
 
271
- each(point.args.params, (param: any) => {
271
+ each(point.g.params, (param: any) => {
272
272
  if (isEntityIdParam(point, param, 'load')) {
273
- step.match.id = args.input?.id ?? ent.name + '01'
273
+ step.m.id = args.input?.id ?? ent.name + '01'
274
274
  }
275
275
  else {
276
- step.match[param.name] = args.input?.[param.name] ?? param.name.replace(/_id/, '') + '01'
276
+ step.m[param.n] = args.input?.[param.n] ?? param.n.replace(/_id/, '') + '01'
277
277
  }
278
278
  })
279
279
 
@@ -297,12 +297,12 @@ const removeStep: MakeFlowStep = (
297
297
  const point = getelem(opmap.remove.points, -1)
298
298
  const step = newFlowStep('remove', args)
299
299
 
300
- each(point.args.params, (param: any) => {
300
+ each(point.g.params, (param: any) => {
301
301
  if (isEntityIdParam(point, param, 'remove')) {
302
- step.match.id = args.input?.id ?? ent.name + '01'
302
+ step.m.id = args.input?.id ?? ent.name + '01'
303
303
  }
304
304
  else {
305
- step.match[param.name] = args.input?.[param.name] ?? param.name.replace(/_id/, '') + '01'
305
+ step.m[param.n] = args.input?.[param.n] ?? param.n.replace(/_id/, '') + '01'
306
306
  }
307
307
  })
308
308
 
@@ -314,14 +314,14 @@ const removeStep: MakeFlowStep = (
314
314
  function firstTextField(ent: ModelEntity, op?: ModelOp) {
315
315
  const paramNames: Record<string, boolean> = {}
316
316
  each((op as any)?.points).forEach((pt: any) => {
317
- each(pt?.args?.params).forEach((p: any) => {
318
- if (p && null != p.name) {
319
- paramNames[p.name] = true
317
+ each(pt?.g?.params).forEach((p: any) => {
318
+ if (p && null != p.n) {
319
+ paramNames[p.n] = true
320
320
  }
321
321
  })
322
322
  })
323
323
 
324
- const fields = each(ent.fields)
324
+ const fields = Object.keys(ent.fields).sort().map(n => ent.fields[n])
325
325
  for (let fI = 0; fI < fields.length; fI++) {
326
326
  const field = fields[fI]
327
327
  // NOT A readOnly FIELD. The flow writes this one and then asserts the
@@ -329,8 +329,8 @@ function firstTextField(ent: ModelEntity, op?: ModelOp) {
329
329
  // was chosen for. Fields are sorted by name, so which field this lands on
330
330
  // is alphabetical accident: solar's planet, once its spec declared the
331
331
  // server-assigned `forbidReason`, marked that instead of `kind`.
332
- if ('`$STRING`' === field.type && 'id' !== field.name &&
333
- true !== field.readOnly && true !== paramNames[field.name]) {
332
+ if ('`$STRING`' === field.t && 'id' !== field.n &&
333
+ true !== field.ro && true !== paramNames[field.n]) {
334
334
  return field
335
335
  }
336
336
  }
@@ -177,7 +177,7 @@ const graphqlTransform: Transform = async function(
177
177
 
178
178
  each(ment.op, (mop: ModelOp, opname: OpName) => {
179
179
  each(mop.points, (mpoint: ModelPoint) => {
180
- const rootfield = mpoint.orig
180
+ const rootfield = mpoint.o
181
181
 
182
182
  const gfield: GuidePath | undefined = (gent as any)?.field?.[rootfield]
183
183
  const optype = (gfield?.op?.[opname] as any)?.optype ?? 'query'
@@ -231,11 +231,11 @@ const graphqlTransform: Transform = async function(
231
231
  const docname = pascal(entname) + pascal(opname) +
232
232
  (null != actionName ? pascal(actionName) : '')
233
233
 
234
- mpoint.kind = 'graphql'
235
- mpoint.method = 'POST'
236
- mpoint.segments = []
234
+ mpoint.k = 'graphql'
235
+ mpoint.m = 'POST'
236
+ mpoint.s = []
237
237
 
238
- mpoint.graphql = {
238
+ mpoint.gq = {
239
239
  optype: optype as 'query' | 'mutation',
240
240
  field: rootfield,
241
241
  doc: renderDoc(docname, optype, rootfield, vars, selection,
@@ -246,10 +246,10 @@ const graphqlTransform: Transform = async function(
246
246
  // Carried for the field transform, which derives entity fields from
247
247
  // the same object type. The `$` suffix makes cleanTransform strip it
248
248
  // from the emitted model — it is pipeline state, not wire data.
249
- ;(mpoint.graphql as any).entityType$ = entityType
249
+ ;(mpoint.gq as any).entityType$ = entityType
250
250
 
251
251
  if ('connection' === ret.kind) {
252
- mpoint.graphql.page = {
252
+ mpoint.gq.page = {
253
253
  style: 'relay',
254
254
  nodes: ret.nodes ?? 'nodes',
255
255
  cursor: 'pageInfo.endCursor',
@@ -257,7 +257,7 @@ const graphqlTransform: Transform = async function(
257
257
  }
258
258
  }
259
259
 
260
- mpoint.transform.res = '`' + respath + '`'
260
+ mpoint.t.res = '`' + respath + '`'
261
261
  })
262
262
  })
263
263
 
@@ -184,19 +184,19 @@ function resolveOp(opname: OpName, gent: GuideEntity): undefined | ModelOp {
184
184
  const segments = p.segments
185
185
 
186
186
  const mpoint: ModelPoint = {
187
- orig: p.orig,
188
- segments,
189
- rename: p.rename,
190
- method: p.method,
191
- args: {},
192
- transform: { ...((p as any).op?.transform ?? {}) },
193
- select: {
187
+ o: p.orig,
188
+ s: segments,
189
+ r: p.rename,
190
+ m: p.method,
191
+ g: {},
192
+ t: { ...((p as any).op?.transform ?? {}) },
193
+ q: {
194
194
  exist: []
195
195
  }
196
196
  }
197
197
 
198
- mpoint.transform.req = mpoint.transform.req ?? '`reqdata`'
199
- mpoint.transform.res = mpoint.transform.res ?? '`body`'
198
+ mpoint.t.req = mpoint.t.req ?? '`reqdata`'
199
+ mpoint.t.res = mpoint.t.res ?? '`body`'
200
200
 
201
201
  return mpoint
202
202
  })