@usefragments/core 1.10.2 → 2.0.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 (130) hide show
  1. package/dist/{chunk-MZ4SW3TP.js → chunk-3IOWHECM.js} +8 -1
  2. package/dist/{chunk-MZ4SW3TP.js.map → chunk-3IOWHECM.js.map} +1 -1
  3. package/dist/chunk-7ULGH74M.js +66 -0
  4. package/dist/chunk-7ULGH74M.js.map +1 -0
  5. package/dist/{chunk-XN3LSDPY.js → chunk-BMPYIUZE.js} +612 -344
  6. package/dist/chunk-BMPYIUZE.js.map +1 -0
  7. package/dist/{chunk-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
  8. package/dist/chunk-ML5S6QNU.js.map +1 -0
  9. package/dist/{chunk-3LLRNCPX.js → chunk-MZ2FS7U4.js} +1 -1
  10. package/dist/chunk-MZ2FS7U4.js.map +1 -0
  11. package/dist/chunk-PWIJMOI4.js +202 -0
  12. package/dist/chunk-PWIJMOI4.js.map +1 -0
  13. package/dist/chunk-RYFULE43.js +578 -0
  14. package/dist/chunk-RYFULE43.js.map +1 -0
  15. package/dist/codes/index.d.ts +2 -2
  16. package/dist/codes/index.js +3 -2
  17. package/dist/compiled-types/index.d.ts +327 -2
  18. package/dist/compiled-types/index.js +1 -1
  19. package/dist/generate/index.d.ts +3 -2
  20. package/dist/{governance-CLk_wkP9.d.ts → governance-hOPXGbbs.d.ts} +474 -515
  21. package/dist/governance-telemetry.d.ts +6 -0
  22. package/dist/governance-telemetry.js +1 -1
  23. package/dist/{index-_sxhUNqx.d.ts → index-C8bcXVav.d.ts} +448 -448
  24. package/dist/index.d.ts +3280 -1305
  25. package/dist/index.js +2414 -350
  26. package/dist/index.js.map +1 -1
  27. package/dist/manifest.d.ts +228 -0
  28. package/dist/manifest.js +24 -0
  29. package/dist/manifest.js.map +1 -0
  30. package/dist/preview/index.js +45 -1
  31. package/dist/preview/index.js.map +1 -1
  32. package/dist/preview-runtime.d.ts +1 -2
  33. package/dist/preview-runtime.js +150 -14
  34. package/dist/preview-runtime.js.map +1 -1
  35. package/dist/react-types.d.ts +1 -2
  36. package/dist/registry.d.ts +1412 -203
  37. package/dist/registry.js +30 -3
  38. package/dist/schemas/index.d.ts +1 -1
  39. package/dist/schemas/index.js +3 -2
  40. package/dist/storyAdapter.d.ts +1 -2
  41. package/dist/storyAdapter.js +11 -49
  42. package/dist/storyAdapter.js.map +1 -1
  43. package/dist/test-utils.d.ts +3 -2
  44. package/dist/topology/index.d.ts +1 -1
  45. package/dist/topology/index.js +1 -1
  46. package/package.json +8 -2
  47. package/src/__tests__/contract-parser.test.ts +318 -277
  48. package/src/__tests__/preview-runtime-hook.test.tsx +315 -0
  49. package/src/__tests__/preview-runtime.test.tsx +30 -8
  50. package/src/__tests__/schema.test.ts +191 -14
  51. package/src/analysis-plan/analysis-plan-v1.test.ts +320 -0
  52. package/src/analysis-plan/coverage.ts +181 -0
  53. package/src/analysis-plan/digest.ts +141 -0
  54. package/src/analysis-plan/index.ts +34 -0
  55. package/src/analysis-plan/types.ts +207 -0
  56. package/src/approved-contract-tokens.test.ts +39 -0
  57. package/src/approved-contract-tokens.ts +18 -0
  58. package/src/codes/__tests__/codes.test.ts +13 -0
  59. package/src/codes/codes.ts +40 -0
  60. package/src/compiled-types/index.ts +640 -39
  61. package/src/compiled-types/parse.test.ts +145 -4
  62. package/src/component-contract.ts +95 -53
  63. package/src/composition.ts +7 -13
  64. package/src/constants.ts +3 -6
  65. package/src/contract/hash.test.ts +20 -0
  66. package/src/contract/hash.ts +66 -9
  67. package/src/contract/index.ts +24 -1
  68. package/src/contract/manifest.test.ts +94 -0
  69. package/src/contract/manifest.ts +68 -0
  70. package/src/contract/preimage.test.ts +219 -1
  71. package/src/contract/preimage.ts +326 -6
  72. package/src/contract/stamp.test.ts +3 -0
  73. package/src/contract/stamp.ts +1 -1
  74. package/src/contract-parser.ts +54 -30
  75. package/src/defineFragment.test.ts +476 -91
  76. package/src/defineFragment.ts +204 -114
  77. package/src/domain-ids.test.ts +35 -0
  78. package/src/domain-ids.ts +61 -0
  79. package/src/evaluation/evaluate.test.ts +522 -0
  80. package/src/evaluation/evaluate.ts +690 -0
  81. package/src/evaluation/evaluation-v2-receipt-v1.test.ts +772 -0
  82. package/src/evaluation/index.ts +58 -0
  83. package/src/evaluation/receipt.ts +753 -0
  84. package/src/evaluation/types.ts +406 -0
  85. package/src/facts/builders.ts +2 -0
  86. package/src/facts/compile.ts +29 -6
  87. package/src/facts/fact-index.ts +13 -3
  88. package/src/facts/fact-integrity-v1.test.ts +172 -0
  89. package/src/facts/facts.test.ts +15 -0
  90. package/src/facts/ids.ts +46 -3
  91. package/src/facts/index.ts +14 -1
  92. package/src/facts/integrity.ts +134 -0
  93. package/src/facts/types.ts +36 -0
  94. package/src/governance-integrity.test.ts +1 -0
  95. package/src/governance-integrity.ts +5 -3
  96. package/src/governance-telemetry.ts +8 -0
  97. package/src/governance.ts +70 -8
  98. package/src/index.ts +230 -37
  99. package/src/preview/validation.test.ts +62 -0
  100. package/src/preview/validation.ts +48 -2
  101. package/src/preview-runtime.tsx +227 -20
  102. package/src/registry-install-plan.ts +200 -109
  103. package/src/registry-shards.test.ts +263 -0
  104. package/src/registry.ts +237 -0
  105. package/src/repository-binding.test.ts +50 -0
  106. package/src/repository-binding.ts +96 -0
  107. package/src/rules/families.test.ts +36 -0
  108. package/src/rules/finding.ts +7 -2
  109. package/src/rules/index.ts +17 -1
  110. package/src/rules/rule-config.test.ts +66 -0
  111. package/src/rules/rule-config.ts +73 -0
  112. package/src/rules/rules.test.ts +26 -0
  113. package/src/rules/tokens-css-vars-must-be-defined.test.ts +51 -2
  114. package/src/rules/tokens-css-vars-must-be-defined.ts +34 -1
  115. package/src/schema.ts +293 -113
  116. package/src/schemas/index.ts +1 -1
  117. package/src/storyAdapter.test.ts +68 -12
  118. package/src/storyAdapter.ts +44 -75
  119. package/src/topology/resolve-area.ts +1 -1
  120. package/src/types.ts +258 -40
  121. package/dist/chunk-3LLRNCPX.js.map +0 -1
  122. package/dist/chunk-RANPUC6C.js +0 -72
  123. package/dist/chunk-RANPUC6C.js.map +0 -1
  124. package/dist/chunk-XN3LSDPY.js.map +0 -1
  125. package/dist/chunk-YF65VYRY.js.map +0 -1
  126. package/src/fragment-types.ts +0 -214
  127. package/src/react-create-element.test.ts +0 -22
  128. package/src/react-create-element.ts +0 -12
  129. package/src/storyFilters.test.ts +0 -350
  130. package/src/storyFilters.ts +0 -253
@@ -1,173 +1,14 @@
1
1
  import {
2
2
  portableRepoPathError
3
3
  } from "./chunk-EIYNNS77.js";
4
+ import {
5
+ canonicalPreimage,
6
+ contractHash,
7
+ sha256Hex
8
+ } from "./chunk-PWIJMOI4.js";
4
9
 
5
10
  // src/registry.ts
6
11
  import { z } from "zod";
7
-
8
- // src/contract/hash.ts
9
- function normalizeNumber(value) {
10
- if (Number.isNaN(value)) return '"@num:nan"';
11
- if (value === Infinity) return '"@num:+inf"';
12
- if (value === -Infinity) return '"@num:-inf"';
13
- if (Object.is(value, -0)) return "0";
14
- return JSON.stringify(value);
15
- }
16
- function canonicalPreimage(value) {
17
- if (value === void 0 || value === null) return "null";
18
- const type = typeof value;
19
- if (type === "number") return normalizeNumber(value);
20
- if (type === "string" || type === "boolean") return JSON.stringify(value);
21
- if (type === "bigint") return JSON.stringify(value.toString());
22
- if (Array.isArray(value)) {
23
- return `[${value.map(canonicalPreimage).join(",")}]`;
24
- }
25
- if (type !== "object") {
26
- return "null";
27
- }
28
- const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
29
- return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalPreimage(v)}`).join(",")}}`;
30
- }
31
- var K = new Uint32Array([
32
- 1116352408,
33
- 1899447441,
34
- 3049323471,
35
- 3921009573,
36
- 961987163,
37
- 1508970993,
38
- 2453635748,
39
- 2870763221,
40
- 3624381080,
41
- 310598401,
42
- 607225278,
43
- 1426881987,
44
- 1925078388,
45
- 2162078206,
46
- 2614888103,
47
- 3248222580,
48
- 3835390401,
49
- 4022224774,
50
- 264347078,
51
- 604807628,
52
- 770255983,
53
- 1249150122,
54
- 1555081692,
55
- 1996064986,
56
- 2554220882,
57
- 2821834349,
58
- 2952996808,
59
- 3210313671,
60
- 3336571891,
61
- 3584528711,
62
- 113926993,
63
- 338241895,
64
- 666307205,
65
- 773529912,
66
- 1294757372,
67
- 1396182291,
68
- 1695183700,
69
- 1986661051,
70
- 2177026350,
71
- 2456956037,
72
- 2730485921,
73
- 2820302411,
74
- 3259730800,
75
- 3345764771,
76
- 3516065817,
77
- 3600352804,
78
- 4094571909,
79
- 275423344,
80
- 430227734,
81
- 506948616,
82
- 659060556,
83
- 883997877,
84
- 958139571,
85
- 1322822218,
86
- 1537002063,
87
- 1747873779,
88
- 1955562222,
89
- 2024104815,
90
- 2227730452,
91
- 2361852424,
92
- 2428436474,
93
- 2756734187,
94
- 3204031479,
95
- 3329325298
96
- ]);
97
- function rotr(value, bits) {
98
- return (value >>> bits | value << 32 - bits) >>> 0;
99
- }
100
- function sha256Hex(message) {
101
- const bytes = new TextEncoder().encode(message);
102
- const length = bytes.length;
103
- const bitLength = length * 8;
104
- const withMarker = length + 1;
105
- const zeroPad = (56 - withMarker % 64 + 64) % 64;
106
- const total = withMarker + zeroPad + 8;
107
- const buffer = new Uint8Array(total);
108
- buffer.set(bytes, 0);
109
- buffer[length] = 128;
110
- const view = new DataView(buffer.buffer);
111
- view.setUint32(total - 8, Math.floor(bitLength / 4294967296));
112
- view.setUint32(total - 4, bitLength >>> 0);
113
- let h0 = 1779033703;
114
- let h1 = 3144134277;
115
- let h2 = 1013904242;
116
- let h3 = 2773480762;
117
- let h4 = 1359893119;
118
- let h5 = 2600822924;
119
- let h6 = 528734635;
120
- let h7 = 1541459225;
121
- const w = new Uint32Array(64);
122
- for (let chunk = 0; chunk < total; chunk += 64) {
123
- for (let t = 0; t < 16; t++) w[t] = view.getUint32(chunk + t * 4);
124
- for (let t = 16; t < 64; t++) {
125
- const w15 = w[t - 15];
126
- const w2 = w[t - 2];
127
- const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
128
- const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
129
- w[t] = w[t - 16] + s0 + w[t - 7] + s1 >>> 0;
130
- }
131
- let a = h0;
132
- let b = h1;
133
- let c = h2;
134
- let d = h3;
135
- let e = h4;
136
- let f = h5;
137
- let g = h6;
138
- let h = h7;
139
- for (let t = 0; t < 64; t++) {
140
- const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
141
- const ch = e & f ^ ~e & g;
142
- const temp1 = h + s1 + ch + K[t] + w[t] >>> 0;
143
- const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
144
- const maj = a & b ^ a & c ^ b & c;
145
- const temp2 = s0 + maj >>> 0;
146
- h = g;
147
- g = f;
148
- f = e;
149
- e = d + temp1 >>> 0;
150
- d = c;
151
- c = b;
152
- b = a;
153
- a = temp1 + temp2 >>> 0;
154
- }
155
- h0 = h0 + a >>> 0;
156
- h1 = h1 + b >>> 0;
157
- h2 = h2 + c >>> 0;
158
- h3 = h3 + d >>> 0;
159
- h4 = h4 + e >>> 0;
160
- h5 = h5 + f >>> 0;
161
- h6 = h6 + g >>> 0;
162
- h7 = h7 + h >>> 0;
163
- }
164
- return [h0, h1, h2, h3, h4, h5, h6, h7].map((value) => value.toString(16).padStart(8, "0")).join("");
165
- }
166
- function contractHash(body) {
167
- return sha256Hex(canonicalPreimage(body));
168
- }
169
-
170
- // src/registry.ts
171
12
  var REGISTRY_MANIFEST_SCHEMA_VERSION = "fragments.registry.v1";
