@formspec/build 0.1.0-alpha.59 → 0.1.0-alpha.63

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.
Files changed (45) hide show
  1. package/dist/analyzer/class-analyzer.d.ts +1 -1
  2. package/dist/analyzer/class-analyzer.d.ts.map +1 -1
  3. package/dist/analyzer/jsdoc-constraints.d.ts +0 -6
  4. package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
  5. package/dist/analyzer/tsdoc-parser.d.ts +2 -5
  6. package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
  7. package/dist/browser.cjs +1 -1
  8. package/dist/browser.cjs.map +1 -1
  9. package/dist/browser.js +2 -2
  10. package/dist/browser.js.map +1 -1
  11. package/dist/build-alpha.d.ts +2 -1
  12. package/dist/build-beta.d.ts +2 -1
  13. package/dist/build-internal.d.ts +18 -15
  14. package/dist/build.d.ts +2 -1
  15. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +2 -1
  16. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -1
  17. package/dist/canonicalize/tsdoc-canonicalizer.d.ts +2 -1
  18. package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -1
  19. package/dist/cli.cjs +45 -316
  20. package/dist/cli.cjs.map +1 -1
  21. package/dist/cli.js +48 -319
  22. package/dist/cli.js.map +1 -1
  23. package/dist/extensions/registry.d.ts +2 -2
  24. package/dist/extensions/registry.d.ts.map +1 -1
  25. package/dist/generators/method-schema.d.ts +3 -2
  26. package/dist/generators/method-schema.d.ts.map +1 -1
  27. package/dist/index.cjs +44 -315
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +47 -318
  32. package/dist/index.js.map +1 -1
  33. package/dist/internals.cjs +44 -315
  34. package/dist/internals.cjs.map +1 -1
  35. package/dist/internals.js +47 -318
  36. package/dist/internals.js.map +1 -1
  37. package/dist/metadata/index.d.ts +1 -4
  38. package/dist/metadata/index.d.ts.map +1 -1
  39. package/dist/metadata/policy.d.ts +2 -6
  40. package/dist/metadata/policy.d.ts.map +1 -1
  41. package/dist/metadata/resolve.d.ts +3 -2
  42. package/dist/metadata/resolve.d.ts.map +1 -1
  43. package/dist/ui-schema/schema.d.ts +11 -28
  44. package/dist/ui-schema/schema.d.ts.map +1 -1
  45. package/package.json +8 -8
