@sfship/plugin-ship 1.0.0-beta.2

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 (229) hide show
  1. package/LICENSE.txt +206 -0
  2. package/README.md +164 -0
  3. package/lib/commands/ship/flow/eject.d.ts +15 -0
  4. package/lib/commands/ship/flow/eject.js +55 -0
  5. package/lib/commands/ship/flow/eject.js.map +1 -0
  6. package/lib/commands/ship/flow/info.d.ts +15 -0
  7. package/lib/commands/ship/flow/info.js +86 -0
  8. package/lib/commands/ship/flow/info.js.map +1 -0
  9. package/lib/commands/ship/flow/list.d.ts +12 -0
  10. package/lib/commands/ship/flow/list.js +51 -0
  11. package/lib/commands/ship/flow/list.js.map +1 -0
  12. package/lib/commands/ship/flow/run.d.ts +16 -0
  13. package/lib/commands/ship/flow/run.js +90 -0
  14. package/lib/commands/ship/flow/run.js.map +1 -0
  15. package/lib/commands/ship/project/init.d.ts +13 -0
  16. package/lib/commands/ship/project/init.js +81 -0
  17. package/lib/commands/ship/project/init.js.map +1 -0
  18. package/lib/commands/ship/service/connect/github.d.ts +12 -0
  19. package/lib/commands/ship/service/connect/github.js +47 -0
  20. package/lib/commands/ship/service/connect/github.js.map +1 -0
  21. package/lib/commands/ship/service/delete.d.ts +13 -0
  22. package/lib/commands/ship/service/delete.js +44 -0
  23. package/lib/commands/ship/service/delete.js.map +1 -0
  24. package/lib/commands/ship/service/info.d.ts +13 -0
  25. package/lib/commands/ship/service/info.js +51 -0
  26. package/lib/commands/ship/service/info.js.map +1 -0
  27. package/lib/commands/ship/service/list.d.ts +9 -0
  28. package/lib/commands/ship/service/list.js +55 -0
  29. package/lib/commands/ship/service/list.js.map +1 -0
  30. package/lib/commands/ship/task/info.d.ts +15 -0
  31. package/lib/commands/ship/task/info.js +75 -0
  32. package/lib/commands/ship/task/info.js.map +1 -0
  33. package/lib/commands/ship/task/list.d.ts +12 -0
  34. package/lib/commands/ship/task/list.js +45 -0
  35. package/lib/commands/ship/task/list.js.map +1 -0
  36. package/lib/commands/ship/task/run.d.ts +16 -0
  37. package/lib/commands/ship/task/run.js +72 -0
  38. package/lib/commands/ship/task/run.js.map +1 -0
  39. package/lib/core/config.dependency.schema.d.ts +24 -0
  40. package/lib/core/config.dependency.schema.js +34 -0
  41. package/lib/core/config.dependency.schema.js.map +1 -0
  42. package/lib/core/config.loader.d.ts +23 -0
  43. package/lib/core/config.loader.js +62 -0
  44. package/lib/core/config.loader.js.map +1 -0
  45. package/lib/core/config.ship.schema.d.ts +174 -0
  46. package/lib/core/config.ship.schema.js +67 -0
  47. package/lib/core/config.ship.schema.js.map +1 -0
  48. package/lib/core/error.d.ts +29 -0
  49. package/lib/core/error.js +59 -0
  50. package/lib/core/error.js.map +1 -0
  51. package/lib/core/file.d.ts +34 -0
  52. package/lib/core/file.js +123 -0
  53. package/lib/core/file.js.map +1 -0
  54. package/lib/core/flow.context.d.ts +22 -0
  55. package/lib/core/flow.context.js +4 -0
  56. package/lib/core/flow.context.js.map +1 -0
  57. package/lib/core/flow.definition.schema.d.ts +60 -0
  58. package/lib/core/flow.definition.schema.js +56 -0
  59. package/lib/core/flow.definition.schema.js.map +1 -0
  60. package/lib/core/flow.interpolate.d.ts +21 -0
  61. package/lib/core/flow.interpolate.js +64 -0
  62. package/lib/core/flow.interpolate.js.map +1 -0
  63. package/lib/core/flow.registry.d.ts +32 -0
  64. package/lib/core/flow.registry.js +99 -0
  65. package/lib/core/flow.registry.js.map +1 -0
  66. package/lib/core/flow.renderer.d.ts +51 -0
  67. package/lib/core/flow.renderer.js +137 -0
  68. package/lib/core/flow.renderer.js.map +1 -0
  69. package/lib/core/flow.runner.d.ts +13 -0
  70. package/lib/core/flow.runner.js +133 -0
  71. package/lib/core/flow.runner.js.map +1 -0
  72. package/lib/core/flow.store.d.ts +24 -0
  73. package/lib/core/flow.store.js +57 -0
  74. package/lib/core/flow.store.js.map +1 -0
  75. package/lib/core/flow.view.d.ts +20 -0
  76. package/lib/core/flow.view.js +77 -0
  77. package/lib/core/flow.view.js.map +1 -0
  78. package/lib/core/flows/create/package.yml +18 -0
  79. package/lib/core/flows/dependencies/lock.yml +4 -0
  80. package/lib/core/flows/deploy/beta.yml +38 -0
  81. package/lib/core/flows/deploy/dev.yml +26 -0
  82. package/lib/core/flows/deploy/feature.yml +56 -0
  83. package/lib/core/flows/deploy/qa.yml +51 -0
  84. package/lib/core/flows/deploy/regression.yml +60 -0
  85. package/lib/core/flows/deploy/release.yml +38 -0
  86. package/lib/core/flows/release/beta.yml +25 -0
  87. package/lib/core/flows/release/production.yml +16 -0
  88. package/lib/core/org.registry.d.ts +45 -0
  89. package/lib/core/org.registry.js +76 -0
  90. package/lib/core/org.registry.js.map +1 -0
  91. package/lib/core/org.scratch.schema.d.ts +44 -0
  92. package/lib/core/org.scratch.schema.js +62 -0
  93. package/lib/core/org.scratch.schema.js.map +1 -0
  94. package/lib/core/package.dependencies.d.ts +45 -0
  95. package/lib/core/package.dependencies.js +158 -0
  96. package/lib/core/package.dependencies.js.map +1 -0
  97. package/lib/core/package.installer.d.ts +13 -0
  98. package/lib/core/package.installer.js +60 -0
  99. package/lib/core/package.installer.js.map +1 -0
  100. package/lib/core/package.metadata.d.ts +6 -0
  101. package/lib/core/package.metadata.js +33 -0
  102. package/lib/core/package.metadata.js.map +1 -0
  103. package/lib/core/package.namespace.d.ts +10 -0
  104. package/lib/core/package.namespace.js +40 -0
  105. package/lib/core/package.namespace.js.map +1 -0
  106. package/lib/core/package.version.d.ts +42 -0
  107. package/lib/core/package.version.js +60 -0
  108. package/lib/core/package.version.js.map +1 -0
  109. package/lib/core/project.init.d.ts +11 -0
  110. package/lib/core/project.init.js +121 -0
  111. package/lib/core/project.init.js.map +1 -0
  112. package/lib/core/service.d.ts +45 -0
  113. package/lib/core/service.github.d.ts +98 -0
  114. package/lib/core/service.github.js +270 -0
  115. package/lib/core/service.github.js.map +1 -0
  116. package/lib/core/service.js +91 -0
  117. package/lib/core/service.js.map +1 -0
  118. package/lib/core/sfdx-project.d.ts +25 -0
  119. package/lib/core/sfdx-project.js +39 -0
  120. package/lib/core/sfdx-project.js.map +1 -0
  121. package/lib/core/stdout.d.ts +1 -0
  122. package/lib/core/stdout.js +27 -0
  123. package/lib/core/stdout.js.map +1 -0
  124. package/lib/core/task.definition.schema.d.ts +69 -0
  125. package/lib/core/task.definition.schema.js +33 -0
  126. package/lib/core/task.definition.schema.js.map +1 -0
  127. package/lib/core/task.output.d.ts +29 -0
  128. package/lib/core/task.output.js +39 -0
  129. package/lib/core/task.output.js.map +1 -0
  130. package/lib/core/task.param.d.ts +30 -0
  131. package/lib/core/task.param.js +141 -0
  132. package/lib/core/task.param.js.map +1 -0
  133. package/lib/core/task.param.schema.d.ts +22 -0
  134. package/lib/core/task.param.schema.js +26 -0
  135. package/lib/core/task.param.schema.js.map +1 -0
  136. package/lib/core/task.registry.d.ts +22 -0
  137. package/lib/core/task.registry.js +85 -0
  138. package/lib/core/task.registry.js.map +1 -0
  139. package/lib/core/task.view.d.ts +10 -0
  140. package/lib/core/task.view.js +25 -0
  141. package/lib/core/task.view.js.map +1 -0
  142. package/lib/core/tasks/apex/run/test.d.ts +25 -0
  143. package/lib/core/tasks/apex/run/test.js +85 -0
  144. package/lib/core/tasks/apex/run/test.js.map +1 -0
  145. package/lib/core/tasks/data/import/tree.d.ts +12 -0
  146. package/lib/core/tasks/data/import/tree.js +61 -0
  147. package/lib/core/tasks/data/import/tree.js.map +1 -0
  148. package/lib/core/tasks/git/release/create.d.ts +42 -0
  149. package/lib/core/tasks/git/release/create.js +197 -0
  150. package/lib/core/tasks/git/release/create.js.map +1 -0
  151. package/lib/core/tasks/git/release/fetch.d.ts +24 -0
  152. package/lib/core/tasks/git/release/fetch.js +93 -0
  153. package/lib/core/tasks/git/release/fetch.js.map +1 -0
  154. package/lib/core/tasks/git/repo/info.d.ts +12 -0
  155. package/lib/core/tasks/git/repo/info.js +47 -0
  156. package/lib/core/tasks/git/repo/info.js.map +1 -0
  157. package/lib/core/tasks/metadata/deploy.d.ts +12 -0
  158. package/lib/core/tasks/metadata/deploy.js +39 -0
  159. package/lib/core/tasks/metadata/deploy.js.map +1 -0
  160. package/lib/core/tasks/org/assign/permsets.d.ts +12 -0
  161. package/lib/core/tasks/org/assign/permsets.js +54 -0
  162. package/lib/core/tasks/org/assign/permsets.js.map +1 -0
  163. package/lib/core/tasks/org/create/scratch.d.ts +36 -0
  164. package/lib/core/tasks/org/create/scratch.js +127 -0
  165. package/lib/core/tasks/org/create/scratch.js.map +1 -0
  166. package/lib/core/tasks/org/delete/scratch.d.ts +12 -0
  167. package/lib/core/tasks/org/delete/scratch.js +10 -0
  168. package/lib/core/tasks/org/delete/scratch.js.map +1 -0
  169. package/lib/core/tasks/package/create.d.ts +36 -0
  170. package/lib/core/tasks/package/create.js +93 -0
  171. package/lib/core/tasks/package/create.js.map +1 -0
  172. package/lib/core/tasks/package/dependencies/lock.d.ts +6 -0
  173. package/lib/core/tasks/package/dependencies/lock.js +35 -0
  174. package/lib/core/tasks/package/dependencies/lock.js.map +1 -0
  175. package/lib/core/tasks/package/dependencies/verify.d.ts +6 -0
  176. package/lib/core/tasks/package/dependencies/verify.js +44 -0
  177. package/lib/core/tasks/package/dependencies/verify.js.map +1 -0
  178. package/lib/core/tasks/package/install/dependencies.d.ts +22 -0
  179. package/lib/core/tasks/package/install/dependencies.js +43 -0
  180. package/lib/core/tasks/package/install/dependencies.js.map +1 -0
  181. package/lib/core/tasks/package/install/index.d.ts +25 -0
  182. package/lib/core/tasks/package/install/index.js +37 -0
  183. package/lib/core/tasks/package/install/index.js.map +1 -0
  184. package/lib/core/tasks/package/version/create.d.ts +36 -0
  185. package/lib/core/tasks/package/version/create.js +133 -0
  186. package/lib/core/tasks/package/version/create.js.map +1 -0
  187. package/lib/core/tasks/package/version/promote.d.ts +30 -0
  188. package/lib/core/tasks/package/version/promote.js +79 -0
  189. package/lib/core/tasks/package/version/promote.js.map +1 -0
  190. package/lib/core/tasks/package/version/resolve-latest.d.ts +24 -0
  191. package/lib/core/tasks/package/version/resolve-latest.js +78 -0
  192. package/lib/core/tasks/package/version/resolve-latest.js.map +1 -0
  193. package/lib/core/tasks/package/version/resolve-next.d.ts +24 -0
  194. package/lib/core/tasks/package/version/resolve-next.js +49 -0
  195. package/lib/core/tasks/package/version/resolve-next.js.map +1 -0
  196. package/lib/core/tasks/project/deploy/start.d.ts +22 -0
  197. package/lib/core/tasks/project/deploy/start.js +117 -0
  198. package/lib/core/tasks/project/deploy/start.js.map +1 -0
  199. package/lib/core/tasks/project/reset/tracking.d.ts +25 -0
  200. package/lib/core/tasks/project/reset/tracking.js +32 -0
  201. package/lib/core/tasks/project/reset/tracking.js.map +1 -0
  202. package/lib/core/tasks/util/file/exists.d.ts +24 -0
  203. package/lib/core/tasks/util/file/exists.js +53 -0
  204. package/lib/core/tasks/util/file/exists.js.map +1 -0
  205. package/lib/core/tasks/util/file/find.d.ts +30 -0
  206. package/lib/core/tasks/util/file/find.js +70 -0
  207. package/lib/core/tasks/util/file/find.js.map +1 -0
  208. package/lib/core/tasks/util/log.d.ts +13 -0
  209. package/lib/core/tasks/util/log.js +10 -0
  210. package/lib/core/tasks/util/log.js.map +1 -0
  211. package/lib/core/templates/README.md +35 -0
  212. package/lib/core/tree.d.ts +7 -0
  213. package/lib/core/tree.js +42 -0
  214. package/lib/core/tree.js.map +1 -0
  215. package/messages/service.connect.github.md +16 -0
  216. package/messages/ship.flow.eject.md +21 -0
  217. package/messages/ship.flow.info.md +21 -0
  218. package/messages/ship.flow.list.md +15 -0
  219. package/messages/ship.flow.run.md +23 -0
  220. package/messages/ship.project.init.md +23 -0
  221. package/messages/ship.service.delete.md +19 -0
  222. package/messages/ship.service.info.md +19 -0
  223. package/messages/ship.service.list.md +11 -0
  224. package/messages/ship.task.info.md +25 -0
  225. package/messages/ship.task.list.md +15 -0
  226. package/messages/ship.task.run.md +29 -0
  227. package/oclif.lock +10313 -0
  228. package/oclif.manifest.json +707 -0
  229. package/package.json +254 -0
