@contractspec/module.workspace 1.44.0

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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/ai/code-generation.d.ts +28 -0
  4. package/dist/ai/code-generation.d.ts.map +1 -0
  5. package/dist/ai/code-generation.js +138 -0
  6. package/dist/ai/code-generation.js.map +1 -0
  7. package/dist/ai/spec-creation.d.ts +27 -0
  8. package/dist/ai/spec-creation.d.ts.map +1 -0
  9. package/dist/ai/spec-creation.js +102 -0
  10. package/dist/ai/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/feature-scan.d.ts +15 -0
  28. package/dist/analysis/feature-scan.d.ts.map +1 -0
  29. package/dist/analysis/feature-scan.js +152 -0
  30. package/dist/analysis/feature-scan.js.map +1 -0
  31. package/dist/analysis/grouping.d.ts +79 -0
  32. package/dist/analysis/grouping.d.ts.map +1 -0
  33. package/dist/analysis/grouping.js +115 -0
  34. package/dist/analysis/grouping.js.map +1 -0
  35. package/dist/analysis/impact/classifier.d.ts +19 -0
  36. package/dist/analysis/impact/classifier.d.ts.map +1 -0
  37. package/dist/analysis/impact/classifier.js +135 -0
  38. package/dist/analysis/impact/classifier.js.map +1 -0
  39. package/dist/analysis/impact/index.js +2 -0
  40. package/dist/analysis/impact/rules.d.ts +35 -0
  41. package/dist/analysis/impact/rules.d.ts.map +1 -0
  42. package/dist/analysis/impact/rules.js +154 -0
  43. package/dist/analysis/impact/rules.js.map +1 -0
  44. package/dist/analysis/impact/types.d.ts +95 -0
  45. package/dist/analysis/impact/types.d.ts.map +1 -0
  46. package/dist/analysis/index.js +14 -0
  47. package/dist/analysis/snapshot/index.js +2 -0
  48. package/dist/analysis/snapshot/normalizer.d.ts +36 -0
  49. package/dist/analysis/snapshot/normalizer.d.ts.map +1 -0
  50. package/dist/analysis/snapshot/normalizer.js +66 -0
  51. package/dist/analysis/snapshot/normalizer.js.map +1 -0
  52. package/dist/analysis/snapshot/snapshot.d.ts +18 -0
  53. package/dist/analysis/snapshot/snapshot.d.ts.map +1 -0
  54. package/dist/analysis/snapshot/snapshot.js +163 -0
  55. package/dist/analysis/snapshot/snapshot.js.map +1 -0
  56. package/dist/analysis/snapshot/types.d.ts +80 -0
  57. package/dist/analysis/snapshot/types.d.ts.map +1 -0
  58. package/dist/analysis/spec-scan.d.ts +34 -0
  59. package/dist/analysis/spec-scan.d.ts.map +1 -0
  60. package/dist/analysis/spec-scan.js +349 -0
  61. package/dist/analysis/spec-scan.js.map +1 -0
  62. package/dist/analysis/validate/spec-structure.d.ts +29 -0
  63. package/dist/analysis/validate/spec-structure.d.ts.map +1 -0
  64. package/dist/analysis/validate/spec-structure.js +139 -0
  65. package/dist/analysis/validate/spec-structure.js.map +1 -0
  66. package/dist/formatter.d.ts +42 -0
  67. package/dist/formatter.d.ts.map +1 -0
  68. package/dist/formatter.js +163 -0
  69. package/dist/formatter.js.map +1 -0
  70. package/dist/index.d.ts +35 -0
  71. package/dist/index.js +33 -0
  72. package/dist/templates/app-config.d.ts +7 -0
  73. package/dist/templates/app-config.d.ts.map +1 -0
  74. package/dist/templates/app-config.js +106 -0
  75. package/dist/templates/app-config.js.map +1 -0
  76. package/dist/templates/data-view.d.ts +7 -0
  77. package/dist/templates/data-view.d.ts.map +1 -0
  78. package/dist/templates/data-view.js +69 -0
  79. package/dist/templates/data-view.js.map +1 -0
  80. package/dist/templates/event.d.ts +11 -0
  81. package/dist/templates/event.d.ts.map +1 -0
  82. package/dist/templates/event.js +41 -0
  83. package/dist/templates/event.js.map +1 -0
  84. package/dist/templates/experiment.d.ts +7 -0
  85. package/dist/templates/experiment.d.ts.map +1 -0
  86. package/dist/templates/experiment.js +88 -0
  87. package/dist/templates/experiment.js.map +1 -0
  88. package/dist/templates/handler.d.ts +20 -0
  89. package/dist/templates/handler.d.ts.map +1 -0
  90. package/dist/templates/handler.js +96 -0
  91. package/dist/templates/handler.js.map +1 -0
  92. package/dist/templates/integration-utils.js +105 -0
  93. package/dist/templates/integration-utils.js.map +1 -0
  94. package/dist/templates/integration.d.ts +7 -0
  95. package/dist/templates/integration.d.ts.map +1 -0
  96. package/dist/templates/integration.js +63 -0
  97. package/dist/templates/integration.js.map +1 -0
  98. package/dist/templates/knowledge.d.ts +7 -0
  99. package/dist/templates/knowledge.d.ts.map +1 -0
  100. package/dist/templates/knowledge.js +69 -0
  101. package/dist/templates/knowledge.js.map +1 -0
  102. package/dist/templates/migration.d.ts +7 -0
  103. package/dist/templates/migration.d.ts.map +1 -0
  104. package/dist/templates/migration.js +61 -0
  105. package/dist/templates/migration.js.map +1 -0
  106. package/dist/templates/operation.d.ts +11 -0
  107. package/dist/templates/operation.d.ts.map +1 -0
  108. package/dist/templates/operation.js +101 -0
  109. package/dist/templates/operation.js.map +1 -0
  110. package/dist/templates/presentation.d.ts +11 -0
  111. package/dist/templates/presentation.d.ts.map +1 -0
  112. package/dist/templates/presentation.js +79 -0
  113. package/dist/templates/presentation.js.map +1 -0
  114. package/dist/templates/telemetry.d.ts +7 -0
  115. package/dist/templates/telemetry.d.ts.map +1 -0
  116. package/dist/templates/telemetry.js +90 -0
  117. package/dist/templates/telemetry.js.map +1 -0
  118. package/dist/templates/utils.d.ts +27 -0
  119. package/dist/templates/utils.d.ts.map +1 -0
  120. package/dist/templates/utils.js +39 -0
  121. package/dist/templates/utils.js.map +1 -0
  122. package/dist/templates/workflow-runner.d.ts +16 -0
  123. package/dist/templates/workflow-runner.d.ts.map +1 -0
  124. package/dist/templates/workflow-runner.js +49 -0
  125. package/dist/templates/workflow-runner.js.map +1 -0
  126. package/dist/templates/workflow.d.ts +11 -0
  127. package/dist/templates/workflow.d.ts.map +1 -0
  128. package/dist/templates/workflow.js +68 -0
  129. package/dist/templates/workflow.js.map +1 -0
  130. package/dist/types/analysis-types.d.ts +126 -0
  131. package/dist/types/analysis-types.d.ts.map +1 -0
  132. package/dist/types/generation-types.d.ts +84 -0
  133. package/dist/types/generation-types.d.ts.map +1 -0
  134. package/dist/types/generation-types.js +21 -0
  135. package/dist/types/generation-types.js.map +1 -0
  136. package/dist/types/spec-types.d.ts +345 -0
  137. package/dist/types/spec-types.d.ts.map +1 -0
  138. package/package.json +55 -0