172
13
  var REGISTRY_ARTIFACT_SCHEMA_VERSION = "fragments.registry-artifact.v1";
173
14
  var REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION = "fragments.registry-lock.v1";
@@ -289,6 +130,8 @@ var registryManifestBaseSchema = z.object({
289
130
  generatedAt: z.string().datetime(),
290
131
  source: registrySourceSchema,
291
132
  packageFiles: z.array(registryFileSchema).default([]),
133
+ /** Files every install writes, whatever the selection: the stylesheet entry and its closure. */
134
+ baseFiles: z.array(registryFileSchema).default([]),
292
135
  entrypoints: z.array(registryEntrypointSchema).default([]),
293
136
  components: z.record(z.string(), registryComponentSchema),
294
137
  dependencies: z.array(registryDependencySchema).default([]),
@@ -315,6 +158,7 @@ var registryArtifactSchema = z.object({
315
158
  }
316
159
  const manifestFiles = [
317
160
  ...artifact.manifest.packageFiles,
161
+ ...artifact.manifest.baseFiles,
318
162
  ...artifact.manifest.entrypoints.map((entrypoint) => ({
319
163
  path: entrypoint.sourcePath,
320
164
  role: "barrel",
@@ -456,11 +300,176 @@ function registryArtifactDigest(artifact) {
456
300
  function registryManifestCanonicalPreimage(manifest) {
457
301
  return canonicalPreimage(registryHashPayload(manifest));
458
302
  }
303
+ var REGISTRY_INDEX_SCHEMA_VERSION = "fragments.registry-index.v2";
304
+ var REGISTRY_SHARD_SCHEMA_VERSION = "fragments.registry-shard.v2";
305
+ var registryShardPathSchema = registryFilePathSchema.superRefine((value, ctx) => {
306
+ if (!value.endsWith(".json")) {
307
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Shard path must end with .json" });
308
+ }
309
+ });
310
+ var registryShardSchema = z.object({
311
+ schemaVersion: z.literal(REGISTRY_SHARD_SCHEMA_VERSION),
312
+ files: z.record(z.string().min(1), registryFileContentSchema)
313
+ }).superRefine((shard, ctx) => {
314
+ for (const [contentRef, file] of Object.entries(shard.files)) {
315
+ if (contentRef !== `sha256:${file.sha256}`) {
316
+ ctx.addIssue({
317
+ code: z.ZodIssueCode.custom,
318
+ path: ["files", contentRef],
319
+ message: `Shard key ${contentRef} does not match content hash of ${file.path}`
320
+ });
321
+ }
322
+ }
323
+ });
324
+ var registryIndexSchema = z.object({
325
+ schemaVersion: z.literal(REGISTRY_INDEX_SCHEMA_VERSION),
326
+ manifest: registryManifestSchema,
327
+ /** Shard path (relative to the index) → registry file paths whose bodies it carries. */
328
+ shards: z.record(registryShardPathSchema, z.array(registryFilePathSchema).min(1))
329
+ }).superRefine((index, ctx) => {
330
+ const owner = /* @__PURE__ */ new Map();
331
+ for (const [shardPath, paths] of Object.entries(index.shards)) {
332
+ for (const path of paths) {
333
+ const existing = owner.get(path);
334
+ if (existing) {
335
+ ctx.addIssue({
336
+ code: z.ZodIssueCode.custom,
337
+ path: ["shards", shardPath],
338
+ message: `Registry file ${path} is listed in both ${existing} and ${shardPath}`
339
+ });
340
+ }
341
+ owner.set(path, shardPath);
342
+ }
343
+ }
344
+ for (const path of registryManifestFilePaths(index.manifest)) {
345
+ if (!owner.has(path)) {
346
+ ctx.addIssue({
347
+ code: z.ZodIssueCode.custom,
348
+ path: ["shards"],
349
+ message: `Registry file ${path} is not carried by any shard`
350
+ });
351
+ }
352
+ }
353
+ });
354
+ var REGISTRY_POINTER_SCHEMA_VERSION = "fragments.registry-pointer.v1";
355
+ var registryPointerSchema = z.object({
356
+ schemaVersion: z.literal(REGISTRY_POINTER_SCHEMA_VERSION),
357
+ registryId: z.string().min(1),
358
+ version: z.string().min(1),
359
+ registryHash: sha256Schema,
360
+ index: registryShardPathSchema,
361
+ generatedAt: z.string().datetime()
362
+ });
363
+ function buildRegistryPointer(index, indexPath) {
364
+ return registryPointerSchema.parse({
365
+ schemaVersion: REGISTRY_POINTER_SCHEMA_VERSION,
366
+ registryId: index.manifest.registryId,
367
+ version: index.manifest.version,
368
+ registryHash: index.manifest.registryHash,
369
+ index: indexPath,
370
+ generatedAt: index.manifest.generatedAt
371
+ });
372
+ }
373
+ function registryManifestFilePaths(manifest) {
374
+ return [...registryManifestFileMetadata(manifest).keys()].sort(
375
+ (left, right) => left.localeCompare(right)
376
+ );
377
+ }
378
+ function registryManifestFileMetadata(manifest) {
379
+ const files = /* @__PURE__ */ new Map();
380
+ const add = (file) => {
381
+ if (!files.get(file.path)) files.set(file.path, file);
382
+ };
383
+ manifest.packageFiles.forEach(add);
384
+ manifest.baseFiles.forEach(add);
385
+ for (const component of Object.values(manifest.components)) component.files.forEach(add);
386
+ for (const entrypoint of manifest.entrypoints) {
387
+ if (!files.has(entrypoint.sourcePath)) files.set(entrypoint.sourcePath, null);
388
+ }
389
+ return files;
390
+ }
391
+ function defaultRegistryShardPath(path) {
392
+ const componentMatch = /^src\/components\/([^/]+)\//.exec(path);
393
+ if (componentMatch) return `components/${componentMatch[1]}.json`;
394
+ if (!path.startsWith("src/")) return "shared/package.json";
395
+ const segments = path.slice("src/".length).split("/");
396
+ return segments.length > 1 ? `shared/${segments[0]}.json` : "shared/src.json";
397
+ }
398
+ function shardKeyFor(metadata, sha256) {
399
+ return metadata?.contentRef ?? `sha256:${sha256}`;
400
+ }
401
+ function shardRegistryArtifact(artifact, shardPathFor = defaultRegistryShardPath) {
402
+ const metadata = registryManifestFileMetadata(artifact.manifest);
403
+ const shards = /* @__PURE__ */ new Map();
404
+ const shardPaths = {};
405
+ for (const [path, content] of Object.entries(artifact.files).sort(
406
+ ([left], [right]) => left.localeCompare(right)
407
+ )) {
408
+ const shardPath = shardPathFor(path);
409
+ const shard = shards.get(shardPath) ?? {
410
+ schemaVersion: REGISTRY_SHARD_SCHEMA_VERSION,
411
+ files: {}
412
+ };
413
+ shard.files[shardKeyFor(metadata.get(path), content.sha256)] = content;
414
+ shards.set(shardPath, shard);
415
+ (shardPaths[shardPath] ??= []).push(path);
416
+ }
417
+ const index = registryIndexSchema.parse({
418
+ schemaVersion: REGISTRY_INDEX_SCHEMA_VERSION,
419
+ manifest: artifact.manifest,
420
+ shards: shardPaths
421
+ });
422
+ for (const [path, shard] of shards) shards.set(path, registryShardSchema.parse(shard));
423
+ return { index, shards };
424
+ }
425
+ function shardOwnerMap(index) {
426
+ const owner = /* @__PURE__ */ new Map();
427
+ for (const [shardPath, paths] of Object.entries(index.shards)) {
428
+ for (const path of paths) owner.set(path, shardPath);
429
+ }
430
+ return owner;
431
+ }
432
+ function registryShardsForPaths(index, paths) {
433
+ const owner = shardOwnerMap(index);
434
+ const shards = /* @__PURE__ */ new Set();
435
+ for (const path of paths) {
436
+ const shardPath = owner.get(path);
437
+ if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);
438
+ shards.add(shardPath);
439
+ }
440
+ return [...shards].sort((left, right) => left.localeCompare(right));
441
+ }
442
+ function assembleRegistryArtifact(args) {
443
+ const metadata = registryManifestFileMetadata(args.index.manifest);
444
+ const owner = shardOwnerMap(args.index);
445
+ const files = {};
446
+ for (const path of [...new Set(args.paths)].sort((left, right) => left.localeCompare(right))) {
447
+ const shardPath = owner.get(path);
448
+ if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);
449
+ const shard = args.shards.get(shardPath);
450
+ if (!shard) throw new Error(`Registry shard ${shardPath} was not loaded (needed for ${path})`);
451
+ const expected = metadata.get(path) ?? null;
452
+ const content = expected ? shard.files[expected.contentRef] : Object.values(shard.files).find((file) => file.path === path);
453
+ if (!content || content.path !== path) {
454
+ throw new Error(`Registry shard ${shardPath} is missing content for ${path}`);
455
+ }
456
+ const actualSha256 = hashRegistryFileContent(content.content);
457
+ const actualSize = registryFileSize(content.content);
458
+ const expectedSha256 = expected?.sha256 ?? content.sha256;
459
+ const expectedSize = expected?.size ?? content.size;
460
+ if (actualSha256 !== expectedSha256 || actualSize !== expectedSize) {
461
+ throw new Error(`Registry shard ${shardPath} content for ${path} does not match the index`);
462
+ }
463
+ files[path] = content;
464
+ }
465
+ return {
466
+ schemaVersion: REGISTRY_ARTIFACT_SCHEMA_VERSION,
467
+ manifest: args.index.manifest,
468
+ files
469
+ };
470
+ }
459
471
 
460
472
  export {
461
- canonicalPreimage,
462
- sha256Hex,
463
- contractHash,
464
473
  REGISTRY_MANIFEST_SCHEMA_VERSION,
465
474
  REGISTRY_ARTIFACT_SCHEMA_VERSION,
466
475
  REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
@@ -488,6 +497,19 @@ export {
488
497
  buildRegistryArtifact,
489
498
  assertValidRegistryArtifact,
490
499
  registryArtifactDigest,
491
- registryManifestCanonicalPreimage
500
+ registryManifestCanonicalPreimage,
501
+ REGISTRY_INDEX_SCHEMA_VERSION,
502
+ REGISTRY_SHARD_SCHEMA_VERSION,
503
+ registryShardSchema,
504
+ registryIndexSchema,
505
+ REGISTRY_POINTER_SCHEMA_VERSION,
506
+ registryPointerSchema,
507
+ buildRegistryPointer,
508
+ registryManifestFilePaths,
509
+ registryManifestFileMetadata,
510
+ defaultRegistryShardPath,
511
+ shardRegistryArtifact,
512
+ registryShardsForPaths,
513
+ assembleRegistryArtifact
492
514
  };
493
- //# sourceMappingURL=chunk-YF65VYRY.js.map
515
+ //# sourceMappingURL=chunk-ML5S6QNU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { portableRepoPathError } from \"./config-paths.js\";\nimport { canonicalPreimage, contractHash, sha256Hex } from \"./contract/hash.js\";\n\nexport const REGISTRY_MANIFEST_SCHEMA_VERSION = \"fragments.registry.v1\";\nexport const REGISTRY_ARTIFACT_SCHEMA_VERSION = \"fragments.registry-artifact.v1\";\nexport const REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION = \"fragments.registry-lock.v1\";\n\nconst sha256Schema = z.string().regex(/^[0-9a-f]{64}$/);\n\nconst registryPathSchema = z\n .string()\n .min(1)\n .superRefine((value, ctx) => {\n const error = portableRepoPathError(value);\n if (error) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: error });\n }\n });\n\nconst registryFilePathSchema = registryPathSchema.superRefine((value, ctx) => {\n if (value === \".\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"File path must point to a file, not the package root\",\n });\n }\n});\n\nexport const registryDependencyTypeSchema = z.enum([\"runtime\", \"peer\", \"dev\", \"optional\"]);\n\nexport const registryDependencySchema = z.object({\n name: z.string().min(1),\n versionRange: z.string().min(1),\n type: registryDependencyTypeSchema,\n optional: z.boolean().optional(),\n});\n\nexport const registryFileRoleSchema = z.enum([\n \"source\",\n \"style\",\n \"token\",\n \"contract\",\n \"test\",\n \"story\",\n \"example\",\n \"asset\",\n \"barrel\",\n \"metadata\",\n]);\n\nexport const registryFileSchema = z.object({\n path: registryFilePathSchema,\n role: registryFileRoleSchema,\n sha256: sha256Schema,\n size: z.number().int().nonnegative(),\n contentType: z.string().min(1),\n contentRef: z.string().min(1),\n});\n\nexport const registryFileContentSchema = z.object({\n path: registryFilePathSchema,\n content: z.string(),\n sha256: sha256Schema,\n size: z.number().int().nonnegative(),\n contentType: z.string().min(1),\n});\n\nexport const registrySourceSchema = z.discriminatedUnion(\"kind\", [\n z.object({\n kind: z.literal(\"package\"),\n packageName: z.string().min(1),\n version: z.string().optional(),\n rootPath: registryPathSchema.optional(),\n commitSha: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"github\"),\n repoFullName: z.string().min(1),\n commitSha: z.string().min(1),\n path: registryPathSchema.optional(),\n }),\n z.object({\n kind: z.literal(\"local\"),\n rootPath: registryPathSchema.optional(),\n commitSha: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"manual\"),\n label: z.string().min(1),\n }),\n]);\n\nexport const registryComponentExportSchema = z.object({\n name: z.string().min(1),\n kind: z.enum([\"component\", \"hook\", \"utility\", \"type\", \"style\"]).default(\"component\"),\n path: registryFilePathSchema.optional(),\n});\n\nexport const registryComponentSchema = z.object({\n componentId: z.string().min(1),\n publicRef: z.string().min(1),\n name: z.string().min(1),\n status: z.string().min(1).default(\"stable\"),\n tier: z.enum([\"core\", \"composition\", \"utility\", \"custom\"]).default(\"core\"),\n category: z.string().optional(),\n files: z.array(registryFileSchema).min(1),\n styleFiles: z.array(registryFilePathSchema).default([]),\n tokenDependencies: z.array(z.string().min(1)).default([]),\n runtimeDependencies: z.array(registryDependencySchema).default([]),\n peerDependencies: z.array(registryDependencySchema).default([]),\n internalDependencies: z.array(z.string().min(1)).default([]),\n exports: z.array(registryComponentExportSchema).default([]),\n contract: z.unknown().optional(),\n examples: z.array(z.unknown()).default([]),\n provenance: z.record(z.unknown()).default({}),\n});\n\nexport const registryEntrypointSchema = z.object({\n specifier: z.string().min(1),\n sourcePath: registryFilePathSchema,\n});\n\nexport const registryInstallProfileSchema = z.object({\n name: z.string().min(1),\n targetPath: registryPathSchema,\n importPath: z.string().min(1),\n stylePath: registryPathSchema.optional(),\n includeTests: z.boolean().default(false),\n});\n\nconst registryManifestBaseSchema = z.object({\n schemaVersion: z.literal(REGISTRY_MANIFEST_SCHEMA_VERSION),\n registryId: z.string().min(1),\n name: z.string().min(1),\n channel: z.string().min(1),\n version: z.string().min(1),\n contractVersionId: z.string().optional(),\n fcid: sha256Schema.optional(),\n generatedAt: z.string().datetime(),\n source: registrySourceSchema,\n packageFiles: z.array(registryFileSchema).default([]),\n /** Files every install writes, whatever the selection: the stylesheet entry and its closure. */\n baseFiles: z.array(registryFileSchema).default([]),\n entrypoints: z.array(registryEntrypointSchema).default([]),\n components: z.record(z.string(), registryComponentSchema),\n dependencies: z.array(registryDependencySchema).default([]),\n installProfiles: z.array(registryInstallProfileSchema).default([]),\n});\n\nexport const registryManifestDraftSchema = registryManifestBaseSchema;\n\nexport const registryManifestSchema = registryManifestBaseSchema.extend({\n registryHash: sha256Schema,\n});\n\nexport const registryArtifactSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_ARTIFACT_SCHEMA_VERSION),\n manifest: registryManifestSchema,\n files: z.record(registryFilePathSchema, registryFileContentSchema),\n })\n .superRefine((artifact, ctx) => {\n const filesByPath = artifact.files;\n for (const [path, content] of Object.entries(filesByPath)) {\n if (content.path !== path) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", path, \"path\"],\n message: `Registry file map key ${path} does not match content path ${content.path}`,\n });\n }\n }\n\n const manifestFiles = [\n ...artifact.manifest.packageFiles,\n ...artifact.manifest.baseFiles,\n ...artifact.manifest.entrypoints.map((entrypoint) => ({\n path: entrypoint.sourcePath,\n role: \"barrel\" as const,\n sha256: filesByPath[entrypoint.sourcePath]?.sha256 ?? \"\",\n size: filesByPath[entrypoint.sourcePath]?.size ?? 0,\n contentType: filesByPath[entrypoint.sourcePath]?.contentType ?? \"text/plain\",\n contentRef: `sha256:${filesByPath[entrypoint.sourcePath]?.sha256 ?? \"\"}`,\n })),\n ...Object.values(artifact.manifest.components).flatMap((component) => component.files),\n ];\n\n for (const file of manifestFiles) {\n const content = filesByPath[file.path];\n if (!content) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path],\n message: `Missing content for registry file ${file.path}`,\n });\n continue;\n }\n if (content.sha256 !== file.sha256) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path, \"sha256\"],\n message: `Content hash for ${file.path} does not match manifest`,\n });\n }\n if (content.size !== file.size) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path, \"size\"],\n message: `Content size for ${file.path} does not match manifest`,\n });\n }\n }\n });\n\nexport const registryInstallReceiptFileSchema = z.object({\n path: registryFilePathSchema,\n sha256: sha256Schema,\n sourcePath: registryFilePathSchema,\n componentId: z.string().min(1).optional(),\n});\n\nexport const registryInstallReceiptComponentSchema = z.object({\n componentId: z.string().min(1),\n publicRef: z.string().min(1),\n name: z.string().min(1),\n files: z.array(registryFilePathSchema),\n});\n\nexport const registryInstallReceiptSchema = z.object({\n schemaVersion: z.literal(REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION),\n registryId: z.string().min(1),\n registryVersion: z.string().min(1),\n registryHash: sha256Schema,\n fcid: sha256Schema.optional(),\n channel: z.string().min(1).optional(),\n targetPath: registryPathSchema,\n importPath: z.string().min(1),\n installedComponents: z.array(registryInstallReceiptComponentSchema),\n files: z.array(registryInstallReceiptFileSchema),\n dependencies: z.array(registryDependencySchema).default([]),\n installedAt: z.string().datetime(),\n});\n\nexport type RegistryDependencyType = z.infer<typeof registryDependencyTypeSchema>;\nexport type RegistryDependency = z.infer<typeof registryDependencySchema>;\nexport type RegistryFileRole = z.infer<typeof registryFileRoleSchema>;\nexport type RegistryFile = z.infer<typeof registryFileSchema>;\nexport type RegistryFileContent = z.infer<typeof registryFileContentSchema>;\nexport type RegistrySource = z.infer<typeof registrySourceSchema>;\nexport type RegistryComponentExport = z.infer<typeof registryComponentExportSchema>;\nexport type RegistryComponent = z.infer<typeof registryComponentSchema>;\nexport type RegistryEntrypoint = z.infer<typeof registryEntrypointSchema>;\nexport type RegistryInstallProfile = z.infer<typeof registryInstallProfileSchema>;\nexport type RegistryManifestDraft = z.input<typeof registryManifestDraftSchema>;\nexport type RegistryManifest = z.infer<typeof registryManifestSchema>;\nexport type RegistryArtifact = z.infer<typeof registryArtifactSchema>;\nexport type RegistryInstallReceiptFile = z.infer<typeof registryInstallReceiptFileSchema>;\nexport type RegistryInstallReceiptComponent = z.infer<typeof registryInstallReceiptComponentSchema>;\nexport type RegistryInstallReceipt = z.infer<typeof registryInstallReceiptSchema>;\n\nexport interface RegistryFileInput {\n path: string;\n role: RegistryFileRole;\n content: string;\n contentType: string;\n contentRef?: string;\n}\n\nexport interface RegistryArtifactInput {\n manifest: RegistryManifestDraft;\n files: readonly RegistryFileContent[];\n}\n\nfunction registryHashPayload(manifest: RegistryManifestDraft | RegistryManifest): unknown {\n const { generatedAt: _generatedAt, ...withoutGeneratedAt } = manifest;\n if (\"registryHash\" in withoutGeneratedAt) {\n const { registryHash: _registryHash, ...withoutHash } = withoutGeneratedAt;\n return withoutHash;\n }\n return withoutGeneratedAt;\n}\n\nexport function computeRegistryHash(manifest: RegistryManifestDraft | RegistryManifest): string {\n return contractHash(registryHashPayload(manifest));\n}\n\nexport function finalizeRegistryManifest(input: RegistryManifestDraft): RegistryManifest {\n const draft = registryManifestDraftSchema.parse(input);\n return registryManifestSchema.parse({\n ...draft,\n registryHash: computeRegistryHash(draft),\n });\n}\n\nexport function hashRegistryFileContent(content: string): string {\n return sha256Hex(content);\n}\n\nexport function registryFileSize(content: string): number {\n return new TextEncoder().encode(content).length;\n}\n\nexport function buildRegistryFile(input: RegistryFileInput): {\n metadata: RegistryFile;\n content: RegistryFileContent;\n} {\n const sha256 = hashRegistryFileContent(input.content);\n const size = registryFileSize(input.content);\n const path = registryFilePathSchema.parse(input.path);\n const contentType = z.string().min(1).parse(input.contentType);\n return {\n metadata: registryFileSchema.parse({\n path,\n role: input.role,\n sha256,\n size,\n contentType,\n contentRef: input.contentRef ?? `sha256:${sha256}`,\n }),\n content: registryFileContentSchema.parse({\n path,\n content: input.content,\n sha256,\n size,\n contentType,\n }),\n };\n}\n\nexport function buildRegistryArtifact(input: RegistryArtifactInput): RegistryArtifact {\n const manifest = finalizeRegistryManifest(input.manifest);\n const files = new Map<string, RegistryFileContent>();\n for (const file of input.files) {\n const content = registryFileContentSchema.parse(file);\n if (files.has(content.path)) {\n throw new Error(`Duplicate registry file content for ${content.path}`);\n }\n files.set(content.path, content);\n }\n\n return registryArtifactSchema.parse({\n schemaVersion: REGISTRY_ARTIFACT_SCHEMA_VERSION,\n manifest,\n files: Object.fromEntries(files),\n });\n}\n\nexport function assertValidRegistryArtifact(artifact: unknown): RegistryArtifact {\n return registryArtifactSchema.parse(artifact);\n}\n\nexport function registryArtifactDigest(artifact: RegistryArtifact): string {\n const files = Object.fromEntries(\n Object.entries(artifact.files)\n .map(([path, file]) => [path, { sha256: file.sha256, size: file.size }] as const)\n .sort(([leftPath], [rightPath]) => leftPath.localeCompare(rightPath))\n );\n\n return contractHash({\n schemaVersion: artifact.schemaVersion,\n manifest: registryHashPayload(artifact.manifest),\n files,\n });\n}\n\nexport function registryManifestCanonicalPreimage(\n manifest: RegistryManifestDraft | RegistryManifest\n): string {\n return canonicalPreimage(registryHashPayload(manifest));\n}\n\n// ============================================================================\n// Sharded artifact (schema v2): index without bodies + content shards\n// ============================================================================\n\nexport const REGISTRY_INDEX_SCHEMA_VERSION = \"fragments.registry-index.v2\";\nexport const REGISTRY_SHARD_SCHEMA_VERSION = \"fragments.registry-shard.v2\";\n\nconst registryShardPathSchema = registryFilePathSchema.superRefine((value, ctx) => {\n if (!value.endsWith(\".json\")) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Shard path must end with .json\" });\n }\n});\n\nexport const registryShardSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_SHARD_SCHEMA_VERSION),\n files: z.record(z.string().min(1), registryFileContentSchema),\n })\n .superRefine((shard, ctx) => {\n for (const [contentRef, file] of Object.entries(shard.files)) {\n if (contentRef !== `sha256:${file.sha256}`) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", contentRef],\n message: `Shard key ${contentRef} does not match content hash of ${file.path}`,\n });\n }\n }\n });\n\nexport const registryIndexSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_INDEX_SCHEMA_VERSION),\n manifest: registryManifestSchema,\n /** Shard path (relative to the index) → registry file paths whose bodies it carries. */\n shards: z.record(registryShardPathSchema, z.array(registryFilePathSchema).min(1)),\n })\n .superRefine((index, ctx) => {\n const owner = new Map<string, string>();\n for (const [shardPath, paths] of Object.entries(index.shards)) {\n for (const path of paths) {\n const existing = owner.get(path);\n if (existing) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"shards\", shardPath],\n message: `Registry file ${path} is listed in both ${existing} and ${shardPath}`,\n });\n }\n owner.set(path, shardPath);\n }\n }\n for (const path of registryManifestFilePaths(index.manifest)) {\n if (!owner.has(path)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"shards\"],\n message: `Registry file ${path} is not carried by any shard`,\n });\n }\n }\n });\n\n/**\n * A short-lived pointer (`latest.json`) to an immutable versioned index. One hop only;\n * `index` is a relative path so the hop cannot leave the pointer's origin.\n */\nexport const REGISTRY_POINTER_SCHEMA_VERSION = \"fragments.registry-pointer.v1\";\n\nexport const registryPointerSchema = z.object({\n schemaVersion: z.literal(REGISTRY_POINTER_SCHEMA_VERSION),\n registryId: z.string().min(1),\n version: z.string().min(1),\n registryHash: sha256Schema,\n index: registryShardPathSchema,\n generatedAt: z.string().datetime(),\n});\n\nexport type RegistryShard = z.infer<typeof registryShardSchema>;\nexport type RegistryIndex = z.infer<typeof registryIndexSchema>;\nexport type RegistryPointer = z.infer<typeof registryPointerSchema>;\n\nexport function buildRegistryPointer(index: RegistryIndex, indexPath: string): RegistryPointer {\n return registryPointerSchema.parse({\n schemaVersion: REGISTRY_POINTER_SCHEMA_VERSION,\n registryId: index.manifest.registryId,\n version: index.manifest.version,\n registryHash: index.manifest.registryHash,\n index: indexPath,\n generatedAt: index.manifest.generatedAt,\n });\n}\n\n/** Every file path the manifest references, sorted and unique. */\nexport function registryManifestFilePaths(manifest: RegistryManifest): string[] {\n return [...registryManifestFileMetadata(manifest).keys()].sort((left, right) =>\n left.localeCompare(right)\n );\n}\n\n/** Path → metadata for every manifest file; entrypoint-only paths map to `null`. */\nexport function registryManifestFileMetadata(\n manifest: RegistryManifest\n): Map<string, RegistryFile | null> {\n const files = new Map<string, RegistryFile | null>();\n const add = (file: RegistryFile) => {\n if (!files.get(file.path)) files.set(file.path, file);\n };\n manifest.packageFiles.forEach(add);\n manifest.baseFiles.forEach(add);\n for (const component of Object.values(manifest.components)) component.files.forEach(add);\n for (const entrypoint of manifest.entrypoints) {\n if (!files.has(entrypoint.sourcePath)) files.set(entrypoint.sourcePath, null);\n }\n return files;\n}\n\n/**\n * Default shard layout: one shard per component directory, one shard per shared\n * top-level directory under `src/` (`shared/tokens.json`, `shared/utils.json`, …),\n * `shared/src.json` for files directly under `src/`, and `shared/package.json` for\n * package-root files (`package.json`, `fragments.json`) that only complete installs need.\n */\nexport function defaultRegistryShardPath(path: string): string {\n const componentMatch = /^src\\/components\\/([^/]+)\\//.exec(path);\n if (componentMatch) return `components/${componentMatch[1]}.json`;\n if (!path.startsWith(\"src/\")) return \"shared/package.json\";\n const segments = path.slice(\"src/\".length).split(\"/\");\n return segments.length > 1 ? `shared/${segments[0]}.json` : \"shared/src.json\";\n}\n\nexport interface ShardedRegistryArtifact {\n index: RegistryIndex;\n shards: Map<string, RegistryShard>;\n}\n\nfunction shardKeyFor(metadata: RegistryFile | null | undefined, sha256: string): string {\n return metadata?.contentRef ?? `sha256:${sha256}`;\n}\n\nexport function shardRegistryArtifact(\n artifact: RegistryArtifact,\n shardPathFor: (path: string) => string = defaultRegistryShardPath\n): ShardedRegistryArtifact {\n const metadata = registryManifestFileMetadata(artifact.manifest);\n const shards = new Map<string, RegistryShard>();\n const shardPaths: Record<string, string[]> = {};\n\n for (const [path, content] of Object.entries(artifact.files).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n const shardPath = shardPathFor(path);\n const shard = shards.get(shardPath) ?? {\n schemaVersion: REGISTRY_SHARD_SCHEMA_VERSION,\n files: {},\n };\n shard.files[shardKeyFor(metadata.get(path), content.sha256)] = content;\n shards.set(shardPath, shard);\n (shardPaths[shardPath] ??= []).push(path);\n }\n\n const index = registryIndexSchema.parse({\n schemaVersion: REGISTRY_INDEX_SCHEMA_VERSION,\n manifest: artifact.manifest,\n shards: shardPaths,\n });\n for (const [path, shard] of shards) shards.set(path, registryShardSchema.parse(shard));\n return { index, shards };\n}\n\nfunction shardOwnerMap(index: RegistryIndex): Map<string, string> {\n const owner = new Map<string, string>();\n for (const [shardPath, paths] of Object.entries(index.shards)) {\n for (const path of paths) owner.set(path, shardPath);\n }\n return owner;\n}\n\n/** The shards (sorted, unique) that carry the given registry file paths. */\nexport function registryShardsForPaths(index: RegistryIndex, paths: readonly string[]): string[] {\n const owner = shardOwnerMap(index);\n const shards = new Set<string>();\n for (const path of paths) {\n const shardPath = owner.get(path);\n if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);\n shards.add(shardPath);\n }\n return [...shards].sort((left, right) => left.localeCompare(right));\n}\n\n/**\n * Rebuild a v1-shaped artifact from an index plus the shards that cover `paths`.\n * Only the requested paths are materialised; every body is checked against the\n * manifest's hash and size before it is accepted.\n */\nexport function assembleRegistryArtifact(args: {\n index: RegistryIndex;\n shards: ReadonlyMap<string, RegistryShard>;\n paths: readonly string[];\n}): RegistryArtifact {\n const metadata = registryManifestFileMetadata(args.index.manifest);\n const owner = shardOwnerMap(args.index);\n const files: Record<string, RegistryFileContent> = {};\n\n for (const path of [...new Set(args.paths)].sort((left, right) => left.localeCompare(right))) {\n const shardPath = owner.get(path);\n if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);\n const shard = args.shards.get(shardPath);\n if (!shard) throw new Error(`Registry shard ${shardPath} was not loaded (needed for ${path})`);\n const expected = metadata.get(path) ?? null;\n const content = expected\n ? shard.files[expected.contentRef]\n : Object.values(shard.files).find((file) => file.path === path);\n if (!content || content.path !== path) {\n throw new Error(`Registry shard ${shardPath} is missing content for ${path}`);\n }\n // Re-hash the body: a shard's own sha256/size fields are claims, the index is the truth.\n const actualSha256 = hashRegistryFileContent(content.content);\n const actualSize = registryFileSize(content.content);\n const expectedSha256 = expected?.sha256 ?? content.sha256;\n const expectedSize = expected?.size ?? content.size;\n if (actualSha256 !== expectedSha256 || actualSize !== expectedSize) {\n throw new Error(`Registry shard ${shardPath} content for ${path} does not match the index`);\n }\n files[path] = content;\n }\n\n return {\n schemaVersion: REGISTRY_ARTIFACT_SCHEMA_VERSION,\n manifest: args.index.manifest,\n files,\n };\n}\n"],"mappings":"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","names":[]}
@@ -108,4 +108,4 @@ function resolveArea(repoRelPath, topology) {
108
108
  export {
109
109
  resolveArea
110
110
  };
111
- //# sourceMappingURL=chunk-3LLRNCPX.js.map
111
+ //# sourceMappingURL=chunk-MZ2FS7U4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/topology/resolve-area.ts"],"sourcesContent":["/**\n * Topology — map a repo-relative file path to its product area.\n *\n * This is the DRY keystone of the topology layer: the ONLY area-matching\n * implementation in the monorepo. Consumers (CLI scan, Cloud managed-editor\n * preview, cross-repo reconciliation) import it; none reimplements glob/area\n * logic. Pure and browser-safe — no Node, no parser deps.\n *\n * See `docs/fragments-v1/ARCHITECTURE.md §1`.\n */\n\nexport type AreaCriticality = \"low\" | \"medium\" | \"high\" | \"revenue\" | \"regulated\";\n\nexport interface Area {\n id: string;\n name: string;\n criticality: AreaCriticality;\n owners: string[];\n /** Globs matched against repo-relative file paths in v0. */\n files: string[];\n /** Stored for later route-topology adapters; NOT matched in v0. */\n routes?: string[];\n /** Tie-break: higher wins. Defaults to declaration order. */\n priority?: number;\n}\n\nexport interface Topology {\n /** Bump signals \"re-tag\" to consumers that cache. */\n version: number;\n /** Whether area file globs are matched relative to app.path or repo root. Defaults to \"app\". */\n base?: \"app\" | \"repo\";\n /** Array (not a keyed record) so precedence is deterministic. */\n areas: Area[];\n}\n\nexport interface AreaMatch {\n areaId: string;\n areaName: string;\n criticality: AreaCriticality;\n owners: string[];\n /** The winning pattern — surfaced in reports for transparency. */\n matchedGlob: string;\n}\n\n/**\n * Compile a minimal glob to an anchored RegExp. We intentionally do NOT depend\n * on picomatch: core stays lean, the surface we need is small, and we want\n * exact control over Next.js route-group parens (`(marketing)` is a literal\n * path segment here, not an extglob group).\n *\n * Semantics:\n * - `/**` at a segment boundary (end-of-glob or before `/`) → \"this directory\n * and everything under it\": the leading slash is optional, so\n * `src/app/checkout/**` matches `src/app/checkout` AND any descendant.\n * - a bare/leading `**` → matches across path separators (`.*`). Note a\n * leading globstar-then-slash does NOT match the root (use a lone `**`\n * for \"everything\").\n * - `*` → matches within a single segment (`[^/]*`)\n * - `?` → a single non-separator char\n * - `{a,b}` → alternation `(?:a|b)`\n * - every other regex-significant char (`.`, `(`, `)`, `+`, …) is literal\n *\n * Throws on a malformed pattern (e.g. an unbalanced `{`). Callers compile via\n * `compile()`, which catches the throw so a config typo degrades one glob to a\n * non-match instead of aborting the whole scan.\n */\nfunction globToRegExp(glob: string): RegExp {\n let out = \"\";\n let braceDepth = 0;\n let i = 0;\n while (i < glob.length) {\n const ch = glob[i];\n\n // `/**` at a segment boundary → optional slash + anything-below. Matches\n // the directory itself (`a/**` ⇒ `a`) and every descendant.\n if (\n ch === \"/\" &&\n glob[i + 1] === \"*\" &&\n glob[i + 2] === \"*\" &&\n (glob[i + 3] === undefined || glob[i + 3] === \"/\")\n ) {\n out += \"(?:/.*)?\";\n i += 3; // consume `/**`; a trailing `/` (in `a/**/b`) is handled next pass\n continue;\n }\n\n // Bare/leading globstar — crosses path separators.\n if (ch === \"*\" && glob[i + 1] === \"*\") {\n out += \".*\";\n i += 2;\n continue;\n }\n\n switch (ch) {\n case \"*\":\n out += \"[^/]*\"; // single segment\n break;\n case \"?\":\n out += \"[^/]\";\n break;\n case \"{\":\n braceDepth += 1;\n out += \"(?:\";\n break;\n case \"}\":\n if (braceDepth > 0) {\n braceDepth -= 1;\n out += \")\";\n } else {\n out += \"\\\\}\";\n }\n break;\n case \",\":\n out += braceDepth > 0 ? \"|\" : \",\";\n break;\n // Regex-significant chars kept literal (parens cover route groups).\n case \".\":\n case \"(\":\n case \")\":\n case \"+\":\n case \"^\":\n case \"$\":\n case \"|\":\n case \"[\":\n case \"]\":\n case \"\\\\\":\n out += `\\\\${ch}`;\n break;\n default:\n out += ch;\n }\n i += 1;\n }\n return new RegExp(`^${out}$`);\n}\n\ninterface CompiledArea {\n area: Area;\n matchers: { glob: string; re: RegExp }[];\n}\n\n/**\n * Cache compiled matchers per topology object. Consumers pass the same\n * `topology` for every finding in a run, so this turns N×globs recompiles into\n * one. A reloaded config is a new object → fresh entry, so `version` bumps need\n * no manual invalidation.\n */\nconst compiledCache = new WeakMap<Topology, CompiledArea[]>();\n\nfunction compile(topology: Topology): CompiledArea[] {\n const cached = compiledCache.get(topology);\n if (cached) return cached;\n\n // Order by (priority desc, declaration order). Decorate-sort-undecorate keeps\n // the sort stable across engines.\n const ordered = topology.areas\n .map((area, index) => ({ area, index }))\n .sort((a, b) => {\n const pa = a.area.priority ?? 0;\n const pb = b.area.priority ?? 0;\n if (pa !== pb) return pb - pa;\n return a.index - b.index;\n })\n .map(({ area }) => ({\n area,\n matchers: area.files.flatMap((glob) => {\n try {\n return [{ glob, re: globToRegExp(glob) }];\n } catch {\n // A malformed glob (e.g. unbalanced `{`) compiles to an invalid\n // RegExp. Skip it rather than aborting the entire scan — topology\n // config is user-authored, so one typo must not take down\n // `fragments check`. Its files simply fall through to \"Unassigned\".\n if (typeof console !== \"undefined\") {\n console.warn(\n `[topology] ignoring invalid glob in area \"${area.id}\": ${JSON.stringify(glob)}`\n );\n }\n return [];\n }\n }),\n }));\n\n compiledCache.set(topology, ordered);\n return ordered;\n}\n\n/** Normalize to a POSIX, repo-relative path before matching. */\nfunction normalizePath(repoRelPath: string): string {\n return repoRelPath.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/^\\/+/, \"\");\n}\n\n/**\n * Resolve the product area for a repo-relative path. First match by\n * `(priority desc, declaration order)`. Returns `null` when nothing matches —\n * the caller buckets that as the explicit \"Unassigned\" area (never dropped;\n * dropping unmatched evidence would make coverage lie).\n */\nexport function resolveArea(repoRelPath: string, topology: Topology): AreaMatch | null {\n const path = normalizePath(repoRelPath);\n for (const { area, matchers } of compile(topology)) {\n for (const { glob, re } of matchers) {\n if (re.test(path)) {\n return {\n areaId: area.id,\n areaName: area.name,\n criticality: area.criticality,\n owners: area.owners,\n matchedGlob: glob,\n };\n }\n }\n }\n return null;\n}\n"],"mappings":"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","names":[]}