@sixthsummit/ship-cli 0.0.0-stage → 1.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 (55) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +4 -0
  3. package/README.md +45 -2
  4. package/lib/bin.d.ts +3 -0
  5. package/lib/bin.d.ts.map +1 -0
  6. package/lib/bin.js +4 -0
  7. package/lib/bin.js.map +1 -0
  8. package/lib/contract.d.ts +27 -0
  9. package/lib/contract.d.ts.map +1 -0
  10. package/lib/contract.js +99 -0
  11. package/lib/contract.js.map +1 -0
  12. package/lib/create.d.ts +60 -0
  13. package/lib/create.d.ts.map +1 -0
  14. package/lib/create.js +212 -0
  15. package/lib/create.js.map +1 -0
  16. package/lib/forms.d.ts +10 -0
  17. package/lib/forms.d.ts.map +1 -0
  18. package/lib/forms.js +96 -0
  19. package/lib/forms.js.map +1 -0
  20. package/lib/graph.d.ts +195 -0
  21. package/lib/graph.d.ts.map +1 -0
  22. package/lib/graph.js +596 -0
  23. package/lib/graph.js.map +1 -0
  24. package/lib/index.d.ts +7 -0
  25. package/lib/index.d.ts.map +1 -0
  26. package/lib/index.js +7 -0
  27. package/lib/index.js.map +1 -0
  28. package/lib/migration.d.ts +53 -0
  29. package/lib/migration.d.ts.map +1 -0
  30. package/lib/migration.js +303 -0
  31. package/lib/migration.js.map +1 -0
  32. package/lib/release-manifest.json +23 -0
  33. package/lib/ship-api.d.ts +38 -0
  34. package/lib/ship-api.d.ts.map +1 -0
  35. package/lib/ship-api.js +134 -0
  36. package/lib/ship-api.js.map +1 -0
  37. package/package.json +70 -3
  38. package/templates/operation/.github/pull_request_template.md +41 -0
  39. package/templates/operation/AGENTS.md +46 -0
  40. package/templates/operation/README.md +37 -0
  41. package/templates/operation/_gitignore +5 -0
  42. package/templates/operation/_gitmessage +12 -0
  43. package/templates/operation/biome.json +39 -0
  44. package/templates/operation/package.template.json +21 -0
  45. package/templates/operation/ship.config.ts +1 -0
  46. package/templates/operation/src/application.integration.test.ts +15 -0
  47. package/templates/operation/src/application.test.ts +16 -0
  48. package/templates/operation/src/application.ts +7 -0
  49. package/templates/operation/src/modules/system/health.operation.ts +34 -0
  50. package/templates/operation/src/modules/system/module.ts +10 -0
  51. package/templates/operation/src/server.ts +13 -0
  52. package/templates/operation/tsconfig.build.json +11 -0
  53. package/templates/operation/tsconfig.json +17 -0
  54. package/templates/operation/vitest.config.ts +20 -0
  55. package/templates/operation/vitest.integration.config.ts +8 -0
