@cosmicdrift/kumiko-framework 0.221.0 → 0.223.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 (51) hide show
  1. package/package.json +7 -3
  2. package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +1 -3
  3. package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +1 -3
  4. package/src/api/__tests__/auth-routes-mfa-verify.test.ts +1 -3
  5. package/src/api/__tests__/pii-leak-guard.integration.test.ts +17 -5
  6. package/src/api/auth-routes.ts +3 -0
  7. package/src/api/pii-leak-guard.ts +4 -5
  8. package/src/arg-parser.ts +1 -1
  9. package/src/db/__tests__/table-builder-meta-lockstep.test.ts +29 -0
  10. package/src/db/entity-table-meta.ts +6 -1
  11. package/src/db/table-builder.ts +10 -3
  12. package/src/derivatives/__tests__/variant-key.test.ts +123 -1
  13. package/src/derivatives/derivatives-context.ts +4 -0
  14. package/src/derivatives/index.ts +9 -1
  15. package/src/derivatives/variant-key.ts +68 -0
  16. package/src/engine/__tests__/boot-validator.test.ts +113 -0
  17. package/src/engine/__tests__/schema-builder.test.ts +4 -4
  18. package/src/engine/boot-validator/entity-handler.ts +34 -1
  19. package/src/engine/extensions/storage-provider.ts +28 -0
  20. package/src/engine/extensions/user-data.ts +4 -0
  21. package/src/engine/factories.ts +13 -6
  22. package/src/engine/feature-ast/__tests__/parse.test.ts +1 -1
  23. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +1 -3
  24. package/src/engine/feature-ast/extractors/ai-steps.ts +26 -40
  25. package/src/engine/feature-ast/extractors/index.ts +2 -0
  26. package/src/engine/feature-ast/extractors/shared.ts +26 -1
  27. package/src/engine/feature-ast/parse.ts +10 -25
  28. package/src/engine/feature-ast/patch.ts +14 -16
  29. package/src/engine/feature-ast/render.ts +3 -3
  30. package/src/engine/field-helpers.ts +1 -1
  31. package/src/engine/index.ts +5 -0
  32. package/src/engine/pattern-library/mixed-schemas.ts +6 -0
  33. package/src/engine/schema-builder.ts +14 -2
  34. package/src/errors/__tests__/classes.test.ts +16 -2
  35. package/src/errors/__tests__/write-failures.test.ts +10 -0
  36. package/src/errors/classes.ts +14 -13
  37. package/src/errors/write-error-info.ts +1 -1
  38. package/src/files/__tests__/local-provider.contract.test.ts +14 -0
  39. package/src/files/in-memory-provider.ts +4 -0
  40. package/src/files/local-provider.ts +22 -1
  41. package/src/jobs/job-runner.ts +22 -10
  42. package/src/pipeline/__tests__/tenant-timezone-cache.test.ts +89 -0
  43. package/src/pipeline/dispatch-shared.ts +39 -2
  44. package/src/pipeline/dispatch-write.ts +48 -0
  45. package/src/pipeline/dispatcher.ts +5 -0
  46. package/src/pipeline/tenant-timezone-cache.ts +92 -0
  47. package/src/schema-cli.ts +30 -44
  48. package/src/scripts/codemod/pii-personal-migration.ts +7 -7
  49. package/src/stack/__tests__/request-helper.test.ts +2 -2
  50. package/src/testing/file-provider-contract.ts +19 -0
  51. package/src/upgrade-cli.ts +12 -1
@@ -90,6 +90,25 @@ export function describeFileProviderContract(
90
90
  await expect(it.next()).rejects.toThrow();
91
91
  });
92
92
 
93
+ test("list returns only keys under the given prefix", async () => {
94
+ const group = `contract/list-${crypto.randomUUID()}`;
95
+ const keyA = `${group}/a.txt`;
96
+ const keyB = `${group}/b.txt`;
97
+ const outsideKey = `contract/list-${crypto.randomUUID()}/c.txt`;
98
+ writtenKeys.push(keyA, keyB, outsideKey);
99
+ await provider.write(keyA, bytes("a"));
100
+ await provider.write(keyB, bytes("b"));
101
+ await provider.write(outsideKey, bytes("c"));
102
+
103
+ const listed = await provider.list(`${group}/`);
104
+ expect(new Set(listed)).toEqual(new Set([keyA, keyB]));
105
+ });
106
+
107
+ test("list on a prefix with no matches returns an empty array", async () => {
108
+ const listed = await provider.list(`contract/list-missing-${crypto.randomUUID()}/`);
109
+ expect(listed).toEqual([]);
110
+ });
111
+
93
112
  test("getSignedUrl, when implemented, returns a URL string", async () => {
94
113
  // skip: getSignedUrl is optional on the contract — feature-detected
95
114
  if (!provider.getSignedUrl) return;
@@ -271,10 +271,15 @@ type UpgradeMarkerCodemod = {
271
271
  readonly codemod: string;
272
272
  readonly title: string;
273
273
  };
274
+ type UpgradeMarkerManual = {
275
+ readonly version: string;
276
+ readonly title: string;
277
+ };
274
278
  type UpgradeMarker = {
275
279
  readonly version: string;
276
280
  readonly appliedAt: string;
277
281
  readonly codemods: readonly UpgradeMarkerCodemod[];
282
+ readonly pendingManual?: readonly UpgradeMarkerManual[];
278
283
  };
279
284
 
280
285
  function writeUpgradeMarker(targetDir: string, marker: UpgradeMarker): void {
@@ -324,6 +329,7 @@ function markerVersionForPending(
324
329
  // failure — no partial marker. Writes the marker whenever dryRun is false —
325
330
  // even with zero pending entries, so an already-current app still gets a
326
331
  // bootstrap marker recording its installed version (fw#2299).
332
+ // kumiko-lint-ignore complexity-budget sequential codemod runner with zero-pending bootstrap marker
327
333
  async function applyCodemods(
328
334
  out: UpgradeCliOut,
329
335
  pending: readonly ChangelogEntry[],
@@ -352,7 +358,7 @@ async function applyCodemods(
352
358
  const codemodEntries = breaking
353
359
  .filter(hasCodemod)
354
360
  .sort((a, b) => compareVersions(a.version, b.version));
355
- const manualEntries = breaking.filter((e) => !e.codemod);
361
+ const manualEntries = breaking.filter((e) => !hasCodemod(e));
356
362
 
357
363
  for (const e of manualEntries) {
358
364
  out.log(` ⚠ ${e.version} · ${e.title} — no codemod, manual migration required`);
@@ -407,14 +413,19 @@ async function applyCodemods(
407
413
  }
408
414
 
409
415
  const latestVersion = markerVersionForPending(pending, manualEntries, markerVersion);
416
+ const pendingManual = manualEntries.map((e) => ({ version: e.version, title: e.title }));
410
417
  writeUpgradeMarker(targetDir, {
411
418
  version: latestVersion,
412
419
  appliedAt: Temporal.Now.instant().toString(),
413
420
  codemods: ran,
421
+ ...(pendingManual.length > 0 && { pendingManual }),
414
422
  });
415
423
  out.log(
416
424
  ` ✓ Applied ${ran.length} codemod(s). Wrote ${join(targetDir, ".kumiko/upgrade-state.json")}`,
417
425
  );
426
+ if (pendingManual.length > 0) {
427
+ out.log(` ⚠ ${pendingManual.length} breaking change(s) still need manual migration.`);
428
+ }
418
429
  return 0;
419
430
  }
420
431