@@ -0,0 +1,34 @@
1
+ /** Returns true if the path exists on the filesystem. */
2
+ export declare function fileExists(path: string): boolean;
3
+ /** Creates a directory and any missing parents. No-ops if it already exists. */
4
+ export declare function ensureDir(path: string): void;
5
+ /** Lists all entries in a directory. */
6
+ export declare function listDir(path: string, options?: {
7
+ recursive?: boolean;
8
+ }): string[];
9
+ /** Reads a file as a UTF-8 string. */
10
+ export declare function readText(path: string): string;
11
+ /** Reads and parses a JSON file. */
12
+ export declare function readJson<T>(path: string): T;
13
+ /** Writes a UTF-8 string to a file, appending a trailing newline if one is not already present. */
14
+ export declare function writeText(path: string, content: string): void;
15
+ /** Appends a UTF-8 string to a file, creating it if it does not exist. */
16
+ export declare function appendText(path: string, content: string): void;
17
+ /** Writes a value as pretty-printed JSON to a file. */
18
+ export declare function writeJson(path: string, data: unknown): void;
19
+ /** Writes binary data to a file. */
20
+ export declare function writeBinary(path: string, data: Buffer): void;
21
+ /** Removes a file. Throws if the file does not exist or cannot be removed. */
22
+ export declare function removeFile(path: string): void;
23
+ /** Canonicalizes a task or flow name into its registry key form: trimmed, lowercased, forward-slash separated, no leading slash. */
24
+ export declare function normalizePath(name: string): string;
25
+ /** Returns true if the path exists and matches the given kind (`any`, `file`, or `dir`). */
26
+ export declare function pathExists(path: string, kind: 'any' | 'file' | 'dir'): boolean;
27
+ /** Finds files in `dir` whose names (without extension) match a glob pattern. */
28
+ export declare function findFiles(dir: string, options?: {
29
+ pattern?: string;
30
+ recursive?: boolean;
31
+ stripExtension?: boolean;
32
+ }): Promise<string[]>;
33
+ /** Recursively returns all file paths under `dir`. */
34
+ export declare function walkFiles(dir: string): Promise<string[]>;
@@ -0,0 +1,123 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, appendFileSync, } from 'node:fs';
15
+ import { readdir } from 'node:fs/promises';
16
+ import { basename, extname, join } from 'node:path';
17
+ /* c8 ignore start */
18
+ /** Returns true if the path exists on the filesystem. */
19
+ export function fileExists(path) {
20
+ return existsSync(path);
21
+ }
22
+ /** Creates a directory and any missing parents. No-ops if it already exists. */
23
+ export function ensureDir(path) {
24
+ mkdirSync(path, { recursive: true });
25
+ }
26
+ /** Lists all entries in a directory. */
27
+ export function listDir(path, options) {
28
+ return readdirSync(path, options);
29
+ }
30
+ /** Reads a file as a UTF-8 string. */
31
+ export function readText(path) {
32
+ return readFileSync(path, 'utf8');
33
+ }
34
+ /** Reads and parses a JSON file. */
35
+ export function readJson(path) {
36
+ return JSON.parse(readFileSync(path, 'utf8'));
37
+ }
38
+ /** Writes a UTF-8 string to a file, appending a trailing newline if one is not already present. */
39
+ export function writeText(path, content) {
40
+ writeFileSync(path, content.endsWith('\n') ? content : `${content}\n`);
41
+ }
42
+ /** Appends a UTF-8 string to a file, creating it if it does not exist. */
43
+ export function appendText(path, content) {
44
+ appendFileSync(path, content, 'utf8');
45
+ }
46
+ /** Writes a value as pretty-printed JSON to a file. */
47
+ export function writeJson(path, data) {
48
+ writeText(path, JSON.stringify(data, null, 2));
49
+ }
50
+ /** Writes binary data to a file. */
51
+ export function writeBinary(path, data) {
52
+ writeFileSync(path, data);
53
+ }
54
+ /** Removes a file. Throws if the file does not exist or cannot be removed. */
55
+ export function removeFile(path) {
56
+ rmSync(path);
57
+ }
58
+ /** Canonicalizes a task or flow name into its registry key form: trimmed, lowercased, forward-slash separated, no leading slash. */
59
+ export function normalizePath(name) {
60
+ return name.trim().toLowerCase().replaceAll('\\', '/').replace(/^\/+/, '');
61
+ }
62
+ /* c8 ignore stop */
63
+ /** Returns true if the path exists and matches the given kind (`any`, `file`, or `dir`). */
64
+ export function pathExists(path, kind) {
65
+ if (kind === 'any')
66
+ return existsSync(path);
67
+ try {
68
+ const stat = statSync(path);
69
+ return kind === 'file' ? stat.isFile() : stat.isDirectory();
70
+ }
71
+ catch (err) {
72
+ if (err.code === 'ENOENT')
73
+ return false;
74
+ throw err;
75
+ }
76
+ }
77
+ function globToRegex(pattern) {
78
+ const escaped = pattern
79
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
80
+ .replace(/\*/g, '.*')
81
+ .replace(/\?/g, '.');
82
+ return new RegExp(`^${escaped}$`, 'i');
83
+ }
84
+ async function collectFiles(dir, regex, recursive, stripExt) {
85
+ let entries;
86
+ try {
87
+ entries = await readdir(dir, { withFileTypes: true });
88
+ }
89
+ catch {
90
+ return [];
91
+ }
92
+ const results = [];
93
+ for (const entry of entries) {
94
+ if (entry.isDirectory()) {
95
+ if (recursive) {
96
+ // eslint-disable-next-line no-await-in-loop
97
+ results.push(...(await collectFiles(join(dir, entry.name), regex, recursive, stripExt)));
98
+ }
99
+ }
100
+ else if (entry.isFile()) {
101
+ const nameNoExt = basename(entry.name, extname(entry.name));
102
+ if (regex.test(nameNoExt)) {
103
+ results.push(stripExt ? nameNoExt : entry.name);
104
+ }
105
+ }
106
+ }
107
+ return results;
108
+ }
109
+ /** Finds files in `dir` whose names (without extension) match a glob pattern. */
110
+ export async function findFiles(dir, options = {}) {
111
+ const { pattern = '*', recursive = true, stripExtension = true } = options;
112
+ return collectFiles(dir, globToRegex(pattern), recursive, stripExtension);
113
+ }
114
+ /** Recursively returns all file paths under `dir`. */
115
+ export async function walkFiles(dir) {
116
+ const entries = await readdir(dir, { withFileTypes: true });
117
+ const nested = await Promise.all(entries.map((entry) => {
118
+ const fullPath = join(dir, entry.name);
119
+ return entry.isDirectory() ? walkFiles(fullPath) : Promise.resolve([fullPath]);
120
+ }));
121
+ return nested.flat();
122
+ }
123
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/core/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ShipConfig } from './config.ship.schema.js';
2
+ import { Params } from './task.param.schema.js';
3
+ import { OrgRegistry } from './org.registry.js';
4
+ export type FlowContext = {
5
+ /** Absolute path to the directory containing `ship.yml` — the project root. */
6
+ projectDir: string;
7
+ /** Absolute path to the `.ship` directory for the current project. */
8
+ shipDir: string;
9
+ /** The loaded ship configuration for this project. */
10
+ config: ShipConfig;
11
+ /** Registry for accessing Salesforce orgs and their definitions. */
12
+ orgs: OrgRegistry;
13
+ /** Writes a log message to the flow's output. */
14
+ log: (message: string) => void;
15
+ /** The params the flow was invoked with. */
16
+ params: Params;
17
+ /** True if any step has failed with ignore-failure during this flow run. */
18
+ hasFailures: boolean;
19
+ /** Invokes an sf CLI command in-process via oclif's plugin system. */
20
+ runCommand: (id: string, argv: string[]) => Promise<unknown>;
21
+ };
22
+ export declare function createFlowContext(init: Omit<FlowContext, 'hasFailures'>): FlowContext;
@@ -0,0 +1,4 @@
1
+ export function createFlowContext(init) {
2
+ return { hasFailures: false, ...init };
3
+ }
4
+ //# sourceMappingURL=flow.context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.context.js","sourceRoot":"","sources":["../../src/core/flow.context.ts"],"names":[],"mappings":"AAoCA,MAAM,UAAU,iBAAiB,CAAC,IAAsC;IACtE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { z } from 'zod';
2
+ /** A single step within a flow definition. */
3
+ declare const FlowStepSchema: z.ZodObject<{
4
+ task: z.ZodString;
5
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
6
+ if: z.ZodOptional<z.ZodObject<{
7
+ value: z.ZodString;
8
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
9
+ }, z.core.$strict>>;
10
+ 'if-not': z.ZodOptional<z.ZodObject<{
11
+ value: z.ZodString;
12
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
13
+ }, z.core.$strict>>;
14
+ 'ignore-failure': z.ZodOptional<z.ZodBoolean>;
15
+ }, z.core.$strip>;
16
+ /** Defines a named flow: its accepted params and the ordered steps to execute. */
17
+ export declare const FlowDefinitionSchema: z.ZodObject<{
18
+ description: z.ZodOptional<z.ZodString>;
19
+ params: z.ZodOptional<z.ZodArray<z.ZodObject<{
20
+ name: z.ZodString;
21
+ type: z.ZodDefault<z.ZodEnum<{
22
+ string: "string";
23
+ number: "number";
24
+ boolean: "boolean";
25
+ record: "record";
26
+ }>>;
27
+ required: z.ZodOptional<z.ZodBoolean>;
28
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
29
+ description: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>>>;
31
+ steps: z.ZodRecord<z.ZodString, z.ZodObject<{
32
+ task: z.ZodString;
33
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
34
+ if: z.ZodOptional<z.ZodObject<{
35
+ value: z.ZodString;
36
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
37
+ }, z.core.$strict>>;
38
+ 'if-not': z.ZodOptional<z.ZodObject<{
39
+ value: z.ZodString;
40
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
41
+ }, z.core.$strict>>;
42
+ 'ignore-failure': z.ZodOptional<z.ZodBoolean>;
43
+ }, z.core.$strip>>;
44
+ finally: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
45
+ task: z.ZodString;
46
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
47
+ if: z.ZodOptional<z.ZodObject<{
48
+ value: z.ZodString;
49
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
50
+ }, z.core.$strict>>;
51
+ 'if-not': z.ZodOptional<z.ZodObject<{
52
+ value: z.ZodString;
53
+ equals: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
54
+ }, z.core.$strict>>;
55
+ 'ignore-failure': z.ZodOptional<z.ZodBoolean>;
56
+ }, z.core.$strip>>>;
57
+ }, z.core.$strip>;
58
+ export type FlowStep = z.infer<typeof FlowStepSchema>;
59
+ export type FlowDefinition = z.infer<typeof FlowDefinitionSchema>;
60
+ export {};
@@ -0,0 +1,56 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ import { z } from 'zod';
15
+ import { ParamDefinitionSchema, ParamValueSchema } from './task.param.schema.js';
16
+ /** A scalar value or null that a condition can compare against. */
17
+ const FlowStepConditionValueSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
18
+ /** Condition used in `if` / `if-not` step fields. Resolves a `${{ }}` token and optionally compares it to a value. */
19
+ const FlowStepConditionSchema = z
20
+ .object({ value: z.string(), equals: FlowStepConditionValueSchema.optional() })
21
+ .strict();
22
+ /** A single step within a flow definition. */
23
+ const FlowStepSchema = z
24
+ .object({
25
+ /** The task to execute, e.g. "util/log" or "org/create/scratch". */
26
+ task: z.string(),
27
+ /** Parameters passed to the task. */
28
+ params: z.record(z.string(), ParamValueSchema).optional(),
29
+ /** Run step if condition is truthy (or equals a value). */
30
+ if: FlowStepConditionSchema.optional(),
31
+ /** Run step if condition is falsy (or equals a value). */
32
+ 'if-not': FlowStepConditionSchema.optional(),
33
+ /** Continue the flow if this step fails, storing failure state in step outputs. */
34
+ 'ignore-failure': z.boolean().optional(),
35
+ })
36
+ .refine((s) => !(s.if && s['if-not']), { message: 'A step cannot have both "if" and "if-not"' });
37
+ /** Defines a named flow: its accepted params and the ordered steps to execute. */
38
+ export const FlowDefinitionSchema = z
39
+ .object({
40
+ /** Human-readable description of what this flow does. */
41
+ description: z.string().optional(),
42
+ /** Params this flow accepts, passed as `--param key=value` CLI flags when invoking the flow. */
43
+ params: z.array(ParamDefinitionSchema).optional(),
44
+ /** Named steps to execute in definition order. The key is the step ID, used for output references. */
45
+ steps: z.record(z.string(), FlowStepSchema),
46
+ /** Steps that always run after `steps`, regardless of success or failure. */
47
+ finally: z.record(z.string(), FlowStepSchema).optional(),
48
+ })
49
+ .superRefine((flow, ctx) => {
50
+ const dup = Object.keys(flow.finally ?? {}).find((k) => k in flow.steps);
51
+ if (dup) {
52
+ ctx.addIssue({ code: 'custom', message: `Step ID "${dup}" appears in both "steps" and "finally"` });
53
+ }
54
+ });
55
+ /* c8 ignore stop */
56
+ //# sourceMappingURL=flow.definition.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.definition.schema.js","sourceRoot":"","sources":["../../src/core/flow.definition.schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,mEAAmE;AACnE,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAE9F,sHAAsH;AACtH,MAAM,uBAAuB,GAAG,CAAC;KAC9B,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,CAAC,QAAQ,EAAE,EAAE,CAAC;KAC9E,MAAM,EAAE,CAAC;AAEZ,8CAA8C;AAC9C,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,qCAAqC;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,QAAQ,EAAE;IACzD,2DAA2D;IAC3D,EAAE,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IACtC,0DAA0D;IAC1D,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC5C,mFAAmF;IACnF,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC,CAAC;AAEnG,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,yDAAyD;IACzD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,gGAAgG;IAChG,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IACjD,sGAAsG;IACtG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC;IAC3C,6EAA6E;IAC7E,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC;KACD,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACzB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IACzE,IAAI,GAAG,EAAE,CAAC;QACR,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,GAAG,yCAAyC,EAAE,CAAC,CAAC;IACtG,CAAC;AACH,CAAC,CAAC,CAAC;AAIL,oBAAoB"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Traverses a nested object by an array of keys.
3
+ * Returns `undefined` if any segment is missing or non-traversable.
4
+ */
5
+ export declare function deepGet(root: unknown, keys: string[]): unknown;
6
+ /**
7
+ * If `value` is exactly one `${{ path }}` token, resolves the path against
8
+ * `context` — yielding `null` when the path is absent so callers can tell
9
+ * "missing" apart from "empty". Returns `undefined` when `value` is not a single
10
+ * pure token, signalling the caller to treat it as a literal or interpolate
11
+ * embedded tokens itself.
12
+ */
13
+ export declare function resolvePureToken(value: string, context: Record<string, unknown>): unknown;
14
+ /**
15
+ * Interpolates `${{ some.path }}` tokens in a value by looking up paths in a
16
+ * unified context object. Non-string values are returned unchanged; plain
17
+ * objects are interpolated recursively. A pure token resolves to the looked-up
18
+ * value (or `null`); a token embedded in surrounding text is stringified, with
19
+ * misses replaced by an empty string.
20
+ */
21
+ export declare function interpolate(value: unknown, context: Record<string, unknown>): unknown;
@@ -0,0 +1,64 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ const PURE_TOKEN = /^\$\{\{\s*([\w.-]+)\s*\}\}$/;
15
+ /** Matches each `${{ path }}` token embedded within a larger string. */
16
+ const EMBEDDED_TOKEN = /\$\{\{\s*([\w.-]+)\s*\}\}/g;
17
+ /**
18
+ * Traverses a nested object by an array of keys.
19
+ * Returns `undefined` if any segment is missing or non-traversable.
20
+ */
21
+ export function deepGet(root, keys) {
22
+ let val = root;
23
+ for (const key of keys) {
24
+ if (val == null || typeof val !== 'object')
25
+ return undefined;
26
+ val = val[key];
27
+ }
28
+ return val;
29
+ }
30
+ /**
31
+ * If `value` is exactly one `${{ path }}` token, resolves the path against
32
+ * `context` — yielding `null` when the path is absent so callers can tell
33
+ * "missing" apart from "empty". Returns `undefined` when `value` is not a single
34
+ * pure token, signalling the caller to treat it as a literal or interpolate
35
+ * embedded tokens itself.
36
+ */
37
+ export function resolvePureToken(value, context) {
38
+ const match = value.match(PURE_TOKEN);
39
+ return match ? deepGet(context, match[1].split('.')) ?? null : undefined;
40
+ }
41
+ /**
42
+ * Interpolates `${{ some.path }}` tokens in a value by looking up paths in a
43
+ * unified context object. Non-string values are returned unchanged; plain
44
+ * objects are interpolated recursively. A pure token resolves to the looked-up
45
+ * value (or `null`); a token embedded in surrounding text is stringified, with
46
+ * misses replaced by an empty string.
47
+ */
48
+ export function interpolate(value, context) {
49
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
50
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, interpolate(v, context)]));
51
+ }
52
+ if (typeof value !== 'string')
53
+ return value;
54
+ const resolved = resolvePureToken(value, context);
55
+ if (resolved !== undefined)
56
+ return resolved;
57
+ let result = value;
58
+ for (const [match, path] of value.matchAll(EMBEDDED_TOKEN)) {
59
+ const raw = deepGet(context, path.split('.'));
60
+ result = result.replace(match, raw != null ? String(raw) : '');
61
+ }
62
+ return result;
63
+ }
64
+ //# sourceMappingURL=flow.interpolate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.interpolate.js","sourceRoot":"","sources":["../../src/core/flow.interpolate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACjD,wEAAwE;AACxE,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,IAAa,EAAE,IAAc;IACnD,IAAI,GAAG,GAAY,IAAI,CAAC;IACxB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC7D,GAAG,GAAI,GAA+B,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,OAAgC;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,OAAgC;IAC1E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAC/F,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAE5C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { FlowDefinition } from './flow.definition.schema.js';
2
+ export declare const builtinsDir: string;
3
+ /**
4
+ * Resolves flow definitions by name.
5
+ *
6
+ * On construction, scans both the built-in and consumer flow directories and
7
+ * Later sources shadow earlier ones: built-ins → .ship/flows/.
8
+ */
9
+ export declare class FlowRegistry {
10
+ private readonly shipDir;
11
+ private readonly flows;
12
+ /** Built-in flow name → absolute source path, for `flow eject`. */
13
+ private readonly builtinFiles;
14
+ /** @param shipDir - The ship directory for this project. Consumer flows are loaded from `<shipDir>/flows`. */
15
+ constructor(shipDir: string);
16
+ /** Lists all available flow names. */
17
+ list(): string[];
18
+ /**
19
+ * Returns the flow definition for the given name.
20
+ *
21
+ * @param flowName - The flow name, e.g. "ci" or "managed-package/release".
22
+ * @throws If the flow cannot be found in any source.
23
+ */
24
+ resolveFlow(flowName: string): FlowDefinition;
25
+ /**
26
+ * Absolute path to a built-in flow's source `.yml`, or null if `flowName`
27
+ * is not a built-in (unknown, or a project-only flow). Used by `flow eject`.
28
+ *
29
+ * @param flowName - The flow name, e.g. "ci" or "managed-package/release".
30
+ */
31
+ builtinSource(flowName: string): string | null;
32
+ }
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ import { resolve } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { parse } from 'yaml';
17
+ import { listDir, normalizePath, readText } from './file.js';
18
+ import { FlowDefinitionSchema } from './flow.definition.schema.js';
19
+ import { ExpectedError, formatZodError } from './error.js';
20
+ export const builtinsDir = resolve(fileURLToPath(import.meta.url), '..', 'flows');
21
+ function scanDir(dir) {
22
+ try {
23
+ return listDir(dir, { recursive: true })
24
+ .filter((f) => f.endsWith('.yml'))
25
+ .map((f) => f.replaceAll('\\', '/'));
26
+ }
27
+ catch (err) {
28
+ if (err.code !== 'ENOENT')
29
+ throw err;
30
+ return [];
31
+ }
32
+ }
33
+ function loadFromPath(flowPath) {
34
+ let raw;
35
+ try {
36
+ raw = readText(flowPath);
37
+ }
38
+ catch (err) {
39
+ throw new ExpectedError(`Failed to load flow at ${flowPath}: ${err.message}`);
40
+ }
41
+ const parsed = parse(raw);
42
+ const result = FlowDefinitionSchema.safeParse(parsed);
43
+ if (!result.success)
44
+ throw new ExpectedError(`Invalid flow definition at ${flowPath}:\n${formatZodError(result.error)}`);
45
+ return result.data;
46
+ }
47
+ /**
48
+ * Resolves flow definitions by name.
49
+ *
50
+ * On construction, scans both the built-in and consumer flow directories and
51
+ * Later sources shadow earlier ones: built-ins → .ship/flows/.
52
+ */
53
+ export class FlowRegistry {
54
+ shipDir;
55
+ flows;
56
+ /** Built-in flow name → absolute source path, for `flow eject`. */
57
+ builtinFiles;
58
+ /** @param shipDir - The ship directory for this project. Consumer flows are loaded from `<shipDir>/flows`. */
59
+ constructor(shipDir) {
60
+ this.shipDir = shipDir;
61
+ this.flows = new Map();
62
+ this.builtinFiles = new Map();
63
+ for (const file of scanDir(builtinsDir)) {
64
+ const name = normalizePath(file.replace(/\.yml$/, ''));
65
+ const path = resolve(builtinsDir, file);
66
+ this.builtinFiles.set(name, path);
67
+ this.flows.set(name, loadFromPath(path));
68
+ }
69
+ for (const file of scanDir(resolve(shipDir, 'flows')))
70
+ this.flows.set(normalizePath(file.replace(/\.yml$/, '')), loadFromPath(resolve(shipDir, 'flows', file)));
71
+ }
72
+ /** Lists all available flow names. */
73
+ list() {
74
+ return [...this.flows.keys()].sort();
75
+ }
76
+ /**
77
+ * Returns the flow definition for the given name.
78
+ *
79
+ * @param flowName - The flow name, e.g. "ci" or "managed-package/release".
80
+ * @throws If the flow cannot be found in any source.
81
+ */
82
+ resolveFlow(flowName) {
83
+ const name = normalizePath(flowName);
84
+ const flow = this.flows.get(name);
85
+ if (!flow)
86
+ throw new ExpectedError(`Unknown flow "${flowName}". Looked in: ${resolve(this.shipDir, 'flows', name)}`);
87
+ return flow;
88
+ }
89
+ /**
90
+ * Absolute path to a built-in flow's source `.yml`, or null if `flowName`
91
+ * is not a built-in (unknown, or a project-only flow). Used by `flow eject`.
92
+ *
93
+ * @param flowName - The flow name, e.g. "ci" or "managed-package/release".
94
+ */
95
+ builtinSource(flowName) {
96
+ return this.builtinFiles.get(normalizePath(flowName)) ?? null;
97
+ }
98
+ }
99
+ //# sourceMappingURL=flow.registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.registry.js","sourceRoot":"","sources":["../../src/core/flow.registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { FlowStep } from './flow.definition.schema.js';
2
+ import { FlowContext } from './flow.context.js';
3
+ type OutputStream = {
4
+ isTTY?: boolean;
5
+ write(chunk: string): boolean;
6
+ };
7
+ type Steps = ReadonlyArray<readonly [string, FlowStep]>;
8
+ /**
9
+ * Renders a flow run as plain sequential output: a plan banner up front, a
10
+ * heading before each step, the step's own (and any subcommand's) output
11
+ * flowing untouched, and a result summary at the end.
12
+ *
13
+ * All formatting lives in the `flow.view` module so a flow looks the same
14
+ * whether it runs here or is inspected via `ship flow info`.
15
+ */
16
+ export declare class FlowRenderer {
17
+ private readonly flowName;
18
+ private readonly mainSteps;
19
+ private readonly finallySteps;
20
+ private readonly write;
21
+ private readonly stepsById;
22
+ private readonly order;
23
+ private readonly completed;
24
+ private readonly failed;
25
+ private readonly skipped;
26
+ private readonly ignored;
27
+ private currentStep;
28
+ constructor(flowName: string, mainSteps: Steps, finallySteps: Steps, ctx: FlowContext, out?: OutputStream);
29
+ /** The step currently executing, or null between steps. */
30
+ get activeStep(): string | null;
31
+ private get outcome();
32
+ private static timestamp;
33
+ /** Prints the plan banner at the start of the run. */
34
+ start(): void;
35
+ /** Prints the heading for a step that is about to run. */
36
+ stepStart(stepId: string): void;
37
+ stepComplete(stepId: string): void;
38
+ stepFailed(stepId: string): void;
39
+ stepSkipped(stepId: string): void;
40
+ stepIgnored(stepId: string, err: Error): void;
41
+ /** Reports a flow that could not start (e.g. invalid flow params). */
42
+ failedBeforeStart(err: Error): void;
43
+ /** Reports a hard failure: prints the summary, then the error (and stack for unexpected errors). */
44
+ flowFailed(stepId: string, err: Error): void;
45
+ /** Prints the summary and the success banner. */
46
+ success(): void;
47
+ /** Handles a user interrupt (Ctrl+C): marks the active step failed and reports it. */
48
+ interrupt(): void;
49
+ private logLine;
50
+ }
51
+ export {};