@formspec/build 0.1.0-alpha.54 → 0.1.0-alpha.55
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 +18 -4
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +20 -5
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +0 -40
- package/dist/build-beta.d.ts +0 -40
- package/dist/build-internal.d.ts +0 -40
- package/dist/build.d.ts +0 -40
- package/dist/cli.cjs +144 -55
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +141 -43
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/index.cjs +139 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +141 -43
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +140 -51
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +138 -40
- package/dist/internals.js.map +1 -1
- package/package.json +5 -5
package/dist/build-alpha.d.ts
CHANGED
|
@@ -469,46 +469,6 @@ declare interface CustomTypeRegistration_2 {
|
|
|
469
469
|
* Note: `"__integerBrand"` is reserved for the builtin Integer type.
|
|
470
470
|
*/
|
|
471
471
|
readonly brand?: string;
|
|
472
|
-
/**
|
|
473
|
-
* Optional callback to extract a payload from the TypeScript type at
|
|
474
|
-
* analysis time. The returned value is stored on the custom type node
|
|
475
|
-
* and later passed to `toJsonSchema`.
|
|
476
|
-
*
|
|
477
|
-
* Use this to carry type-level information (e.g., a generic argument's
|
|
478
|
-
* resolved literal value) through the IR into schema generation.
|
|
479
|
-
*
|
|
480
|
-
* **Parameters:** typed as `unknown` because `@formspec/core` does not
|
|
481
|
-
* depend on the TypeScript compiler API. Implementations should cast to
|
|
482
|
-
* `ts.Type` and `ts.TypeChecker`. Both parameters originate from the
|
|
483
|
-
* host program's type checker — extensions may rely on host-program
|
|
484
|
-
* symbol identity.
|
|
485
|
-
*
|
|
486
|
-
* **Contract:**
|
|
487
|
-
* - Must be a pure function of `(type, checker)` — no I/O or shared state.
|
|
488
|
-
* - May be invoked multiple times for the same type (no memoization is provided).
|
|
489
|
-
* - Must return a JSON-serializable `ExtensionPayloadValue`. Returning live
|
|
490
|
-
* compiler objects (e.g., `ts.Type`) will corrupt any IR caching.
|
|
491
|
-
* - Errors thrown by the callback are attributed to the extension and
|
|
492
|
-
* reported as build diagnostics.
|
|
493
|
-
* - Returning `undefined` is coerced to `null` at the call site.
|
|
494
|
-
*
|
|
495
|
-
* @param type - The resolved TypeScript type (cast to `ts.Type`).
|
|
496
|
-
* @param checker - The TypeScript type checker (cast to `ts.TypeChecker`).
|
|
497
|
-
* @returns A JSON-serializable payload, or `null` if no payload can be extracted.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* extractPayload: (type: unknown, checker: unknown) => {
|
|
502
|
-
* const tsType = type as ts.Type;
|
|
503
|
-
* const tsChecker = checker as ts.TypeChecker;
|
|
504
|
-
* const prop = tsType.getProperty('target');
|
|
505
|
-
* if (!prop) return null;
|
|
506
|
-
* const propType = tsChecker.getTypeOfSymbol(prop);
|
|
507
|
-
* return propType.isStringLiteral() ? propType.value : null;
|
|
508
|
-
* }
|
|
509
|
-
* ```
|
|
510
|
-
*/
|
|
511
|
-
readonly extractPayload?: (type: unknown, checker: unknown) => ExtensionPayloadValue;
|
|
512
472
|
/**
|
|
513
473
|
* Converts the custom type's payload into a JSON Schema fragment.
|
|
514
474
|
*
|
package/dist/build-beta.d.ts
CHANGED
|
@@ -469,46 +469,6 @@ declare interface CustomTypeRegistration_2 {
|
|
|
469
469
|
* Note: `"__integerBrand"` is reserved for the builtin Integer type.
|
|
470
470
|
*/
|
|
471
471
|
readonly brand?: string;
|
|
472
|
-
/**
|
|
473
|
-
* Optional callback to extract a payload from the TypeScript type at
|
|
474
|
-
* analysis time. The returned value is stored on the custom type node
|
|
475
|
-
* and later passed to `toJsonSchema`.
|
|
476
|
-
*
|
|
477
|
-
* Use this to carry type-level information (e.g., a generic argument's
|
|
478
|
-
* resolved literal value) through the IR into schema generation.
|
|
479
|
-
*
|
|
480
|
-
* **Parameters:** typed as `unknown` because `@formspec/core` does not
|
|
481
|
-
* depend on the TypeScript compiler API. Implementations should cast to
|
|
482
|
-
* `ts.Type` and `ts.TypeChecker`. Both parameters originate from the
|
|
483
|
-
* host program's type checker — extensions may rely on host-program
|
|
484
|
-
* symbol identity.
|
|
485
|
-
*
|
|
486
|
-
* **Contract:**
|
|
487
|
-
* - Must be a pure function of `(type, checker)` — no I/O or shared state.
|
|
488
|
-
* - May be invoked multiple times for the same type (no memoization is provided).
|
|
489
|
-
* - Must return a JSON-serializable `ExtensionPayloadValue`. Returning live
|
|
490
|
-
* compiler objects (e.g., `ts.Type`) will corrupt any IR caching.
|
|
491
|
-
* - Errors thrown by the callback are attributed to the extension and
|
|
492
|
-
* reported as build diagnostics.
|
|
493
|
-
* - Returning `undefined` is coerced to `null` at the call site.
|
|
494
|
-
*
|
|
495
|
-
* @param type - The resolved TypeScript type (cast to `ts.Type`).
|
|
496
|
-
* @param checker - The TypeScript type checker (cast to `ts.TypeChecker`).
|
|
497
|
-
* @returns A JSON-serializable payload, or `null` if no payload can be extracted.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* extractPayload: (type: unknown, checker: unknown) => {
|
|
502
|
-
* const tsType = type as ts.Type;
|
|
503
|
-
* const tsChecker = checker as ts.TypeChecker;
|
|
504
|
-
* const prop = tsType.getProperty('target');
|
|
505
|
-
* if (!prop) return null;
|
|
506
|
-
* const propType = tsChecker.getTypeOfSymbol(prop);
|
|
507
|
-
* return propType.isStringLiteral() ? propType.value : null;
|
|
508
|
-
* }
|
|
509
|
-
* ```
|
|
510
|
-
*/
|
|
511
|
-
readonly extractPayload?: (type: unknown, checker: unknown) => ExtensionPayloadValue;
|
|
512
472
|
/**
|
|
513
473
|
* Converts the custom type's payload into a JSON Schema fragment.
|
|
514
474
|
*
|
package/dist/build-internal.d.ts
CHANGED
|
@@ -469,46 +469,6 @@ declare interface CustomTypeRegistration_2 {
|
|
|
469
469
|
* Note: `"__integerBrand"` is reserved for the builtin Integer type.
|
|
470
470
|
*/
|
|
471
471
|
readonly brand?: string;
|
|
472
|
-
/**
|
|
473
|
-
* Optional callback to extract a payload from the TypeScript type at
|
|
474
|
-
* analysis time. The returned value is stored on the custom type node
|
|
475
|
-
* and later passed to `toJsonSchema`.
|
|
476
|
-
*
|
|
477
|
-
* Use this to carry type-level information (e.g., a generic argument's
|
|
478
|
-
* resolved literal value) through the IR into schema generation.
|
|
479
|
-
*
|
|
480
|
-
* **Parameters:** typed as `unknown` because `@formspec/core` does not
|
|
481
|
-
* depend on the TypeScript compiler API. Implementations should cast to
|
|
482
|
-
* `ts.Type` and `ts.TypeChecker`. Both parameters originate from the
|
|
483
|
-
* host program's type checker — extensions may rely on host-program
|
|
484
|
-
* symbol identity.
|
|
485
|
-
*
|
|
486
|
-
* **Contract:**
|
|
487
|
-
* - Must be a pure function of `(type, checker)` — no I/O or shared state.
|
|
488
|
-
* - May be invoked multiple times for the same type (no memoization is provided).
|
|
489
|
-
* - Must return a JSON-serializable `ExtensionPayloadValue`. Returning live
|
|
490
|
-
* compiler objects (e.g., `ts.Type`) will corrupt any IR caching.
|
|
491
|
-
* - Errors thrown by the callback are attributed to the extension and
|
|
492
|
-
* reported as build diagnostics.
|
|
493
|
-
* - Returning `undefined` is coerced to `null` at the call site.
|
|
494
|
-
*
|
|
495
|
-
* @param type - The resolved TypeScript type (cast to `ts.Type`).
|
|
496
|
-
* @param checker - The TypeScript type checker (cast to `ts.TypeChecker`).
|
|
497
|
-
* @returns A JSON-serializable payload, or `null` if no payload can be extracted.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* extractPayload: (type: unknown, checker: unknown) => {
|
|
502
|
-
* const tsType = type as ts.Type;
|
|
503
|
-
* const tsChecker = checker as ts.TypeChecker;
|
|
504
|
-
* const prop = tsType.getProperty('target');
|
|
505
|
-
* if (!prop) return null;
|
|
506
|
-
* const propType = tsChecker.getTypeOfSymbol(prop);
|
|
507
|
-
* return propType.isStringLiteral() ? propType.value : null;
|
|
508
|
-
* }
|
|
509
|
-
* ```
|
|
510
|
-
*/
|
|
511
|
-
readonly extractPayload?: (type: unknown, checker: unknown) => ExtensionPayloadValue;
|
|
512
472
|
/**
|
|
513
473
|
* Converts the custom type's payload into a JSON Schema fragment.
|
|
514
474
|
*
|
package/dist/build.d.ts
CHANGED
|
@@ -469,46 +469,6 @@ declare interface CustomTypeRegistration_2 {
|
|
|
469
469
|
* Note: `"__integerBrand"` is reserved for the builtin Integer type.
|
|
470
470
|
*/
|
|
471
471
|
readonly brand?: string;
|
|
472
|
-
/**
|
|
473
|
-
* Optional callback to extract a payload from the TypeScript type at
|
|
474
|
-
* analysis time. The returned value is stored on the custom type node
|
|
475
|
-
* and later passed to `toJsonSchema`.
|
|
476
|
-
*
|
|
477
|
-
* Use this to carry type-level information (e.g., a generic argument's
|
|
478
|
-
* resolved literal value) through the IR into schema generation.
|
|
479
|
-
*
|
|
480
|
-
* **Parameters:** typed as `unknown` because `@formspec/core` does not
|
|
481
|
-
* depend on the TypeScript compiler API. Implementations should cast to
|
|
482
|
-
* `ts.Type` and `ts.TypeChecker`. Both parameters originate from the
|
|
483
|
-
* host program's type checker — extensions may rely on host-program
|
|
484
|
-
* symbol identity.
|
|
485
|
-
*
|
|
486
|
-
* **Contract:**
|
|
487
|
-
* - Must be a pure function of `(type, checker)` — no I/O or shared state.
|
|
488
|
-
* - May be invoked multiple times for the same type (no memoization is provided).
|
|
489
|
-
* - Must return a JSON-serializable `ExtensionPayloadValue`. Returning live
|
|
490
|
-
* compiler objects (e.g., `ts.Type`) will corrupt any IR caching.
|
|
491
|
-
* - Errors thrown by the callback are attributed to the extension and
|
|
492
|
-
* reported as build diagnostics.
|
|
493
|
-
* - Returning `undefined` is coerced to `null` at the call site.
|
|
494
|
-
*
|
|
495
|
-
* @param type - The resolved TypeScript type (cast to `ts.Type`).
|
|
496
|
-
* @param checker - The TypeScript type checker (cast to `ts.TypeChecker`).
|
|
497
|
-
* @returns A JSON-serializable payload, or `null` if no payload can be extracted.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* extractPayload: (type: unknown, checker: unknown) => {
|
|
502
|
-
* const tsType = type as ts.Type;
|
|
503
|
-
* const tsChecker = checker as ts.TypeChecker;
|
|
504
|
-
* const prop = tsType.getProperty('target');
|
|
505
|
-
* if (!prop) return null;
|
|
506
|
-
* const propType = tsChecker.getTypeOfSymbol(prop);
|
|
507
|
-
* return propType.isStringLiteral() ? propType.value : null;
|
|
508
|
-
* }
|
|
509
|
-
* ```
|
|
510
|
-
*/
|
|
511
|
-
readonly extractPayload?: (type: unknown, checker: unknown) => ExtensionPayloadValue;
|
|
512
472
|
/**
|
|
513
473
|
* Converts the custom type's payload into a JSON Schema fragment.
|
|
514
474
|
*
|
package/dist/cli.cjs
CHANGED
|
@@ -1241,10 +1241,11 @@ function generatePrimitiveType(type) {
|
|
|
1241
1241
|
function generateEnumType(type, ctx) {
|
|
1242
1242
|
if (ctx.enumSerialization === "oneOf") {
|
|
1243
1243
|
return {
|
|
1244
|
-
oneOf: type.members.map((m) =>
|
|
1245
|
-
const
|
|
1246
|
-
title
|
|
1247
|
-
|
|
1244
|
+
oneOf: type.members.map((m) => {
|
|
1245
|
+
const stringValue = String(m.value);
|
|
1246
|
+
const title = m.displayName !== void 0 && m.displayName !== stringValue ? m.displayName : void 0;
|
|
1247
|
+
return title !== void 0 ? { const: m.value, title } : { const: m.value };
|
|
1248
|
+
})
|
|
1248
1249
|
};
|
|
1249
1250
|
}
|
|
1250
1251
|
const schema = { enum: type.members.map((m) => m.value) };
|
|
@@ -2072,6 +2073,11 @@ function buildConstraintTagSources(extensions) {
|
|
|
2072
2073
|
}));
|
|
2073
2074
|
}
|
|
2074
2075
|
function createExtensionRegistry(extensions) {
|
|
2076
|
+
const registryLog = (0, import_internal.getSyntheticLogger)();
|
|
2077
|
+
registryLog.debug("createExtensionRegistry: constructing", {
|
|
2078
|
+
extensionCount: extensions.length,
|
|
2079
|
+
extensionIds: extensions.map((e) => e.extensionId)
|
|
2080
|
+
});
|
|
2075
2081
|
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
2076
2082
|
let symbolMap = /* @__PURE__ */ new Map();
|
|
2077
2083
|
const typeMap = /* @__PURE__ */ new Map();
|
|
@@ -2203,6 +2209,14 @@ function createExtensionRegistry(extensions) {
|
|
|
2203
2209
|
}
|
|
2204
2210
|
}
|
|
2205
2211
|
}
|
|
2212
|
+
registryLog.debug("createExtensionRegistry: complete", {
|
|
2213
|
+
typeCount: typeMap.size,
|
|
2214
|
+
constraintCount: constraintMap.size,
|
|
2215
|
+
constraintTagCount: constraintTagMap.size,
|
|
2216
|
+
broadeningCount: builtinBroadeningMap.size,
|
|
2217
|
+
annotationCount: annotationMap.size,
|
|
2218
|
+
metadataSlotCount: metadataSlotMap.size
|
|
2219
|
+
});
|
|
2206
2220
|
return {
|
|
2207
2221
|
extensions,
|
|
2208
2222
|
findType: (typeId) => typeMap.get(typeId),
|
|
@@ -2851,56 +2865,82 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2851
2865
|
if (definition === null) {
|
|
2852
2866
|
return [];
|
|
2853
2867
|
}
|
|
2868
|
+
const nonNullPlacement = placement;
|
|
2869
|
+
const log2 = (0, import_internal4.getBuildLogger)();
|
|
2870
|
+
const broadeningLog = (0, import_internal4.getBroadeningLogger)();
|
|
2871
|
+
const syntheticLog = (0, import_internal4.getSyntheticLogger)();
|
|
2872
|
+
const logsEnabled = log2 !== import_core4.noopLogger || broadeningLog !== import_core4.noopLogger;
|
|
2873
|
+
const syntheticTraceEnabled = syntheticLog !== import_core4.noopLogger;
|
|
2874
|
+
const logStart = logsEnabled ? (0, import_internal4.nowMicros)() : 0;
|
|
2875
|
+
const subjectTypeKind = logsEnabled ? (0, import_internal4.describeTypeKind)(subjectType, checker) : "";
|
|
2876
|
+
function emit(outcome, result2) {
|
|
2877
|
+
if (!logsEnabled) {
|
|
2878
|
+
return result2;
|
|
2879
|
+
}
|
|
2880
|
+
const entry = {
|
|
2881
|
+
consumer: "build",
|
|
2882
|
+
tag: tagName,
|
|
2883
|
+
placement: nonNullPlacement,
|
|
2884
|
+
subjectTypeKind,
|
|
2885
|
+
roleOutcome: outcome,
|
|
2886
|
+
elapsedMicros: (0, import_internal4.elapsedMicros)(logStart)
|
|
2887
|
+
};
|
|
2888
|
+
(0, import_internal4.logTagApplication)(log2, entry);
|
|
2889
|
+
if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
|
|
2890
|
+
(0, import_internal4.logTagApplication)(broadeningLog, entry);
|
|
2891
|
+
}
|
|
2892
|
+
return result2;
|
|
2893
|
+
}
|
|
2854
2894
|
if (!definition.placements.includes(placement)) {
|
|
2855
|
-
return [
|
|
2895
|
+
return emit("A-reject", [
|
|
2856
2896
|
makeDiagnostic(
|
|
2857
2897
|
"INVALID_TAG_PLACEMENT",
|
|
2858
2898
|
`Tag "@${tagName}" is not allowed on ${placementLabel(placement)}.`,
|
|
2859
2899
|
provenance
|
|
2860
2900
|
)
|
|
2861
|
-
];
|
|
2901
|
+
]);
|
|
2862
2902
|
}
|
|
2863
2903
|
const target = parsedTag?.target ?? null;
|
|
2864
2904
|
let evaluatedType = subjectType;
|
|
2865
2905
|
let targetLabel = node.getText(sourceFile);
|
|
2866
2906
|
if (target !== null) {
|
|
2867
2907
|
if (target.kind !== "path") {
|
|
2868
|
-
return [
|
|
2908
|
+
return emit("B-reject", [
|
|
2869
2909
|
makeDiagnostic(
|
|
2870
2910
|
"UNSUPPORTED_TARGETING_SYNTAX",
|
|
2871
2911
|
`Tag "@${tagName}" does not support ${target.kind} targeting syntax.`,
|
|
2872
2912
|
provenance
|
|
2873
2913
|
)
|
|
2874
|
-
];
|
|
2914
|
+
]);
|
|
2875
2915
|
}
|
|
2876
2916
|
if (!target.valid || target.path === null) {
|
|
2877
|
-
return [
|
|
2917
|
+
return emit("B-reject", [
|
|
2878
2918
|
makeDiagnostic(
|
|
2879
2919
|
"UNSUPPORTED_TARGETING_SYNTAX",
|
|
2880
2920
|
`Tag "@${tagName}" has invalid path targeting syntax.`,
|
|
2881
2921
|
provenance
|
|
2882
2922
|
)
|
|
2883
|
-
];
|
|
2923
|
+
]);
|
|
2884
2924
|
}
|
|
2885
2925
|
const resolution = (0, import_internal3.resolvePathTargetType)(subjectType, checker, target.path.segments);
|
|
2886
2926
|
if (resolution.kind === "missing-property") {
|
|
2887
|
-
return [
|
|
2927
|
+
return emit("B-reject", [
|
|
2888
2928
|
makeDiagnostic(
|
|
2889
2929
|
"UNKNOWN_PATH_TARGET",
|
|
2890
2930
|
`Target "${target.rawText}": path-targeted constraint "${tagName}" references unknown path segment "${resolution.segment}"`,
|
|
2891
2931
|
provenance
|
|
2892
2932
|
)
|
|
2893
|
-
];
|
|
2933
|
+
]);
|
|
2894
2934
|
}
|
|
2895
2935
|
if (resolution.kind === "unresolvable") {
|
|
2896
2936
|
const actualType = checker.typeToString(resolution.type, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2897
|
-
return [
|
|
2937
|
+
return emit("B-reject", [
|
|
2898
2938
|
makeDiagnostic(
|
|
2899
2939
|
"TYPE_MISMATCH",
|
|
2900
2940
|
`Target "${target.rawText}": path-targeted constraint "${tagName}" is invalid because type "${actualType}" cannot be traversed`,
|
|
2901
2941
|
provenance
|
|
2902
2942
|
)
|
|
2903
|
-
];
|
|
2943
|
+
]);
|
|
2904
2944
|
}
|
|
2905
2945
|
evaluatedType = resolution.type;
|
|
2906
2946
|
targetLabel = target.rawText;
|
|
@@ -2929,13 +2969,13 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2929
2969
|
tagName,
|
|
2930
2970
|
parsedTag?.argumentText
|
|
2931
2971
|
) : null;
|
|
2932
|
-
return [
|
|
2972
|
+
return emit("B-reject", [
|
|
2933
2973
|
makeDiagnostic(
|
|
2934
2974
|
"TYPE_MISMATCH",
|
|
2935
2975
|
hint === null ? baseMessage : `${baseMessage}. ${hint}`,
|
|
2936
2976
|
provenance
|
|
2937
2977
|
)
|
|
2938
|
-
];
|
|
2978
|
+
]);
|
|
2939
2979
|
}
|
|
2940
2980
|
}
|
|
2941
2981
|
const argumentExpression = renderSyntheticArgumentExpression(
|
|
@@ -2943,14 +2983,23 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2943
2983
|
parsedTag?.argumentText ?? ""
|
|
2944
2984
|
);
|
|
2945
2985
|
if (definition.requiresArgument && argumentExpression === null) {
|
|
2946
|
-
return [];
|
|
2986
|
+
return emit("A-pass", []);
|
|
2947
2987
|
}
|
|
2948
2988
|
if (hasBroadening) {
|
|
2949
|
-
return [];
|
|
2989
|
+
return emit("bypass", []);
|
|
2950
2990
|
}
|
|
2951
2991
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2952
2992
|
const hostType = options?.hostType ?? subjectType;
|
|
2953
2993
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2994
|
+
if (syntheticTraceEnabled) {
|
|
2995
|
+
syntheticLog.trace("invoking synthetic checker", {
|
|
2996
|
+
consumer: "build",
|
|
2997
|
+
tag: tagName,
|
|
2998
|
+
placement,
|
|
2999
|
+
subjectTypeKind,
|
|
3000
|
+
subjectTypeText
|
|
3001
|
+
});
|
|
3002
|
+
}
|
|
2954
3003
|
const result = (0, import_internal3.checkSyntheticTagApplication)({
|
|
2955
3004
|
tagName,
|
|
2956
3005
|
placement,
|
|
@@ -2977,26 +3026,26 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2977
3026
|
} : {}
|
|
2978
3027
|
});
|
|
2979
3028
|
if (result.diagnostics.length === 0) {
|
|
2980
|
-
return [];
|
|
3029
|
+
return emit("C-pass", []);
|
|
2981
3030
|
}
|
|
2982
3031
|
const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
|
|
2983
3032
|
if (setupDiagnostic !== void 0) {
|
|
2984
|
-
return [
|
|
3033
|
+
return emit("C-reject", [
|
|
2985
3034
|
makeDiagnostic(
|
|
2986
3035
|
setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
|
|
2987
3036
|
setupDiagnostic.message,
|
|
2988
3037
|
provenance
|
|
2989
3038
|
)
|
|
2990
|
-
];
|
|
3039
|
+
]);
|
|
2991
3040
|
}
|
|
2992
3041
|
const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
|
|
2993
|
-
return [
|
|
3042
|
+
return emit("C-reject", [
|
|
2994
3043
|
makeDiagnostic(
|
|
2995
3044
|
"TYPE_MISMATCH",
|
|
2996
3045
|
`Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
|
|
2997
3046
|
provenance
|
|
2998
3047
|
)
|
|
2999
|
-
];
|
|
3048
|
+
]);
|
|
3000
3049
|
}
|
|
3001
3050
|
function getExtensionTagNames(options) {
|
|
3002
3051
|
return [
|
|
@@ -3308,7 +3357,7 @@ function getTagCommentText(tag) {
|
|
|
3308
3357
|
}
|
|
3309
3358
|
return ts4.getTextOfJSDocComment(tag.comment);
|
|
3310
3359
|
}
|
|
3311
|
-
var ts4, import_internal3, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
|
|
3360
|
+
var ts4, import_internal3, import_internals4, import_internals5, import_core4, import_internal4, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
|
|
3312
3361
|
var init_tsdoc_parser = __esm({
|
|
3313
3362
|
"src/analyzer/tsdoc-parser.ts"() {
|
|
3314
3363
|
"use strict";
|
|
@@ -3316,8 +3365,10 @@ var init_tsdoc_parser = __esm({
|
|
|
3316
3365
|
import_internal3 = require("@formspec/analysis/internal");
|
|
3317
3366
|
import_internals4 = require("@formspec/core/internals");
|
|
3318
3367
|
import_internals5 = require("@formspec/core/internals");
|
|
3368
|
+
import_core4 = require("@formspec/core");
|
|
3319
3369
|
init_resolve_custom_type();
|
|
3320
3370
|
init_builtin_brands();
|
|
3371
|
+
import_internal4 = require("@formspec/analysis/internal");
|
|
3321
3372
|
SYNTHETIC_TYPE_FORMAT_FLAGS = ts4.TypeFormatFlags.NoTruncation | ts4.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
3322
3373
|
MAX_HINT_CANDIDATES = 5;
|
|
3323
3374
|
MAX_HINT_DEPTH = 3;
|
|
@@ -3424,7 +3475,7 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
|
3424
3475
|
};
|
|
3425
3476
|
}
|
|
3426
3477
|
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
3427
|
-
const analysis = (0,
|
|
3478
|
+
const analysis = (0, import_internal5.analyzeMetadataForNodeWithChecker)({
|
|
3428
3479
|
checker,
|
|
3429
3480
|
node,
|
|
3430
3481
|
logicalName,
|
|
@@ -3765,7 +3816,7 @@ function getLeadingParsedTags(node) {
|
|
|
3765
3816
|
if (!commentText.startsWith("/**")) {
|
|
3766
3817
|
continue;
|
|
3767
3818
|
}
|
|
3768
|
-
parsedTags.push(...(0,
|
|
3819
|
+
parsedTags.push(...(0, import_internal5.parseCommentBlock)(commentText, { offset: range.pos }).tags);
|
|
3769
3820
|
}
|
|
3770
3821
|
return parsedTags;
|
|
3771
3822
|
}
|
|
@@ -4174,6 +4225,22 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
4174
4225
|
}
|
|
4175
4226
|
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
4176
4227
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
4228
|
+
const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
|
|
4229
|
+
const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts6.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
|
|
4230
|
+
const argumentDecl = argumentSymbol?.declarations?.[0];
|
|
4231
|
+
if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
|
|
4232
|
+
const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
|
|
4233
|
+
if (argumentName !== void 0) {
|
|
4234
|
+
return {
|
|
4235
|
+
tsType: argumentType,
|
|
4236
|
+
typeNode: {
|
|
4237
|
+
kind: "reference",
|
|
4238
|
+
name: argumentName,
|
|
4239
|
+
typeArguments: []
|
|
4240
|
+
}
|
|
4241
|
+
};
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4177
4244
|
return {
|
|
4178
4245
|
tsType: argumentType,
|
|
4179
4246
|
typeNode: resolveTypeNode(
|
|
@@ -4440,22 +4507,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
4440
4507
|
sourceNode
|
|
4441
4508
|
);
|
|
4442
4509
|
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
4510
|
return {
|
|
4456
4511
|
kind: "custom",
|
|
4457
|
-
typeId,
|
|
4458
|
-
payload
|
|
4512
|
+
typeId: customTypeIdFromLookup(customTypeLookup),
|
|
4513
|
+
payload: null
|
|
4459
4514
|
};
|
|
4460
4515
|
}
|
|
4461
4516
|
const primitiveAlias = tryResolveNamedPrimitiveAlias(
|
|
@@ -4639,6 +4694,21 @@ function getReferencedTypeAliasDeclaration(sourceNode, checker) {
|
|
|
4639
4694
|
}
|
|
4640
4695
|
return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
|
|
4641
4696
|
}
|
|
4697
|
+
function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
|
|
4698
|
+
const typeName = getNamedTypeName(type);
|
|
4699
|
+
const namedDecl = getNamedTypeDeclaration(type);
|
|
4700
|
+
if (typeName !== null && namedDecl !== void 0) {
|
|
4701
|
+
return { typeName, namedDecl };
|
|
4702
|
+
}
|
|
4703
|
+
if (sourceNode === void 0) {
|
|
4704
|
+
return null;
|
|
4705
|
+
}
|
|
4706
|
+
const refAliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
|
|
4707
|
+
if (refAliasDecl === void 0) {
|
|
4708
|
+
return null;
|
|
4709
|
+
}
|
|
4710
|
+
return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
|
|
4711
|
+
}
|
|
4642
4712
|
function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
4643
4713
|
if (!ts6.isTypeReferenceNode(typeNode)) {
|
|
4644
4714
|
return false;
|
|
@@ -4697,8 +4767,23 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
4697
4767
|
);
|
|
4698
4768
|
}
|
|
4699
4769
|
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4700
|
-
const
|
|
4701
|
-
|
|
4770
|
+
const recovered = resolveNamedTypeWithSourceRecovery(type, sourceNode, checker);
|
|
4771
|
+
let typeName = null;
|
|
4772
|
+
let namedDecl;
|
|
4773
|
+
if (recovered !== null) {
|
|
4774
|
+
const recoveredAliasDecl = ts6.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
|
|
4775
|
+
if (recoveredAliasDecl !== void 0) {
|
|
4776
|
+
const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
|
|
4777
|
+
const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
|
|
4778
|
+
if (isNonGeneric && (aliasUnderlyingType.isUnion() || isObjectType(aliasUnderlyingType))) {
|
|
4779
|
+
typeName = recovered.typeName;
|
|
4780
|
+
namedDecl = recovered.namedDecl;
|
|
4781
|
+
}
|
|
4782
|
+
} else {
|
|
4783
|
+
typeName = recovered.typeName;
|
|
4784
|
+
namedDecl = recovered.namedDecl;
|
|
4785
|
+
}
|
|
4786
|
+
}
|
|
4702
4787
|
if (typeName && typeName in typeRegistry) {
|
|
4703
4788
|
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4704
4789
|
}
|
|
@@ -4730,6 +4815,10 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4730
4815
|
if (!typeName) {
|
|
4731
4816
|
return result;
|
|
4732
4817
|
}
|
|
4818
|
+
const existing = typeRegistry[typeName];
|
|
4819
|
+
if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
|
|
4820
|
+
return { kind: "reference", name: typeName, typeArguments: [] };
|
|
4821
|
+
}
|
|
4733
4822
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4734
4823
|
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4735
4824
|
metadataPolicy,
|
|
@@ -5377,12 +5466,12 @@ function detectFormSpecReference(typeNode) {
|
|
|
5377
5466
|
}
|
|
5378
5467
|
return null;
|
|
5379
5468
|
}
|
|
5380
|
-
var ts6,
|
|
5469
|
+
var ts6, import_internal5, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
|
|
5381
5470
|
var init_class_analyzer = __esm({
|
|
5382
5471
|
"src/analyzer/class-analyzer.ts"() {
|
|
5383
5472
|
"use strict";
|
|
5384
5473
|
ts6 = __toESM(require("typescript"), 1);
|
|
5385
|
-
|
|
5474
|
+
import_internal5 = require("@formspec/analysis/internal");
|
|
5386
5475
|
init_jsdoc_constraints();
|
|
5387
5476
|
init_tsdoc_parser();
|
|
5388
5477
|
init_resolve_custom_type();
|
|
@@ -5889,7 +5978,7 @@ var init_symbol_registry = __esm({
|
|
|
5889
5978
|
|
|
5890
5979
|
// src/validate/constraint-validator.ts
|
|
5891
5980
|
function validateFieldNode(ctx, field) {
|
|
5892
|
-
const analysis = (0,
|
|
5981
|
+
const analysis = (0, import_internal6.analyzeConstraintTargets)(
|
|
5893
5982
|
field.name,
|
|
5894
5983
|
field.type,
|
|
5895
5984
|
field.constraints,
|
|
@@ -5907,7 +5996,7 @@ function validateFieldNode(ctx, field) {
|
|
|
5907
5996
|
}
|
|
5908
5997
|
function validateObjectProperty(ctx, parentName, property) {
|
|
5909
5998
|
const qualifiedName = `${parentName}.${property.name}`;
|
|
5910
|
-
const analysis = (0,
|
|
5999
|
+
const analysis = (0, import_internal6.analyzeConstraintTargets)(
|
|
5911
6000
|
qualifiedName,
|
|
5912
6001
|
property.type,
|
|
5913
6002
|
property.constraints,
|
|
@@ -5958,11 +6047,11 @@ function validateIR(ir, options) {
|
|
|
5958
6047
|
valid: ctx.diagnostics.every((diagnostic) => diagnostic.severity !== "error")
|
|
5959
6048
|
};
|
|
5960
6049
|
}
|
|
5961
|
-
var
|
|
6050
|
+
var import_internal6;
|
|
5962
6051
|
var init_constraint_validator = __esm({
|
|
5963
6052
|
"src/validate/constraint-validator.ts"() {
|
|
5964
6053
|
"use strict";
|
|
5965
|
-
|
|
6054
|
+
import_internal6 = require("@formspec/analysis/internal");
|
|
5966
6055
|
}
|
|
5967
6056
|
});
|
|
5968
6057
|
|
|
@@ -6710,7 +6799,7 @@ function generateSchemasFromReturnType(options) {
|
|
|
6710
6799
|
}
|
|
6711
6800
|
function resolveDeclarationMetadata(options) {
|
|
6712
6801
|
const resolved = resolveStaticOptions(options);
|
|
6713
|
-
const analysis = (0,
|
|
6802
|
+
const analysis = (0, import_internal7.analyzeMetadataForNodeWithChecker)({
|
|
6714
6803
|
checker: options.context.checker,
|
|
6715
6804
|
node: options.declaration,
|
|
6716
6805
|
metadata: resolved.metadata,
|
|
@@ -6756,12 +6845,12 @@ function unwrapPromiseTypeNode(typeNode) {
|
|
|
6756
6845
|
function isPromiseTypeReferenceNode(typeNode) {
|
|
6757
6846
|
return ts11.isTypeReferenceNode(typeNode) && ts11.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
|
|
6758
6847
|
}
|
|
6759
|
-
var ts11,
|
|
6848
|
+
var ts11, import_internal7, import_internals6;
|
|
6760
6849
|
var init_discovered_schema = __esm({
|
|
6761
6850
|
"src/generators/discovered-schema.ts"() {
|
|
6762
6851
|
"use strict";
|
|
6763
6852
|
ts11 = __toESM(require("typescript"), 1);
|
|
6764
|
-
|
|
6853
|
+
import_internal7 = require("@formspec/analysis/internal");
|
|
6765
6854
|
init_class_analyzer();
|
|
6766
6855
|
init_class_schema();
|
|
6767
6856
|
init_ir_generator();
|
|
@@ -7003,7 +7092,7 @@ __export(index_exports, {
|
|
|
7003
7092
|
writeSchemas: () => writeSchemas
|
|
7004
7093
|
});
|
|
7005
7094
|
function buildFormSchemas(form, options) {
|
|
7006
|
-
const logger = options?.logger ??
|
|
7095
|
+
const logger = options?.logger ?? import_core5.noopLogger;
|
|
7007
7096
|
logger.debug("buildFormSchemas: starting schema generation");
|
|
7008
7097
|
return {
|
|
7009
7098
|
jsonSchema: generateJsonSchema(form, options),
|
|
@@ -7020,7 +7109,7 @@ function writeSchemas(form, options) {
|
|
|
7020
7109
|
metadata,
|
|
7021
7110
|
logger: rawLogger
|
|
7022
7111
|
} = options;
|
|
7023
|
-
const logger = (rawLogger ??
|
|
7112
|
+
const logger = (rawLogger ?? import_core5.noopLogger).child({ stage: "write" });
|
|
7024
7113
|
const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? { logger: rawLogger } : {
|
|
7025
7114
|
...vendorPrefix !== void 0 && { vendorPrefix },
|
|
7026
7115
|
...enumSerialization !== void 0 && { enumSerialization },
|
|
@@ -7039,11 +7128,11 @@ function writeSchemas(form, options) {
|
|
|
7039
7128
|
fs.writeFileSync(uiSchemaPath, JSON.stringify(uiSchema2, null, indent));
|
|
7040
7129
|
return { jsonSchemaPath, uiSchemaPath };
|
|
7041
7130
|
}
|
|
7042
|
-
var
|
|
7131
|
+
var import_core5, fs, path3;
|
|
7043
7132
|
var init_index = __esm({
|
|
7044
7133
|
"src/index.ts"() {
|
|
7045
7134
|
"use strict";
|
|
7046
|
-
|
|
7135
|
+
import_core5 = require("@formspec/core");
|
|
7047
7136
|
init_generator();
|
|
7048
7137
|
init_generator2();
|
|
7049
7138
|
init_ir_generator();
|