@formspec/build 0.1.0-alpha.55 → 0.1.0-alpha.58
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/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +26 -8
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +26 -8
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +7 -6
- package/dist/build-beta.d.ts +7 -6
- package/dist/build-internal.d.ts +7 -6
- package/dist/build.d.ts +7 -6
- package/dist/cli.cjs +86 -19
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +88 -19
- package/dist/cli.js.map +1 -1
- package/dist/generators/class-schema.d.ts +2 -2
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/index.cjs +81 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +83 -16
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +81 -16
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +83 -16
- package/dist/internals.js.map +1 -1
- package/dist/json-schema/generator.d.ts +1 -1
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts +1 -1
- package/dist/json-schema/ir-generator.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -944,20 +944,29 @@ function assertNoSerializedNameCollisions(ir) {
|
|
|
944
944
|
}
|
|
945
945
|
|
|
946
946
|
// src/json-schema/ir-generator.ts
|
|
947
|
+
function parseEnumSerialization(value) {
|
|
948
|
+
switch (value) {
|
|
949
|
+
case void 0:
|
|
950
|
+
case "enum":
|
|
951
|
+
return "enum";
|
|
952
|
+
case "oneOf":
|
|
953
|
+
return "oneOf";
|
|
954
|
+
case "smart-size":
|
|
955
|
+
return "smart-size";
|
|
956
|
+
default:
|
|
957
|
+
throw new Error(
|
|
958
|
+
`Invalid enumSerialization "${String(value)}". Expected "enum", "oneOf", or "smart-size".`
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
947
962
|
function makeContext(options) {
|
|
948
963
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
949
|
-
const
|
|
964
|
+
const enumSerialization = parseEnumSerialization(options?.enumSerialization);
|
|
950
965
|
if (!vendorPrefix.startsWith("x-")) {
|
|
951
966
|
throw new Error(
|
|
952
967
|
`Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
|
|
953
968
|
);
|
|
954
969
|
}
|
|
955
|
-
if (rawEnumSerialization !== void 0 && rawEnumSerialization !== "enum" && rawEnumSerialization !== "oneOf") {
|
|
956
|
-
throw new Error(
|
|
957
|
-
`Invalid enumSerialization "${rawEnumSerialization}". Expected "enum" or "oneOf".`
|
|
958
|
-
);
|
|
959
|
-
}
|
|
960
|
-
const enumSerialization = rawEnumSerialization ?? "enum";
|
|
961
970
|
return {
|
|
962
971
|
defs: {},
|
|
963
972
|
typeNameMap: {},
|
|
@@ -1165,7 +1174,7 @@ function generatePrimitiveType(type) {
|
|
|
1165
1174
|
};
|
|
1166
1175
|
}
|
|
1167
1176
|
function generateEnumType(type, ctx) {
|
|
1168
|
-
if (ctx.enumSerialization === "oneOf") {
|
|
1177
|
+
if (ctx.enumSerialization === "oneOf" || ctx.enumSerialization === "smart-size" && shouldSerializeEnumAsOneOf(type)) {
|
|
1169
1178
|
return {
|
|
1170
1179
|
oneOf: type.members.map((m) => {
|
|
1171
1180
|
const stringValue = String(m.value);
|
|
@@ -1175,12 +1184,21 @@ function generateEnumType(type, ctx) {
|
|
|
1175
1184
|
};
|
|
1176
1185
|
}
|
|
1177
1186
|
const schema = { enum: type.members.map((m) => m.value) };
|
|
1187
|
+
if (ctx.enumSerialization === "smart-size") {
|
|
1188
|
+
return schema;
|
|
1189
|
+
}
|
|
1178
1190
|
const displayNames = buildEnumDisplayNameExtension(type);
|
|
1179
1191
|
if (displayNames !== void 0) {
|
|
1180
1192
|
schema[`${ctx.vendorPrefix}-display-names`] = displayNames;
|
|
1181
1193
|
}
|
|
1182
1194
|
return schema;
|
|
1183
1195
|
}
|
|
1196
|
+
function shouldSerializeEnumAsOneOf(type) {
|
|
1197
|
+
return type.members.some((member) => {
|
|
1198
|
+
const title = member.displayName ?? String(member.value);
|
|
1199
|
+
return title !== String(member.value);
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1184
1202
|
function buildEnumDisplayNameExtension(type) {
|
|
1185
1203
|
if (!type.members.some((member) => member.displayName !== void 0)) {
|
|
1186
1204
|
return void 0;
|
|
@@ -2370,6 +2388,8 @@ import {
|
|
|
2370
2388
|
getBuildLogger,
|
|
2371
2389
|
getBroadeningLogger,
|
|
2372
2390
|
getSyntheticLogger as getSyntheticLogger2,
|
|
2391
|
+
getTypedParserLogger,
|
|
2392
|
+
parseTagArgument,
|
|
2373
2393
|
describeTypeKind,
|
|
2374
2394
|
elapsedMicros,
|
|
2375
2395
|
nowMicros,
|
|
@@ -2526,6 +2546,7 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
|
|
|
2526
2546
|
sourceFile,
|
|
2527
2547
|
tagName,
|
|
2528
2548
|
parsedTag,
|
|
2549
|
+
text,
|
|
2529
2550
|
provenance,
|
|
2530
2551
|
supportingDeclarations,
|
|
2531
2552
|
options
|
|
@@ -2553,6 +2574,9 @@ function renderSyntheticArgumentExpression(valueKind, argumentText) {
|
|
|
2553
2574
|
case "number":
|
|
2554
2575
|
case "integer":
|
|
2555
2576
|
case "signedInteger":
|
|
2577
|
+
if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
|
|
2578
|
+
return trimmed;
|
|
2579
|
+
}
|
|
2556
2580
|
return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
|
|
2557
2581
|
case "string":
|
|
2558
2582
|
return JSON.stringify(argumentText);
|
|
@@ -2764,7 +2788,7 @@ function hasBuiltinConstraintBroadening(tagName, options) {
|
|
|
2764
2788
|
const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
|
|
2765
2789
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
2766
2790
|
}
|
|
2767
|
-
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, provenance, supportingDeclarations, options) {
|
|
2791
|
+
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, supportingDeclarations, options) {
|
|
2768
2792
|
if (!isBuiltinConstraintName(tagName)) {
|
|
2769
2793
|
return [];
|
|
2770
2794
|
}
|
|
@@ -2785,8 +2809,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2785
2809
|
const log = getBuildLogger();
|
|
2786
2810
|
const broadeningLog = getBroadeningLogger();
|
|
2787
2811
|
const syntheticLog = getSyntheticLogger2();
|
|
2812
|
+
const typedParserLog = getTypedParserLogger();
|
|
2788
2813
|
const logsEnabled = log !== noopLogger3 || broadeningLog !== noopLogger3;
|
|
2789
2814
|
const syntheticTraceEnabled = syntheticLog !== noopLogger3;
|
|
2815
|
+
const typedParserTraceEnabled = typedParserLog !== noopLogger3;
|
|
2790
2816
|
const logStart = logsEnabled ? nowMicros() : 0;
|
|
2791
2817
|
const subjectTypeKind = logsEnabled ? describeTypeKind(subjectType, checker) : "";
|
|
2792
2818
|
function emit(outcome, result2) {
|
|
@@ -2894,16 +2920,57 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2894
2920
|
]);
|
|
2895
2921
|
}
|
|
2896
2922
|
}
|
|
2897
|
-
const
|
|
2898
|
-
definition.valueKind,
|
|
2899
|
-
parsedTag?.argumentText ?? ""
|
|
2900
|
-
);
|
|
2901
|
-
if (definition.requiresArgument && argumentExpression === null) {
|
|
2902
|
-
return emit("A-pass", []);
|
|
2903
|
-
}
|
|
2923
|
+
const effectiveArgumentText = parsedTag !== null ? parseTagSyntax(tagName, rawText).argumentText : rawText;
|
|
2904
2924
|
if (hasBroadening) {
|
|
2905
2925
|
return emit("bypass", []);
|
|
2906
2926
|
}
|
|
2927
|
+
const typedParseResult = parseTagArgument(tagName, effectiveArgumentText, "build");
|
|
2928
|
+
if (!typedParseResult.ok) {
|
|
2929
|
+
if (typedParserTraceEnabled) {
|
|
2930
|
+
typedParserLog.trace("typed-parser C-reject", {
|
|
2931
|
+
consumer: "build",
|
|
2932
|
+
tag: tagName,
|
|
2933
|
+
placement: nonNullPlacement,
|
|
2934
|
+
subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
|
|
2935
|
+
roleOutcome: "C-reject",
|
|
2936
|
+
diagnosticCode: typedParseResult.diagnostic.code
|
|
2937
|
+
});
|
|
2938
|
+
}
|
|
2939
|
+
let mappedCode;
|
|
2940
|
+
switch (typedParseResult.diagnostic.code) {
|
|
2941
|
+
case "MISSING_TAG_ARGUMENT":
|
|
2942
|
+
mappedCode = "MISSING_TAG_ARGUMENT";
|
|
2943
|
+
break;
|
|
2944
|
+
case "INVALID_TAG_ARGUMENT":
|
|
2945
|
+
mappedCode = "INVALID_TAG_ARGUMENT";
|
|
2946
|
+
break;
|
|
2947
|
+
case "UNKNOWN_TAG":
|
|
2948
|
+
throw new Error(
|
|
2949
|
+
`Unexpected UNKNOWN_TAG from parseTagArgument("${tagName}") \u2014 tag was resolved via getTagDefinition.`
|
|
2950
|
+
);
|
|
2951
|
+
default: {
|
|
2952
|
+
const _exhaustive = typedParseResult.diagnostic.code;
|
|
2953
|
+
throw new Error(`Unknown diagnostic code: ${String(_exhaustive)}`);
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
return emit("C-reject", [
|
|
2957
|
+
makeDiagnostic(mappedCode, typedParseResult.diagnostic.message, provenance)
|
|
2958
|
+
]);
|
|
2959
|
+
}
|
|
2960
|
+
if (typedParserTraceEnabled) {
|
|
2961
|
+
typedParserLog.trace("typed-parser C-pass", {
|
|
2962
|
+
consumer: "build",
|
|
2963
|
+
tag: tagName,
|
|
2964
|
+
placement: nonNullPlacement,
|
|
2965
|
+
subjectTypeKind: subjectTypeKind !== "" ? subjectTypeKind : "-",
|
|
2966
|
+
roleOutcome: "C-pass",
|
|
2967
|
+
valueKind: typedParseResult.value.kind
|
|
2968
|
+
});
|
|
2969
|
+
}
|
|
2970
|
+
const argumentExpression = renderSyntheticArgumentExpression(
|
|
2971
|
+
definition.valueKind,
|
|
2972
|
+
effectiveArgumentText
|
|
2973
|
+
);
|
|
2907
2974
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2908
2975
|
const hostType = options?.hostType ?? subjectType;
|
|
2909
2976
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|