@archrad/deterministic 0.1.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 (93) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/CONTRIBUTING.md +15 -0
  3. package/LICENSE +17 -0
  4. package/README.md +284 -0
  5. package/SECURITY.md +26 -0
  6. package/biome.json +25 -0
  7. package/demo-validate.gif +0 -0
  8. package/dist/cli-findings.d.ts +23 -0
  9. package/dist/cli-findings.d.ts.map +1 -0
  10. package/dist/cli-findings.js +88 -0
  11. package/dist/cli.d.ts +7 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +341 -0
  14. package/dist/edgeConfigCodeGenerator.d.ts +55 -0
  15. package/dist/edgeConfigCodeGenerator.d.ts.map +1 -0
  16. package/dist/edgeConfigCodeGenerator.js +249 -0
  17. package/dist/exportPipeline.d.ts +23 -0
  18. package/dist/exportPipeline.d.ts.map +1 -0
  19. package/dist/exportPipeline.js +65 -0
  20. package/dist/golden-bundle.d.ts +21 -0
  21. package/dist/golden-bundle.d.ts.map +1 -0
  22. package/dist/golden-bundle.js +166 -0
  23. package/dist/graphPredicates.d.ts +10 -0
  24. package/dist/graphPredicates.d.ts.map +1 -0
  25. package/dist/graphPredicates.js +33 -0
  26. package/dist/hostPort.d.ts +12 -0
  27. package/dist/hostPort.d.ts.map +1 -0
  28. package/dist/hostPort.js +39 -0
  29. package/dist/index.d.ts +22 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +21 -0
  32. package/dist/ir-lint.d.ts +11 -0
  33. package/dist/ir-lint.d.ts.map +1 -0
  34. package/dist/ir-lint.js +16 -0
  35. package/dist/ir-normalize.d.ts +48 -0
  36. package/dist/ir-normalize.d.ts.map +1 -0
  37. package/dist/ir-normalize.js +81 -0
  38. package/dist/ir-structural.d.ts +40 -0
  39. package/dist/ir-structural.d.ts.map +1 -0
  40. package/dist/ir-structural.js +267 -0
  41. package/dist/lint-graph.d.ts +40 -0
  42. package/dist/lint-graph.d.ts.map +1 -0
  43. package/dist/lint-graph.js +133 -0
  44. package/dist/lint-rules.d.ts +40 -0
  45. package/dist/lint-rules.d.ts.map +1 -0
  46. package/dist/lint-rules.js +290 -0
  47. package/dist/nodeExpress.d.ts +2 -0
  48. package/dist/nodeExpress.d.ts.map +1 -0
  49. package/dist/nodeExpress.js +528 -0
  50. package/dist/openapi-structural.d.ts +26 -0
  51. package/dist/openapi-structural.d.ts.map +1 -0
  52. package/dist/openapi-structural.js +82 -0
  53. package/dist/openapi-to-ir.d.ts +26 -0
  54. package/dist/openapi-to-ir.d.ts.map +1 -0
  55. package/dist/openapi-to-ir.js +131 -0
  56. package/dist/pythonFastAPI.d.ts +2 -0
  57. package/dist/pythonFastAPI.d.ts.map +1 -0
  58. package/dist/pythonFastAPI.js +664 -0
  59. package/dist/validate-drift.d.ts +54 -0
  60. package/dist/validate-drift.d.ts.map +1 -0
  61. package/dist/validate-drift.js +184 -0
  62. package/dist/yamlToIr.d.ts +14 -0
  63. package/dist/yamlToIr.d.ts.map +1 -0
  64. package/dist/yamlToIr.js +39 -0
  65. package/docs/CONCEPT_ADOPTION_AND_LIMITS.md +47 -0
  66. package/docs/CUSTOM_RULES.md +87 -0
  67. package/docs/ENGINEERING_NOTES.md +42 -0
  68. package/docs/IR_CONTRACT.md +54 -0
  69. package/docs/STRUCTURAL_VS_SEMANTIC_VALIDATION.md +86 -0
  70. package/fixtures/demo-direct-db-layered.json +37 -0
  71. package/fixtures/demo-direct-db-violation.json +22 -0
  72. package/fixtures/ecommerce-with-warnings.json +89 -0
  73. package/fixtures/invalid-cycle.json +15 -0
  74. package/fixtures/invalid-edge-unknown-node.json +14 -0
  75. package/fixtures/minimal-graph.json +14 -0
  76. package/fixtures/minimal-graph.yaml +13 -0
  77. package/fixtures/payment-retry-demo.json +43 -0
  78. package/llms.txt +99 -0
  79. package/package.json +84 -0
  80. package/schemas/archrad-ir-graph-v1.schema.json +67 -0
  81. package/scripts/DEMO_GIF_STORYBOARD.md +100 -0
  82. package/scripts/GIF_RECORDING_STEP_BY_STEP.md +125 -0
  83. package/scripts/README_DEMO_RECORDING.md +314 -0
  84. package/scripts/SOCIAL_POST_DRIFT_AND_INGESTION.md +17 -0
  85. package/scripts/golden-path-demo.ps1 +25 -0
  86. package/scripts/golden-path-demo.sh +23 -0
  87. package/scripts/invoke-drift-check.ps1 +16 -0
  88. package/scripts/record-demo-drift.tape +50 -0
  89. package/scripts/record-demo-payment-retry.tape +36 -0
  90. package/scripts/record-demo-validate.tape +34 -0
  91. package/scripts/record-demo.tape +33 -0
  92. package/scripts/run-demo-drift-sequence.ps1 +45 -0
  93. package/scripts/run-demo-drift-sequence.sh +41 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-to-ir.d.ts","sourceRoot":"","sources":["../src/openapi-to-ir.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAuBD,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,EAAE,CAgD1F;AAaD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgClG;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMnF;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQnF"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * OpenAPI 3.x → canonical blueprint IR (structural HTTP surface only).
