@contractspec/module.workspace 0.0.0-canary-20260113162409

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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/ai/prompts/code-generation.d.ts +24 -0
  4. package/dist/ai/prompts/code-generation.d.ts.map +1 -0
  5. package/dist/ai/prompts/code-generation.js +134 -0
  6. package/dist/ai/prompts/code-generation.js.map +1 -0
  7. package/dist/ai/prompts/spec-creation.d.ts +28 -0
  8. package/dist/ai/prompts/spec-creation.d.ts.map +1 -0
  9. package/dist/ai/prompts/spec-creation.js +102 -0
  10. package/dist/ai/prompts/spec-creation.js.map +1 -0
  11. package/dist/analysis/deps/graph.d.ts +34 -0
  12. package/dist/analysis/deps/graph.d.ts.map +1 -0
  13. package/dist/analysis/deps/graph.js +85 -0
  14. package/dist/analysis/deps/graph.js.map +1 -0
  15. package/dist/analysis/deps/parse-imports.d.ts +17 -0
  16. package/dist/analysis/deps/parse-imports.d.ts.map +1 -0
  17. package/dist/analysis/deps/parse-imports.js +31 -0
  18. package/dist/analysis/deps/parse-imports.js.map +1 -0
  19. package/dist/analysis/diff/deep-diff.d.ts +33 -0
  20. package/dist/analysis/diff/deep-diff.d.ts.map +1 -0
  21. package/dist/analysis/diff/deep-diff.js +114 -0
  22. package/dist/analysis/diff/deep-diff.js.map +1 -0
  23. package/dist/analysis/diff/semantic.d.ts +11 -0
  24. package/dist/analysis/diff/semantic.d.ts.map +1 -0
  25. package/dist/analysis/diff/semantic.js +97 -0
  26. package/dist/analysis/diff/semantic.js.map +1 -0
  27. package/dist/analysis/example-scan.d.ts +15 -0
  28. package/dist/analysis/example-scan.d.ts.map +1 -0
  29. package/dist/analysis/example-scan.js +116 -0
  30. package/dist/analysis/example-scan.js.map +1 -0
  31. package/dist/analysis/feature-extractor.js +203 -0
  32. package/dist/analysis/feature-extractor.js.map +1 -0
  33. package/dist/analysis/feature-scan.d.ts +15 -0
  34. package/dist/analysis/feature-scan.d.ts.map +1 -0
  35. package/dist/analysis/feature-scan.js +56 -0
  36. package/dist/analysis/feature-scan.js.map +1 -0
  37. package/dist/analysis/grouping.d.ts +79 -0
  38. package/dist/analysis/grouping.d.ts.map +1 -0
  39. package/dist/analysis/grouping.js +115 -0
  40. package/dist/analysis/grouping.js.map +1 -0
  41. package/dist/analysis/impact/classifier.d.ts +19 -0
  42. package/dist/analysis/impact/classifier.d.ts.map +1 -0
  43. package/dist/analysis/impact/classifier.js +135 -0
  44. package/dist/analysis/impact/classifier.js.map +1 -0
  45. package/dist/analysis/impact/index.js +2 -0
  46. package/dist/analysis/impact/rules.d.ts +35 -0
  47. package/dist/analysis/impact/rules.d.ts.map +1 -0
  48. package/dist/analysis/impact/rules.js +154 -0
  49. package/dist/analysis/impact/rules.js.map +1 -0
  50. package/dist/analysis/impact/types.d.ts +95 -0
  51. package/dist/analysis/impact/types.d.ts.map +1 -0
  52. package/dist/analysis/index.js +18 -0
  53. package/dist/analysis/snapshot/index.js +2 -0
  54. package/dist/analysis/snapshot/normalizer.d.ts +36 -0
  55. package/dist/analysis/snapshot/normalizer.d.ts.map +1 -0
  56. package/dist/analysis/snapshot/normalizer.js +67 -0
  57. package/dist/analysis/snapshot/normalizer.js.map +1 -0
  58. package/dist/analysis/snapshot/snapshot.d.ts +18 -0
  59. package/dist/analysis/snapshot/snapshot.d.ts.map +1 -0
  60. package/dist/analysis/snapshot/snapshot.js +163 -0
  61. package/dist/analysis/snapshot/snapshot.js.map +1 -0
  62. package/dist/analysis/snapshot/types.d.ts +74 -0
  63. package/dist/analysis/snapshot/types.d.ts.map +1 -0
  64. package/dist/analysis/spec-parser.d.ts +11 -0
  65. package/dist/analysis/spec-parser.d.ts.map +1 -0
  66. package/dist/analysis/spec-parser.js +89 -0
  67. package/dist/analysis/spec-parser.js.map +1 -0
  68. package/dist/analysis/spec-parsing-utils.d.ts +26 -0
  69. package/dist/analysis/spec-parsing-utils.d.ts.map +1 -0
  70. package/dist/analysis/spec-parsing-utils.js +98 -0
  71. package/dist/analysis/spec-parsing-utils.js.map +1 -0
  72. package/dist/analysis/spec-scan.d.ts +20 -0
  73. package/dist/analysis/spec-scan.d.ts.map +1 -0
  74. package/dist/analysis/spec-scan.js +141 -0
  75. package/dist/analysis/spec-scan.js.map +1 -0
  76. package/dist/analysis/utils/matchers.js +77 -0
  77. package/dist/analysis/utils/matchers.js.map +1 -0
  78. package/dist/analysis/utils/variables.js +45 -0
  79. package/dist/analysis/utils/variables.js.map +1 -0
  80. package/dist/analysis/validate/index.js +1 -0
  81. package/dist/analysis/validate/spec-structure.d.ts +29 -0
  82. package/dist/analysis/validate/spec-structure.d.ts.map +1 -0
  83. package/dist/analysis/validate/spec-structure.js +455 -0
  84. package/dist/analysis/validate/spec-structure.js.map +1 -0
  85. package/dist/formatter.d.ts +42 -0
  86. package/dist/formatter.d.ts.map +1 -0
  87. package/dist/formatter.js +163 -0
  88. package/dist/formatter.js.map +1 -0
  89. package/dist/formatters/index.js +2 -0
  90. package/dist/formatters/spec-markdown.d.ts +31 -0
  91. package/dist/formatters/spec-markdown.d.ts.map +1 -0
  92. package/dist/formatters/spec-markdown.js +263 -0
  93. package/dist/formatters/spec-markdown.js.map +1 -0
  94. package/dist/formatters/spec-to-docblock.d.ts +14 -0
  95. package/dist/formatters/spec-to-docblock.d.ts.map +1 -0
  96. package/dist/formatters/spec-to-docblock.js +48 -0
  97. package/dist/formatters/spec-to-docblock.js.map +1 -0
  98. package/dist/index.d.ts +42 -0
  99. package/dist/index.js +39 -0
  100. package/dist/templates/app-config.d.ts +7 -0
  101. package/dist/templates/app-config.d.ts.map +1 -0
  102. package/dist/templates/app-config.js +107 -0
  103. package/dist/templates/app-config.js.map +1 -0
  104. package/dist/templates/data-view.d.ts +7 -0
  105. package/dist/templates/data-view.d.ts.map +1 -0
  106. package/dist/templates/data-view.js +69 -0
  107. package/dist/templates/data-view.js.map +1 -0
  108. package/dist/templates/event.d.ts +11 -0
  109. package/dist/templates/event.d.ts.map +1 -0
  110. package/dist/templates/event.js +41 -0
  111. package/dist/templates/event.js.map +1 -0
  112. package/dist/templates/experiment.d.ts +7 -0
  113. package/dist/templates/experiment.d.ts.map +1 -0
  114. package/dist/templates/experiment.js +88 -0
  115. package/dist/templates/experiment.js.map +1 -0
  116. package/dist/templates/handler.d.ts +20 -0
  117. package/dist/templates/handler.d.ts.map +1 -0
  118. package/dist/templates/handler.js +96 -0
  119. package/dist/templates/handler.js.map +1 -0
  120. package/dist/templates/integration-utils.js +105 -0
  121. package/dist/templates/integration-utils.js.map +1 -0
  122. package/dist/templates/integration.d.ts +7 -0
  123. package/dist/templates/integration.d.ts.map +1 -0
  124. package/dist/templates/integration.js +62 -0
  125. package/dist/templates/integration.js.map +1 -0
  126. package/dist/templates/knowledge.d.ts +7 -0
  127. package/dist/templates/knowledge.d.ts.map +1 -0
  128. package/dist/templates/knowledge.js +69 -0
  129. package/dist/templates/knowledge.js.map +1 -0
  130. package/dist/templates/migration.d.ts +7 -0
  131. package/dist/templates/migration.d.ts.map +1 -0
  132. package/dist/templates/migration.js +61 -0
  133. package/dist/templates/migration.js.map +1 -0
  134. package/dist/templates/operation.d.ts +11 -0
  135. package/dist/templates/operation.d.ts.map +1 -0
  136. package/dist/templates/operation.js +101 -0
  137. package/dist/templates/operation.js.map +1 -0
  138. package/dist/templates/presentation.d.ts +11 -0
  139. package/dist/templates/presentation.d.ts.map +1 -0
  140. package/dist/templates/presentation.js +79 -0
  141. package/dist/templates/presentation.js.map +1 -0
  142. package/dist/templates/telemetry.d.ts +7 -0
  143. package/dist/templates/telemetry.d.ts.map +1 -0
  144. package/dist/templates/telemetry.js +90 -0
  145. package/dist/templates/telemetry.js.map +1 -0
  146. package/dist/templates/utils.d.ts +27 -0
  147. package/dist/templates/utils.d.ts.map +1 -0
  148. package/dist/templates/utils.js +39 -0
  149. package/dist/templates/utils.js.map +1 -0
  150. package/dist/templates/workflow-runner.d.ts +16 -0
  151. package/dist/templates/workflow-runner.d.ts.map +1 -0
  152. package/dist/templates/workflow-runner.js +49 -0
  153. package/dist/templates/workflow-runner.js.map +1 -0
  154. package/dist/templates/workflow.d.ts +11 -0
  155. package/dist/templates/workflow.d.ts.map +1 -0
  156. package/dist/templates/workflow.js +68 -0
  157. package/dist/templates/workflow.js.map +1 -0
  158. package/dist/types/analysis-types.d.ts +199 -0
  159. package/dist/types/analysis-types.d.ts.map +1 -0
  160. package/dist/types/generation-types.d.ts +87 -0
  161. package/dist/types/generation-types.d.ts.map +1 -0
  162. package/dist/types/generation-types.js +21 -0
  163. package/dist/types/generation-types.js.map +1 -0
  164. package/dist/types/llm-types.d.ts +138 -0
  165. package/dist/types/llm-types.d.ts.map +1 -0
  166. package/dist/types/rulesync-types.d.ts +24 -0
  167. package/dist/types/rulesync-types.d.ts.map +1 -0
  168. package/dist/types/spec-types.d.ts +343 -0
  169. package/dist/types/spec-types.d.ts.map +1 -0
  170. package/package.json +63 -0
