@formspec/build 0.1.0-alpha.54 → 0.1.0-alpha.57
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/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +44 -12
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +46 -13
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +7 -46
- package/dist/build-beta.d.ts +7 -46
- package/dist/build-internal.d.ts +7 -46
- package/dist/build.d.ts +7 -46
- package/dist/cli.cjs +175 -66
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +172 -54
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts.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 +165 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +167 -51
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +166 -59
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +164 -48
- 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 +5 -5
package/dist/cli.cjs
CHANGED
|
@@ -1018,20 +1018,29 @@ var init_collision_guards = __esm({
|
|
|
1018
1018
|
});
|
|
1019
1019
|
|
|
1020
1020
|
// src/json-schema/ir-generator.ts
|
|
1021
|
+
function parseEnumSerialization(value) {
|
|
1022
|
+
switch (value) {
|
|
1023
|
+
case void 0:
|
|
1024
|
+
case "enum":
|
|
1025
|
+
return "enum";
|
|
1026
|
+
case "oneOf":
|
|
1027
|
+
return "oneOf";
|
|
1028
|
+
case "smart-size":
|
|
1029
|
+
return "smart-size";
|
|
1030
|
+
default:
|
|
1031
|
+
throw new Error(
|
|
1032
|
+
`Invalid enumSerialization "${String(value)}". Expected "enum", "oneOf", or "smart-size".`
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1021
1036
|
function makeContext(options) {
|
|
1022
1037
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
1023
|
-
const
|
|
1038
|
+
const enumSerialization = parseEnumSerialization(options?.enumSerialization);
|
|
1024
1039
|
if (!vendorPrefix.startsWith("x-")) {
|
|
1025
1040
|
throw new Error(
|
|
1026
1041
|
`Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
|
|
1027
1042
|
);
|
|
1028
1043
|
}
|
|
1029
|
-
if (rawEnumSerialization !== void 0 && rawEnumSerialization !== "enum" && rawEnumSerialization !== "oneOf") {
|
|
1030
|
-
throw new Error(
|
|
1031
|
-
`Invalid enumSerialization "${rawEnumSerialization}". Expected "enum" or "oneOf".`
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1034
|
-
const enumSerialization = rawEnumSerialization ?? "enum";
|
|
1035
1044
|
return {
|
|
1036
1045
|
defs: {},
|
|
1037
1046
|
typeNameMap: {},
|
|
@@ -1239,21 +1248,31 @@ function generatePrimitiveType(type) {
|
|
|
1239
1248
|
};
|
|
1240
1249
|
}
|
|
1241
1250
|
function generateEnumType(type, ctx) {
|
|
1242
|
-
if (ctx.enumSerialization === "oneOf") {
|
|
1251
|
+
if (ctx.enumSerialization === "oneOf" || ctx.enumSerialization === "smart-size" && shouldSerializeEnumAsOneOf(type)) {
|
|
1243
1252
|
return {
|
|
1244
|
-
oneOf: type.members.map((m) =>
|
|
1245
|
-
const
|
|
1246
|
-
title
|
|
1247
|
-
|
|
1253
|
+
oneOf: type.members.map((m) => {
|
|
1254
|
+
const stringValue = String(m.value);
|
|
1255
|
+
const title = m.displayName !== void 0 && m.displayName !== stringValue ? m.displayName : void 0;
|
|
1256
|
+
return title !== void 0 ? { const: m.value, title } : { const: m.value };
|
|
1257
|
+
})
|
|
1248
1258
|
};
|
|
1249
1259
|
}
|
|
1250
1260
|
const schema = { enum: type.members.map((m) => m.value) };
|
|
1261
|
+
if (ctx.enumSerialization === "smart-size") {
|
|
1262
|
+
return schema;
|
|
1263
|
+
}
|
|
1251
1264
|
const displayNames = buildEnumDisplayNameExtension(type);
|
|
1252
1265
|
if (displayNames !== void 0) {
|
|
1253
1266
|
schema[`${ctx.vendorPrefix}-display-names`] = displayNames;
|
|
1254
1267
|
}
|
|
1255
1268
|
return schema;
|
|
1256
1269
|
}
|
|
1270
|
+
function shouldSerializeEnumAsOneOf(type) {
|
|
1271
|
+
return type.members.some((member) => {
|
|
1272
|
+
const title = member.displayName ?? String(member.value);
|
|
1273
|
+
return title !== String(member.value);
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1257
1276
|
function buildEnumDisplayNameExtension(type) {
|
|
1258
1277
|
if (!type.members.some((member) => member.displayName !== void 0)) {
|
|
1259
1278
|
return void 0;
|
|
@@ -2072,6 +2091,11 @@ function buildConstraintTagSources(extensions) {
|
|
|
2072
2091
|
}));
|
|
2073
2092
|
}
|
|
2074
2093
|
function createExtensionRegistry(extensions) {
|
|
2094
|
+
const registryLog = (0, import_internal.getSyntheticLogger)();
|
|
2095
|
+
registryLog.debug("createExtensionRegistry: constructing", {
|
|
2096
|
+
extensionCount: extensions.length,
|
|
2097
|
+
extensionIds: extensions.map((e) => e.extensionId)
|
|
2098
|
+
});
|
|
2075
2099
|
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
2076
2100
|
let symbolMap = /* @__PURE__ */ new Map();
|
|
2077
2101
|
const typeMap = /* @__PURE__ */ new Map();
|
|
@@ -2203,6 +2227,14 @@ function createExtensionRegistry(extensions) {
|
|
|
2203
2227
|
}
|
|
2204
2228
|
}
|
|
2205
2229
|
}
|
|
2230
|
+
registryLog.debug("createExtensionRegistry: complete", {
|
|
2231
|
+
typeCount: typeMap.size,
|
|
2232
|
+
constraintCount: constraintMap.size,
|
|
2233
|
+
constraintTagCount: constraintTagMap.size,
|
|
2234
|
+
broadeningCount: builtinBroadeningMap.size,
|
|
2235
|
+
annotationCount: annotationMap.size,
|
|
2236
|
+
metadataSlotCount: metadataSlotMap.size
|
|
2237
|
+
});
|
|
2206
2238
|
return {
|
|
2207
2239
|
extensions,
|
|
2208
2240
|
findType: (typeId) => typeMap.get(typeId),
|
|
@@ -2851,56 +2883,82 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2851
2883
|
if (definition === null) {
|
|
2852
2884
|
return [];
|
|
2853
2885
|
}
|
|
2886
|
+
const nonNullPlacement = placement;
|
|
2887
|
+
const log2 = (0, import_internal4.getBuildLogger)();
|
|
2888
|
+
const broadeningLog = (0, import_internal4.getBroadeningLogger)();
|
|
2889
|
+
const syntheticLog = (0, import_internal4.getSyntheticLogger)();
|
|
2890
|
+
const logsEnabled = log2 !== import_core4.noopLogger || broadeningLog !== import_core4.noopLogger;
|
|
2891
|
+
const syntheticTraceEnabled = syntheticLog !== import_core4.noopLogger;
|
|
2892
|
+
const logStart = logsEnabled ? (0, import_internal4.nowMicros)() : 0;
|
|
2893
|
+
const subjectTypeKind = logsEnabled ? (0, import_internal4.describeTypeKind)(subjectType, checker) : "";
|
|
2894
|
+
function emit(outcome, result2) {
|
|
2895
|
+
if (!logsEnabled) {
|
|
2896
|
+
return result2;
|
|
2897
|
+
}
|
|
2898
|
+
const entry = {
|
|
2899
|
+
consumer: "build",
|
|
2900
|
+
tag: tagName,
|
|
2901
|
+
placement: nonNullPlacement,
|
|
2902
|
+
subjectTypeKind,
|
|
2903
|
+
roleOutcome: outcome,
|
|
2904
|
+
elapsedMicros: (0, import_internal4.elapsedMicros)(logStart)
|
|
2905
|
+
};
|
|
2906
|
+
(0, import_internal4.logTagApplication)(log2, entry);
|
|
2907
|
+
if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
|
|
2908
|
+
(0, import_internal4.logTagApplication)(broadeningLog, entry);
|
|
2909
|
+
}
|
|
2910
|
+
return result2;
|
|
2911
|
+
}
|
|
2854
2912
|
if (!definition.placements.includes(placement)) {
|
|
2855
|
-
return [
|
|
2913
|
+
return emit("A-reject", [
|
|
2856
2914
|
makeDiagnostic(
|
|
2857
2915
|
"INVALID_TAG_PLACEMENT",
|
|
2858
2916
|
`Tag "@${tagName}" is not allowed on ${placementLabel(placement)}.`,
|
|
2859
2917
|
provenance
|
|
2860
2918
|
)
|
|
2861
|
-
];
|
|
2919
|
+
]);
|
|
2862
2920
|
}
|
|
2863
2921
|
const target = parsedTag?.target ?? null;
|
|
2864
2922
|
let evaluatedType = subjectType;
|
|
2865
2923
|
let targetLabel = node.getText(sourceFile);
|
|
2866
2924
|
if (target !== null) {
|
|
2867
2925
|
if (target.kind !== "path") {
|
|
2868
|
-
return [
|
|
2926
|
+
return emit("B-reject", [
|
|
2869
2927
|
makeDiagnostic(
|
|
2870
2928
|
"UNSUPPORTED_TARGETING_SYNTAX",
|
|
2871
2929
|
`Tag "@${tagName}" does not support ${target.kind} targeting syntax.`,
|
|
2872
2930
|
provenance
|
|
2873
2931
|
)
|
|
2874
|
-
];
|
|
2932
|
+
]);
|
|
2875
2933
|
}
|
|
2876
2934
|
if (!target.valid || target.path === null) {
|
|
2877
|
-
return [
|
|
2935
|
+
return emit("B-reject", [
|
|
2878
2936
|
makeDiagnostic(
|
|
2879
2937
|
"UNSUPPORTED_TARGETING_SYNTAX",
|
|
2880
2938
|
`Tag "@${tagName}" has invalid path targeting syntax.`,
|
|
2881
2939
|
provenance
|
|
2882
2940
|
)
|
|
2883
|
-
];
|
|
2941
|
+
]);
|
|
2884
2942
|
}
|
|
2885
2943
|
const resolution = (0, import_internal3.resolvePathTargetType)(subjectType, checker, target.path.segments);
|
|
2886
2944
|
if (resolution.kind === "missing-property") {
|
|
2887
|
-
return [
|
|
2945
|
+
return emit("B-reject", [
|
|
2888
2946
|
makeDiagnostic(
|
|
2889
2947
|
"UNKNOWN_PATH_TARGET",
|
|
2890
2948
|
`Target "${target.rawText}": path-targeted constraint "${tagName}" references unknown path segment "${resolution.segment}"`,
|
|
2891
2949
|
provenance
|
|
2892
2950
|
)
|
|
2893
|
-
];
|
|
2951
|
+
]);
|
|
2894
2952
|
}
|
|
2895
2953
|
if (resolution.kind === "unresolvable") {
|
|
2896
2954
|
const actualType = checker.typeToString(resolution.type, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2897
|
-
return [
|
|
2955
|
+
return emit("B-reject", [
|
|
2898
2956
|
makeDiagnostic(
|
|
2899
2957
|
"TYPE_MISMATCH",
|
|
2900
2958
|
`Target "${target.rawText}": path-targeted constraint "${tagName}" is invalid because type "${actualType}" cannot be traversed`,
|
|
2901
2959
|
provenance
|
|
2902
2960
|
)
|
|
2903
|
-
];
|
|
2961
|
+
]);
|
|
2904
2962
|
}
|
|
2905
2963
|
evaluatedType = resolution.type;
|
|
2906
2964
|
targetLabel = target.rawText;
|
|
@@ -2929,13 +2987,13 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2929
2987
|
tagName,
|
|
2930
2988
|
parsedTag?.argumentText
|
|
2931
2989
|
) : null;
|
|
2932
|
-
return [
|
|
2990
|
+
return emit("B-reject", [
|
|
2933
2991
|
makeDiagnostic(
|
|
2934
2992
|
"TYPE_MISMATCH",
|
|
2935
2993
|
hint === null ? baseMessage : `${baseMessage}. ${hint}`,
|
|
2936
2994
|
provenance
|
|
2937
2995
|
)
|
|
2938
|
-
];
|
|
2996
|
+
]);
|
|
2939
2997
|
}
|
|
2940
2998
|
}
|
|
2941
2999
|
const argumentExpression = renderSyntheticArgumentExpression(
|
|
@@ -2943,14 +3001,23 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2943
3001
|
parsedTag?.argumentText ?? ""
|
|
2944
3002
|
);
|
|
2945
3003
|
if (definition.requiresArgument && argumentExpression === null) {
|
|
2946
|
-
return [];
|
|
3004
|
+
return emit("A-pass", []);
|
|
2947
3005
|
}
|
|
2948
3006
|
if (hasBroadening) {
|
|
2949
|
-
return [];
|
|
3007
|
+
return emit("bypass", []);
|
|
2950
3008
|
}
|
|
2951
3009
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2952
3010
|
const hostType = options?.hostType ?? subjectType;
|
|
2953
3011
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
3012
|
+
if (syntheticTraceEnabled) {
|
|
3013
|
+
syntheticLog.trace("invoking synthetic checker", {
|
|
3014
|
+
consumer: "build",
|
|
3015
|
+
tag: tagName,
|
|
3016
|
+
placement,
|
|
3017
|
+
subjectTypeKind,
|
|
3018
|
+
subjectTypeText
|
|
3019
|
+
});
|
|
3020
|
+
}
|
|
2954
3021
|
const result = (0, import_internal3.checkSyntheticTagApplication)({
|
|
2955
3022
|
tagName,
|
|
2956
3023
|
placement,
|
|
@@ -2977,26 +3044,26 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2977
3044
|
} : {}
|
|
2978
3045
|
});
|
|
2979
3046
|
if (result.diagnostics.length === 0) {
|
|
2980
|
-
return [];
|
|
3047
|
+
return emit("C-pass", []);
|
|
2981
3048
|
}
|
|
2982
3049
|
const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
|
|
2983
3050
|
if (setupDiagnostic !== void 0) {
|
|
2984
|
-
return [
|
|
3051
|
+
return emit("C-reject", [
|
|
2985
3052
|
makeDiagnostic(
|
|
2986
3053
|
setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
|
|
2987
3054
|
setupDiagnostic.message,
|
|
2988
3055
|
provenance
|
|
2989
3056
|
)
|
|
2990
|
-
];
|
|
3057
|
+
]);
|
|
2991
3058
|
}
|
|
2992
3059
|
const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
|
|
2993
|
-
return [
|
|
3060
|
+
return emit("C-reject", [
|
|
2994
3061
|
makeDiagnostic(
|
|
2995
3062
|
"TYPE_MISMATCH",
|
|
2996
3063
|
`Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
|
|
2997
3064
|
provenance
|
|
2998
3065
|
)
|
|
2999
|
-
];
|
|
3066
|
+
]);
|
|
3000
3067
|
}
|
|
3001
3068
|
function getExtensionTagNames(options) {
|
|
3002
3069
|
return [
|
|
@@ -3308,7 +3375,7 @@ function getTagCommentText(tag) {
|
|
|
3308
3375
|
}
|
|
3309
3376
|
return ts4.getTextOfJSDocComment(tag.comment);
|
|
3310
3377
|
}
|
|
3311
|
-
var ts4, import_internal3, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
|
|
3378
|
+
var ts4, import_internal3, import_internals4, import_internals5, import_core4, import_internal4, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
|
|
3312
3379
|
var init_tsdoc_parser = __esm({
|
|
3313
3380
|
"src/analyzer/tsdoc-parser.ts"() {
|
|
3314
3381
|
"use strict";
|
|
@@ -3316,8 +3383,10 @@ var init_tsdoc_parser = __esm({
|
|
|
3316
3383
|
import_internal3 = require("@formspec/analysis/internal");
|
|
3317
3384
|
import_internals4 = require("@formspec/core/internals");
|
|
3318
3385
|
import_internals5 = require("@formspec/core/internals");
|
|
3386
|
+
import_core4 = require("@formspec/core");
|
|
3319
3387
|
init_resolve_custom_type();
|
|
3320
3388
|
init_builtin_brands();
|
|
3389
|
+
import_internal4 = require("@formspec/analysis/internal");
|
|
3321
3390
|
SYNTHETIC_TYPE_FORMAT_FLAGS = ts4.TypeFormatFlags.NoTruncation | ts4.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
3322
3391
|
MAX_HINT_CANDIDATES = 5;
|
|
3323
3392
|
MAX_HINT_DEPTH = 3;
|
|
@@ -3424,7 +3493,7 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
|
3424
3493
|
};
|
|
3425
3494
|
}
|
|
3426
3495
|
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
3427
|
-
const analysis = (0,
|
|
3496
|
+
const analysis = (0, import_internal5.analyzeMetadataForNodeWithChecker)({
|
|
3428
3497
|
checker,
|
|
3429
3498
|
node,
|
|
3430
3499
|
logicalName,
|
|
@@ -3765,7 +3834,7 @@ function getLeadingParsedTags(node) {
|
|
|
3765
3834
|
if (!commentText.startsWith("/**")) {
|
|
3766
3835
|
continue;
|
|
3767
3836
|
}
|
|
3768
|
-
parsedTags.push(...(0,
|
|
3837
|
+
parsedTags.push(...(0, import_internal5.parseCommentBlock)(commentText, { offset: range.pos }).tags);
|
|
3769
3838
|
}
|
|
3770
3839
|
return parsedTags;
|
|
3771
3840
|
}
|
|
@@ -4174,6 +4243,22 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4174
4243
|
}
|
|
4175
4244
|
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
4176
4245
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
4246
|
+
const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
|
|
4247
|
+
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts6.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
|
|
4248
|
+
const argumentDecl = argumentSymbol?.declarations?.[0];
|
|
4249
|
+
if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
|
|
4250
|
+
const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
|
|
4251
|
+
if (argumentName !== void 0) {
|
|
4252
|
+
return {
|
|
4253
|
+
tsType: argumentType,
|
|
4254
|
+
typeNode: {
|
|
4255
|
+
kind: "reference",
|
|
4256
|
+
name: argumentName,
|
|
4257
|
+
typeArguments: []
|
|
4258
|
+
}
|
|
4259
|
+
};
|
|
4260
|
+
}
|
|
4261
|
+
}
|
|
4177
4262
|
return {
|
|
4178
4263
|
tsType: argumentType,
|
|
4179
4264
|
typeNode: resolveTypeNode(
|
|
@@ -4440,22 +4525,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4440
4525
|
sourceNode
|
|
4441
4526
|
);
|
|
4442
4527
|
if (customTypeLookup !== null) {
|
|
4443
|
-
const typeId = customTypeIdFromLookup(customTypeLookup);
|
|
4444
|
-
let payload = null;
|
|
4445
|
-
if (customTypeLookup.registration.extractPayload !== void 0) {
|
|
4446
|
-
try {
|
|
4447
|
-
payload = customTypeLookup.registration.extractPayload(type, checker) ?? null;
|
|
4448
|
-
} catch (cause) {
|
|
4449
|
-
throw new Error(
|
|
4450
|
-
`extractPayload for custom type "${customTypeLookup.registration.typeName}" in extension "${customTypeLookup.extensionId}" threw`,
|
|
4451
|
-
{ cause }
|
|
4452
|
-
);
|
|
4453
|
-
}
|
|
4454
|
-
}
|
|
4455
4528
|
return {
|
|
4456
4529
|
kind: "custom",
|
|
4457
|
-
typeId,
|
|
4458
|
-
payload
|
|
4530
|
+
typeId: customTypeIdFromLookup(customTypeLookup),
|
|
4531
|
+
payload: null
|
|
4459
4532
|
};
|
|
4460
4533
|
}
|
|
4461
4534
|
const primitiveAlias = tryResolveNamedPrimitiveAlias(
|
|
@@ -4639,6 +4712,21 @@ function getReferencedTypeAliasDeclaration(sourceNode, checker) {
|
|
|
4639
4712
|
}
|
|
4640
4713
|
return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
4641
4714
|
}
|
|
4715
|
+
function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
|
|
4716
|
+
const typeName = getNamedTypeName(type);
|
|
4717
|
+
const namedDecl = getNamedTypeDeclaration(type);
|
|
4718
|
+
if (typeName !== null && namedDecl !== void 0) {
|
|
4719
|
+
return { typeName, namedDecl };
|
|
4720
|
+
}
|
|
4721
|
+
if (sourceNode === void 0) {
|
|
4722
|
+
return null;
|
|
4723
|
+
}
|
|
4724
|
+
const refAliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
4725
|
+
if (refAliasDecl === void 0) {
|
|
4726
|
+
return null;
|
|
4727
|
+
}
|
|
4728
|
+
return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
|
|
4729
|
+
}
|
|
4642
4730
|
function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
4643
4731
|
if (!ts6.isTypeReferenceNode(typeNode)) {
|
|
4644
4732
|
return false;
|
|
@@ -4697,8 +4785,23 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
4697
4785
|
);
|
|
4698
4786
|
}
|
|
4699
4787
|
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4700
|
-
const
|
|
4701
|
-
|
|
4788
|
+
const recovered = resolveNamedTypeWithSourceRecovery(type, sourceNode, checker);
|
|
4789
|
+
let typeName = null;
|
|
4790
|
+
let namedDecl;
|
|
4791
|
+
if (recovered !== null) {
|
|
4792
|
+
const recoveredAliasDecl = ts6.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
|
|
4793
|
+
if (recoveredAliasDecl !== void 0) {
|
|
4794
|
+
const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
|
|
4795
|
+
const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
|
|
4796
|
+
if (isNonGeneric && (aliasUnderlyingType.isUnion() || isObjectType(aliasUnderlyingType))) {
|
|
4797
|
+
typeName = recovered.typeName;
|
|
4798
|
+
namedDecl = recovered.namedDecl;
|
|
4799
|
+
}
|
|
4800
|
+
} else {
|
|
4801
|
+
typeName = recovered.typeName;
|
|
4802
|
+
namedDecl = recovered.namedDecl;
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4702
4805
|
if (typeName && typeName in typeRegistry) {
|
|
4703
4806
|
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4704
4807
|
}
|
|
@@ -4730,6 +4833,10 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4730
4833
|
if (!typeName) {
|
|
4731
4834
|
return result;
|
|
4732
4835
|
}
|
|
4836
|
+
const existing = typeRegistry[typeName];
|
|
4837
|
+
if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
|
|
4838
|
+
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4839
|
+
}
|
|
4733
4840
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4734
4841
|
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4735
4842
|
metadataPolicy,
|
|
@@ -5377,12 +5484,12 @@ function detectFormSpecReference(typeNode) {
|
|
|
5377
5484
|
}
|
|
5378
5485
|
return null;
|
|
5379
5486
|
}
|
|
5380
|
-
var ts6,
|
|
5487
|
+
var ts6, import_internal5, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
|
|
5381
5488
|
var init_class_analyzer = __esm({
|
|
5382
5489
|
"src/analyzer/class-analyzer.ts"() {
|
|
5383
5490
|
"use strict";
|
|
5384
5491
|
ts6 = __toESM(require("typescript"), 1);
|
|
5385
|
-
|
|
5492
|
+
import_internal5 = require("@formspec/analysis/internal");
|
|
5386
5493
|
init_jsdoc_constraints();
|
|
5387
5494
|
init_tsdoc_parser();
|
|
5388
5495
|
init_resolve_custom_type();
|
|
@@ -5889,7 +5996,7 @@ var init_symbol_registry = __esm({
|
|
|
5889
5996
|
|
|
5890
5997
|
// src/validate/constraint-validator.ts
|
|
5891
5998
|
function validateFieldNode(ctx, field) {
|
|
5892
|
-
const analysis = (0,
|
|
5999
|
+
const analysis = (0, import_internal6.analyzeConstraintTargets)(
|
|
5893
6000
|
field.name,
|
|
5894
6001
|
field.type,
|
|
5895
6002
|
field.constraints,
|
|
@@ -5907,7 +6014,7 @@ function validateFieldNode(ctx, field) {
|
|
|
5907
6014
|
}
|
|
5908
6015
|
function validateObjectProperty(ctx, parentName, property) {
|
|
5909
6016
|
const qualifiedName = `${parentName}.${property.name}`;
|
|
5910
|
-
const analysis = (0,
|
|
6017
|
+
const analysis = (0, import_internal6.analyzeConstraintTargets)(
|
|
5911
6018
|
qualifiedName,
|
|
5912
6019
|
property.type,
|
|
5913
6020
|
property.constraints,
|
|
@@ -5958,11 +6065,11 @@ function validateIR(ir, options) {
|
|
|
5958
6065
|
valid: ctx.diagnostics.every((diagnostic) => diagnostic.severity !== "error")
|
|
5959
6066
|
};
|
|
5960
6067
|
}
|
|
5961
|
-
var
|
|
6068
|
+
var import_internal6;
|
|
5962
6069
|
var init_constraint_validator = __esm({
|
|
5963
6070
|
"src/validate/constraint-validator.ts"() {
|
|
5964
6071
|
"use strict";
|
|
5965
|
-
|
|
6072
|
+
import_internal6 = require("@formspec/analysis/internal");
|
|
5966
6073
|
}
|
|
5967
6074
|
});
|
|
5968
6075
|
|
|
@@ -6710,7 +6817,7 @@ function generateSchemasFromReturnType(options) {
|
|
|
6710
6817
|
}
|
|
6711
6818
|
function resolveDeclarationMetadata(options) {
|
|
6712
6819
|
const resolved = resolveStaticOptions(options);
|
|
6713
|
-
const analysis = (0,
|
|
6820
|
+
const analysis = (0, import_internal7.analyzeMetadataForNodeWithChecker)({
|
|
6714
6821
|
checker: options.context.checker,
|
|
6715
6822
|
node: options.declaration,
|
|
6716
6823
|
metadata: resolved.metadata,
|
|
@@ -6756,12 +6863,12 @@ function unwrapPromiseTypeNode(typeNode) {
|
|
|
6756
6863
|
function isPromiseTypeReferenceNode(typeNode) {
|
|
6757
6864
|
return ts11.isTypeReferenceNode(typeNode) && ts11.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
|
|
6758
6865
|
}
|
|
6759
|
-
var ts11,
|
|
6866
|
+
var ts11, import_internal7, import_internals6;
|
|
6760
6867
|
var init_discovered_schema = __esm({
|
|
6761
6868
|
"src/generators/discovered-schema.ts"() {
|
|
6762
6869
|
"use strict";
|
|
6763
6870
|
ts11 = __toESM(require("typescript"), 1);
|
|
6764
|
-
|
|
6871
|
+
import_internal7 = require("@formspec/analysis/internal");
|
|
6765
6872
|
init_class_analyzer();
|
|
6766
6873
|
init_class_schema();
|
|
6767
6874
|
init_ir_generator();
|
|
@@ -7003,7 +7110,7 @@ __export(index_exports, {
|
|
|
7003
7110
|
writeSchemas: () => writeSchemas
|
|
7004
7111
|
});
|
|
7005
7112
|
function buildFormSchemas(form, options) {
|
|
7006
|
-
const logger = options?.logger ??
|
|
7113
|
+
const logger = options?.logger ?? import_core5.noopLogger;
|
|
7007
7114
|
logger.debug("buildFormSchemas: starting schema generation");
|
|
7008
7115
|
return {
|
|
7009
7116
|
jsonSchema: generateJsonSchema(form, options),
|
|
@@ -7020,7 +7127,7 @@ function writeSchemas(form, options) {
|
|
|
7020
7127
|
metadata,
|
|
7021
7128
|
logger: rawLogger
|
|
7022
7129
|
} = options;
|
|
7023
|
-
const logger = (rawLogger ??
|
|
7130
|
+
const logger = (rawLogger ?? import_core5.noopLogger).child({ stage: "write" });
|
|
7024
7131
|
const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? { logger: rawLogger } : {
|
|
7025
7132
|
...vendorPrefix !== void 0 && { vendorPrefix },
|
|
7026
7133
|
...enumSerialization !== void 0 && { enumSerialization },
|
|
@@ -7039,11 +7146,11 @@ function writeSchemas(form, options) {
|
|
|
7039
7146
|
fs.writeFileSync(uiSchemaPath, JSON.stringify(uiSchema2, null, indent));
|
|
7040
7147
|
return { jsonSchemaPath, uiSchemaPath };
|
|
7041
7148
|
}
|
|
7042
|
-
var
|
|
7149
|
+
var import_core5, fs, path3;
|
|
7043
7150
|
var init_index = __esm({
|
|
7044
7151
|
"src/index.ts"() {
|
|
7045
7152
|
"use strict";
|
|
7046
|
-
|
|
7153
|
+
import_core5 = require("@formspec/core");
|
|
7047
7154
|
init_generator();
|
|
7048
7155
|
init_generator2();
|
|
7049
7156
|
init_ir_generator();
|
|
@@ -7105,7 +7212,7 @@ Usage:
|
|
|
7105
7212
|
Options:
|
|
7106
7213
|
-o, --out-dir <dir> Output directory (default: ./generated)
|
|
7107
7214
|
-n, --name <name> Base name for output files (default: derived from input)
|
|
7108
|
-
--enum-serialization <enum|oneOf>
|
|
7215
|
+
--enum-serialization <enum|oneOf|smart-size>
|
|
7109
7216
|
Enum JSON Schema representation (default: enum)
|
|
7110
7217
|
-h, --help Show this help message
|
|
7111
7218
|
|
|
@@ -7157,8 +7264,10 @@ function parseArgs(args) {
|
|
|
7157
7264
|
console.error("Error: --enum-serialization requires a value");
|
|
7158
7265
|
return null;
|
|
7159
7266
|
}
|
|
7160
|
-
if (nextArg !== "enum" && nextArg !== "oneOf") {
|
|
7161
|
-
console.error(
|
|
7267
|
+
if (nextArg !== "enum" && nextArg !== "oneOf" && nextArg !== "smart-size") {
|
|
7268
|
+
console.error(
|
|
7269
|
+
'Error: --enum-serialization must be "enum", "oneOf", or "smart-size"'
|
|
7270
|
+
);
|
|
7162
7271
|
return null;
|
|
7163
7272
|
}
|
|
7164
7273
|
enumSerialization = nextArg;
|