@formspec/build 0.1.0-alpha.11 → 0.1.0-alpha.13

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 (135) hide show
  1. package/README.md +51 -15
  2. package/dist/__tests__/chain-dsl-canonicalizer.test.d.ts +2 -0
  3. package/dist/__tests__/chain-dsl-canonicalizer.test.d.ts.map +1 -0
  4. package/dist/__tests__/constraint-validator.test.d.ts +2 -0
  5. package/dist/__tests__/constraint-validator.test.d.ts.map +1 -0
  6. package/dist/__tests__/extension-api.test.d.ts +2 -0
  7. package/dist/__tests__/extension-api.test.d.ts.map +1 -0
  8. package/dist/__tests__/fixtures/example-a-builtins.d.ts +18 -0
  9. package/dist/__tests__/fixtures/example-a-builtins.d.ts.map +1 -1
  10. package/dist/__tests__/guards.test.d.ts +2 -0
  11. package/dist/__tests__/guards.test.d.ts.map +1 -0
  12. package/dist/__tests__/ir-analyzer.test.d.ts +11 -0
  13. package/dist/__tests__/ir-analyzer.test.d.ts.map +1 -0
  14. package/dist/__tests__/ir-jsdoc-constraints.test.d.ts +12 -0
  15. package/dist/__tests__/ir-jsdoc-constraints.test.d.ts.map +1 -0
  16. package/dist/__tests__/ir-json-schema-generator.test.d.ts +11 -0
  17. package/dist/__tests__/ir-json-schema-generator.test.d.ts.map +1 -0
  18. package/dist/__tests__/ir-ui-schema-generator.test.d.ts +2 -0
  19. package/dist/__tests__/ir-ui-schema-generator.test.d.ts.map +1 -0
  20. package/dist/__tests__/jsdoc-constraints.test.d.ts +4 -4
  21. package/dist/__tests__/parity/fixtures/address/chain-dsl.d.ts +9 -0
  22. package/dist/__tests__/parity/fixtures/address/chain-dsl.d.ts.map +1 -0
  23. package/dist/__tests__/parity/fixtures/address/expected-ir.d.ts +9 -0
  24. package/dist/__tests__/parity/fixtures/address/expected-ir.d.ts.map +1 -0
  25. package/dist/__tests__/parity/fixtures/address/tsdoc.d.ts +19 -0
  26. package/dist/__tests__/parity/fixtures/address/tsdoc.d.ts.map +1 -0
  27. package/dist/__tests__/parity/fixtures/product-config/chain-dsl.d.ts +13 -0
  28. package/dist/__tests__/parity/fixtures/product-config/chain-dsl.d.ts.map +1 -0
  29. package/dist/__tests__/parity/fixtures/product-config/expected-ir.d.ts +9 -0
  30. package/dist/__tests__/parity/fixtures/product-config/expected-ir.d.ts.map +1 -0
  31. package/dist/__tests__/parity/fixtures/product-config/tsdoc.d.ts +28 -0
  32. package/dist/__tests__/parity/fixtures/product-config/tsdoc.d.ts.map +1 -0
  33. package/dist/__tests__/parity/fixtures/user-registration/chain-dsl.d.ts +12 -0
  34. package/dist/__tests__/parity/fixtures/user-registration/chain-dsl.d.ts.map +1 -0
  35. package/dist/__tests__/parity/fixtures/user-registration/expected-ir.d.ts +9 -0
  36. package/dist/__tests__/parity/fixtures/user-registration/expected-ir.d.ts.map +1 -0
  37. package/dist/__tests__/parity/fixtures/user-registration/tsdoc.d.ts +19 -0
  38. package/dist/__tests__/parity/fixtures/user-registration/tsdoc.d.ts.map +1 -0
  39. package/dist/__tests__/parity/parity.test.d.ts +14 -0
  40. package/dist/__tests__/parity/parity.test.d.ts.map +1 -0
  41. package/dist/__tests__/parity/utils.d.ts +139 -0
  42. package/dist/__tests__/parity/utils.d.ts.map +1 -0
  43. package/dist/analyzer/class-analyzer.d.ts +54 -99
  44. package/dist/analyzer/class-analyzer.d.ts.map +1 -1
  45. package/dist/analyzer/jsdoc-constraints.d.ts +78 -30
  46. package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
  47. package/dist/analyzer/tsdoc-parser.d.ts +61 -0
  48. package/dist/analyzer/tsdoc-parser.d.ts.map +1 -0
  49. package/dist/browser.cjs +998 -309
  50. package/dist/browser.cjs.map +1 -1
  51. package/dist/browser.d.ts +10 -6
  52. package/dist/browser.d.ts.map +1 -1
  53. package/dist/browser.js +996 -308
  54. package/dist/browser.js.map +1 -1
  55. package/dist/build.d.ts +65 -150
  56. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +18 -0
  57. package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -0
  58. package/dist/canonicalize/index.d.ts +8 -0
  59. package/dist/canonicalize/index.d.ts.map +1 -0
  60. package/dist/canonicalize/tsdoc-canonicalizer.d.ts +34 -0
  61. package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -0
  62. package/dist/cli.cjs +1455 -1656
  63. package/dist/cli.cjs.map +1 -1
  64. package/dist/cli.js +1459 -1647
  65. package/dist/cli.js.map +1 -1
  66. package/dist/extensions/index.d.ts +8 -0
  67. package/dist/extensions/index.d.ts.map +1 -0
  68. package/dist/extensions/registry.d.ts +55 -0
  69. package/dist/extensions/registry.d.ts.map +1 -0
  70. package/dist/generators/class-schema.d.ts +23 -38
  71. package/dist/generators/class-schema.d.ts.map +1 -1
  72. package/dist/generators/method-schema.d.ts +6 -8
  73. package/dist/generators/method-schema.d.ts.map +1 -1
  74. package/dist/index.cjs +1391 -1614
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.ts +6 -8
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +1403 -1610
  79. package/dist/index.js.map +1 -1
  80. package/dist/internals.cjs +1642 -824
  81. package/dist/internals.cjs.map +1 -1
  82. package/dist/internals.d.ts +12 -3
  83. package/dist/internals.d.ts.map +1 -1
  84. package/dist/internals.js +1645 -820
  85. package/dist/internals.js.map +1 -1
  86. package/dist/json-schema/generator.d.ts +10 -5
  87. package/dist/json-schema/generator.d.ts.map +1 -1
  88. package/dist/json-schema/ir-generator.d.ts +84 -0
  89. package/dist/json-schema/ir-generator.d.ts.map +1 -0
  90. package/dist/json-schema/schema.d.ts +3 -3
  91. package/dist/json-schema/types.d.ts +5 -6
  92. package/dist/json-schema/types.d.ts.map +1 -1
  93. package/dist/ui-schema/generator.d.ts +5 -15
  94. package/dist/ui-schema/generator.d.ts.map +1 -1
  95. package/dist/ui-schema/ir-generator.d.ts +53 -0
  96. package/dist/ui-schema/ir-generator.d.ts.map +1 -0
  97. package/dist/validate/constraint-validator.d.ts +66 -0
  98. package/dist/validate/constraint-validator.d.ts.map +1 -0
  99. package/dist/validate/index.d.ts +9 -0
  100. package/dist/validate/index.d.ts.map +1 -0
  101. package/package.json +5 -4
  102. package/dist/__tests__/analyzer-edge-cases.test.d.ts +0 -13
  103. package/dist/__tests__/analyzer-edge-cases.test.d.ts.map +0 -1
  104. package/dist/__tests__/analyzer.test.d.ts +0 -5
  105. package/dist/__tests__/analyzer.test.d.ts.map +0 -1
  106. package/dist/__tests__/codegen.test.d.ts +0 -5
  107. package/dist/__tests__/codegen.test.d.ts.map +0 -1
  108. package/dist/__tests__/decorator-pipeline.test.d.ts +0 -11
  109. package/dist/__tests__/decorator-pipeline.test.d.ts.map +0 -1
  110. package/dist/__tests__/fixtures/example-b-decorators.d.ts +0 -5
  111. package/dist/__tests__/fixtures/example-b-decorators.d.ts.map +0 -1
  112. package/dist/__tests__/fixtures/example-b-extended.d.ts +0 -5
  113. package/dist/__tests__/fixtures/example-b-extended.d.ts.map +0 -1
  114. package/dist/__tests__/fixtures/example-c-custom.d.ts +0 -5
  115. package/dist/__tests__/fixtures/example-c-custom.d.ts.map +0 -1
  116. package/dist/__tests__/fixtures/example-c-decorators.d.ts +0 -5
  117. package/dist/__tests__/fixtures/example-c-decorators.d.ts.map +0 -1
  118. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts +0 -6
  119. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts.map +0 -1
  120. package/dist/__tests__/fixtures/example-e-decorators.d.ts +0 -11
  121. package/dist/__tests__/fixtures/example-e-decorators.d.ts.map +0 -1
  122. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts +0 -5
  123. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts.map +0 -1
  124. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts +0 -16
  125. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts.map +0 -1
  126. package/dist/__tests__/fixtures/example-nested-class.d.ts +0 -45
  127. package/dist/__tests__/fixtures/example-nested-class.d.ts.map +0 -1
  128. package/dist/__tests__/interface-types.test.d.ts +0 -11
  129. package/dist/__tests__/interface-types.test.d.ts.map +0 -1
  130. package/dist/analyzer/decorator-extractor.d.ts +0 -78
  131. package/dist/analyzer/decorator-extractor.d.ts.map +0 -1
  132. package/dist/analyzer/type-converter.d.ts +0 -75
  133. package/dist/analyzer/type-converter.d.ts.map +0 -1
  134. package/dist/codegen/index.d.ts +0 -75
  135. package/dist/codegen/index.d.ts.map +0 -1
