@voxgig/sdkgen 4.24.3 → 4.25.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/bin/voxgig-sdkgen +1 -1
- package/dist/action/action.js +9 -5
- package/dist/action/action.js.map +1 -1
- package/dist/action/check.js +36 -7
- package/dist/action/check.js.map +1 -1
- package/dist/action/doctor.js +8 -9
- package/dist/action/doctor.js.map +1 -1
- package/dist/action/feature.js +1 -1
- package/dist/action/feature.js.map +1 -1
- package/dist/action/kind.d.ts +2 -1
- package/dist/action/kind.js +21 -23
- package/dist/action/kind.js.map +1 -1
- package/dist/action/package.js +1 -1
- package/dist/action/package.js.map +1 -1
- package/dist/action/remove.js +6 -5
- package/dist/action/remove.js.map +1 -1
- package/dist/action/resolve.js +2 -2
- package/dist/action/resolve.js.map +1 -1
- package/dist/action/target.js +4 -2
- package/dist/action/target.js.map +1 -1
- package/dist/cmp/AgentGuide.js +2 -2
- package/dist/cmp/AgentGuideContent.js +9 -9
- package/dist/cmp/AgentGuideFeature.js +3 -3
- package/dist/cmp/AgentGuideFeature.js.map +1 -1
- package/dist/cmp/AgentGuideTop.js +1 -1
- package/dist/cmp/Deploy.js +2 -2
- package/dist/helpers/definition.d.ts +8 -1
- package/dist/helpers/definition.js +115 -10
- package/dist/helpers/definition.js.map +1 -1
- package/dist/helpers/manifest.js +4 -3
- package/dist/helpers/manifest.js.map +1 -1
- package/dist/helpers/modelcheck.d.ts +1 -0
- package/dist/helpers/modelcheck.js +9 -1
- package/dist/helpers/modelcheck.js.map +1 -1
- package/dist/helpers/shipped.js +1 -1
- package/dist/helpers/shipped.js.map +1 -1
- package/dist/sdkgen.js +6 -2
- package/dist/sdkgen.js.map +1 -1
- package/dist/testkit.js +6 -6
- package/dist/testkit.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/project/.sdk/model/feature/feature-index.aontu +27 -0
- package/project/.sdk/src/cmp/zig/fragment/Root.fragment.zig +1 -1
- package/project/.sdk/tm/c/Makefile +1 -1
- package/project/.sdk/tm/c/feature/secrets.h +2 -2
- package/project/.sdk/tm/c/feature/validate.h +2 -2
- package/project/.sdk/tm/clojure/src/sdk/features.clj +1 -1
- package/project/.sdk/tm/cpp/Makefile +1 -1
- package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +1 -1
- package/project/.sdk/tm/csharp/Makefile +1 -1
- package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +1 -1
- package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +1 -1
- package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +1 -1
- package/project/.sdk/tm/lua/test/primary_utility_test.lua +1 -1
- package/project/.sdk/tm/ocaml/sdk_features.ml +1 -1
- package/project/.sdk/tm/perl/t/primary_utility.t +1 -1
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +1 -1
- package/project/.sdk/tm/py/test/test_primary_utility.py +1 -1
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +1 -1
- package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +1 -1
- package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +1 -1
- package/project/.sdk/tm/swift/Makefile +1 -1
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +1 -1
- package/project/.sdk/tm/ts/test/utility/Corpus.test.ts +1 -1
- package/project/sdkgen-package.json +1 -1
- package/src/action/action.ts +13 -5
- package/src/action/check.ts +52 -8
- package/src/action/doctor.ts +12 -12
- package/src/action/feature.ts +1 -1
- package/src/action/kind.ts +32 -30
- package/src/action/package.ts +1 -1
- package/src/action/remove.ts +10 -6
- package/src/action/resolve.ts +3 -3
- package/src/action/target.ts +5 -2
- package/src/cmp/AgentGuide.ts +2 -2
- package/src/cmp/AgentGuideContent.ts +9 -9
- package/src/cmp/AgentGuideFeature.ts +3 -3
- package/src/cmp/AgentGuideTop.ts +1 -1
- package/src/cmp/Deploy.ts +2 -2
- package/src/helpers/definition.ts +163 -10
- package/src/helpers/manifest.ts +5 -4
- package/src/helpers/modelcheck.ts +15 -1
- package/src/helpers/shipped.ts +1 -1
- package/src/sdkgen.ts +8 -2
- package/src/testkit.ts +6 -6
- package/testkit.js +1 -1
- package/project/.sdk/model/feature/feature-index.aon +0 -27
- /package/model/{sdkgen.aon → sdkgen.aontu} +0 -0
- /package/project/.sdk/model/feature/{audit.aon → audit.aontu} +0 -0
- /package/project/.sdk/model/feature/{cache.aon → cache.aontu} +0 -0
- /package/project/.sdk/model/feature/{clienttrack.aon → clienttrack.aontu} +0 -0
- /package/project/.sdk/model/feature/{cost.aon → cost.aontu} +0 -0
- /package/project/.sdk/model/feature/{debug.aon → debug.aontu} +0 -0
- /package/project/.sdk/model/feature/{idempotency.aon → idempotency.aontu} +0 -0
- /package/project/.sdk/model/feature/{log.aon → log.aontu} +0 -0
- /package/project/.sdk/model/feature/{metrics.aon → metrics.aontu} +0 -0
- /package/project/.sdk/model/feature/{netsim.aon → netsim.aontu} +0 -0
- /package/project/.sdk/model/feature/{paging.aon → paging.aontu} +0 -0
- /package/project/.sdk/model/feature/{proxy.aon → proxy.aontu} +0 -0
- /package/project/.sdk/model/feature/{ratelimit.aon → ratelimit.aontu} +0 -0
- /package/project/.sdk/model/feature/{rbac.aon → rbac.aontu} +0 -0
- /package/project/.sdk/model/feature/{retry.aon → retry.aontu} +0 -0
- /package/project/.sdk/model/feature/{secrets.aon → secrets.aontu} +0 -0
- /package/project/.sdk/model/feature/{streaming.aon → streaming.aontu} +0 -0
- /package/project/.sdk/model/feature/{telemetry.aon → telemetry.aontu} +0 -0
- /package/project/.sdk/model/feature/{test.aon → test.aontu} +0 -0
- /package/project/.sdk/model/feature/{timeout.aon → timeout.aontu} +0 -0
- /package/project/.sdk/model/feature/{validate.aon → validate.aontu} +0 -0
- /package/project/.sdk/model/target/{c.aon → c.aontu} +0 -0
- /package/project/.sdk/model/target/{clojure.aon → clojure.aontu} +0 -0
- /package/project/.sdk/model/target/{cpp.aon → cpp.aontu} +0 -0
- /package/project/.sdk/model/target/{csharp.aon → csharp.aontu} +0 -0
- /package/project/.sdk/model/target/{elixir.aon → elixir.aontu} +0 -0
- /package/project/.sdk/model/target/{go-cli.aon → go-cli.aontu} +0 -0
- /package/project/.sdk/model/target/{go-mcp.aon → go-mcp.aontu} +0 -0
- /package/project/.sdk/model/target/{go.aon → go.aontu} +0 -0
- /package/project/.sdk/model/target/{java.aon → java.aontu} +0 -0
- /package/project/.sdk/model/target/{js.aon → js.aontu} +0 -0
- /package/project/.sdk/model/target/{kotlin.aon → kotlin.aontu} +0 -0
- /package/project/.sdk/model/target/{lua.aon → lua.aontu} +0 -0
- /package/project/.sdk/model/target/{ocaml.aon → ocaml.aontu} +0 -0
- /package/project/.sdk/model/target/{perl.aon → perl.aontu} +0 -0
- /package/project/.sdk/model/target/{php.aon → php.aontu} +0 -0
- /package/project/.sdk/model/target/{py-data.aon → py-data.aontu} +0 -0
- /package/project/.sdk/model/target/{py.aon → py.aontu} +0 -0
- /package/project/.sdk/model/target/{rb.aon → rb.aontu} +0 -0
- /package/project/.sdk/model/target/{rust.aon → rust.aontu} +0 -0
- /package/project/.sdk/model/target/{scala.aon → scala.aontu} +0 -0
- /package/project/.sdk/model/target/{swift.aon → swift.aontu} +0 -0
- /package/project/.sdk/model/target/{ts.aon → ts.aontu} +0 -0
- /package/project/.sdk/model/target/{zig.aon → zig.aontu} +0 -0
package/src/action/remove.ts
CHANGED
|
@@ -11,7 +11,9 @@ import type {
|
|
|
11
11
|
|
|
12
12
|
import { SdkGenError } from '../utility'
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
assertMigrated, definitionPathAny, indexName, indexPath,
|
|
16
|
+
} from '../helpers/definition'
|
|
15
17
|
|
|
16
18
|
import { findFeatureSources, BASE_FEATURE } from '../helpers/featureSource'
|
|
17
19
|
|
|
@@ -158,8 +160,10 @@ async function planRemove(
|
|
|
158
160
|
'\n a name matches ' + ITEM_NAME_RE.source + ' — it is not a path')
|
|
159
161
|
}
|
|
160
162
|
|
|
163
|
+
assertMigrated(fs, [indexPath(root, kind)])
|
|
164
|
+
|
|
161
165
|
const declared: any = kindCollection(model, kind)?.[name]
|
|
162
|
-
const modelfile =
|
|
166
|
+
const modelfile = definitionPathAny(fs, root, kind, name)
|
|
163
167
|
const hasModel = fs.existsSync(modelfile)
|
|
164
168
|
|
|
165
169
|
if (null == declared && !hasModel) {
|
|
@@ -213,7 +217,7 @@ async function planRemove(
|
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
if (hasModel) {
|
|
216
|
-
plan.files.push('model/' + kind + '/' +
|
|
220
|
+
plan.files.push('model/' + kind + '/' + Path.basename(modelfile))
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
const wanted = new Set(plan.files)
|
|
@@ -226,7 +230,7 @@ async function planRemove(
|
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
232
|
|
|
229
|
-
const index =
|
|
233
|
+
const index = indexPath(root, kind)
|
|
230
234
|
plan.indexed = fs.existsSync(index) &&
|
|
231
235
|
removeIndexEntries(String(fs.readFileSync(index, 'utf8')), [name]) !==
|
|
232
236
|
String(fs.readFileSync(index, 'utf8'))
|
|
@@ -353,7 +357,7 @@ function projectMentions(kind: string, name: string, actx: ActionContext): strin
|
|
|
353
357
|
|
|
354
358
|
const out: string[] = []
|
|
355
359
|
for (const r of walk(fs, modeldir)) {
|
|
356
|
-
if (
|
|
360
|
+
if (!/\.(aontu|aon)$/.test(r) || r.startsWith(own)) {
|
|
357
361
|
continue
|
|
358
362
|
}
|
|
359
363
|
let src = ''
|
|
@@ -404,7 +408,7 @@ function applyRemove(plan: RemovePlan, actx: ActionContext, dryrun: boolean): st
|
|
|
404
408
|
}
|
|
405
409
|
|
|
406
410
|
if (plan.indexed) {
|
|
407
|
-
const index =
|
|
411
|
+
const index = indexPath(root, kind)
|
|
408
412
|
say('model/' + kind + '/' + indexName(kind), 'the index entry for ' + name)
|
|
409
413
|
if (!dryrun) {
|
|
410
414
|
fs.writeFileSync(index,
|
package/src/action/resolve.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { getelem } from '@voxgig/struct'
|
|
|
6
6
|
|
|
7
7
|
import { KIT } from '../types'
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { definitionPathAny } from '../helpers/definition'
|
|
10
10
|
import { readManifest, checkShape, ITEM_NAME_RE } from '../helpers/manifest'
|
|
11
11
|
|
|
12
12
|
|
|
@@ -123,7 +123,7 @@ function resolveSource(ref: string, kind: string, ctx$: any): Source {
|
|
|
123
123
|
// Path.join, not concatenation: an absolute Windows ref makes `folder`
|
|
124
124
|
// backslash-separated, and appending '/model/...' produced a mixed-
|
|
125
125
|
// separator path that some readers handle and others do not.
|
|
126
|
-
model:
|
|
126
|
+
model: definitionPathAny(fs, folder, kind, origname),
|
|
127
127
|
|
|
128
128
|
package: sourcePackage(fs, folder, kind, origname, ctx$),
|
|
129
129
|
}
|
|
@@ -276,7 +276,7 @@ function providesStill(
|
|
|
276
276
|
// No manifest, or one too malformed to be believed: a bare `.sdk`-shaped
|
|
277
277
|
// folder is a legal source, and its definition file is the only claim it
|
|
278
278
|
// makes.
|
|
279
|
-
return fs.existsSync(
|
|
279
|
+
return fs.existsSync(definitionPathAny(fs, folder, kind, seek))
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
|
package/src/action/target.ts
CHANGED
|
@@ -20,6 +20,8 @@ import { templateReplacements, provenanceReplace } from '../helpers/stdrep'
|
|
|
20
20
|
|
|
21
21
|
import { isJunk, copyOpts } from '../helpers/junk'
|
|
22
22
|
|
|
23
|
+
import { definitionPathAny, migrateIncludes } from '../helpers/definition'
|
|
24
|
+
|
|
23
25
|
import { Aontu } from 'aontu'
|
|
24
26
|
|
|
25
27
|
import {
|
|
@@ -496,11 +498,12 @@ function readTargetFeature(
|
|
|
496
498
|
const { log } = ctx$
|
|
497
499
|
const fs = ctx$.fs()
|
|
498
500
|
|
|
499
|
-
const path = tfolder
|
|
501
|
+
const path = definitionPathAny(fs, tfolder, 'target', torigname)
|
|
500
502
|
|
|
501
503
|
try {
|
|
502
504
|
const errs: any[] = []
|
|
503
|
-
const
|
|
505
|
+
const src = migrateIncludes(fs.readFileSync(path, 'utf8'))
|
|
506
|
+
const model = new Aontu().generate(src, { path, errs })
|
|
504
507
|
|
|
505
508
|
if (0 < errs.length) {
|
|
506
509
|
throw new Error(errs.map((e: any) => e.msg || String(e)).join('\n'))
|
package/src/cmp/AgentGuide.ts
CHANGED
|
@@ -61,7 +61,7 @@ ${langCommandsBlock(lang)}
|
|
|
61
61
|
|
|
62
62
|
| Source | Path | Edit when… |
|
|
63
63
|
| --- | --- | --- |
|
|
64
|
-
| Target definition | \`.sdk/model/target/${lang}.
|
|
64
|
+
| Target definition | \`.sdk/model/target/${lang}.aontu\` | deps, module, extension, phases change |
|
|
65
65
|
| Templates | \`.sdk/tm/${lang}/\` | the file is the **same for every API** (runtime, transport, base classes) — copied verbatim with placeholder substitution |
|
|
66
66
|
| Components | \`.sdk/src/cmp/${lang}/\` | the file's shape **depends on the API** (entities, constructor, README, tests) — TypeScript that walks the model |
|
|
67
67
|
|
|
@@ -88,7 +88,7 @@ Each feature's runtime and its own guide live in \`src/feature/<name>/\`.
|
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
90
90
|
Content(`Each feature is a flat file in the \`feature/\` package. Its hooks and
|
|
91
|
-
default activation come from \`.sdk/model/feature/<name>.
|
|
91
|
+
default activation come from \`.sdk/model/feature/<name>.aontu\`; customise
|
|
92
92
|
the runtime under \`.sdk/tm/${lang}/feature/\` and regenerate.
|
|
93
93
|
|
|
94
94
|
| Feature | Runtime file | Active hooks |
|
|
@@ -196,11 +196,11 @@ npm run build && npm run generate
|
|
|
196
196
|
|
|
197
197
|
To author a **new** feature:
|
|
198
198
|
|
|
199
|
-
1. Define its model at \`.sdk/model/feature/<name>.
|
|
199
|
+
1. Define its model at \`.sdk/model/feature/<name>.aontu\` — \`name: key()\`,
|
|
200
200
|
\`title\`, \`version\`, \`active\`, \`config.options.active\`, a \`hook\`
|
|
201
201
|
map (\`<Stage>: active: true\`), and per-language \`deps\`.
|
|
202
|
-
2. Register it in \`.sdk/model/feature/feature-index.
|
|
203
|
-
\`@"<name>.
|
|
202
|
+
2. Register it in \`.sdk/model/feature/feature-index.aontu\` with
|
|
203
|
+
\`@"<name>.aontu"\`.
|
|
204
204
|
3. Provide the per-language runtime under that target's feature template dir
|
|
205
205
|
(\`.sdk/tm/<lang>/src/feature/<name>/\` for ts/js, \`.sdk/tm/<lang>/feature/\`
|
|
206
206
|
otherwise) — the \`FEATURE_Name\` / \`FEATURE_VERSION\` placeholders are
|
|
@@ -225,23 +225,23 @@ Each language target is generated from **two layers**:
|
|
|
225
225
|
|
|
226
226
|
Placeholders substituted on copy: \`ProjectName\` (Pascal-case SDK name),
|
|
227
227
|
\`GOMODULE\` (Go module path), \`FEATURE_Name\` / \`FEATURE_VERSION\`, and the
|
|
228
|
-
\`$$path$$\` interpolation of a model value (such as the name) in \`.
|
|
228
|
+
\`$$path$$\` interpolation of a model value (such as the name) in \`.aontu\`.
|
|
229
229
|
|
|
230
230
|
Propagate a change: edit the template/component → \`npm run build\` (only
|
|
231
231
|
needed if you touched a component) → \`npm run generate\`. Target shape and
|
|
232
|
-
deps live in \`.sdk/model/target/<lang>.
|
|
233
|
-
\`.sdk/model/feature/<name>.
|
|
232
|
+
deps live in \`.sdk/model/target/<lang>.aontu\`; features in
|
|
233
|
+
\`.sdk/model/feature/<name>.aontu\`.
|
|
234
234
|
`
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
|
|
238
238
|
function aontuSection(): string {
|
|
239
|
-
return `## The model language (aontu, \`.
|
|
239
|
+
return `## The model language (aontu, \`.aontu\` files)
|
|
240
240
|
|
|
241
241
|
The model is one structured object assembled by **aontu** (a unification
|
|
242
242
|
engine) from three sources: the API model (entities/operations, from the
|
|
243
243
|
OpenAPI spec via \`@voxgig/apidef\`), the base schema, and the target/feature
|
|
244
|
-
definitions in \`.sdk/model/\`. An \`.
|
|
244
|
+
definitions in \`.sdk/model/\`. An \`.aontu\` file is a relaxed JSON (jsonic
|
|
245
245
|
syntax) with unification semantics:
|
|
246
246
|
|
|
247
247
|
| Syntax | Meaning |
|
|
@@ -251,7 +251,7 @@ syntax) with unification semantics:
|
|
|
251
251
|
| \`*default \\| type\` | A default value unified against a type (e.g. \`*true \\| boolean\`). |
|
|
252
252
|
| \`name: key()\` | Bind a field to its map key (so \`feature: log: {}\` gets \`name: 'log'\`). |
|
|
253
253
|
| \`$$path$$\` | Interpolate a model value into a string — e.g. the SDK \`name\`. |
|
|
254
|
-
| \`@"./file.
|
|
254
|
+
| \`@"./file.aontu"\` | Include another fragment (how the index files work). The \`./\` is required on a local path. |
|
|
255
255
|
| \`x: .y\` | Reference another path's value (e.g. \`deps: ts: .js\`). |
|
|
256
256
|
|
|
257
257
|
For example, the schema for every feature entry:
|
|
@@ -65,8 +65,8 @@ later feature can override an earlier one.
|
|
|
65
65
|
|
|
66
66
|
| Part | Path |
|
|
67
67
|
| --- | --- |
|
|
68
|
-
| Model definition | \`.sdk/model/feature/${name}.
|
|
69
|
-
| Registered in | \`.sdk/model/feature/feature-index.
|
|
68
|
+
| Model definition | \`.sdk/model/feature/${name}.aontu\` (name, title, version, \`config.options.active\`, the \`hook\` map, per-language \`deps\`) |
|
|
69
|
+
| Registered in | \`.sdk/model/feature/feature-index.aontu\` (\`@"${name}.aontu"\`) |
|
|
70
70
|
| Runtime template | \`.sdk/tm/${lang}/src/feature/${name}/\` (copied here on \`generate\`; \`FEATURE_Name\`/\`FEATURE_VERSION\` substituted) |
|
|
71
71
|
|
|
72
72
|
(Paths are relative to the **project root** — four levels up from here.)
|
|
@@ -74,7 +74,7 @@ later feature can override an earlier one.
|
|
|
74
74
|
## Customising this feature
|
|
75
75
|
|
|
76
76
|
- **Turn hooks on/off**: edit the \`hook\` map in
|
|
77
|
-
\`.sdk/model/feature/${name}.
|
|
77
|
+
\`.sdk/model/feature/${name}.aontu\` (\`<Stage>: active: true|false\`).
|
|
78
78
|
- **Change default activation**: set \`config.options.active\` in the same file.
|
|
79
79
|
- **Dependencies**: edit \`deps.<lang>\` in the same file.
|
|
80
80
|
- **Behaviour**: edit the runtime template under
|
package/src/cmp/AgentGuideTop.ts
CHANGED
|
@@ -111,7 +111,7 @@ target's feature container) for the generated adapter.
|
|
|
111
111
|
|
|
112
112
|
\`\`\`
|
|
113
113
|
.sdk/
|
|
114
|
-
model/ the model: target/, feature/, and index .
|
|
114
|
+
model/ the model: target/, feature/, and index .aontu files
|
|
115
115
|
src/cmp/<lang>/ components — TypeScript that generates API-specific source
|
|
116
116
|
tm/<lang>/ templates — verbatim source copied with placeholders
|
|
117
117
|
dist/ compiled components (npm run build)
|
package/src/cmp/Deploy.ts
CHANGED
|
@@ -151,7 +151,7 @@ deploy-dry-${t.name}:
|
|
|
151
151
|
|
|
152
152
|
return `# ${model.Name} SDK deployment. GENERATED by @voxgig/sdkgen — regenerated
|
|
153
153
|
# on every \`npm run generate\` in .sdk/; publication details live in the
|
|
154
|
-
# model (.sdk/model/target/<target>.
|
|
154
|
+
# model (.sdk/model/target/<target>.aontu, \`publish\` section).
|
|
155
155
|
#
|
|
156
156
|
# Every port gets a git release tag <target>/vX.Y.Z. Ports with an ACTIVE
|
|
157
157
|
# registry also publish a package there. Credentials are injected at exec
|
|
@@ -188,7 +188,7 @@ TARGETS := ${targets.map((t: any) => t.name).join(' ')}
|
|
|
188
188
|
deploy:
|
|
189
189
|
\t@echo "Deployment is per-target — pick one (each upload is irreversible):"
|
|
190
190
|
\t@echo " make deploy-<target> targets: $(TARGETS)"
|
|
191
|
-
\t@echo "Registry state is set in the model (.sdk/model/target/<t>.
|
|
191
|
+
\t@echo "Registry state is set in the model (.sdk/model/target/<t>.aontu):"
|
|
192
192
|
${targets.map((t: any) => {
|
|
193
193
|
const reg = registryOf(t)
|
|
194
194
|
const state = reg ? `${reg.name} ${regIsActive(reg) ? 'ACTIVE' : 'publish pending (deploy = git tag only)'}` : 'tag-only'
|
|
@@ -1,12 +1,129 @@
|
|
|
1
1
|
|
|
2
2
|
import Path from 'node:path'
|
|
3
3
|
|
|
4
|
+
import { SdkGenError } from '../utility'
|
|
5
|
+
|
|
4
6
|
import { isJunk } from './junk'
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
const EXT = '.aontu'
|
|
10
|
+
|
|
11
|
+
// Pre-rename aontu files: read from a package not yet renamed, never written.
|
|
12
|
+
const LEGACY_EXT = '.aon'
|
|
13
|
+
|
|
14
|
+
const SOURCE_RE = /\.(aontu|aon)$/
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
function definitionFileName(name: string): string {
|
|
18
|
+
return name + EXT
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
7
22
|
// The definition file for one item.
|
|
8
23
|
function definitionPath(sdkfolder: string, kind: string, name: string): string {
|
|
9
|
-
return Path.join(sdkfolder, 'model', kind, name
|
|
24
|
+
return Path.join(sdkfolder, 'model', kind, definitionFileName(name))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
function legacyPath(path: string): string {
|
|
29
|
+
return path.replace(/\.aontu$/, LEGACY_EXT)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
function isLegacyPath(path: string): boolean {
|
|
34
|
+
return path.endsWith(LEGACY_EXT)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// The file an item ACTUALLY has: `.aontu`, else the pre-rename `.aon`. Without
|
|
39
|
+
// the fallback a remove reports success and leaves the file behind, and an
|
|
40
|
+
// item from a package that has not renamed its files is not found at all.
|
|
41
|
+
function definitionPathAny(
|
|
42
|
+
fs: any, sdkfolder: string, kind: string, name: string,
|
|
43
|
+
): string {
|
|
44
|
+
const current = definitionPath(sdkfolder, kind, name)
|
|
45
|
+
if (fs.existsSync(current)) {
|
|
46
|
+
return current
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const legacy = legacyPath(current)
|
|
50
|
+
|
|
51
|
+
return fs.existsSync(legacy) ? legacy : current
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
const LEGACY_INCLUDE_RE =
|
|
56
|
+
/@([ \t]*)(?:"((?:[^"\\\r\n]|\\.)*)\.aon"|'((?:[^'\\\r\n]|\\.)*)\.aon')/y
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
// Renames each `.aon` include to `.aontu`, the only extension aontu reads.
|
|
60
|
+
// Strings and comments are skipped whole, so a `.aon` that is only text stays.
|
|
61
|
+
function migrateIncludes(src: string): string {
|
|
62
|
+
return mapLegacyIncludes(src, (gap: string, quote: string, path: string) =>
|
|
63
|
+
'@' + gap + quote + path + '.aontu' + quote)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
// Removes each `.aon` include instead, leaving what the file itself declares.
|
|
68
|
+
function dropLegacyIncludes(src: string): string {
|
|
69
|
+
return mapLegacyIncludes(src, () => '')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
function mapLegacyIncludes(
|
|
74
|
+
src: string, replace: (gap: string, quote: string, path: string) => string,
|
|
75
|
+
): string {
|
|
76
|
+
let out = ''
|
|
77
|
+
let at = 0
|
|
78
|
+
|
|
79
|
+
while (at < src.length) {
|
|
80
|
+
LEGACY_INCLUDE_RE.lastIndex = at
|
|
81
|
+
const include = '@' === src[at] ? LEGACY_INCLUDE_RE.exec(src) : null
|
|
82
|
+
|
|
83
|
+
if (null != include) {
|
|
84
|
+
const [, gap, dq, sq] = include
|
|
85
|
+
out += null != dq ? replace(gap, '"', dq) : replace(gap, "'", sq)
|
|
86
|
+
at = LEGACY_INCLUDE_RE.lastIndex
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const end = textEnd(src, at)
|
|
91
|
+
out += src.slice(at, end)
|
|
92
|
+
at = end
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return out
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
// The end of the string or comment that starts at `at`, else `at + 1`.
|
|
100
|
+
function textEnd(src: string, at: number): number {
|
|
101
|
+
const c = src[at]
|
|
102
|
+
const next = src[at + 1]
|
|
103
|
+
|
|
104
|
+
if ('#' === c || ('/' === c && '/' === next)) {
|
|
105
|
+
const eol = src.indexOf('\n', at)
|
|
106
|
+
return eol < 0 ? src.length : eol
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if ('/' === c && '*' === next) {
|
|
110
|
+
const close = src.indexOf('*/', at + 2)
|
|
111
|
+
return close < 0 ? src.length : close + 2
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if ('"' === c || "'" === c || '`' === c) {
|
|
115
|
+
for (let i = at + 1; i < src.length; i++) {
|
|
116
|
+
if ('\\' === src[i]) {
|
|
117
|
+
i++
|
|
118
|
+
}
|
|
119
|
+
else if (c === src[i] || ('`' !== c && '\n' === src[i])) {
|
|
120
|
+
return i + 1
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return src.length
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return at + 1
|
|
10
127
|
}
|
|
11
128
|
|
|
12
129
|
|
|
@@ -18,13 +135,19 @@ function definitionFolder(sdkfolder: string, kind: string): string {
|
|
|
18
135
|
|
|
19
136
|
// The include list beside them.
|
|
20
137
|
function indexName(kind: string): string {
|
|
21
|
-
return kind + '-index
|
|
138
|
+
return kind + '-index' + EXT
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
function indexPath(sdkfolder: string, kind: string): string {
|
|
143
|
+
return Path.join(definitionFolder(sdkfolder, kind), indexName(kind))
|
|
22
144
|
}
|
|
23
145
|
|
|
24
146
|
|
|
25
147
|
function definitionNames(fs: any, sdkfolder: string, kind: string): string[] {
|
|
26
148
|
const dir = definitionFolder(sdkfolder, kind)
|
|
27
149
|
const index = indexName(kind)
|
|
150
|
+
const indexes = [index, legacyPath(index)]
|
|
28
151
|
|
|
29
152
|
let entries: string[]
|
|
30
153
|
try {
|
|
@@ -34,20 +157,50 @@ function definitionNames(fs: any, sdkfolder: string, kind: string): string[] {
|
|
|
34
157
|
return []
|
|
35
158
|
}
|
|
36
159
|
|
|
37
|
-
// The
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
.map((n: string) => n.replace(
|
|
44
|
-
|
|
160
|
+
// The suffix alone is not enough: `.#target.aontu` is an emacs lock link and
|
|
161
|
+
// `target.aontu.orig` a merge leftover, either of which would invent an item
|
|
162
|
+
// that then resolves nowhere. See helpers/junk. Both extensions, deduped.
|
|
163
|
+
const names = new Set<string>(entries
|
|
164
|
+
.filter((n: string) =>
|
|
165
|
+
SOURCE_RE.test(n) && !indexes.includes(n) && !isJunk(n))
|
|
166
|
+
.map((n: string) => n.replace(SOURCE_RE, '')))
|
|
167
|
+
|
|
168
|
+
return [...names].sort()
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
// A project from before the rename has the `.aon` file and no `.aontu`: aontu
|
|
173
|
+
// reads neither it nor a new `.aontu` written beside it that nothing includes.
|
|
174
|
+
function assertMigrated(fs: any, paths: string[]): void {
|
|
175
|
+
const stale = paths
|
|
176
|
+
.filter((p: string) => !fs.existsSync(p) && fs.existsSync(legacyPath(p)))
|
|
177
|
+
.map((p: string) => Path.normalize(legacyPath(p)).split(Path.sep).join('/'))
|
|
178
|
+
|
|
179
|
+
if (0 === stale.length) {
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
throw new SdkGenError(
|
|
184
|
+
'This project predates .aontu model files: ' + stale.join(', ') +
|
|
185
|
+
(1 === stale.length ? ' has' : ' have') + ' no .aontu counterpart, ' +
|
|
186
|
+
'and aontu reads only .aontu.' +
|
|
187
|
+
'\n Re-scaffold the project with the current create-sdkgen, which ' +
|
|
188
|
+
'migrates it:' +
|
|
189
|
+
'\n npm create @voxgig/sdkgen@latest ... (run over this project, ' +
|
|
190
|
+
'with the arguments it was created with)')
|
|
45
191
|
}
|
|
46
192
|
|
|
47
193
|
|
|
48
194
|
export {
|
|
195
|
+
assertMigrated,
|
|
196
|
+
definitionFileName,
|
|
49
197
|
definitionPath,
|
|
198
|
+
definitionPathAny,
|
|
50
199
|
definitionFolder,
|
|
200
|
+
dropLegacyIncludes,
|
|
51
201
|
definitionNames,
|
|
52
202
|
indexName,
|
|
203
|
+
indexPath,
|
|
204
|
+
isLegacyPath,
|
|
205
|
+
migrateIncludes,
|
|
53
206
|
}
|
package/src/helpers/manifest.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import Path from 'node:path'
|
|
3
3
|
|
|
4
|
-
import { definitionNames } from './definition'
|
|
4
|
+
import { definitionNames, definitionPathAny } from './definition'
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
const MANIFEST = 'sdkgen-package.json'
|
|
@@ -281,8 +281,9 @@ function validateManifest(
|
|
|
281
281
|
if (!claimed.has(name)) {
|
|
282
282
|
found.push({
|
|
283
283
|
level: 'warn', point: 'manifest-item-unclaimed', file, kind, name,
|
|
284
|
-
note: file + ': model/' + kind + '/' +
|
|
285
|
-
|
|
284
|
+
note: file + ': model/' + kind + '/' +
|
|
285
|
+
Path.basename(definitionPathAny(fs, sdkfolder, kind, name)) +
|
|
286
|
+
' is in the package but not listed in `provides.' + kind +
|
|
286
287
|
'` — nothing will install it'
|
|
287
288
|
})
|
|
288
289
|
}
|
|
@@ -304,7 +305,7 @@ function missingPaths(
|
|
|
304
305
|
const missing: string[] = []
|
|
305
306
|
|
|
306
307
|
if (!defined.has(name)) {
|
|
307
|
-
missing.push('model/' + kind + '/' + name + '.
|
|
308
|
+
missing.push('model/' + kind + '/' + name + '.aontu')
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
for (const tree of (def.trees ?? []).filter((t) => t.required)) {
|
|
@@ -67,6 +67,10 @@ function includeLine(file: string): string {
|
|
|
67
67
|
type CompileResult = {
|
|
68
68
|
model?: any
|
|
69
69
|
errors: string[]
|
|
70
|
+
|
|
71
|
+
// aontu's code for each error that carries one, such as
|
|
72
|
+
// `multisource_not_found` for an include that did not resolve.
|
|
73
|
+
why: string[]
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
|
|
@@ -104,14 +108,23 @@ function compileModel(
|
|
|
104
108
|
model,
|
|
105
109
|
errors: errs.map((e: any) =>
|
|
106
110
|
tidy((null == e.why ? '' : '[' + e.why + '] ') + (e.msg ?? String(e)))),
|
|
111
|
+
why: whyOf(errs),
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
catch (err: any) {
|
|
110
|
-
return {
|
|
115
|
+
return {
|
|
116
|
+
errors: [tidy(err.message ?? String(err))],
|
|
117
|
+
why: whyOf('function' === typeof err?.errs ? err.errs() : []),
|
|
118
|
+
}
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
|
|
123
|
+
function whyOf(errs: any[]): string[] {
|
|
124
|
+
return errs.map((e: any) => e?.why).filter((w: any) => 'string' === typeof w)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
115
128
|
const PUBLISH_OVERRIDES: [string, string, string][] = [
|
|
116
129
|
['publish: version', "'9.9.9'", "'8.8.8'"],
|
|
117
130
|
['publish: tag: active', 'false', 'true'],
|
|
@@ -141,6 +154,7 @@ function publishOverrideProbe(
|
|
|
141
154
|
return {
|
|
142
155
|
model: first.model ?? second.model,
|
|
143
156
|
errors: [...first.errors, ...second.errors],
|
|
157
|
+
why: [...first.why, ...second.why],
|
|
144
158
|
}
|
|
145
159
|
}
|
|
146
160
|
|
package/src/helpers/shipped.ts
CHANGED
package/src/sdkgen.ts
CHANGED
|
@@ -87,9 +87,11 @@ import {
|
|
|
87
87
|
import type { FeatureSource } from './helpers/featureSource'
|
|
88
88
|
import { stationLibrary } from './helpers/station'
|
|
89
89
|
import {
|
|
90
|
+
assertMigrated,
|
|
90
91
|
definitionPath,
|
|
91
92
|
definitionFolder,
|
|
92
93
|
definitionNames,
|
|
94
|
+
indexPath,
|
|
93
95
|
} from './helpers/definition'
|
|
94
96
|
import { isNoise, copyOpts } from './helpers/junk'
|
|
95
97
|
import {
|
|
@@ -156,6 +158,7 @@ import { edition_add } from './action/edition'
|
|
|
156
158
|
|
|
157
159
|
// The verbs, built from the kind registry — see action/dispatch.
|
|
158
160
|
import { ACTION_MAP, actionNames, needsModel } from './action/dispatch'
|
|
161
|
+
import { KINDS } from './action/kind'
|
|
159
162
|
|
|
160
163
|
|
|
161
164
|
|
|
@@ -398,7 +401,7 @@ function SdkGen(opts: SdkGenOptions) {
|
|
|
398
401
|
|
|
399
402
|
|
|
400
403
|
function resolveModel(wanted: boolean) {
|
|
401
|
-
const path = './model/sdk.
|
|
404
|
+
const path = './model/sdk.aontu'
|
|
402
405
|
const errs: any[] = []
|
|
403
406
|
|
|
404
407
|
// A verb that does not act on a project (see `needsModel`) is run where
|
|
@@ -409,6 +412,9 @@ function SdkGen(opts: SdkGenOptions) {
|
|
|
409
412
|
return { model: { main: {} } as any, url: path }
|
|
410
413
|
}
|
|
411
414
|
|
|
415
|
+
assertMigrated(fs, [
|
|
416
|
+
path, ...Object.keys(KINDS).map((kind: string) => indexPath('.', kind))])
|
|
417
|
+
|
|
412
418
|
if (null == aontu) {
|
|
413
419
|
aontu = new Aontu()
|
|
414
420
|
}
|
|
@@ -536,7 +542,7 @@ SdkGen.makeBuild = async function(opts: SdkGenOptions) {
|
|
|
536
542
|
root: opts.root,
|
|
537
543
|
def: opts.def || 'no-def',
|
|
538
544
|
kind: 'openapi-3',
|
|
539
|
-
model: opts.model ? (opts.model.folder + '/api.
|
|
545
|
+
model: opts.model ? (opts.model.folder + '/api.aontu') : 'no-model',
|
|
540
546
|
meta: opts.meta || {},
|
|
541
547
|
}
|
|
542
548
|
|
package/src/testkit.ts
CHANGED
|
@@ -102,17 +102,17 @@ function stageConsumer(opts: StageOptions = {}): Consumer {
|
|
|
102
102
|
Fs.mkdirSync(Path.join(sdk, 'model', 'target'), { recursive: true })
|
|
103
103
|
Fs.mkdirSync(Path.join(sdk, 'model', 'feature'), { recursive: true })
|
|
104
104
|
|
|
105
|
-
Fs.writeFileSync(Path.join(sdk, 'model', 'target', 'target-index.
|
|
105
|
+
Fs.writeFileSync(Path.join(sdk, 'model', 'target', 'target-index.aontu'),
|
|
106
106
|
'# Targets\n')
|
|
107
|
-
Fs.writeFileSync(Path.join(sdk, 'model', 'feature', 'feature-index.
|
|
107
|
+
Fs.writeFileSync(Path.join(sdk, 'model', 'feature', 'feature-index.aontu'),
|
|
108
108
|
'# Features\n')
|
|
109
109
|
|
|
110
110
|
const name = opts.name ?? 'demo'
|
|
111
111
|
|
|
112
|
-
Fs.writeFileSync(Path.join(sdk, 'model', 'sdk.
|
|
112
|
+
Fs.writeFileSync(Path.join(sdk, 'model', 'sdk.aontu'),
|
|
113
113
|
"name: '" + name + "'\n" +
|
|
114
|
-
'@"./target/target-index.
|
|
115
|
-
'@"./feature/feature-index.
|
|
114
|
+
'@"./target/target-index.aontu"\n' +
|
|
115
|
+
'@"./feature/feature-index.aontu"\n' +
|
|
116
116
|
(opts.extra ? opts.extra + '\n' : ''))
|
|
117
117
|
|
|
118
118
|
const modules = Path.join(sdk, 'node_modules')
|
|
@@ -138,7 +138,7 @@ function stageConsumer(opts: StageOptions = {}): Consumer {
|
|
|
138
138
|
[KIT]: { feature: {}, entity: {}, target: {} },
|
|
139
139
|
},
|
|
140
140
|
},
|
|
141
|
-
url: Path.join(sdk, 'model', 'sdk.
|
|
141
|
+
url: Path.join(sdk, 'model', 'sdk.aontu'),
|
|
142
142
|
jostraca: Jostraca({ existing: { txt: { write: true, merge: false } } }),
|
|
143
143
|
opts: { dryrun: false },
|
|
144
144
|
}
|
package/testkit.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// A stub rather than an `exports` map entry, on purpose. A map would name
|
|
6
6
|
// this subpath and, in doing so, replace the deep-import freedom this package
|
|
7
7
|
// has without one — and consumers depend on that freedom invisibly (generated
|
|
8
|
-
// model files include `@voxgig/sdkgen/model/sdkgen.
|
|
8
|
+
// model files include `@voxgig/sdkgen/model/sdkgen.aontu`; the scaffold is
|
|
9
9
|
// reached as `@voxgig/sdkgen/project/<lang>`). See the `_no_exports_comment`
|
|
10
10
|
// in package.json for what was measured.
|
|
11
11
|
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Features
|
|
2
|
-
|
|
3
|
-
# Core
|
|
4
|
-
@"./test.aon"
|
|
5
|
-
@"./log.aon"
|
|
6
|
-
@"./secrets.aon"
|
|
7
|
-
|
|
8
|
-
# Enterprise capabilities
|
|
9
|
-
@"./retry.aon"
|
|
10
|
-
@"./timeout.aon"
|
|
11
|
-
@"./ratelimit.aon"
|
|
12
|
-
@"./cache.aon"
|
|
13
|
-
@"./cost.aon"
|
|
14
|
-
@"./idempotency.aon"
|
|
15
|
-
@"./paging.aon"
|
|
16
|
-
@"./streaming.aon"
|
|
17
|
-
@"./proxy.aon"
|
|
18
|
-
@"./telemetry.aon"
|
|
19
|
-
@"./metrics.aon"
|
|
20
|
-
@"./debug.aon"
|
|
21
|
-
@"./audit.aon"
|
|
22
|
-
@"./clienttrack.aon"
|
|
23
|
-
@"./rbac.aon"
|
|
24
|
-
@"./validate.aon"
|
|
25
|
-
|
|
26
|
-
# Test support: network behaviour simulation
|
|
27
|
-
@"./netsim.aon"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|