@ankhorage/zora 26.1.5 → 27.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 (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -13
  3. package/dist/capabilities/index.d.ts.map +1 -1
  4. package/dist/capabilities/index.js +2 -63
  5. package/dist/capabilities/index.js.map +3 -3
  6. package/package.json +5 -103
  7. package/src/capabilities/index.test.ts +4 -7
  8. package/src/capabilities/index.ts +1 -62
  9. package/src/invertedThemeAcceptance.test.tsx +1 -1
  10. package/src/packedWebConsumerAcceptance.test.ts +20 -0
  11. package/src/structureOwnership.test.ts +1 -1
  12. package/src/webPackageExports.test.ts +1 -0
  13. package/dist/cli/commands/create.d.ts +0 -14
  14. package/dist/cli/commands/create.d.ts.map +0 -1
  15. package/dist/cli/commands/create.js +0 -22
  16. package/dist/cli/commands/create.js.map +0 -1
  17. package/dist/cli/commands/sync.d.ts +0 -14
  18. package/dist/cli/commands/sync.d.ts.map +0 -1
  19. package/dist/cli/commands/sync.js +0 -18
  20. package/dist/cli/commands/sync.js.map +0 -1
  21. package/dist/cli/index.d.ts +0 -27
  22. package/dist/cli/index.d.ts.map +0 -1
  23. package/dist/cli/index.js +0 -44
  24. package/dist/cli/index.js.map +0 -1
  25. package/dist/features/web-component-artifact/adapters/outbound/node/createNodeWebComponentArtifactFileSystem.d.ts +0 -4
  26. package/dist/features/web-component-artifact/adapters/outbound/node/createNodeWebComponentArtifactFileSystem.d.ts.map +0 -1
  27. package/dist/features/web-component-artifact/adapters/outbound/node/createNodeWebComponentArtifactFileSystem.js +0 -88
  28. package/dist/features/web-component-artifact/adapters/outbound/node/createNodeWebComponentArtifactFileSystem.js.map +0 -1
  29. package/dist/features/web-component-artifact/adapters/outbound/node/readWebDesiredStateWithNodeAsync.d.ts +0 -5
  30. package/dist/features/web-component-artifact/adapters/outbound/node/readWebDesiredStateWithNodeAsync.d.ts.map +0 -1
  31. package/dist/features/web-component-artifact/adapters/outbound/node/readWebDesiredStateWithNodeAsync.js +0 -24
  32. package/dist/features/web-component-artifact/adapters/outbound/node/readWebDesiredStateWithNodeAsync.js.map +0 -1
  33. package/dist/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.d.ts +0 -10
  34. package/dist/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.d.ts.map +0 -1
  35. package/dist/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.js +0 -2
  36. package/dist/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.js.map +0 -1
  37. package/dist/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.d.ts +0 -15
  38. package/dist/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.d.ts.map +0 -1
  39. package/dist/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.js +0 -76
  40. package/dist/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.js.map +0 -1
  41. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.d.ts +0 -6
  42. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.d.ts.map +0 -1
  43. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js +0 -61
  44. package/dist/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.js.map +0 -1
  45. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts +0 -8
  46. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.d.ts.map +0 -1
  47. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js +0 -10
  48. package/dist/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.js.map +0 -1
  49. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.d.ts +0 -3
  50. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.d.ts.map +0 -1
  51. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js +0 -16
  52. package/dist/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.js.map +0 -1
  53. package/dist/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.d.ts +0 -4
  54. package/dist/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.d.ts.map +0 -1
  55. package/dist/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.js +0 -7
  56. package/dist/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.js.map +0 -1
  57. package/src/cli/commands/create.ts +0 -37
  58. package/src/cli/commands/sync.ts +0 -35
  59. package/src/cli/index.test.ts +0 -35
  60. package/src/cli/index.ts +0 -57
  61. package/src/features/web-component-artifact/adapters/outbound/node/createNodeWebComponentArtifactFileSystem.ts +0 -109
  62. package/src/features/web-component-artifact/adapters/outbound/node/readWebDesiredStateWithNodeAsync.ts +0 -29
  63. package/src/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.ts +0 -9
  64. package/src/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.test.ts +0 -128
  65. package/src/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.ts +0 -133
  66. package/src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts +0 -60
  67. package/src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts +0 -18
  68. package/src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts +0 -17
  69. package/src/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.ts +0 -16
  70. package/src/webArtifactRuntime.test.ts +0 -14
@@ -1,10 +0,0 @@
1
- export interface WebComponentArtifactFileSystemPort {
2
- joinPath(...parts: readonly string[]): string;
3
- createStageDirectoryAsync(outputDirectory: string): Promise<string>;
4
- commitStageDirectoryAsync(stageDirectory: string, outputDirectory: string): Promise<void>;
5
- removeStageDirectoryAsync(stageDirectory: string): Promise<void>;
6
- ensureDirectoryAsync(path: string): Promise<void>;
7
- readTextFileAsync(path: string): Promise<string>;
8
- writeTextFileAsync(path: string, content: string): Promise<void>;
9
- }
10
- //# sourceMappingURL=WebComponentArtifactFileSystemPort.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WebComponentArtifactFileSystemPort.d.ts","sourceRoot":"","sources":["../../../../../../src/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,GAAG,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;IAC9C,yBAAyB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpE,yBAAyB,CAAC,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=WebComponentArtifactFileSystemPort.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WebComponentArtifactFileSystemPort.js","sourceRoot":"","sources":["../../../../../../src/features/web-component-artifact/application/ports/outbound/WebComponentArtifactFileSystemPort.ts"],"names":[],"mappings":"","sourcesContent":["export interface WebComponentArtifactFileSystemPort {\n joinPath(...parts: readonly string[]): string;\n createStageDirectoryAsync(outputDirectory: string): Promise<string>;\n commitStageDirectoryAsync(stageDirectory: string, outputDirectory: string): Promise<void>;\n removeStageDirectoryAsync(stageDirectory: string): Promise<void>;\n ensureDirectoryAsync(path: string): Promise<void>;\n readTextFileAsync(path: string): Promise<string>;\n writeTextFileAsync(path: string, content: string): Promise<void>;\n}\n"]}
@@ -1,15 +0,0 @@
1
- import type { WebComponentArtifactFileSystemPort } from '../ports/outbound/WebComponentArtifactFileSystemPort';
2
- export interface SynchronizeWebComponentArtifactsInput {
3
- readonly components: readonly string[];
4
- readonly outputDirectory: string;
5
- readonly packageRoot: string;
6
- readonly packageVersion: string;
7
- }
8
- export interface SynchronizeWebComponentArtifactsResult {
9
- readonly components: readonly string[];
10
- readonly files: readonly string[];
11
- readonly outputDirectory: string;
12
- }
13
- /*** Reconcile one desired web set from a single published ZORA generation. */
14
- export declare function synchronizeWebComponentArtifactsAsync(input: SynchronizeWebComponentArtifactsInput, fileSystem: WebComponentArtifactFileSystemPort): Promise<SynchronizeWebComponentArtifactsResult>;
15
- //# sourceMappingURL=synchronizeWebComponentArtifactsAsync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeWebComponentArtifactsAsync.d.ts","sourceRoot":"","sources":["../../../../../src/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,sDAAsD,CAAC;AAE/G,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAYD,8EAA8E;AAC9E,wBAAsB,qCAAqC,CACzD,KAAK,EAAE,qCAAqC,EAC5C,UAAU,EAAE,kCAAkC,GAC7C,OAAO,CAAC,sCAAsC,CAAC,CAmDjD"}
@@ -1,76 +0,0 @@
1
- import { isRecord } from '@ankhorage/utility/object';
2
- /*** Reconcile one desired web set from a single published ZORA generation. */
3
- export async function synchronizeWebComponentArtifactsAsync(input, fileSystem) {
4
- const catalog = await readArtifactCatalogAsync(input.packageRoot, fileSystem);
5
- const components = [...new Set(input.components)].sort();
6
- const selected = components.map((component) => {
7
- const artifact = catalog.artifacts.find((candidate) => candidate.component === component);
8
- if (artifact === undefined)
9
- throw new Error(`Unsupported ZORA web component: ${component}`);
10
- return artifact;
11
- });
12
- const files = [
13
- ...new Set([...catalog.runtime.files, ...selected.flatMap(({ files }) => files)]),
14
- ].sort();
15
- const stage = await fileSystem.createStageDirectoryAsync(input.outputDirectory);
16
- try {
17
- await Promise.all(files.map(async (file) => {
18
- const source = await fileSystem.readTextFileAsync(fileSystem.joinPath(input.packageRoot, 'web-dist', file));
19
- const destination = fileSystem.joinPath(stage, file);
20
- await fileSystem.ensureDirectoryAsync(fileSystem.joinPath(stage, parentDirectory(file)));
21
- await fileSystem.writeTextFileAsync(destination, `// Generated by @ankhorage/zora v${input.packageVersion}. Do not edit manually.\n${source}`);
22
- }));
23
- await fileSystem.writeTextFileAsync(fileSystem.joinPath(stage, 'materialization.json'), `${JSON.stringify({
24
- schemaVersion: 1,
25
- owner: '@ankhorage/zora',
26
- ownerVersion: input.packageVersion,
27
- platform: 'web',
28
- components,
29
- files: [...files, 'materialization.json'].sort(),
30
- }, null, 2)}\n`);
31
- await fileSystem.commitStageDirectoryAsync(stage, input.outputDirectory);
32
- }
33
- catch (error) {
34
- await fileSystem.removeStageDirectoryAsync(stage);
35
- throw error;
36
- }
37
- return {
38
- components,
39
- files: [...files, 'materialization.json'].sort(),
40
- outputDirectory: input.outputDirectory,
41
- };
42
- }
43
- /*** Read and validate the packaged catalog before changing consumer output. */
44
- async function readArtifactCatalogAsync(packageRoot, fileSystem) {
45
- const source = await fileSystem.readTextFileAsync(fileSystem.joinPath(packageRoot, 'web-dist', 'manifest.json'));
46
- const parsed = JSON.parse(source);
47
- if (!isRecord(parsed) ||
48
- parsed.schemaVersion !== 2 ||
49
- !isRecord(parsed.runtime) ||
50
- !isFileList(parsed.runtime.files) ||
51
- !Array.isArray(parsed.artifacts)) {
52
- throw new Error('Invalid ZORA web artifact manifest.');
53
- }
54
- const artifacts = parsed.artifacts.map((artifact) => {
55
- if (!isRecord(artifact) ||
56
- typeof artifact.component !== 'string' ||
57
- !isFileList(artifact.files)) {
58
- throw new Error('Invalid ZORA web artifact manifest entry.');
59
- }
60
- return { component: artifact.component, files: artifact.files };
61
- });
62
- return { runtime: { files: parsed.runtime.files }, artifacts };
63
- }
64
- /*** Accept only known, relative generated file paths. */
65
- function isFileList(value) {
66
- return (Array.isArray(value) &&
67
- value.length > 0 &&
68
- value.every((entry) => typeof entry === 'string' &&
69
- /^(?:runtime|components|chunks|assets)\/[A-Za-z0-9_./-]+$/u.test(entry) &&
70
- !entry.split('/').includes('..')));
71
- }
72
- /*** Resolve the parent path inside the generated directory. */
73
- function parentDirectory(file) {
74
- return file.slice(0, file.lastIndexOf('/'));
75
- }
76
- //# sourceMappingURL=synchronizeWebComponentArtifactsAsync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeWebComponentArtifactsAsync.js","sourceRoot":"","sources":["../../../../../src/features/web-component-artifact/application/use-cases/synchronizeWebComponentArtifactsAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRecord } from '@ankhorage/utility/object';\n\nimport type { WebComponentArtifactFileSystemPort } from '../ports/outbound/WebComponentArtifactFileSystemPort';\n\nexport interface SynchronizeWebComponentArtifactsInput {\n readonly components: readonly string[];\n readonly outputDirectory: string;\n readonly packageRoot: string;\n readonly packageVersion: string;\n}\n\nexport interface SynchronizeWebComponentArtifactsResult {\n readonly components: readonly string[];\n readonly files: readonly string[];\n readonly outputDirectory: string;\n}\n\ninterface ArtifactDefinition {\n readonly component: string;\n readonly files: readonly string[];\n}\n\ninterface WebArtifactCatalog {\n readonly runtime: { readonly files: readonly string[] };\n readonly artifacts: readonly ArtifactDefinition[];\n}\n\n/*** Reconcile one desired web set from a single published ZORA generation. */\nexport async function synchronizeWebComponentArtifactsAsync(\n input: SynchronizeWebComponentArtifactsInput,\n fileSystem: WebComponentArtifactFileSystemPort,\n): Promise<SynchronizeWebComponentArtifactsResult> {\n const catalog = await readArtifactCatalogAsync(input.packageRoot, fileSystem);\n const components = [...new Set(input.components)].sort();\n const selected = components.map((component) => {\n const artifact = catalog.artifacts.find((candidate) => candidate.component === component);\n if (artifact === undefined) throw new Error(`Unsupported ZORA web component: ${component}`);\n return artifact;\n });\n const files = [\n ...new Set([...catalog.runtime.files, ...selected.flatMap(({ files }) => files)]),\n ].sort();\n const stage = await fileSystem.createStageDirectoryAsync(input.outputDirectory);\n try {\n await Promise.all(\n files.map(async (file) => {\n const source = await fileSystem.readTextFileAsync(\n fileSystem.joinPath(input.packageRoot, 'web-dist', file),\n );\n const destination = fileSystem.joinPath(stage, file);\n await fileSystem.ensureDirectoryAsync(fileSystem.joinPath(stage, parentDirectory(file)));\n await fileSystem.writeTextFileAsync(\n destination,\n `// Generated by @ankhorage/zora v${input.packageVersion}. Do not edit manually.\\n${source}`,\n );\n }),\n );\n await fileSystem.writeTextFileAsync(\n fileSystem.joinPath(stage, 'materialization.json'),\n `${JSON.stringify(\n {\n schemaVersion: 1,\n owner: '@ankhorage/zora',\n ownerVersion: input.packageVersion,\n platform: 'web',\n components,\n files: [...files, 'materialization.json'].sort(),\n },\n null,\n 2,\n )}\\n`,\n );\n await fileSystem.commitStageDirectoryAsync(stage, input.outputDirectory);\n } catch (error) {\n await fileSystem.removeStageDirectoryAsync(stage);\n throw error;\n }\n return {\n components,\n files: [...files, 'materialization.json'].sort(),\n outputDirectory: input.outputDirectory,\n };\n}\n\n/*** Read and validate the packaged catalog before changing consumer output. */\nasync function readArtifactCatalogAsync(\n packageRoot: string,\n fileSystem: WebComponentArtifactFileSystemPort,\n): Promise<WebArtifactCatalog> {\n const source = await fileSystem.readTextFileAsync(\n fileSystem.joinPath(packageRoot, 'web-dist', 'manifest.json'),\n );\n const parsed: unknown = JSON.parse(source);\n if (\n !isRecord(parsed) ||\n parsed.schemaVersion !== 2 ||\n !isRecord(parsed.runtime) ||\n !isFileList(parsed.runtime.files) ||\n !Array.isArray(parsed.artifacts)\n ) {\n throw new Error('Invalid ZORA web artifact manifest.');\n }\n const artifacts = parsed.artifacts.map((artifact: unknown) => {\n if (\n !isRecord(artifact) ||\n typeof artifact.component !== 'string' ||\n !isFileList(artifact.files)\n ) {\n throw new Error('Invalid ZORA web artifact manifest entry.');\n }\n return { component: artifact.component, files: artifact.files };\n });\n return { runtime: { files: parsed.runtime.files }, artifacts };\n}\n\n/*** Accept only known, relative generated file paths. */\nfunction isFileList(value: unknown): value is readonly string[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n value.every(\n (entry) =>\n typeof entry === 'string' &&\n /^(?:runtime|components|chunks|assets)\\/[A-Za-z0-9_./-]+$/u.test(entry) &&\n !entry.split('/').includes('..'),\n )\n );\n}\n\n/*** Resolve the parent path inside the generated directory. */\nfunction parentDirectory(file: string): string {\n return file.slice(0, file.lastIndexOf('/'));\n}\n"]}
@@ -1,6 +0,0 @@
1
- /*** Add one requested web component and regenerate the complete declared set. */
2
- export declare function createWebDesiredStateWithNodeAsync(input: {
3
- readonly component: string;
4
- readonly projectRoot: string;
5
- }): Promise<import("../application/use-cases/synchronizeWebComponentArtifactsAsync").SynchronizeWebComponentArtifactsResult>;
6
- //# sourceMappingURL=createWebDesiredStateWithNodeAsync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createWebDesiredStateWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"AAQA,iFAAiF;AACjF,wBAAsB,kCAAkC,CAAC,KAAK,EAAE;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,4HA+BA"}
@@ -1,61 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { readFile, rename, rm, writeFile } from 'node:fs/promises';
3
- import { dirname, join, resolve } from 'node:path';
4
- import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
5
- import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
6
- import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
7
- /*** Add one requested web component and regenerate the complete declared set. */
8
- export async function createWebDesiredStateWithNodeAsync(input) {
9
- const desired = await readWebDesiredStateWithNodeAsync(input.projectRoot, true);
10
- const components = [...new Set([...desired.components, input.component])].sort();
11
- const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
12
- const desiredPath = resolve(input.projectRoot, 'zora.web.json');
13
- const previous = await readFile(desiredPath, 'utf8').catch((error) => {
14
- if (isMissingFile(error))
15
- return undefined;
16
- throw error;
17
- });
18
- const next = `${JSON.stringify({ schemaVersion: 1, components }, null, 2)}\n`;
19
- if (next !== previous)
20
- await replaceDesiredStateAsync(desiredPath, next);
21
- try {
22
- return await synchronizeWebComponentArtifactsWithNodeAsync({
23
- components,
24
- outputDirectory: resolve(input.projectRoot, '.ankh', 'zora', 'web'),
25
- packageRoot,
26
- packageVersion,
27
- });
28
- }
29
- catch (error) {
30
- if (next !== previous) {
31
- try {
32
- if (previous === undefined)
33
- await rm(desiredPath);
34
- else
35
- await replaceDesiredStateAsync(desiredPath, previous);
36
- }
37
- catch (rollbackError) {
38
- throw new AggregateError([error, rollbackError], 'ZORA create and rollback failed.', {
39
- cause: rollbackError,
40
- });
41
- }
42
- }
43
- throw error;
44
- }
45
- }
46
- /*** Replace the authoritative project declaration only after its complete contents are staged. */
47
- async function replaceDesiredStateAsync(path, content) {
48
- const temporaryPath = join(dirname(path), `.zora-web-${randomUUID()}.tmp`);
49
- try {
50
- await writeFile(temporaryPath, content, 'utf8');
51
- await rename(temporaryPath, path);
52
- }
53
- finally {
54
- await rm(temporaryPath, { force: true });
55
- }
56
- }
57
- /*** Recognize only absent desired state, not unrelated filesystem failures. */
58
- function isMissingFile(error) {
59
- return error instanceof Error && 'code' in error && error.code === 'ENOENT';
60
- }
61
- //# sourceMappingURL=createWebDesiredStateWithNodeAsync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createWebDesiredStateWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';\nimport { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';\nimport { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';\n\n/*** Add one requested web component and regenerate the complete declared set. */\nexport async function createWebDesiredStateWithNodeAsync(input: {\n readonly component: string;\n readonly projectRoot: string;\n}) {\n const desired = await readWebDesiredStateWithNodeAsync(input.projectRoot, true);\n const components = [...new Set([...desired.components, input.component])].sort();\n const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();\n const desiredPath = resolve(input.projectRoot, 'zora.web.json');\n const previous = await readFile(desiredPath, 'utf8').catch((error: unknown) => {\n if (isMissingFile(error)) return undefined;\n throw error;\n });\n const next = `${JSON.stringify({ schemaVersion: 1, components }, null, 2)}\\n`;\n if (next !== previous) await replaceDesiredStateAsync(desiredPath, next);\n try {\n return await synchronizeWebComponentArtifactsWithNodeAsync({\n components,\n outputDirectory: resolve(input.projectRoot, '.ankh', 'zora', 'web'),\n packageRoot,\n packageVersion,\n });\n } catch (error) {\n if (next !== previous) {\n try {\n if (previous === undefined) await rm(desiredPath);\n else await replaceDesiredStateAsync(desiredPath, previous);\n } catch (rollbackError) {\n throw new AggregateError([error, rollbackError], 'ZORA create and rollback failed.', {\n cause: rollbackError,\n });\n }\n }\n throw error;\n }\n}\n\n/*** Replace the authoritative project declaration only after its complete contents are staged. */\nasync function replaceDesiredStateAsync(path: string, content: string): Promise<void> {\n const temporaryPath = join(dirname(path), `.zora-web-${randomUUID()}.tmp`);\n try {\n await writeFile(temporaryPath, content, 'utf8');\n await rename(temporaryPath, path);\n } finally {\n await rm(temporaryPath, { force: true });\n }\n}\n\n/*** Recognize only absent desired state, not unrelated filesystem failures. */\nfunction isMissingFile(error: unknown): boolean {\n return error instanceof Error && 'code' in error && error.code === 'ENOENT';\n}\n"]}
@@ -1,8 +0,0 @@
1
- /*** Reads the active ZORA package location and version for generated web artifacts. */
2
- export declare function readWebComponentPackageMetadataAsync(): Promise<WebComponentPackageMetadata>;
3
- interface WebComponentPackageMetadata {
4
- readonly packageRoot: string;
5
- readonly packageVersion: string;
6
- }
7
- export {};
8
- //# sourceMappingURL=readWebComponentPackageMetadataAsync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"readWebComponentPackageMetadataAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts"],"names":[],"mappings":"AAIA,uFAAuF;AACvF,wBAAsB,oCAAoC,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAOjG;AAED,UAAU,2BAA2B;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
@@ -1,10 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- /*** Reads the active ZORA package location and version for generated web artifacts. */
5
- export async function readWebComponentPackageMetadataAsync() {
6
- const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
7
- const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8'));
8
- return { packageRoot, packageVersion: packageJson.version };
9
- }
10
- //# sourceMappingURL=readWebComponentPackageMetadataAsync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"readWebComponentPackageMetadataAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/readWebComponentPackageMetadataAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,oCAAoC;IACxD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACpF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE1F,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;AAC9D,CAAC","sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/*** Reads the active ZORA package location and version for generated web artifacts. */\nexport async function readWebComponentPackageMetadataAsync(): Promise<WebComponentPackageMetadata> {\n const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');\n const packageJson = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')) as {\n readonly version: string;\n };\n\n return { packageRoot, packageVersion: packageJson.version };\n}\n\ninterface WebComponentPackageMetadata {\n readonly packageRoot: string;\n readonly packageVersion: string;\n}\n"]}
@@ -1,3 +0,0 @@
1
- /*** Load project desired state and sync it from the active ZORA package release. */
2
- export declare function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot: string): Promise<import("../application/use-cases/synchronizeWebComponentArtifactsAsync").SynchronizeWebComponentArtifactsResult>;
3
- //# sourceMappingURL=synchronizeDeclaredWebComponentsWithNodeAsync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"AAMA,oFAAoF;AACpF,wBAAsB,6CAA6C,CAAC,WAAW,EAAE,MAAM,4HAStF"}
@@ -1,16 +0,0 @@
1
- import { resolve } from 'node:path';
2
- import { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';
3
- import { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';
4
- import { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';
5
- /*** Load project desired state and sync it from the active ZORA package release. */
6
- export async function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot) {
7
- const desired = await readWebDesiredStateWithNodeAsync(projectRoot, false);
8
- const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();
9
- return await synchronizeWebComponentArtifactsWithNodeAsync({
10
- components: desired.components,
11
- outputDirectory: resolve(projectRoot, '.ankh', 'zora', 'web'),
12
- packageRoot,
13
- packageVersion,
14
- });
15
- }
16
- //# sourceMappingURL=synchronizeDeclaredWebComponentsWithNodeAsync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeDeclaredWebComponentsWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,gCAAgC,EAAE,MAAM,4DAA4D,CAAC;AAC9G,OAAO,EAAE,oCAAoC,EAAE,MAAM,wCAAwC,CAAC;AAC9F,OAAO,EAAE,6CAA6C,EAAE,MAAM,iDAAiD,CAAC;AAEhH,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,6CAA6C,CAAC,WAAmB;IACrF,MAAM,OAAO,GAAG,MAAM,gCAAgC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC3E,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,oCAAoC,EAAE,CAAC;IACrF,OAAO,MAAM,6CAA6C,CAAC;QACzD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,eAAe,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;QAC7D,WAAW;QACX,cAAc;KACf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { resolve } from 'node:path';\n\nimport { readWebDesiredStateWithNodeAsync } from '../adapters/outbound/node/readWebDesiredStateWithNodeAsync';\nimport { readWebComponentPackageMetadataAsync } from './readWebComponentPackageMetadataAsync';\nimport { synchronizeWebComponentArtifactsWithNodeAsync } from './synchronizeWebComponentArtifactsWithNodeAsync';\n\n/*** Load project desired state and sync it from the active ZORA package release. */\nexport async function synchronizeDeclaredWebComponentsWithNodeAsync(projectRoot: string) {\n const desired = await readWebDesiredStateWithNodeAsync(projectRoot, false);\n const { packageRoot, packageVersion } = await readWebComponentPackageMetadataAsync();\n return await synchronizeWebComponentArtifactsWithNodeAsync({\n components: desired.components,\n outputDirectory: resolve(projectRoot, '.ankh', 'zora', 'web'),\n packageRoot,\n packageVersion,\n });\n}\n"]}
@@ -1,4 +0,0 @@
1
- import { type SynchronizeWebComponentArtifactsInput, type SynchronizeWebComponentArtifactsResult } from '../application/use-cases/synchronizeWebComponentArtifactsAsync';
2
- /*** Wire Node filesystem operations into shared ZORA web reconciliation. */
3
- export declare function synchronizeWebComponentArtifactsWithNodeAsync(input: SynchronizeWebComponentArtifactsInput): Promise<SynchronizeWebComponentArtifactsResult>;
4
- //# sourceMappingURL=synchronizeWebComponentArtifactsWithNodeAsync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeWebComponentArtifactsWithNodeAsync.d.ts","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,qCAAqC,EAC1C,KAAK,sCAAsC,EAC5C,MAAM,gEAAgE,CAAC;AAExE,4EAA4E;AAC5E,wBAAsB,6CAA6C,CACjE,KAAK,EAAE,qCAAqC,GAC3C,OAAO,CAAC,sCAAsC,CAAC,CAKjD"}
@@ -1,7 +0,0 @@
1
- import { createNodeWebComponentArtifactFileSystem } from '../adapters/outbound/node/createNodeWebComponentArtifactFileSystem';
2
- import { synchronizeWebComponentArtifactsAsync, } from '../application/use-cases/synchronizeWebComponentArtifactsAsync';
3
- /*** Wire Node filesystem operations into shared ZORA web reconciliation. */
4
- export async function synchronizeWebComponentArtifactsWithNodeAsync(input) {
5
- return await synchronizeWebComponentArtifactsAsync(input, createNodeWebComponentArtifactFileSystem());
6
- }
7
- //# sourceMappingURL=synchronizeWebComponentArtifactsWithNodeAsync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synchronizeWebComponentArtifactsWithNodeAsync.js","sourceRoot":"","sources":["../../../../src/features/web-component-artifact/composition/synchronizeWebComponentArtifactsWithNodeAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wCAAwC,EAAE,MAAM,oEAAoE,CAAC;AAC9H,OAAO,EACL,qCAAqC,GAGtC,MAAM,gEAAgE,CAAC;AAExE,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,6CAA6C,CACjE,KAA4C;IAE5C,OAAO,MAAM,qCAAqC,CAChD,KAAK,EACL,wCAAwC,EAAE,CAC3C,CAAC;AACJ,CAAC","sourcesContent":["import { createNodeWebComponentArtifactFileSystem } from '../adapters/outbound/node/createNodeWebComponentArtifactFileSystem';\nimport {\n synchronizeWebComponentArtifactsAsync,\n type SynchronizeWebComponentArtifactsInput,\n type SynchronizeWebComponentArtifactsResult,\n} from '../application/use-cases/synchronizeWebComponentArtifactsAsync';\n\n/*** Wire Node filesystem operations into shared ZORA web reconciliation. */\nexport async function synchronizeWebComponentArtifactsWithNodeAsync(\n input: SynchronizeWebComponentArtifactsInput,\n): Promise<SynchronizeWebComponentArtifactsResult> {\n return await synchronizeWebComponentArtifactsAsync(\n input,\n createNodeWebComponentArtifactFileSystem(),\n );\n}\n"]}
@@ -1,37 +0,0 @@
1
- import { resolve } from 'node:path';
2
-
3
- import { createWebDesiredStateWithNodeAsync } from '../../features/web-component-artifact/composition/createWebDesiredStateWithNodeAsync';
4
-
5
- interface ZoraCreateCommandRequest {
6
- readonly argv: readonly string[];
7
- readonly context: {
8
- readonly cwd: string;
9
- writeStderr(text: string): void;
10
- writeStdout(text: string): void;
11
- };
12
- }
13
-
14
- /*** Add one web component to project desired state and reconcile its shared runtime. */
15
- export async function create(
16
- request: ZoraCreateCommandRequest,
17
- ): Promise<{ readonly exitCode: number }> {
18
- try {
19
- const [component, platform] = request.argv;
20
- if (request.argv.length !== 2 || component === undefined || platform !== '--web') {
21
- throw new Error('Usage: ankh zora create <component> --web');
22
- }
23
- const result = await createWebDesiredStateWithNodeAsync({
24
- component,
25
- projectRoot: resolve(request.context.cwd),
26
- });
27
- request.context.writeStdout(
28
- `Materialized ZORA ${component} with ${result.components.length} web component(s) at ${result.outputDirectory}\n`,
29
- );
30
- return { exitCode: 0 };
31
- } catch (error) {
32
- request.context.writeStderr(
33
- `ZORA create failed: ${error instanceof Error ? error.message : String(error)}\n`,
34
- );
35
- return { exitCode: 1 };
36
- }
37
- }
@@ -1,35 +0,0 @@
1
- import { resolve } from 'node:path';
2
-
3
- import { synchronizeDeclaredWebComponentsWithNodeAsync } from '../../features/web-component-artifact/composition/synchronizeDeclaredWebComponentsWithNodeAsync';
4
-
5
- interface ZoraSyncCommandRequest {
6
- readonly argv: readonly string[];
7
- readonly context: {
8
- readonly cwd: string;
9
- writeStderr(text: string): void;
10
- writeStdout(text: string): void;
11
- };
12
- }
13
-
14
- /*** Reconcile the declared web component set from the installed ZORA provider. */
15
- export async function sync(
16
- request: ZoraSyncCommandRequest,
17
- ): Promise<{ readonly exitCode: number }> {
18
- try {
19
- if (request.argv.length !== 1 || request.argv[0] !== '--web') {
20
- throw new Error('Usage: ankh zora sync --web');
21
- }
22
- const result = await synchronizeDeclaredWebComponentsWithNodeAsync(
23
- resolve(request.context.cwd),
24
- );
25
- request.context.writeStdout(
26
- `Synchronized ${result.components.length} ZORA web component(s) at ${result.outputDirectory}\n`,
27
- );
28
- return { exitCode: 0 };
29
- } catch (error) {
30
- request.context.writeStderr(
31
- `ZORA sync failed: ${error instanceof Error ? error.message : String(error)}\n`,
32
- );
33
- return { exitCode: 1 };
34
- }
35
- }
@@ -1,35 +0,0 @@
1
- import { expect, test } from 'bun:test';
2
-
3
- import { CAPABILITIES } from '../capabilities';
4
- import provider from './index';
5
-
6
- test('publishes ZORA create and sync through the Ankh provider', () => {
7
- expect(provider.id).toBe('@ankhorage/zora');
8
- expect(provider.category).toBe('zora');
9
- expect(provider.capabilities).toEqual(
10
- CAPABILITIES.filter((capability) => capability.access.includes('invoke')),
11
- );
12
- expect(provider.commands).toEqual([
13
- {
14
- path: ['create'],
15
- capability: 'zora.create',
16
- summary: 'Materialize a canonical ZORA component for a target platform.',
17
- },
18
- {
19
- path: ['sync'],
20
- capability: 'zora.sync',
21
- summary: 'Regenerate the declared ZORA web materialization.',
22
- },
23
- ]);
24
- expect(provider.handlers).toHaveLength(2);
25
- expect(provider.handlers[0]?.path).toEqual(['create']);
26
- expect(provider.handlers[1]?.path).toEqual(['sync']);
27
- });
28
-
29
- test('maps every provider command to one executable canonical capability independent of catalog order', () => {
30
- const commandCapabilityIds = provider.commands.map((command) => command.capability);
31
- const capabilityIds = provider.capabilities.map((capability) => capability.id);
32
-
33
- expect(new Set(commandCapabilityIds).size).toBe(commandCapabilityIds.length);
34
- expect(new Set(commandCapabilityIds)).toEqual(new Set(capabilityIds));
35
- });
package/src/cli/index.ts DELETED
@@ -1,57 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
-
5
- import type { AnkhRuntimeCommandProvider } from '@ankhorage/ankh';
6
- import type { Capability } from '@ankhorage/contracts/capability';
7
-
8
- import { CAPABILITIES } from '../capabilities';
9
- import { create } from './commands/create';
10
- import { sync } from './commands/sync';
11
-
12
- const CREATE_COMMAND = {
13
- path: ['create'],
14
- capability: 'zora.create' satisfies Capability['id'],
15
- summary: 'Materialize a canonical ZORA component for a target platform.',
16
- } as const;
17
- const SYNC_COMMAND = {
18
- path: ['sync'],
19
- capability: 'zora.sync' satisfies Capability['id'],
20
- summary: 'Regenerate the declared ZORA web materialization.',
21
- } as const;
22
- const COMMAND_CAPABILITIES = CAPABILITIES.filter((capability) =>
23
- capability.access.includes('invoke'),
24
- );
25
-
26
- const provider = {
27
- id: '@ankhorage/zora',
28
- category: 'zora',
29
- version: readPackageVersion(),
30
- capabilities: COMMAND_CAPABILITIES,
31
- commands: [CREATE_COMMAND, SYNC_COMMAND],
32
- handlers: [
33
- {
34
- path: CREATE_COMMAND.path,
35
- handler: create,
36
- },
37
- {
38
- path: SYNC_COMMAND.path,
39
- handler: sync,
40
- },
41
- ],
42
- } satisfies AnkhRuntimeCommandProvider;
43
-
44
- export default provider;
45
-
46
- /*** Read the installed ZORA version for the Ankh provider manifest. */
47
- function readPackageVersion(): string {
48
- const packageJson = JSON.parse(
49
- readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json'), 'utf8'),
50
- ) as { readonly version?: unknown };
51
-
52
- if (typeof packageJson.version !== 'string' || packageJson.version.trim() === '') {
53
- throw new Error('ZORA package.json must define a non-empty version.');
54
- }
55
-
56
- return packageJson.version;
57
- }
@@ -1,109 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import {
3
- mkdir,
4
- mkdtemp,
5
- readFile,
6
- readlink,
7
- realpath,
8
- rename,
9
- rm,
10
- symlink,
11
- writeFile,
12
- } from 'node:fs/promises';
13
- import { basename, dirname, join } from 'node:path';
14
-
15
- import type { WebComponentArtifactFileSystemPort } from '../../../application/ports/outbound/WebComponentArtifactFileSystemPort';
16
-
17
- /*** Create the Node filesystem adapter used by ZORA web-component materialization. */
18
- export function createNodeWebComponentArtifactFileSystem(
19
- platform: NodeJS.Platform = process.platform,
20
- ): WebComponentArtifactFileSystemPort {
21
- return {
22
- joinPath(...parts) {
23
- return join(...parts);
24
- },
25
- async createStageDirectoryAsync(outputDirectory) {
26
- const parent = dirname(outputDirectory);
27
- await mkdir(parent, { recursive: true });
28
- return await mkdtemp(join(parent, '.web-gen-'));
29
- },
30
- async commitStageDirectoryAsync(stageDirectory, outputDirectory) {
31
- const parent = dirname(outputDirectory);
32
- const previous = await readlink(outputDirectory).catch((error: unknown) => {
33
- if (isMissingFile(error)) return undefined;
34
- throw error;
35
- });
36
- const previousDirectory =
37
- previous === undefined ? undefined : await realpath(outputDirectory);
38
- if (
39
- previousDirectory !== undefined &&
40
- (dirname(previousDirectory) !== (await realpath(parent)) ||
41
- !isGeneratedDirectoryName(basename(previousDirectory)))
42
- ) {
43
- throw new Error(`Refusing to replace non-ZORA materialization: ${outputDirectory}`);
44
- }
45
- const temporaryLink = join(parent, `.web-link-${randomUUID()}`);
46
- try {
47
- await symlink(
48
- platform === 'win32' ? stageDirectory : basename(stageDirectory),
49
- temporaryLink,
50
- platform === 'win32' ? 'junction' : 'dir',
51
- );
52
- if (platform === 'win32' && previousDirectory !== undefined) {
53
- await replaceWindowsJunctionAsync(temporaryLink, outputDirectory);
54
- } else {
55
- await rename(temporaryLink, outputDirectory);
56
- }
57
- } finally {
58
- await rm(temporaryLink, { force: true });
59
- }
60
- if (
61
- previousDirectory !== undefined &&
62
- previousDirectory !== (await realpath(stageDirectory))
63
- ) {
64
- await rm(previousDirectory, { force: true, recursive: true }).catch(() => undefined);
65
- }
66
- },
67
- async removeStageDirectoryAsync(stageDirectory) {
68
- await rm(stageDirectory, { force: true, recursive: true });
69
- },
70
- async ensureDirectoryAsync(path) {
71
- await mkdir(path, { recursive: true });
72
- },
73
- async readTextFileAsync(path) {
74
- return await readFile(path, 'utf8');
75
- },
76
- async writeTextFileAsync(path, content) {
77
- await writeFile(path, content, 'utf8');
78
- },
79
- };
80
- }
81
-
82
- /*** Swap Windows junctions with rollback because rename cannot replace an occupied destination. */
83
- async function replaceWindowsJunctionAsync(temporaryLink: string, outputDirectory: string) {
84
- const previousLink = join(dirname(outputDirectory), `.web-link-${randomUUID()}`);
85
- await rename(outputDirectory, previousLink);
86
- try {
87
- await rename(temporaryLink, outputDirectory);
88
- } catch (error) {
89
- try {
90
- await rename(previousLink, outputDirectory);
91
- } catch (rollbackError) {
92
- throw new AggregateError([error, rollbackError], 'ZORA web swap and rollback failed.', {
93
- cause: rollbackError,
94
- });
95
- }
96
- throw error;
97
- }
98
- await rm(previousLink, { force: true });
99
- }
100
-
101
- /*** Recognize only the private generation directories written by this adapter. */
102
- function isGeneratedDirectoryName(value: string): boolean {
103
- return /^\.web-gen-[A-Za-z0-9]+$/u.test(value);
104
- }
105
-
106
- /*** Distinguish a missing first-generation link from other filesystem errors. */
107
- function isMissingFile(error: unknown): boolean {
108
- return error instanceof Error && 'code' in error && error.code === 'ENOENT';
109
- }
@@ -1,29 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { resolve } from 'node:path';
3
-
4
- import { isRecord } from '@ankhorage/utility/object';
5
-
6
- /*** Read the version-controlled desired component set outside generated output. */
7
- export async function readWebDesiredStateWithNodeAsync(
8
- projectRoot: string,
9
- allowMissing: boolean,
10
- ): Promise<{ readonly components: readonly string[] }> {
11
- const path = resolve(projectRoot, 'zora.web.json');
12
- const source = await readFile(path, 'utf8').catch((error: unknown) => {
13
- if (allowMissing && error instanceof Error && 'code' in error && error.code === 'ENOENT') {
14
- return undefined;
15
- }
16
- throw error;
17
- });
18
- if (source === undefined) return { components: [] };
19
- const parsed: unknown = JSON.parse(source);
20
- if (
21
- !isRecord(parsed) ||
22
- parsed.schemaVersion !== 1 ||
23
- !Array.isArray(parsed.components) ||
24
- !parsed.components.every((component) => typeof component === 'string')
25
- ) {
26
- throw new Error(`Invalid ZORA web desired state: ${path}`);
27
- }
28
- return { components: parsed.components };
29
- }