@@ -1,47 +1,68 @@
1
1
  /**
2
- * Class analyzer for extracting fields, types, and decorators.
2
+ * Class analyzer for extracting fields, types, and JSDoc constraints.
3
3
  *
4
- * Analyzes a TypeScript class declaration to extract:
5
- * - Field names and TypeScript types
6
- * - Decorator metadata (Field, Minimum, Maximum, etc.)
7
- * - Field optionality
8
- * - TSDoc @deprecated tags
9
- * - Default values from property initializers
4
+ * Produces `IRClassAnalysis` containing `FieldNode[]` and `typeRegistry`
5
+ * directly from class, interface, or type alias declarations.
6
+ * All downstream generation routes through the canonical FormIR.
10
7
  */
11
8
  import * as ts from "typescript";
12
- import { type DecoratorInfo } from "./decorator-extractor.js";
9
+ import type { FieldNode, TypeNode, TypeDefinition, JsonValue } from "@formspec/core";
13
10
  /**
14
- * Analyzed field information from a class.
11
+ * Layout metadata extracted from `@Group` and `@ShowWhen` decorators.
12
+ * One entry per field, in the same order as `fields`.
15
13
  */
16
- export interface FieldInfo {
17
- /** Field name */
18
- name: string;
19
- /** TypeScript type node for the field */
20
- typeNode: ts.TypeNode | undefined;
21
- /** Resolved type from the type checker */
22
- type: ts.Type;
23
- /** Whether the field is optional (has ? modifier) */
24
- optional: boolean;
25
- /** Decorators applied to the field */
26
- decorators: DecoratorInfo[];
27
- /** Whether the field has a TSDoc @deprecated tag */
28
- deprecated: boolean;
29
- /** Default value extracted from the property initializer (literal values only) */
30
- defaultValue: unknown;
14
+ export interface FieldLayoutMetadata {
15
+ /** Group label from `@Group("label")`, or undefined if ungrouped. */
16
+ readonly groupLabel?: string;
17
+ /** ShowWhen condition from `@ShowWhen({ field, value })`, or undefined if always visible. */
18
+ readonly showWhen?: {
19
+ readonly field: string;
20
+ readonly value: JsonValue;
21
+ };
31
22
  }
32
23
  /**
33
- * Result of analyzing a class declaration.
24
+ * Result of analyzing a class/interface/type alias into canonical IR.
34
25
  */
35
- export interface ClassAnalysis {
36
- /** Class name */
37
- name: string;
38
- /** Analyzed fields */
39
- fields: FieldInfo[];
40
- /** Instance methods */
41
- instanceMethods: MethodInfo[];
26
+ export interface IRClassAnalysis {
27
+ /** Type name */
28
+ readonly name: string;
29
+ /** Analyzed fields as canonical IR FieldNodes */
30
+ readonly fields: readonly FieldNode[];
31
+ /** Layout metadata per field (same order/length as `fields`). */
32
+ readonly fieldLayouts: readonly FieldLayoutMetadata[];
33
+ /** Named type definitions referenced by fields */
34
+ readonly typeRegistry: Record<string, TypeDefinition>;
35
+ /** Instance methods (retained for downstream method-schema generation) */
36
+ readonly instanceMethods: readonly MethodInfo[];
42
37
  /** Static methods */
43
- staticMethods: MethodInfo[];
38
+ readonly staticMethods: readonly MethodInfo[];
44
39
  }
40
+ /**
41
+ * Result of analyzing a type alias into IR — either success or error.
42
+ */
43
+ export type AnalyzeTypeAliasToIRResult = {
44
+ readonly ok: true;
45
+ readonly analysis: IRClassAnalysis;
46
+ } | {
47
+ readonly ok: false;
48
+ readonly error: string;
49
+ };
50
+ /**
51
+ * Analyzes a class declaration and produces canonical IR FieldNodes.
52
+ */
53
+ export declare function analyzeClassToIR(classDecl: ts.ClassDeclaration, checker: ts.TypeChecker, file?: string): IRClassAnalysis;
54
+ /**
55
+ * Analyzes an interface declaration and produces canonical IR FieldNodes.
56
+ */
57
+ export declare function analyzeInterfaceToIR(interfaceDecl: ts.InterfaceDeclaration, checker: ts.TypeChecker, file?: string): IRClassAnalysis;
58
+ /**
59
+ * Analyzes a type alias declaration and produces canonical IR FieldNodes.
60
+ */
61
+ export declare function analyzeTypeAliasToIR(typeAlias: ts.TypeAliasDeclaration, checker: ts.TypeChecker, file?: string): AnalyzeTypeAliasToIRResult;
62
+ /**
63
+ * Resolves a TypeScript type to a canonical IR TypeNode.
64
+ */
65
+ export declare function resolveTypeNode(type: ts.Type, checker: ts.TypeChecker, file: string, typeRegistry: Record<string, TypeDefinition>, visiting: Set<ts.Type>): TypeNode;
45
66
  /**
46
67
  * Analyzed method information.
47
68
  */
@@ -70,70 +91,4 @@ export interface ParameterInfo {
70
91
  /** Whether the parameter is optional (has ? or default value) */
71
92
  optional: boolean;
72
93
  }
73
- /**
74
- * Analyzes a class declaration to extract fields and methods.
75
- *
76
- * @param classDecl - The class declaration to analyze
77
- * @param checker - TypeScript type checker
78
- * @returns Analysis result with fields and methods
79
- */
80
- export declare function analyzeClass(classDecl: ts.ClassDeclaration, checker: ts.TypeChecker): ClassAnalysis;
81
- /**
82
- * Analyzes a property declaration to extract field info.
83
- */
84
- export declare function analyzeField(prop: ts.PropertyDeclaration, checker: ts.TypeChecker): FieldInfo | null;
85
- /**
86
- * Analyzes an interface declaration to extract field information.
87
- *
88
- * Similar to {@link analyzeClass} but for interface declarations.
89
- * Extracts JSDoc constraint tags (`@Minimum`, `@MaxLength`, etc.) and
90
- * display metadata (`@Field_displayName`, `@Field_description`) from
91
- * property signatures, producing the same {@link ClassAnalysis}
92
- * structure for downstream schema generation.
93
- *
94
- * @param interfaceDecl - The interface declaration to analyze
95
- * @param checker - TypeScript type checker
96
- * @returns Analysis result with fields (no methods — interfaces have no implementations)
97
- */
98
- export declare function analyzeInterface(interfaceDecl: ts.InterfaceDeclaration, checker: ts.TypeChecker): ClassAnalysis;
99
- /**
100
- * Result of analyzing a type alias — either a successful analysis or
101
- * an error describing why the alias can't be analyzed.
102
- */
103
- export type AnalyzeTypeAliasResult = {
104
- ok: true;
105
- analysis: ClassAnalysis;
106
- } | {
107
- ok: false;
108
- error: string;
109
- };
110
- /**
111
- * Analyzes a type alias declaration to extract field information.
112
- *
113
- * Supports type aliases whose body is a type literal (object type):
114
- *
115
- * ```typescript
116
- * type Config = {
117
- * // @Field_displayName Name @Minimum 1
118
- * name: string;
119
- * };
120
- * ```
121
- *
122
- * Returns an error result (not an exception) for non-object-literal aliases,
123
- * allowing callers to accumulate diagnostics across multiple types.
124
- *
125
- * @param typeAlias - The type alias declaration to analyze
126
- * @param checker - TypeScript type checker
127
- * @returns Success with analysis, or error with a diagnostic message including line number
128
- */
129
- export declare function analyzeTypeAlias(typeAlias: ts.TypeAliasDeclaration, checker: ts.TypeChecker): AnalyzeTypeAliasResult;
130
- /**
131
- * Analyzes an interface property signature to extract field info.
132
- *
133
- * Extracts JSDoc constraint tags (`@Minimum`, `@MaxLength`, etc.) and
134
- * display metadata (`@DisplayName`, `@Description`) from the property's
135
- * TSDoc comments. Also used by the type converter for nested interface/type
136
- * alias constraint propagation.
137
- */
138
- export declare function analyzeInterfaceProperty(prop: ts.PropertySignature, checker: ts.TypeChecker): FieldInfo | null;
139
94
  //# sourceMappingURL=class-analyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"class-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/class-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGnG;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;IAClC,0CAA0C;IAC1C,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,oDAAoD;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,kFAAkF;IAClF,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,uBAAuB;IACvB,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,qBAAqB;IACrB,aAAa,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,uBAAuB;IACvB,cAAc,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;IACxC,2BAA2B;IAC3B,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,QAAQ,EAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;IAClC,oBAAoB;IACpB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,0DAA0D;IAC1D,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iEAAiE;IACjE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,EAAE,CAAC,gBAAgB,EAC9B,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,aAAa,CA+Bf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,EAAE,CAAC,mBAAmB,EAC5B,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,SAAS,GAAG,IAAI,CA6ClB;AAsLD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,EAAE,CAAC,oBAAoB,EACtC,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,aAAa,CAmBf;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAClC,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,sBAAsB,CAkCxB;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,EAAE,CAAC,iBAAiB,EAC1B,OAAO,EAAE,EAAE,CAAC,WAAW,GACtB,SAAS,GAAG,IAAI,CAyClB"}
1
+ {"version":3,"file":"class-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/class-analyzer.ts"],"names":[],"mappings":"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"}
@@ -1,47 +1,95 @@
1
1
  /**
2
- * JSDoc constraint tag extractor.
2
+ * JSDoc constraint and annotation extractor.
3
3
  *
4
- * Extracts constraint tags from JSDoc comments on class fields and returns
5
- * synthetic {@link DecoratorInfo} objects that integrate seamlessly with
6
- * the existing decorator-based constraint pipeline.
4
+ * Extracts constraints and annotation tags from JSDoc comments on
5
+ * class/interface fields and returns canonical IR nodes directly:
6
+ * - {@link ConstraintNode} for set-influencing tags (@Minimum, @Pattern, etc.)
7
+ * - {@link AnnotationNode} for value-influencing tags (@Field_displayName, etc.)
7
8
  *
8
- * Supported tags correspond to keys in {@link CONSTRAINT_TAG_DEFINITIONS}
9
+ * The IR extraction path uses the official `@microsoft/tsdoc` parser for
10
+ * constraints (all TSDoc-compliant alphanumeric names) and the TypeScript
11
+ * compiler JSDoc API for annotation tags (which contain underscores, e.g.
12
+ * `@Field_displayName`).
13
+ *
14
+ * Supported constraints correspond to keys in {@link BUILTIN_CONSTRAINT_DEFINITIONS}
9
15
  * from `@formspec/core` (e.g., `@Minimum`, `@Maximum`, `@Pattern`).
10
16
  */
11
17
  import * as ts from "typescript";
12
- import type { DecoratorInfo } from "./decorator-extractor.js";
18
+ import { type ConstraintNode, type AnnotationNode } from "@formspec/core";
19
+ /**
20
+ * A constraint argument value.
21
+ */
22
+ export type ConstraintArg = string | number | boolean | null | ConstraintArg[] | {
23
+ [key: string]: ConstraintArg;
24
+ };
25
+ /**
26
+ * Extracted constraint information from a JSDoc tag.
27
+ * @deprecated Use {@link ConstraintNode} from the IR path instead.
28
+ */
29
+ export interface ConstraintInfo {
30
+ /** Constraint name (e.g., "Minimum", "Pattern", "Field") */
31
+ name: string;
32
+ /** Constraint arguments as literal values */
33
+ args: ConstraintArg[];
34
+ /** Raw AST node (undefined for synthetic JSDoc constraint entries) */
35
+ node: ts.Decorator | undefined;
36
+ }
13
37
  /**
14
- * Extracts JSDoc constraint tags from a TypeScript AST node and returns
15
- * synthetic {@link DecoratorInfo} objects.
38
+ * Extracts constraints from JSDoc comments on a TypeScript AST node and returns
39
+ * canonical {@link ConstraintNode} objects.
16
40
  *
17
- * For each recognised tag (case-sensitive PascalCase match against
18
- * {@link CONSTRAINT_TAG_DEFINITIONS}), the comment text is parsed
19
- * according to the tag's declared value type:
20
- * - `"number"` tags: parsed via `Number()` — skipped when NaN
21
- * - `"string"` tags (`Pattern`): used as-is (trimmed)
41
+ * Uses the official `@microsoft/tsdoc` parser for structured tag extraction.
42
+ * Constraints are registered as custom block tags in the TSDoc configuration.
22
43
  *
23
44
  * @param node - The AST node to inspect for JSDoc tags
24
- * @returns Synthetic decorator info objects for each valid constraint tag
45
+ * @param file - Absolute path to the source file for provenance
46
+ * @returns Canonical constraint nodes for each valid constraint tag
25
47
  */
26
- export declare function extractJSDocConstraints(node: ts.Node): DecoratorInfo[];
48
+ export declare function extractJSDocConstraintNodes(node: ts.Node, file?: string): ConstraintNode[];
27
49
  /**
28
- * Extracts `@Field_displayName` and `@Field_description` TSDoc tags from
29
- * a node and returns a synthetic `Field` {@link DecoratorInfo} if either
30
- * is present.
50
+ * Extracts `@Field_displayName`, `@Field_description`, and `@deprecated`
51
+ * TSDoc tags from a node and returns canonical {@link AnnotationNode} objects.
31
52
  *
32
- * This enables interface properties to carry display metadata via TSDoc
33
- * tags instead of the `@Field` decorator (which requires a class):
53
+ * Uses a hybrid approach:
54
+ * - `@deprecated` is extracted via the TSDoc parser (standard tag).
55
+ * - `@Field_displayName` and `@Field_description` are extracted via the
56
+ * TypeScript compiler JSDoc API because they contain underscores which
57
+ * are invalid in TSDoc tag names.
34
58
  *
35
- * ```typescript
36
- * interface Config {
37
- * // @Field_displayName Program Name
38
- * // @Field_description Internal identifier
39
- * programName: string;
40
- * }
41
- * ```
59
+ * @param node - The AST node to inspect for annotation tags
60
+ * @param file - Absolute path to the source file for provenance
61
+ * @returns Canonical annotation nodes
62
+ */
63
+ export declare function extractJSDocAnnotationNodes(node: ts.Node, file?: string): AnnotationNode[];
64
+ /**
65
+ * Checks if a node has a TSDoc `@deprecated` tag.
66
+ *
67
+ * Uses the TSDoc parser for structured detection.
68
+ */
69
+ export declare function hasDeprecatedTag(node: ts.Node): boolean;
70
+ /**
71
+ * Extracts a default value from a property initializer and returns a
72
+ * {@link DefaultValueAnnotationNode} if present.
73
+ *
74
+ * Only extracts literal values (strings, numbers, booleans, null).
75
+ */
76
+ export declare function extractDefaultValueAnnotation(initializer: ts.Expression | undefined, file?: string): AnnotationNode | null;
77
+ /**
78
+ * Extracts JSDoc constraint tags and returns synthetic {@link ConstraintInfo}
79
+ * objects for backward compatibility with the decorator-based pipeline.
80
+ *
81
+ * Uses the TypeScript compiler JSDoc API (not TSDoc parser) to maintain
82
+ * identical behavior with the legacy pipeline.
83
+ *
84
+ * @deprecated Use {@link extractJSDocConstraintNodes} for IR output.
85
+ */
86
+ export declare function extractJSDocConstraints(node: ts.Node): ConstraintInfo[];
87
+ /**
88
+ * Extracts `@Field_displayName` and `@Field_description` TSDoc tags
89
+ * and returns a synthetic `Field` {@link ConstraintInfo} for backward
90
+ * compatibility with the decorator-based pipeline.
42
91
  *
43
- * @param node - The AST node to inspect for display metadata tags
44
- * @returns A synthetic `Field` decorator info, or null if no tags found
92
+ * @deprecated Use {@link extractJSDocAnnotationNodes} for IR output.
45
93
  */
46
- export declare function extractJSDocFieldMetadata(node: ts.Node): DecoratorInfo | null;
94
+ export declare function extractJSDocFieldMetadata(node: ts.Node): ConstraintInfo | null;
47
95
  //# sourceMappingURL=jsdoc-constraints.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsdoc-constraints.d.ts","sourceRoot":"","sources":["../../src/analyzer/jsdoc-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAgB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE5E;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,aAAa,EAAE,CAoDtE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,aAAa,GAAG,IAAI,CAiC7E"}
1
+ {"version":3,"file":"jsdoc-constraints.d.ts","sourceRoot":"","sources":["../../src/analyzer/jsdoc-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AAOxB;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,aAAa,EAAE,GACf;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAErC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,sEAAsE;IACtE,IAAI,EAAE,EAAE,CAAC,SAAS,GAAG,SAAS,CAAC;CAChC;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,SAAK,GAAG,cAAc,EAAE,CAGtF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,SAAK,GAAG,cAAc,EAAE,CAGtF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,EAAE,CAAC,UAAU,GAAG,SAAS,EACtC,IAAI,SAAK,GACR,cAAc,GAAG,IAAI,CAwCvB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,cAAc,EAAE,CA8CvE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,cAAc,GAAG,IAAI,CAgC9E"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * TSDoc-based structured tag parser.
3
+ *
4
+ * Bridges the TypeScript compiler AST with the official `@microsoft/tsdoc`
5
+ * parser to extract constraint and annotation tags from JSDoc comments
6
+ * on class/interface/type-alias properties.
7
+ *
8
+ * The parser recognises two categories of tags:
9
+ *
10
+ * 1. **Constraint tags** (all alphanumeric, TSDoc-compliant):
11
+ * `@Minimum`, `@Maximum`, `@ExclusiveMinimum`, `@ExclusiveMaximum`,
12
+ * `@MinLength`, `@MaxLength`, `@Pattern`, `@EnumOptions`
13
+ * — Parsed via TSDocParser as custom block tags.
14
+ *
15
+ * 2. **Annotation tags** (`@Field_displayName`, `@Field_description`):
16
+ * These contain underscores which are not valid in TSDoc tag names.
17
+ * They are extracted via the TypeScript compiler's `ts.getJSDocTags()`
18
+ * until a future migration to underscore-free tag names.
19
+ *
20
+ * The `@deprecated` tag is a standard TSDoc block tag, parsed structurally.
21
+ *
22
+ * **Fallback strategy**: TSDoc treats `{` / `}` as inline tag delimiters and
23
+ * `@` as a tag prefix, so content containing these characters (e.g. JSON
24
+ * objects in `@EnumOptions`, regex patterns with `@` in `@Pattern`) gets
25
+ * mangled by the TSDoc parser. For these tags, the raw text is extracted
26
+ * via the TS compiler's `ts.getJSDocTags()` API which preserves content
27
+ * verbatim.
28
+ */
29
+ import * as ts from "typescript";
30
+ import { type ConstraintNode, type AnnotationNode } from "@formspec/core";
31
+ /**
32
+ * Result of parsing a single JSDoc comment attached to a TS AST node.
33
+ */
34
+ export interface TSDocParseResult {
35
+ /** Constraint IR nodes extracted from custom block tags. */
36
+ readonly constraints: readonly ConstraintNode[];
37
+ /** Annotation IR nodes extracted from modifier/block tags and TS JSDoc API. */
38
+ readonly annotations: readonly AnnotationNode[];
39
+ }
40
+ /**
41
+ * Parses the JSDoc comment attached to a TypeScript AST node using the
42
+ * official TSDoc parser and returns canonical IR constraint and annotation
43
+ * nodes.
44
+ *
45
+ * For constraint tags (`@Minimum`, `@Pattern`, `@EnumOptions`, etc.),
46
+ * the structured TSDoc parser is used. For annotation tags that contain
47
+ * underscores (`@Field_displayName`, `@Field_description`), the TypeScript
48
+ * compiler JSDoc API is used as a fallback.
49
+ *
50
+ * @param node - The TS AST node to inspect (PropertyDeclaration, PropertySignature, etc.)
51
+ * @param file - Absolute source file path for provenance
52
+ * @returns Parsed constraint and annotation nodes
53
+ */
54
+ export declare function parseTSDocTags(node: ts.Node, file?: string): TSDocParseResult;
55
+ /**
56
+ * Checks if a TS AST node has a `@deprecated` tag using the TSDoc parser.
57
+ *
58
+ * Falls back to the TS compiler API for nodes without doc comments.
59
+ */
60
+ export declare function hasDeprecatedTagTSDoc(node: ts.Node): boolean;
61
+ //# sourceMappingURL=tsdoc-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsdoc-parser.d.ts","sourceRoot":"","sources":["../../src/analyzer/tsdoc-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAYjC,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EAIpB,MAAM,gBAAgB,CAAC;AA8ExB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;CACjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,SAAK,GAAG,gBAAgB,CAuHzE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAsB5D"}