@@ -2522,6 +2522,8 @@ export declare interface SchemaGenerationTarget {
2522
2522
  */
2523
2523
  export declare type SchemaSourceDeclaration = ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration;
2524
2524
 
2525
+ /* Excluded from this release type: SetupDiagnostic */
2526
+
2525
2527
  /**
2526
2528
  * Severity level for constraint violations.
2527
2529
  * - "error": Violation fails validation
@@ -2606,7 +2608,6 @@ export declare interface StaticSchemaGenerationOptions {
2606
2608
  readonly configPath?: string | undefined;
2607
2609
  }
2608
2610
 
2609
- /* Excluded from this release type: SyntheticCompilerDiagnostic */
2610
2611
  export { TextField }
2611
2612
 
2612
2613
  /**
@@ -2490,6 +2490,8 @@ export declare interface SchemaGenerationTarget {
2490
2490
  */
2491
2491
  export declare type SchemaSourceDeclaration = ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration;
2492
2492
 
2493
+ /* Excluded from this release type: SetupDiagnostic */
2494
+
2493
2495
  /**
2494
2496
  * Severity level for constraint violations.
2495
2497
  * - "error": Violation fails validation
@@ -2574,7 +2576,6 @@ export declare interface StaticSchemaGenerationOptions {
2574
2576
  readonly configPath?: string | undefined;
2575
2577
  }
2576
2578
 
2577
- /* Excluded from this release type: SyntheticCompilerDiagnostic */
2578
2579
  export { TextField }
2579
2580
 
2580
2581
  /**
@@ -1043,7 +1043,7 @@ export declare interface ExtensionRegistry {
1043
1043
  *
1044
1044
  * @internal
1045
1045
  */
1046
- readonly setupDiagnostics: readonly SyntheticCompilerDiagnostic[];
1046
+ readonly setupDiagnostics: readonly SetupDiagnostic[];
1047
1047
  /**
1048
1048
  * Look up a custom type registration by its fully-qualified type ID.
1049
1049
  *
@@ -2538,6 +2538,23 @@ export declare interface SchemaGenerationTarget {
2538
2538
  */
2539
2539
  export declare type SchemaSourceDeclaration = ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration;
2540
2540
 
2541
+ /**
2542
+ * Setup-time diagnostic produced by the `_validateExtensionSetup` helper.
2543
+ *
2544
+ * The `kind` field distinguishes between a "setup" failure (invalid type
2545
+ * name, duplicate registration) and an unsupported built-in override.
2546
+ *
2547
+ * @internal
2548
+ */
2549
+ export declare interface SetupDiagnostic {
2550
+ /** The category of diagnostic. */
2551
+ readonly kind: "unsupported-custom-type-override" | "synthetic-setup";
2552
+ /** TypeScript diagnostic code, or -1 for non-TypeScript diagnostics. */
2553
+ readonly code: number;
2554
+ /** Human-readable description of the diagnostic. */
2555
+ readonly message: string;
2556
+ }
2557
+
2541
2558
  /**
2542
2559
  * Severity level for constraint violations.
2543
2560
  * - "error": Violation fails validation
@@ -2622,20 +2639,6 @@ export declare interface StaticSchemaGenerationOptions {
2622
2639
  readonly configPath?: string | undefined;
2623
2640
  }
2624
2641
 
2625
- /**
2626
- * A simplified TypeScript diagnostic surfaced from the synthetic compiler pass.
2627
- *
2628
- * @internal
2629
- */
2630
- export declare interface SyntheticCompilerDiagnostic {
2631
- /** The category of diagnostic: a raw TypeScript error, an unsupported global built-in override, or a synthetic setup failure. */
2632
- readonly kind: "typescript" | "unsupported-custom-type-override" | "synthetic-setup";
2633
- /** TypeScript diagnostic code, or -1 for non-TypeScript diagnostics. */
2634
- readonly code: number;
2635
- /** Human-readable description of the diagnostic. */
2636
- readonly message: string;
2637
- }
2638
-
2639
2642
  export { TextField }
2640
2643
 
2641
2644
  /**
package/dist/build.d.ts CHANGED
@@ -2490,6 +2490,8 @@ export declare interface SchemaGenerationTarget {
2490
2490
  */
2491
2491
  export declare type SchemaSourceDeclaration = ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration;
2492
2492
 
2493
+ /* Excluded from this release type: SetupDiagnostic */
2494
+
2493
2495
  /**
2494
2496
  * Severity level for constraint violations.
2495
2497
  * - "error": Violation fails validation
@@ -2574,7 +2576,6 @@ export declare interface StaticSchemaGenerationOptions {
2574
2576
  readonly configPath?: string | undefined;
2575
2577
  }
2576
2578
 
2577
- /* Excluded from this release type: SyntheticCompilerDiagnostic */
2578
2579
  export { TextField }
2579
2580
 
2580
2581
  /**
@@ -15,8 +15,9 @@ import type { FormIR } from "@formspec/core/internals";
15
15
  * @param form - A form specification created via `formspec(...)` from `@formspec/dsl`
16
16
  * @returns The canonical intermediate representation
17
17
  */
18
- export interface CanonicalizeChainDSLOptions {
18
+ interface CanonicalizeChainDSLOptions {
19
19
  readonly metadata?: MetadataPolicyInput;
20
20
  }
21
21
  export declare function canonicalizeChainDSL(form: FormSpec<readonly FormElement[]>, options?: CanonicalizeChainDSLOptions): FormIR;
22
+ export {};
22
23
  //# sourceMappingURL=chain-dsl-canonicalizer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chain-dsl-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/chain-dsl-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EASV,WAAW,EACX,QAAQ,EAMR,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAYV,MAAM,EAaP,MAAM,0BAA0B,CAAC;AA4ClC;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAoBR"}
1
+ {"version":3,"file":"chain-dsl-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/chain-dsl-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EASV,WAAW,EACX,QAAQ,EAMR,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAYV,MAAM,EAaP,MAAM,0BAA0B,CAAC;AA4ClC;;;;;GAKG;AACH,UAAU,2BAA2B;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAoBR"}
@@ -18,7 +18,7 @@ export interface TSDocSource {
18
18
  /** Absolute path to the source file. */
19
19
  readonly file: string;
20
20
  }
21
- export interface CanonicalizeTSDocOptions {
21
+ interface CanonicalizeTSDocOptions {
22
22
  readonly metadata?: MetadataPolicyInput;
23
23
  }
24
24
  /**
@@ -35,4 +35,5 @@ export interface CanonicalizeTSDocOptions {
35
35
  * @returns The canonical FormIR
36
36
  */
37
37
  export declare function canonicalizeTSDoc(analysis: IRClassAnalysis, source?: TSDocSource, options?: CanonicalizeTSDocOptions): FormIR;
38
+ export {};
38
39
  //# sourceMappingURL=tsdoc-canonicalizer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tsdoc-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/tsdoc-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,+BAA+B,CAAC;AAE1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,MAAM,CA8BR"}
1
+ {"version":3,"file":"tsdoc-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/tsdoc-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,+BAA+B,CAAC;AAE1F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,wBAAwB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,MAAM,CA8BR"}
package/dist/cli.cjs CHANGED
@@ -2178,7 +2178,7 @@ function buildConstraintTagSources(extensions) {
2178
2178
  }));
2179
2179
  }
