@voxgig/sdkgen 4.18.1 → 4.18.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.
@@ -103,9 +103,11 @@ const Config = cmp(async function Config(props: any) {
103
103
  pluginImports(feature)
104
104
  },
105
105
 
106
- '// #FeatureClasses': () => each(feature, (f: any) => {
107
- Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
108
- }),
106
+ '// #FeatureClasses': () => {
107
+ each(feature, (f: any) => {
108
+ Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
109
+ })
110
+ },
109
111
 
110
112
  '// #FeaturePlugins': () => pluginDefs(feature),
111
113
 
@@ -147,28 +149,34 @@ const Config = cmp(async function Config(props: any) {
147
149
  Line(` target: ${JSON.stringify(configDef.main.target)},`)
148
150
  },
149
151
 
150
- '// #FeatureClasses': () => each(feature, (f: any) => {
151
- // Trailing comma: the map has one entry per feature, so entries
152
- // must be comma-separated (a single feature hid this until now).
153
- Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
154
- }),
152
+ '// #FeatureClasses': () => {
153
+ each(feature, (f: any) => {
154
+ // Trailing comma: the map has one entry per feature, so entries
155
+ // must be comma-separated (a single feature hid this until now).
156
+ Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
157
+ })
158
+ },
155
159
 
156
160
  '// #FeaturePlugins': () => pluginDefs(feature),
157
161
 
158
162
  // Rendered from configDefinition's def, not from f.config, so the
159
163
  // literal carries the feature's `transport` role (station design
160
164
  // §8.4) beside its options and cannot drift from the data rep.
161
- '// #FeatureConfigs': () => each(feature, (f: any) => {
162
- Line(` ${f.name}: ${formatJson(configDef.feature[f.name], { margin: 4 })},`)
163
- }),
165
+ '// #FeatureConfigs': () => {
166
+ each(feature, (f: any) => {
167
+ Line(` ${f.name}: ${formatJson(configDef.feature[f.name], { margin: 4 })},`)
168
+ })
169
+ },
164
170
 
165
171
 
166
- '// #EntityConfigs': () => each(entity, (entity: any) => {
167
- Content(`
168
- ${entity.name}: {
169
- },
170
- `)
171
- }),
172
+ '// #EntityConfigs': () => {
173
+ each(entity, (entity: any) => {
174
+ Content(`
175
+ ${entity.name}: {
176
+ },
177
+ `)
178
+ })
179
+ },
172
180
 
173
181
  // configDefinition's `def.entity` verbatim, NOT rebuilt here. This
174
182
  // reduce was a second copy of that function's entityDefs loop, and
@@ -106,9 +106,11 @@ const Config = cmp(async function Config(props: any) {
106
106
  pluginImports(feature)
107
107
  },
108
108
 
109
- '// #FeatureClasses': () => each(feature, (f: any) => {
110
- Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
111
- }),
109
+ '// #FeatureClasses': () => {
110
+ each(feature, (f: any) => {
111
+ Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
112
+ })
113
+ },
112
114
 
113
115
  '// #FeaturePlugins': () => pluginDefs(feature),
114
116
 
@@ -150,28 +152,34 @@ const Config = cmp(async function Config(props: any) {
150
152
  Line(` target: ${JSON.stringify(configDef.main.target)},`)
151
153
  },
152
154
 
153
- '// #FeatureClasses': () => each(feature, (f: any) => {
154
- // Trailing comma: the map has one entry per feature, so entries
155
- // must be comma-separated (a single feature hid this until now).
156
- Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
157
- }),
155
+ '// #FeatureClasses': () => {
156
+ each(feature, (f: any) => {
157
+ // Trailing comma: the map has one entry per feature, so entries
158
+ // must be comma-separated (a single feature hid this until now).
159
+ Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
160
+ })
161
+ },
158
162
 
159
163
  '// #FeaturePlugins': () => pluginDefs(feature),
160
164
 
161
165
  // Rendered from configDefinition's def, not from f.config, so the
162
166
  // literal carries the feature's `transport` role (station design
163
167
  // §8.4) beside its options and cannot drift from the data rep.
164
- '// #FeatureConfigs': () => each(feature, (f: any) => {
165
- Line(` ${f.name}: ${formatJson(configDef.feature[f.name], { margin: 4 })},`)
166
- }),
168
+ '// #FeatureConfigs': () => {
169
+ each(feature, (f: any) => {
170
+ Line(` ${f.name}: ${formatJson(configDef.feature[f.name], { margin: 4 })},`)
171
+ })
172
+ },
167
173
 
168
174
 
169
- '// #EntityConfigs': () => each(entity, (entity: any) => {
170
- Content(`
171
- ${entity.name}: {
172
- },
173
- `)
174
- }),
175
+ '// #EntityConfigs': () => {
176
+ each(entity, (entity: any) => {
177
+ Content(`
178
+ ${entity.name}: {
179
+ },
180
+ `)
181
+ })
182
+ },
175
183
 
176
184
  // configDefinition's `def.entity` verbatim, NOT rebuilt here. This
177
185
  // reduce was a second copy of that function's entityDefs loop, and
@@ -3,7 +3,7 @@
3
3
  "package": 1
4
4
  },
5
5
  "name": "@voxgig/sdkgen",
6
- "version": "4.18.1",
6
+ "version": "4.18.3",
7
7
  "provides": {
8
8
  "target": [
9
9
  "c",
@@ -49,7 +49,7 @@ import { templateReplacements } from '../helpers/stdrep'
49
49
 
50
50
  import { copyOpts } from '../helpers/junk'
51
51
 
52
- import { resolveKind, kindModel, kindTrees } from './kind'
52
+ import { resolveKind, kindModel, kindIndex, kindTrees } from './kind'
53
53
  import type { TreeDef } from './kind'
54
54
 
55
55
  import { registerInstalled } from './resolve'
@@ -257,6 +257,14 @@ const EditionRoot = cmp(function EditionRoot(props: any) {
257
257
 
258
258
  log.info({ point: 'edition-done', edition: source.name, note: source.name })
259
259
  })
260
+
261
+ // ONCE, after the loop. See kindIndex.
262
+ if (0 < dnames.length) {
263
+ Folder({ name: 'model/edition' }, () => kindIndex({
264
+ kind: 'edition', names: dnames,
265
+ content: ctx$.meta.content.edition_index,
266
+ }))
267
+ }
260
268
  })
261
269
  })
262
270
 
@@ -31,7 +31,7 @@ import { templateReplacements } from '../helpers/stdrep'
31
31
 
32
32
  import { copyOpts } from '../helpers/junk'
33
33
 
34
- import { resolveKind, kindModel } from './kind'
34
+ import { resolveKind, kindModel, kindIndex } from './kind'
35
35
 
36
36
 
37
37
  import {
@@ -279,6 +279,16 @@ const FeatureRoot = cmp(function FeatureRoot(props: any) {
279
279
  note: fname
280
280
  })
281
281
  })