package/lib/create.js ADDED
@@ -0,0 +1,212 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { cp, mkdir, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
3
+ import { basename, join, resolve } from "node:path";
4
+ const PROJECT_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
5
+ const TEXT_FILE_PATTERN = /(?:^|\/)(?:[^/]+\.(?:json|md|ts)|_gitignore|_gitmessage)$/u;
6
+ export class ScaffoldError extends Error {
7
+ /** @param {string} message */
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ScaffoldError";
11
+ }
12
+ }
13
+ /**
14
+ * @typedef {{
15
+ * schemaVersion: 1,
16
+ * packageManager: string,
17
+ * packages: Record<string, string>,
18
+ * dependencies: Record<string, string>,
19
+ * devDependencies: Record<string, string>
20
+ * }} ScaffoldReleaseManifest
21
+ */
22
+ /**
23
+ * @param {string} manifestPath
24
+ * @returns {Promise<ScaffoldReleaseManifest>}
25
+ */
26
+ export async function loadScaffoldReleaseManifest(manifestPath) {
27
+ let value;
28
+ try {
29
+ value = JSON.parse(await readFile(manifestPath, "utf8"));
30
+ }
31
+ catch (error) {
32
+ throw new ScaffoldError(`could not read the scaffold release manifest at ${manifestPath}: ${errorMessage(error)}`);
33
+ }
34
+ if (value?.schemaVersion !== 1 ||
35
+ typeof value.packageManager !== "string" ||
36
+ !isStringRecord(value.packages) ||
37
+ !isStringRecord(value.dependencies) ||
38
+ !isStringRecord(value.devDependencies)) {
39
+ throw new ScaffoldError(`invalid scaffold release manifest at ${manifestPath}`);
40
+ }
41
+ return value;
42
+ }
43
+ /**
44
+ * Create the smallest operation-native Ship application.
45
+ *
46
+ * @param {{
47
+ * projectName: string,
48
+ * cwd?: string,
49
+ * currentDirectory?: boolean,
50
+ * skipInstall?: boolean,
51
+ * templateDirectory: string,
52
+ * releaseManifest: ScaffoldReleaseManifest,
53
+ * install?: (targetDirectory: string) => void,
54
+ * spawn?: (command: string, args: string[], options: object) => {
55
+ * error?: Error,
56
+ * status: number | null
57
+ * }
58
+ * }} options
59
+ */
60
+ export async function createOperationProject(options) {
61
+ const cwd = resolve(options.cwd ?? process.cwd());
62
+ const currentDirectory = options.currentDirectory === true;
63
+ if (!currentDirectory && options.projectName === ".") {
64
+ throw new ScaffoldError("project name `.` requires --current-dir");
65
+ }
66
+ const packageName = currentDirectory && options.projectName === "." ? basename(cwd) : options.projectName;
67
+ validateProjectName(packageName);
68
+ const targetDirectory = currentDirectory ? cwd : resolve(cwd, options.projectName);
69
+ const createdTarget = !currentDirectory;
70
+ await assertWritableTarget(targetDirectory, currentDirectory);
71
+ try {
72
+ if (createdTarget)
73
+ await mkdir(targetDirectory);
74
+ await cp(options.templateDirectory, targetDirectory, { recursive: true, errorOnExist: true });
75
+ await renameTemplateDotfiles(targetDirectory);
76
+ await renderTemplate(targetDirectory, {
77
+ PROJECT_NAME: displayName(packageName),
78
+ PACKAGE_NAME: packageName,
79
+ PACKAGE_MANAGER: options.releaseManifest.packageManager,
80
+ });
81
+ await writeGeneratedPackageJson(targetDirectory, packageName, options.releaseManifest);
82
+ if (!options.skipInstall) {
83
+ if (options.install)
84
+ options.install(targetDirectory);
85
+ else
86
+ installDependencies(targetDirectory, options.spawn ?? spawnSync);
87
+ }
88
+ }
89
+ catch (error) {
90
+ if (createdTarget)
91
+ await rm(targetDirectory, { force: true, recursive: true });
92
+ if (error instanceof ScaffoldError)
93
+ throw error;
94
+ throw new ScaffoldError(`could not create ${packageName}: ${errorMessage(error)}`);
95
+ }
96
+ return {
97
+ packageName,
98
+ targetDirectory,
99
+ installed: !options.skipInstall,
100
+ };
101
+ }
102
+ /** @param {string} projectName */
103
+ function validateProjectName(projectName) {
104
+ if (!PROJECT_NAME_PATTERN.test(projectName)) {
105
+ throw new ScaffoldError("project name must be lower-case kebab-case using letters, numbers, and single hyphens");
106
+ }
107
+ }
108
+ /** @param {string} targetDirectory @param {boolean} currentDirectory */
109
+ async function assertWritableTarget(targetDirectory, currentDirectory) {
110
+ if (currentDirectory) {
111
+ const entries = await readdir(targetDirectory);
112
+ if (entries.length > 0) {
113
+ throw new ScaffoldError("--current-dir requires an empty directory");
114
+ }
115
+ return;
116
+ }
117
+ try {
118
+ await stat(targetDirectory);
119
+ }
120
+ catch (error) {
121
+ if (error && typeof error === "object" && Reflect.get(error, "code") === "ENOENT")
122
+ return;
123
+ throw error;
124
+ }
125
+ throw new ScaffoldError(`target already exists: ${targetDirectory}`);
126
+ }
127
+ /** @param {string} targetDirectory */
128
+ async function renameTemplateDotfiles(targetDirectory) {
129
+ await rename(join(targetDirectory, "_gitignore"), join(targetDirectory, ".gitignore"));
130
+ await rename(join(targetDirectory, "_gitmessage"), join(targetDirectory, ".gitmessage"));
131
+ }
132
+ /** @param {string} targetDirectory @param {Record<string, string>} replacements */
133
+ async function renderTemplate(targetDirectory, replacements) {
134
+ for (const path of await listFiles(targetDirectory)) {
135
+ const relativePath = path.slice(targetDirectory.length).replaceAll("\\", "/");
136
+ if (!TEXT_FILE_PATTERN.test(relativePath))
137
+ continue;
138
+ let content = await readFile(path, "utf8");
139
+ for (const [key, value] of Object.entries(replacements)) {
140
+ content = content.replaceAll(`{{${key}}}`, value);
141
+ }
142
+ await writeFile(path, content);
143
+ }
144
+ }
145
+ /** @param {string} directory @returns {Promise<string[]>} */
146
+ async function listFiles(directory) {
147
+ const paths = [];
148
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
149
+ const path = join(directory, entry.name);
150
+ if (entry.isDirectory())
151
+ paths.push(...(await listFiles(path)));
152
+ else if (entry.isFile())
153
+ paths.push(path);
154
+ }
155
+ return paths;
156
+ }
157
+ /**
158
+ * @param {string} targetDirectory
159
+ * @param {string} packageName
160
+ * @param {ScaffoldReleaseManifest} manifest
161
+ */
162
+ async function writeGeneratedPackageJson(targetDirectory, packageName, manifest) {
163
+ const sourcePath = join(targetDirectory, "package.template.json");
164
+ const packageJson = JSON.parse(await readFile(sourcePath, "utf8"));
165
+ packageJson.name = packageName;
166
+ packageJson.packageManager = manifest.packageManager;
167
+ packageJson.dependencies = {
168
+ ...manifest.packages,
169
+ ...manifest.dependencies,
170
+ };
171
+ packageJson.devDependencies = manifest.devDependencies;
172
+ await writeFile(join(targetDirectory, "package.json"), `${JSON.stringify(packageJson, null, 2)}\n`);
173
+ await rm(sourcePath);
174
+ }
175
+ /**
176
+ * @param {string} targetDirectory
177
+ * @param {(command: string, args: string[], options: object) => {
178
+ * error?: Error,
179
+ * status: number | null
180
+ * }} spawn
181
+ */
182
+ function installDependencies(targetDirectory, spawn) {
183
+ const result = spawn("pnpm", ["install"], {
184
+ cwd: targetDirectory,
185
+ encoding: "utf8",
186
+ stdio: "inherit",
187
+ });
188
+ if (result.error)
189
+ throw result.error;
190
+ if (result.status !== 0) {
191
+ throw new ScaffoldError(`pnpm install exited with ${result.status ?? "no status"}`);
192
+ }
193
+ }
194
+ /** @param {string} value */
195
+ function displayName(value) {
196
+ return value
197
+ .split("-")
198
+ .map((part) => `${part[0].toUpperCase()}${part.slice(1)}`)
199
+ .join(" ");
200
+ }
201
+ /** @param {unknown} value */
202
+ function isStringRecord(value) {
203
+ return (typeof value === "object" &&
204
+ value !== null &&
205
+ !Array.isArray(value) &&
206
+ Object.values(value).every((item) => typeof item === "string"));
207
+ }
208
+ /** @param {unknown} error */
209
+ function errorMessage(error) {
210
+ return error instanceof Error ? error.message : String(error);
211
+ }
212
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.js"],"names":[],"mappings":"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"}
package/lib/forms.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Emit primitive identity-codec bindings from the projected body, never server validators.
3
+ * @param {import("@sixthsummit/ship-contract").ClientContract} contract
4
+ * @param {string} operationId
5
+ * @param {Readonly<Record<string, string | number | boolean | null>>} initialValues
6
+ * @param {string} [exportName]
7
+ * @returns {string}
8
+ */
9
+ export function renderOperationFormBinding(contract: import("@sixthsummit/ship-contract").ClientContract, operationId: string, initialValues: Readonly<Record<string, string | number | boolean | null>>, exportName?: string): string;
10
+ //# sourceMappingURL=forms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../src/forms.js"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qDANW,OAAO,4BAA4B,EAAE,cAAc,eACnD,MAAM,iBACN,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,eAC1D,MAAM,GACJ,MAAM,CAkGlB"}
package/lib/forms.js ADDED
@@ -0,0 +1,96 @@
1
+ import { compileFunction } from "node:vm";
2
+ /**
3
+ * Emit primitive identity-codec bindings from the projected body, never server validators.
4
+ * @param {import("@sixthsummit/ship-contract").ClientContract} contract
5
+ * @param {string} operationId
6
+ * @param {Readonly<Record<string, string | number | boolean | null>>} initialValues
7
+ * @param {string} [exportName]
8
+ * @returns {string}
9
+ */
10
+ export function renderOperationFormBinding(contract, operationId, initialValues, exportName = "operationFormBinding") {
11
+ if (!/^[A-Za-z_$][\w$]*$/u.test(exportName))
12
+ throw new TypeError("Invalid form export name");
13
+ try {
14
+ if (exportName === "await")
15
+ throw new SyntaxError("Module keyword");
16
+ compileFunction(`"use strict"; const ${exportName} = null;`);
17
+ }
18
+ catch {
19
+ throw new TypeError("Invalid form export name");
20
+ }
21
+ const operation = contract.operations.find((entry) => entry.id === operationId);
22
+ const schema = operation?.input.body?.jsonSchema;
23
+ if (!schema || schema.type !== "object" || !schema.properties)
24
+ throw new TypeError("Form projection requires an object body");
25
+ const composition = [
26
+ "allOf",
27
+ "anyOf",
28
+ "oneOf",
29
+ "not",
30
+ "if",
31
+ "then",
32
+ "else",
33
+ "$ref",
34
+ "$dynamicRef",
35
+ "dependentSchemas",
36
+ "dependentRequired",
37
+ ];
38
+ if (composition.some((key) => Object.hasOwn(schema, key)))
39
+ throw new TypeError("Unsupported composed form body");
40
+ const fields = Object.entries(schema.properties).map(([name, property]) => {
41
+ if (property.anyOf && Object.hasOwn(property, "type"))
42
+ throw new TypeError(`Unsupported intersected form field: ${name}`);
43
+ if (composition.some((key) => key !== "anyOf" && Object.hasOwn(property, key)))
44
+ throw new TypeError(`Unsupported form field: ${name}`);
45
+ const nullBranch = property.anyOf?.find((entry) => entry.type === "null");
46
+ if (nullBranch &&
47
+ Object.keys(nullBranch).some((key) => !["type", "title", "description"].includes(key)))
48
+ throw new TypeError(`Unsupported null form branch: ${name}`);
49
+ if (["__proto__", "constructor", "prototype"].includes(name))
50
+ throw new TypeError(`Unsupported form field name: ${name}`);
51
+ if (property.enum ||
52
+ property.const !== undefined ||
53
+ property.allOf ||
54
+ property.oneOf ||
55
+ (property.anyOf &&
56
+ (property.anyOf.length !== 2 || !property.anyOf.some((entry) => entry.type === "null"))) ||
57
+ (Array.isArray(property.type) &&
58
+ (property.type.length !== 2 || !property.type.includes("null"))))
59
+ throw new TypeError(`Unsupported form field: ${name}`);
60
+ const nullable = property.anyOf?.find((entry) => entry.type === "null") ||
61
+ (Array.isArray(property.type) && property.type.includes("null"));
62
+ const valueSchema = property.anyOf
63
+ ? property.anyOf.find((entry) => entry.type !== "null")
64
+ : Array.isArray(property.type)
65
+ ? { ...property, type: property.type.find((type) => type !== "null") }
66
+ : property;
67
+ if (!valueSchema || !["string", "number", "integer", "boolean"].includes(valueSchema.type))
68
+ throw new TypeError(`Unsupported form field: ${name}`);
69
+ if (valueSchema.enum || valueSchema.const !== undefined)
70
+ throw new TypeError(`Unsupported form field: ${name}`);
71
+ if (composition.some((key) => Object.hasOwn(valueSchema, key)))
72
+ throw new TypeError(`Unsupported form field: ${name}`);
73
+ if (!Object.hasOwn(initialValues, name))
74
+ throw new TypeError(`Explicit initial value required: ${name}`);
75
+ const initial = initialValues[name];
76
+ const type = valueSchema.type === "integer" ? "number" : valueSchema.type;
77
+ if (typeof initial === "number" &&
78
+ (!Number.isFinite(initial) || (valueSchema.type === "integer" && !Number.isInteger(initial))))
79
+ throw new TypeError(`Invalid numeric initial value: ${name}`);
80
+ if (!(initial === null && nullable) && typeof initial !== type)
81
+ throw new TypeError(`Invalid initial value: ${name}`);
82
+ const tsType = `${type}${nullable ? " | null" : ""}`;
83
+ const optional = !(schema.required ?? []).includes(name);
84
+ const state = optional
85
+ ? { kind: "omitted", controlValue: initial }
86
+ : { kind: "value", value: initial };
87
+ const checks = [];
88
+ if (type === "string" && valueSchema.minLength !== undefined)
89
+ checks.push(`if (value !== null && value.length < ${Number(valueSchema.minLength)}) return [{path:[${JSON.stringify(name)}],code:"min_length",message:"Value is too short"}];`);
90
+ return `${JSON.stringify(name)}: { optional: ${optional}, initial: ${JSON.stringify(state)}, codec: { encode: (value: ${tsType}): ${tsType} => value, decode: (value: ${tsType}): ${tsType} => value }, validate: (value: ${tsType}) => { ${checks.join(" ")} return []; } }`;
91
+ });
92
+ if (Object.keys(initialValues).some((name) => !(name in schema.properties)))
93
+ throw new TypeError("Unknown initial field");
94
+ return `export const ${exportName} = { operation: ${JSON.stringify(operationId)}, fields: {${fields.join(",\n")}} } as const;\n`;
95
+ }
96
+ //# sourceMappingURL=forms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.js","sourceRoot":"","sources":["../src/forms.js"],"names":[],"mappings":"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"}
package/lib/graph.d.ts ADDED
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @param {GraphCliOptions} [options]
3
+ * @returns {Promise<LoadedApplication>}
4
+ */
5
+ export function loadApplication(options?: GraphCliOptions): Promise<LoadedApplication>;
6
+ /**
7
+ * @param {GraphCliOptions} [options]
8
+ * @returns {Promise<Readonly<{command: "check", ok: true, graph: ApplicationGraph, emitted?: string}>>}
9
+ */
10
+ export function checkApplication(options?: GraphCliOptions): Promise<Readonly<{
11
+ command: "check";
12
+ ok: true;
13
+ graph: ApplicationGraph;
14
+ emitted?: string;
15
+ }>>;
16
+ /**
17
+ * @param {GraphKind} kind
18
+ * @param {string | undefined} id
19
+ * @param {GraphCliOptions} [options]
20
+ * @returns {Promise<Readonly<{command: "inspect", ok: true, kind: GraphKind, id: string, node: GraphNode}>>}
21
+ */
22
+ export function inspectApplication(kind: GraphKind, id: string | undefined, options?: GraphCliOptions): Promise<Readonly<{
23
+ command: "inspect";
24
+ ok: true;
25
+ kind: GraphKind;
26
+ id: string;
27
+ node: GraphNode;
28
+ }>>;
29
+ /**
30
+ * @param {GraphKind} kind
31
+ * @param {string | undefined} id
32
+ * @param {GraphCliOptions} [options]
33
+ * @returns {Promise<Readonly<{command: "affected", ok: true, kind: GraphKind, id: string, affected: AffectedGraphSurface}>>}
34
+ */
35
+ export function affectedApplication(kind: GraphKind, id: string | undefined, options?: GraphCliOptions): Promise<Readonly<{
36
+ command: "affected";
37
+ ok: true;
38
+ kind: GraphKind;
39
+ id: string;
40
+ affected: AffectedGraphSurface;
41
+ }>>;
42
+ /**
43
+ * @param {() => Promise<unknown>} command
44
+ * @param {{format?: GraphOutputFormat}} [options]
45
+ * @param {GraphIo} [io]
46
+ * @returns {Promise<GraphCliExitCode>}
47
+ */
48
+ export function runGraphCommand(command: () => Promise<unknown>, options?: {
49
+ format?: GraphOutputFormat;
50
+ }, io?: GraphIo): Promise<GraphCliExitCode>;
51
+ /** @typedef {import("@sixthsummit/ship-core").AnyModule} AnyModule */
52
+ /** @typedef {import("@sixthsummit/ship-core").ApplicationGraph} ApplicationGraph */
53
+ /** @typedef {import("@sixthsummit/ship-core").CompiledApplication<string, readonly AnyModule[]>} LoadedApplication */
54
+ /** @typedef {import("@sixthsummit/ship-core").ModuleGraphNode | import("@sixthsummit/ship-core").OperationGraphNode | import("@sixthsummit/ship-core").ProviderGraphNode | import("@sixthsummit/ship-core").ChannelGraphNode | import("@sixthsummit/ship-core").JobGraphNode | ApplicationGraph} GraphNode */
55
+ /** @typedef {"human" | "json"} GraphOutputFormat */
56
+ /** @typedef {"app" | "module" | "operation" | "provider" | "channel" | "job"} GraphKind */
57
+ /** @typedef {0 | 1 | 2} GraphCliExitCode */
58
+ /**
59
+ * @typedef {object} GraphCliDiagnostic
60
+ * @property {string} code
61
+ * @property {"error" | "warning"} severity
62
+ * @property {string} message
63
+ * @property {string} hint
64
+ * @property {string=} appId
65
+ * @property {string=} moduleId
66
+ * @property {string=} operationId
67
+ * @property {string=} providerId
68
+ * @property {string=} path
69
+ */
70
+ /**
71
+ * @typedef {object} GraphCliOptions
72
+ * @property {string=} cwd
73
+ * @property {string=} appPath
74
+ * @property {string=} emit
75
+ * @property {GraphOutputFormat=} format
76
+ */
77
+ /**
78
+ * @typedef {object} AffectedGraphSurface
79
+ * @property {readonly string[]} modules
80
+ * @property {readonly string[]} operations
81
+ * @property {readonly string[]} providers
82
+ */
83
+ /**
84
+ * @typedef {object} GraphIo
85
+ * @property {(value: string) => unknown} stdout
86
+ * @property {(value: string) => unknown} stderr
87
+ */
88
+ export const GRAPH_CLI_EXIT: Readonly<{
89
+ success: 0;
90
+ applicationInvalid: 1;
91
+ usageOrLoadError: 2;
92
+ }>;
93
+ export class GraphCliError extends Error {
94
+ /**
95
+ * @param {readonly GraphCliDiagnostic[]} diagnostics
96
+ * @param {GraphCliExitCode} [exitCode]
97
+ * @param {ErrorOptions} [options]
98
+ */
99
+ constructor(diagnostics: readonly GraphCliDiagnostic[], exitCode?: GraphCliExitCode, options?: ErrorOptions);
100
+ diagnostics: readonly Readonly<{
101
+ code: string;
102
+ severity: "error" | "warning";
103
+ message: string;
104
+ hint: string;
105
+ appId?: string | undefined;
106
+ moduleId?: string | undefined;
107
+ operationId?: string | undefined;
108
+ providerId?: string | undefined;
109
+ path?: string | undefined;
110
+ }>[];
111
+ exitCode: GraphCliExitCode;
112
+ }
113
+ export const __test: Readonly<{
114
+ affectedByModule: typeof affectedByModule;
115
+ affectedByOperation: typeof affectedByOperation;
116
+ affectedByProvider: typeof affectedByProvider;
117
+ normalizeGraphError: typeof normalizeGraphError;
118
+ projectPermissions: typeof projectPermissions;
119
+ renderFailure: typeof renderFailure;
120
+ renderSuccess: typeof renderSuccess;
121
+ }>;
122
+ export type AnyModule = import("@sixthsummit/ship-core").AnyModule;
123
+ export type ApplicationGraph = import("@sixthsummit/ship-core").ApplicationGraph;
124
+ export type LoadedApplication = import("@sixthsummit/ship-core").CompiledApplication<string, readonly AnyModule[]>;
125
+ export type GraphNode = import("@sixthsummit/ship-core").ModuleGraphNode | import("@sixthsummit/ship-core").OperationGraphNode | import("@sixthsummit/ship-core").ProviderGraphNode | import("@sixthsummit/ship-core").ChannelGraphNode | import("@sixthsummit/ship-core").JobGraphNode | ApplicationGraph;
126
+ export type GraphOutputFormat = "human" | "json";
127
+ export type GraphKind = "app" | "module" | "operation" | "provider" | "channel" | "job";
128
+ export type GraphCliExitCode = 0 | 1 | 2;
129
+ export type GraphCliDiagnostic = {
130
+ code: string;
131
+ severity: "error" | "warning";
132
+ message: string;
133
+ hint: string;
134
+ appId?: string | undefined;
135
+ moduleId?: string | undefined;
136
+ operationId?: string | undefined;
137
+ providerId?: string | undefined;
138
+ path?: string | undefined;
139
+ };
140
+ export type GraphCliOptions = {
141
+ cwd?: string | undefined;
142
+ appPath?: string | undefined;
143
+ emit?: string | undefined;
144
+ format?: GraphOutputFormat | undefined;
145
+ };
146
+ export type AffectedGraphSurface = {
147
+ modules: readonly string[];
148
+ operations: readonly string[];
149
+ providers: readonly string[];
150
+ };
151
+ export type GraphIo = {
152
+ stdout: (value: string) => unknown;
153
+ stderr: (value: string) => unknown;
154
+ };
155
+ declare function affectedByModule(graph: any, id: any): Readonly<{
156
+ modules: readonly any[];
157
+ operations: readonly any[];
158
+ providers: readonly any[];
159
+ }>;
160
+ /**
161
+ * An operation affects itself, and a write affects every cached read it
162
+ * invalidates: the declared tags are real graph edges, so a change to an
163
+ * invalidating write reaches the reads whose entries it purges.
164
+ */
165
+ declare function affectedByOperation(graph: any, operation: any): Readonly<{
166
+ modules: readonly any[];
167
+ operations: readonly any[];
168
+ providers: readonly any[];
169
+ }>;
170
+ declare function affectedByProvider(graph: any, id: any): Readonly<{
171
+ modules: readonly any[];
172
+ operations: readonly any[];
173
+ providers: readonly any[];
174
+ }>;
175
+ declare function normalizeGraphError(cause: any): GraphCliError;
176
+ /**
177
+ * Every permission slug an app or module's operations (and HTTP job triggers)
178
+ * demand, with the operations that demand it. A slug under `ship.` is
179
+ * introduced by a framework module (`ship.outbox:manage`, `ship.jobs:manage`,
180
+ * `ship.webhooks:replay`) and must be granted by the consumer's own
181
+ * authorization model before those operations can be reached.
182
+ *
183
+ * @param {ApplicationGraph} graph
184
+ * @param {string | undefined} moduleId
185
+ * @returns {readonly Readonly<{permission: string, framework: boolean, operations: readonly string[]}>[]}
186
+ */
187
+ declare function projectPermissions(graph: ApplicationGraph, moduleId: string | undefined): readonly Readonly<{
188
+ permission: string;
189
+ framework: boolean;
190
+ operations: readonly string[];
191
+ }>[];
192
+ declare function renderFailure(error: any, format: any): any;
193
+ declare function renderSuccess(result: any, format: any): string;
194
+ export {};
195
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.js"],"names":[],"mappings":"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"}