@voxgig/build 4.3.0 → 4.11.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 (100) hide show
  1. package/README.md +51 -2
  2. package/build.ts +20 -0
  3. package/dist/api/api_gen.d.ts +7 -0
  4. package/dist/api/api_gen.js +370 -0
  5. package/dist/api/api_gen.js.map +1 -0
  6. package/dist/build.d.ts +16 -1
  7. package/dist/build.js +17 -1
  8. package/dist/build.js.map +1 -1
  9. package/dist/doc/doc_gen.d.ts +8 -0
  10. package/dist/doc/doc_gen.js +397 -0
  11. package/dist/doc/doc_gen.js.map +1 -0
  12. package/dist/env/web/web_gen.js +159 -1
  13. package/dist/env/web/web_gen.js.map +1 -1
  14. package/dist/shape/ent.js +4 -2
  15. package/dist/shape/ent.js.map +1 -1
  16. package/env/web/web_gen.ts +174 -1
  17. package/package.json +6 -9
  18. package/tm/web/backend/env/shared/seed.ts.frag +23 -0
  19. package/tm/web/backend/env/web/api.ts.frag +157 -0
  20. package/tm/web/backend/env/web/web.ts.frag +37 -4
  21. package/tm/web/backend/srv/api/api-srv.ts.frag +4 -0
  22. package/tm/web/backend/srv/api/expose.ts.frag +33 -0
  23. package/tm/web/backend/srv/api/get_info.ts.frag +6 -0
  24. package/tm/web/backend/srv/api/on_ent.ts.frag +124 -0
  25. package/tm/web/backend/srv/auth/apikey_util.ts.frag +10 -0
  26. package/tm/web/backend/srv/auth/auth-srv.ts.frag +1 -0
  27. package/tm/web/backend/srv/auth/change_pass.ts.frag +12 -0
  28. package/tm/web/backend/srv/auth/create_apikey.ts.frag +33 -0
  29. package/tm/web/backend/srv/auth/get_info.ts.frag +1 -0
  30. package/tm/web/backend/srv/auth/list_apikey.ts.frag +15 -0
  31. package/tm/web/backend/srv/auth/load_auth.ts.frag +10 -1
  32. package/tm/web/backend/srv/auth/remind_pass.ts.frag +35 -0
  33. package/tm/web/backend/srv/auth/revoke_apikey.ts.frag +23 -0
  34. package/tm/web/backend/srv/auth/signin_user.ts.frag +12 -2
  35. package/tm/web/backend/srv/auth/signout_user.ts.frag +11 -1
  36. package/tm/web/backend/srv/auth/update_user.ts.frag +15 -0
  37. package/tm/web/backend/srv/auth/user_util.ts.frag +21 -0
  38. package/tm/web/backend/srv/auth/web_change_pass.ts.frag +16 -0
  39. package/tm/web/backend/srv/auth/web_create_apikey.ts.frag +15 -0
  40. package/tm/web/backend/srv/auth/web_list_apikey.ts.frag +11 -0
  41. package/tm/web/backend/srv/auth/web_load_auth.ts.frag +1 -0
  42. package/tm/web/backend/srv/auth/web_remind_pass.ts.frag +7 -0
  43. package/tm/web/backend/srv/auth/web_revoke_apikey.ts.frag +14 -0
  44. package/tm/web/backend/srv/auth/web_signin_user.ts.frag +1 -0
  45. package/tm/web/backend/srv/auth/web_signout_user.ts.frag +11 -3
  46. package/tm/web/backend/srv/auth/web_update_user.ts.frag +11 -0
  47. package/tm/web/backend/srv/ent/access.ts.frag +179 -0
  48. package/tm/web/backend/srv/ent/cmd_list.ts.frag +86 -0
  49. package/tm/web/backend/srv/ent/cmd_load.ts.frag +56 -0
  50. package/tm/web/backend/srv/ent/cmd_remove.ts.frag +60 -0
  51. package/tm/web/backend/srv/ent/cmd_save.ts.frag +141 -0
  52. package/tm/web/backend/srv/ent/ent-srv.ts.frag +4 -0
  53. package/tm/web/backend/srv/ent/get_info.ts.frag +6 -0
  54. package/tm/web/backend/srv/ent/web_cmd_list.ts.frag +17 -0
  55. package/tm/web/backend/srv/ent/web_cmd_load.ts.frag +17 -0
  56. package/tm/web/backend/srv/ent/web_cmd_remove.ts.frag +17 -0
  57. package/tm/web/backend/srv/ent/web_cmd_save.ts.frag +17 -0
  58. package/tm/web/backend/test/unit/env/web/api-router.test.ts.frag +315 -0
  59. package/tm/web/backend/test/unit/env/web/surface.test.ts.frag +109 -0
  60. package/tm/web/backend/test/unit/srv/api/api.setup.ts.frag +162 -0
  61. package/tm/web/backend/test/unit/srv/api/api.test.ts.frag +225 -0
  62. package/tm/web/backend/test/unit/srv/auth/apikey.test.ts.frag +152 -0
  63. package/tm/web/backend/test/unit/srv/auth/auth.setup.ts.frag +40 -0
  64. package/tm/web/backend/test/unit/srv/auth/session.test.ts.frag +189 -0
  65. package/tm/web/backend/test/unit/srv/ent/ent.setup.ts.frag +53 -0
  66. package/tm/web/backend/test/unit/srv/ent/proxy.test.ts.frag +109 -0
  67. package/tm/web/docs/explanation/web-architecture.md.frag +50 -0
  68. package/tm/web/docs/how-to/add-a-custom-entity-view.md.frag +53 -0
  69. package/tm/web/docs/how-to/change-the-theme.md.frag +63 -0
  70. package/tm/web/docs/how-to/customise-the-web-app.md.frag +68 -0
  71. package/tm/web/docs/how-to/use-the-api.md.frag +53 -0
  72. package/tm/web/docs/reference/web-app.md.frag +98 -0
  73. package/tm/web/web/AGENTS.md.frag +52 -0
  74. package/tm/web/web/e2e/smoke.spec.js.frag +13 -11
  75. package/tm/web/web/index.html.frag +3 -0
  76. package/tm/web/web/package.json.frag +4 -1
  77. package/tm/web/web/playwright.config.js.frag +6 -1
  78. package/tm/web/web/src/api.js.frag +92 -0
  79. package/tm/web/web/src/bus.js.frag +46 -23
  80. package/tm/web/web/src/cmp/admin.js.frag +292 -193
  81. package/tm/web/web/src/cmp/admin.md.frag +51 -0
  82. package/tm/web/web/src/cmp/app.js.frag +12 -15
  83. package/tm/web/web/src/cmp/app.md.frag +28 -0
  84. package/tm/web/web/src/cmp/auth.js.frag +69 -41
  85. package/tm/web/web/src/cmp/auth.md.frag +36 -0
  86. package/tm/web/web/src/cmp/public.js.frag +58 -0
  87. package/tm/web/web/src/cmp/public.md.frag +26 -0
  88. package/tm/web/web/src/cmp/settings.js.frag +178 -0
  89. package/tm/web/web/src/cmp/settings.md.frag +30 -0
  90. package/tm/web/web/src/cmp/shell.js.frag +231 -0
  91. package/tm/web/web/src/cmp/shell.md.frag +49 -0
  92. package/tm/web/web/src/cmp/view/custom-view.js.frag +47 -0
  93. package/tm/web/web/src/cmp/view/custom-view.md.frag +31 -0
  94. package/tm/web/web/src/custom.css.frag +8 -0
  95. package/tm/web/web/src/customise.js.frag +30 -0
  96. package/tm/web/web/src/hooks.js.frag +79 -0
  97. package/tm/web/web/src/main.js.frag +17 -4
  98. package/tm/web/web/src/model.js.frag +162 -0
  99. package/tm/web/web/src/style.css.frag +135 -21
  100. package/tm/web/web/src/theme.js.frag +82 -0
