@voxgig/system 1.3.1 → 1.4.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.
package/README.md CHANGED
@@ -56,3 +56,26 @@ Add.fields(folder, 'thing', ['title', 'done:Boolean'])
56
56
  ## License
57
57
 
58
58
  MIT. Copyright (c) Voxgig Ltd.
59
+
60
+ ## Custom generation templates
61
+
62
+ Generation templates resolve in layers — first hit wins:
63
+
64
+ 1. `backend/src/gen/<name>.ts` — compiled generator override (deep custom)
65
+ 2. `backend/tm/lambda/<frag>` — project fragment (text-level custom)
66
+ 3. `@voxgig/build` defaults
67
+
68
+ ```bash
69
+ voxgig-system template list # each template + its providing layer
70
+ voxgig-system template eject srv.yml.frag # copy fragment -> tm/lambda/
71
+ voxgig-system template eject srv_yml --code # copy generator -> src/gen/
72
+ voxgig-system template diff # ejected copies vs installed package
73
+ ```
74
+
75
+ Fragments are jostraca-style text templates with `$$slot$$` placeholders —
76
+ edit and re-run `npm run model-build`, no compile step. Ejecting records
77
+ provenance (`tm/lambda/.ejected.json`) so `template diff` can flag
78
+ upstream template changes after a `@voxgig/build` upgrade. `--code`
79
+ copies the template source rewired to `@voxgig/build`'s public API; the
80
+ project then owns that generator (`npm run build && npm run model-build`
81
+ after edits).
package/cmd.ts CHANGED
@@ -17,9 +17,12 @@
17
17
  // model build (npm run model-build) afterwards to compile.
18
18
 
19
19
  import { addEntity, addSrv, addMsg, addFields } from './lib/add'
20
+ import {
21
+ listTemplates, ejectFragment, ejectCode, diffTemplates,
22
+ } from './lib/template'
20
23
 
21
24
 
22
- const USAGE = `Usage: voxgig-system add <element> [args...]
25
+ const USAGE = `Usage: voxgig-system <command> [args...]
23
26
 
24
27
  add entity [name|spec] add an entity (name may be zone/name)
25
28
  add srv [name|spec] add a service
@@ -27,6 +30,11 @@ const USAGE = `Usage: voxgig-system add <element> [args...]
27
30
  add field <entity> [field...] add field(s) to an entity
28
31
  add fields <entity> [field...] alias of add field
29
32
 
33
+ template list templates + the layer providing each
34
+ template eject <name> copy a fragment into backend/tm/lambda/
35
+ template eject <name> --code copy a generator into backend/src/gen/
36
+ template diff ejected copies vs the installed package
37
+
30
38
  name: plain element name - an empty element is added
31
39
  spec: jsonic definition with config options, e.g.
32
40
  add entity '{name:thing,field:{title:{kind:String}}}'
@@ -34,6 +42,11 @@ spec: jsonic definition with config options, e.g.
34
42
  add msg '{name:thing.save.item,params:{title:String}}'
35
43
  add field thing title 'done:Boolean' 'note:{kind:String,valid:Skip}'
36
44
 
45
+ Generation templates resolve in layers (first hit wins): project
46
+ src/gen/<name>.ts (code override) -> project tm/lambda/<frag> (text
47
+ fragment) -> @voxgig/build defaults. Eject a fragment to customize the
48
+ text shape with no compile step; eject --code for structural changes.
49
+
37
50
  Run inside the project (or backend/) folder. Then: npm run model-build
38
51
  `
39
52
 
