@ankhorage/deploy 0.1.0 → 0.2.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 (147) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/project/ProjectDeploymentPaths.d.ts +17 -0
  4. package/dist/project/ProjectDeploymentPaths.d.ts.map +1 -0
  5. package/dist/project/ProjectDeploymentPaths.js +2 -0
  6. package/dist/project/ProjectDeploymentPaths.js.map +1 -0
  7. package/dist/project/ResolvedDeployProject.d.ts +11 -0
  8. package/dist/project/ResolvedDeployProject.d.ts.map +1 -0
  9. package/dist/project/ResolvedDeployProject.js +2 -0
  10. package/dist/project/ResolvedDeployProject.js.map +1 -0
  11. package/dist/project/history/ProjectDeploymentHistoryRecord.d.ts +14 -0
  12. package/dist/project/history/ProjectDeploymentHistoryRecord.d.ts.map +1 -0
  13. package/dist/project/history/ProjectDeploymentHistoryRecord.js +2 -0
  14. package/dist/project/history/ProjectDeploymentHistoryRecord.js.map +1 -0
  15. package/dist/project/history/historySchemaVersion.d.ts +2 -0
  16. package/dist/project/history/historySchemaVersion.d.ts.map +1 -0
  17. package/dist/project/history/historySchemaVersion.js +2 -0
  18. package/dist/project/history/historySchemaVersion.js.map +1 -0
  19. package/dist/project/history/listProjectDeploymentHistory.d.ts +5 -0
  20. package/dist/project/history/listProjectDeploymentHistory.d.ts.map +1 -0
  21. package/dist/project/history/listProjectDeploymentHistory.js +25 -0
  22. package/dist/project/history/listProjectDeploymentHistory.js.map +1 -0
  23. package/dist/project/history/parseProjectDeploymentHistoryRecord.d.ts +3 -0
  24. package/dist/project/history/parseProjectDeploymentHistoryRecord.d.ts.map +1 -0
  25. package/dist/project/history/parseProjectDeploymentHistoryRecord.js +40 -0
  26. package/dist/project/history/parseProjectDeploymentHistoryRecord.js.map +1 -0
  27. package/dist/project/history/readProjectDeploymentHistory.d.ts +6 -0
  28. package/dist/project/history/readProjectDeploymentHistory.d.ts.map +1 -0
  29. package/dist/project/history/readProjectDeploymentHistory.js +26 -0
  30. package/dist/project/history/readProjectDeploymentHistory.js.map +1 -0
  31. package/dist/project/history/recordProjectDeploymentHistory.d.ts +6 -0
  32. package/dist/project/history/recordProjectDeploymentHistory.d.ts.map +1 -0
  33. package/dist/project/history/recordProjectDeploymentHistory.js +40 -0
  34. package/dist/project/history/recordProjectDeploymentHistory.js.map +1 -0
  35. package/dist/project/history/validation/diagnostic.d.ts +2 -0
  36. package/dist/project/history/validation/diagnostic.d.ts.map +1 -0
  37. package/dist/project/history/validation/diagnostic.js +14 -0
  38. package/dist/project/history/validation/diagnostic.js.map +1 -0
  39. package/dist/project/history/validation/execution.d.ts +2 -0
  40. package/dist/project/history/validation/execution.d.ts.map +1 -0
  41. package/dist/project/history/validation/execution.js +40 -0
  42. package/dist/project/history/validation/execution.js.map +1 -0
  43. package/dist/project/history/validation/failure.d.ts +2 -0
  44. package/dist/project/history/validation/failure.d.ts.map +1 -0
  45. package/dist/project/history/validation/failure.js +13 -0
  46. package/dist/project/history/validation/failure.js.map +1 -0
  47. package/dist/project/history/validation/isIsoTimestamp.d.ts +2 -0
  48. package/dist/project/history/validation/isIsoTimestamp.d.ts.map +1 -0
  49. package/dist/project/history/validation/isIsoTimestamp.js +6 -0
  50. package/dist/project/history/validation/isIsoTimestamp.js.map +1 -0
  51. package/dist/project/history/validation/observedTarget.d.ts +2 -0
  52. package/dist/project/history/validation/observedTarget.d.ts.map +1 -0
  53. package/dist/project/history/validation/observedTarget.js +24 -0
  54. package/dist/project/history/validation/observedTarget.js.map +1 -0
  55. package/dist/project/history/validation/plan.d.ts +2 -0
  56. package/dist/project/history/validation/plan.d.ts.map +1 -0
  57. package/dist/project/history/validation/plan.js +18 -0
  58. package/dist/project/history/validation/plan.js.map +1 -0
  59. package/dist/project/history/validation/planStep.d.ts +2 -0
  60. package/dist/project/history/validation/planStep.d.ts.map +1 -0
  61. package/dist/project/history/validation/planStep.js +17 -0
  62. package/dist/project/history/validation/planStep.js.map +1 -0
  63. package/dist/project/history/validation/providerSelection.d.ts +2 -0
  64. package/dist/project/history/validation/providerSelection.d.ts.map +1 -0
  65. package/dist/project/history/validation/providerSelection.js +13 -0
  66. package/dist/project/history/validation/providerSelection.js.map +1 -0
  67. package/dist/project/history/validation/requiredAction.d.ts +2 -0
  68. package/dist/project/history/validation/requiredAction.d.ts.map +1 -0
  69. package/dist/project/history/validation/requiredAction.js +27 -0
  70. package/dist/project/history/validation/requiredAction.js.map +1 -0
  71. package/dist/project/history/validation/shared.d.ts +3 -0
  72. package/dist/project/history/validation/shared.d.ts.map +1 -0
  73. package/dist/project/history/validation/shared.js +8 -0
  74. package/dist/project/history/validation/shared.js.map +1 -0
  75. package/dist/project/history/validation/stepOutcome.d.ts +2 -0
  76. package/dist/project/history/validation/stepOutcome.d.ts.map +1 -0
  77. package/dist/project/history/validation/stepOutcome.js +21 -0
  78. package/dist/project/history/validation/stepOutcome.js.map +1 -0
  79. package/dist/project/history/validation/targetChange.d.ts +2 -0
  80. package/dist/project/history/validation/targetChange.d.ts.map +1 -0
  81. package/dist/project/history/validation/targetChange.js +19 -0
  82. package/dist/project/history/validation/targetChange.js.map +1 -0
  83. package/dist/project/history/validation/verification.d.ts +2 -0
  84. package/dist/project/history/validation/verification.d.ts.map +1 -0
  85. package/dist/project/history/validation/verification.js +23 -0
  86. package/dist/project/history/validation/verification.js.map +1 -0
  87. package/dist/project/index.d.ts +12 -0
  88. package/dist/project/index.d.ts.map +1 -0
  89. package/dist/project/index.js +9 -0
  90. package/dist/project/index.js.map +1 -0
  91. package/dist/project/io/assertContainedPath.d.ts +2 -0
  92. package/dist/project/io/assertContainedPath.d.ts.map +1 -0
  93. package/dist/project/io/assertContainedPath.js +33 -0
  94. package/dist/project/io/assertContainedPath.js.map +1 -0
  95. package/dist/project/io/assertSafeSegment.d.ts +3 -0
  96. package/dist/project/io/assertSafeSegment.d.ts.map +1 -0
  97. package/dist/project/io/assertSafeSegment.js +15 -0
  98. package/dist/project/io/assertSafeSegment.js.map +1 -0
  99. package/dist/project/io/atomicWriteFile.d.ts +6 -0
  100. package/dist/project/io/atomicWriteFile.d.ts.map +1 -0
  101. package/dist/project/io/atomicWriteFile.js +18 -0
  102. package/dist/project/io/atomicWriteFile.js.map +1 -0
  103. package/dist/project/io/atomicWriteJson.d.ts +6 -0
  104. package/dist/project/io/atomicWriteJson.d.ts.map +1 -0
  105. package/dist/project/io/atomicWriteJson.js +10 -0
  106. package/dist/project/io/atomicWriteJson.js.map +1 -0
  107. package/dist/project/io/hasOnlyKeys.d.ts +2 -0
  108. package/dist/project/io/hasOnlyKeys.d.ts.map +1 -0
  109. package/dist/project/io/hasOnlyKeys.js +4 -0
  110. package/dist/project/io/hasOnlyKeys.js.map +1 -0
  111. package/dist/project/io/isMissingPathError.d.ts +2 -0
  112. package/dist/project/io/isMissingPathError.d.ts.map +1 -0
  113. package/dist/project/io/isMissingPathError.js +4 -0
  114. package/dist/project/io/isMissingPathError.js.map +1 -0
  115. package/dist/project/io/isRecord.d.ts +2 -0
  116. package/dist/project/io/isRecord.d.ts.map +1 -0
  117. package/dist/project/io/isRecord.js +4 -0
  118. package/dist/project/io/isRecord.js.map +1 -0
  119. package/dist/project/io/normalizeProjectRoot.d.ts +2 -0
  120. package/dist/project/io/normalizeProjectRoot.d.ts.map +1 -0
  121. package/dist/project/io/normalizeProjectRoot.js +18 -0
  122. package/dist/project/io/normalizeProjectRoot.js.map +1 -0
  123. package/dist/project/io/readJsonFile.d.ts +2 -0
  124. package/dist/project/io/readJsonFile.d.ts.map +1 -0
  125. package/dist/project/io/readJsonFile.js +11 -0
  126. package/dist/project/io/readJsonFile.js.map +1 -0
  127. package/dist/project/io/readProjectManifest.d.ts +6 -0
  128. package/dist/project/io/readProjectManifest.d.ts.map +1 -0
  129. package/dist/project/io/readProjectManifest.js +20 -0
  130. package/dist/project/io/readProjectManifest.js.map +1 -0
  131. package/dist/project/readProjectDeploymentConfig.d.ts +5 -0
  132. package/dist/project/readProjectDeploymentConfig.d.ts.map +1 -0
  133. package/dist/project/readProjectDeploymentConfig.js +6 -0
  134. package/dist/project/readProjectDeploymentConfig.js.map +1 -0
  135. package/dist/project/resolveDeployProject.d.ts +5 -0
  136. package/dist/project/resolveDeployProject.d.ts.map +1 -0
  137. package/dist/project/resolveDeployProject.js +15 -0
  138. package/dist/project/resolveDeployProject.js.map +1 -0
  139. package/dist/project/resolveProjectDeploymentPaths.d.ts +3 -0
  140. package/dist/project/resolveProjectDeploymentPaths.d.ts.map +1 -0
  141. package/dist/project/resolveProjectDeploymentPaths.js +25 -0
  142. package/dist/project/resolveProjectDeploymentPaths.js.map +1 -0
  143. package/dist/project/updateProjectDeploymentConfig.d.ts +7 -0
  144. package/dist/project/updateProjectDeploymentConfig.d.ts.map +1 -0
  145. package/dist/project/updateProjectDeploymentConfig.js +23 -0
  146. package/dist/project/updateProjectDeploymentConfig.js.map +1 -0
  147. package/package.json +6 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/deploy
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 94a6a3b: Add the explicit-root Deploy project API, canonical authored deployment paths, safe deployment configuration updates, and immutable deployment history.
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # @ankhorage/deploy
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v0.0.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v0.1.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
7
7
 