3
+ * OSS + product share this: CLI `archrad ingest openapi`, Cloud merge-into-graph, CI regenerate.
4
+ * This is not semantic architecture truth — only operations under `paths` become `http` nodes.
5
+ */
6
+ import { parseOpenApiString, validateOpenApiStructural } from './openapi-structural.js';
7
+ export class OpenApiIngestError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = 'OpenApiIngestError';
11
+ }
12
+ }
13
+ const HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'options', 'head'];
14
+ function normalizeOpenApiPath(pathKey) {
15
+ const s = String(pathKey).trim() || '/';
16
+ return s.startsWith('/') ? s : `/${s}`;
17
+ }
18
+ function safeServiceName(title) {
19
+ const t = String(title || 'openapi-service')
20
+ .trim()
21
+ .replace(/[^a-zA-Z0-9_-]+/g, '-')
22
+ .replace(/^-+|-+$/g, '')
23
+ .toLowerCase();
24
+ return t.slice(0, 63) || 'openapi-service';
25
+ }
26
+ function safeNodeId(path, method) {
27
+ const slug = `${method}_${path}`.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_|_$/g, '').toLowerCase();
28
+ return `openapi_${slug || 'route'}`.slice(0, 80);
29
+ }
30
+ /**
31
+ * List HTTP operations as IR `http` nodes (ids unique within this batch; caller dedupes against a graph).
32
+ */
33
+ export function openApiDocumentToHttpNodes(doc) {
34
+ const paths = doc.paths;
35
+ if (!paths || typeof paths !== 'object' || Array.isArray(paths)) {
36
+ return [];
37
+ }
38
+ const nodes = [];
39
+ const usedIds = new Set();
40
+ for (const [pathKey, pathItem] of Object.entries(paths)) {
41
+ if (!pathItem || typeof pathItem !== 'object' || Array.isArray(pathItem))
42
+ continue;
43
+ const url = normalizeOpenApiPath(pathKey);
44
+ for (const m of HTTP_METHODS) {
45
+ const op = pathItem[m];
46
+ if (!op || typeof op !== 'object' || Array.isArray(op))
47
+ continue;
48
+ const summary = typeof op.summary === 'string'
49
+ ? String(op.summary)
50
+ : typeof op.operationId === 'string'
51
+ ? String(op.operationId)
52
+ : '';
53
+ let id = safeNodeId(url, m);
54
+ while (usedIds.has(id)) {
55
+ id = `${id}_${Math.random().toString(36).slice(2, 7)}`;
56
+ }
57
+ usedIds.add(id);
58
+ const operationId = op.operationId;
59
+ nodes.push({
60
+ id,
61
+ type: 'http',
62
+ kind: 'http',
63
+ name: summary || `${m.toUpperCase()} ${url}`,
64
+ config: {
65
+ url,
66
+ route: url,
67
+ method: m.toUpperCase(),
68
+ openApiIngest: true,
69
+ ...(typeof operationId === 'string' && operationId.trim() ? { operationId } : {}),
70
+ },
71
+ });
72
+ }
73
+ }
74
+ return nodes;
75
+ }
76
+ function provenanceBlock(doc) {
77
+ const ver = doc.openapi != null ? String(doc.openapi) : doc.swagger != null ? String(doc.swagger) : '';
78
+ const info = (doc.info && typeof doc.info === 'object' ? doc.info : {});
79
+ return {
80
+ source: 'openapi-ingest',
81
+ openapiVersion: ver,
82
+ specTitle: String(info.title ?? ''),
83
+ specVersion: String(info.version ?? ''),
84
+ };
85
+ }
86
+ /**
87
+ * Full canonical IR wrapper: `{ graph: { metadata, nodes, edges }, metadata? }` — same shape as `yaml-to-ir` / `minimal-graph.json`.
88
+ */
89
+ export function openApiDocumentToCanonicalIr(doc) {
90
+ const v = validateOpenApiStructural(doc);
91
+ if (!v.ok) {
92
+ throw new OpenApiIngestError(`Invalid OpenAPI document shape: ${v.errors.join('; ')}`);
93
+ }
94
+ const info = (doc.info && typeof doc.info === 'object' ? doc.info : {});
95
+ const title = String(info.title ?? 'OpenAPI service');
96
+ const description = String(info.description ?? '').trim();
97
+ const serviceName = safeServiceName(title);
98
+ const nodes = openApiDocumentToHttpNodes(doc);
99
+ if (nodes.length === 0) {
100
+ throw new OpenApiIngestError('No operations found under `paths` (supported methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD).');
101
+ }
102
+ const prov = provenanceBlock(doc);
103
+ return {
104
+ metadata: { name: serviceName },
105
+ graph: {
106
+ metadata: {
107
+ name: serviceName,
108
+ ...(description ? { description } : {}),
109
+ provenance: prov,
110
+ },
111
+ nodes,
112
+ edges: [],
113
+ },
114
+ };
115
+ }
116
+ export function openApiStringToCanonicalIr(content) {
117
+ const parsed = parseOpenApiString(content);
118
+ if (!parsed) {
119
+ throw new OpenApiIngestError('Could not parse OpenAPI as JSON or YAML');
120
+ }
121
+ return openApiDocumentToCanonicalIr(parsed.doc);
122
+ }
123
+ export function openApiUnknownToCanonicalIr(input) {
124
+ if (typeof input === 'string') {
125
+ return openApiStringToCanonicalIr(input);
126
+ }
127
+ if (input && typeof input === 'object' && !Array.isArray(input)) {
128
+ return openApiDocumentToCanonicalIr(input);
129
+ }
130
+ throw new OpenApiIngestError('OpenAPI input must be a JSON/YAML string or a parsed object');
131
+ }
@@ -0,0 +1,2 @@
1
+ export default function generatePythonFastAPIFiles(actualIR: any, opts?: any): Promise<Record<string, string>>;
2
+ //# sourceMappingURL=pythonFastAPI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pythonFastAPI.d.ts","sourceRoot":"","sources":["../src/pythonFastAPI.ts"],"names":[],"mappings":"AA4OA,wBAA8B,0BAA0B,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAE,GAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC,CA2ctH"}