@cms0/cms0 0.0.1
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/cms0.js +30 -0
- package/dist/cjs/cli.cjs +7 -0
- package/dist/cjs/config.cjs +6 -0
- package/dist/cjs/generated/schema-descriptor.cjs +523 -0
- package/dist/cjs/index.cjs +48 -0
- package/dist/cjs/libs/cli/build.cjs +14 -0
- package/dist/cjs/libs/cli/cli.cjs +64 -0
- package/dist/cjs/libs/cli/config-loader.cjs +211 -0
- package/dist/cjs/libs/cli/descriptor-builder-alt.cjs +221 -0
- package/dist/cjs/libs/cli/descriptor-builder.cjs +232 -0
- package/dist/cjs/libs/cli/descriptor-writer.cjs +23 -0
- package/dist/cjs/libs/cli/index.cjs +10 -0
- package/dist/cjs/libs/cli/paths.cjs +28 -0
- package/dist/cjs/libs/cli/publisher.cjs +103 -0
- package/dist/cjs/libs/cli/types.cjs +3 -0
- package/dist/cjs/libs/cli/watcher.cjs +34 -0
- package/dist/cjs/schema-descriptors.cjs +5 -0
- package/dist/cjs/utils/index.cjs +2 -0
- package/dist/esm/cli.js +5 -0
- package/dist/esm/config.js +3 -0
- package/dist/esm/generated/schema-descriptor.js +520 -0
- package/dist/esm/index.js +45 -0
- package/dist/esm/libs/cli/build.js +12 -0
- package/dist/esm/libs/cli/cli.js +62 -0
- package/dist/esm/libs/cli/config-loader.js +168 -0
- package/dist/esm/libs/cli/descriptor-builder-alt.js +216 -0
- package/dist/esm/libs/cli/descriptor-builder.js +227 -0
- package/dist/esm/libs/cli/descriptor-writer.js +18 -0
- package/dist/esm/libs/cli/index.js +4 -0
- package/dist/esm/libs/cli/paths.js +21 -0
- package/dist/esm/libs/cli/publisher.js +101 -0
- package/dist/esm/libs/cli/types.js +2 -0
- package/dist/esm/libs/cli/watcher.js +29 -0
- package/dist/esm/schema-descriptors.js +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/config.d.ts +22 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/generated/schema-descriptor.d.ts +520 -0
- package/dist/types/generated/schema-descriptor.d.ts.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/libs/cli/build.d.ts +5 -0
- package/dist/types/libs/cli/build.d.ts.map +1 -0
- package/dist/types/libs/cli/cli.d.ts +3 -0
- package/dist/types/libs/cli/cli.d.ts.map +1 -0
- package/dist/types/libs/cli/config-loader.d.ts +12 -0
- package/dist/types/libs/cli/config-loader.d.ts.map +1 -0
- package/dist/types/libs/cli/descriptor-builder-alt.d.ts +5 -0
- package/dist/types/libs/cli/descriptor-builder-alt.d.ts.map +1 -0
- package/dist/types/libs/cli/descriptor-builder.d.ts +5 -0
- package/dist/types/libs/cli/descriptor-builder.d.ts.map +1 -0
- package/dist/types/libs/cli/descriptor-writer.d.ts +4 -0
- package/dist/types/libs/cli/descriptor-writer.d.ts.map +1 -0
- package/dist/types/libs/cli/index.d.ts +4 -0
- package/dist/types/libs/cli/index.d.ts.map +1 -0
- package/dist/types/libs/cli/paths.d.ts +4 -0
- package/dist/types/libs/cli/paths.d.ts.map +1 -0
- package/dist/types/libs/cli/publisher.d.ts +5 -0
- package/dist/types/libs/cli/publisher.d.ts.map +1 -0
- package/dist/types/libs/cli/types.d.ts +8 -0
- package/dist/types/libs/cli/types.d.ts.map +1 -0
- package/dist/types/libs/cli/watcher.d.ts +5 -0
- package/dist/types/libs/cli/watcher.d.ts.map +1 -0
- package/dist/types/schema-descriptors.d.ts +2 -0
- package/dist/types/schema-descriptors.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildDescriptor = buildDescriptor;
|
|
7
|
+
// Build a schema descriptor by inspecting user types with ts-morph.
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const ts_morph_1 = require("ts-morph");
|
|
11
|
+
const config_loader_js_1 = require("./config-loader.cjs");
|
|
12
|
+
function unwrapOptional(type) {
|
|
13
|
+
let optional = false;
|
|
14
|
+
let nullable = false;
|
|
15
|
+
if (type.isUnion()) {
|
|
16
|
+
const unionTypes = type.getUnionTypes();
|
|
17
|
+
const filtered = unionTypes.filter((t) => {
|
|
18
|
+
if (t.isNull()) {
|
|
19
|
+
nullable = true;
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (t.isUndefined()) {
|
|
23
|
+
optional = true;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
});
|
|
28
|
+
if (filtered.length === 1) {
|
|
29
|
+
return { base: filtered[0], optional, nullable };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { base: type, optional, nullable };
|
|
33
|
+
}
|
|
34
|
+
function getDescriptorForType(type, modelMap, warnings, ctx, opts) {
|
|
35
|
+
const { base, optional, nullable } = unwrapOptional(type);
|
|
36
|
+
const isOptional = !!opts?.optional || optional;
|
|
37
|
+
const isNullable = !!opts?.nullable || nullable;
|
|
38
|
+
if (base.isString()) {
|
|
39
|
+
return {
|
|
40
|
+
kind: "primitive",
|
|
41
|
+
type: "string",
|
|
42
|
+
optional: isOptional,
|
|
43
|
+
nullable: isNullable,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (base.isNumber()) {
|
|
47
|
+
return {
|
|
48
|
+
kind: "primitive",
|
|
49
|
+
type: "number",
|
|
50
|
+
optional: isOptional,
|
|
51
|
+
nullable: isNullable,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (base.isBoolean()) {
|
|
55
|
+
return {
|
|
56
|
+
kind: "primitive",
|
|
57
|
+
type: "boolean",
|
|
58
|
+
optional: isOptional,
|
|
59
|
+
nullable: isNullable,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (base.isArray()) {
|
|
63
|
+
const elem = base.getArrayElementTypeOrThrow();
|
|
64
|
+
return {
|
|
65
|
+
kind: "array",
|
|
66
|
+
type: "array",
|
|
67
|
+
items: getDescriptorForType(elem, modelMap, warnings, `${ctx}[]`),
|
|
68
|
+
optional: isOptional,
|
|
69
|
+
nullable: isNullable,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const aliasSymbol = base.getAliasSymbol();
|
|
73
|
+
if (aliasSymbol) {
|
|
74
|
+
const name = aliasSymbol.getName();
|
|
75
|
+
if (modelMap[name]) {
|
|
76
|
+
return {
|
|
77
|
+
kind: "modelRef",
|
|
78
|
+
model: name,
|
|
79
|
+
optional: isOptional,
|
|
80
|
+
nullable: isNullable,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (base.isObject() && !base.isInterface()) {
|
|
85
|
+
const props = {};
|
|
86
|
+
for (const prop of base.getProperties()) {
|
|
87
|
+
const propDecl = prop.getDeclarations()[0];
|
|
88
|
+
const analyzed = unwrapOptional(propDecl.getType());
|
|
89
|
+
props[prop.getName()] = getDescriptorForType(analyzed.base, modelMap, warnings, `${ctx}.${prop.getName()}`, {
|
|
90
|
+
optional: prop.isOptional() || analyzed.optional,
|
|
91
|
+
nullable: analyzed.nullable,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
kind: "object",
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: props,
|
|
98
|
+
optional: isOptional,
|
|
99
|
+
nullable: isNullable,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// unsupported or unknown type; fall back to string and record warning
|
|
103
|
+
warnings.add(`cms0: unsupported type at ${ctx}; falling back to string`);
|
|
104
|
+
return {
|
|
105
|
+
kind: "primitive",
|
|
106
|
+
type: "string",
|
|
107
|
+
optional: isOptional,
|
|
108
|
+
nullable: isNullable,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function collectModels(sourceFiles, modelMap, warnings) {
|
|
112
|
+
sourceFiles.forEach((sf) => {
|
|
113
|
+
sf.getTypeAliases().forEach((alias) => {
|
|
114
|
+
if (!alias.hasExportKeyword())
|
|
115
|
+
return;
|
|
116
|
+
const name = alias.getName();
|
|
117
|
+
const type = alias.getType();
|
|
118
|
+
if (type.isObject()) {
|
|
119
|
+
const props = {};
|
|
120
|
+
for (const prop of type.getProperties()) {
|
|
121
|
+
const decl = prop.getDeclarations()[0];
|
|
122
|
+
const propType = decl.getType();
|
|
123
|
+
props[prop.getName()] = getDescriptorForType(propType, modelMap, warnings, `model ${name}.${prop.getName()}`);
|
|
124
|
+
}
|
|
125
|
+
modelMap[name] = { kind: "model", properties: props };
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function findRootType(sourceFiles) {
|
|
131
|
+
for (const sf of sourceFiles) {
|
|
132
|
+
const invoc = sf
|
|
133
|
+
?.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression)
|
|
134
|
+
.find((call) => call.getExpression().getText() === "cms0");
|
|
135
|
+
if (invoc) {
|
|
136
|
+
const typeArgs = invoc.getTypeArguments();
|
|
137
|
+
if (typeArgs.length > 0) {
|
|
138
|
+
return typeArgs[0].getType();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
function buildDescriptor(resolved) {
|
|
145
|
+
const tsconfig = resolved.tsconfigPath ?? (0, config_loader_js_1.findTsConfig)(resolved.entryFile);
|
|
146
|
+
const project = tsconfig
|
|
147
|
+
? new ts_morph_1.Project({ tsConfigFilePath: tsconfig })
|
|
148
|
+
: new ts_morph_1.Project();
|
|
149
|
+
const warnings = new Set();
|
|
150
|
+
const entryDir = path_1.default.dirname(path_1.default.resolve(resolved.entryFile));
|
|
151
|
+
if (!project.getSourceFile(resolved.entryFile) &&
|
|
152
|
+
fs_1.default.existsSync(resolved.entryFile)) {
|
|
153
|
+
project.addSourceFileAtPath(resolved.entryFile);
|
|
154
|
+
}
|
|
155
|
+
const sourceFiles = project.getSourceFiles().filter((sf) => {
|
|
156
|
+
const filePath = path_1.default.resolve(sf.getFilePath());
|
|
157
|
+
const rel = path_1.default.relative(entryDir, filePath);
|
|
158
|
+
return rel && !rel.startsWith("..") && !path_1.default.isAbsolute(rel);
|
|
159
|
+
});
|
|
160
|
+
const modelMap = {};
|
|
161
|
+
collectModels(sourceFiles, modelMap, warnings);
|
|
162
|
+
const rootType = findRootType(sourceFiles);
|
|
163
|
+
if (!rootType) {
|
|
164
|
+
throw new Error("Could not locate cms0<T>() invocation in project sources.");
|
|
165
|
+
}
|
|
166
|
+
const roots = {};
|
|
167
|
+
for (const prop of rootType.getProperties()) {
|
|
168
|
+
const name = prop.getName();
|
|
169
|
+
const decl = prop.getDeclarations()[0];
|
|
170
|
+
const analyzed = unwrapOptional(decl.getType());
|
|
171
|
+
const propType = analyzed.base;
|
|
172
|
+
const propOptional = prop.isOptional() || analyzed.optional;
|
|
173
|
+
const propNullable = analyzed.nullable;
|
|
174
|
+
if (propType.isArray()) {
|
|
175
|
+
const elem = propType.getArrayElementTypeOrThrow();
|
|
176
|
+
const itemDesc = getDescriptorForType(elem, modelMap, warnings, `root ${name}[]`);
|
|
177
|
+
roots[name] = {
|
|
178
|
+
type: "array",
|
|
179
|
+
items: itemDesc,
|
|
180
|
+
optional: propOptional,
|
|
181
|
+
nullable: propNullable,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
else if (propType.isObject() && !propType.isArray()) {
|
|
185
|
+
const objDesc = getDescriptorForType(propType, modelMap, warnings, `root ${name}`, {
|
|
186
|
+
optional: propOptional,
|
|
187
|
+
nullable: propNullable,
|
|
188
|
+
});
|
|
189
|
+
if (objDesc.kind === "object") {
|
|
190
|
+
roots[name] = {
|
|
191
|
+
type: "object",
|
|
192
|
+
properties: objDesc.properties,
|
|
193
|
+
optional: propOptional,
|
|
194
|
+
nullable: propNullable,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
else if (objDesc.kind === "modelRef") {
|
|
198
|
+
roots[name] = {
|
|
199
|
+
type: "object",
|
|
200
|
+
properties: {},
|
|
201
|
+
optional: propOptional,
|
|
202
|
+
nullable: propNullable,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
roots[name] = {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {},
|
|
209
|
+
optional: propOptional,
|
|
210
|
+
nullable: propNullable,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
roots[name] = {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
[name]: getDescriptorForType(propType, modelMap, warnings, `root ${name}.${name}`, {
|
|
219
|
+
optional: propOptional,
|
|
220
|
+
nullable: propNullable,
|
|
221
|
+
}),
|
|
222
|
+
},
|
|
223
|
+
optional: propOptional,
|
|
224
|
+
nullable: propNullable,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (warnings.size) {
|
|
229
|
+
warnings.forEach((w) => console.warn(w));
|
|
230
|
+
}
|
|
231
|
+
return { models: modelMap, roots };
|
|
232
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.writeDescriptorFile = writeDescriptorFile;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function writeDescriptorFile(descriptor, outputPath) {
|
|
10
|
+
const output = `// Auto-generated schema descriptor\nexport const schemaDescriptor = ${JSON.stringify(descriptor, null, 2)} as const;\n`;
|
|
11
|
+
try {
|
|
12
|
+
fs_1.default.mkdirSync(path_1.default.dirname(outputPath), { recursive: true });
|
|
13
|
+
fs_1.default.writeFileSync(outputPath, output, "utf8");
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
if (err?.code === "EPERM" || err?.code === "EACCES") {
|
|
17
|
+
console.warn(`cms0: skipped writing descriptor (no write permission): ${outputPath}`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
throw err;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runFromCli = exports.startWatcher = exports.buildOnce = void 0;
|
|
4
|
+
// Public surface for cms0 CLI utilities.
|
|
5
|
+
var build_js_1 = require("./build.cjs");
|
|
6
|
+
Object.defineProperty(exports, "buildOnce", { enumerable: true, get: function () { return build_js_1.buildOnce; } });
|
|
7
|
+
var watcher_js_1 = require("./watcher.cjs");
|
|
8
|
+
Object.defineProperty(exports, "startWatcher", { enumerable: true, get: function () { return watcher_js_1.startWatcher; } });
|
|
9
|
+
var cli_js_1 = require("./cli.cjs");
|
|
10
|
+
Object.defineProperty(exports, "runFromCli", { enumerable: true, get: function () { return cli_js_1.runFromCli; } });
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.packageRoot = exports.descriptorOutPath = void 0;
|
|
7
|
+
// Path utilities for locating package-relative outputs.
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const url_1 = require("url");
|
|
10
|
+
const importMetaUrl = (() => {
|
|
11
|
+
try {
|
|
12
|
+
// Avoid syntax that breaks CommonJS compilation; evaluate only if supported
|
|
13
|
+
// eslint-disable-next-line no-new-func
|
|
14
|
+
return Function("return import.meta.url")();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
})();
|
|
20
|
+
const here = typeof __dirname === "string"
|
|
21
|
+
? __dirname
|
|
22
|
+
: importMetaUrl
|
|
23
|
+
? path_1.default.dirname((0, url_1.fileURLToPath)(importMetaUrl))
|
|
24
|
+
: process.cwd();
|
|
25
|
+
const packageRoot = path_1.default.resolve(here, "../../..");
|
|
26
|
+
exports.packageRoot = packageRoot;
|
|
27
|
+
const descriptorOutPath = path_1.default.resolve(packageRoot, "src/generated/schema-descriptor.ts");
|
|
28
|
+
exports.descriptorOutPath = descriptorOutPath;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.publishDescriptor = publishDescriptor;
|
|
4
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
5
|
+
const startSpinner = (label) => {
|
|
6
|
+
if (!process.stdout.isTTY) {
|
|
7
|
+
console.log(`${label}...`);
|
|
8
|
+
return {
|
|
9
|
+
stop: (message) => {
|
|
10
|
+
if (message)
|
|
11
|
+
console.log(message);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const frames = ["|", "/", "-", "\\"];
|
|
16
|
+
let idx = 0;
|
|
17
|
+
const timer = setInterval(() => {
|
|
18
|
+
const frame = frames[idx % frames.length];
|
|
19
|
+
idx += 1;
|
|
20
|
+
process.stdout.write(`\r${frame} ${label}`);
|
|
21
|
+
}, 120);
|
|
22
|
+
return {
|
|
23
|
+
stop: (message) => {
|
|
24
|
+
clearInterval(timer);
|
|
25
|
+
process.stdout.write("\r");
|
|
26
|
+
if (message)
|
|
27
|
+
process.stdout.write(`${message}\n`);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
async function waitForAdminReady(baseUrl, headers) {
|
|
32
|
+
const healthUrl = `${baseUrl.replace(/\/$/, "")}/ok`;
|
|
33
|
+
const maxWaitMs = 30_000;
|
|
34
|
+
const startedAt = Date.now();
|
|
35
|
+
const spinner = startSpinner("cms0: waiting for admin to reload");
|
|
36
|
+
await sleep(250);
|
|
37
|
+
let attempt = 0;
|
|
38
|
+
while (Date.now() - startedAt < maxWaitMs) {
|
|
39
|
+
attempt += 1;
|
|
40
|
+
try {
|
|
41
|
+
const res = await fetch(healthUrl, { headers });
|
|
42
|
+
if (res.ok) {
|
|
43
|
+
spinner.stop("cms0: admin ready");
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore transient errors during restart
|
|
49
|
+
}
|
|
50
|
+
await sleep(Math.min(500 + attempt * 250, 2000));
|
|
51
|
+
}
|
|
52
|
+
spinner.stop("cms0: admin restart timed out");
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
async function publishDescriptor(resolved, descriptor) {
|
|
56
|
+
if (!resolved.apiBaseUrl)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
const payload = {
|
|
60
|
+
version: new Date().toISOString(),
|
|
61
|
+
descriptor,
|
|
62
|
+
};
|
|
63
|
+
const headers = {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
};
|
|
66
|
+
if (resolved.apiKey) {
|
|
67
|
+
headers["Authorization"] = `Bearer ${resolved.apiKey}`;
|
|
68
|
+
}
|
|
69
|
+
const target = `${resolved.apiBaseUrl.replace(/\/$/, "")}/schema`;
|
|
70
|
+
const maxAttempts = 5;
|
|
71
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
72
|
+
try {
|
|
73
|
+
const res = await fetch(target, {
|
|
74
|
+
method: "POST",
|
|
75
|
+
headers,
|
|
76
|
+
body: JSON.stringify(payload),
|
|
77
|
+
});
|
|
78
|
+
if (!res.ok) {
|
|
79
|
+
throw new Error(`status ${res.status}`);
|
|
80
|
+
}
|
|
81
|
+
const ready = await waitForAdminReady(resolved.apiBaseUrl.replace(/\/$/, ""), headers);
|
|
82
|
+
if (!ready) {
|
|
83
|
+
console.warn("cms0: publish succeeded, but admin did not become healthy in time.");
|
|
84
|
+
}
|
|
85
|
+
console.log(`cms0: published descriptor to ${target}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
const waitMs = Math.min(2000 * attempt, 5000);
|
|
90
|
+
console.warn(`cms0: publish attempt ${attempt}/${maxAttempts} failed (${err instanceof Error ? err.message : err}).` + (attempt < maxAttempts ? ` retrying in ${waitMs}ms...` : ""));
|
|
91
|
+
if (attempt < maxAttempts) {
|
|
92
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.warn("cms0: giving up on publishing descriptor for now.");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
console.warn(`cms0: failed to publish descriptor ${err instanceof Error ? err.message : err}`, err);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startWatcher = startWatcher;
|
|
7
|
+
// File watcher that rebuilds descriptors on entry changes.
|
|
8
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
9
|
+
const build_js_1 = require("./build.cjs");
|
|
10
|
+
function startWatcher(resolved, afterBuild) {
|
|
11
|
+
const watcher = chokidar_1.default.watch([resolved.entryFile], {
|
|
12
|
+
ignoreInitial: false,
|
|
13
|
+
});
|
|
14
|
+
const run = (after) => {
|
|
15
|
+
try {
|
|
16
|
+
const descriptor = (0, build_js_1.buildOnce)(resolved);
|
|
17
|
+
if (after) {
|
|
18
|
+
Promise.resolve(after(descriptor)).catch((err) => {
|
|
19
|
+
console.error("cms0: post-build hook failed", err);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error("cms0: generation failed", err);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// Trigger a build on startup and whenever the entry file changes.
|
|
28
|
+
watcher.on("ready", () => run(afterBuild));
|
|
29
|
+
watcher.on("change", () => run(afterBuild));
|
|
30
|
+
watcher.on("error", (error) => {
|
|
31
|
+
console.error("cms0: watcher error", error);
|
|
32
|
+
});
|
|
33
|
+
return watcher;
|
|
34
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schemaDescriptor = void 0;
|
|
4
|
+
var schema_descriptor_1 = require("@cms0/cms0/generated/schema-descriptor");
|
|
5
|
+
Object.defineProperty(exports, "schemaDescriptor", { enumerable: true, get: function () { return schema_descriptor_1.schemaDescriptor; } });
|
package/dist/esm/cli.js
ADDED