8
8
  Declarative deployment engine for Expo apps across web, iOS, and Android.
9
9
 
@@ -0,0 +1,17 @@
1
+ export interface ProjectDeploymentPaths {
2
+ readonly projectRoot: string;
3
+ readonly manifestPath: string;
4
+ readonly authoredRoot: string;
5
+ readonly listingRoot: string;
6
+ readonly assetsRoot: string;
7
+ readonly sharedAssetsRoot: string;
8
+ readonly androidAssetsRoot: string;
9
+ readonly androidScreenshotsRoot: string;
10
+ readonly iosAssetsRoot: string;
11
+ readonly iosScreenshotsRoot: string;
12
+ readonly monetizationRoot: string;
13
+ readonly productsPath: string;
14
+ readonly releasePath: string;
15
+ readonly historyRoot: string;
16
+ }
17
+ //# sourceMappingURL=ProjectDeploymentPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectDeploymentPaths.d.ts","sourceRoot":"","sources":["../../src/project/ProjectDeploymentPaths.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ProjectDeploymentPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectDeploymentPaths.js","sourceRoot":"","sources":["../../src/project/ProjectDeploymentPaths.ts"],"names":[],"mappings":"","sourcesContent":["export interface ProjectDeploymentPaths {\n readonly projectRoot: string;\n readonly manifestPath: string;\n readonly authoredRoot: string;\n readonly listingRoot: string;\n readonly assetsRoot: string;\n readonly sharedAssetsRoot: string;\n readonly androidAssetsRoot: string;\n readonly androidScreenshotsRoot: string;\n readonly iosAssetsRoot: string;\n readonly iosScreenshotsRoot: string;\n readonly monetizationRoot: string;\n readonly productsPath: string;\n readonly releasePath: string;\n readonly historyRoot: string;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { AppManifest } from '@ankhorage/contracts';
2
+ import type { AppDeployManifest } from '@ankhorage/contracts/deploy';
3
+ import type { ProjectDeploymentPaths } from './ProjectDeploymentPaths';
4
+ export interface ResolvedDeployProject {
5
+ readonly projectRoot: string;
6
+ readonly manifestPath: string;
7
+ readonly manifest: AppManifest;
8
+ readonly deploy: AppDeployManifest | null;
9
+ readonly paths: ProjectDeploymentPaths;
10
+ }
11
+ //# sourceMappingURL=ResolvedDeployProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResolvedDeployProject.d.ts","sourceRoot":"","sources":["../../src/project/ResolvedDeployProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;CACxC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ResolvedDeployProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResolvedDeployProject.js","sourceRoot":"","sources":["../../src/project/ResolvedDeployProject.ts"],"names":[],"mappings":"","sourcesContent":["import type { AppManifest } from '@ankhorage/contracts';\nimport type { AppDeployManifest } from '@ankhorage/contracts/deploy';\n\nimport type { ProjectDeploymentPaths } from './ProjectDeploymentPaths';\n\nexport interface ResolvedDeployProject {\n readonly projectRoot: string;\n readonly manifestPath: string;\n readonly manifest: AppManifest;\n readonly deploy: AppDeployManifest | null;\n readonly paths: ProjectDeploymentPaths;\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import type { AppDeployManifest } from '@ankhorage/contracts/deploy';
2
+ import type { DeploymentExecutionResult } from '../../domain/DeploymentExecutionResult';
3
+ import type { DeploymentPlan } from '../../domain/DeploymentPlan';
4
+ import type { DeploymentVerificationResult } from '../../domain/DeploymentVerificationResult';
5
+ export interface ProjectDeploymentHistoryRecord {
6
+ readonly schemaVersion: 1;
7
+ readonly deploymentId: string;
8
+ readonly recordedAt: string;
9
+ readonly desired: AppDeployManifest | null;
10
+ readonly plan: DeploymentPlan;
11
+ readonly execution: DeploymentExecutionResult;
12
+ readonly verification?: DeploymentVerificationResult;
13
+ }
14
+ //# sourceMappingURL=ProjectDeploymentHistoryRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectDeploymentHistoryRecord.d.ts","sourceRoot":"","sources":["../../../src/project/history/ProjectDeploymentHistoryRecord.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,2CAA2C,CAAC;AAE9F,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,YAAY,CAAC,EAAE,4BAA4B,CAAC;CACtD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ProjectDeploymentHistoryRecord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectDeploymentHistoryRecord.js","sourceRoot":"","sources":["../../../src/project/history/ProjectDeploymentHistoryRecord.ts"],"names":[],"mappings":"","sourcesContent":["import type { AppDeployManifest } from '@ankhorage/contracts/deploy';\n\nimport type { DeploymentExecutionResult } from '../../domain/DeploymentExecutionResult';\nimport type { DeploymentPlan } from '../../domain/DeploymentPlan';\nimport type { DeploymentVerificationResult } from '../../domain/DeploymentVerificationResult';\n\nexport interface ProjectDeploymentHistoryRecord {\n readonly schemaVersion: 1;\n readonly deploymentId: string;\n readonly recordedAt: string;\n readonly desired: AppDeployManifest | null;\n readonly plan: DeploymentPlan;\n readonly execution: DeploymentExecutionResult;\n readonly verification?: DeploymentVerificationResult;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION: 1;
2
+ //# sourceMappingURL=historySchemaVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historySchemaVersion.d.ts","sourceRoot":"","sources":["../../../src/project/history/historySchemaVersion.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yCAAyC,EAAG,CAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION = 1;
2
+ //# sourceMappingURL=historySchemaVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historySchemaVersion.js","sourceRoot":"","sources":["../../../src/project/history/historySchemaVersion.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yCAAyC,GAAG,CAAU,CAAC","sourcesContent":["export const PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION = 1 as const;\n"]}
@@ -0,0 +1,5 @@
1
+ import type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';
2
+ export declare function listProjectDeploymentHistory(options: {
3
+ readonly projectRoot: string;
4
+ }): Promise<readonly ProjectDeploymentHistoryRecord[]>;
5
+ //# sourceMappingURL=listProjectDeploymentHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listProjectDeploymentHistory.d.ts","sourceRoot":"","sources":["../../../src/project/history/listProjectDeploymentHistory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAGvF,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,GAAG,OAAO,CAAC,SAAS,8BAA8B,EAAE,CAAC,CAcrD"}
@@ -0,0 +1,25 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { isMissingPathError } from '../io/isMissingPathError';
3
+ import { resolveDeployProject } from '../resolveDeployProject';
4
+ import { readProjectDeploymentHistory } from './readProjectDeploymentHistory';
5
+ export async function listProjectDeploymentHistory(options) {
6
+ const project = await resolveDeployProject({ projectRoot: options.projectRoot });
7
+ const entries = await readHistoryEntries(project.paths.historyRoot);
8
+ const ids = entries
9
+ .filter((entry) => entry.isDirectory())
10
+ .map((entry) => entry.name)
11
+ .sort((left, right) => left.localeCompare(right));
12
+ const records = await Promise.all(ids.map((deploymentId) => readProjectDeploymentHistory({ projectRoot: project.projectRoot, deploymentId })));
13
+ return records.filter((record) => record !== null);
14
+ }
15
+ async function readHistoryEntries(historyRoot) {
16
+ try {
17
+ return await fs.readdir(historyRoot, { withFileTypes: true });
18
+ }
19
+ catch (error) {
20
+ if (isMissingPathError(error))
21
+ return [];
22
+ throw error;
23
+ }
24
+ }
25
+ //# sourceMappingURL=listProjectDeploymentHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listProjectDeploymentHistory.js","sourceRoot":"","sources":["../../../src/project/history/listProjectDeploymentHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,OAElD;IACC,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,OAAO;SAChB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACvB,4BAA4B,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,YAAY,EAAE,CAAC,CACjF,CACF,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAA4C,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAC/F,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,WAAmB;IACnD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,kBAAkB,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { type Dirent, promises as fs } from 'node:fs';\n\nimport { isMissingPathError } from '../io/isMissingPathError';\nimport { resolveDeployProject } from '../resolveDeployProject';\nimport type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';\nimport { readProjectDeploymentHistory } from './readProjectDeploymentHistory';\n\nexport async function listProjectDeploymentHistory(options: {\n readonly projectRoot: string;\n}): Promise<readonly ProjectDeploymentHistoryRecord[]> {\n const project = await resolveDeployProject({ projectRoot: options.projectRoot });\n const entries = await readHistoryEntries(project.paths.historyRoot);\n const ids = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort((left, right) => left.localeCompare(right));\n\n const records = await Promise.all(\n ids.map((deploymentId) =>\n readProjectDeploymentHistory({ projectRoot: project.projectRoot, deploymentId }),\n ),\n );\n return records.filter((record): record is ProjectDeploymentHistoryRecord => record !== null);\n}\n\nasync function readHistoryEntries(historyRoot: string): Promise<readonly Dirent[]> {\n try {\n return await fs.readdir(historyRoot, { withFileTypes: true });\n } catch (error) {\n if (isMissingPathError(error)) return [];\n throw error;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';
2
+ export declare function parseProjectDeploymentHistoryRecord(value: unknown): ProjectDeploymentHistoryRecord;
3
+ //# sourceMappingURL=parseProjectDeploymentHistoryRecord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseProjectDeploymentHistoryRecord.d.ts","sourceRoot":"","sources":["../../../src/project/history/parseProjectDeploymentHistoryRecord.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAgBvF,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,GACb,8BAA8B,CAUhC"}
@@ -0,0 +1,40 @@
1
+ import { isAppDeployManifest } from '@ankhorage/contracts/deploy';
2
+ import { isSafeSegment } from '../io/assertSafeSegment';
3
+ import { hasOnlyKeys } from '../io/hasOnlyKeys';
4
+ import { isRecord } from '../io/isRecord';
5
+ import { PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION } from './historySchemaVersion';
6
+ import { isDeploymentExecution } from './validation/execution';
7
+ import { isIsoTimestamp } from './validation/isIsoTimestamp';
8
+ import { isDeploymentPlan } from './validation/plan';
9
+ import { isDeploymentVerification } from './validation/verification';
10
+ const HISTORY_KEYS = new Set([
11
+ 'schemaVersion',
12
+ 'deploymentId',
13
+ 'recordedAt',
14
+ 'desired',
15
+ 'plan',
16
+ 'execution',
17
+ 'verification',
18
+ ]);
19
+ export function parseProjectDeploymentHistoryRecord(value) {
20
+ if (isRecord(value) && value.schemaVersion !== PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION) {
21
+ throw new Error(`Unsupported deployment history schema version: ${String(value.schemaVersion)}`);
22
+ }
23
+ if (!isHistoryRecord(value)) {
24
+ throw new Error('Deployment history record has an invalid canonical shape.');
25
+ }
26
+ return value;
27
+ }
28
+ function isHistoryRecord(value) {
29
+ return (isRecord(value) &&
30
+ hasOnlyKeys(value, HISTORY_KEYS) &&
31
+ value.schemaVersion === PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION &&
32
+ typeof value.deploymentId === 'string' &&
33
+ isSafeSegment(value.deploymentId) &&
34
+ isIsoTimestamp(value.recordedAt) &&
35
+ (value.desired === null || isAppDeployManifest(value.desired)) &&
36
+ isDeploymentPlan(value.plan) &&
37
+ isDeploymentExecution(value.execution) &&
38
+ (value.verification === undefined || isDeploymentVerification(value.verification)));
39
+ }
40
+ //# sourceMappingURL=parseProjectDeploymentHistoryRecord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseProjectDeploymentHistoryRecord.js","sourceRoot":"","sources":["../../../src/project/history/parseProjectDeploymentHistoryRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,yCAAyC,EAAE,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,eAAe;IACf,cAAc;IACd,YAAY;IACZ,SAAS;IACT,MAAM;IACN,WAAW;IACX,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,UAAU,mCAAmC,CACjD,KAAc;IAEd,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,aAAa,KAAK,yCAAyC,EAAE,CAAC;QACzF,MAAM,IAAI,KAAK,CACb,kDAAkD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC;QAChC,KAAK,CAAC,aAAa,KAAK,yCAAyC;QACjE,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ;QACtC,aAAa,CAAC,KAAK,CAAC,YAAY,CAAC;QACjC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC;QAChC,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9D,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5B,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC;QACtC,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,wBAAwB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CACnF,CAAC;AACJ,CAAC","sourcesContent":["import { isAppDeployManifest } from '@ankhorage/contracts/deploy';\n\nimport { isSafeSegment } from '../io/assertSafeSegment';\nimport { hasOnlyKeys } from '../io/hasOnlyKeys';\nimport { isRecord } from '../io/isRecord';\nimport { PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION } from './historySchemaVersion';\nimport type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';\nimport { isDeploymentExecution } from './validation/execution';\nimport { isIsoTimestamp } from './validation/isIsoTimestamp';\nimport { isDeploymentPlan } from './validation/plan';\nimport { isDeploymentVerification } from './validation/verification';\n\nconst HISTORY_KEYS = new Set([\n 'schemaVersion',\n 'deploymentId',\n 'recordedAt',\n 'desired',\n 'plan',\n 'execution',\n 'verification',\n]);\n\nexport function parseProjectDeploymentHistoryRecord(\n value: unknown,\n): ProjectDeploymentHistoryRecord {\n if (isRecord(value) && value.schemaVersion !== PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION) {\n throw new Error(\n `Unsupported deployment history schema version: ${String(value.schemaVersion)}`,\n );\n }\n if (!isHistoryRecord(value)) {\n throw new Error('Deployment history record has an invalid canonical shape.');\n }\n return value;\n}\n\nfunction isHistoryRecord(value: unknown): value is ProjectDeploymentHistoryRecord {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, HISTORY_KEYS) &&\n value.schemaVersion === PROJECT_DEPLOYMENT_HISTORY_SCHEMA_VERSION &&\n typeof value.deploymentId === 'string' &&\n isSafeSegment(value.deploymentId) &&\n isIsoTimestamp(value.recordedAt) &&\n (value.desired === null || isAppDeployManifest(value.desired)) &&\n isDeploymentPlan(value.plan) &&\n isDeploymentExecution(value.execution) &&\n (value.verification === undefined || isDeploymentVerification(value.verification))\n );\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';
2
+ export declare function readProjectDeploymentHistory(options: {
3
+ readonly projectRoot: string;
4
+ readonly deploymentId: string;
5
+ }): Promise<ProjectDeploymentHistoryRecord | null>;
6
+ //# sourceMappingURL=readProjectDeploymentHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readProjectDeploymentHistory.d.ts","sourceRoot":"","sources":["../../../src/project/history/readProjectDeploymentHistory.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAEvF,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAkBjD"}
@@ -0,0 +1,26 @@
1
+ import path from 'node:path';
2
+ import { assertSafeSegment } from '../io/assertSafeSegment';
3
+ import { isMissingPathError } from '../io/isMissingPathError';
4
+ import { readJsonFile } from '../io/readJsonFile';
5
+ import { resolveDeployProject } from '../resolveDeployProject';
6
+ import { parseProjectDeploymentHistoryRecord } from './parseProjectDeploymentHistoryRecord';
7
+ export async function readProjectDeploymentHistory(options) {
8
+ assertSafeSegment(options.deploymentId, 'deployment id');
9
+ const project = await resolveDeployProject({ projectRoot: options.projectRoot });
10
+ const recordPath = path.join(project.paths.historyRoot, options.deploymentId, 'deployment.json');
11
+ let parsed;
12
+ try {
13
+ parsed = await readJsonFile(recordPath, 'Deployment history record');
14
+ }
15
+ catch (error) {
16
+ if (isMissingPathError(error))
17
+ return null;
18
+ throw error;
19
+ }
20
+ const record = parseProjectDeploymentHistoryRecord(parsed);
21
+ if (record.deploymentId !== options.deploymentId) {
22
+ throw new Error(`Deployment history id does not match its directory: ${options.deploymentId}`);
23
+ }
24
+ return record;
25
+ }
26
+ //# sourceMappingURL=readProjectDeploymentHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readProjectDeploymentHistory.js","sourceRoot":"","sources":["../../../src/project/history/readProjectDeploymentHistory.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAG5F,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,OAGlD;IACC,iBAAiB,CAAC,OAAO,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAEjG,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,kBAAkB,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,mCAAmC,CAAC,MAAM,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,YAAY,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uDAAuD,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import path from 'node:path';\n\nimport { assertSafeSegment } from '../io/assertSafeSegment';\nimport { isMissingPathError } from '../io/isMissingPathError';\nimport { readJsonFile } from '../io/readJsonFile';\nimport { resolveDeployProject } from '../resolveDeployProject';\nimport { parseProjectDeploymentHistoryRecord } from './parseProjectDeploymentHistoryRecord';\nimport type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';\n\nexport async function readProjectDeploymentHistory(options: {\n readonly projectRoot: string;\n readonly deploymentId: string;\n}): Promise<ProjectDeploymentHistoryRecord | null> {\n assertSafeSegment(options.deploymentId, 'deployment id');\n const project = await resolveDeployProject({ projectRoot: options.projectRoot });\n const recordPath = path.join(project.paths.historyRoot, options.deploymentId, 'deployment.json');\n\n let parsed: unknown;\n try {\n parsed = await readJsonFile(recordPath, 'Deployment history record');\n } catch (error) {\n if (isMissingPathError(error)) return null;\n throw error;\n }\n\n const record = parseProjectDeploymentHistoryRecord(parsed);\n if (record.deploymentId !== options.deploymentId) {\n throw new Error(`Deployment history id does not match its directory: ${options.deploymentId}`);\n }\n return record;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';
2
+ export declare function recordProjectDeploymentHistory(options: {
3
+ readonly projectRoot: string;
4
+ readonly record: ProjectDeploymentHistoryRecord;
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=recordProjectDeploymentHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordProjectDeploymentHistory.d.ts","sourceRoot":"","sources":["../../../src/project/history/recordProjectDeploymentHistory.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAEvF,wBAAsB,8BAA8B,CAAC,OAAO,EAAE;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAC;CACjD,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBhB"}
@@ -0,0 +1,40 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { assertContainedWritePath } from '../io/assertContainedPath';
4
+ import { assertSafeSegment } from '../io/assertSafeSegment';
5
+ import { atomicWriteJson } from '../io/atomicWriteJson';
6
+ import { resolveDeployProject } from '../resolveDeployProject';
7
+ import { parseProjectDeploymentHistoryRecord } from './parseProjectDeploymentHistoryRecord';
8
+ export async function recordProjectDeploymentHistory(options) {
9
+ const record = parseProjectDeploymentHistoryRecord(options.record);
10
+ assertSafeSegment(record.deploymentId, 'deployment id');
11
+ const project = await resolveDeployProject({ projectRoot: options.projectRoot });
12
+ const recordRoot = path.join(project.paths.historyRoot, record.deploymentId);
13
+ const recordPath = path.join(recordRoot, 'deployment.json');
14
+ await assertContainedWritePath(project.projectRoot, recordPath);
15
+ await fs.mkdir(project.paths.historyRoot, { recursive: true });
16
+ await createRecordDirectory(recordRoot, record.deploymentId);
17
+ try {
18
+ await atomicWriteJson({
19
+ projectRoot: project.projectRoot,
20
+ filePath: recordPath,
21
+ value: record,
22
+ });
23
+ }
24
+ catch (error) {
25
+ await fs.rm(recordRoot, { recursive: true, force: true });
26
+ throw error;
27
+ }
28
+ }
29
+ async function createRecordDirectory(recordRoot, deploymentId) {
30
+ try {
31
+ await fs.mkdir(recordRoot);
32
+ }
33
+ catch (error) {
34
+ if (error instanceof Error && 'code' in error && error.code === 'EEXIST') {
35
+ throw new Error(`Deployment history already exists: ${deploymentId}`, { cause: error });
36
+ }
37
+ throw error;
38
+ }
39
+ }
40
+ //# sourceMappingURL=recordProjectDeploymentHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordProjectDeploymentHistory.js","sourceRoot":"","sources":["../../../src/project/history/recordProjectDeploymentHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAG5F,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,OAGpD;IACC,MAAM,MAAM,GAAG,mCAAmC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACnE,iBAAiB,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IAC5D,MAAM,wBAAwB,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAChE,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,MAAM,eAAe,CAAC;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,UAAkB,EAAE,YAAoB;IAC3E,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CAAC,sCAAsC,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport { assertContainedWritePath } from '../io/assertContainedPath';\nimport { assertSafeSegment } from '../io/assertSafeSegment';\nimport { atomicWriteJson } from '../io/atomicWriteJson';\nimport { resolveDeployProject } from '../resolveDeployProject';\nimport { parseProjectDeploymentHistoryRecord } from './parseProjectDeploymentHistoryRecord';\nimport type { ProjectDeploymentHistoryRecord } from './ProjectDeploymentHistoryRecord';\n\nexport async function recordProjectDeploymentHistory(options: {\n readonly projectRoot: string;\n readonly record: ProjectDeploymentHistoryRecord;\n}): Promise<void> {\n const record = parseProjectDeploymentHistoryRecord(options.record);\n assertSafeSegment(record.deploymentId, 'deployment id');\n\n const project = await resolveDeployProject({ projectRoot: options.projectRoot });\n const recordRoot = path.join(project.paths.historyRoot, record.deploymentId);\n const recordPath = path.join(recordRoot, 'deployment.json');\n await assertContainedWritePath(project.projectRoot, recordPath);\n await fs.mkdir(project.paths.historyRoot, { recursive: true });\n await createRecordDirectory(recordRoot, record.deploymentId);\n\n try {\n await atomicWriteJson({\n projectRoot: project.projectRoot,\n filePath: recordPath,\n value: record,\n });\n } catch (error) {\n await fs.rm(recordRoot, { recursive: true, force: true });\n throw error;\n }\n}\n\nasync function createRecordDirectory(recordRoot: string, deploymentId: string): Promise<void> {\n try {\n await fs.mkdir(recordRoot);\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'EEXIST') {\n throw new Error(`Deployment history already exists: ${deploymentId}`, { cause: error });\n }\n throw error;\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isPlanDiagnostic(value: unknown): boolean;
2
+ //# sourceMappingURL=diagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/diagnostic.ts"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASxD"}
@@ -0,0 +1,14 @@
1
+ import { DEPLOYMENT_PLAN_DIAGNOSTIC_CODES } from '../../../domain/DeploymentPlanDiagnostic';
2
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
3
+ import { isRecord } from '../../io/isRecord';
4
+ import { isTargetId } from './shared';
5
+ const DIAGNOSTIC_KEYS = new Set(['code', 'target', 'message', 'stepId']);
6
+ export function isPlanDiagnostic(value) {
7
+ return (isRecord(value) &&
8
+ hasOnlyKeys(value, DIAGNOSTIC_KEYS) &&
9
+ DEPLOYMENT_PLAN_DIAGNOSTIC_CODES.some((code) => code === value.code) &&
10
+ isTargetId(value.target) &&
11
+ typeof value.message === 'string' &&
12
+ (value.stepId === undefined || typeof value.stepId === 'string'));
13
+ }
14
+ //# sourceMappingURL=diagnostic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic.js","sourceRoot":"","sources":["../../../../src/project/history/validation/diagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEzE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,eAAe,CAAC;QACnC,gCAAgC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;QACpE,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;QACxB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CACjE,CAAC;AACJ,CAAC","sourcesContent":["import { DEPLOYMENT_PLAN_DIAGNOSTIC_CODES } from '../../../domain/DeploymentPlanDiagnostic';\nimport { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isTargetId } from './shared';\n\nconst DIAGNOSTIC_KEYS = new Set(['code', 'target', 'message', 'stepId']);\n\nexport function isPlanDiagnostic(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, DIAGNOSTIC_KEYS) &&\n DEPLOYMENT_PLAN_DIAGNOSTIC_CODES.some((code) => code === value.code) &&\n isTargetId(value.target) &&\n typeof value.message === 'string' &&\n (value.stepId === undefined || typeof value.stepId === 'string')\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isDeploymentExecution(value: unknown): boolean;
2
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/execution.ts"],"names":[],"mappings":"AAcA,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAa7D"}
@@ -0,0 +1,40 @@
1
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
2
+ import { isRecord } from '../../io/isRecord';
3
+ import { isPlanDiagnostic } from './diagnostic';
4
+ import { isDeploymentFailure } from './failure';
5
+ import { isPlanStep } from './planStep';
6
+ import { isRequiredAction } from './requiredAction';
7
+ import { isStepOutcome } from './stepOutcome';
8
+ const RECORD_KEYS = new Set(['step', 'outcome']);
9
+ const BLOCKED_KEYS = new Set(['status', 'diagnostics', 'records']);
10
+ const COMPLETED_KEYS = new Set(['status', 'records']);
11
+ const ACTION_KEYS = new Set(['status', 'action', 'records']);
12
+ const FAILED_KEYS = new Set(['status', 'failure', 'records']);
13
+ export function isDeploymentExecution(value) {
14
+ if (!isRecord(value) || !Array.isArray(value.records))
15
+ return false;
16
+ if (!value.records.every(isExecutionRecord))
17
+ return false;
18
+ if (value.status === 'completed')
19
+ return hasOnlyKeys(value, COMPLETED_KEYS);
20
+ if (value.status === 'blocked')
21
+ return isBlocked(value);
22
+ if (value.status === 'action-required') {
23
+ return hasOnlyKeys(value, ACTION_KEYS) && isRequiredAction(value.action);
24
+ }
25
+ return (value.status === 'failed' &&
26
+ hasOnlyKeys(value, FAILED_KEYS) &&
27
+ isDeploymentFailure(value.failure));
28
+ }
29
+ function isExecutionRecord(value) {
30
+ return (isRecord(value) &&
31
+ hasOnlyKeys(value, RECORD_KEYS) &&
32
+ isPlanStep(value.step) &&
33
+ isStepOutcome(value.outcome));
34
+ }
35
+ function isBlocked(value) {
36
+ return (hasOnlyKeys(value, BLOCKED_KEYS) &&
37
+ Array.isArray(value.diagnostics) &&
38
+ value.diagnostics.every(isPlanDiagnostic));
39
+ }
40
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../../src/project/history/validation/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AACjD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AACnE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AACtD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAC7D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAE9D,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACpE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACvC,OAAO,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,QAAQ;QACzB,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC;QAC/B,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC;QAC/B,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;QACtB,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAC7B,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAA8B;IAC/C,OAAO,CACL,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QAChC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAC1C,CAAC;AACJ,CAAC","sourcesContent":["import { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isPlanDiagnostic } from './diagnostic';\nimport { isDeploymentFailure } from './failure';\nimport { isPlanStep } from './planStep';\nimport { isRequiredAction } from './requiredAction';\nimport { isStepOutcome } from './stepOutcome';\n\nconst RECORD_KEYS = new Set(['step', 'outcome']);\nconst BLOCKED_KEYS = new Set(['status', 'diagnostics', 'records']);\nconst COMPLETED_KEYS = new Set(['status', 'records']);\nconst ACTION_KEYS = new Set(['status', 'action', 'records']);\nconst FAILED_KEYS = new Set(['status', 'failure', 'records']);\n\nexport function isDeploymentExecution(value: unknown): boolean {\n if (!isRecord(value) || !Array.isArray(value.records)) return false;\n if (!value.records.every(isExecutionRecord)) return false;\n if (value.status === 'completed') return hasOnlyKeys(value, COMPLETED_KEYS);\n if (value.status === 'blocked') return isBlocked(value);\n if (value.status === 'action-required') {\n return hasOnlyKeys(value, ACTION_KEYS) && isRequiredAction(value.action);\n }\n return (\n value.status === 'failed' &&\n hasOnlyKeys(value, FAILED_KEYS) &&\n isDeploymentFailure(value.failure)\n );\n}\n\nfunction isExecutionRecord(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, RECORD_KEYS) &&\n isPlanStep(value.step) &&\n isStepOutcome(value.outcome)\n );\n}\n\nfunction isBlocked(value: Record<string, unknown>): boolean {\n return (\n hasOnlyKeys(value, BLOCKED_KEYS) &&\n Array.isArray(value.diagnostics) &&\n value.diagnostics.every(isPlanDiagnostic)\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isDeploymentFailure(value: unknown): boolean;
2
+ //# sourceMappingURL=failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/failure.ts"],"names":[],"mappings":"AAMA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAS3D"}
@@ -0,0 +1,13 @@
1
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
2
+ import { isRecord } from '../../io/isRecord';
3
+ import { isNonEmptyString, isTargetId } from './shared';
4
+ const FAILURE_KEYS = new Set(['code', 'message', 'target', 'provider']);
5
+ export function isDeploymentFailure(value) {
6
+ return (isRecord(value) &&
7
+ hasOnlyKeys(value, FAILURE_KEYS) &&
8
+ isNonEmptyString(value.code) &&
9
+ typeof value.message === 'string' &&
10
+ (value.target === undefined || isTargetId(value.target)) &&
11
+ (value.provider === undefined || isNonEmptyString(value.provider)));
12
+ }
13
+ //# sourceMappingURL=failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.js","sourceRoot":"","sources":["../../../../src/project/history/validation/failure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAExE,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC;QAChC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CACnE,CAAC;AACJ,CAAC","sourcesContent":["import { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isNonEmptyString, isTargetId } from './shared';\n\nconst FAILURE_KEYS = new Set(['code', 'message', 'target', 'provider']);\n\nexport function isDeploymentFailure(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, FAILURE_KEYS) &&\n isNonEmptyString(value.code) &&\n typeof value.message === 'string' &&\n (value.target === undefined || isTargetId(value.target)) &&\n (value.provider === undefined || isNonEmptyString(value.provider))\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isIsoTimestamp(value: unknown): value is string;
2
+ //# sourceMappingURL=isIsoTimestamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isIsoTimestamp.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/isIsoTimestamp.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAM9D"}
@@ -0,0 +1,6 @@
1
+ export function isIsoTimestamp(value) {
2
+ return (typeof value === 'string' &&
3
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(value) &&
4
+ !Number.isNaN(Date.parse(value)));
5
+ }
6
+ //# sourceMappingURL=isIsoTimestamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isIsoTimestamp.js","sourceRoot":"","sources":["../../../../src/project/history/validation/isIsoTimestamp.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,oDAAoD,CAAC,IAAI,CAAC,KAAK,CAAC;QAChE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CACjC,CAAC;AACJ,CAAC","sourcesContent":["export function isIsoTimestamp(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/.test(value) &&\n !Number.isNaN(Date.parse(value))\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isObservedTarget(value: unknown): boolean;
2
+ //# sourceMappingURL=observedTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observedTarget.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/observedTarget.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAqBxD"}
@@ -0,0 +1,24 @@
1
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
2
+ import { isRecord } from '../../io/isRecord';
3
+ import { isProviderSelection } from './providerSelection';
4
+ import { isNonEmptyString } from './shared';
5
+ const WEB_KEYS = new Set(['target', 'providers']);
6
+ const ANDROID_KEYS = new Set(['target', 'package', 'providers']);
7
+ const IOS_KEYS = new Set(['target', 'bundleIdentifier', 'providers']);
8
+ export function isObservedTarget(value) {
9
+ if (!isRecord(value))
10
+ return false;
11
+ if (value.target === 'web') {
12
+ return hasOnlyKeys(value, WEB_KEYS) && isProviderSelection(value.providers);
13
+ }
14
+ if (value.target === 'android') {
15
+ return (hasOnlyKeys(value, ANDROID_KEYS) &&
16
+ isNonEmptyString(value.package) &&
17
+ isProviderSelection(value.providers));
18
+ }
19
+ return (value.target === 'ios' &&
20
+ hasOnlyKeys(value, IOS_KEYS) &&
21
+ isNonEmptyString(value.bundleIdentifier) &&
22
+ isProviderSelection(value.providers));
23
+ }
24
+ //# sourceMappingURL=observedTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observedTarget.js","sourceRoot":"","sources":["../../../../src/project/history/validation/observedTarget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAClD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC;AAEtE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CACL,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC;YAChC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC;YAC/B,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CACrC,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,KAAK;QACtB,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC;QAC5B,gBAAgB,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACxC,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CACrC,CAAC;AACJ,CAAC","sourcesContent":["import { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isProviderSelection } from './providerSelection';\nimport { isNonEmptyString } from './shared';\n\nconst WEB_KEYS = new Set(['target', 'providers']);\nconst ANDROID_KEYS = new Set(['target', 'package', 'providers']);\nconst IOS_KEYS = new Set(['target', 'bundleIdentifier', 'providers']);\n\nexport function isObservedTarget(value: unknown): boolean {\n if (!isRecord(value)) return false;\n\n if (value.target === 'web') {\n return hasOnlyKeys(value, WEB_KEYS) && isProviderSelection(value.providers);\n }\n\n if (value.target === 'android') {\n return (\n hasOnlyKeys(value, ANDROID_KEYS) &&\n isNonEmptyString(value.package) &&\n isProviderSelection(value.providers)\n );\n }\n\n return (\n value.target === 'ios' &&\n hasOnlyKeys(value, IOS_KEYS) &&\n isNonEmptyString(value.bundleIdentifier) &&\n isProviderSelection(value.providers)\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isDeploymentPlan(value: unknown): boolean;
2
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/plan.ts"],"names":[],"mappings":"AAQA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYxD"}
@@ -0,0 +1,18 @@
1
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
2
+ import { isRecord } from '../../io/isRecord';
3
+ import { isPlanDiagnostic } from './diagnostic';
4
+ import { isPlanStep } from './planStep';
5
+ import { isTargetChange } from './targetChange';
6
+ const PLAN_KEYS = new Set(['changes', 'steps', 'diagnostics', 'executable']);
7
+ export function isDeploymentPlan(value) {
8
+ return (isRecord(value) &&
9
+ hasOnlyKeys(value, PLAN_KEYS) &&
10
+ Array.isArray(value.changes) &&
11
+ value.changes.every(isTargetChange) &&
12
+ Array.isArray(value.steps) &&
13
+ value.steps.every(isPlanStep) &&
14
+ Array.isArray(value.diagnostics) &&
15
+ value.diagnostics.every(isPlanDiagnostic) &&
16
+ typeof value.executable === 'boolean');
17
+ }
18
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../../src/project/history/validation/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;AAE7E,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC;QAC7B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC;QACnC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QAC1B,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;QAC7B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QAChC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACzC,OAAO,KAAK,CAAC,UAAU,KAAK,SAAS,CACtC,CAAC;AACJ,CAAC","sourcesContent":["import { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isPlanDiagnostic } from './diagnostic';\nimport { isPlanStep } from './planStep';\nimport { isTargetChange } from './targetChange';\n\nconst PLAN_KEYS = new Set(['changes', 'steps', 'diagnostics', 'executable']);\n\nexport function isDeploymentPlan(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, PLAN_KEYS) &&\n Array.isArray(value.changes) &&\n value.changes.every(isTargetChange) &&\n Array.isArray(value.steps) &&\n value.steps.every(isPlanStep) &&\n Array.isArray(value.diagnostics) &&\n value.diagnostics.every(isPlanDiagnostic) &&\n typeof value.executable === 'boolean'\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function isPlanStep(value: unknown): boolean;
2
+ //# sourceMappingURL=planStep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planStep.d.ts","sourceRoot":"","sources":["../../../../src/project/history/validation/planStep.ts"],"names":[],"mappings":"AAQA,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWlD"}
@@ -0,0 +1,17 @@
1
+ import { DEPLOYMENT_CAPABILITIES } from '../../../domain/DeploymentCapability';
2
+ import { DEPLOYMENT_STEP_OPERATIONS } from '../../../domain/DeploymentPlanStep';
3
+ import { hasOnlyKeys } from '../../io/hasOnlyKeys';
4
+ import { isRecord } from '../../io/isRecord';
5
+ import { isNonEmptyString, isTargetId } from './shared';
6
+ const STEP_KEYS = new Set(['id', 'target', 'phase', 'operation', 'provider', 'reason']);
7
+ export function isPlanStep(value) {
8
+ return (isRecord(value) &&
9
+ hasOnlyKeys(value, STEP_KEYS) &&
10
+ isNonEmptyString(value.id) &&
11
+ isTargetId(value.target) &&
12
+ DEPLOYMENT_CAPABILITIES.some((phase) => phase === value.phase) &&
13
+ DEPLOYMENT_STEP_OPERATIONS.some((operation) => operation === value.operation) &&
14
+ (value.provider === undefined || isNonEmptyString(value.provider)) &&
15
+ typeof value.reason === 'string');
16
+ }
17
+ //# sourceMappingURL=planStep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planStep.js","sourceRoot":"","sources":["../../../../src/project/history/validation/planStep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAExF,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC;QAC7B,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;QACxB,uBAAuB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC;QAC9D,0BAA0B,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;QAC7E,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClE,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CACjC,CAAC;AACJ,CAAC","sourcesContent":["import { DEPLOYMENT_CAPABILITIES } from '../../../domain/DeploymentCapability';\nimport { DEPLOYMENT_STEP_OPERATIONS } from '../../../domain/DeploymentPlanStep';\nimport { hasOnlyKeys } from '../../io/hasOnlyKeys';\nimport { isRecord } from '../../io/isRecord';\nimport { isNonEmptyString, isTargetId } from './shared';\n\nconst STEP_KEYS = new Set(['id', 'target', 'phase', 'operation', 'provider', 'reason']);\n\nexport function isPlanStep(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, STEP_KEYS) &&\n isNonEmptyString(value.id) &&\n isTargetId(value.target) &&\n DEPLOYMENT_CAPABILITIES.some((phase) => phase === value.phase) &&\n DEPLOYMENT_STEP_OPERATIONS.some((operation) => operation === value.operation) &&\n (value.provider === undefined || isNonEmptyString(value.provider)) &&\n typeof value.reason === 'string'\n );\n}\n"]}