@@ -0,0 +1,45 @@
1
+ import { findMatchingDelimiter } from "./matchers.js";
2
+
3
+ //#region src/analysis/utils/variables.ts
4
+ /**
5
+ * Variable resolution utilities.
6
+ * Handles simple static variable extraction and substitution in source blocks.
7
+ */
8
+ /**
9
+ * Extract top-level array constants from source code.
10
+ * Example: const OWNERS = ['alice', 'bob'] as const;
11
+ */
12
+ function extractArrayConstants(code) {
13
+ const variables = /* @__PURE__ */ new Map();
14
+ const regex = /const\s+(\w+)\s*=\s*\[/g;
15
+ let match;
16
+ while ((match = regex.exec(code)) !== null) {
17
+ const name = match[1];
18
+ const startIndex = match.index + match[0].length - 1;
19
+ const endIndex = findMatchingDelimiter(code, startIndex, "[", "]");
20
+ if (endIndex !== -1) {
21
+ const value = code.substring(startIndex, endIndex + 1);
22
+ if (name) variables.set(name, value);
23
+ }
24
+ }
25
+ return variables;
26
+ }
27
+ /**
28
+ * Substitute spread variables in a source block with their resolved values.
29
+ * Example: owners: [...OWNERS] -> owners: ['alice', 'bob']
30
+ */
31
+ function resolveVariablesInBlock(block, variables) {
32
+ if (variables.size === 0) return block;
33
+ return block.replace(/\.\.\.(\w+)/g, (match, name) => {
34
+ const value = variables.get(name);
35
+ if (value) {
36
+ if (value.startsWith("[") && value.endsWith("]")) return value.substring(1, value.length - 1);
37
+ return value;
38
+ }
39
+ return match;
40
+ });
41
+ }
42
+
43
+ //#endregion
44
+ export { extractArrayConstants, resolveVariablesInBlock };
45
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.js","names":[],"sources":["../../../src/analysis/utils/variables.ts"],"sourcesContent":["/**\n * Variable resolution utilities.\n * Handles simple static variable extraction and substitution in source blocks.\n */\n\nimport { findMatchingDelimiter } from './matchers';\n\n/**\n * Extract top-level array constants from source code.\n * Example: const OWNERS = ['alice', 'bob'] as const;\n */\nexport function extractArrayConstants(code: string): Map<string, string> {\n const variables = new Map<string, string>();\n\n // Regex to find potential array constants\n // Matches: const NAME = [ ...\n const regex = /const\\s+(\\w+)\\s*=\\s*\\[/g;\n let match;\n\n while ((match = regex.exec(code)) !== null) {\n const name = match[1];\n const startIndex = match.index + match[0].length - 1; // pointing to [\n const endIndex = findMatchingDelimiter(code, startIndex, '[', ']');\n\n if (endIndex !== -1) {\n // Extract the full array string: ['a', 'b']\n const value = code.substring(startIndex, endIndex + 1);\n if (name) {\n variables.set(name, value);\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Substitute spread variables in a source block with their resolved values.\n * Example: owners: [...OWNERS] -> owners: ['alice', 'bob']\n */\nexport function resolveVariablesInBlock(\n block: string,\n variables: Map<string, string>\n): string {\n if (variables.size === 0) return block;\n\n // Look for spreads: ...NAME\n return block.replace(/\\.\\.\\.(\\w+)/g, (match, name) => {\n const value = variables.get(name);\n if (value) {\n // Remove the surrounding brackets from the value if we are spreading into an array\n // But ... is also used in objects.\n // In the array case: owners: [...OWNERS] -> owners: ['a', 'b']\n // OWNERS = ['a', 'b']\n\n // We need to strip the outer [ and ] from the value to \"spread\" it\n if (value.startsWith('[') && value.endsWith(']')) {\n return value.substring(1, value.length - 1);\n }\n return value;\n }\n return match;\n });\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,sBAAsB,MAAmC;CACvE,MAAM,4BAAY,IAAI,KAAqB;CAI3C,MAAM,QAAQ;CACd,IAAI;AAEJ,SAAQ,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM;EAC1C,MAAM,OAAO,MAAM;EACnB,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,SAAS;EACnD,MAAM,WAAW,sBAAsB,MAAM,YAAY,KAAK,IAAI;AAElE,MAAI,aAAa,IAAI;GAEnB,MAAM,QAAQ,KAAK,UAAU,YAAY,WAAW,EAAE;AACtD,OAAI,KACF,WAAU,IAAI,MAAM,MAAM;;;AAKhC,QAAO;;;;;;AAOT,SAAgB,wBACd,OACA,WACQ;AACR,KAAI,UAAU,SAAS,EAAG,QAAO;AAGjC,QAAO,MAAM,QAAQ,iBAAiB,OAAO,SAAS;EACpD,MAAM,QAAQ,UAAU,IAAI,KAAK;AACjC,MAAI,OAAO;AAOT,OAAI,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI,CAC9C,QAAO,MAAM,UAAU,GAAG,MAAM,SAAS,EAAE;AAE7C,UAAO;;AAET,SAAO;GACP"}
@@ -0,0 +1 @@
1
+ import { validateSpecStructure } from "./spec-structure.js";
@@ -0,0 +1,29 @@
1
+ import { ValidationResult } from "../../types/analysis-types.js";
2
+
3
+ //#region src/analysis/validate/spec-structure.d.ts
4
+
5
+ /**
6
+ * Rule severity level for lint rules.
7
+ */
8
+ type RuleSeverity = 'off' | 'warn' | 'error';
9
+ /**
10
+ * Spec kind for rule overrides mapping.
11
+ */
12
+ type SpecKind = 'operation' | 'event' | 'presentation' | 'feature' | 'workflow' | 'data-view' | 'migration' | 'telemetry' | 'experiment' | 'app-config';
13
+ /**
14
+ * Interface for resolving rule severity.
15
+ */
16
+ interface RulesConfig {
17
+ /**
18
+ * Get the severity for a rule, considering spec kind overrides.
19
+ * Returns 'warn' by default if not configured.
20
+ */
21
+ getRule(ruleName: string, specKind: SpecKind): RuleSeverity;
22
+ }
23
+ /**
24
+ * Validate spec structure based on source code and filename.
25
+ */
26
+ declare function validateSpecStructure(code: string, fileName: string, rulesConfig?: RulesConfig): ValidationResult;
27
+ //#endregion
28
+ export { RuleSeverity, RulesConfig, SpecKind, validateSpecStructure };
29
+ //# sourceMappingURL=spec-structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-structure.d.ts","names":[],"sources":["../../../src/analysis/validate/spec-structure.ts"],"sourcesContent":[],"mappings":";;;;AA2DA;;;KAtCY,YAAA;;;;KAKA,QAAA;;;;UAeK,WAAA;;;;;sCAKqB,WAAW;;;;;iBAajC,qBAAA,+CAGD,cACZ"}
@@ -0,0 +1,455 @@
1
+ import { Node, Project, SyntaxKind } from "ts-morph";
2
+
3
+ //#region src/analysis/validate/spec-structure.ts
4
+ /**
5
+ * Spec structure validation utilities.
6
+ * Extracted from cli-contractspec/src/commands/validate/spec-checker.ts
7
+ */
8
+ /**
9
+ * Default rules config that returns 'warn' for all rules.
10
+ */
11
+ const DEFAULT_RULES_CONFIG = { getRule: () => "warn" };
12
+ /**
13
+ * Validate spec structure based on source code and filename.
14
+ */
15
+ function validateSpecStructure(code, fileName, rulesConfig = DEFAULT_RULES_CONFIG) {
16
+ const errors = [];
17
+ const warnings = [];
18
+ const sourceFile = new Project({ useInMemoryFileSystem: true }).createSourceFile(fileName, code);
19
+ if (!(sourceFile.getExportAssignments().length > 0 || sourceFile.getVariableStatements().some((s) => s.isExported()) || sourceFile.getFunctions().some((f) => f.isExported()) || sourceFile.getClasses().some((c) => c.isExported()) || sourceFile.getExportDeclarations().length > 0)) errors.push("No exported spec found");
20
+ if (fileName.includes(".contracts.") || fileName.includes(".contract.") || fileName.includes(".operations.") || fileName.includes(".operation.")) validateOperationSpec(sourceFile, errors, warnings, rulesConfig);
21
+ if (fileName.includes(".event.")) validateEventSpec(sourceFile, errors, warnings, rulesConfig);
22
+ if (fileName.includes(".presentation.")) validatePresentationSpec(sourceFile, errors, warnings);
23
+ if (fileName.includes(".workflow.")) validateWorkflowSpec(sourceFile, errors, warnings, rulesConfig);
24
+ if (fileName.includes(".data-view.")) validateDataViewSpec(sourceFile, errors, warnings, rulesConfig);
25
+ if (fileName.includes(".migration.")) validateMigrationSpec(sourceFile, errors, warnings, rulesConfig);
26
+ if (fileName.includes(".telemetry.")) validateTelemetrySpec(sourceFile, errors, warnings, rulesConfig);
27
+ if (fileName.includes(".experiment.")) validateExperimentSpec(sourceFile, errors, warnings, rulesConfig);
28
+ if (fileName.includes(".app-config.")) validateAppConfigSpec(sourceFile, errors, warnings, rulesConfig);
29
+ validateCommonFields(sourceFile, fileName, errors, warnings, rulesConfig);
30
+ return {
31
+ valid: errors.length === 0,
32
+ errors,
33
+ warnings
34
+ };
35
+ }
36
+ /**
37
+ * Helper to emit a message based on rule severity.
38
+ */
39
+ function emitRule(ruleName, specKind, message, errors, warnings, rulesConfig) {
40
+ const severity = rulesConfig.getRule(ruleName, specKind);
41
+ if (severity === "off") return;
42
+ if (severity === "error") errors.push(message);
43
+ else warnings.push(message);
44
+ }
45
+ /**
46
+ * Validate operation spec
47
+ */
48
+ function validateOperationSpec(sourceFile, errors, warnings, rulesConfig) {
49
+ const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
50
+ if (!callExpressions.some((call) => {
51
+ const text = call.getExpression().getText();
52
+ return text === "defineCommand" || text === "defineQuery";
53
+ })) errors.push("Missing defineCommand or defineQuery call");
54
+ let specObject;
55
+ for (const call of callExpressions) {
56
+ const text = call.getExpression().getText();
57
+ if (text === "defineCommand" || text === "defineQuery") {
58
+ const args = call.getArguments();
59
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
60
+ specObject = args[0];
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ if (specObject && Node.isObjectLiteralExpression(specObject)) {
66
+ if (!specObject.getProperty("meta")) errors.push("Missing meta section");
67
+ if (!specObject.getProperty("io")) errors.push("Missing io section");
68
+ if (!specObject.getProperty("policy")) errors.push("Missing policy section");
69
+ const metaProp = specObject.getProperty("meta");
70
+ let hasKey = false;
71
+ let hasVersion = false;
72
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
73
+ const metaObj = metaProp.getInitializer();
74
+ if (metaObj && Node.isObjectLiteralExpression(metaObj)) {
75
+ if (metaObj.getProperty("key")) hasKey = true;
76
+ if (metaObj.getProperty("version")) hasVersion = true;
77
+ }
78
+ }
79
+ if (!hasKey) {
80
+ if (specObject.getProperty("key")) hasKey = true;
81
+ }
82
+ if (!hasKey) errors.push("Missing or invalid key field");
83
+ if (!hasVersion) {
84
+ if (specObject.getProperty("version")) hasVersion = true;
85
+ }
86
+ if (!hasVersion) errors.push("Missing or invalid version field");
87
+ const hasExplicitKind = specObject.getProperty("kind");
88
+ if (!callExpressions.find((c) => {
89
+ const t = c.getExpression().getText();
90
+ return t === "defineCommand" || t === "defineQuery";
91
+ })?.getExpression().getText() && !hasExplicitKind) errors.push("Missing kind: use defineCommand(), defineQuery(), or explicit kind field");
92
+ if (!specObject.getProperty("acceptance")) emitRule("require-acceptance", "operation", "No acceptance scenarios defined", errors, warnings, rulesConfig);
93
+ if (!specObject.getProperty("examples")) emitRule("require-examples", "operation", "No examples provided", errors, warnings, rulesConfig);
94
+ }
95
+ if (sourceFile.getFullText().includes("TODO")) emitRule("no-todo", "operation", "Contains TODO items that need completion", errors, warnings, rulesConfig);
96
+ }
97
+ function validateTelemetrySpec(sourceFile, errors, warnings, rulesConfig) {
98
+ const specObject = getSpecObject(sourceFile, "TelemetrySpec");
99
+ if (!specObject) {
100
+ errors.push("Missing TelemetrySpec type annotation");
101
+ return;
102
+ }
103
+ if (specObject) {
104
+ const metaProp = specObject.getProperty("meta");
105
+ let hasName = false;
106
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
107
+ const metaObj = metaProp.getInitializer();
108
+ if (Node.isObjectLiteralExpression(metaObj)) {
109
+ if (metaObj.getProperty("name")) hasName = true;
110
+ }
111
+ }
112
+ if (!hasName) errors.push("TelemetrySpec.meta is required");
113
+ if (!specObject.getProperty("events")) errors.push("TelemetrySpec must declare events");
114
+ if (!specObject.getProperty("privacy")) emitRule("telemetry-privacy", "telemetry", "No explicit privacy classification found", errors, warnings, rulesConfig);
115
+ }
116
+ }
117
+ function validateExperimentSpec(sourceFile, errors, warnings, rulesConfig) {
118
+ const specObject = getSpecObject(sourceFile, "ExperimentSpec");
119
+ if (!specObject) {
120
+ errors.push("Missing ExperimentSpec type annotation");
121
+ return;
122
+ }
123
+ if (!specObject.getProperty("controlVariant")) errors.push("ExperimentSpec must declare controlVariant");
124
+ if (!specObject.getProperty("variants")) errors.push("ExperimentSpec must declare variants");
125
+ if (!specObject.getProperty("allocation")) emitRule("experiment-allocation", "experiment", "ExperimentSpec missing allocation configuration", errors, warnings, rulesConfig);
126
+ }
127
+ function validateAppConfigSpec(sourceFile, errors, warnings, rulesConfig) {
128
+ const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "defineAppConfig");
129
+ let specObject;
130
+ if (defineCall) {
131
+ const args = defineCall.getArguments();
132
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) specObject = args[0];
133
+ } else specObject = getSpecObject(sourceFile, "AppBlueprintSpec");
134
+ if (!specObject) {
135
+ errors.push("Missing defineAppConfig call or AppBlueprintSpec type annotation");
136
+ return;
137
+ }
138
+ const metaProp = specObject.getProperty("meta");
139
+ if (!metaProp) errors.push("AppBlueprintSpec must define meta");
140
+ else if (Node.isPropertyAssignment(metaProp)) {
141
+ const metaObj = metaProp.getInitializer();
142
+ if (Node.isObjectLiteralExpression(metaObj)) {
143
+ if (!metaObj.getProperty("appId")) emitRule("app-config-appid", "app-config", "AppBlueprint meta missing appId assignment", errors, warnings, rulesConfig);
144
+ }
145
+ }
146
+ if (!specObject.getProperty("capabilities")) emitRule("app-config-capabilities", "app-config", "App blueprint spec does not declare capabilities", errors, warnings, rulesConfig);
147
+ }
148
+ /**
149
+ * Validate event spec
150
+ */
151
+ function validateEventSpec(sourceFile, errors, warnings, rulesConfig) {
152
+ const defineEventCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "defineEvent");
153
+ if (!defineEventCall) {
154
+ errors.push("Missing defineEvent call");
155
+ return;
156
+ }
157
+ let specObject;
158
+ const args = defineEventCall.getArguments();
159
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) specObject = args[0];
160
+ if (specObject && Node.isObjectLiteralExpression(specObject)) {
161
+ const metaProp = specObject.getProperty("meta");
162
+ let hasKey = false;
163
+ let hasVersion = false;
164
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
165
+ const metaObj = metaProp.getInitializer();
166
+ if (Node.isObjectLiteralExpression(metaObj)) {
167
+ const keyP = metaObj.getProperty("key");
168
+ if (keyP && Node.isPropertyAssignment(keyP)) {
169
+ const init = keyP.getInitializer();
170
+ if (init && Node.isStringLiteral(init)) hasKey = true;
171
+ }
172
+ if (metaObj.getProperty("version")) hasVersion = true;
173
+ }
174
+ }
175
+ if (!hasKey) {
176
+ const kp = specObject.getProperty("key");
177
+ if (kp && Node.isPropertyAssignment(kp)) {
178
+ const init = kp.getInitializer();
179
+ if (init && Node.isStringLiteral(init)) hasKey = true;
180
+ }
181
+ }
182
+ if (!hasVersion && specObject.getProperty("version")) hasVersion = true;
183
+ if (!hasKey) errors.push("Missing or invalid key field");
184
+ if (!hasVersion) errors.push("Missing or invalid version field");
185
+ if (!specObject.getProperty("payload")) errors.push("Missing payload field");
186
+ let name = "";
187
+ const getName = (obj) => {
188
+ const init = obj.getInitializer();
189
+ if (init && Node.isStringLiteral(init)) return init.getLiteralText();
190
+ return "";
191
+ };
192
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
193
+ const metaObj = metaProp.getInitializer();
194
+ if (Node.isObjectLiteralExpression(metaObj)) {
195
+ const nameP = metaObj.getProperty("name");
196
+ if (nameP && Node.isPropertyAssignment(nameP)) name = getName(nameP);
197
+ }
198
+ }
199
+ if (!name) {
200
+ const nameP = specObject.getProperty("name");
201
+ if (nameP && Node.isPropertyAssignment(nameP)) name = getName(nameP);
202
+ }
203
+ if (name) {
204
+ if (!(name.split(".").pop() ?? "").match(/(ed|created|updated|deleted|completed)$/i)) emitRule("event-past-tense", "event", "Event name should use past tense (e.g., \"created\", \"updated\")", errors, warnings, rulesConfig);
205
+ }
206
+ }
207
+ }
208
+ /**
209
+ * Validate presentation spec (V2 format)
210
+ */
211
+ function validatePresentationSpec(sourceFile, errors, _warnings) {
212
+ const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "definePresentation");
213
+ let specObject;
214
+ if (defineCall) {
215
+ const args = defineCall.getArguments();
216
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) specObject = args[0];
217
+ } else specObject = getSpecObject(sourceFile, "PresentationSpec");
218
+ if (!specObject) {
219
+ errors.push("Missing definePresentation call or PresentationSpec type annotation");
220
+ return;
221
+ }
222
+ if (!specObject.getProperty("meta")) errors.push("Missing meta section");
223
+ const sourceProp = specObject.getProperty("source");
224
+ if (!sourceProp) errors.push("Missing source section");
225
+ else if (Node.isPropertyAssignment(sourceProp)) {
226
+ const sourceObj = sourceProp.getInitializer();
227
+ if (Node.isObjectLiteralExpression(sourceObj)) {
228
+ const typeProp = sourceObj.getProperty("type");
229
+ if (!typeProp) errors.push("Missing or invalid source.type field");
230
+ else if (Node.isPropertyAssignment(typeProp)) {
231
+ const init = typeProp.getInitializer();
232
+ if (init && Node.isStringLiteral(init)) {
233
+ const val = init.getLiteralText();
234
+ if (val !== "component" && val !== "blocknotejs") errors.push("Missing or invalid source.type field");
235
+ }
236
+ }
237
+ }
238
+ }
239
+ if (!specObject.getProperty("targets")) errors.push("Missing targets section");
240
+ }
241
+ function validateWorkflowSpec(sourceFile, errors, warnings, rulesConfig) {
242
+ const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "defineWorkflow");
243
+ let specObject;
244
+ if (defineCall) {
245
+ const args = defineCall.getArguments();
246
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) specObject = args[0];
247
+ } else specObject = getSpecObject(sourceFile, "WorkflowSpec");
248
+ if (!specObject) {
249
+ errors.push("Missing defineWorkflow call or WorkflowSpec type annotation");
250
+ return;
251
+ }
252
+ if (!specObject.getProperty("definition")) errors.push("Missing definition section");
253
+ else {
254
+ const defProp = specObject.getProperty("definition");
255
+ if (defProp && Node.isPropertyAssignment(defProp)) {
256
+ const defObj = defProp.getInitializer();
257
+ if (Node.isObjectLiteralExpression(defObj)) {
258
+ if (!defObj.getProperty("steps")) errors.push("Workflow must declare steps");
259
+ if (!defObj.getProperty("transitions")) emitRule("workflow-transitions", "workflow", "No transitions declared; workflow will complete after first step.", errors, warnings, rulesConfig);
260
+ }
261
+ }
262
+ }
263
+ let titleFound = false;
264
+ let domainFound = false;
265
+ const metaProp = specObject.getProperty("meta");
266
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
267
+ const metaObj = metaProp.getInitializer();
268
+ if (Node.isObjectLiteralExpression(metaObj)) {
269
+ if (metaObj.getProperty("title")) titleFound = true;
270
+ if (metaObj.getProperty("domain")) domainFound = true;
271
+ }
272
+ }
273
+ if (!titleFound && specObject.getProperty("title")) titleFound = true;
274
+ if (!domainFound && specObject.getProperty("domain")) domainFound = true;
275
+ if (!titleFound) warnings.push("Missing workflow title");
276
+ if (!domainFound) warnings.push("Missing domain field");
277
+ if (sourceFile.getFullText().includes("TODO")) emitRule("no-todo", "workflow", "Contains TODO items that need completion", errors, warnings, rulesConfig);
278
+ }
279
+ function validateMigrationSpec(sourceFile, errors, warnings, rulesConfig) {
280
+ const specObject = getSpecObject(sourceFile, "MigrationSpec");
281
+ if (!specObject) {
282
+ errors.push("Missing MigrationSpec type annotation");
283
+ return;
284
+ }
285
+ const planProp = specObject.getProperty("plan");
286
+ if (!planProp) errors.push("Missing plan section");
287
+ else if (Node.isPropertyAssignment(planProp)) {
288
+ const planObj = planProp.getInitializer();
289
+ if (Node.isObjectLiteralExpression(planObj)) {
290
+ if (!planObj.getProperty("up")) errors.push("Migration must define at least one up step");
291
+ }
292
+ }
293
+ let nameFound = false;
294
+ let versionFound = false;
295
+ const metaProp = specObject.getProperty("meta");
296
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
297
+ const metaObj = metaProp.getInitializer();
298
+ if (Node.isObjectLiteralExpression(metaObj)) {
299
+ if (metaObj.getProperty("name")) nameFound = true;
300
+ if (metaObj.getProperty("version")) versionFound = true;
301
+ }
302
+ }
303
+ if (!nameFound && specObject.getProperty("name")) nameFound = true;
304
+ if (!versionFound && specObject.getProperty("version")) versionFound = true;
305
+ if (!nameFound) errors.push("Missing or invalid migration name");
306
+ if (!versionFound) errors.push("Missing or invalid migration version");
307
+ if (sourceFile.getFullText().includes("TODO")) emitRule("no-todo", "migration", "Contains TODO items that need completion", errors, warnings, rulesConfig);
308
+ }
309
+ /**
310
+ * Validate common fields across all spec types
311
+ */
312
+ function validateCommonFields(sourceFile, fileName, errors, warnings, rulesConfig) {
313
+ const code = sourceFile.getFullText();
314
+ const isInternalLib = fileName.includes("/libs/contracts/") || fileName.includes("/libs/contracts-transformers/") || fileName.includes("/libs/schema/");
315
+ if (code.includes("SchemaModel") && !isInternalLib) {
316
+ if (!sourceFile.getImportDeclarations().some((i) => i.getModuleSpecifierValue().includes("@contractspec/lib.schema"))) errors.push("Missing import for SchemaModel from @contractspec/lib.schema");
317
+ }
318
+ if ((code.includes("OperationSpec") || code.includes("PresentationSpec") || code.includes("EventSpec") || code.includes("FeatureSpec") || code.includes("WorkflowSpec") || code.includes("DataViewSpec") || code.includes("MigrationSpec") || code.includes("TelemetrySpec") || code.includes("ExperimentSpec") || code.includes("AppBlueprintSpec") || code.includes("defineCommand") || code.includes("defineQuery") || code.includes("defineEvent") || code.includes("definePresentation") || code.includes("defineWorkflow") || code.includes("defineDataView") || code.includes("defineAppConfig") || code.includes("defineFeature") || code.includes("defineExperiment") || code.includes("defineTelemetry") || code.includes("defineMigration")) && !isInternalLib) {
319
+ if (!sourceFile.getImportDeclarations().some((i) => i.getModuleSpecifierValue().includes("@contractspec/lib.contracts"))) errors.push("Missing import from @contractspec/lib.contracts");
320
+ }
321
+ const specObject = findMainExportedObject(sourceFile);
322
+ if (specObject && Node.isObjectLiteralExpression(specObject)) {
323
+ const ownersProp = specObject.getProperty("owners");
324
+ let ownersArr = void 0;
325
+ const checkOwners = (prop) => {
326
+ if (Node.isPropertyAssignment(prop)) {
327
+ const init = prop.getInitializer();
328
+ if (init && Node.isArrayLiteralExpression(init)) return init;
329
+ }
330
+ };
331
+ if (ownersProp) ownersArr = checkOwners(ownersProp);
332
+ if (!ownersArr) {
333
+ const metaProp = specObject.getProperty("meta");
334
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
335
+ const metaObj = metaProp.getInitializer();
336
+ if (metaObj && Node.isObjectLiteralExpression(metaObj)) {
337
+ const o = metaObj.getProperty("owners");
338
+ if (o) ownersArr = checkOwners(o);
339
+ }
340
+ }
341
+ }
342
+ if (ownersArr) {
343
+ for (const elem of ownersArr.getElements()) if (Node.isStringLiteral(elem)) {
344
+ const val = elem.getLiteralText();
345
+ if (!val.includes("@") && !val.includes("Enum") && !val.match(/[A-Z][a-zA-Z0-9_]+/)) emitRule("require-owners-format", "operation", "Owners should start with @ or use an Enum/Constant", errors, warnings, rulesConfig);
346
+ }
347
+ }
348
+ let stabilityFound = false;
349
+ if (specObject.getProperty("stability")) stabilityFound = true;
350
+ if (!stabilityFound) {
351
+ const metaProp = specObject.getProperty("meta");
352
+ if (metaProp && Node.isPropertyAssignment(metaProp)) {
353
+ const metaObj = metaProp.getInitializer();
354
+ if (Node.isObjectLiteralExpression(metaObj)) {
355
+ if (metaObj.getProperty("stability")) stabilityFound = true;
356
+ }
357
+ }
358
+ }
359
+ if (!stabilityFound) emitRule("require-stability", "operation", "Missing or invalid stability field", errors, warnings, rulesConfig);
360
+ }
361
+ }
362
+ function validateDataViewSpec(sourceFile, errors, warnings, rulesConfig) {
363
+ const defineCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "defineDataView");
364
+ let specObject;
365
+ if (defineCall) {
366
+ const args = defineCall.getArguments();
367
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) specObject = args[0];
368
+ } else specObject = getSpecObject(sourceFile, "DataViewSpec");
369
+ if (!specObject) {
370
+ errors.push("Missing defineDataView call or DataViewSpec type annotation");
371
+ return;
372
+ }
373
+ if (!specObject.getProperty("meta")) errors.push("Missing meta section");
374
+ if (!specObject.getProperty("source")) errors.push("Missing source section");
375
+ const viewProp = specObject.getProperty("view");
376
+ if (!viewProp) {
377
+ errors.push("Missing view section");
378
+ errors.push("Missing or invalid view.kind (list/table/detail/grid)");
379
+ } else if (Node.isPropertyAssignment(viewProp)) {
380
+ const viewObj = viewProp.getInitializer();
381
+ if (Node.isObjectLiteralExpression(viewObj)) {
382
+ const kindProp = viewObj.getProperty("kind");
383
+ if (!kindProp) errors.push("Missing or invalid view.kind (list/table/detail/grid)");
384
+ else if (Node.isPropertyAssignment(kindProp)) {
385
+ const init = kindProp.getInitializer();
386
+ if (init && Node.isStringLiteral(init)) {
387
+ const val = init.getLiteralText();
388
+ if (![
389
+ "list",
390
+ "table",
391
+ "detail",
392
+ "grid"
393
+ ].includes(val)) errors.push("Missing or invalid view.kind (list/table/detail/grid)");
394
+ }
395
+ }
396
+ }
397
+ }
398
+ let fieldsFound = false;
399
+ if (viewProp && Node.isPropertyAssignment(viewProp)) {
400
+ const viewObj = viewProp.getInitializer();
401
+ if (Node.isObjectLiteralExpression(viewObj)) {
402
+ if (viewObj.getProperty("fields")) fieldsFound = true;
403
+ }
404
+ }
405
+ if (!fieldsFound && specObject.getProperty("fields")) fieldsFound = true;
406
+ if (!fieldsFound) emitRule("data-view-fields", "data-view", "No fields defined for data view", errors, warnings, rulesConfig);
407
+ }
408
+ function getSpecObject(sourceFile, typeName) {
409
+ const varStmts = sourceFile.getVariableStatements();
410
+ for (const stmt of varStmts) if (stmt.isExported()) for (const decl of stmt.getDeclarations()) {
411
+ const typeNode = decl.getTypeNode();
412
+ if (typeNode && typeNode.getText().includes(typeName)) {
413
+ const init = decl.getInitializer();
414
+ if (init && Node.isObjectLiteralExpression(init)) return init;
415
+ }
416
+ }
417
+ const exportAssign = sourceFile.getExportAssignment((d) => !d.isExportEquals());
418
+ if (exportAssign) {
419
+ const expr = exportAssign.getExpression();
420
+ if (Node.isAsExpression(expr)) {
421
+ if (expr.getTypeNode()?.getText().includes(typeName)) {
422
+ const inner = expr.getExpression();
423
+ if (Node.isObjectLiteralExpression(inner)) return inner;
424
+ }
425
+ }
426
+ if (Node.isObjectLiteralExpression(expr)) return expr;
427
+ }
428
+ }
429
+ function findMainExportedObject(sourceFile) {
430
+ const varStmts = sourceFile.getVariableStatements();
431
+ for (const stmt of varStmts) if (stmt.isExported()) for (const decl of stmt.getDeclarations()) {
432
+ const init = decl.getInitializer();
433
+ if (init) {
434
+ if (Node.isObjectLiteralExpression(init)) return init;
435
+ if (Node.isCallExpression(init)) {
436
+ const args = init.getArguments();
437
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) return args[0];
438
+ }
439
+ }
440
+ }
441
+ const exportAssign = sourceFile.getExportAssignment((d) => !d.isExportEquals());
442
+ if (exportAssign) {
443
+ const expr = exportAssign.getExpression();
444
+ if (Node.isObjectLiteralExpression(expr)) return expr;
445
+ if (Node.isAsExpression(expr) && Node.isObjectLiteralExpression(expr.getExpression())) return expr.getExpression();
446
+ if (Node.isCallExpression(expr)) {
447
+ const args = expr.getArguments();
448
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) return args[0];
449
+ }
450
+ }
451
+ }
452
+
453
+ //#endregion
454
+ export { validateSpecStructure };
455
+ //# sourceMappingURL=spec-structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-structure.js","names":[],"sources":["../../../src/analysis/validate/spec-structure.ts"],"sourcesContent":["/**\n * Spec structure validation utilities.\n * Extracted from cli-contractspec/src/commands/validate/spec-checker.ts\n */\n\nimport {\n Project,\n Node,\n SyntaxKind,\n SourceFile,\n ObjectLiteralExpression,\n InitializerExpressionGetableNode,\n PropertyAssignment,\n} from 'ts-morph';\nimport type { ValidationResult } from '../../types/analysis-types';\n\nexport type { ValidationResult };\n\n/**\n * Rule severity level for lint rules.\n */\nexport type RuleSeverity = 'off' | 'warn' | 'error';\n\n/**\n * Spec kind for rule overrides mapping.\n */\nexport type SpecKind =\n | 'operation'\n | 'event'\n | 'presentation'\n | 'feature'\n | 'workflow'\n | 'data-view'\n | 'migration'\n | 'telemetry'\n | 'experiment'\n | 'app-config';\n\n/**\n * Interface for resolving rule severity.\n */\nexport interface RulesConfig {\n /**\n * Get the severity for a rule, considering spec kind overrides.\n * Returns 'warn' by default if not configured.\n */\n getRule(ruleName: string, specKind: SpecKind): RuleSeverity;\n}\n\n/**\n * Default rules config that returns 'warn' for all rules.\n */\nconst DEFAULT_RULES_CONFIG: RulesConfig = {\n getRule: () => 'warn',\n};\n\n/**\n * Validate spec structure based on source code and filename.\n */\nexport function validateSpecStructure(\n code: string,\n fileName: string,\n rulesConfig: RulesConfig = DEFAULT_RULES_CONFIG\n): ValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sourceFile = project.createSourceFile(fileName, code);\n\n // Check for required exports (any export is sufficient for validity check)\n const hasExport =\n sourceFile.getExportAssignments().length > 0 ||\n sourceFile.getVariableStatements().some((s) => s.isExported()) ||\n sourceFile.getFunctions().some((f) => f.isExported()) ||\n sourceFile.getClasses().some((c) => c.isExported()) ||\n sourceFile.getExportDeclarations().length > 0;\n\n if (!hasExport) {\n errors.push('No exported spec found');\n }\n\n // Validate operation specs\n if (\n fileName.includes('.contracts.') ||\n fileName.includes('.contract.') ||\n fileName.includes('.operations.') ||\n fileName.includes('.operation.')\n ) {\n validateOperationSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n // Validate event specs\n if (fileName.includes('.event.')) {\n validateEventSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n // Validate presentation specs\n if (fileName.includes('.presentation.')) {\n validatePresentationSpec(sourceFile, errors, warnings);\n }\n\n if (fileName.includes('.workflow.')) {\n validateWorkflowSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n if (fileName.includes('.data-view.')) {\n validateDataViewSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n if (fileName.includes('.migration.')) {\n validateMigrationSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n if (fileName.includes('.telemetry.')) {\n validateTelemetrySpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n if (fileName.includes('.experiment.')) {\n validateExperimentSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n if (fileName.includes('.app-config.')) {\n validateAppConfigSpec(sourceFile, errors, warnings, rulesConfig);\n }\n\n // Common validations\n validateCommonFields(sourceFile, fileName, errors, warnings, rulesConfig);\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Helper to emit a message based on rule severity.\n */\nfunction emitRule(\n ruleName: string,\n specKind: SpecKind,\n message: string,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n): void {\n const severity = rulesConfig.getRule(ruleName, specKind);\n if (severity === 'off') return;\n if (severity === 'error') {\n errors.push(message);\n } else {\n warnings.push(message);\n }\n}\n\n/**\n * Validate operation spec\n */\nfunction validateOperationSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n // Check for defineCommand or defineQuery calls\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const hasDefine = callExpressions.some((call) => {\n const text = call.getExpression().getText();\n return text === 'defineCommand' || text === 'defineQuery';\n });\n\n if (!hasDefine) {\n errors.push('Missing defineCommand or defineQuery call');\n }\n\n // To check fields inside defineCommand/Query({ ... }), we find the object literal passed as argument\n let specObject: ObjectLiteralExpression | undefined;\n for (const call of callExpressions) {\n const text = call.getExpression().getText();\n if (text === 'defineCommand' || text === 'defineQuery') {\n const args = call.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n break;\n }\n }\n }\n\n if (specObject && Node.isObjectLiteralExpression(specObject)) {\n // Check for required meta fields\n if (!specObject.getProperty('meta')) {\n errors.push('Missing meta section');\n }\n\n if (!specObject.getProperty('io')) {\n errors.push('Missing io section');\n }\n\n if (!specObject.getProperty('policy')) {\n errors.push('Missing policy section');\n }\n\n const metaProp = specObject.getProperty('meta');\n let hasKey = false;\n let hasVersion = false;\n\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (metaObj && Node.isObjectLiteralExpression(metaObj)) {\n if (metaObj.getProperty('key')) hasKey = true;\n if (metaObj.getProperty('version')) hasVersion = true;\n }\n }\n\n if (!hasKey) {\n // Double check if top level\n if (specObject.getProperty('key')) hasKey = true;\n }\n\n if (!hasKey) {\n errors.push('Missing or invalid key field');\n }\n\n if (!hasVersion) {\n if (specObject.getProperty('version')) hasVersion = true;\n }\n\n if (!hasVersion) {\n errors.push('Missing or invalid version field');\n }\n\n // Check for kind\n const hasExplicitKind = specObject.getProperty('kind');\n const callText = callExpressions\n .find((c) => {\n const t = c.getExpression().getText();\n return t === 'defineCommand' || t === 'defineQuery';\n })\n ?.getExpression()\n .getText();\n\n if (!callText && !hasExplicitKind) {\n errors.push(\n 'Missing kind: use defineCommand(), defineQuery(), or explicit kind field'\n );\n }\n\n // Configurable warnings\n if (!specObject.getProperty('acceptance')) {\n emitRule(\n 'require-acceptance',\n 'operation',\n 'No acceptance scenarios defined',\n errors,\n warnings,\n rulesConfig\n );\n }\n\n if (!specObject.getProperty('examples')) {\n emitRule(\n 'require-examples',\n 'operation',\n 'No examples provided',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n\n // TODO check\n const fullText = sourceFile.getFullText();\n if (fullText.includes('TODO')) {\n emitRule(\n 'no-todo',\n 'operation',\n 'Contains TODO items that need completion',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\nfunction validateTelemetrySpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n const specObject = getSpecObject(sourceFile, 'TelemetrySpec');\n\n if (!specObject) {\n errors.push('Missing TelemetrySpec type annotation');\n return;\n }\n\n if (specObject) {\n // Check meta.name\n const metaProp = specObject.getProperty('meta');\n let hasName = false;\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n if (metaObj.getProperty('name')) hasName = true;\n }\n }\n if (!hasName) {\n errors.push('TelemetrySpec.meta is required');\n }\n\n if (!specObject.getProperty('events')) {\n errors.push('TelemetrySpec must declare events');\n }\n\n const privacyProp = specObject.getProperty('privacy');\n if (!privacyProp) {\n emitRule(\n 'telemetry-privacy',\n 'telemetry',\n 'No explicit privacy classification found',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n}\n\nfunction validateExperimentSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n const specObject = getSpecObject(sourceFile, 'ExperimentSpec');\n\n if (!specObject) {\n errors.push('Missing ExperimentSpec type annotation');\n return;\n }\n\n if (!specObject.getProperty('controlVariant')) {\n errors.push('ExperimentSpec must declare controlVariant');\n }\n if (!specObject.getProperty('variants')) {\n errors.push('ExperimentSpec must declare variants');\n }\n if (!specObject.getProperty('allocation')) {\n emitRule(\n 'experiment-allocation',\n 'experiment',\n 'ExperimentSpec missing allocation configuration',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\nfunction validateAppConfigSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n // Check for defineAppConfig call first\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const defineCall = callExpressions.find(\n (c) => c.getExpression().getText() === 'defineAppConfig'\n );\n\n let specObject: ObjectLiteralExpression | undefined;\n\n if (defineCall) {\n const args = defineCall.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n }\n } else {\n specObject = getSpecObject(sourceFile, 'AppBlueprintSpec');\n }\n\n if (!specObject) {\n errors.push(\n 'Missing defineAppConfig call or AppBlueprintSpec type annotation'\n );\n return;\n }\n\n const metaProp = specObject.getProperty('meta');\n if (!metaProp) {\n errors.push('AppBlueprintSpec must define meta');\n } else if (Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n if (!metaObj.getProperty('appId')) {\n emitRule(\n 'app-config-appid',\n 'app-config',\n 'AppBlueprint meta missing appId assignment',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n }\n\n if (!specObject.getProperty('capabilities')) {\n emitRule(\n 'app-config-capabilities',\n 'app-config',\n 'App blueprint spec does not declare capabilities',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\n/**\n * Validate event spec\n */\nfunction validateEventSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const defineEventCall = callExpressions.find(\n (c) => c.getExpression().getText() === 'defineEvent'\n );\n\n if (!defineEventCall) {\n errors.push('Missing defineEvent call');\n return;\n }\n\n let specObject: ObjectLiteralExpression | undefined;\n const args = defineEventCall.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n }\n\n if (specObject && Node.isObjectLiteralExpression(specObject)) {\n const metaProp = specObject.getProperty('meta');\n let hasKey = false;\n let hasVersion = false;\n\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n const keyP = metaObj.getProperty('key');\n if (keyP && Node.isPropertyAssignment(keyP)) {\n const init = keyP.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n hasKey = true;\n }\n }\n if (metaObj.getProperty('version')) hasVersion = true;\n }\n }\n\n if (!hasKey) {\n const kp = specObject.getProperty('key');\n if (kp && Node.isPropertyAssignment(kp)) {\n const init = kp.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n hasKey = true;\n }\n }\n }\n if (!hasVersion && specObject.getProperty('version')) hasVersion = true;\n\n if (!hasKey) {\n errors.push('Missing or invalid key field');\n }\n\n if (!hasVersion) {\n errors.push('Missing or invalid version field');\n }\n\n if (!specObject.getProperty('payload')) {\n errors.push('Missing payload field');\n }\n\n let name = '';\n const getName = (\n obj: InitializerExpressionGetableNode & PropertyAssignment\n ) => {\n const init = obj.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n return init.getLiteralText();\n }\n return '';\n };\n\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n const nameP = metaObj.getProperty('name');\n if (nameP && Node.isPropertyAssignment(nameP)) {\n name = getName(nameP);\n }\n }\n }\n if (!name) {\n const nameP = specObject.getProperty('name');\n if (nameP && Node.isPropertyAssignment(nameP)) {\n name = getName(nameP);\n }\n }\n\n if (name) {\n const eventName = name.split('.').pop() ?? '';\n if (!eventName.match(/(ed|created|updated|deleted|completed)$/i)) {\n emitRule(\n 'event-past-tense',\n 'event',\n 'Event name should use past tense (e.g., \"created\", \"updated\")',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n }\n}\n\n/**\n * Validate presentation spec (V2 format)\n */\nfunction validatePresentationSpec(\n sourceFile: SourceFile,\n errors: string[],\n _warnings: string[]\n) {\n // Check for definePresentation call first\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const defineCall = callExpressions.find(\n (c) => c.getExpression().getText() === 'definePresentation'\n );\n\n let specObject: ObjectLiteralExpression | undefined;\n\n if (defineCall) {\n const args = defineCall.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n }\n } else {\n specObject = getSpecObject(sourceFile, 'PresentationSpec');\n }\n\n if (!specObject) {\n errors.push(\n 'Missing definePresentation call or PresentationSpec type annotation'\n );\n return;\n }\n\n if (!specObject.getProperty('meta')) {\n errors.push('Missing meta section');\n }\n\n const sourceProp = specObject.getProperty('source');\n if (!sourceProp) {\n errors.push('Missing source section');\n } else if (Node.isPropertyAssignment(sourceProp)) {\n const sourceObj = sourceProp.getInitializer();\n if (Node.isObjectLiteralExpression(sourceObj)) {\n const typeProp = sourceObj.getProperty('type');\n if (!typeProp) {\n errors.push('Missing or invalid source.type field');\n } else if (Node.isPropertyAssignment(typeProp)) {\n const init = typeProp.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n const val = init.getLiteralText();\n if (val !== 'component' && val !== 'blocknotejs') {\n errors.push('Missing or invalid source.type field');\n }\n }\n }\n }\n }\n\n if (!specObject.getProperty('targets')) {\n errors.push('Missing targets section');\n }\n}\n\nfunction validateWorkflowSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n // Check for defineWorkflow call first\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const defineCall = callExpressions.find(\n (c) => c.getExpression().getText() === 'defineWorkflow'\n );\n\n let specObject: ObjectLiteralExpression | undefined;\n\n if (defineCall) {\n const args = defineCall.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n }\n } else {\n specObject = getSpecObject(sourceFile, 'WorkflowSpec');\n }\n\n if (!specObject) {\n errors.push('Missing defineWorkflow call or WorkflowSpec type annotation');\n return;\n }\n\n if (!specObject.getProperty('definition')) {\n errors.push('Missing definition section');\n } else {\n const defProp = specObject.getProperty('definition');\n if (defProp && Node.isPropertyAssignment(defProp)) {\n const defObj = defProp.getInitializer();\n if (Node.isObjectLiteralExpression(defObj)) {\n if (!defObj.getProperty('steps')) {\n errors.push('Workflow must declare steps');\n }\n if (!defObj.getProperty('transitions')) {\n emitRule(\n 'workflow-transitions',\n 'workflow',\n 'No transitions declared; workflow will complete after first step.',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n }\n }\n\n let titleFound = false;\n let domainFound = false;\n\n const metaProp = specObject.getProperty('meta');\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n if (metaObj.getProperty('title')) titleFound = true;\n if (metaObj.getProperty('domain')) domainFound = true;\n }\n }\n\n if (!titleFound && specObject.getProperty('title')) titleFound = true;\n if (!domainFound && specObject.getProperty('domain')) domainFound = true;\n\n if (!titleFound) {\n warnings.push('Missing workflow title');\n }\n if (!domainFound) {\n warnings.push('Missing domain field');\n }\n\n if (sourceFile.getFullText().includes('TODO')) {\n emitRule(\n 'no-todo',\n 'workflow',\n 'Contains TODO items that need completion',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\nfunction validateMigrationSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n const specObject = getSpecObject(sourceFile, 'MigrationSpec');\n\n if (!specObject) {\n errors.push('Missing MigrationSpec type annotation');\n return;\n }\n\n const planProp = specObject.getProperty('plan');\n if (!planProp) {\n errors.push('Missing plan section');\n } else if (Node.isPropertyAssignment(planProp)) {\n const planObj = planProp.getInitializer();\n if (Node.isObjectLiteralExpression(planObj)) {\n if (!planObj.getProperty('up')) {\n errors.push('Migration must define at least one up step');\n }\n }\n }\n\n let nameFound = false;\n let versionFound = false;\n\n const metaProp = specObject.getProperty('meta');\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n if (metaObj.getProperty('name')) nameFound = true;\n if (metaObj.getProperty('version')) versionFound = true;\n }\n }\n\n if (!nameFound && specObject.getProperty('name')) nameFound = true;\n if (!versionFound && specObject.getProperty('version')) versionFound = true;\n\n if (!nameFound) {\n errors.push('Missing or invalid migration name');\n }\n\n if (!versionFound) {\n errors.push('Missing or invalid migration version');\n }\n\n if (sourceFile.getFullText().includes('TODO')) {\n emitRule(\n 'no-todo',\n 'migration',\n 'Contains TODO items that need completion',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\n/**\n * Validate common fields across all spec types\n */\nfunction validateCommonFields(\n sourceFile: SourceFile,\n fileName: string,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n const code = sourceFile.getFullText();\n\n // Skip import checks for internal library files that define the types\n const isInternalLib =\n fileName.includes('/libs/contracts/') ||\n fileName.includes('/libs/contracts-transformers/') ||\n fileName.includes('/libs/schema/');\n\n if (code.includes('SchemaModel') && !isInternalLib) {\n const imports = sourceFile.getImportDeclarations();\n const hasSchemaImport = imports.some((i) =>\n i.getModuleSpecifierValue().includes('@contractspec/lib.schema')\n );\n\n if (!hasSchemaImport) {\n errors.push(\n 'Missing import for SchemaModel from @contractspec/lib.schema'\n );\n }\n }\n\n const usesSpecTypes =\n code.includes('OperationSpec') ||\n code.includes('PresentationSpec') ||\n code.includes('EventSpec') ||\n code.includes('FeatureSpec') ||\n code.includes('WorkflowSpec') ||\n code.includes('DataViewSpec') ||\n code.includes('MigrationSpec') ||\n code.includes('TelemetrySpec') ||\n code.includes('ExperimentSpec') ||\n code.includes('AppBlueprintSpec') ||\n code.includes('defineCommand') ||\n code.includes('defineQuery') ||\n code.includes('defineEvent') ||\n code.includes('definePresentation') ||\n code.includes('defineWorkflow') ||\n code.includes('defineDataView') ||\n code.includes('defineAppConfig') ||\n code.includes('defineFeature') || // Assuming features are validated elsewhere\n code.includes('defineExperiment') ||\n code.includes('defineTelemetry') ||\n code.includes('defineMigration');\n\n if (usesSpecTypes && !isInternalLib) {\n const imports = sourceFile.getImportDeclarations();\n const hasContractsImport = imports.some((i) =>\n i.getModuleSpecifierValue().includes('@contractspec/lib.contracts')\n );\n\n if (!hasContractsImport) {\n errors.push('Missing import from @contractspec/lib.contracts');\n }\n }\n\n const specObject = findMainExportedObject(sourceFile);\n\n if (specObject && Node.isObjectLiteralExpression(specObject)) {\n // Check owners format\n const ownersProp = specObject.getProperty('owners');\n // If owners in meta?\n let ownersArr = undefined;\n\n const checkOwners = (prop: Node) => {\n if (Node.isPropertyAssignment(prop)) {\n const init = prop.getInitializer();\n if (init && Node.isArrayLiteralExpression(init)) {\n return init;\n }\n }\n return undefined;\n };\n\n if (ownersProp) ownersArr = checkOwners(ownersProp);\n\n if (!ownersArr) {\n // Check meta.owners\n const metaProp = specObject.getProperty('meta');\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (metaObj && Node.isObjectLiteralExpression(metaObj)) {\n const o = metaObj.getProperty('owners');\n if (o) ownersArr = checkOwners(o);\n }\n }\n }\n\n if (ownersArr) {\n for (const elem of ownersArr.getElements()) {\n if (Node.isStringLiteral(elem)) {\n const val = elem.getLiteralText();\n if (\n !val.includes('@') &&\n !val.includes('Enum') &&\n !val.match(/[A-Z][a-zA-Z0-9_]+/)\n ) {\n emitRule(\n 'require-owners-format',\n 'operation',\n 'Owners should start with @ or use an Enum/Constant',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n }\n }\n\n // Check for stability\n // Similar logic: top level or meta\n let stabilityFound = false;\n const stabilityProp = specObject.getProperty('stability');\n if (stabilityProp) stabilityFound = true;\n\n if (!stabilityFound) {\n const metaProp = specObject.getProperty('meta');\n if (metaProp && Node.isPropertyAssignment(metaProp)) {\n const metaObj = metaProp.getInitializer();\n if (Node.isObjectLiteralExpression(metaObj)) {\n if (metaObj.getProperty('stability')) stabilityFound = true;\n }\n }\n }\n\n if (!stabilityFound) {\n emitRule(\n 'require-stability',\n 'operation',\n 'Missing or invalid stability field',\n errors,\n warnings,\n rulesConfig\n );\n }\n }\n}\n\nfunction validateDataViewSpec(\n sourceFile: SourceFile,\n errors: string[],\n warnings: string[],\n rulesConfig: RulesConfig\n) {\n // Check for defineDataView call first\n const callExpressions = sourceFile.getDescendantsOfKind(\n SyntaxKind.CallExpression\n );\n const defineCall = callExpressions.find(\n (c) => c.getExpression().getText() === 'defineDataView'\n );\n\n let specObject: ObjectLiteralExpression | undefined;\n\n if (defineCall) {\n const args = defineCall.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n specObject = args[0];\n }\n } else {\n specObject = getSpecObject(sourceFile, 'DataViewSpec');\n }\n\n if (!specObject) {\n errors.push('Missing defineDataView call or DataViewSpec type annotation');\n return;\n }\n if (!specObject.getProperty('meta')) {\n errors.push('Missing meta section');\n }\n if (!specObject.getProperty('source')) {\n errors.push('Missing source section');\n }\n\n const viewProp = specObject.getProperty('view');\n if (!viewProp) {\n errors.push('Missing view section');\n // Ensure missing kind warning is also triggered for strict validation\n errors.push('Missing or invalid view.kind (list/table/detail/grid)');\n } else if (Node.isPropertyAssignment(viewProp)) {\n const viewObj = viewProp.getInitializer();\n if (Node.isObjectLiteralExpression(viewObj)) {\n const kindProp = viewObj.getProperty('kind');\n if (!kindProp) {\n errors.push('Missing or invalid view.kind (list/table/detail/grid)');\n } else if (Node.isPropertyAssignment(kindProp)) {\n const init = kindProp.getInitializer();\n if (init && Node.isStringLiteral(init)) {\n const val = init.getLiteralText();\n if (!['list', 'table', 'detail', 'grid'].includes(val)) {\n errors.push(\n 'Missing or invalid view.kind (list/table/detail/grid)'\n );\n }\n }\n }\n }\n }\n\n let fieldsFound = false;\n if (viewProp && Node.isPropertyAssignment(viewProp)) {\n const viewObj = viewProp.getInitializer();\n if (Node.isObjectLiteralExpression(viewObj)) {\n if (viewObj.getProperty('fields')) fieldsFound = true;\n }\n }\n if (!fieldsFound && specObject.getProperty('fields')) fieldsFound = true;\n\n if (!fieldsFound) {\n emitRule(\n 'data-view-fields',\n 'data-view',\n 'No fields defined for data view',\n errors,\n warnings,\n rulesConfig\n );\n }\n}\n\n// Helper to find spec object with specific type annotation\nfunction getSpecObject(\n sourceFile: SourceFile,\n typeName: string\n): ObjectLiteralExpression | undefined {\n const varStmts = sourceFile.getVariableStatements();\n for (const stmt of varStmts) {\n if (stmt.isExported()) {\n for (const decl of stmt.getDeclarations()) {\n const typeNode = decl.getTypeNode();\n if (typeNode && typeNode.getText().includes(typeName)) {\n const init = decl.getInitializer();\n if (init && Node.isObjectLiteralExpression(init)) {\n return init;\n }\n }\n }\n }\n }\n const exportAssign = sourceFile.getExportAssignment(\n (d) => !d.isExportEquals()\n );\n if (exportAssign) {\n const expr = exportAssign.getExpression();\n if (Node.isAsExpression(expr)) {\n if (expr.getTypeNode()?.getText().includes(typeName)) {\n const inner = expr.getExpression();\n if (Node.isObjectLiteralExpression(inner)) return inner;\n }\n }\n if (Node.isObjectLiteralExpression(expr)) {\n return expr;\n }\n }\n return undefined;\n}\n\nfunction findMainExportedObject(\n sourceFile: SourceFile\n): ObjectLiteralExpression | undefined {\n // Return any object that looks like it could be the main spec\n const varStmts = sourceFile.getVariableStatements();\n for (const stmt of varStmts) {\n if (stmt.isExported()) {\n for (const decl of stmt.getDeclarations()) {\n const init = decl.getInitializer();\n if (init) {\n if (Node.isObjectLiteralExpression(init)) return init;\n if (Node.isCallExpression(init)) {\n const args = init.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0]))\n return args[0];\n }\n }\n }\n }\n }\n const exportAssign = sourceFile.getExportAssignment(\n (d) => !d.isExportEquals()\n );\n if (exportAssign) {\n const expr = exportAssign.getExpression();\n if (Node.isObjectLiteralExpression(expr)) return expr;\n if (\n Node.isAsExpression(expr) &&\n Node.isObjectLiteralExpression(expr.getExpression())\n )\n return expr.getExpression() as ObjectLiteralExpression;\n if (Node.isCallExpression(expr)) {\n const args = expr.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0]))\n return args[0];\n }\n }\n return undefined;\n}\n"],"mappings":"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"}