package/README.md CHANGED
@@ -1,5 +1,54 @@
1
- # Build
1
+ # @voxgig/build
2
2
 
3
- PROTOTYPE.
3
+ Code generation for Voxgig system projects. Reads the compiled
4
+ [voxgig-model](https://github.com/voxgig/model) (`model.json`) and generates
5
+ deployment artifacts and application code with the
6
+ [jostraca](https://github.com/jostraca/jostraca) templating library:
4
7
 
8
+ - **EnvLambda** — AWS Lambda deployment templates (Serverless function
9
+ defs, per-service handlers, resources).
10
+ - **EnvGen** — per-environment deployment artifacts (`local`, `basic`,
11
+ `docker`, `vm`, `aws`, `azure`, `cloudflare`, `web`) driven by the
12
+ model's `main: env:` declarations.
13
+ - **EnvWeb** — a full model-driven enterprise web app: SPA frontend
14
+ (public site, login, app shell, generic entity CRUD with relationship
15
+ navigation, settings), backend web runner, auth + generic entity
16
+ services, design themes, customisation hooks, and custom entity views.
17
+ - **Docs** — model-driven documentation for generated projects: mermaid
18
+ ER / message-flow / system-map diagrams and per-service READMEs,
19
+ regenerated on every model-build.
20
+ - **Api** — a strict-JSON REST API defined by the model (`main.api`):
21
+ uniform entity paths, API-key auth, an OpenAPI spec generated from the
22
+ entity field definitions, and generated request-validation shapes.
5
23
 
24
+ Generation is normally driven by `npm run model-build` inside a project
25
+ created with `npm create @voxgig/system` — you rarely call this package
26
+ directly.
27
+
28
+ ## Documentation
29
+
30
+ Organised by the [Diátaxis](https://diataxis.fr) framework:
31
+
32
+ - **Tutorial**: [From model to generated app](docs/tutorial.md)
33
+ - **How-to guides**:
34
+ - [Customise generation templates](docs/how-to/customise-templates.md)
35
+ - [Generate the web app (EnvWeb)](docs/how-to/generate-the-web-app.md)
36
+ - [Add a target environment](docs/how-to/add-an-environment.md)
37
+ - **Reference**:
38
+ - [Public API](docs/reference/api.md)
39
+ - [EnvWeb: files, slots, model inputs](docs/reference/envweb.md)
40
+ - **Explanation**: [Design](docs/explanation/design.md)
41
+
42
+ Working on this repo with an AI agent? See [AGENTS.md](AGENTS.md).
43
+
44
+ ## Develop
45
+
46
+ ```bash
47
+ npm install
48
+ npm run build # tsc -> dist/ (dist is committed; always rebuild before commit)
49
+ npm test # node:test + coverage thresholds
50
+ ```
51
+
52
+ ## License
53
+
54
+ MIT. Copyright (c) Voxgig Ltd.
package/build.ts CHANGED
@@ -19,6 +19,8 @@ import { resources_yml } from './env/lambda/res_yml'
19
19
 
20
20
  import { env_gen, ENV_FILES, ENV_SRC, KINDS as ENV_KINDS } from './env/env_gen'
21
21
  import { web_gen, WEB_FILES } from './env/web/web_gen'
22
+ import { doc_gen } from './doc/doc_gen'
23
+ import { api_gen } from './api/api_gen'
22
24
 
23
25
  import {
24
26
  generate, empty, TM,
@@ -55,6 +57,22 @@ const EnvWeb = {
55
57
  }
56
58
 
57
59
 
60
+ // Docs: model-driven documentation (mermaid ER/message-flow/system-map
61
+ // diagrams + per-service READMEs), regenerated every model-build. See
62
+ // doc/doc_gen.ts.
63
+ const Docs = {
64
+ doc_gen,
65
+ }
66
+
67
+
68
+ // Api: the strict-JSON REST API (model main.api) - OpenAPI spec from the
69
+ // entity field definitions + generated request-validation shapes. See
70
+ // api/api_gen.ts.
71
+ const Api = {
72
+ api_gen,
73
+ }
74
+
75
+
58
76
  // Fragment tooling (used by voxgig-system template list/eject/diff, and
59
77
  // available to project code).
60
78
  const Fragments = {
@@ -69,6 +87,8 @@ export {
69
87
  EnvLambda,
70
88
  EnvGen,
71
89
  EnvWeb,
90
+ Docs,
91
+ Api,
72
92
  Fragments,
73
93
 
74
94
  // Building blocks for ejected project templates (src/gen/<name>.ts
@@ -0,0 +1,7 @@
1
+ type ApiSpec = {
2
+ root: string;
3
+ };
4
+ declare const api_gen: (model: any, spec: ApiSpec) => Promise<{
5
+ created: string[];
6
+ }>;
7
+ export { api_gen, };
@@ -0,0 +1,370 @@
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.api_gen = void 0;
8
+ // Api: generation for the strict-JSON REST API (model main.api).
9
+ // Regenerated on every model-build (pure functions of the model,
10
+ // content-diffed, AUTO-GENERATED):
11
+ //
12
+ // backend/gen/api/openapi.json OpenAPI 3.1 spec; schemas from the
13
+ // entity field definitions (an entity
14
+ // response schema plus <Name>Create /
15
+ // <Name>Update request schemas, which
16
+ // mirror the gubu shapes below)
17
+ // backend/gen/api/openapi.yaml the same spec in YAML - the format
18
+ // most SDK/codegen tools (incl.
19
+ // @voxgig/sdkgen) expect
20
+ // backend/src/srv/api/valid_gen.ts gubu shapes per exposed entity op,
21
+ // used by the api service to validate
22
+ // request bodies (strict: closed)
23
+ //
24
+ // The JSON and YAML are the SAME object (openapi(model)), just serialized
25
+ // twice - they never diverge.
26
+ //
27
+ // Exposure rules (same as the api service's expose.ts): application
28
+ // entities are exposed by default, the sys zone never is, per-entity
29
+ // overrides live under main.api.ent.
30
+ const fs_1 = __importDefault(require("fs"));
31
+ const path_1 = __importDefault(require("path"));
32
+ const js_yaml_1 = __importDefault(require("js-yaml"));
33
+ // Server-managed fields: never client-writable (and readOnly in OpenAPI).
34
+ const MANAGED = ['id', 'owner_id', 't_c', 't_m'];
35
+ function apiConf(model) {
36
+ const api = (model.main && model.main.api) || {};
37
+ return {
38
+ active: false !== api.active && null != model.main.api,
39
+ prefix: api.prefix || '/api',
40
+ version: api.version || 'v1',
41
+ ent: api.ent || {},
42
+ };
43
+ }
44
+ function exposed(model) {
45
+ const conf = apiConf(model);
46
+ const out = [];
47
+ const zones = (model.main && model.main.ent) || {};
48
+ for (const zone of Object.keys(zones)) {
49
+ if ('sys' === zone) {
50
+ continue;
51
+ }
52
+ for (const name of Object.keys(zones[zone])) {
53
+ const canon = zone + '/' + name;
54
+ const entconf = conf.ent[canon];
55
+ if (entconf && false === entconf.active) {
56
+ continue;
57
+ }
58
+ out.push({ canon, zone, name, def: zones[zone][name] || {} });
59
+ }
60
+ }
61
+ return out.sort((a, b) => a.canon < b.canon ? -1 : 1);
62
+ }
63
+ function fieldsOf(def) {
64
+ const out = [];
65
+ const fields = def.field || {};
66
+ for (const fname of Object.keys(fields).sort()) {
67
+ const f = fields[fname] || {};
68
+ const valid = null == f.valid ? '' : String(f.valid);
69
+ out.push({
70
+ name: fname,
71
+ kind: ['String', 'Number', 'Boolean'].includes(f.kind) ? f.kind : 'String',
72
+ required: !MANAGED.includes(fname) && !/Skip/.test(valid),
73
+ managed: MANAGED.includes(fname),
74
+ label: f.label || fname,
75
+ ref: f.ref,
76
+ });
77
+ }
78
+ return out;
79
+ }
80
+ // ---- valid_gen.ts ----
81
+ function validGenTs(model) {
82
+ const ents = exposed(model);
83
+ const lines = [];
84
+ lines.push('/* AUTO-GENERATED from the model by @voxgig/build (api_gen) - do not edit.');
85
+ lines.push(' Regenerated on every model-build. */');
86
+ lines.push('');
87
+ lines.push('// Request-body validation shapes for the REST API, derived from the');
88
+ lines.push('// entity field definitions. Shapes are CLOSED (strict JSON: unknown');
89
+ lines.push('// fields are rejected); server-managed fields (' + MANAGED.join(', ') + ')');
90
+ lines.push('// are excluded entirely. create requires the required fields; update');
91
+ lines.push('// accepts any subset (partial).');
92
+ lines.push('');
93
+ lines.push('module.exports = function makeShapes(Gubu: any) {');
94
+ lines.push(' const { Skip } = Gubu');
95
+ lines.push(' const shapes: any = {}');
96
+ lines.push('');
97
+ for (const e of ents) {
98
+ const flds = fieldsOf(e.def).filter((f) => !f.managed);
99
+ const create = flds.map((f) => ` ${f.name}: ${f.required ? f.kind : `Skip(${f.kind})`},`);
100
+ const update = flds.map((f) => ` ${f.name}: Skip(${f.kind}),`);
101
+ lines.push(` shapes['${e.canon}'] = {`);
102
+ lines.push(' create: Gubu({');
103
+ lines.push(...create);
104
+ lines.push(' }),');
105
+ lines.push(' update: Gubu({');
106
+ lines.push(...update);
107
+ lines.push(' }),');
108
+ lines.push(' }');
109
+ lines.push('');
110
+ }
111
+ lines.push(' return shapes');
112
+ lines.push('}');
113
+ lines.push('');
114
+ return lines.join('\n');
115
+ }
116
+ // ---- openapi.json ----
117
+ const KINDTYPE = {
118
+ String: 'string', Number: 'number', Boolean: 'boolean',
119
+ };
120
+ function openapi(model) {
121
+ const conf = apiConf(model);
122
+ const core = (model.main.conf && model.main.conf.core) || {};
123
+ const ents = exposed(model);
124
+ const schemas = {
125
+ Error: {
126
+ type: 'object',
127
+ additionalProperties: false,
128
+ properties: {
129
+ error: {
130
+ type: 'object',
131
+ additionalProperties: true,
132
+ properties: {
133
+ code: { type: 'string' },
134
+ message: { type: 'string' },
135
+ details: { type: 'array', items: { type: 'object' } },
136
+ },
137
+ required: ['code'],
138
+ },
139
+ },
140
+ required: ['error'],
141
+ },
142
+ };
143
+ const paths = {};
144
+ for (const e of ents) {
145
+ const sname = schemaName(e.canon);
146
+ const flds = fieldsOf(e.def);
147
+ const properties = {};
148
+ const required = [];
149
+ for (const f of flds) {
150
+ properties[f.name] = { type: KINDTYPE[f.kind], title: f.label };
151
+ if (f.managed) {
152
+ properties[f.name].readOnly = true;
153
+ }
154
+ if (f.ref) {
155
+ properties[f.name].description = 'Reference to ' + f.ref;
156
+ }
157
+ if (f.required) {
158
+ required.push(f.name);
159
+ }
160
+ }
161
+ schemas[sname] = {
162
+ type: 'object',
163
+ additionalProperties: false,
164
+ properties,
165
+ ...(required.length ? { required } : {}),
166
+ };
167
+ // Request bodies are NOT the entity schema. The entity schema describes
168
+ // what comes back - it carries the server-managed fields, and its
169
+ // `required` list is the create contract. What the server ACCEPTS is
170
+ // narrower, and differs per op (see validGenTs, which derives the
171
+ // enforcing gubu shapes from these same fields):
172
+ //
173
+ // create managed fields rejected; required fields required
174
+ // update managed fields rejected; everything optional (partial)
175
+ //
176
+ // Marking the managed fields `readOnly` on the entity schema is not
177
+ // enough on its own. It is the correct OpenAPI signal, but a closed
178
+ // schema (`additionalProperties: false`) plus `readOnly` is a
179
+ // combination most codegen tools ignore - they emit a request type with
180
+ // every property - so a generated client sends `id` and the closed gubu
181
+ // shape rejects the whole body with 400. Separate request schemas say
182
+ // the same thing in a form every tool understands.
183
+ const writable = flds.filter((f) => !f.managed);
184
+ const writableProps = {};
185
+ for (const f of writable) {
186
+ writableProps[f.name] = { type: KINDTYPE[f.kind], title: f.label };
187
+ if (f.ref) {
188
+ writableProps[f.name].description = 'Reference to ' + f.ref;
189
+ }
190
+ }
191
+ const writableRequired = writable.filter((f) => f.required).map((f) => f.name);
192
+ schemas[sname + 'Create'] = {
193
+ type: 'object',
194
+ additionalProperties: false,
195
+ properties: writableProps,
196
+ ...(writableRequired.length ? { required: writableRequired } : {}),
197
+ };
198
+ schemas[sname + 'Update'] = {
199
+ type: 'object',
200
+ additionalProperties: false,
201
+ properties: writableProps,
202
+ };
203
+ const ref = { $ref: '#/components/schemas/' + sname };
204
+ const createRef = { $ref: '#/components/schemas/' + sname + 'Create' };
205
+ const updateRef = { $ref: '#/components/schemas/' + sname + 'Update' };
206
+ const errRef = { $ref: '#/components/schemas/Error' };
207
+ const errResponses = {
208
+ '400': { description: 'Invalid request', content: { 'application/json': { schema: errRef } } },
209
+ '401': { description: 'Missing or invalid API key', content: { 'application/json': { schema: errRef } } },
210
+ '403': { description: 'Forbidden', content: { 'application/json': { schema: errRef } } },
211
+ '404': { description: 'Not found', content: { 'application/json': { schema: errRef } } },
212
+ };
213
+ const itemResult = (desc) => ({
214
+ description: desc,
215
+ content: {
216
+ 'application/json': {
217
+ schema: {
218
+ type: 'object', additionalProperties: false,
219
+ properties: { item: ref }, required: ['item'],
220
+ },
221
+ },
222
+ },
223
+ });
224
+ const base = '/' + conf.version + '/' + e.canon;
225
+ paths[base] = {
226
+ get: {
227
+ operationId: opId('list', e), summary: 'List ' + e.name + ' entities',
228
+ tags: [e.canon],
229
+ parameters: flds.map((f) => ({
230
+ name: f.name, in: 'query', required: false,
231
+ schema: { type: KINDTYPE[f.kind] },
232
+ description: 'Filter by ' + f.name,
233
+ })),
234
+ responses: {
235
+ '200': {
236
+ description: 'Matching ' + e.name + ' entities',
237
+ content: {
238
+ 'application/json': {
239
+ schema: {
240
+ type: 'object', additionalProperties: false,
241
+ properties: { items: { type: 'array', items: ref } },
242
+ required: ['items'],
243
+ },
244
+ },
245
+ },
246
+ },
247
+ ...errResponses,
248
+ },
249
+ },
250
+ post: {
251
+ operationId: opId('create', e), summary: 'Create a ' + e.name,
252
+ tags: [e.canon],
253
+ requestBody: {
254
+ required: true,
255
+ content: { 'application/json': { schema: createRef } },
256
+ },
257
+ responses: { '201': itemResult('The created ' + e.name), ...errResponses },
258
+ },
259
+ };
260
+ paths[base + '/{id}'] = {
261
+ parameters: [{
262
+ name: 'id', in: 'path', required: true, schema: { type: 'string' },
263
+ }],
264
+ get: {
265
+ operationId: opId('load', e), summary: 'Load one ' + e.name,
266
+ tags: [e.canon],
267
+ responses: { '200': itemResult('The ' + e.name), ...errResponses },
268
+ },
269
+ put: {
270
+ operationId: opId('update', e), summary: 'Update a ' + e.name + ' (partial)',
271
+ tags: [e.canon],
272
+ requestBody: {
273
+ required: true,
274
+ content: { 'application/json': { schema: updateRef } },
275
+ },
276
+ responses: { '200': itemResult('The updated ' + e.name), ...errResponses },
277
+ },
278
+ delete: {
279
+ operationId: opId('remove', e), summary: 'Remove a ' + e.name,
280
+ tags: [e.canon],
281
+ responses: {
282
+ '200': {
283
+ description: 'Removed',
284
+ content: {
285
+ 'application/json': {
286
+ schema: {
287
+ type: 'object', additionalProperties: false,
288
+ properties: { ok: { type: 'boolean' }, id: { type: 'string' } },
289
+ required: ['ok', 'id'],
290
+ },
291
+ },
292
+ },
293
+ },
294
+ ...errResponses,
295
+ },
296
+ },
297
+ };
298
+ }
299
+ return {
300
+ openapi: '3.1.0',
301
+ info: {
302
+ title: (core.name || 'system') + ' API',
303
+ version: conf.version,
304
+ description: 'Strict-JSON REST API, generated from the model. ' +
305
+ 'Uniform entity paths: <zone>/<name>[/<id>].',
306
+ },
307
+ servers: [{ url: conf.prefix }],
308
+ security: [{ bearerAuth: [] }],
309
+ components: {
310
+ securitySchemes: {
311
+ bearerAuth: {
312
+ type: 'http', scheme: 'bearer',
313
+ description: 'API access key (create one under Settings & security)',
314
+ },
315
+ },
316
+ schemas,
317
+ },
318
+ paths,
319
+ };
320
+ }
321
+ // Uniform operation ids for SDK generation: list_proj_project, ...
322
+ function opId(op, e) {
323
+ return op + '_' + e.zone + '_' + e.name;
324
+ }
325
+ function schemaName(canon) {
326
+ return canon.split('/').map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('');
327
+ }
328
+ function writeIfChanged(dest, content) {
329
+ const existing = fs_1.default.existsSync(dest) ? fs_1.default.readFileSync(dest, 'utf8') : null;
330
+ if (existing === content) {
331
+ return false;
332
+ }
333
+ fs_1.default.mkdirSync(path_1.default.dirname(dest), { recursive: true });
334
+ fs_1.default.writeFileSync(dest, content);
335
+ return true;
336
+ }
337
+ // api_gen(model, spec): generate the REST API artifacts. No-op unless
338
+ // the model declares main.api. Returns { created }.
339
+ const api_gen = async (model, spec) => {
340
+ const created = [];
341
+ if (null == (model.main && model.main.api)) {
342
+ return { created };
343
+ }
344
+ const doc = openapi(model);
345
+ const spec_json = JSON.stringify(doc, null, 2) + '\n';
346
+ if (writeIfChanged(path_1.default.join(spec.root, 'backend', 'gen', 'api', 'openapi.json'), spec_json)) {
347
+ created.push('backend/gen/api/openapi.json');
348
+ }
349
+ // YAML of the SAME object. noRefs is REQUIRED: the spec reuses $ref
350
+ // objects (the Error schema ref appears in every error response, each
351
+ // entity ref in several operations), and without noRefs js-yaml emits
352
+ // anchors/aliases (&ref_0 / *ref_0) that most OpenAPI codegen tools -
353
+ // including @voxgig/sdkgen - do not resolve. lineWidth:-1 stops long
354
+ // strings (descriptions, the server url) being line-folded.
355
+ const spec_yaml = js_yaml_1.default.dump(doc, { noRefs: true, lineWidth: -1 });
356
+ if (writeIfChanged(path_1.default.join(spec.root, 'backend', 'gen', 'api', 'openapi.yaml'), spec_yaml)) {
357
+ created.push('backend/gen/api/openapi.yaml');
358
+ }
359
+ // The validation shapes land next to the api service - only when the
360
+ // service is implemented (its folder exists).
361
+ const srvapi = path_1.default.join(spec.root, 'backend', 'src', 'srv', 'api');
362
+ if (fs_1.default.existsSync(srvapi)) {
363
+ if (writeIfChanged(path_1.default.join(srvapi, 'valid_gen.ts'), validGenTs(model))) {
364
+ created.push('backend/src/srv/api/valid_gen.ts');
365
+ }
366
+ }
367
+ return { created: created.sort() };
368
+ };
369
+ exports.api_gen = api_gen;
370
+ //# sourceMappingURL=api_gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api_gen.js","sourceRoot":"","sources":["../../api/api_gen.ts"],"names":[],"mappings":"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"}
package/dist/build.d.ts CHANGED
@@ -56,10 +56,25 @@ declare const EnvWeb: {
56
56
  out: string;
57
57
  }[];
58
58
  };
59
+ declare const Docs: {
60
+ doc_gen: (model: any, spec: {
61
+ root: string;
62
+ srvfolder?: string;
63
+ }) => Promise<{
64
+ created: string[];
65
+ }>;
66
+ };
67
+ declare const Api: {
68
+ api_gen: (model: any, spec: {
69
+ root: string;
70
+ }) => Promise<{
71
+ created: string[];
72
+ }>;
73
+ };
59
74
  declare const Fragments: {
60
75
  load: typeof loadFragment;
61
76
  render: typeof renderFragment;
62
77
  list: typeof listFragments;
63
78
  folder: string;
64
79
  };
65
- export { EnvLambda, EnvGen, EnvWeb, Fragments, generate, empty, TM, loadFragment, renderFragment, MsgMetaShape, CoreConfShape, CloudConfShape, res_dynamo_yml, };
80
+ export { EnvLambda, EnvGen, EnvWeb, Docs, Api, Fragments, generate, empty, TM, loadFragment, renderFragment, MsgMetaShape, CoreConfShape, CloudConfShape, res_dynamo_yml, };
package/dist/build.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /* Copyright © 2022-2026 Voxgig Ltd, MIT License. */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.res_dynamo_yml = exports.CloudConfShape = exports.CoreConfShape = exports.MsgMetaShape = exports.renderFragment = exports.loadFragment = exports.TM = exports.empty = exports.generate = exports.Fragments = exports.EnvWeb = exports.EnvGen = exports.EnvLambda = void 0;
4
+ exports.res_dynamo_yml = exports.CloudConfShape = exports.CoreConfShape = exports.MsgMetaShape = exports.renderFragment = exports.loadFragment = exports.TM = exports.empty = exports.generate = exports.Fragments = exports.Api = exports.Docs = exports.EnvWeb = exports.EnvGen = exports.EnvLambda = void 0;
5
5
  // EnvLambda: generation of the Lambda deployment templates, built on the
6
6
  // jostraca templating library. The templates live in env/lambda/, one file
7
7
  // per output for convenience:
@@ -19,6 +19,8 @@ const srv_handler_1 = require("./env/lambda/srv_handler");
19
19
  const res_yml_1 = require("./env/lambda/res_yml");
20
20
  const env_gen_1 = require("./env/env_gen");
21
21
  const web_gen_1 = require("./env/web/web_gen");
22
+ const doc_gen_1 = require("./doc/doc_gen");
23
+ const api_gen_1 = require("./api/api_gen");
22
24
  const generate_1 = require("./env/lambda/generate");
23
25
  Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } });
24
26
  Object.defineProperty(exports, "empty", { enumerable: true, get: function () { return generate_1.empty; } });
@@ -54,6 +56,20 @@ const EnvWeb = {
54
56
  files: web_gen_1.WEB_FILES,
55
57
  };
56
58
  exports.EnvWeb = EnvWeb;
59
+ // Docs: model-driven documentation (mermaid ER/message-flow/system-map
60
+ // diagrams + per-service READMEs), regenerated every model-build. See
61
+ // doc/doc_gen.ts.
62
+ const Docs = {
63
+ doc_gen: doc_gen_1.doc_gen,
64
+ };
65
+ exports.Docs = Docs;
66
+ // Api: the strict-JSON REST API (model main.api) - OpenAPI spec from the
67
+ // entity field definitions + generated request-validation shapes. See
68
+ // api/api_gen.ts.
69
+ const Api = {
70
+ api_gen: api_gen_1.api_gen,
71
+ };
72
+ exports.Api = Api;
57
73
  // Fragment tooling (used by voxgig-system template list/eject/diff, and
58
74
  // available to project code).
59
75
  const Fragments = {
package/dist/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../build.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;AAEpD,yEAAyE;AACzE,2EAA2E;AAC3E,8BAA8B;AAC9B,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,wEAAwE;AACxE,qCAAqC;AAErC,kDAA8C;AAC9C,0DAAsD;AACtD,kDAAoD;AAEpD,2CAA+E;AAC/E,+CAAsD;AAEtD,oDAG8B;AAmD5B,yFArDA,mBAAQ,OAqDA;AACR,sFAtDU,gBAAK,OAsDV;AACL,mFAvDiB,aAAE,OAuDjB;AACF,6FAvDA,uBAAY,OAuDA;AACZ,+FAxDc,yBAAc,OAwDd;AArDhB,qCAA0C;AAsDxC,6FAtDO,kBAAY,OAsDP;AArDd,uCAA4D;AAsD1D,8FAtDO,oBAAa,OAsDP;AACb,+FAvDsB,qBAAc,OAuDtB;AAtDhB,yDAAqD;AAuDnD,+FAvDO,+BAAc,OAuDP;AApDhB,MAAM,SAAS,GAAG;IAChB,OAAO,EAAP,iBAAO;IACP,WAAW,EAAX,yBAAW;IACX,aAAa,EAAb,uBAAa;CACd,CAAA;AAgCC,8BAAS;AA7BX,wEAAwE;AACxE,yDAAyD;AACzD,MAAM,MAAM,GAAG;IACb,OAAO,EAAP,iBAAO;IACP,KAAK,EAAE,mBAAS;IAChB,QAAQ,EAAE,iBAAO;IACjB,KAAK,EAAE,CAAC,GAAG,eAAS,EAAE,KAAK,CAAC;CAC7B,CAAA;AAuBC,wBAAM;AApBR,oEAAoE;AACpE,wDAAwD;AACxD,MAAM,MAAM,GAAG;IACb,OAAO,EAAP,iBAAO;IACP,KAAK,EAAE,mBAAS;CACjB,CAAA;AAgBC,wBAAM;AAbR,wEAAwE;AACxE,8BAA8B;AAC9B,MAAM,SAAS,GAAG;IAChB,IAAI,EAAE,uBAAY;IAClB,MAAM,EAAE,yBAAc;IACtB,IAAI,EAAE,wBAAa;IACnB,MAAM,EAAE,iBAAM;CACf,CAAA;AAOC,8BAAS"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../build.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;AAEpD,yEAAyE;AACzE,2EAA2E;AAC3E,8BAA8B;AAC9B,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,wEAAwE;AACxE,qCAAqC;AAErC,kDAA8C;AAC9C,0DAAsD;AACtD,kDAAoD;AAEpD,2CAA+E;AAC/E,+CAAsD;AACtD,2CAAuC;AACvC,2CAAuC;AAEvC,oDAG8B;AAqE5B,yFAvEA,mBAAQ,OAuEA;AACR,sFAxEU,gBAAK,OAwEV;AACL,mFAzEiB,aAAE,OAyEjB;AACF,6FAzEA,uBAAY,OAyEA;AACZ,+FA1Ec,yBAAc,OA0Ed;AAvEhB,qCAA0C;AAwExC,6FAxEO,kBAAY,OAwEP;AAvEd,uCAA4D;AAwE1D,8FAxEO,oBAAa,OAwEP;AACb,+FAzEsB,qBAAc,OAyEtB;AAxEhB,yDAAqD;AAyEnD,+FAzEO,+BAAc,OAyEP;AAtEhB,MAAM,SAAS,GAAG;IAChB,OAAO,EAAP,iBAAO;IACP,WAAW,EAAX,yBAAW;IACX,aAAa,EAAb,uBAAa;CACd,CAAA;AAgDC,8BAAS;AA7CX,wEAAwE;AACxE,yDAAyD;AACzD,MAAM,MAAM,GAAG;IACb,OAAO,EAAP,iBAAO;IACP,KAAK,EAAE,mBAAS;IAChB,QAAQ,EAAE,iBAAO;IACjB,KAAK,EAAE,CAAC,GAAG,eAAS,EAAE,KAAK,CAAC;CAC7B,CAAA;AAuCC,wBAAM;AApCR,oEAAoE;AACpE,wDAAwD;AACxD,MAAM,MAAM,GAAG;IACb,OAAO,EAAP,iBAAO;IACP,KAAK,EAAE,mBAAS;CACjB,CAAA;AAgCC,wBAAM;AA7BR,uEAAuE;AACvE,sEAAsE;AACtE,kBAAkB;AAClB,MAAM,IAAI,GAAG;IACX,OAAO,EAAP,iBAAO;CACR,CAAA;AAyBC,oBAAI;AAtBN,yEAAyE;AACzE,sEAAsE;AACtE,kBAAkB;AAClB,MAAM,GAAG,GAAG;IACV,OAAO,EAAP,iBAAO;CACR,CAAA;AAkBC,kBAAG;AAfL,wEAAwE;AACxE,8BAA8B;AAC9B,MAAM,SAAS,GAAG;IAChB,IAAI,EAAE,uBAAY;IAClB,MAAM,EAAE,yBAAc;IACtB,IAAI,EAAE,wBAAa;IACnB,MAAM,EAAE,iBAAM;CACf,CAAA;AASC,8BAAS"}
@@ -0,0 +1,8 @@
1
+ type DocSpec = {
2
+ root: string;
3
+ srvfolder?: string;
4
+ };
5
+ declare const doc_gen: (model: any, spec: DocSpec) => Promise<{
6
+ created: string[];
7
+ }>;
8
+ export { doc_gen, };