@@ -0,0 +1,106 @@
1
+ import { toPascalCase } from "./utils.js";
2
+
3
+ //#region src/templates/app-config.ts
4
+ function generateAppBlueprintSpec(data) {
5
+ const exportName = toPascalCase(data.name.split(".").pop() ?? "App") + "AppConfig";
6
+ const capabilitiesSection = buildCapabilitiesSection(data);
7
+ const featuresSection = buildFeaturesSection(data);
8
+ const dataViewsSection = buildMappingSection("dataViews", data.dataViews);
9
+ const workflowsSection = buildMappingSection("workflows", data.workflows);
10
+ const policiesSection = buildPolicySection(data);
11
+ const themeSection = buildThemeSection(data);
12
+ const telemetrySection = buildTelemetrySection(data);
13
+ const experimentsSection = buildExperimentsSection(data);
14
+ const flagsSection = buildFeatureFlagsSection(data);
15
+ const routesSection = buildRoutesSection(data);
16
+ const notesSection = data.notes ? ` notes: '${escapeString(data.notes)}',\n` : "";
17
+ return `import type { AppBlueprintSpec } from '@contractspec/lib.contracts/app-config';
18
+
19
+ export const ${exportName}: AppBlueprintSpec = {
20
+ meta: {
21
+ key: '${escapeString(data.name)}',
22
+ version: ${data.version},
23
+ title: '${escapeString(data.title)}',
24
+ description: '${escapeString(data.description)}',
25
+ domain: '${escapeString(data.domain)}',
26
+ owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(", ")}],
27
+ tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(", ")}],
28
+ stability: '${data.stability}',
29
+ appId: '${escapeString(data.appId)}',
30
+ },
31
+ ${capabilitiesSection}${featuresSection}${dataViewsSection}${workflowsSection}${policiesSection}${themeSection}${telemetrySection}${experimentsSection}${flagsSection}${routesSection}${notesSection}};\n`;
32
+ }
33
+ function buildCapabilitiesSection(data) {
34
+ if (data.capabilitiesEnabled.length === 0 && data.capabilitiesDisabled.length === 0) return "";
35
+ return ` capabilities: {\n${data.capabilitiesEnabled.length > 0 ? ` enabled: [${data.capabilitiesEnabled.map((key) => formatCapabilityRef(key)).join(", ")}],\n` : ""}${data.capabilitiesDisabled.length > 0 ? ` disabled: [${data.capabilitiesDisabled.map((key) => formatCapabilityRef(key)).join(", ")}],\n` : ""} },\n`;
36
+ }
37
+ function buildFeaturesSection(data) {
38
+ if (data.featureIncludes.length === 0 && data.featureExcludes.length === 0) return "";
39
+ return ` features: {\n${data.featureIncludes.length > 0 ? ` include: [${data.featureIncludes.map((key) => `{ key: '${escapeString(key)}' }`).join(", ")}],\n` : ""}${data.featureExcludes.length > 0 ? ` exclude: [${data.featureExcludes.map((key) => `{ key: '${escapeString(key)}' }`).join(", ")}],\n` : ""} },\n`;
40
+ }
41
+ function buildMappingSection(prop, mappings) {
42
+ if (mappings.length === 0) return "";
43
+ return ` ${prop}: {\n${mappings.map((mapping) => ` ${mapping.slot}: {
44
+ name: '${escapeString(mapping.name)}',
45
+ ${typeof mapping.version === "number" ? `version: ${mapping.version},` : ""}
46
+ }`).join(",\n")}\n },\n`;
47
+ }
48
+ function buildPolicySection(data) {
49
+ if (data.policyRefs.length === 0) return "";
50
+ return ` policies: [\n${data.policyRefs.map((policy) => ` {
51
+ name: '${escapeString(policy.name)}'${typeof policy.version === "number" ? `,\n version: ${policy.version}` : ""}
52
+ }`).join(",\n")}\n ],\n`;
53
+ }
54
+ function buildThemeSection(data) {
55
+ if (!data.theme) return "";
56
+ return ` theme: {\n${` primary: { name: '${escapeString(data.theme.name)}', version: ${data.theme.version} },\n`}${data.themeFallbacks.length > 0 ? ` fallbacks: [${data.themeFallbacks.map((theme) => `{ name: '${escapeString(theme.name)}', version: ${theme.version} }`).join(", ")}],\n` : ""} },\n`;
57
+ }
58
+ function buildTelemetrySection(data) {
59
+ if (!data.telemetry) return "";
60
+ return ` telemetry: {
61
+ spec: {
62
+ name: '${escapeString(data.telemetry.name)}'${typeof data.telemetry.version === "number" ? `,\n version: ${data.telemetry.version}` : ""}
63
+ },
64
+ },\n`;
65
+ }
66
+ function buildExperimentsSection(data) {
67
+ if (data.activeExperiments.length === 0 && data.pausedExperiments.length === 0) return "";
68
+ return ` experiments: {\n${data.activeExperiments.length > 0 ? ` active: [${data.activeExperiments.map((exp) => formatExperimentRef(exp)).join(", ")}],\n` : ""}${data.pausedExperiments.length > 0 ? ` paused: [${data.pausedExperiments.map((exp) => formatExperimentRef(exp)).join(", ")}],\n` : ""} },\n`;
69
+ }
70
+ function buildFeatureFlagsSection(data) {
71
+ if (data.featureFlags.length === 0) return "";
72
+ return ` featureFlags: [\n${data.featureFlags.map((flag) => ` {
73
+ key: '${escapeString(flag.key)}',
74
+ enabled: ${flag.enabled},
75
+ ${flag.variant ? `variant: '${escapeString(flag.variant)}',` : ""}
76
+ ${flag.description ? `description: '${escapeString(flag.description)}',` : ""}
77
+ }`).join(",\n")}\n ],\n`;
78
+ }
79
+ function buildRoutesSection(data) {
80
+ if (data.routes.length === 0) return "";
81
+ return ` routes: [\n${data.routes.map((route) => {
82
+ return ` { ${[
83
+ `path: '${escapeString(route.path)}'`,
84
+ route.label ? `label: '${escapeString(route.label)}'` : null,
85
+ route.dataView ? `dataView: '${escapeString(route.dataView)}'` : null,
86
+ route.workflow ? `workflow: '${escapeString(route.workflow)}'` : null,
87
+ route.guardName ? `guard: { name: '${escapeString(route.guardName)}'${typeof route.guardVersion === "number" ? `, version: ${route.guardVersion}` : ""} }` : null,
88
+ route.featureFlag ? `featureFlag: '${escapeString(route.featureFlag)}'` : null,
89
+ route.experimentName ? `experiment: { name: '${escapeString(route.experimentName)}'${typeof route.experimentVersion === "number" ? `, version: ${route.experimentVersion}` : ""} }` : null
90
+ ].filter(Boolean).join(", ")} }`;
91
+ }).join(",\n")}\n ],\n`;
92
+ }
93
+ function formatCapabilityRef(key) {
94
+ return `{ key: '${escapeString(key)}' }`;
95
+ }
96
+ function formatExperimentRef(exp) {
97
+ const version = typeof exp.version === "number" ? `, version: ${exp.version}` : "";
98
+ return `{ name: '${escapeString(exp.name)}'${version} }`;
99
+ }
100
+ function escapeString(value) {
101
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
102
+ }
103
+
104
+ //#endregion
105
+ export { generateAppBlueprintSpec };
106
+ //# sourceMappingURL=app-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config.js","names":[],"sources":["../../src/templates/app-config.ts"],"sourcesContent":["import type { AppBlueprintSpecData } from '../types/spec-types';\nimport { toPascalCase } from './utils';\n\nexport function generateAppBlueprintSpec(data: AppBlueprintSpecData): string {\n const exportName =\n toPascalCase(data.name.split('.').pop() ?? 'App') + 'AppConfig';\n\n const capabilitiesSection = buildCapabilitiesSection(data);\n const featuresSection = buildFeaturesSection(data);\n const dataViewsSection = buildMappingSection('dataViews', data.dataViews);\n const workflowsSection = buildMappingSection('workflows', data.workflows);\n const policiesSection = buildPolicySection(data);\n const themeSection = buildThemeSection(data);\n const telemetrySection = buildTelemetrySection(data);\n const experimentsSection = buildExperimentsSection(data);\n const flagsSection = buildFeatureFlagsSection(data);\n const routesSection = buildRoutesSection(data);\n const notesSection = data.notes\n ? ` notes: '${escapeString(data.notes)}',\\n`\n : '';\n\n return `import type { AppBlueprintSpec } from '@contractspec/lib.contracts/app-config';\n\nexport const ${exportName}: AppBlueprintSpec = {\n meta: {\n key: '${escapeString(data.name)}',\n version: ${data.version},\n title: '${escapeString(data.title)}',\n description: '${escapeString(data.description)}',\n domain: '${escapeString(data.domain)}',\n owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(', ')}],\n stability: '${data.stability}',\n appId: '${escapeString(data.appId)}',\n },\n${capabilitiesSection}${featuresSection}${dataViewsSection}${workflowsSection}${policiesSection}${themeSection}${telemetrySection}${experimentsSection}${flagsSection}${routesSection}${notesSection}};\\n`;\n}\n\nfunction buildCapabilitiesSection(data: AppBlueprintSpecData): string {\n if (\n data.capabilitiesEnabled.length === 0 &&\n data.capabilitiesDisabled.length === 0\n ) {\n return '';\n }\n const enabled =\n data.capabilitiesEnabled.length > 0\n ? ` enabled: [${data.capabilitiesEnabled.map((key) => formatCapabilityRef(key)).join(', ')}],\\n`\n : '';\n const disabled =\n data.capabilitiesDisabled.length > 0\n ? ` disabled: [${data.capabilitiesDisabled.map((key) => formatCapabilityRef(key)).join(', ')}],\\n`\n : '';\n return ` capabilities: {\\n${enabled}${disabled} },\\n`;\n}\n\nfunction buildFeaturesSection(data: AppBlueprintSpecData): string {\n if (data.featureIncludes.length === 0 && data.featureExcludes.length === 0) {\n return '';\n }\n const include =\n data.featureIncludes.length > 0\n ? ` include: [${data.featureIncludes.map((key) => `{ key: '${escapeString(key)}' }`).join(', ')}],\\n`\n : '';\n const exclude =\n data.featureExcludes.length > 0\n ? ` exclude: [${data.featureExcludes.map((key) => `{ key: '${escapeString(key)}' }`).join(', ')}],\\n`\n : '';\n return ` features: {\\n${include}${exclude} },\\n`;\n}\n\nfunction buildMappingSection(\n prop: 'dataViews' | 'workflows',\n mappings: AppBlueprintSpecData['dataViews']\n): string {\n if (mappings.length === 0) return '';\n const body = mappings\n .map(\n (mapping) => ` ${mapping.slot}: {\n name: '${escapeString(mapping.name)}',\n ${typeof mapping.version === 'number' ? `version: ${mapping.version},` : ''}\n }`\n )\n .join(',\\n');\n return ` ${prop}: {\\n${body}\\n },\\n`;\n}\n\nfunction buildPolicySection(data: AppBlueprintSpecData): string {\n if (data.policyRefs.length === 0) return '';\n const entries = data.policyRefs\n .map(\n (policy) => ` {\n name: '${escapeString(policy.name)}'${typeof policy.version === 'number' ? `,\\n version: ${policy.version}` : ''}\n }`\n )\n .join(',\\n');\n return ` policies: [\\n${entries}\\n ],\\n`;\n}\n\nfunction buildThemeSection(data: AppBlueprintSpecData): string {\n if (!data.theme) return '';\n const primary = ` primary: { name: '${escapeString(data.theme.name)}', version: ${data.theme.version} },\\n`;\n const fallbacks =\n data.themeFallbacks.length > 0\n ? ` fallbacks: [${data.themeFallbacks\n .map(\n (theme) =>\n `{ name: '${escapeString(theme.name)}', version: ${theme.version} }`\n )\n .join(', ')}],\\n`\n : '';\n return ` theme: {\\n${primary}${fallbacks} },\\n`;\n}\n\nfunction buildTelemetrySection(data: AppBlueprintSpecData): string {\n if (!data.telemetry) return '';\n return ` telemetry: {\n spec: {\n name: '${escapeString(data.telemetry.name)}'${\n typeof data.telemetry.version === 'number'\n ? `,\\n version: ${data.telemetry.version}`\n : ''\n }\n },\n },\\n`;\n}\n\nfunction buildExperimentsSection(data: AppBlueprintSpecData): string {\n if (\n data.activeExperiments.length === 0 &&\n data.pausedExperiments.length === 0\n ) {\n return '';\n }\n const active =\n data.activeExperiments.length > 0\n ? ` active: [${data.activeExperiments.map((exp) => formatExperimentRef(exp)).join(', ')}],\\n`\n : '';\n const paused =\n data.pausedExperiments.length > 0\n ? ` paused: [${data.pausedExperiments.map((exp) => formatExperimentRef(exp)).join(', ')}],\\n`\n : '';\n return ` experiments: {\\n${active}${paused} },\\n`;\n}\n\nfunction buildFeatureFlagsSection(data: AppBlueprintSpecData): string {\n if (data.featureFlags.length === 0) return '';\n const flags = data.featureFlags\n .map(\n (flag) => ` {\n key: '${escapeString(flag.key)}',\n enabled: ${flag.enabled},\n ${flag.variant ? `variant: '${escapeString(flag.variant)}',` : ''}\n ${flag.description ? `description: '${escapeString(flag.description)}',` : ''}\n }`\n )\n .join(',\\n');\n return ` featureFlags: [\\n${flags}\\n ],\\n`;\n}\n\nfunction buildRoutesSection(data: AppBlueprintSpecData): string {\n if (data.routes.length === 0) return '';\n const routes = data.routes\n .map((route) => {\n const entries = [\n `path: '${escapeString(route.path)}'`,\n route.label ? `label: '${escapeString(route.label)}'` : null,\n route.dataView ? `dataView: '${escapeString(route.dataView)}'` : null,\n route.workflow ? `workflow: '${escapeString(route.workflow)}'` : null,\n route.guardName\n ? `guard: { name: '${escapeString(route.guardName)}'${\n typeof route.guardVersion === 'number'\n ? `, version: ${route.guardVersion}`\n : ''\n } }`\n : null,\n route.featureFlag\n ? `featureFlag: '${escapeString(route.featureFlag)}'`\n : null,\n route.experimentName\n ? `experiment: { name: '${escapeString(route.experimentName)}'${\n typeof route.experimentVersion === 'number'\n ? `, version: ${route.experimentVersion}`\n : ''\n } }`\n : null,\n ].filter(Boolean);\n return ` { ${entries.join(', ')} }`;\n })\n .join(',\\n');\n return ` routes: [\\n${routes}\\n ],\\n`;\n}\n\nfunction formatCapabilityRef(key: string): string {\n return `{ key: '${escapeString(key)}' }`;\n}\n\nfunction formatExperimentRef(exp: { name: string; version?: number }): string {\n const version =\n typeof exp.version === 'number' ? `, version: ${exp.version}` : '';\n return `{ name: '${escapeString(exp.name)}'${version} }`;\n}\n\nfunction escapeString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { DataViewSpecData } from "../types/spec-types.js";
2
+
3
+ //#region src/templates/data-view.d.ts
4
+ declare function generateDataViewSpec(data: DataViewSpecData): string;
5
+ //#endregion
6
+ export { generateDataViewSpec };
7
+ //# sourceMappingURL=data-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-view.d.ts","names":[],"sources":["../../src/templates/data-view.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,oBAAA,OAA2B"}
@@ -0,0 +1,69 @@
1
+ import { escapeString, toPascalCase } from "./utils.js";
2
+
3
+ //#region src/templates/data-view.ts
4
+ function generateDataViewSpec(data) {
5
+ const viewVarName = toPascalCase(data.name.split(".").pop() ?? "DataView") + "DataView";
6
+ const fields = data.fields.map((field) => ` {
7
+ key: '${escapeString(field.key)}',
8
+ label: '${escape(field.label)}',
9
+ dataPath: '${escapeString(field.dataPath)}',
10
+ ${field.format ? `format: '${escapeString(field.format)}',` : ""}
11
+ ${field.sortable ? "sortable: true," : ""}
12
+ ${field.filterable ? "filterable: true," : ""}
13
+ }`).join(",\n");
14
+ const secondaryFields = data.secondaryFields?.length ? `secondaryFields: [${data.secondaryFields.map((key) => `'${escapeString(key)}'`).join(", ")}],` : "";
15
+ const itemOperation = data.itemOperation ? `item: { name: '${escapeString(data.itemOperation.name)}', version: ${data.itemOperation.version} },` : "";
16
+ return `import type { DataViewSpec } from '@contractspec/lib.contracts/data-views';
17
+
18
+ export const ${viewVarName}: DataViewSpec = {
19
+ meta: {
20
+ key: '${escapeString(data.name)}',
21
+ version: ${data.version},
22
+ entity: '${escapeString(data.entity)}',
23
+ title: '${escape(data.title)}',
24
+ description: '${escape(data.description || "Describe the purpose of this data view.")}',
25
+ domain: '${escape(data.domain || data.entity)}',
26
+ owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(", ")}],
27
+ tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(", ")}],
28
+ stability: '${data.stability}',
29
+ },
30
+ source: {
31
+ primary: {
32
+ name: '${escapeString(data.primaryOperation.name)}',
33
+ version: ${data.primaryOperation.version},
34
+ },
35
+ ${itemOperation}
36
+ refreshEvents: [
37
+ // { name: 'entity.updated', version: 1 },
38
+ ],
39
+ },
40
+ view: {
41
+ kind: '${data.kind}',
42
+ fields: [
43
+ ${fields}
44
+ ],
45
+ ${data.primaryField ? `primaryField: '${escapeString(data.primaryField)}',` : ""}
46
+ ${secondaryFields}
47
+ filters: [
48
+ // Example filter:
49
+ // { key: 'search', label: 'Search', field: 'fullName', type: 'search' },
50
+ ],
51
+ actions: [
52
+ // Example action:
53
+ // { key: 'open', label: 'Open', kind: 'navigation' },
54
+ ],
55
+ },
56
+ states: {
57
+ // empty: { name: 'app.data.empty', version: 1 },
58
+ // error: { name: 'app.data.error', version: 1 },
59
+ },
60
+ };
61
+ `;
62
+ }
63
+ function escape(value) {
64
+ return value.replace(/'/g, "\\'");
65
+ }
66
+
67
+ //#endregion
68
+ export { generateDataViewSpec };
69
+ //# sourceMappingURL=data-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-view.js","names":[],"sources":["../../src/templates/data-view.ts"],"sourcesContent":["import type { DataViewSpecData } from '../types/spec-types';\nimport { toPascalCase, escapeString } from './utils';\n\nexport function generateDataViewSpec(data: DataViewSpecData): string {\n const viewVarName =\n toPascalCase(data.name.split('.').pop() ?? 'DataView') + 'DataView';\n\n const fields = data.fields\n .map(\n (field) => ` {\n key: '${escapeString(field.key)}',\n label: '${escape(field.label)}',\n dataPath: '${escapeString(field.dataPath)}',\n ${field.format ? `format: '${escapeString(field.format)}',` : ''}\n ${field.sortable ? 'sortable: true,' : ''}\n ${field.filterable ? 'filterable: true,' : ''}\n }`\n )\n .join(',\\n');\n\n const secondaryFields = data.secondaryFields?.length\n ? `secondaryFields: [${data.secondaryFields\n .map((key) => `'${escapeString(key)}'`)\n .join(', ')}],`\n : '';\n\n const itemOperation = data.itemOperation\n ? `item: { name: '${escapeString(data.itemOperation.name)}', version: ${data.itemOperation.version} },`\n : '';\n\n return `import type { DataViewSpec } from '@contractspec/lib.contracts/data-views';\n\nexport const ${viewVarName}: DataViewSpec = {\n meta: {\n key: '${escapeString(data.name)}',\n version: ${data.version},\n entity: '${escapeString(data.entity)}',\n title: '${escape(data.title)}',\n description: '${escape(\n data.description || 'Describe the purpose of this data view.'\n )}',\n domain: '${escape(data.domain || data.entity)}',\n owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(', ')}],\n stability: '${data.stability}',\n },\n source: {\n primary: {\n name: '${escapeString(data.primaryOperation.name)}',\n version: ${data.primaryOperation.version},\n },\n ${itemOperation}\n refreshEvents: [\n // { name: 'entity.updated', version: 1 },\n ],\n },\n view: {\n kind: '${data.kind}',\n fields: [\n${fields}\n ],\n ${data.primaryField ? `primaryField: '${escapeString(data.primaryField)}',` : ''}\n ${secondaryFields}\n filters: [\n // Example filter:\n // { key: 'search', label: 'Search', field: 'fullName', type: 'search' },\n ],\n actions: [\n // Example action:\n // { key: 'open', label: 'Open', kind: 'navigation' },\n ],\n },\n states: {\n // empty: { name: 'app.data.empty', version: 1 },\n // error: { name: 'app.data.error', version: 1 },\n },\n};\n`;\n}\n\nfunction escape(value: string): string {\n return value.replace(/'/g, \"\\\\'\");\n}\n"],"mappings":";;;AAGA,SAAgB,qBAAqB,MAAgC;CACnE,MAAM,cACJ,aAAa,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,WAAW,GAAG;CAE3D,MAAM,SAAS,KAAK,OACjB,KACE,UAAU;gBACD,aAAa,MAAM,IAAI,CAAC;kBACtB,OAAO,MAAM,MAAM,CAAC;qBACjB,aAAa,MAAM,SAAS,CAAC;UACxC,MAAM,SAAS,YAAY,aAAa,MAAM,OAAO,CAAC,MAAM,GAAG;UAC/D,MAAM,WAAW,oBAAoB,GAAG;UACxC,MAAM,aAAa,sBAAsB,GAAG;SAEjD,CACA,KAAK,MAAM;CAEd,MAAM,kBAAkB,KAAK,iBAAiB,SAC1C,qBAAqB,KAAK,gBACvB,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CACtC,KAAK,KAAK,CAAC,MACd;CAEJ,MAAM,gBAAgB,KAAK,gBACvB,kBAAkB,aAAa,KAAK,cAAc,KAAK,CAAC,cAAc,KAAK,cAAc,QAAQ,OACjG;AAEJ,QAAO;;eAEM,YAAY;;YAEf,aAAa,KAAK,KAAK,CAAC;eACrB,KAAK,QAAQ;eACb,aAAa,KAAK,OAAO,CAAC;cAC3B,OAAO,KAAK,MAAM,CAAC;oBACb,OACd,KAAK,eAAe,0CACrB,CAAC;eACS,OAAO,KAAK,UAAU,KAAK,OAAO,CAAC;eACnC,KAAK,OAAO,KAAK,UAAU,IAAI,aAAa,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;aACpE,KAAK,KAAK,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;kBACvD,KAAK,UAAU;;;;eAIlB,aAAa,KAAK,iBAAiB,KAAK,CAAC;iBACvC,KAAK,iBAAiB,QAAQ;;MAEzC,cAAc;;;;;;aAMP,KAAK,KAAK;;EAErB,OAAO;;MAEH,KAAK,eAAe,kBAAkB,aAAa,KAAK,aAAa,CAAC,MAAM,GAAG;MAC/E,gBAAgB;;;;;;;;;;;;;;;;;AAkBtB,SAAS,OAAO,OAAuB;AACrC,QAAO,MAAM,QAAQ,MAAM,MAAM"}
@@ -0,0 +1,11 @@
1
+ import { EventSpecData } from "../types/spec-types.js";
2
+
3
+ //#region src/templates/event.d.ts
4
+
5
+ /**
6
+ * Generate event spec TypeScript code.
7
+ */
8
+ declare function generateEventSpec(data: EventSpecData): string;
9
+ //#endregion
10
+ export { generateEventSpec };
11
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","names":[],"sources":["../../src/templates/event.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAWgB,iBAAA,OAAwB"}
@@ -0,0 +1,41 @@
1
+ import { toPascalCase } from "./utils.js";
2
+
3
+ //#region src/templates/event.ts
4
+ /**
5
+ * Generate event spec TypeScript code.
6
+ */
7
+ function generateEventSpec(data) {
8
+ const { name, version, description, stability, owners, tags, piiFields } = data;
9
+ const eventVarName = toPascalCase(name.replace(/\./g, "_")) + "V" + version;
10
+ const payloadSchemaName = eventVarName + "Payload";
11
+ return `import { defineEvent } from '@contractspec/lib.contracts';
12
+ import { ScalarTypeEnum, SchemaModel } from '@contractspec/lib.schema';
13
+
14
+ // TODO: Define event payload schema
15
+ export const ${payloadSchemaName} = new SchemaModel({
16
+ name: '${payloadSchemaName}',
17
+ description: 'Payload for ${name}',
18
+ fields: {
19
+ // Add your payload fields here
20
+ // example: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
21
+ },
22
+ });
23
+
24
+ export const ${eventVarName} = defineEvent({
25
+ meta: {
26
+ name: '${name}',
27
+ version: ${version},
28
+ description: '${description}',
29
+ stability: '${stability}',
30
+ owners: [${owners.map((o) => `'${o}'`).join(", ")}],
31
+ tags: [${tags.map((t) => `'${t}'`).join(", ")}],
32
+ },
33
+ ${piiFields.length > 0 ? `pii: [${piiFields.map((f) => `'${f}'`).join(", ")}],` : "// pii: [],"}
34
+ payload: ${payloadSchemaName},
35
+ });
36
+ `;
37
+ }
38
+
39
+ //#endregion
40
+ export { generateEventSpec };
41
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","names":[],"sources":["../../src/templates/event.ts"],"sourcesContent":["/**\n * Event spec template generation.\n * Extracted from cli-contractspec/src/templates/event.template.ts\n */\n\nimport type { EventSpecData } from '../types/spec-types';\nimport { toPascalCase } from './utils';\n\n/**\n * Generate event spec TypeScript code.\n */\nexport function generateEventSpec(data: EventSpecData): string {\n const { name, version, description, stability, owners, tags, piiFields } =\n data;\n\n const eventVarName = toPascalCase(name.replace(/\\./g, '_')) + 'V' + version;\n const payloadSchemaName = eventVarName + 'Payload';\n\n return `import { defineEvent } from '@contractspec/lib.contracts';\nimport { ScalarTypeEnum, SchemaModel } from '@contractspec/lib.schema';\n\n// TODO: Define event payload schema\nexport const ${payloadSchemaName} = new SchemaModel({\n name: '${payloadSchemaName}',\n description: 'Payload for ${name}',\n fields: {\n // Add your payload fields here\n // example: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nexport const ${eventVarName} = defineEvent({\n meta: {\n name: '${name}',\n version: ${version},\n description: '${description}',\n stability: '${stability}',\n owners: [${owners.map((o) => `'${o}'`).join(', ')}],\n tags: [${tags.map((t) => `'${t}'`).join(', ')}],\n },\n ${piiFields.length > 0 ? `pii: [${piiFields.map((f) => `'${f}'`).join(', ')}],` : '// pii: [],'}\n payload: ${payloadSchemaName},\n});\n`;\n}\n"],"mappings":";;;;;;AAWA,SAAgB,kBAAkB,MAA6B;CAC7D,MAAM,EAAE,MAAM,SAAS,aAAa,WAAW,QAAQ,MAAM,cAC3D;CAEF,MAAM,eAAe,aAAa,KAAK,QAAQ,OAAO,IAAI,CAAC,GAAG,MAAM;CACpE,MAAM,oBAAoB,eAAe;AAEzC,QAAO;;;;eAIM,kBAAkB;WACtB,kBAAkB;8BACC,KAAK;;;;;;;eAOpB,aAAa;;aAEf,KAAK;eACH,QAAQ;oBACH,YAAY;kBACd,UAAU;eACb,OAAO,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;aACzC,KAAK,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;;IAE9C,UAAU,SAAS,IAAI,SAAS,UAAU,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,cAAc;aACrF,kBAAkB"}
@@ -0,0 +1,7 @@
1
+ import { ExperimentSpecData } from "../types/spec-types.js";
2
+
3
+ //#region src/templates/experiment.d.ts
4
+ declare function generateExperimentSpec(data: ExperimentSpecData): string;
5
+ //#endregion
6
+ export { generateExperimentSpec };
7
+ //# sourceMappingURL=experiment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment.d.ts","names":[],"sources":["../../src/templates/experiment.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,sBAAA,OAA6B"}
@@ -0,0 +1,88 @@
1
+ import { toPascalCase } from "./utils.js";
2
+
3
+ //#region src/templates/experiment.ts
4
+ function generateExperimentSpec(data) {
5
+ const specVar = toPascalCase(data.name.split(".").pop() ?? "Experiment") + "Experiment";
6
+ const variants = data.variants.map((variant) => {
7
+ const overrides = variant.overrides?.length ? ` overrides: [
8
+ ${variant.overrides.map((override) => ` {
9
+ type: '${override.type}',
10
+ target: '${escapeString(override.target)}',
11
+ ${typeof override.version === "number" ? `version: ${override.version},` : ""}
12
+ }`).join(",\n")}
13
+ ],` : "";
14
+ return ` {
15
+ id: '${escapeString(variant.id)}',
16
+ name: '${escapeString(variant.name)}',
17
+ ${variant.description ? `description: '${escapeString(variant.description)}',` : ""}
18
+ ${typeof variant.weight === "number" ? `weight: ${variant.weight},` : ""}
19
+ ${overrides}
20
+ }`;
21
+ }).join(",\n");
22
+ const allocation = renderAllocation(data.allocation);
23
+ const metrics = data.successMetrics?.length ? ` successMetrics: [
24
+ ${data.successMetrics.map((metric) => ` {
25
+ name: '${escapeString(metric.name)}',
26
+ telemetryEvent: { name: '${escapeString(metric.eventName)}', version: ${metric.eventVersion} },
27
+ aggregation: '${metric.aggregation}',
28
+ ${typeof metric.target === "number" ? `target: ${metric.target},` : ""}
29
+ }`).join(",\n")}
30
+ ],` : "";
31
+ return `import type { ExperimentSpec } from '@contractspec/lib.contracts/experiments';
32
+
33
+ export const ${specVar}: ExperimentSpec = {
34
+ meta: {
35
+ key: '${escapeString(data.name)}',
36
+ version: ${data.version},
37
+ title: '${escapeString(data.name)} experiment',
38
+ description: '${escapeString(data.description || "Describe the experiment goal.")}',
39
+ domain: '${escapeString(data.domain)}',
40
+ owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(", ")}],
41
+ tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(", ")}],
42
+ stability: '${data.stability}',
43
+ },
44
+ controlVariant: '${escapeString(data.controlVariant)}',
45
+ variants: [
46
+ ${variants}
47
+ ],
48
+ allocation: ${allocation},
49
+ ${metrics}
50
+ };
51
+ `;
52
+ }
53
+ function renderAllocation(allocation) {
54
+ switch (allocation.type) {
55
+ case "random": return `{
56
+ type: 'random',
57
+ ${allocation.salt ? `salt: '${escapeString(allocation.salt)}',` : ""}
58
+ }`;
59
+ case "sticky": return `{
60
+ type: 'sticky',
61
+ attribute: '${allocation.attribute}',
62
+ ${allocation.salt ? `salt: '${escapeString(allocation.salt)}',` : ""}
63
+ }`;
64
+ case "targeted": return `{
65
+ type: 'targeted',
66
+ rules: [
67
+ ${allocation.rules.map((rule) => ` {
68
+ variantId: '${escapeString(rule.variantId)}',
69
+ ${typeof rule.percentage === "number" ? `percentage: ${rule.percentage},` : ""}
70
+ ${rule.policy ? `policy: { name: '${escapeString(rule.policy.name)}'${typeof rule.policy.version === "number" ? `, version: ${rule.policy.version}` : ""} },` : ""}
71
+ ${rule.expression ? `expression: '${escapeString(rule.expression)}',` : ""}
72
+ }`).join(",\n")}
73
+ ],
74
+ fallback: '${allocation.fallback ?? "control"}',
75
+ }`;
76
+ default: return renderUnsupportedAllocation(allocation);
77
+ }
78
+ }
79
+ function escapeString(value) {
80
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
81
+ }
82
+ function renderUnsupportedAllocation(allocation) {
83
+ throw new Error(`Unsupported allocation type ${allocation}`);
84
+ }
85
+
86
+ //#endregion
87
+ export { generateExperimentSpec };
88
+ //# sourceMappingURL=experiment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experiment.js","names":[],"sources":["../../src/templates/experiment.ts"],"sourcesContent":["import type { ExperimentSpecData } from '../types/spec-types';\nimport { toPascalCase } from './utils';\n\nexport function generateExperimentSpec(data: ExperimentSpecData): string {\n const specVar =\n toPascalCase(data.name.split('.').pop() ?? 'Experiment') + 'Experiment';\n\n const variants = data.variants\n .map((variant) => {\n const overrides = variant.overrides?.length\n ? ` overrides: [\n${variant.overrides\n .map(\n (override) => ` {\n type: '${override.type}',\n target: '${escapeString(override.target)}',\n ${typeof override.version === 'number' ? `version: ${override.version},` : ''}\n }`\n )\n .join(',\\n')}\n ],`\n : '';\n return ` {\n id: '${escapeString(variant.id)}',\n name: '${escapeString(variant.name)}',\n ${variant.description ? `description: '${escapeString(variant.description)}',` : ''}\n ${typeof variant.weight === 'number' ? `weight: ${variant.weight},` : ''}\n${overrides}\n }`;\n })\n .join(',\\n');\n\n const allocation = renderAllocation(data.allocation);\n\n const metrics = data.successMetrics?.length\n ? ` successMetrics: [\n${data.successMetrics\n .map(\n (metric) => ` {\n name: '${escapeString(metric.name)}',\n telemetryEvent: { name: '${escapeString(metric.eventName)}', version: ${metric.eventVersion} },\n aggregation: '${metric.aggregation}',\n ${typeof metric.target === 'number' ? `target: ${metric.target},` : ''}\n }`\n )\n .join(',\\n')}\n ],`\n : '';\n\n return `import type { ExperimentSpec } from '@contractspec/lib.contracts/experiments';\n\nexport const ${specVar}: ExperimentSpec = {\n meta: {\n key: '${escapeString(data.name)}',\n version: ${data.version},\n title: '${escapeString(data.name)} experiment',\n description: '${escapeString(\n data.description || 'Describe the experiment goal.'\n )}',\n domain: '${escapeString(data.domain)}',\n owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(', ')}],\n stability: '${data.stability}',\n },\n controlVariant: '${escapeString(data.controlVariant)}',\n variants: [\n${variants}\n ],\n allocation: ${allocation},\n${metrics}\n};\n`;\n}\n\nfunction renderAllocation(\n allocation: ExperimentSpecData['allocation']\n): string {\n switch (allocation.type) {\n case 'random':\n return `{\n type: 'random',\n ${allocation.salt ? `salt: '${escapeString(allocation.salt)}',` : ''}\n }`;\n case 'sticky':\n return `{\n type: 'sticky',\n attribute: '${allocation.attribute}',\n ${allocation.salt ? `salt: '${escapeString(allocation.salt)}',` : ''}\n }`;\n case 'targeted':\n return `{\n type: 'targeted',\n rules: [\n${allocation.rules\n .map(\n (rule) => ` {\n variantId: '${escapeString(rule.variantId)}',\n ${typeof rule.percentage === 'number' ? `percentage: ${rule.percentage},` : ''}\n ${\n rule.policy\n ? `policy: { name: '${escapeString(rule.policy.name)}'${typeof rule.policy.version === 'number' ? `, version: ${rule.policy.version}` : ''} },`\n : ''\n }\n ${rule.expression ? `expression: '${escapeString(rule.expression)}',` : ''}\n }`\n )\n .join(',\\n')}\n ],\n fallback: '${allocation.fallback ?? 'control'}',\n }`;\n default:\n return renderUnsupportedAllocation(allocation);\n }\n}\n\nfunction escapeString(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction renderUnsupportedAllocation(allocation: never): string {\n throw new Error(\n `Unsupported allocation type ${allocation as unknown as string}`\n );\n}\n"],"mappings":";;;AAGA,SAAgB,uBAAuB,MAAkC;CACvE,MAAM,UACJ,aAAa,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,aAAa,GAAG;CAE7D,MAAM,WAAW,KAAK,SACnB,KAAK,YAAY;EAChB,MAAM,YAAY,QAAQ,WAAW,SACjC;EACR,QAAQ,UACP,KACE,aAAa;mBACC,SAAS,KAAK;qBACZ,aAAa,SAAS,OAAO,CAAC;YACvC,OAAO,SAAS,YAAY,WAAW,YAAY,SAAS,QAAQ,KAAK,GAAG;WAErF,CACA,KAAK,MAAM,CAAC;YAEL;AACJ,SAAO;aACA,aAAa,QAAQ,GAAG,CAAC;eACvB,aAAa,QAAQ,KAAK,CAAC;QAClC,QAAQ,cAAc,iBAAiB,aAAa,QAAQ,YAAY,CAAC,MAAM,GAAG;QAClF,OAAO,QAAQ,WAAW,WAAW,WAAW,QAAQ,OAAO,KAAK,GAAG;EAC7E,UAAU;;GAEN,CACD,KAAK,MAAM;CAEd,MAAM,aAAa,iBAAiB,KAAK,WAAW;CAEpD,MAAM,UAAU,KAAK,gBAAgB,SACjC;EACJ,KAAK,eACJ,KACE,WAAW;eACD,aAAa,OAAO,KAAK,CAAC;iCACR,aAAa,OAAO,UAAU,CAAC,cAAc,OAAO,aAAa;sBAC5E,OAAO,YAAY;QACjC,OAAO,OAAO,WAAW,WAAW,WAAW,OAAO,OAAO,KAAK,GAAG;OAE1E,CACA,KAAK,MAAM,CAAC;QAET;AAEJ,QAAO;;eAEM,QAAQ;;YAEX,aAAa,KAAK,KAAK,CAAC;eACrB,KAAK,QAAQ;cACd,aAAa,KAAK,KAAK,CAAC;oBAClB,aACd,KAAK,eAAe,gCACrB,CAAC;eACS,aAAa,KAAK,OAAO,CAAC;eAC1B,KAAK,OAAO,KAAK,UAAU,IAAI,aAAa,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;aACpE,KAAK,KAAK,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;kBACvD,KAAK,UAAU;;qBAEZ,aAAa,KAAK,eAAe,CAAC;;EAErD,SAAS;;gBAEK,WAAW;EACzB,QAAQ;;;;AAKV,SAAS,iBACP,YACQ;AACR,SAAQ,WAAW,MAAnB;EACE,KAAK,SACH,QAAO;;MAEP,WAAW,OAAO,UAAU,aAAa,WAAW,KAAK,CAAC,MAAM,GAAG;;EAErE,KAAK,SACH,QAAO;;kBAEK,WAAW,UAAU;MACjC,WAAW,OAAO,UAAU,aAAa,WAAW,KAAK,CAAC,MAAM,GAAG;;EAErE,KAAK,WACH,QAAO;;;EAGX,WAAW,MACV,KACE,SAAS;sBACQ,aAAa,KAAK,UAAU,CAAC;UACzC,OAAO,KAAK,eAAe,WAAW,eAAe,KAAK,WAAW,KAAK,GAAG;UAE7E,KAAK,SACD,oBAAoB,aAAa,KAAK,OAAO,KAAK,CAAC,GAAG,OAAO,KAAK,OAAO,YAAY,WAAW,cAAc,KAAK,OAAO,YAAY,GAAG,OACzI,GACL;UACC,KAAK,aAAa,gBAAgB,aAAa,KAAK,WAAW,CAAC,MAAM,GAAG;SAEhF,CACA,KAAK,MAAM,CAAC;;iBAEE,WAAW,YAAY,UAAU;;EAE9C,QACE,QAAO,4BAA4B,WAAW;;;AAIpD,SAAS,aAAa,OAAuB;AAC3C,QAAO,MAAM,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,MAAM;;AAG1D,SAAS,4BAA4B,YAA2B;AAC9D,OAAM,IAAI,MACR,+BAA+B,aAChC"}
@@ -0,0 +1,20 @@
1
+ //#region src/templates/handler.d.ts
2
+ /**
3
+ * Handler and component template generation.
4
+ * Extracted from cli-contractspec/src/templates/handler.template.ts
5
+ */
6
+ /**
7
+ * Generate handler implementation template.
8
+ */
9
+ declare function generateHandlerTemplate(specName: string, kind: 'command' | 'query'): string;
10
+ /**
11
+ * Generate React component template.
12
+ */
13
+ declare function generateComponentTemplate(componentName: string, description: string): string;
14
+ /**
15
+ * Generate test template.
16
+ */
17
+ declare function generateTestTemplate(targetName: string, type: 'handler' | 'component'): string;
18
+ //#endregion
19
+ export { generateComponentTemplate, generateHandlerTemplate, generateTestTemplate };
20
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","names":[],"sources":["../../src/templates/handler.ts"],"sourcesContent":[],"mappings":";;AAUA;AAyCA;AA6BA;;;;iBAtEgB,uBAAA;;;;iBAyCA,yBAAA;;;;iBA6BA,oBAAA"}
@@ -0,0 +1,96 @@
1
+ import { toCamelCase, toKebabCase, toPascalCase } from "./utils.js";
2
+
3
+ //#region src/templates/handler.ts
4
+ /**
5
+ * Handler and component template generation.
6
+ * Extracted from cli-contractspec/src/templates/handler.template.ts
7
+ */
8
+ /**
9
+ * Generate handler implementation template.
10
+ */
11
+ function generateHandlerTemplate(specName, kind) {
12
+ const handlerName = toCamelCase(specName.split(".").pop() ?? "unknown") + "Handler";
13
+ const specVarName = toPascalCase(specName.split(".").pop() ?? "Unknown") + "Spec";
14
+ return `import type { ContractHandler } from '@contractspec/lib.contracts';
15
+ import { ${specVarName} } from '../contracts/${toKebabCase(specName)}.contracts';
16
+
17
+ /**
18
+ * Handler for ${specName}
19
+ */
20
+ export const ${handlerName}: ContractHandler<typeof ${specVarName}> = async (
21
+ input,
22
+ context
23
+ ) => {
24
+ // TODO: Implement ${kind} logic
25
+
26
+ try {
27
+ // 1. Validate prerequisites
28
+ // 2. Perform business logic
29
+ // 3. Emit events if needed
30
+ // 4. Return result
31
+
32
+ return {
33
+ ok: true,
34
+ };
35
+ } catch (error) {
36
+ // Handle and map errors to spec.io.errors
37
+ throw error;
38
+ }
39
+ };
40
+ `;
41
+ }
42
+ /**
43
+ * Generate React component template.
44
+ */
45
+ function generateComponentTemplate(componentName, description) {
46
+ const pascalName = toPascalCase(componentName);
47
+ return `import React from 'react';
48
+
49
+ interface ${pascalName}Props {
50
+ // TODO: Define props based on presentation spec
51
+ }
52
+
53
+ /**
54
+ * ${description}
55
+ */
56
+ export const ${pascalName}: React.FC<${pascalName}Props> = (props) => {
57
+ return (
58
+ <div>
59
+ {/* TODO: Implement component UI */}
60
+ <p>Component: ${pascalName}</p>
61
+ </div>
62
+ );
63
+ };
64
+ `;
65
+ }
66
+ /**
67
+ * Generate test template.
68
+ */
69
+ function generateTestTemplate(targetName, type) {
70
+ const importPath = type === "handler" ? "../handlers" : "../components";
71
+ const testName = toPascalCase(targetName);
72
+ return `import { describe, it, expect } from 'bun:test';
73
+ import { ${testName} } from '${importPath}/${toKebabCase(targetName)}';
74
+
75
+ describe('${testName}', () => {
76
+ it('should ${type === "handler" ? "handle valid input" : "render correctly"}', async () => {
77
+ // TODO: Implement test
78
+ expect(true).toBe(true);
79
+ });
80
+
81
+ it('should handle edge cases', async () => {
82
+ // TODO: Test edge cases
83
+ });
84
+
85
+ ${type === "handler" ? `it('should handle errors appropriately', async () => {
86
+ // TODO: Test error scenarios
87
+ });` : `it('should be accessible', async () => {
88
+ // TODO: Test accessibility
89
+ });`}
90
+ });
91
+ `;
92
+ }
93
+
94
+ //#endregion
95
+ export { generateComponentTemplate, generateHandlerTemplate, generateTestTemplate };
96
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","names":[],"sources":["../../src/templates/handler.ts"],"sourcesContent":["/**\n * Handler and component template generation.\n * Extracted from cli-contractspec/src/templates/handler.template.ts\n */\n\nimport { toPascalCase, toCamelCase, toKebabCase } from './utils';\n\n/**\n * Generate handler implementation template.\n */\nexport function generateHandlerTemplate(\n specName: string,\n kind: 'command' | 'query'\n): string {\n const handlerName =\n toCamelCase(specName.split('.').pop() ?? 'unknown') + 'Handler';\n const specVarName =\n toPascalCase(specName.split('.').pop() ?? 'Unknown') + 'Spec';\n\n return `import type { ContractHandler } from '@contractspec/lib.contracts';\nimport { ${specVarName} } from '../contracts/${toKebabCase(specName)}.contracts';\n\n/**\n * Handler for ${specName}\n */\nexport const ${handlerName}: ContractHandler<typeof ${specVarName}> = async (\n input,\n context\n) => {\n // TODO: Implement ${kind} logic\n \n try {\n // 1. Validate prerequisites\n // 2. Perform business logic\n // 3. Emit events if needed\n // 4. Return result\n \n return {\n ok: true,\n };\n } catch (error) {\n // Handle and map errors to spec.io.errors\n throw error;\n }\n};\n`;\n}\n\n/**\n * Generate React component template.\n */\nexport function generateComponentTemplate(\n componentName: string,\n description: string\n): string {\n const pascalName = toPascalCase(componentName);\n\n return `import React from 'react';\n\ninterface ${pascalName}Props {\n // TODO: Define props based on presentation spec\n}\n\n/**\n * ${description}\n */\nexport const ${pascalName}: React.FC<${pascalName}Props> = (props) => {\n return (\n <div>\n {/* TODO: Implement component UI */}\n <p>Component: ${pascalName}</p>\n </div>\n );\n};\n`;\n}\n\n/**\n * Generate test template.\n */\nexport function generateTestTemplate(\n targetName: string,\n type: 'handler' | 'component'\n): string {\n const importPath = type === 'handler' ? '../handlers' : '../components';\n const testName = toPascalCase(targetName);\n\n return `import { describe, it, expect } from 'bun:test';\nimport { ${testName} } from '${importPath}/${toKebabCase(targetName)}';\n\ndescribe('${testName}', () => {\n it('should ${type === 'handler' ? 'handle valid input' : 'render correctly'}', async () => {\n // TODO: Implement test\n expect(true).toBe(true);\n });\n\n it('should handle edge cases', async () => {\n // TODO: Test edge cases\n });\n\n ${\n type === 'handler'\n ? `it('should handle errors appropriately', async () => {\n // TODO: Test error scenarios\n });`\n : `it('should be accessible', async () => {\n // TODO: Test accessibility\n });`\n }\n});\n`;\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,wBACd,UACA,MACQ;CACR,MAAM,cACJ,YAAY,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,UAAU,GAAG;CACxD,MAAM,cACJ,aAAa,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,UAAU,GAAG;AAEzD,QAAO;WACE,YAAY,wBAAwB,YAAY,SAAS,CAAC;;;iBAGpD,SAAS;;eAEX,YAAY,2BAA2B,YAAY;;;;uBAI3C,KAAK;;;;;;;;;;;;;;;;;;;;;AAsB5B,SAAgB,0BACd,eACA,aACQ;CACR,MAAM,aAAa,aAAa,cAAc;AAE9C,QAAO;;YAEG,WAAW;;;;;KAKlB,YAAY;;eAEF,WAAW,aAAa,WAAW;;;;sBAI5B,WAAW;;;;;;;;;AAUjC,SAAgB,qBACd,YACA,MACQ;CACR,MAAM,aAAa,SAAS,YAAY,gBAAgB;CACxD,MAAM,WAAW,aAAa,WAAW;AAEzC,QAAO;WACE,SAAS,WAAW,WAAW,GAAG,YAAY,WAAW,CAAC;;YAEzD,SAAS;eACN,SAAS,YAAY,uBAAuB,mBAAmB;;;;;;;;;IAU1E,SAAS,YACL;;SAGA;;OAGL"}
@@ -0,0 +1,105 @@
1
+ //#region src/templates/integration-utils.ts
2
+ function renderConfigSchema(fields) {
3
+ const requiredFields = fields.filter((field) => field.required);
4
+ return ` schema: {
5
+ type: 'object',
6
+ ${requiredFields.length > 0 ? ` required: [${requiredFields.map((field) => `'${field.key}'`).join(", ")}],
7
+ ` : ""} properties: {
8
+ ${(fields.length ? fields.map((field) => {
9
+ const description = field.description ? `, description: '${escape(field.description)}'` : "";
10
+ return ` ${field.key}: { type: '${mapConfigType(field.type)}'${description} }`;
11
+ }).join(",\n") : "") || " "}
12
+ },
13
+ },\n`;
14
+ }
15
+ function renderSecretSchema(fields) {
16
+ const requiredFields = fields.filter((field) => field.required);
17
+ return ` schema: {
18
+ type: 'object',
19
+ ${requiredFields.length > 0 ? ` required: [${requiredFields.map((field) => `'${field.key}'`).join(", ")}],
20
+ ` : ""} properties: {
21
+ ${(fields.length ? fields.map((field) => {
22
+ const description = field.description ? `, description: '${escape(field.description)}'` : "";
23
+ return ` ${field.key}: { type: 'string'${description} }`;
24
+ }).join(",\n") : "") || " "}
25
+ },
26
+ },\n`;
27
+ }
28
+ function renderConfigExample(fields) {
29
+ if (fields.length === 0) return `{}`;
30
+ return `{
31
+ ${fields.map((field) => {
32
+ switch (field.type) {
33
+ case "number": return ` ${field.key}: 0`;
34
+ case "boolean": return ` ${field.key}: true`;
35
+ case "string":
36
+ default: return ` ${field.key}: '${field.key.toUpperCase()}_VALUE'`;
37
+ }
38
+ }).join(",\n")}
39
+ }`;
40
+ }
41
+ function renderSecretExample(fields) {
42
+ if (fields.length === 0) return `{}`;
43
+ return `{
44
+ ${fields.map((field) => ` ${field.key}: '${field.key.toUpperCase()}_SECRET'`).join(",\n")}
45
+ }`;
46
+ }
47
+ function renderConstraints(rpm, rph) {
48
+ if (rpm == null && rph == null) return "";
49
+ const entries = [];
50
+ if (rpm != null) entries.push(` rpm: ${rpm}`);
51
+ if (rph != null) entries.push(` rph: ${rph}`);
52
+ return ` constraints: {
53
+ rateLimit: {
54
+ ${entries.join(",\n")}
55
+ },
56
+ },
57
+ `;
58
+ }
59
+ function renderByokSetup(modes, instructions, scopes) {
60
+ if (!modes.includes("byok")) return "";
61
+ const instructionsLine = instructions ? ` setupInstructions: '${escape(instructions)}',\n` : "";
62
+ const scopesLine = scopes && scopes.length ? ` requiredScopes: [${scopes.map((scope) => `'${escape(scope)}'`).join(", ")}],\n` : "";
63
+ if (!instructionsLine && !scopesLine) return "";
64
+ return ` byokSetup: {
65
+ ${instructionsLine}${scopesLine} },
66
+ `;
67
+ }
68
+ function mapConfigType(type) {
69
+ switch (type) {
70
+ case "number": return "number";
71
+ case "boolean": return "boolean";
72
+ case "string":
73
+ default: return "string";
74
+ }
75
+ }
76
+ function stabilityToEnum(stability) {
77
+ switch (stability) {
78
+ case "beta": return "Beta";
79
+ case "stable": return "Stable";
80
+ case "deprecated": return "Deprecated";
81
+ case "experimental":
82
+ default: return "Experimental";
83
+ }
84
+ }
85
+ function renderProvides(data) {
86
+ return data.capabilitiesProvided.map((cap) => ` { key: '${cap.key}', version: ${cap.version} }`).join(",\n");
87
+ }
88
+ function renderRequires(data) {
89
+ if (data.capabilitiesRequired.length === 0) return "";
90
+ return ` requires: [
91
+ ${data.capabilitiesRequired.map((req) => {
92
+ const version = typeof req.version === "number" ? `, version: ${req.version}` : "";
93
+ const optional = req.optional ? ", optional: true" : "";
94
+ const reason = req.reason ? `, reason: '${escape(req.reason)}'` : "";
95
+ return ` { key: '${req.key}'${version}${optional}${reason} }`;
96
+ }).join(",\n")}
97
+ ],`;
98
+ }
99
+ function escape(value) {
100
+ return value.replace(/`/g, "\\`").replace(/'/g, "\\'");
101
+ }
102
+
103
+ //#endregion
104
+ export { escape, renderByokSetup, renderConfigExample, renderConfigSchema, renderConstraints, renderProvides, renderRequires, renderSecretExample, renderSecretSchema, stabilityToEnum };
105
+ //# sourceMappingURL=integration-utils.js.map