@amritk/mjst 0.5.1 → 0.6.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 +41 -4
- package/dist/cli-config.d.ts +21 -3
- package/dist/cli.js +345 -176
- package/dist/combine-files.d.ts +13 -0
- package/dist/parse-cli-args.d.ts +4 -2
- package/package.json +4 -4
- package/src/cli-config.ts +21 -3
- package/src/cli.ts +256 -67
- package/src/combine-files.test.ts +49 -0
- package/src/combine-files.ts +43 -0
- package/src/load-config.test.ts +9 -0
- package/src/load-config.ts +3 -0
- package/src/parse-cli-args.test.ts +48 -0
- package/src/parse-cli-args.ts +118 -94
package/dist/cli.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { execFile } from "node:child_process";
|
|
5
|
-
import { mkdir, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
6
|
-
import { dirname as dirname2, join as join8, resolve as resolve3 } from "node:path";
|
|
5
|
+
import { mkdir, readdir, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { basename, dirname as dirname2, join as join8, relative, resolve as resolve3, sep } from "node:path";
|
|
7
7
|
import { promisify } from "node:util";
|
|
8
8
|
|
|
9
9
|
// ../adapters/dist/get-adapter.js
|
|
@@ -90281,12 +90281,13 @@ var buildJsDocBlock = (title, description, commentUrl) => {
|
|
|
90281
90281
|
`;
|
|
90282
90282
|
return block;
|
|
90283
90283
|
};
|
|
90284
|
-
var getTypeScriptType = (schema) => {
|
|
90285
|
-
const base = getUnbrandedType(schema);
|
|
90284
|
+
var getTypeScriptType = (schema, options = {}) => {
|
|
90285
|
+
const base = getUnbrandedType(schema, options);
|
|
90286
90286
|
const brand2 = getMjstBrand(schema);
|
|
90287
90287
|
return brand2 ? `(${base} & { readonly __brand: '${brand2}' })` : base;
|
|
90288
90288
|
};
|
|
90289
|
-
var
|
|
90289
|
+
var recordType = (keyType, valueType, options) => options.readonly ? `Readonly<Record<${keyType}, ${valueType}>>` : `Record<${keyType}, ${valueType}>`;
|
|
90290
|
+
var getUnbrandedType = (schema, options = {}) => {
|
|
90290
90291
|
if (typeof schema === "boolean") {
|
|
90291
90292
|
return getBooleanSubSchemaType(schema);
|
|
90292
90293
|
}
|
|
@@ -90334,29 +90335,29 @@ var getUnbrandedType = (schema) => {
|
|
|
90334
90335
|
return multiEnumUnion;
|
|
90335
90336
|
}
|
|
90336
90337
|
if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
|
|
90337
|
-
let oneOfUnion = getTypeScriptType(schema.oneOf[0]);
|
|
90338
|
+
let oneOfUnion = getTypeScriptType(schema.oneOf[0], options);
|
|
90338
90339
|
for (let i = 1;i < schema.oneOf.length; i++) {
|
|
90339
|
-
oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i]);
|
|
90340
|
+
oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i], options);
|
|
90340
90341
|
}
|
|
90341
90342
|
return oneOfUnion;
|
|
90342
90343
|
}
|
|
90343
90344
|
if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
|
|
90344
|
-
let anyOfUnion = getTypeScriptType(schema.anyOf[0]);
|
|
90345
|
+
let anyOfUnion = getTypeScriptType(schema.anyOf[0], options);
|
|
90345
90346
|
for (let i = 1;i < schema.anyOf.length; i++) {
|
|
90346
|
-
anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i]);
|
|
90347
|
+
anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i], options);
|
|
90347
90348
|
}
|
|
90348
90349
|
return anyOfUnion;
|
|
90349
90350
|
}
|
|
90350
90351
|
if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
|
|
90351
|
-
let intersectionTypes = getTypeScriptType(schema.allOf[0]);
|
|
90352
|
+
let intersectionTypes = getTypeScriptType(schema.allOf[0], options);
|
|
90352
90353
|
for (let i = 1;i < schema.allOf.length; i++) {
|
|
90353
|
-
intersectionTypes += " & " + getTypeScriptType(schema.allOf[i]);
|
|
90354
|
+
intersectionTypes += " & " + getTypeScriptType(schema.allOf[i], options);
|
|
90354
90355
|
}
|
|
90355
90356
|
return intersectionTypes;
|
|
90356
90357
|
}
|
|
90357
90358
|
const conditionalResult = getConditionalObjectSchema(schema);
|
|
90358
90359
|
if (conditionalResult) {
|
|
90359
|
-
const baseType = getTypeScriptType(conditionalResult.schema);
|
|
90360
|
+
const baseType = getTypeScriptType(conditionalResult.schema, options);
|
|
90360
90361
|
if (conditionalResult.thenRef) {
|
|
90361
90362
|
return `(${baseType}) & ${refToName2(conditionalResult.thenRef)}`;
|
|
90362
90363
|
}
|
|
@@ -90365,20 +90366,20 @@ var getUnbrandedType = (schema) => {
|
|
|
90365
90366
|
if (!schema.type) {
|
|
90366
90367
|
if (schema.additionalProperties !== undefined) {
|
|
90367
90368
|
if (typeof schema.additionalProperties === "boolean") {
|
|
90368
|
-
return
|
|
90369
|
+
return recordType("string", getBooleanSubSchemaType(schema.additionalProperties), options);
|
|
90369
90370
|
}
|
|
90370
|
-
return
|
|
90371
|
+
return recordType("string", getTypeScriptType(schema.additionalProperties, options), options);
|
|
90371
90372
|
}
|
|
90372
90373
|
if (schema.patternProperties && typeof schema.patternProperties === "object") {
|
|
90373
90374
|
const firstEntry = Object.entries(schema.patternProperties)[0];
|
|
90374
90375
|
if (firstEntry) {
|
|
90375
90376
|
const [pattern2, value10] = firstEntry;
|
|
90376
90377
|
if (value10 !== undefined) {
|
|
90377
|
-
const valueType = typeof value10 === "boolean" ? getBooleanSubSchemaType(value10) : getTypeScriptType(value10);
|
|
90378
|
+
const valueType = typeof value10 === "boolean" ? getBooleanSubSchemaType(value10) : getTypeScriptType(value10, options);
|
|
90378
90379
|
if (pattern2 === "^x-") {
|
|
90379
|
-
return `
|
|
90380
|
+
return recordType("`x-${string}`", valueType, options);
|
|
90380
90381
|
}
|
|
90381
|
-
return
|
|
90382
|
+
return recordType("string", valueType, options);
|
|
90382
90383
|
}
|
|
90383
90384
|
}
|
|
90384
90385
|
}
|
|
@@ -90431,41 +90432,42 @@ var getUnbrandedType = (schema) => {
|
|
|
90431
90432
|
return "boolean";
|
|
90432
90433
|
case "array":
|
|
90433
90434
|
if (schema.items) {
|
|
90434
|
-
const itemType = getTypeScriptType(schema.items);
|
|
90435
|
+
const itemType = getTypeScriptType(schema.items, options);
|
|
90435
90436
|
const wrappedItemType = itemType.includes(" | ") ? `(${itemType})` : itemType;
|
|
90436
|
-
return `${wrappedItemType}[]`;
|
|
90437
|
+
return options.readonly ? `readonly ${wrappedItemType}[]` : `${wrappedItemType}[]`;
|
|
90437
90438
|
}
|
|
90438
|
-
return "unknown[]";
|
|
90439
|
+
return options.readonly ? "readonly unknown[]" : "unknown[]";
|
|
90439
90440
|
case "object":
|
|
90440
90441
|
if (schema.properties) {
|
|
90442
|
+
const readonlyPrefix = options.readonly ? "readonly " : "";
|
|
90441
90443
|
let properties = "";
|
|
90442
90444
|
let first5 = true;
|
|
90443
90445
|
for (const key in schema.properties) {
|
|
90444
90446
|
const propSchema = schema.properties[key];
|
|
90445
90447
|
const isRequired = schema.required?.includes(key) ?? false;
|
|
90446
90448
|
const optional3 = isRequired ? "" : "?";
|
|
90447
|
-
const propType = getTypeScriptType(propSchema);
|
|
90449
|
+
const propType = getTypeScriptType(propSchema, options);
|
|
90448
90450
|
if (!first5)
|
|
90449
90451
|
properties += "; ";
|
|
90450
|
-
properties += safeKey(key) + optional3 + ": " + propType;
|
|
90452
|
+
properties += readonlyPrefix + safeKey(key) + optional3 + ": " + propType;
|
|
90451
90453
|
first5 = false;
|
|
90452
90454
|
}
|
|
90453
90455
|
return "{ " + properties + " }";
|
|
90454
90456
|
}
|
|
90455
90457
|
if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
90456
|
-
const additionalPropType = getTypeScriptType(schema.additionalProperties);
|
|
90457
|
-
return
|
|
90458
|
+
const additionalPropType = getTypeScriptType(schema.additionalProperties, options);
|
|
90459
|
+
return recordType("string", additionalPropType, options);
|
|
90458
90460
|
}
|
|
90459
90461
|
if (schema.patternProperties && typeof schema.patternProperties === "object") {
|
|
90460
90462
|
const firstEntry = Object.entries(schema.patternProperties)[0];
|
|
90461
90463
|
if (firstEntry) {
|
|
90462
90464
|
const [pattern2, patternVal] = firstEntry;
|
|
90463
90465
|
if (patternVal) {
|
|
90464
|
-
const valueType = getTypeScriptType(patternVal);
|
|
90466
|
+
const valueType = getTypeScriptType(patternVal, options);
|
|
90465
90467
|
if (pattern2 === "^x-") {
|
|
90466
|
-
return `
|
|
90468
|
+
return recordType("`x-${string}`", valueType, options);
|
|
90467
90469
|
}
|
|
90468
|
-
return
|
|
90470
|
+
return recordType("string", valueType, options);
|
|
90469
90471
|
}
|
|
90470
90472
|
}
|
|
90471
90473
|
}
|
|
@@ -90474,9 +90476,10 @@ var getUnbrandedType = (schema) => {
|
|
|
90474
90476
|
return "unknown";
|
|
90475
90477
|
}
|
|
90476
90478
|
};
|
|
90477
|
-
var generateTypeDefinition = (schema, typeName) => {
|
|
90479
|
+
var generateTypeDefinition = (schema, typeName, options = {}) => {
|
|
90480
|
+
const readonlyPrefix = options.readonly ? "readonly " : "";
|
|
90478
90481
|
if (!isObjectLikeSchema(schema)) {
|
|
90479
|
-
const tsType = getTypeScriptType(schema);
|
|
90482
|
+
const tsType = getTypeScriptType(schema, options);
|
|
90480
90483
|
let result = "";
|
|
90481
90484
|
if (isSchemaObject2(schema) && schema.$comment && typeof schema.$comment === "string") {
|
|
90482
90485
|
result += buildJsDocBlock(typeName, schema.$comment);
|
|
@@ -90504,23 +90507,23 @@ var generateTypeDefinition = (schema, typeName) => {
|
|
|
90504
90507
|
if (firstPatternProperty === undefined) {
|
|
90505
90508
|
return `export type ${typeName} = Record<string, unknown>;`;
|
|
90506
90509
|
}
|
|
90507
|
-
const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty);
|
|
90510
|
+
const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty, options);
|
|
90508
90511
|
const keyType = firstPattern === "^x-" ? "`x-${string}`" : "string";
|
|
90509
90512
|
let result2 = "";
|
|
90510
90513
|
if (jsDocTitle && jsDocDescription) {
|
|
90511
90514
|
result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
|
|
90512
90515
|
}
|
|
90513
|
-
result2 += `export type ${typeName} =
|
|
90516
|
+
result2 += `export type ${typeName} = ${recordType(keyType, patternPropType, options)};`;
|
|
90514
90517
|
return result2;
|
|
90515
90518
|
}
|
|
90516
90519
|
if (!hasProperties2 && hasAdditionalProperties2 && normalizedSchema.additionalProperties) {
|
|
90517
|
-
const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties);
|
|
90520
|
+
const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties, options);
|
|
90518
90521
|
let result2 = "";
|
|
90519
90522
|
if (jsDocTitle && jsDocDescription) {
|
|
90520
90523
|
result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
|
|
90521
90524
|
}
|
|
90522
90525
|
result2 += `export type ${typeName} = {
|
|
90523
|
-
[key: string]: ${additionalPropType};
|
|
90526
|
+
${readonlyPrefix}[key: string]: ${additionalPropType};
|
|
90524
90527
|
};`;
|
|
90525
90528
|
return result2;
|
|
90526
90529
|
}
|
|
@@ -90531,8 +90534,8 @@ var generateTypeDefinition = (schema, typeName) => {
|
|
|
90531
90534
|
const propSchema = schemaProps[key];
|
|
90532
90535
|
const isRequired = normalizedSchema.required?.includes(key) ?? false;
|
|
90533
90536
|
const optional3 = isRequired ? "" : "?";
|
|
90534
|
-
const propType = getTypeScriptType(propSchema);
|
|
90535
|
-
const quotedKey = safeKey(key);
|
|
90537
|
+
const propType = getTypeScriptType(propSchema, options);
|
|
90538
|
+
const quotedKey = readonlyPrefix + safeKey(key);
|
|
90536
90539
|
if (!isFirstProp)
|
|
90537
90540
|
properties += `
|
|
90538
90541
|
`;
|
|
@@ -90580,31 +90583,32 @@ var PACKAGE_IMPORTS = {
|
|
|
90580
90583
|
"validate-record": "import { validateRecord } from '@amritk/helpers/validate-record';",
|
|
90581
90584
|
"has-ref": "import { hasRef } from '@amritk/helpers/schema-guards';"
|
|
90582
90585
|
};
|
|
90583
|
-
var
|
|
90584
|
-
"is-object": "
|
|
90585
|
-
"validate-array": "
|
|
90586
|
-
"validate-record": "
|
|
90587
|
-
"has-ref": "
|
|
90586
|
+
var EMBEDDED_NAMED_EXPORTS = {
|
|
90587
|
+
"is-object": "isObject",
|
|
90588
|
+
"validate-array": "validateArray",
|
|
90589
|
+
"validate-record": "validateRecord",
|
|
90590
|
+
"has-ref": "hasRef"
|
|
90588
90591
|
};
|
|
90589
|
-
var
|
|
90592
|
+
var embeddedImport = (helper, prefix) => `import { ${EMBEDDED_NAMED_EXPORTS[helper]} } from '${prefix}_helpers/${helper}';`;
|
|
90593
|
+
var collectHelpers = (parserFunction, mode, helpersImportPrefix = "./") => {
|
|
90590
90594
|
const imports = [];
|
|
90591
90595
|
const used = new Set;
|
|
90592
|
-
const
|
|
90596
|
+
const importFor = (helper) => mode === "embedded" ? embeddedImport(helper, helpersImportPrefix) : PACKAGE_IMPORTS[helper];
|
|
90593
90597
|
if (parserFunction.includes("validateArray")) {
|
|
90594
|
-
imports.push(
|
|
90598
|
+
imports.push(importFor("validate-array"));
|
|
90595
90599
|
used.add("validate-array");
|
|
90596
90600
|
}
|
|
90597
90601
|
if (parserFunction.includes("validateRecord")) {
|
|
90598
|
-
imports.push(
|
|
90602
|
+
imports.push(importFor("validate-record"));
|
|
90599
90603
|
used.add("validate-record");
|
|
90600
90604
|
used.add("is-object");
|
|
90601
90605
|
}
|
|
90602
90606
|
if (parserFunction.includes("isObject")) {
|
|
90603
|
-
imports.push(
|
|
90607
|
+
imports.push(importFor("is-object"));
|
|
90604
90608
|
used.add("is-object");
|
|
90605
90609
|
}
|
|
90606
90610
|
if (parserFunction.includes("hasRef(")) {
|
|
90607
|
-
imports.push(
|
|
90611
|
+
imports.push(importFor("has-ref"));
|
|
90608
90612
|
used.add("has-ref");
|
|
90609
90613
|
}
|
|
90610
90614
|
return { imports, used };
|
|
@@ -92269,7 +92273,7 @@ var generateFile = (schema, typeName, options) => {
|
|
|
92269
92273
|
const selfRef = options?.selfRef;
|
|
92270
92274
|
const rootSchema = options?.rootSchema;
|
|
92271
92275
|
const helpersMode = options?.helpersMode ?? "package";
|
|
92272
|
-
const typeDefinition = generateTypeDefinition(schema, typeName);
|
|
92276
|
+
const typeDefinition = generateTypeDefinition(schema, typeName, { readonly: options?.readonly ?? false });
|
|
92273
92277
|
if (typesOnly) {
|
|
92274
92278
|
const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema });
|
|
92275
92279
|
let result2 = "";
|
|
@@ -92294,7 +92298,7 @@ var generateFile = (schema, typeName, options) => {
|
|
|
92294
92298
|
const combinedFunctions = `${shapeValidator}
|
|
92295
92299
|
|
|
92296
92300
|
${parserFunction}`;
|
|
92297
|
-
const helpers = collectHelpers(combinedFunctions, helpersMode);
|
|
92301
|
+
const helpers = collectHelpers(combinedFunctions, helpersMode, options?.helpersImportPrefix);
|
|
92298
92302
|
const imports = [...collectImports(schema, { selfRef, rootSchema }), ...helpers.imports];
|
|
92299
92303
|
let result = "";
|
|
92300
92304
|
if (imports.length > 0) {
|
|
@@ -92336,7 +92340,7 @@ var extractDynamicAnchorDefs = (schema) => {
|
|
|
92336
92340
|
}
|
|
92337
92341
|
return refs;
|
|
92338
92342
|
};
|
|
92339
|
-
var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict2, helpersMode = "package") => {
|
|
92343
|
+
var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict2, helpersMode = "package", helpersImportPrefix = "./", readonly2 = false) => {
|
|
92340
92344
|
rootSchema = upgradeDraft07Schema(rootSchema);
|
|
92341
92345
|
const files = [];
|
|
92342
92346
|
const processedRefs = new Set;
|
|
@@ -92350,6 +92354,8 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
|
|
|
92350
92354
|
typesOnly: typesOnly ?? false,
|
|
92351
92355
|
rootSchema,
|
|
92352
92356
|
helpersMode,
|
|
92357
|
+
helpersImportPrefix,
|
|
92358
|
+
readonly: readonly2,
|
|
92353
92359
|
...logWarnings !== undefined ? { logWarnings } : {},
|
|
92354
92360
|
...strict2 !== undefined ? { strict: strict2 } : {}
|
|
92355
92361
|
});
|
|
@@ -92385,6 +92391,8 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
|
|
|
92385
92391
|
selfRef: ref,
|
|
92386
92392
|
rootSchema,
|
|
92387
92393
|
helpersMode,
|
|
92394
|
+
helpersImportPrefix,
|
|
92395
|
+
readonly: readonly2,
|
|
92388
92396
|
...logWarnings !== undefined ? { logWarnings } : {},
|
|
92389
92397
|
...strict2 !== undefined ? { strict: strict2 } : {}
|
|
92390
92398
|
});
|
|
@@ -92458,6 +92466,41 @@ var deriveRootTypeName = (schema) => {
|
|
|
92458
92466
|
return name || "Document";
|
|
92459
92467
|
};
|
|
92460
92468
|
|
|
92469
|
+
// src/combine-files.ts
|
|
92470
|
+
var IMPORT_RE = /^import\s/;
|
|
92471
|
+
var RELATIVE_IMPORT_RE = /\bfrom\s+['"]\.\.?\//;
|
|
92472
|
+
var combineGeneratedFiles = (files) => {
|
|
92473
|
+
const externalImports = new Set;
|
|
92474
|
+
const bodies = [];
|
|
92475
|
+
for (const file2 of files) {
|
|
92476
|
+
if (file2.filename === "index.ts")
|
|
92477
|
+
continue;
|
|
92478
|
+
const bodyLines = [];
|
|
92479
|
+
for (const line of file2.content.split(`
|
|
92480
|
+
`)) {
|
|
92481
|
+
if (IMPORT_RE.test(line.trimStart())) {
|
|
92482
|
+
if (RELATIVE_IMPORT_RE.test(line))
|
|
92483
|
+
continue;
|
|
92484
|
+
externalImports.add(line.trim());
|
|
92485
|
+
continue;
|
|
92486
|
+
}
|
|
92487
|
+
bodyLines.push(line);
|
|
92488
|
+
}
|
|
92489
|
+
const body = bodyLines.join(`
|
|
92490
|
+
`).trim();
|
|
92491
|
+
if (body)
|
|
92492
|
+
bodies.push(body);
|
|
92493
|
+
}
|
|
92494
|
+
const importBlock = [...externalImports].sort().join(`
|
|
92495
|
+
`);
|
|
92496
|
+
return [importBlock, bodies.join(`
|
|
92497
|
+
|
|
92498
|
+
`)].filter(Boolean).join(`
|
|
92499
|
+
|
|
92500
|
+
`) + `
|
|
92501
|
+
`;
|
|
92502
|
+
};
|
|
92503
|
+
|
|
92461
92504
|
// src/detect-helpers-mode.ts
|
|
92462
92505
|
import { createRequire as createRequire2 } from "node:module";
|
|
92463
92506
|
import { resolve } from "node:path";
|
|
@@ -92486,13 +92529,16 @@ var loadConfig = async (configPath) => {
|
|
|
92486
92529
|
const obj = parsed;
|
|
92487
92530
|
return {
|
|
92488
92531
|
...typeof obj["schema"] === "string" && { schema: obj["schema"] },
|
|
92532
|
+
...typeof obj["schemaDir"] === "string" && { schemaDir: obj["schemaDir"] },
|
|
92489
92533
|
...typeof obj["outDir"] === "string" && { outDir: obj["outDir"] },
|
|
92534
|
+
...typeof obj["outFile"] === "string" && { outFile: obj["outFile"] },
|
|
92490
92535
|
...isSourceFormat(obj["input"]) && { input: obj["input"] },
|
|
92491
92536
|
...typeof obj["export"] === "string" && { export: obj["export"] },
|
|
92492
92537
|
...typeof obj["typesOnly"] === "boolean" && { typesOnly: obj["typesOnly"] },
|
|
92493
92538
|
...typeof obj["build"] === "boolean" && { build: obj["build"] },
|
|
92494
92539
|
...typeof obj["logWarnings"] === "boolean" && { logWarnings: obj["logWarnings"] },
|
|
92495
|
-
...typeof obj["strict"] === "boolean" && { strict: obj["strict"] }
|
|
92540
|
+
...typeof obj["strict"] === "boolean" && { strict: obj["strict"] },
|
|
92541
|
+
...typeof obj["readonly"] === "boolean" && { readonly: obj["readonly"] }
|
|
92496
92542
|
};
|
|
92497
92543
|
};
|
|
92498
92544
|
|
|
@@ -92527,92 +92573,106 @@ ${String(error54)}`);
|
|
|
92527
92573
|
|
|
92528
92574
|
// src/parse-cli-args.ts
|
|
92529
92575
|
var SOURCE_FORMATS2 = ["json", "typebox", "zod", "valibot", "effect"];
|
|
92576
|
+
var BOOLEAN_KEYS = new Set(["typesOnly", "build", "logWarnings", "strict", "readonly"]);
|
|
92577
|
+
var VALUE_KEYS = new Set([
|
|
92578
|
+
"schema",
|
|
92579
|
+
"schemaDir",
|
|
92580
|
+
"outDir",
|
|
92581
|
+
"outFile",
|
|
92582
|
+
"input",
|
|
92583
|
+
"export",
|
|
92584
|
+
"helpers"
|
|
92585
|
+
]);
|
|
92586
|
+
var toCamelCase = (key) => key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
92587
|
+
var parseHelpersValue = (value10) => {
|
|
92588
|
+
if (value10 === "package" || value10 === "embedded")
|
|
92589
|
+
return value10;
|
|
92590
|
+
return;
|
|
92591
|
+
};
|
|
92592
|
+
var parseInputValue = (value10) => SOURCE_FORMATS2.includes(value10) ? value10 : undefined;
|
|
92593
|
+
var assignValue = (config3, key, value10) => {
|
|
92594
|
+
switch (key) {
|
|
92595
|
+
case "schema":
|
|
92596
|
+
config3.schema = value10;
|
|
92597
|
+
return true;
|
|
92598
|
+
case "schemaDir":
|
|
92599
|
+
config3.schemaDir = value10;
|
|
92600
|
+
return true;
|
|
92601
|
+
case "outDir":
|
|
92602
|
+
config3.outDir = value10;
|
|
92603
|
+
return true;
|
|
92604
|
+
case "outFile":
|
|
92605
|
+
config3.outFile = value10;
|
|
92606
|
+
return true;
|
|
92607
|
+
case "export":
|
|
92608
|
+
config3.export = value10;
|
|
92609
|
+
return true;
|
|
92610
|
+
case "input": {
|
|
92611
|
+
const parsed = parseInputValue(value10);
|
|
92612
|
+
if (parsed)
|
|
92613
|
+
config3.input = parsed;
|
|
92614
|
+
return true;
|
|
92615
|
+
}
|
|
92616
|
+
case "helpers": {
|
|
92617
|
+
const parsed = parseHelpersValue(value10);
|
|
92618
|
+
if (parsed)
|
|
92619
|
+
config3.helpers = parsed;
|
|
92620
|
+
return true;
|
|
92621
|
+
}
|
|
92622
|
+
default:
|
|
92623
|
+
return false;
|
|
92624
|
+
}
|
|
92625
|
+
};
|
|
92626
|
+
var assignBoolean = (config3, key, value10) => {
|
|
92627
|
+
switch (key) {
|
|
92628
|
+
case "typesOnly":
|
|
92629
|
+
config3.typesOnly = value10;
|
|
92630
|
+
return true;
|
|
92631
|
+
case "build":
|
|
92632
|
+
config3.build = value10;
|
|
92633
|
+
return true;
|
|
92634
|
+
case "logWarnings":
|
|
92635
|
+
config3.logWarnings = value10;
|
|
92636
|
+
return true;
|
|
92637
|
+
case "strict":
|
|
92638
|
+
config3.strict = value10;
|
|
92639
|
+
return true;
|
|
92640
|
+
case "readonly":
|
|
92641
|
+
config3.readonly = value10;
|
|
92642
|
+
return true;
|
|
92643
|
+
default:
|
|
92644
|
+
return false;
|
|
92645
|
+
}
|
|
92646
|
+
};
|
|
92530
92647
|
var parseCliArgs = (args2) => {
|
|
92531
92648
|
const config3 = {};
|
|
92532
|
-
const parseHelpersValue = (value10) => {
|
|
92533
|
-
if (value10 === "package" || value10 === "embedded")
|
|
92534
|
-
return value10;
|
|
92535
|
-
return;
|
|
92536
|
-
};
|
|
92537
|
-
const parseInputValue = (value10) => SOURCE_FORMATS2.includes(value10) ? value10 : undefined;
|
|
92538
92649
|
for (let i = 0;i < args2.length; i++) {
|
|
92539
92650
|
const arg = args2[i];
|
|
92540
|
-
if (!arg) {
|
|
92651
|
+
if (!arg || !arg.startsWith("--")) {
|
|
92541
92652
|
continue;
|
|
92542
92653
|
}
|
|
92543
|
-
|
|
92544
|
-
|
|
92545
|
-
const
|
|
92654
|
+
const equalsIndex = arg.indexOf("=");
|
|
92655
|
+
if (equalsIndex !== -1) {
|
|
92656
|
+
const key2 = toCamelCase(arg.slice(2, equalsIndex));
|
|
92546
92657
|
const value10 = arg.slice(equalsIndex + 1);
|
|
92547
|
-
if (
|
|
92548
|
-
config3
|
|
92549
|
-
} else
|
|
92550
|
-
config3
|
|
92551
|
-
} else if (key === "input") {
|
|
92552
|
-
const parsed = parseInputValue(value10);
|
|
92553
|
-
if (parsed)
|
|
92554
|
-
config3.input = parsed;
|
|
92555
|
-
} else if (key === "export") {
|
|
92556
|
-
config3.export = value10;
|
|
92557
|
-
} else if (key === "types-only") {
|
|
92558
|
-
config3.typesOnly = value10 !== "false";
|
|
92559
|
-
} else if (key === "build") {
|
|
92560
|
-
config3.build = value10 !== "false";
|
|
92561
|
-
} else if (key === "log-warnings") {
|
|
92562
|
-
config3.logWarnings = value10 !== "false";
|
|
92563
|
-
} else if (key === "strict") {
|
|
92564
|
-
config3.strict = value10 !== "false";
|
|
92565
|
-
} else if (key === "helpers") {
|
|
92566
|
-
const parsed = parseHelpersValue(value10);
|
|
92567
|
-
if (parsed)
|
|
92568
|
-
config3.helpers = parsed;
|
|
92658
|
+
if (BOOLEAN_KEYS.has(key2)) {
|
|
92659
|
+
assignBoolean(config3, key2, value10 !== "false");
|
|
92660
|
+
} else {
|
|
92661
|
+
assignValue(config3, key2, value10);
|
|
92569
92662
|
}
|
|
92570
92663
|
continue;
|
|
92571
92664
|
}
|
|
92572
|
-
|
|
92573
|
-
|
|
92574
|
-
|
|
92575
|
-
|
|
92576
|
-
|
|
92577
|
-
|
|
92578
|
-
} else if (arg === "--outDir") {
|
|
92579
|
-
const value10 = args2[i + 1];
|
|
92580
|
-
if (value10 && !value10.startsWith("--")) {
|
|
92581
|
-
config3.outDir = value10;
|
|
92582
|
-
i++;
|
|
92583
|
-
}
|
|
92584
|
-
} else if (arg === "--input") {
|
|
92585
|
-
const value10 = args2[i + 1];
|
|
92586
|
-
if (value10 && !value10.startsWith("--")) {
|
|
92587
|
-
const parsed = parseInputValue(value10);
|
|
92588
|
-
if (parsed) {
|
|
92589
|
-
config3.input = parsed;
|
|
92590
|
-
i++;
|
|
92591
|
-
}
|
|
92592
|
-
}
|
|
92593
|
-
} else if (arg === "--export") {
|
|
92665
|
+
const key = toCamelCase(arg.slice(2));
|
|
92666
|
+
if (BOOLEAN_KEYS.has(key)) {
|
|
92667
|
+
assignBoolean(config3, key, true);
|
|
92668
|
+
continue;
|
|
92669
|
+
}
|
|
92670
|
+
if (VALUE_KEYS.has(key)) {
|
|
92594
92671
|
const value10 = args2[i + 1];
|
|
92595
92672
|
if (value10 && !value10.startsWith("--")) {
|
|
92596
|
-
config3
|
|
92673
|
+
assignValue(config3, key, value10);
|
|
92597
92674
|
i++;
|
|
92598
92675
|
}
|
|
92599
|
-
} else if (arg === "--types-only") {
|
|
92600
|
-
config3.typesOnly = true;
|
|
92601
|
-
} else if (arg === "--build") {
|
|
92602
|
-
config3.build = true;
|
|
92603
|
-
} else if (arg === "--log-warnings") {
|
|
92604
|
-
config3.logWarnings = true;
|
|
92605
|
-
} else if (arg === "--strict") {
|
|
92606
|
-
config3.strict = true;
|
|
92607
|
-
} else if (arg === "--helpers") {
|
|
92608
|
-
const value10 = args2[i + 1];
|
|
92609
|
-
if (value10 && !value10.startsWith("--")) {
|
|
92610
|
-
const parsed = parseHelpersValue(value10);
|
|
92611
|
-
if (parsed) {
|
|
92612
|
-
config3.helpers = parsed;
|
|
92613
|
-
i++;
|
|
92614
|
-
}
|
|
92615
|
-
}
|
|
92616
92676
|
}
|
|
92617
92677
|
}
|
|
92618
92678
|
return config3;
|
|
@@ -92632,77 +92692,186 @@ var extractConfigPath = (args2) => {
|
|
|
92632
92692
|
}
|
|
92633
92693
|
return;
|
|
92634
92694
|
};
|
|
92635
|
-
var
|
|
92636
|
-
const args2 = process.argv.slice(2);
|
|
92637
|
-
const configPath = extractConfigPath(args2);
|
|
92638
|
-
const fileConfig = configPath ? await loadConfig(configPath) : {};
|
|
92639
|
-
const cliConfig = parseCliArgs(args2);
|
|
92640
|
-
const config3 = { ...fileConfig, ...cliConfig };
|
|
92641
|
-
if (!config3.schema) {
|
|
92642
|
-
console.error("Error: --schema is required. Provide a path to a JSON Schema file.");
|
|
92643
|
-
process.exit(1);
|
|
92644
|
-
}
|
|
92645
|
-
if (!config3.outDir) {
|
|
92646
|
-
console.error("Error: --outDir is required. Provide an output directory for generated files.");
|
|
92647
|
-
process.exit(1);
|
|
92648
|
-
}
|
|
92649
|
-
const schemaPath = resolve3(config3.schema);
|
|
92695
|
+
var loadSchema = async (config3, schemaPath) => {
|
|
92650
92696
|
const inputFormat = config3.input ?? "json";
|
|
92651
|
-
let schema;
|
|
92652
92697
|
if (inputFormat === "json") {
|
|
92653
|
-
|
|
92654
|
-
}
|
|
92655
|
-
|
|
92656
|
-
|
|
92657
|
-
|
|
92698
|
+
return JSON.parse(await readFile3(schemaPath, "utf-8"));
|
|
92699
|
+
}
|
|
92700
|
+
console.log(`Input format: ${inputFormat}`);
|
|
92701
|
+
const source = await loadSchemaModule(schemaPath, config3.export);
|
|
92702
|
+
return getAdapter(inputFormat).toJSONSchema(source);
|
|
92703
|
+
};
|
|
92704
|
+
var writeGeneratedFile = async (baseDir, filename, content) => {
|
|
92705
|
+
const filePath = join8(baseDir, filename);
|
|
92706
|
+
await mkdir(dirname2(filePath), { recursive: true });
|
|
92707
|
+
await writeFile(filePath, content, "utf-8");
|
|
92708
|
+
};
|
|
92709
|
+
var buildOutput = async (outputDir, tsFiles, typesOnly) => {
|
|
92710
|
+
const tsconfigContent = JSON.stringify({
|
|
92711
|
+
compilerOptions: {
|
|
92712
|
+
target: "ESNext",
|
|
92713
|
+
module: "ESNext",
|
|
92714
|
+
moduleResolution: "bundler",
|
|
92715
|
+
declaration: true,
|
|
92716
|
+
emitDeclarationOnly: typesOnly,
|
|
92717
|
+
skipLibCheck: true
|
|
92718
|
+
},
|
|
92719
|
+
include: tsFiles.map((file2) => `./${file2}`)
|
|
92720
|
+
}, null, 2);
|
|
92721
|
+
const tsconfigPath = join8(outputDir, ".tsconfig-mjst-build.json");
|
|
92722
|
+
await writeFile(tsconfigPath, tsconfigContent, "utf-8");
|
|
92723
|
+
try {
|
|
92724
|
+
await execFileAsync("npx", ["tsc", "--project", tsconfigPath]);
|
|
92725
|
+
} catch {
|
|
92726
|
+
throw new Error("TypeScript compilation failed. Check the generated files for errors.");
|
|
92727
|
+
} finally {
|
|
92728
|
+
await unlink(tsconfigPath);
|
|
92658
92729
|
}
|
|
92659
|
-
const
|
|
92730
|
+
for (const file2 of tsFiles) {
|
|
92731
|
+
await unlink(join8(outputDir, file2));
|
|
92732
|
+
console.log(`Built: ${file2.replace(/\.ts$/, ".js")}`);
|
|
92733
|
+
console.log(`Built: ${file2.replace(/\.ts$/, ".d.ts")}`);
|
|
92734
|
+
}
|
|
92735
|
+
console.log(`
|
|
92736
|
+
Total files built: ${tsFiles.length * 2}`);
|
|
92737
|
+
};
|
|
92738
|
+
var findJsonSchemas = async (dir3) => {
|
|
92739
|
+
const entries8 = await readdir(dir3, { withFileTypes: true });
|
|
92740
|
+
const results = [];
|
|
92741
|
+
for (const entry of entries8) {
|
|
92742
|
+
const full = join8(dir3, entry.name);
|
|
92743
|
+
if (entry.isDirectory()) {
|
|
92744
|
+
results.push(...await findJsonSchemas(full));
|
|
92745
|
+
} else if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
92746
|
+
results.push(full);
|
|
92747
|
+
}
|
|
92748
|
+
}
|
|
92749
|
+
return results;
|
|
92750
|
+
};
|
|
92751
|
+
var runSingle = async (config3, schemaPath, outputDir) => {
|
|
92752
|
+
const schema = await loadSchema(config3, schemaPath);
|
|
92660
92753
|
await mkdir(outputDir, { recursive: true });
|
|
92661
92754
|
const helpersMode = config3.helpers ?? detectHelpersMode(outputDir);
|
|
92662
92755
|
console.log(`Helpers mode: ${helpersMode}${config3.helpers ? " (explicit)" : " (auto-detected)"}`);
|
|
92663
92756
|
const rootTypeName = deriveRootTypeName(schema);
|
|
92664
92757
|
console.log(`Root type: ${rootTypeName}`);
|
|
92665
|
-
const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode);
|
|
92758
|
+
const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode, undefined, config3.readonly);
|
|
92666
92759
|
for (const file2 of files) {
|
|
92667
|
-
|
|
92668
|
-
await mkdir(dirname2(filePath), { recursive: true });
|
|
92669
|
-
await writeFile(filePath, file2.content, "utf-8");
|
|
92760
|
+
await writeGeneratedFile(outputDir, file2.filename, file2.content);
|
|
92670
92761
|
console.log(`Generated: ${file2.filename}`);
|
|
92671
92762
|
}
|
|
92672
92763
|
if (config3.build) {
|
|
92673
|
-
|
|
92674
|
-
|
|
92675
|
-
|
|
92676
|
-
|
|
92677
|
-
|
|
92678
|
-
|
|
92679
|
-
|
|
92680
|
-
|
|
92681
|
-
|
|
92682
|
-
|
|
92683
|
-
|
|
92684
|
-
|
|
92685
|
-
|
|
92686
|
-
|
|
92687
|
-
|
|
92688
|
-
|
|
92689
|
-
|
|
92690
|
-
|
|
92691
|
-
|
|
92692
|
-
|
|
92764
|
+
await buildOutput(outputDir, files.map((f) => f.filename), config3.typesOnly);
|
|
92765
|
+
} else {
|
|
92766
|
+
console.log(`
|
|
92767
|
+
Total files generated: ${files.length}`);
|
|
92768
|
+
}
|
|
92769
|
+
};
|
|
92770
|
+
var runSingleFile = async (config3, schemaPath, outFilePath) => {
|
|
92771
|
+
const schema = await loadSchema(config3, schemaPath);
|
|
92772
|
+
const outputDir = dirname2(outFilePath);
|
|
92773
|
+
await mkdir(outputDir, { recursive: true });
|
|
92774
|
+
const rootTypeName = deriveRootTypeName(schema);
|
|
92775
|
+
console.log(`Root type: ${rootTypeName}`);
|
|
92776
|
+
const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, config3.helpers ?? "package", undefined, config3.readonly);
|
|
92777
|
+
await writeFile(outFilePath, combineGeneratedFiles(files), "utf-8");
|
|
92778
|
+
console.log(`Generated: ${relative(process.cwd(), outFilePath)}`);
|
|
92779
|
+
if (config3.build) {
|
|
92780
|
+
await buildOutput(outputDir, [basename(outFilePath)], config3.typesOnly);
|
|
92781
|
+
} else {
|
|
92782
|
+
console.log(`
|
|
92783
|
+
Total files generated: 1`);
|
|
92784
|
+
}
|
|
92785
|
+
};
|
|
92786
|
+
var runRecursive = async (config3, schemaDir, outputDir) => {
|
|
92787
|
+
if (config3.input && config3.input !== "json") {
|
|
92788
|
+
console.error("Error: --schemaDir only supports JSON Schema files; remove --input or set it to 'json'.");
|
|
92789
|
+
process.exit(1);
|
|
92790
|
+
}
|
|
92791
|
+
const schemaFiles = await findJsonSchemas(schemaDir);
|
|
92792
|
+
if (schemaFiles.length === 0) {
|
|
92793
|
+
console.error(`Error: no .json schema files found under ${schemaDir}.`);
|
|
92794
|
+
process.exit(1);
|
|
92795
|
+
}
|
|
92796
|
+
await mkdir(outputDir, { recursive: true });
|
|
92797
|
+
const helpersMode = config3.helpers ?? detectHelpersMode(outputDir);
|
|
92798
|
+
console.log(`Helpers mode: ${helpersMode}${config3.helpers ? " (explicit)" : " (auto-detected)"}`);
|
|
92799
|
+
const sharedHelpers = new Map;
|
|
92800
|
+
const writtenTsFiles = [];
|
|
92801
|
+
for (const schemaFile of schemaFiles) {
|
|
92802
|
+
const relPath = relative(schemaDir, schemaFile);
|
|
92803
|
+
const relNoExt = relPath.slice(0, -".json".length);
|
|
92804
|
+
const schemaSubDir = join8(outputDir, relNoExt);
|
|
92805
|
+
const depth = relNoExt.split(sep).filter(Boolean).length;
|
|
92806
|
+
const helpersImportPrefix = "../".repeat(depth);
|
|
92807
|
+
const schema = await loadSchema(config3, schemaFile);
|
|
92808
|
+
const rootTypeName = deriveRootTypeName(schema);
|
|
92809
|
+
console.log(`
|
|
92810
|
+
${relPath} → ${relNoExt}/ (root type: ${rootTypeName})`);
|
|
92811
|
+
const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode, helpersImportPrefix, config3.readonly);
|
|
92693
92812
|
for (const file2 of files) {
|
|
92694
|
-
|
|
92695
|
-
|
|
92696
|
-
|
|
92697
|
-
|
|
92698
|
-
|
|
92813
|
+
if (file2.filename.startsWith("_helpers/")) {
|
|
92814
|
+
sharedHelpers.set(file2.filename, file2.content);
|
|
92815
|
+
continue;
|
|
92816
|
+
}
|
|
92817
|
+
await writeGeneratedFile(schemaSubDir, file2.filename, file2.content);
|
|
92818
|
+
const relativeFilename = join8(relNoExt, file2.filename);
|
|
92819
|
+
writtenTsFiles.push(relativeFilename);
|
|
92820
|
+
console.log(`Generated: ${relativeFilename}`);
|
|
92699
92821
|
}
|
|
92700
|
-
|
|
92701
|
-
|
|
92822
|
+
}
|
|
92823
|
+
for (const [filename, content] of sharedHelpers) {
|
|
92824
|
+
await writeGeneratedFile(outputDir, filename, content);
|
|
92825
|
+
writtenTsFiles.push(filename);
|
|
92826
|
+
console.log(`Generated: ${filename}`);
|
|
92827
|
+
}
|
|
92828
|
+
if (config3.build) {
|
|
92829
|
+
await buildOutput(outputDir, writtenTsFiles, config3.typesOnly);
|
|
92702
92830
|
} else {
|
|
92703
92831
|
console.log(`
|
|
92704
|
-
Total files generated: ${
|
|
92832
|
+
Total files generated: ${writtenTsFiles.length}`);
|
|
92833
|
+
}
|
|
92834
|
+
};
|
|
92835
|
+
var run10 = async () => {
|
|
92836
|
+
const args2 = process.argv.slice(2);
|
|
92837
|
+
const configPath = extractConfigPath(args2);
|
|
92838
|
+
const fileConfig = configPath ? await loadConfig(configPath) : {};
|
|
92839
|
+
const cliConfig = parseCliArgs(args2);
|
|
92840
|
+
const config3 = { ...fileConfig, ...cliConfig };
|
|
92841
|
+
if (config3.outDir && config3.outFile) {
|
|
92842
|
+
console.error("Error: provide only one of --out-dir or --out-file, not both.");
|
|
92843
|
+
process.exit(1);
|
|
92844
|
+
}
|
|
92845
|
+
if (config3.outFile) {
|
|
92846
|
+
if (!config3.typesOnly) {
|
|
92847
|
+
console.error("Error: --out-file currently supports only --types-only output. Add --types-only or use --out-dir.");
|
|
92848
|
+
process.exit(1);
|
|
92849
|
+
}
|
|
92850
|
+
if (config3.schemaDir) {
|
|
92851
|
+
console.error("Error: --out-file cannot be combined with --schema-dir; use --out-dir for recursive output.");
|
|
92852
|
+
process.exit(1);
|
|
92853
|
+
}
|
|
92854
|
+
if (!config3.schema) {
|
|
92855
|
+
console.error("Error: --schema is required. Provide a path to a JSON Schema.");
|
|
92856
|
+
process.exit(1);
|
|
92857
|
+
}
|
|
92858
|
+
await runSingleFile(config3, resolve3(config3.schema), resolve3(config3.outFile));
|
|
92859
|
+
return;
|
|
92860
|
+
}
|
|
92861
|
+
if (!config3.outDir) {
|
|
92862
|
+
console.error("Error: --out-dir or --out-file is required. Provide an output destination for generated files.");
|
|
92863
|
+
process.exit(1);
|
|
92864
|
+
}
|
|
92865
|
+
const outputDir = resolve3(config3.outDir);
|
|
92866
|
+
if (config3.schemaDir) {
|
|
92867
|
+
await runRecursive(config3, resolve3(config3.schemaDir), outputDir);
|
|
92868
|
+
return;
|
|
92869
|
+
}
|
|
92870
|
+
if (!config3.schema) {
|
|
92871
|
+
console.error("Error: --schema (or --schemaDir) is required. Provide a path to a JSON Schema.");
|
|
92872
|
+
process.exit(1);
|
|
92705
92873
|
}
|
|
92874
|
+
await runSingle(config3, resolve3(config3.schema), outputDir);
|
|
92706
92875
|
};
|
|
92707
92876
|
run10().catch((error54) => {
|
|
92708
92877
|
console.error(error54 instanceof Error ? error54.message : error54);
|