2180
2180
  function createExtensionRegistry(extensions) {
2181
- const registryLog = (0, import_internal.getSyntheticLogger)();
2181
+ const registryLog = (0, import_internal.getRegistryLogger)();
2182
2182
  registryLog.debug("createExtensionRegistry: constructing", {
2183
2183
  extensionCount: extensions.length,
2184
2184
  extensionIds: extensions.map((e) => e.extensionId)
@@ -2554,151 +2554,34 @@ var init_builtin_brands = __esm({
2554
2554
  });
2555
2555
 
2556
2556
  // src/analyzer/tsdoc-parser.ts
2557
- function sharedTagValueOptions(options) {
2557
+ function sharedTagValueOptions(options, pathResolvedCustomTypeId) {
2558
2558
  return {
2559
2559
  ...options?.extensionRegistry !== void 0 ? { registry: options.extensionRegistry } : {},
2560
- ...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
2560
+ ...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {},
2561
+ ...pathResolvedCustomTypeId !== void 0 ? { pathResolvedCustomTypeId } : {}
2561
2562
  };
2562
2563
  }
2563
- function getExtensionTypeNames(registry) {
2564
- if (registry === void 0) {
2565
- return /* @__PURE__ */ new Set();
2566
- }
2567
- return new Set(
2568
- registry.extensions.flatMap(
2569
- (ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
2570
- )
2571
- );
2564
+ function customTypeIdForResolvedType(resolvedType, checker, registry) {
2565
+ if (registry === void 0) return void 0;
2566
+ const lookup = resolveCustomTypeFromTsType(resolvedType, checker, registry);
2567
+ return lookup === null ? void 0 : customTypeIdFromLookup(lookup);
2572
2568
  }
2573
- function collectImportedNames(sourceFile) {
2574
- const importedNames = /* @__PURE__ */ new Set();
2575
- for (const statement of sourceFile.statements) {
2576
- if (ts3.isImportDeclaration(statement) && statement.importClause !== void 0) {
2577
- const clause = statement.importClause;
2578
- if (clause.name !== void 0) {
2579
- importedNames.add(clause.name.text);
2580
- }
2581
- if (clause.namedBindings !== void 0) {
2582
- if (ts3.isNamedImports(clause.namedBindings)) {
2583
- for (const specifier of clause.namedBindings.elements) {
2584
- importedNames.add(specifier.name.text);
2585
- }
2586
- } else if (ts3.isNamespaceImport(clause.namedBindings)) {
2587
- importedNames.add(clause.namedBindings.name.text);
2588
- }
2589
- }
2590
- continue;
2591
- }
2592
- if (ts3.isImportEqualsDeclaration(statement)) {
2593
- importedNames.add(statement.name.text);
2594
- }
2595
- }
2596
- return importedNames;
2597
- }
2598
- function isNonReferenceIdentifier(node) {
2599
- const parent = node.parent;
2600
- if ((ts3.isBindingElement(parent) || ts3.isClassDeclaration(parent) || ts3.isEnumDeclaration(parent) || ts3.isEnumMember(parent) || ts3.isFunctionDeclaration(parent) || ts3.isFunctionExpression(parent) || ts3.isImportClause(parent) || ts3.isImportEqualsDeclaration(parent) || ts3.isImportSpecifier(parent) || ts3.isInterfaceDeclaration(parent) || ts3.isMethodDeclaration(parent) || ts3.isMethodSignature(parent) || ts3.isModuleDeclaration(parent) || ts3.isNamespaceExport(parent) || ts3.isNamespaceImport(parent) || ts3.isParameter(parent) || ts3.isPropertyDeclaration(parent) || ts3.isPropertySignature(parent) || ts3.isSetAccessorDeclaration(parent) || ts3.isGetAccessorDeclaration(parent) || ts3.isTypeAliasDeclaration(parent) || ts3.isTypeParameterDeclaration(parent) || ts3.isVariableDeclaration(parent)) && parent.name === node) {
2601
- return true;
2602
- }
2603
- if ((ts3.isPropertyAssignment(parent) || ts3.isPropertyAccessExpression(parent)) && parent.name === node) {
2604
- return true;
2605
- }
2606
- if (ts3.isQualifiedName(parent) && parent.right === node) {
2607
- return true;
2608
- }
2609
- return false;
2610
- }
2611
- function astReferencesImportedName(root, importedNames) {
2612
- if (importedNames.size === 0) {
2613
- return false;
2614
- }
2615
- let found = false;
2616
- const visit = (node) => {
2617
- if (found) return;
2618
- if (ts3.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2619
- found = true;
2620
- return;
2621
- }
2622
- ts3.forEachChild(node, visit);
2623
- };
2624
- visit(root);
2625
- return found;
2626
- }
2627
- function getObjectMembers(statement) {
2628
- if (ts3.isInterfaceDeclaration(statement)) {
2629
- return statement.members;
2630
- }
2631
- if (ts3.isTypeLiteralNode(statement.type)) {
2632
- return statement.type.members;
2633
- }
2634
- return void 0;
2635
- }
2636
- function rewriteImportedMemberTypes(statement, sourceFile, importedNames) {
2637
- const members = getObjectMembers(statement);
2638
- if (members === void 0) {
2639
- return null;
2640
- }
2641
- const replacements = [];
2642
- for (const member of members) {
2643
- if (!ts3.isPropertySignature(member)) {
2644
- if (astReferencesImportedName(member, importedNames)) {
2645
- return null;
2646
- }
2647
- continue;
2648
- }
2649
- const typeAnnotation = member.type;
2650
- if (typeAnnotation === void 0) continue;
2651
- if (astReferencesImportedName(typeAnnotation, importedNames)) {
2652
- replacements.push({
2653
- start: typeAnnotation.getStart(sourceFile),
2654
- end: typeAnnotation.getEnd()
2655
- });
2656
- }
2657
- }
2658
- if (replacements.length === 0) {
2659
- return statement.getText(sourceFile);
2660
- }
2661
- const stmtStart = statement.getStart(sourceFile);
2662
- let result = statement.getText(sourceFile);
2663
- for (const { start, end } of [...replacements].reverse()) {
2664
- result = result.slice(0, start - stmtStart) + "unknown" + result.slice(end - stmtStart);
2569
+ function resolvePathTargetCustomTypeId(parsedTag, subjectType, checker, registry) {
2570
+ if (parsedTag === null) return void 0;
2571
+ const target = parsedTag.target;
2572
+ if (target?.kind !== "path" || !target.valid || target.path === null) {
2573
+ return void 0;
2665
2574
  }
2666
- return result;
2667
- }
2668
- function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2669
- const importedNames = collectImportedNames(sourceFile);
2670
- const importedNamesToSkip = new Set(
2671
- [...importedNames].filter((name) => !extensionTypeNames.has(name))
2672
- );
2673
- const result = [];
2674
- for (const statement of sourceFile.statements) {
2675
- if (ts3.isImportDeclaration(statement)) continue;
2676
- if (ts3.isImportEqualsDeclaration(statement)) continue;
2677
- if (ts3.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
2678
- if (!astReferencesImportedName(statement, importedNamesToSkip)) {
2679
- result.push(statement.getText(sourceFile));
2680
- continue;
2681
- }
2682
- if (ts3.isInterfaceDeclaration(statement) || ts3.isTypeAliasDeclaration(statement)) {
2683
- const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
2684
- if (rewritten !== null) {
2685
- result.push(rewritten);
2686
- }
2687
- }
2575
+ if (subjectType === void 0 || checker === void 0) {
2576
+ return void 0;
2688
2577
  }
2689
- return result;
2690
- }
2691
- function pushUniqueCompilerDiagnostics(target, additions) {
2692
- for (const diagnostic of additions) {
2693
- if ((diagnostic.code === "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" || diagnostic.code === "SYNTHETIC_SETUP_FAILURE") && target.some(
2694
- (existing) => existing.code === diagnostic.code && existing.message === diagnostic.message
2695
- )) {
2696
- continue;
2697
- }
2698
- target.push(diagnostic);
2578
+ const resolution = (0, import_internal4.resolvePathTargetType)(subjectType, checker, target.path.segments);
2579
+ if (resolution.kind !== "resolved") {
2580
+ return void 0;
2699
2581
  }
2582
+ return customTypeIdForResolvedType(resolution.type, checker, registry);
2700
2583
  }
2701
- function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, supportingDeclarations, options, constraints, diagnostics) {
2584
+ function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, options, constraints, diagnostics) {
2702
2585
  const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2703
2586
  node,
2704
2587
  sourceFile,
@@ -2706,74 +2589,30 @@ function processConstraintTag(tagName, text, parsedTag, provenance, node, source
2706
2589
  parsedTag,
2707
2590
  text,
2708
2591
  provenance,
2709
- supportingDeclarations,
2710
2592
  options
2711
2593
  );
2712
2594
  if (compilerDiagnostics.length > 0) {
2713
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2595
+ diagnostics.push(...compilerDiagnostics);
2714
2596
  return;
2715
2597
  }
2598
+ const pathResolvedCustomTypeId = resolvePathTargetCustomTypeId(
2599
+ parsedTag,
2600
+ options?.subjectType,
2601
+ options?.checker,
2602
+ options?.extensionRegistry
2603
+ );
2716
2604
  const constraintNode = (0, import_internal4.parseConstraintTagValue)(
2717
2605
  tagName,
2718
2606
  text,
2719
2607
  provenance,
2720
- sharedTagValueOptions(options)
2608
+ sharedTagValueOptions(options, pathResolvedCustomTypeId)
2721
2609
  );
2722
2610
  if (constraintNode) {
2723
2611
  constraints.push(constraintNode);
2724
2612
  }
2725
2613
  }
2726
- function renderSyntheticArgumentExpression(valueKind, argumentText) {
2727
- const trimmed = argumentText.trim();
2728
- if (trimmed === "") {
2729
- return null;
2730
- }
2731
- switch (valueKind) {
2732
- case "number":
2733
- case "integer":
2734
- case "signedInteger":
2735
- if (trimmed === "Infinity" || trimmed === "-Infinity" || trimmed === "NaN") {
2736
- return trimmed;
2737
- }
2738
- return Number.isFinite(Number(trimmed)) ? trimmed : JSON.stringify(trimmed);
2739
- case "string":
2740
- return JSON.stringify(argumentText);
2741
- case "json":
2742
- try {
2743
- JSON.parse(trimmed);
2744
- return `(${trimmed})`;
2745
- } catch {
2746
- return JSON.stringify(trimmed);
2747
- }
2748
- case "boolean":
2749
- return trimmed === "true" || trimmed === "false" ? trimmed : JSON.stringify(trimmed);
2750
- case "condition":
2751
- return "undefined as unknown as FormSpecCondition";
2752
- case null:
2753
- return null;
2754
- default: {
2755
- return String(valueKind);
2756
- }
2757
- }
2758
- }
2759
- function getArrayElementType(type, checker) {
2760
- if (!checker.isArrayType(type)) {
2761
- return null;
2762
- }
2763
- return checker.getTypeArguments(type)[0] ?? null;
2764
- }
2765
2614
  function supportsConstraintCapability(type, checker, capability) {
2766
- if (capability === void 0) {
2767
- return true;
2768
- }
2769
- if ((0, import_internal4.hasTypeSemanticCapability)(type, checker, capability)) {
2770
- return true;
2771
- }
2772
- if (capability === "string-like") {
2773
- const itemType = getArrayElementType(type, checker);
2774
- return itemType !== null && (0, import_internal4.hasTypeSemanticCapability)(itemType, checker, capability);
2775
- }
2776
- return false;
2615
+ return (0, import_internal4._supportsConstraintCapability)(capability, type, checker);
2777
2616
  }
2778
2617
  function stripHintNullishUnion(type) {
2779
2618
  if (!type.isUnion()) {
@@ -2898,53 +2737,11 @@ function placementLabel(placement) {
2898
2737
  }
2899
2738
  }
2900
2739
  }
2901
- function capabilityLabel(capability) {
2902
- switch (capability) {
2903
- case "numeric-comparable":
2904
- return "number";
2905
- case "string-like":
2906
- return "string";
2907
- case "array-like":
2908
- return "array";
2909
- case "enum-member-addressable":
2910
- return "enum";
2911
- case "json-like":
2912
- return "JSON-compatible";
2913
- case "object-like":
2914
- return "object";
2915
- case "condition-like":
2916
- return "conditional";
2917
- case void 0:
2918
- return "compatible";
2919
- default:
2920
- return capability;
2921
- }
2922
- }
2923
- function getBroadenedCustomTypeId(fieldType) {
2924
- if (fieldType?.kind === "custom") {
2925
- return fieldType.typeId;
2926
- }
2927
- if (fieldType?.kind !== "union") {
2928
- return void 0;
2929
- }
2930
- const customMembers = fieldType.members.filter(
2931
- (member) => member.kind === "custom"
2932
- );
2933
- if (customMembers.length !== 1) {
2934
- return void 0;
2935
- }
2936
- const nonCustomMembers = fieldType.members.filter((member) => member.kind !== "custom");
2937
- const allOtherMembersAreNull = nonCustomMembers.every(
2938
- (member) => member.kind === "primitive" && member.primitiveKind === "null"
2939
- );
2940
- const customMember = customMembers[0];
2941
- return allOtherMembersAreNull && customMember !== void 0 ? customMember.typeId : void 0;
2942
- }
2943
2740
  function hasBuiltinConstraintBroadening(tagName, options) {
2944
- const broadenedTypeId = getBroadenedCustomTypeId(options?.fieldType);
2741
+ const broadenedTypeId = (0, import_internal4.getBroadenedCustomTypeId)(options?.fieldType);
2945
2742
  return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
2946
2743
  }
2947
- function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, supportingDeclarations, options) {
2744
+ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, rawText, provenance, options) {
2948
2745
  if (!(0, import_internals4.isBuiltinConstraintName)(tagName)) {
2949
2746
  return [];
2950
2747
  }
@@ -2964,16 +2761,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2964
2761
  const nonNullPlacement = placement;
2965
2762
  const log2 = (0, import_internal5.getBuildLogger)();
2966
2763
  const broadeningLog = (0, import_internal5.getBroadeningLogger)();
2967
- const syntheticLog = (0, import_internal5.getSyntheticLogger)();
2968
2764
  const typedParserLog = (0, import_internal5.getTypedParserLogger)();
2969
2765
  const logsEnabled = log2 !== import_core4.noopLogger || broadeningLog !== import_core4.noopLogger;
2970
- const syntheticTraceEnabled = syntheticLog !== import_core4.noopLogger;
2971
2766
  const typedParserTraceEnabled = typedParserLog !== import_core4.noopLogger;
2972
2767
  const logStart = logsEnabled ? (0, import_internal5.nowMicros)() : 0;
2973
2768
  const subjectTypeKind = logsEnabled ? (0, import_internal5.describeTypeKind)(subjectType, checker) : "";
2974
- function emit(outcome, result2) {
2769
+ function emit(outcome, result) {
2975
2770
  if (!logsEnabled) {
2976
- return result2;
2771
+ return result;
2977
2772
  }
2978
2773
  const entry = {
2979
2774
  consumer: "build",
@@ -2987,7 +2782,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2987
2782
  if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
2988
2783
  (0, import_internal5.logTagApplication)(broadeningLog, entry);
2989
2784
  }
2990
- return result2;
2785
+ return result;
2991
2786
  }
2992
2787
  if (!definition.placements.includes(placement)) {
2993
2788
  return emit("A-reject", [
@@ -3031,7 +2826,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
3031
2826
  ]);
3032
2827
  }
3033
2828
  if (resolution.kind === "unresolvable") {
3034
- const actualType = checker.typeToString(resolution.type, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2829
+ const actualType = checker.typeToString(resolution.type, node, TYPE_FORMAT_FLAGS);
3035
2830
  return emit("B-reject", [
3036
2831
  makeDiagnostic(
3037
2832
  "TYPE_MISMATCH",
@@ -3045,21 +2840,21 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
3045
2840
  }
3046
2841
  const hasBroadening = (() => {
3047
2842
  if (target === null) {
3048
- if ((0, import_internal3._isIntegerBrandedType)((0, import_internal4.stripNullishUnion)(subjectType)) && definition.capabilities.includes("numeric-comparable")) {
2843
+ if ((0, import_internal3._isIntegerBrandedType)((0, import_internal4.stripNullishUnion)(subjectType)) && definition.capabilities[0] === "numeric-comparable") {
3049
2844
  return true;
3050
2845
  }
3051
2846
  return hasBuiltinConstraintBroadening(tagName, options);
3052
2847
  }
3053
2848
  const registry = options?.extensionRegistry;
3054
2849
  if (registry === void 0) return false;
3055
- const resolved = resolveCustomTypeFromTsType(evaluatedType, checker, registry);
3056
- return resolved !== null && registry.findBuiltinConstraintBroadening(customTypeIdFromLookup(resolved), tagName) !== void 0;
2850
+ const typeId = customTypeIdForResolvedType(evaluatedType, checker, registry);
2851
+ return typeId !== void 0 && registry.findBuiltinConstraintBroadening(typeId, tagName) !== void 0;
3057
2852
  })();
3058
2853
  if (!hasBroadening) {
3059
2854
  const requiredCapability = definition.capabilities[0];
3060
2855
  if (requiredCapability !== void 0 && !supportsConstraintCapability(evaluatedType, checker, requiredCapability)) {
3061
- const actualType = checker.typeToString(evaluatedType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
3062
- const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${capabilityLabel(requiredCapability)} targets, but field type is "${actualType}"`;
2856
+ const actualType = checker.typeToString(evaluatedType, node, TYPE_FORMAT_FLAGS);
2857
+ const baseMessage = `Target "${targetLabel}": constraint "${tagName}" is only valid on ${(0, import_internal4._capabilityLabel)(requiredCapability)} targets, but field type is "${actualType}"`;
3063
2858
  const hint = target === null ? buildPathTargetHint(
3064
2859
  subjectType,
3065
2860
  checker,
@@ -3107,68 +2902,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
3107
2902
  valueKind: typedParseResult.value.kind
3108
2903
  });
3109
2904
  }
3110
- const argumentExpression = renderSyntheticArgumentExpression(
3111
- definition.valueKind,
3112
- effectiveArgumentText
3113
- );
3114
- const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
3115
- const hostType = options?.hostType ?? subjectType;
3116
- const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
3117
- if (syntheticTraceEnabled) {
3118
- syntheticLog.trace("invoking synthetic checker", {
3119
- consumer: "build",
3120
- tag: tagName,
3121
- placement,
3122
- subjectTypeKind,
3123
- subjectTypeText
3124
- });
3125
- }
3126
- const result = (0, import_internal4.checkSyntheticTagApplication)({
3127
- tagName,
3128
- placement,
3129
- hostType: hostTypeText,
3130
- subjectType: subjectTypeText,
3131
- ...target?.kind === "path" ? { target: { kind: "path", text: target.rawText } } : {},
3132
- ...argumentExpression !== null ? { argumentExpression } : {},
3133
- supportingDeclarations,
3134
- ...options?.extensionRegistry !== void 0 ? {
3135
- extensions: options.extensionRegistry.extensions.map((extension) => ({
3136
- extensionId: extension.extensionId,
3137
- ...extension.constraintTags !== void 0 ? {
3138
- constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
3139
- } : {},
3140
- ...extension.metadataSlots !== void 0 ? {
3141
- metadataSlots: extension.metadataSlots
3142
- } : {},
3143
- ...extension.types !== void 0 ? {
3144
- customTypes: extension.types.map((t) => ({
3145
- tsTypeNames: t.tsTypeNames ?? [t.typeName]
3146
- }))
3147
- } : {}
3148
- }))
3149
- } : {}
3150
- });
3151
- if (result.diagnostics.length === 0) {
3152
- return emit("D-pass", []);
3153
- }
3154
- const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
3155
- if (setupDiagnostic !== void 0) {
3156
- return emit("C-reject", [
3157
- makeDiagnostic(
3158
- (0, import_internal5._mapSetupDiagnosticCode)(setupDiagnostic.kind),
3159
- setupDiagnostic.message,
3160
- provenance
3161
- )
3162
- ]);
3163
- }
3164
- const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
3165
- return emit("C-reject", [
3166
- makeDiagnostic(
3167
- "TYPE_MISMATCH",
3168
- `Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
3169
- provenance
3170
- )
3171
- ]);
2905
+ return emit("C-pass", []);
3172
2906
  }
3173
2907
  function getExtensionTagNames(options) {
3174
2908
  return [
@@ -3211,8 +2945,8 @@ function getParseCacheKey(node, file, options) {
3211
2945
  start: node.getFullStart(),
3212
2946
  end: node.getEnd(),
3213
2947
  fieldType: options?.fieldType ?? null,
3214
- subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS) : null,
3215
- hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS) : null,
2948
+ subjectType: checker !== void 0 && options?.subjectType !== void 0 ? checker.typeToString(options.subjectType, node, TYPE_FORMAT_FLAGS) : null,
2949
+ hostType: checker !== void 0 && options?.hostType !== void 0 ? checker.typeToString(options.hostType, node, TYPE_FORMAT_FLAGS) : null,
3216
2950
  extensions: getExtensionRegistryCacheKey(options?.extensionRegistry)
3217
2951
  });
3218
2952
  }
@@ -3241,8 +2975,6 @@ function parseTSDocTags(node, file = "", options) {
3241
2975
  let placeholderProvenance;
3242
2976
  const sourceFile = node.getSourceFile();
3243
2977
  const sourceText = sourceFile.getFullText();
3244
- const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
3245
- const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
3246
2978
  const commentRanges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
3247
2979
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
3248
2980
  const extensionTagNames = getExtensionTagNames(options);
@@ -3307,7 +3039,6 @@ function parseTSDocTags(node, file = "", options) {
3307
3039
  provenance2,
3308
3040
  node,
3309
3041
  sourceFile,
3310
- supportingDeclarations,
3311
3042
  options,
3312
3043
  constraints,
3313
3044
  diagnostics
@@ -3325,7 +3056,6 @@ function parseTSDocTags(node, file = "", options) {
3325
3056
  provenance,
3326
3057
  node,
3327
3058
  sourceFile,
3328
- supportingDeclarations,
3329
3059
  options,
3330
3060
  constraints,
3331
3061
  diagnostics
@@ -3389,7 +3119,6 @@ function parseTSDocTags(node, file = "", options) {
3389
3119
  provenance,
3390
3120
  node,
3391
3121
  sourceFile,
3392
- supportingDeclarations,
3393
3122
  options,
3394
3123
  constraints,
3395
3124
  diagnostics
@@ -3490,7 +3219,7 @@ function getTagCommentText(tag) {
3490
3219
  }
3491
3220
  return ts3.getTextOfJSDocComment(tag.comment);
3492
3221
  }
3493
- var ts3, import_internal4, import_internals4, import_internals5, import_core4, import_internal5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3222
+ var ts3, import_internal4, import_internals4, import_internals5, import_core4, import_internal5, TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3494
3223
  var init_tsdoc_parser = __esm({
3495
3224
  "src/analyzer/tsdoc-parser.ts"() {
3496
3225
  "use strict";
@@ -3502,7 +3231,7 @@ var init_tsdoc_parser = __esm({
3502
3231
  init_resolve_custom_type();
3503
3232
  init_builtin_brands();
3504
3233
  import_internal5 = require("@formspec/analysis/internal");
3505
- SYNTHETIC_TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3234
+ TYPE_FORMAT_FLAGS = ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3506
3235
  MAX_HINT_CANDIDATES = 5;
3507
3236
  MAX_HINT_DEPTH = 3;
3508
3237
  parseResultCache = /* @__PURE__ */ new Map();