@@ -48,14 +61,69 @@ async function main() {
48
61
 
49
62
  const [cmd, element, ...args] = argv
50
63
 
64
+ const start = process.cwd()
65
+
66
+ if ('template' === cmd || 'templates' === cmd) {
67
+ try {
68
+ if ('list' === element) {
69
+ for (const row of listTemplates(start)) {
70
+ console.log(
71
+ row.kind.padEnd(10) + row.name.padEnd(24) + row.layer)
72
+ }
73
+ }
74
+ else if ('eject' === element) {
75
+ const name = args.filter((a) => !a.startsWith('-'))[0]
76
+ if (null == name) {
77
+ throw new Error('template eject: missing template name')
78
+ }
79
+ if (args.includes('--code')) {
80
+ const dest = ejectCode(start, name)
81
+ console.log('ejected generator: ' + dest)
82
+ console.log('\nThis project copy now owns the ' + name +
83
+ ' generator. After editing:')
84
+ console.log(' npm run build && npm run model-build')
85
+ }
86
+ else {
87
+ const dest = ejectFragment(start, name)
88
+ console.log('ejected fragment: ' + dest)
89
+ console.log('\nEdit the fragment, then: npm run model-build')
90
+ }
91
+ }
92
+ else if ('diff' === element) {
93
+ const rows = diffTemplates(start)
94
+ if (0 === rows.length) {
95
+ console.log('nothing ejected')
96
+ }
97
+ for (const row of rows) {
98
+ console.log('== ' + row.name + ' (upstream: ' +
99
+ row.upstream + ')')
100
+ if (row.diff) {
101
+ console.log(row.diff)
102
+ }
103
+ else if ('' === row.diff) {
104
+ console.log(' identical to package')
105
+ }
106
+ }
107
+ }
108
+ else {
109
+ console.error('voxgig-system: unknown template command: ' + element)
110
+ console.log(USAGE)
111
+ process.exit(1)
112
+ }
113
+ process.exit(0)
114
+ }
115
+ catch (e: any) {
116
+ console.error('voxgig-system: ' + e.message)
117
+ process.exit(1)
118
+ }
119
+ }
120
+
51
121
  if ('add' !== cmd) {
52
122
  console.error('voxgig-system: unknown command: ' + cmd)
53
123
  console.log(USAGE)
54
124
  process.exit(1)
55
125
  }
56
126
 
57
- const start = process.cwd()
58
-
59
127
  try {
60
128
  if ('entity' === element) {
61
129
  requireArgs(args, 1, 'add entity')
package/dist/cmd.js CHANGED
@@ -18,7 +18,8 @@ exports.main = main;
18
18
  // are found via model/model.jsonic and appended to. Run the project's
19
19
  // model build (npm run model-build) afterwards to compile.
20
20
  const add_1 = require("./lib/add");
21
- const USAGE = `Usage: voxgig-system add <element> [args...]
21
+ const template_1 = require("./lib/template");
22
+ const USAGE = `Usage: voxgig-system <command> [args...]
22
23
 
23
24
  add entity [name|spec] add an entity (name may be zone/name)
24
25
  add srv [name|spec] add a service
@@ -26,6 +27,11 @@ const USAGE = `Usage: voxgig-system add <element> [args...]
26
27
  add field <entity> [field...] add field(s) to an entity
27
28
  add fields <entity> [field...] alias of add field
28
29
 
30
+ template list templates + the layer providing each
31
+ template eject <name> copy a fragment into backend/tm/lambda/
32
+ template eject <name> --code copy a generator into backend/src/gen/
33
+ template diff ejected copies vs the installed package
34
+
29
35
  name: plain element name - an empty element is added
30
36
  spec: jsonic definition with config options, e.g.
31
37
  add entity '{name:thing,field:{title:{kind:String}}}'
@@ -33,6 +39,11 @@ spec: jsonic definition with config options, e.g.
33
39
  add msg '{name:thing.save.item,params:{title:String}}'
34
40
  add field thing title 'done:Boolean' 'note:{kind:String,valid:Skip}'
35
41
 
42
+ Generation templates resolve in layers (first hit wins): project
43
+ src/gen/<name>.ts (code override) -> project tm/lambda/<frag> (text
44
+ fragment) -> @voxgig/build defaults. Eject a fragment to customize the
45
+ text shape with no compile step; eject --code for structural changes.
46
+
36
47
  Run inside the project (or backend/) folder. Then: npm run model-build
37
48
  `;
38
49
  async function main() {
@@ -42,12 +53,65 @@ async function main() {
42
53
  process.exit(0 === argv.length ? 1 : 0);
43
54
  }
44
55
  const [cmd, element, ...args] = argv;
56
+ const start = process.cwd();
57
+ if ('template' === cmd || 'templates' === cmd) {
58
+ try {
59
+ if ('list' === element) {
60
+ for (const row of (0, template_1.listTemplates)(start)) {
61
+ console.log(row.kind.padEnd(10) + row.name.padEnd(24) + row.layer);
62
+ }
63
+ }
64
+ else if ('eject' === element) {
65
+ const name = args.filter((a) => !a.startsWith('-'))[0];
66
+ if (null == name) {
67
+ throw new Error('template eject: missing template name');
68
+ }
69
+ if (args.includes('--code')) {
70
+ const dest = (0, template_1.ejectCode)(start, name);
71
+ console.log('ejected generator: ' + dest);
72
+ console.log('\nThis project copy now owns the ' + name +
73
+ ' generator. After editing:');
74
+ console.log(' npm run build && npm run model-build');
75
+ }
76
+ else {
77
+ const dest = (0, template_1.ejectFragment)(start, name);
78
+ console.log('ejected fragment: ' + dest);
79
+ console.log('\nEdit the fragment, then: npm run model-build');
80
+ }
81
+ }
82
+ else if ('diff' === element) {
83
+ const rows = (0, template_1.diffTemplates)(start);
84
+ if (0 === rows.length) {
85
+ console.log('nothing ejected');
86
+ }
87
+ for (const row of rows) {
88
+ console.log('== ' + row.name + ' (upstream: ' +
89
+ row.upstream + ')');
90
+ if (row.diff) {
91
+ console.log(row.diff);
92
+ }
93
+ else if ('' === row.diff) {
94
+ console.log(' identical to package');
95
+ }
96
+ }
97
+ }
98
+ else {
99
+ console.error('voxgig-system: unknown template command: ' + element);
100
+ console.log(USAGE);
101
+ process.exit(1);
102
+ }
103
+ process.exit(0);
104
+ }
105
+ catch (e) {
106
+ console.error('voxgig-system: ' + e.message);
107
+ process.exit(1);
108
+ }
109
+ }
45
110
  if ('add' !== cmd) {
46
111
  console.error('voxgig-system: unknown command: ' + cmd);
47
112
  console.log(USAGE);
48
113
  process.exit(1);
49
114
  }
50
- const start = process.cwd();
51
115
  try {
52
116
  if ('entity' === element) {
53
117
  requireArgs(args, 1, 'add entity');
package/dist/cmd.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cmd.js","sourceRoot":"","sources":["../cmd.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cmd.js","sourceRoot":"","sources":["../cmd.ts"],"names":[],"mappings":";;AACA,+CAA+C;;QAqL7C,IAAI;AAnLN,wEAAwE;AACxE,EAAE;AACF,yDAAyD;AACzD,yDAAyD;AACzD,yDAAyD;AACzD,sEAAsE;AACtE,sEAAsE;AACtE,EAAE;AACF,8DAA8D;AAC9D,wEAAwE;AACxE,EAAE;AACF,wEAAwE;AACxE,sEAAsE;AACtE,2DAA2D;AAE3D,mCAAgE;AAChE,6CAEuB;AAGvB,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Bb,CAAA;AAGD,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAElC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACzC,CAAC;IAED,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAE3B,IAAI,UAAU,KAAK,GAAG,IAAI,WAAW,KAAK,GAAG,EAAE,CAAC;QAC9C,IAAI,CAAC;YACH,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,KAAK,MAAM,GAAG,IAAI,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;oBACvC,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;gBAC1D,CAAC;YACH,CAAC;iBACI,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;gBACtD,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;gBAC1D,CAAC;gBACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,MAAM,IAAI,GAAG,IAAA,oBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;oBACnC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAA;oBACzC,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAG,IAAI;wBACpD,4BAA4B,CAAC,CAAA;oBAC/B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;gBACvD,CAAC;qBACI,CAAC;oBACJ,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;oBACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAA;oBACxC,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAA;gBAC/D,CAAC;YACH,CAAC;iBACI,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,KAAK,CAAC,CAAA;gBACjC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;oBACtB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;gBAChC,CAAC;gBACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,GAAG,eAAe;wBAC5C,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;oBACrB,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;wBACb,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;oBACvB,CAAC;yBACI,IAAI,EAAE,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;iBACI,CAAC;gBACJ,OAAO,CAAC,KAAK,CAAC,2CAA2C,GAAG,OAAO,CAAC,CAAA;gBACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,CAAM,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;YAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kCAAkC,GAAG,GAAG,CAAC,CAAA;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC;QACH,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,YAAY,CAAC,CAAA;YAClC,MAAM,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YACrC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACf,CAAC;aACI,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC3B,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;YAC/B,MAAM,GAAG,GAAG,IAAA,YAAM,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACf,CAAC;aACI,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC3B,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;YAC/B,MAAM,GAAG,GAAG,IAAA,YAAM,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACf,CAAC;aACI,IAAI,OAAO,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrD,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,CAAA;YACjC,MAAM,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YACpD,MAAM,CAAC,GAAG,CAAC,CAAA;QACb,CAAC;aACI,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,kCAAkC,GAAG,OAAO,CAAC,CAAA;YAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,CAAM,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAGD,SAAS,WAAW,CAAC,IAAc,EAAE,CAAS,EAAE,IAAY;IAC1D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,uBAAuB,CAAC,CAAA;IACjD,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,OAAyC;IACvD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;AACH,CAAC;AAGD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAA;AACR,CAAC"}
@@ -0,0 +1,24 @@
1
+ declare const GENERATORS: string[];
2
+ export type Project = {
3
+ backend: string;
4
+ tm: string;
5
+ gen: string;
6
+ pkg: string;
7
+ pkgtm: string;
8
+ };
9
+ declare function resolveProject(start: string): Project;
10
+ export type TemplateRow = {
11
+ name: string;
12
+ kind: 'fragment' | 'generator';
13
+ layer: string;
14
+ };
15
+ declare function listTemplates(start: string): TemplateRow[];
16
+ declare function ejectFragment(start: string, name: string): string;
17
+ declare function ejectCode(start: string, name: string): string;
18
+ export type DiffRow = {
19
+ name: string;
20
+ upstream: 'unchanged' | 'changed' | 'missing';
21
+ diff?: string;
22
+ };
23
+ declare function diffTemplates(start: string): DiffRow[];
24
+ export { resolveProject, listTemplates, ejectFragment, ejectCode, diffTemplates, GENERATORS, };
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /* Copyright © 2026 Voxgig Ltd, MIT License. */
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.GENERATORS = void 0;
8
+ exports.resolveProject = resolveProject;
9
+ exports.listTemplates = listTemplates;
10
+ exports.ejectFragment = ejectFragment;
11
+ exports.ejectCode = ejectCode;
12
+ exports.diffTemplates = diffTemplates;
13
+ // Template customization tooling: list / eject / diff for the generation
14
+ // templates provided by @voxgig/build.
15
+ //
16
+ // Layered resolution (first hit wins):
17
+ // 1. backend/src/gen/<name>.ts compiled generator override (deep custom)
18
+ // 2. backend/tm/lambda/<frag> project fragment (text-level custom)
19
+ // 3. @voxgig/build package defaults
20
+ //
21
+ // eject copies a package fragment (or, with code=true, a template source
22
+ // rewired to the package's public API) into the project, recording
23
+ // provenance in tm/lambda/.ejected.json so diff can show upstream drift
24
+ // after package upgrades.
25
+ const node_crypto_1 = __importDefault(require("node:crypto"));
26
+ const node_fs_1 = __importDefault(require("node:fs"));
27
+ const node_path_1 = __importDefault(require("node:path"));
28
+ const node_child_process_1 = require("node:child_process");
29
+ const add_1 = require("./add");
30
+ // The code-level template generators (env/lambda/<name>.ts in the package).
31
+ const GENERATORS = ['srv_yml', 'srv_handler', 'res_yml'];
32
+ exports.GENERATORS = GENERATORS;
33
+ // Generator shorthand -> default fragment.
34
+ const GENERATOR_FRAG = {
35
+ srv_yml: 'srv.yml.frag',
36
+ srv_handler: 'srv_handler.ts.frag',
37
+ res_yml: 'res.role.yml.frag',
38
+ };
39
+ function resolveProject(start) {
40
+ const files = (0, add_1.resolveModelFiles)(start);
41
+ const backend = node_path_1.default.dirname(files.folder);
42
+ let pkgjson;
43
+ try {
44
+ pkgjson = require.resolve('@voxgig/build/package.json', {
45
+ paths: [backend, files.folder, start],
46
+ });
47
+ }
48
+ catch (e) {
49
+ throw new Error('@voxgig/build not found from ' + backend +
50
+ ' - is it installed? (npm install)');
51
+ }
52
+ const pkg = node_path_1.default.dirname(pkgjson);
53
+ return {
54
+ backend,
55
+ tm: node_path_1.default.join(backend, 'tm', 'lambda'),
56
+ gen: node_path_1.default.join(backend, 'src', 'gen'),
57
+ pkg,
58
+ pkgtm: node_path_1.default.join(pkg, 'tm', 'lambda'),
59
+ };
60
+ }
61
+ function pkgVersion(project) {
62
+ return JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(project.pkg, 'package.json'), 'utf8')).version;
63
+ }
64
+ function sha256(content) {
65
+ return node_crypto_1.default.createHash('sha256').update(content).digest('hex');
66
+ }
67
+ function readProvenance(project) {
68
+ const p = node_path_1.default.join(project.tm, '.ejected.json');
69
+ return node_fs_1.default.existsSync(p) ? JSON.parse(node_fs_1.default.readFileSync(p, 'utf8')) : {};
70
+ }
71
+ function writeProvenance(project, prov) {
72
+ node_fs_1.default.mkdirSync(project.tm, { recursive: true });
73
+ node_fs_1.default.writeFileSync(node_path_1.default.join(project.tm, '.ejected.json'), JSON.stringify(prov, null, 2) + '\n');
74
+ }
75
+ // List each template with the layer that currently provides it.
76
+ function listTemplates(start) {
77
+ const project = resolveProject(start);
78
+ const rows = [];
79
+ for (const gen of GENERATORS) {
80
+ const override = node_path_1.default.join(project.gen, gen + '.ts');
81
+ rows.push({
82
+ name: gen,
83
+ kind: 'generator',
84
+ layer: node_fs_1.default.existsSync(override) ?
85
+ 'project (src/gen/' + gen + '.ts)' : 'package',
86
+ });
87
+ }
88
+ const frags = node_fs_1.default.readdirSync(project.pkgtm)
89
+ .filter((f) => f.endsWith('.frag')).sort();
90
+ for (const frag of frags) {
91
+ rows.push({
92
+ name: frag,
93
+ kind: 'fragment',
94
+ layer: node_fs_1.default.existsSync(node_path_1.default.join(project.tm, frag)) ?
95
+ 'project (tm/lambda/' + frag + ')' : 'package',
96
+ });
97
+ }
98
+ return rows;
99
+ }
100
+ // Eject a fragment (text template) into backend/tm/lambda/.
101
+ function ejectFragment(start, name) {
102
+ const project = resolveProject(start);
103
+ const frag = GENERATOR_FRAG[name] || name;
104
+ const srcpath = node_path_1.default.join(project.pkgtm, frag);
105
+ if (!node_fs_1.default.existsSync(srcpath)) {
106
+ const avail = node_fs_1.default.readdirSync(project.pkgtm)
107
+ .filter((f) => f.endsWith('.frag')).sort();
108
+ throw new Error('unknown fragment: ' + frag +
109
+ ' (available: ' + avail.join(', ') + ')');
110
+ }
111
+ const dest = node_path_1.default.join(project.tm, frag);
112
+ if (node_fs_1.default.existsSync(dest)) {
113
+ throw new Error('already ejected: ' + node_path_1.default.relative(start, dest));
114
+ }
115
+ const content = node_fs_1.default.readFileSync(srcpath, 'utf8');
116
+ node_fs_1.default.mkdirSync(project.tm, { recursive: true });
117
+ node_fs_1.default.writeFileSync(dest, content);
118
+ const prov = readProvenance(project);
119
+ prov[frag] = {
120
+ package: '@voxgig/build',
121
+ version: pkgVersion(project),
122
+ sha256: sha256(content),
123
+ };
124
+ writeProvenance(project, prov);
125
+ return dest;
126
+ }
127
+ // Eject a generator source (compiled component override) into
128
+ // backend/src/gen/<name>.ts, rewiring package-internal imports to the
129
+ // public '@voxgig/build' API.
130
+ function ejectCode(start, name) {
131
+ const project = resolveProject(start);
132
+ if (!GENERATORS.includes(name)) {
133
+ throw new Error('unknown generator: ' + name +
134
+ ' (available: ' + GENERATORS.join(', ') + ')');
135
+ }
136
+ const srcpath = node_path_1.default.join(project.pkg, 'env', 'lambda', name + '.ts');
137
+ if (!node_fs_1.default.existsSync(srcpath)) {
138
+ throw new Error('template source not shipped by installed ' +
139
+ '@voxgig/build (' + pkgVersion(project) + ') - needs >= 4.1.0');
140
+ }
141
+ const dest = node_path_1.default.join(project.gen, name + '.ts');
142
+ if (node_fs_1.default.existsSync(dest)) {
143
+ throw new Error('already ejected: ' + node_path_1.default.relative(start, dest));
144
+ }
145
+ let src = node_fs_1.default.readFileSync(srcpath, 'utf8');
146
+ // Package-internal imports -> public API.
147
+ src = src
148
+ .replace(/from '\.\/generate'/g, "from '@voxgig/build'")
149
+ .replace(/from '\.\.\/\.\.\/shape\/msg'/g, "from '@voxgig/build'")
150
+ .replace(/from '\.\.\/\.\.\/shape\/conf'/g, "from '@voxgig/build'")
151
+ .replace(/from '\.\.\/\.\.\/yml\/res_dynamo_yml'/g, "from '@voxgig/build'");
152
+ const version = pkgVersion(project);
153
+ src = '// Ejected from @voxgig/build ' + version +
154
+ ' (env/lambda/' + name + '.ts).\n' +
155
+ '// This project copy now OWNS this generator: the build action uses\n' +
156
+ '// it instead of the package default. After editing, run:\n' +
157
+ '// npm run build && npm run model-build\n' +
158
+ '// Compare with the package version: voxgig-system template diff\n' +
159
+ src;
160
+ node_fs_1.default.mkdirSync(project.gen, { recursive: true });
161
+ node_fs_1.default.writeFileSync(dest, src);
162
+ const prov = readProvenance(project);
163
+ prov['code:' + name] = {
164
+ package: '@voxgig/build',
165
+ version,
166
+ sha256: sha256(node_fs_1.default.readFileSync(srcpath)),
167
+ };
168
+ writeProvenance(project, prov);
169
+ return dest;
170
+ }
171
+ // For each ejected template, report upstream drift (package version now
172
+ // differs from what was ejected) and show package-vs-project diffs.
173
+ function diffTemplates(start) {
174
+ const project = resolveProject(start);
175
+ const prov = readProvenance(project);
176
+ const rows = [];
177
+ for (const key of Object.keys(prov).sort()) {
178
+ const rec = prov[key];
179
+ const isCode = key.startsWith('code:');
180
+ const name = isCode ? key.substring(5) : key;
181
+ const pkgfile = isCode ?
182
+ node_path_1.default.join(project.pkg, 'env', 'lambda', name + '.ts') :
183
+ node_path_1.default.join(project.pkgtm, name);
184
+ const projfile = isCode ?
185
+ node_path_1.default.join(project.gen, name + '.ts') :
186
+ node_path_1.default.join(project.tm, name);
187
+ if (!node_fs_1.default.existsSync(pkgfile)) {
188
+ rows.push({ name: key, upstream: 'missing' });
189
+ continue;
190
+ }
191
+ const upstream = sha256(node_fs_1.default.readFileSync(pkgfile)) === rec.sha256 ?
192
+ 'unchanged' : 'changed';
193
+ let diff = undefined;
194
+ if (node_fs_1.default.existsSync(projfile)) {
195
+ const res = (0, node_child_process_1.spawnSync)('diff', ['-u', pkgfile, projfile], { encoding: 'utf8' });
196
+ diff = 0 === res.status ? '' : res.stdout;
197
+ }
198
+ rows.push({ name: key, upstream, diff });
199
+ }
200
+ return rows;
201
+ }
202
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../lib/template.ts"],"names":[],"mappings":"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"}
package/dist/system.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { Msg } from './lib/types';
2
2
  import { Utility } from './lib/utility';
3
3
  import { MakeSrv } from './srv/make';
4
4
  import { addEntity, addSrv, addMsg, addFields, resolveModelFiles } from './lib/add';
5
+ import { listTemplates, ejectFragment, ejectCode, diffTemplates } from './lib/template';
5
6
  declare function messages(seneca: any, options: any, reload: any): void;
6
7
  declare function gubuify(params: any, Gubu: any): any;
7
8
  declare function prepare(seneca: any, require: any): void;
@@ -26,4 +27,10 @@ declare const Add: {
26
27
  fields: typeof addFields;
27
28
  resolveModelFiles: typeof resolveModelFiles;
28
29
  };
29
- export { Add, gubuify, System, MakeSrv, Utility, Local, Live, };
30
+ declare const Template: {
31
+ list: typeof listTemplates;
32
+ eject: typeof ejectFragment;
33
+ ejectCode: typeof ejectCode;
34
+ diff: typeof diffTemplates;
35
+ };
36
+ export { Add, Template, gubuify, System, MakeSrv, Utility, Local, Live, };
package/dist/system.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Utility = exports.MakeSrv = exports.System = exports.Add = void 0;
7
+ exports.Utility = exports.MakeSrv = exports.System = exports.Template = exports.Add = void 0;
8
8
  exports.gubuify = gubuify;
9
9
  exports.Local = Local;
10
10
  exports.Live = Live;
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "Utility", { enumerable: true, get: function () {
15
15
  const make_1 = require("./srv/make");
16
16
  Object.defineProperty(exports, "MakeSrv", { enumerable: true, get: function () { return make_1.MakeSrv; } });
17
17
  const add_1 = require("./lib/add");
18
+ const template_1 = require("./lib/template");
18
19
  const { srvmsgs, deep } = utility_1.Utility;
19
20
  function messages(seneca, options, reload) {
20
21
  let srvname = seneca.fixedargs.plugin$.name.replace(/^srv_/, '');
@@ -155,4 +156,11 @@ const Add = {
155
156
  resolveModelFiles: add_1.resolveModelFiles,
156
157
  };
157
158
  exports.Add = Add;
159
+ const Template = {
160
+ list: template_1.listTemplates,
161
+ eject: template_1.ejectFragment,
162
+ ejectCode: template_1.ejectCode,
163
+ diff: template_1.diffTemplates,
164
+ };
165
+ exports.Template = Template;
158
166
  //# sourceMappingURL=system.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../system.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../system.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,278 @@
1
+ /* Copyright © 2026 Voxgig Ltd, MIT License. */
2
+
3
+ // Template customization tooling: list / eject / diff for the generation
4
+ // templates provided by @voxgig/build.
5
+ //
6
+ // Layered resolution (first hit wins):
7
+ // 1. backend/src/gen/<name>.ts compiled generator override (deep custom)
8
+ // 2. backend/tm/lambda/<frag> project fragment (text-level custom)
9
+ // 3. @voxgig/build package defaults
10
+ //
11
+ // eject copies a package fragment (or, with code=true, a template source
12
+ // rewired to the package's public API) into the project, recording
13
+ // provenance in tm/lambda/.ejected.json so diff can show upstream drift
14
+ // after package upgrades.
15
+
16
+ import Crypto from 'node:crypto'
17
+ import Fs from 'node:fs'
18
+ import Path from 'node:path'
19
+ import { spawnSync } from 'node:child_process'
20
+
21
+ import { resolveModelFiles } from './add'
22
+
23
+
24
+ // The code-level template generators (env/lambda/<name>.ts in the package).
25
+ const GENERATORS = ['srv_yml', 'srv_handler', 'res_yml']
26
+
27
+ // Generator shorthand -> default fragment.
28
+ const GENERATOR_FRAG: Record<string, string> = {
29
+ srv_yml: 'srv.yml.frag',
30
+ srv_handler: 'srv_handler.ts.frag',
31
+ res_yml: 'res.role.yml.frag',
32
+ }
33
+
34
+
35
+ export type Project = {
36
+ backend: string // the project backend folder (holds model/, tm/, src/)
37
+ tm: string // backend/tm/lambda
38
+ gen: string // backend/src/gen
39
+ pkg: string // resolved @voxgig/build package folder
40
+ pkgtm: string // package tm/lambda
41
+ }
42
+
43
+
44
+ function resolveProject(start: string): Project {
45
+ const files = resolveModelFiles(start)
46
+ const backend = Path.dirname(files.folder)
47
+
48
+ let pkgjson: string
49
+ try {
50
+ pkgjson = require.resolve('@voxgig/build/package.json', {
51
+ paths: [backend, files.folder, start],
52
+ })
53
+ }
54
+ catch (e: any) {
55
+ throw new Error('@voxgig/build not found from ' + backend +
56
+ ' - is it installed? (npm install)')
57
+ }
58
+ const pkg = Path.dirname(pkgjson)
59
+
60
+ return {
61
+ backend,
62
+ tm: Path.join(backend, 'tm', 'lambda'),
63
+ gen: Path.join(backend, 'src', 'gen'),
64
+ pkg,
65
+ pkgtm: Path.join(pkg, 'tm', 'lambda'),
66
+ }
67
+ }
68
+
69
+
70
+ function pkgVersion(project: Project): string {
71
+ return JSON.parse(
72
+ Fs.readFileSync(Path.join(project.pkg, 'package.json'), 'utf8')).version
73
+ }
74
+
75
+ function sha256(content: string | Buffer): string {
76
+ return Crypto.createHash('sha256').update(content).digest('hex')
77
+ }
78
+
79
+
80
+ type Provenance = Record<string, {
81
+ package: string, version: string, sha256: string
82
+ }>
83
+
84
+ function readProvenance(project: Project): Provenance {
85
+ const p = Path.join(project.tm, '.ejected.json')
86
+ return Fs.existsSync(p) ? JSON.parse(Fs.readFileSync(p, 'utf8')) : {}
87
+ }
88
+
89
+ function writeProvenance(project: Project, prov: Provenance) {
90
+ Fs.mkdirSync(project.tm, { recursive: true })
91
+ Fs.writeFileSync(Path.join(project.tm, '.ejected.json'),
92
+ JSON.stringify(prov, null, 2) + '\n')
93
+ }
94
+
95
+
96
+ export type TemplateRow = {
97
+ name: string // fragment or generator name
98
+ kind: 'fragment' | 'generator'
99
+ layer: string // which layer currently provides it
100
+ }
101
+
102
+ // List each template with the layer that currently provides it.
103
+ function listTemplates(start: string): TemplateRow[] {
104
+ const project = resolveProject(start)
105
+
106
+ const rows: TemplateRow[] = []
107
+
108
+ for (const gen of GENERATORS) {
109
+ const override = Path.join(project.gen, gen + '.ts')
110
+ rows.push({
111
+ name: gen,
112
+ kind: 'generator',
113
+ layer: Fs.existsSync(override) ?
114
+ 'project (src/gen/' + gen + '.ts)' : 'package',
115
+ })
116
+ }
117
+
118
+ const frags = Fs.readdirSync(project.pkgtm)
119
+ .filter((f) => f.endsWith('.frag')).sort()
120
+ for (const frag of frags) {
121
+ rows.push({
122
+ name: frag,
123
+ kind: 'fragment',
124
+ layer: Fs.existsSync(Path.join(project.tm, frag)) ?
125
+ 'project (tm/lambda/' + frag + ')' : 'package',
126
+ })
127
+ }
128
+
129
+ return rows
130
+ }
131
+
132
+
133
+ // Eject a fragment (text template) into backend/tm/lambda/.
134
+ function ejectFragment(start: string, name: string): string {
135
+ const project = resolveProject(start)
136
+
137
+ const frag = GENERATOR_FRAG[name] || name
138
+ const srcpath = Path.join(project.pkgtm, frag)
139
+ if (!Fs.existsSync(srcpath)) {
140
+ const avail = Fs.readdirSync(project.pkgtm)
141
+ .filter((f) => f.endsWith('.frag')).sort()
142
+ throw new Error('unknown fragment: ' + frag +
143
+ ' (available: ' + avail.join(', ') + ')')
144
+ }
145
+
146
+ const dest = Path.join(project.tm, frag)
147
+ if (Fs.existsSync(dest)) {
148
+ throw new Error('already ejected: ' + Path.relative(start, dest))
149
+ }
150
+
151
+ const content = Fs.readFileSync(srcpath, 'utf8')
152
+ Fs.mkdirSync(project.tm, { recursive: true })
153
+ Fs.writeFileSync(dest, content)
154
+
155
+ const prov = readProvenance(project)
156
+ prov[frag] = {
157
+ package: '@voxgig/build',
158
+ version: pkgVersion(project),
159
+ sha256: sha256(content),
160
+ }
161
+ writeProvenance(project, prov)
162
+
163
+ return dest
164
+ }
165
+
166
+
167
+ // Eject a generator source (compiled component override) into
168
+ // backend/src/gen/<name>.ts, rewiring package-internal imports to the
169
+ // public '@voxgig/build' API.
170
+ function ejectCode(start: string, name: string): string {
171
+ const project = resolveProject(start)
172
+
173
+ if (!GENERATORS.includes(name)) {
174
+ throw new Error('unknown generator: ' + name +
175
+ ' (available: ' + GENERATORS.join(', ') + ')')
176
+ }
177
+
178
+ const srcpath = Path.join(project.pkg, 'env', 'lambda', name + '.ts')
179
+ if (!Fs.existsSync(srcpath)) {
180
+ throw new Error('template source not shipped by installed ' +
181
+ '@voxgig/build (' + pkgVersion(project) + ') - needs >= 4.1.0')
182
+ }
183
+
184
+ const dest = Path.join(project.gen, name + '.ts')
185
+ if (Fs.existsSync(dest)) {
186
+ throw new Error('already ejected: ' + Path.relative(start, dest))
187
+ }
188
+
189
+ let src = Fs.readFileSync(srcpath, 'utf8')
190
+
191
+ // Package-internal imports -> public API.
192
+ src = src
193
+ .replace(/from '\.\/generate'/g, "from '@voxgig/build'")
194
+ .replace(/from '\.\.\/\.\.\/shape\/msg'/g, "from '@voxgig/build'")
195
+ .replace(/from '\.\.\/\.\.\/shape\/conf'/g, "from '@voxgig/build'")
196
+ .replace(/from '\.\.\/\.\.\/yml\/res_dynamo_yml'/g, "from '@voxgig/build'")
197
+
198
+ const version = pkgVersion(project)
199
+ src = '// Ejected from @voxgig/build ' + version +
200
+ ' (env/lambda/' + name + '.ts).\n' +
201
+ '// This project copy now OWNS this generator: the build action uses\n' +
202
+ '// it instead of the package default. After editing, run:\n' +
203
+ '// npm run build && npm run model-build\n' +
204
+ '// Compare with the package version: voxgig-system template diff\n' +
205
+ src
206
+
207
+ Fs.mkdirSync(project.gen, { recursive: true })
208
+ Fs.writeFileSync(dest, src)
209
+
210
+ const prov = readProvenance(project)
211
+ prov['code:' + name] = {
212
+ package: '@voxgig/build',
213
+ version,
214
+ sha256: sha256(Fs.readFileSync(srcpath)),
215
+ }
216
+ writeProvenance(project, prov)
217
+
218
+ return dest
219
+ }
220
+
221
+
222
+ export type DiffRow = {
223
+ name: string
224
+ upstream: 'unchanged' | 'changed' | 'missing'
225
+ diff?: string // unified diff of package vs project copy
226
+ }
227
+
228
+ // For each ejected template, report upstream drift (package version now
229
+ // differs from what was ejected) and show package-vs-project diffs.
230
+ function diffTemplates(start: string): DiffRow[] {
231
+ const project = resolveProject(start)
232
+ const prov = readProvenance(project)
233
+
234
+ const rows: DiffRow[] = []
235
+
236
+ for (const key of Object.keys(prov).sort()) {
237
+ const rec = prov[key]
238
+ const isCode = key.startsWith('code:')
239
+ const name = isCode ? key.substring(5) : key
240
+
241
+ const pkgfile = isCode ?
242
+ Path.join(project.pkg, 'env', 'lambda', name + '.ts') :
243
+ Path.join(project.pkgtm, name)
244
+ const projfile = isCode ?
245
+ Path.join(project.gen, name + '.ts') :
246
+ Path.join(project.tm, name)
247
+
248
+ if (!Fs.existsSync(pkgfile)) {
249
+ rows.push({ name: key, upstream: 'missing' })
250
+ continue
251
+ }
252
+
253
+ const upstream =
254
+ sha256(Fs.readFileSync(pkgfile)) === rec.sha256 ?
255
+ 'unchanged' : 'changed'
256
+
257
+ let diff: string | undefined = undefined
258
+ if (Fs.existsSync(projfile)) {
259
+ const res = spawnSync('diff', ['-u', pkgfile, projfile],
260
+ { encoding: 'utf8' })
261
+ diff = 0 === res.status ? '' : res.stdout
262
+ }
263
+
264
+ rows.push({ name: key, upstream, diff })
265
+ }
266
+
267
+ return rows
268
+ }
269
+
270
+
271
+ export {
272
+ resolveProject,
273
+ listTemplates,
274
+ ejectFragment,
275
+ ejectCode,
276
+ diffTemplates,
277
+ GENERATORS,
278
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxgig/system",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "main": "dist/system.js",
5
5
  "type": "commonjs",
6
6
  "types": "dist/system.d.ts",
package/system.ts CHANGED
@@ -14,6 +14,7 @@ import { Utility } from './lib/utility'
14
14
  import { MakeSrv } from './srv/make'
15
15
 
16
16
  import { addEntity, addSrv, addMsg, addFields, resolveModelFiles } from './lib/add'
17
+ import { listTemplates, ejectFragment, ejectCode, diffTemplates } from './lib/template'
17
18
 
18
19
 
19
20
 
@@ -224,8 +225,16 @@ const Add = {
224
225
  resolveModelFiles,
225
226
  }
226
227
 
228
+ const Template = {
229
+ list: listTemplates,
230
+ eject: ejectFragment,
231
+ ejectCode,
232
+ diff: diffTemplates,
233
+ }
234
+
227
235
  export {
228
236
  Add,
237
+ Template,
229
238
  gubuify,
230
239
  System,
231
240
  MakeSrv,