282
+
283
+ // ONCE, after the loop, with every name this run installed. Emitted inside
284
+ // kindModel it was one File component per feature on the same path, which
285
+ // jostraca 0.38 refuses.
286
+ if (0 < fnames.length) {
287
+ Folder({ name: 'model/feature' }, () => kindIndex({
288
+ kind: 'feature', names: fnames,
289
+ content: ctx$.meta.content.feature_index,
290
+ }))
291
+ }
282
292
  })
283
293
 
284
294
  })
@@ -262,7 +262,7 @@ function kindModel(props: {
262
262
  names: string[],
263
263
  content: string,
264
264
  }) {
265
- const { ctx$, kind, source, names, content } = props
265
+ const { ctx$, kind, source } = props
266
266
  const def = kindDef(kind)
267
267
  const fs = ctx$.fs()
268
268
  const log = ctx$.log
@@ -312,7 +312,30 @@ function kindModel(props: {
312
312
  Copy({ from: source.model, replace })
313
313
  }
314
314
 
315
- File({ name: def.name + '-index.aon' }, () => UpdateIndex({
315
+ }
316
+
317
+
318
+ // The kind's include list, emitted ONCE for the whole run.
319
+ //
320
+ // This used to live at the end of kindModel, which is called per item, and the
321
+ // comment there said so plainly: "the index File is re-rendered per item and
322
+ // the last render wins, so each render has to carry all of them". jostraca
323
+ // 0.38 added a duplicate-output-path check and now refuses that outright:
324
+ //
325
+ // two File components resolve to the same output path,
326
+ // path=/out/model/feature/feature-index.aon
327
+ //
328
+ // Last-write-wins was never the intent, only the mechanism. Installing three
329
+ // features rendered the index three times to write it once. Emitting it after
330
+ // the loop, with the complete name list, produces the same file from one File
331
+ // component and says what it means.
332
+ function kindIndex(props: {
333
+ kind: string,
334
+ names: string[],
335
+ content: string,
336
+ }) {
337
+ const { kind, names, content } = props
338
+ File({ name: kindDef(kind).name + '-index.aon' }, () => UpdateIndex({
316
339
  content,
317
340
  names,
318
341
  }))
@@ -350,5 +373,6 @@ export {
350
373
  kindDef,
351
374
  resolveKind,
352
375
  kindModel,
376
+ kindIndex,
353
377
  isBare,
354
378
  }
@@ -51,7 +51,7 @@ import {
51
51
  loadContent,
52
52
  } from './action'
53
53
 
54
- import { kindModel, resolveKind, escapeRe } from './kind'
54
+ import { kindModel, kindIndex, resolveKind, escapeRe } from './kind'
55
55
 
56
56
  import { BUNDLED, resolveSource, registerInstalled } from './resolve'
57
57
 
@@ -281,6 +281,16 @@ const TargetRoot = cmp(function TargetRoot(props: any) {
281
281
  })
282
282
 
283
283
  })
284
+
285
+ // ONCE, after the loop. See kindIndex: emitted per item it was one File
286
+ // component per target on the same output path, which jostraca 0.38
287
+ // refuses.
288
+ if (0 < tnames.length) {
289
+ Folder({ name: 'model/target' }, () => kindIndex({
290
+ kind: 'target', names: tnames,
291
+ content: ctx$.meta.content.target_index,
292
+ }))
293
+ }
284
294
  })
285
295
  })
286
296
 
package/src/sdkgen.ts CHANGED
@@ -1148,7 +1148,13 @@ type Component = (props: any, children?: any) => void
1148
1148
 
1149
1149
 
1150
1150
  // Prevents TS2742
1151
- export const cmp: (component: Function) => Component = JostracaModule.cmp
1151
+ // `typeof` rather than a hand-written signature: jostraca 0.38 made cmp
1152
+ // generic, `<P, Arg, Child>(component: (props: CmpProps<P>, ...) => any) =>
1153
+ // Component<P, Arg, Child>`, and the old annotation `(component: Function) =>
1154
+ // Component` no longer matched it. Deferring to the module's own type keeps
1155
+ // this correct across jostraca versions AND still names the type, which is
1156
+ // what prevented TS2742 in the first place.
1157
+ export const cmp: typeof JostracaModule.cmp = JostracaModule.cmp
1152
1158
  export const names: (base: any, name: string, prop?: string) => any = JostracaModule.names
1153
1159
  export const each: (subject?: any, apply?: any) => any = JostracaModule.each
1154
1160
  export const snakify: (input: any[] | string) => string = JostracaModule.snakify