@saws/cli 2.0.0-beta.0 → 2.0.0-beta.11

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 (74) hide show
  1. package/README.md +189 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/bin/saws.d.ts +0 -1
  4. package/dist/bin/saws.js +32 -40
  5. package/dist/commands/app/deploy.d.ts +4 -0
  6. package/dist/commands/app/deploy.js +20 -0
  7. package/dist/commands/app/index.d.ts +2 -0
  8. package/dist/commands/app/index.js +16 -0
  9. package/dist/commands/app/install.d.ts +5 -0
  10. package/dist/commands/app/install.js +41 -0
  11. package/dist/commands/app/paths.d.ts +1 -0
  12. package/dist/commands/app/paths.js +8 -0
  13. package/dist/commands/app/process.d.ts +2 -0
  14. package/dist/commands/app/process.js +28 -0
  15. package/dist/commands/deploy/command.d.ts +2 -7
  16. package/dist/commands/deploy/command.js +13 -19
  17. package/dist/commands/deploy/index.d.ts +0 -1
  18. package/dist/commands/deploy/index.js +1 -4
  19. package/dist/commands/dev/command.d.ts +1 -7
  20. package/dist/commands/dev/command.js +46 -48
  21. package/dist/commands/dev/index.d.ts +0 -1
  22. package/dist/commands/dev/index.js +1 -6
  23. package/dist/commands/dev/tui/dev-tui.d.ts +18 -3
  24. package/dist/commands/dev/tui/dev-tui.js +263 -29
  25. package/dist/commands/host/command.d.ts +3 -2
  26. package/dist/commands/host/command.js +112 -7
  27. package/dist/commands/host/create.d.ts +9 -0
  28. package/dist/commands/host/create.js +30 -0
  29. package/dist/commands/host/deployment-key.d.ts +2 -0
  30. package/dist/commands/host/deployment-key.js +40 -0
  31. package/dist/commands/host/import-key.d.ts +5 -0
  32. package/dist/commands/host/import-key.js +40 -0
  33. package/dist/commands/host/index.d.ts +0 -1
  34. package/dist/commands/host/index.js +25 -3
  35. package/dist/commands/init/command.d.ts +1 -7
  36. package/dist/commands/init/command.js +24 -15
  37. package/dist/commands/init/index.d.ts +0 -1
  38. package/dist/commands/init/index.js +1 -5
  39. package/dist/commands/init/templates/gitignore.template.d.ts +1 -0
  40. package/dist/commands/init/templates/gitignore.template.js +4 -0
  41. package/dist/commands/init/templates/saws-ts.template.d.ts +3 -0
  42. package/dist/commands/init/templates/saws-ts.template.js +7 -0
  43. package/dist/commands/init/templates/tsconfig-json.template.d.ts +1 -0
  44. package/dist/commands/init/templates/tsconfig-json.template.js +4 -0
  45. package/dist/commands/logs/command.d.ts +5 -0
  46. package/dist/commands/logs/command.js +19 -0
  47. package/dist/commands/logs/index.d.ts +2 -0
  48. package/dist/commands/logs/index.js +7 -0
  49. package/dist/commands/secrets/command.d.ts +2 -2
  50. package/dist/commands/secrets/command.js +21 -9
  51. package/dist/commands/secrets/index.d.ts +0 -1
  52. package/dist/commands/secrets/index.js +7 -5
  53. package/dist/hosts.d.ts +1 -3
  54. package/dist/hosts.js +11 -10
  55. package/package.json +10 -20
  56. package/dist/bin/saws.d.ts.map +0 -1
  57. package/dist/commands/deploy/command.d.ts.map +0 -1
  58. package/dist/commands/deploy/index.d.ts.map +0 -1
  59. package/dist/commands/dev/command.d.ts.map +0 -1
  60. package/dist/commands/dev/index.d.ts.map +0 -1
  61. package/dist/commands/dev/tui/dev-tui.d.ts.map +0 -1
  62. package/dist/commands/host/command.d.ts.map +0 -1
  63. package/dist/commands/host/command.test.d.ts +0 -2
  64. package/dist/commands/host/command.test.d.ts.map +0 -1
  65. package/dist/commands/host/command.test.js +0 -13
  66. package/dist/commands/host/index.d.ts.map +0 -1
  67. package/dist/commands/init/command.d.ts.map +0 -1
  68. package/dist/commands/init/command.test.d.ts +0 -2
  69. package/dist/commands/init/command.test.d.ts.map +0 -1
  70. package/dist/commands/init/command.test.js +0 -40
  71. package/dist/commands/init/index.d.ts.map +0 -1
  72. package/dist/commands/secrets/command.d.ts.map +0 -1
  73. package/dist/commands/secrets/index.d.ts.map +0 -1
  74. package/dist/hosts.d.ts.map +0 -1
@@ -1,10 +1,32 @@
1
1
  import { Command } from "commander";
2
2
  import { configureHostCommand } from "./command.js";
3
+ import { createHostCommand } from "./create.js";
4
+ import { importHostKeyCommand } from "./import-key.js";
3
5
  export const createCommand = () => new Command("host")
4
6
  .description("configure deployment hosts")
7
+ .addCommand(new Command("create")
8
+ .description("create a global deployment host")
9
+ .argument("<name>", "global host name")
10
+ .requiredOption("--address <address>", "host name or IP address")
11
+ .requiredOption("--user <deployment-user>", "persistent deployment account")
12
+ .option("--ssh-port <port>", "SSH port")
13
+ .option("--platform <platform>", 'Docker platform such as "linux/amd64"')
14
+ .option("--exposure <mode>", 'network exposure policy: "tunnel" or "public"')
15
+ .option("--allowed-tcp-port <port...>", "public TCP ports allowed by the host firewall")
16
+ .action(createHostCommand))
17
+ .addCommand(new Command("key")
18
+ .description("manage global host deployment keys")
19
+ .addCommand(new Command("import")
20
+ .description("import an existing private key into encrypted global storage")
21
+ .argument("<name>", "global host name")
22
+ .requiredOption("--file <path>", "path to an SSH private key")
23
+ .option("--force", "replace an existing deployment key")
24
+ .action(importHostKeyCommand)))
5
25
  .addCommand(new Command("configure")
6
- .description("install Docker and apply the configured security policy")
26
+ .description("bootstrap a deployment user and apply host security policy")
7
27
  .argument("[name]", "host name; optional when exactly one host exists")
8
- .option("--config <string>", "path to service definition")
9
- .option("--dry-run", "print the remote configuration command")
28
+ .requiredOption("--user <bootstrap-user>", "existing SSH account used for initial configuration")
29
+ .option("--config <path>", "path to saws.ts")
30
+ .option("--global", "configure a host from the global host registry")
31
+ .option("--dry-run", "describe configuration without making changes")
10
32
  .action(configureHostCommand));
@@ -1,7 +1 @@
1
- export interface InitCommandOptions {
2
- rootDir?: string;
3
- config?: string;
4
- dryRun?: boolean;
5
- }
6
- export declare function initCommand(serviceName: string, path: string | undefined, options: InitCommandOptions): Promise<void>;
7
- //# sourceMappingURL=command.d.ts.map
1
+ export declare const initCommand: (serviceName?: string, configPath?: string) => Promise<void>;
@@ -1,15 +1,24 @@
1
- import { findServiceDefinition, getSawsConfig, InitContext, } from "@saws/core";
2
- export async function initCommand(serviceName, path, options) {
3
- const rootDir = options.rootDir ?? process.cwd();
4
- const rootService = await getSawsConfig(options.config ?? path);
5
- const service = findServiceDefinition(rootService, serviceName);
6
- await service.init(new InitContext({
7
- stage: "local",
8
- rootDir,
9
- dryRun: options.dryRun ?? false,
10
- env: process.env,
11
- logSink: ({ stream, chunk }) => {
12
- (stream === "stderr" ? process.stderr : process.stdout).write(chunk);
13
- },
14
- }));
15
- }
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import { findServiceDefinition, getSawsConfig } from "@saws/core";
4
+ import { installDependencies } from "@saws/core/utils/dependency-management";
5
+ import { createFileIfNotExists } from "@saws/core/utils/create-file-if-not-exists";
6
+ import { sawsTsTemplate } from "./templates/saws-ts.template.js";
7
+ import { tsconfigJsonTemplate } from "./templates/tsconfig-json.template.js";
8
+ import { gitignoreTemplate } from "./templates/gitignore.template.js";
9
+ export const initCommand = async (serviceName, configPath) => {
10
+ if (serviceName != null) {
11
+ const serviceDefinition = await getSawsConfig(configPath);
12
+ await findServiceDefinition(serviceDefinition, serviceName).init();
13
+ return;
14
+ }
15
+ const name = path.parse(path.resolve(".")).name;
16
+ // not used for now
17
+ await installDependencies([]);
18
+ await installDependencies(["@saws/core", "typescript", "@tsconfig/node26"], {
19
+ development: true,
20
+ });
21
+ await fs.writeFile("./tsconfig.json", tsconfigJsonTemplate(), {});
22
+ await createFileIfNotExists("./saws.ts", sawsTsTemplate({ name }));
23
+ await createFileIfNotExists("./.gitignore", gitignoreTemplate());
24
+ };
@@ -1,3 +1,2 @@
1
1
  import { Command } from "commander";
2
2
  export declare const createCommand: () => Command;
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,10 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { initCommand } from "./command.js";
3
3
  export const createCommand = () => new Command("init")
4
- .description("bootstrap one configured service and its dependencies")
5
- .argument("<service>", "name of the service to initialize")
4
+ .argument("[service]", "name of the service to initialize")
6
5
  .argument("[config]", "path to service definition")
7
- .option("--root-dir <string>", "project root used for generated files")
8
- .option("--config <string>", "path to service definition")
9
- .option("--dry-run", "allow service initializers to preview their changes")
10
6
  .action(initCommand);
@@ -0,0 +1 @@
1
+ export declare const gitignoreTemplate: () => string;
@@ -0,0 +1,4 @@
1
+ export const gitignoreTemplate = () => `node_modules
2
+ .saws/saws-*-local-output.json
3
+ .saws/.secrets
4
+ .DS_Store`;
@@ -0,0 +1,3 @@
1
+ export declare const sawsTsTemplate: ({ name }: {
2
+ name: string;
3
+ }) => string;
@@ -0,0 +1,7 @@
1
+ export const sawsTsTemplate = ({ name }) => `import { ServiceDefinition } from "@saws/core";
2
+
3
+ export default new ServiceDefinition({
4
+ name: "${name}",
5
+ dependencies: [],
6
+ });
7
+ `;
@@ -0,0 +1 @@
1
+ export declare const tsconfigJsonTemplate: () => string;
@@ -0,0 +1,4 @@
1
+ export const tsconfigJsonTemplate = () => /* json */ `{
2
+ "extends": "@tsconfig/node26/tsconfig.json",
3
+ "files": []
4
+ }`;
@@ -0,0 +1,5 @@
1
+ export interface LogsCommandOptions {
2
+ config?: string;
3
+ stage: string;
4
+ }
5
+ export declare const logsCommand: (serviceName: string | undefined, options: LogsCommandOptions) => Promise<void>;
@@ -0,0 +1,19 @@
1
+ import { findServiceDefinition, getSawsConfig } from "@saws/core";
2
+ export const logsCommand = async (serviceName, options) => {
3
+ const { config, stage } = options;
4
+ if (stage == null || stage.length === 0) {
5
+ throw new Error("logs requires --stage <string>");
6
+ }
7
+ if (stage === "local")
8
+ return;
9
+ process.env.STAGE = stage;
10
+ const serviceDefinition = await getSawsConfig(config);
11
+ if (serviceName != null) {
12
+ await findServiceDefinition(serviceDefinition, serviceName).logs(stage);
13
+ return;
14
+ }
15
+ await Promise.all(collectServices(serviceDefinition).map((service) => service.logs(stage)));
16
+ };
17
+ function collectServices(root) {
18
+ return [...new Set(root.getAllDependencies())];
19
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const createCommand: () => Command;
@@ -0,0 +1,7 @@
1
+ import { Command } from "commander";
2
+ import { logsCommand } from "./command.js";
3
+ export const createCommand = () => new Command("logs")
4
+ .option("--stage <string>", "stage to tail logs from")
5
+ .option("--config <path>", "path to service definition")
6
+ .argument("[service]", "name of the service to tail logs from")
7
+ .action(logsCommand);
@@ -1,8 +1,8 @@
1
1
  export interface SecretsCommandOptions {
2
+ config?: string;
2
3
  stage?: string;
4
+ global?: boolean;
3
5
  set?: string;
4
6
  get?: boolean;
5
- rootDir?: string;
6
7
  }
7
8
  export declare function secretsCommand(name: string, options: SecretsCommandOptions): Promise<void>;
8
- //# sourceMappingURL=command.d.ts.map
@@ -1,16 +1,28 @@
1
- import { SecretsManager } from "@saws/secrets";
1
+ import { getSawsConfigModule, SecretsManager } from "@saws/core";
2
2
  export async function secretsCommand(name, options) {
3
- const manager = new SecretsManager({
4
- stage: options.stage ?? "local",
5
- rootDir: options.rootDir ?? process.cwd(),
6
- });
3
+ const value = options.set;
4
+ if (options.get && value != null) {
5
+ throw new Error("secrets accepts only one of --get or --set <value>");
6
+ }
7
+ if (!options.get && value == null) {
8
+ throw new Error("secrets requires either --get or --set <value>");
9
+ }
10
+ if (!options.global) {
11
+ process.env.STAGE = options.stage ?? "local";
12
+ }
13
+ const config = await getSawsConfigModule(options.config);
14
+ const manager = config.secrets;
15
+ if (!(manager instanceof SecretsManager)) {
16
+ throw new Error('saws.ts must export a SecretsManager instance named "secrets"');
17
+ }
18
+ const secrets = options.global ? manager.global : manager;
7
19
  if (options.get) {
8
- console.log(await manager.get(name));
20
+ console.log(await secrets.get(name));
9
21
  return;
10
22
  }
11
- if (options.set == null) {
12
- throw new Error("secrets requires either --get or --set <value>");
23
+ if (value == null) {
24
+ throw new Error("secrets requires --set <value>");
13
25
  }
14
- await manager.set(name, options.set);
26
+ await secrets.set(name, value);
15
27
  console.log("Set secret");
16
28
  }
@@ -1,3 +1,2 @@
1
1
  import { Command } from "commander";
2
2
  export declare const createCommand: () => Command;
3
- //# sourceMappingURL=index.d.ts.map
@@ -1,9 +1,11 @@
1
1
  import { Command } from "commander";
2
2
  import { secretsCommand } from "./command.js";
3
3
  export const createCommand = () => new Command("secrets")
4
- .argument("<string>", "secret name")
5
- .option("--stage <string>", "stage", "local")
6
- .option("--set <string>", "set secret value")
7
- .option("--get", "get secret value")
8
- .option("--root-dir <string>", "project root used for local secrets")
4
+ .description("get or set encrypted project secrets")
5
+ .argument("<name>", "secret name")
6
+ .option("--stage <string>", "stage for a stage-scoped secret", "local")
7
+ .option("--global", "use the global secret scope")
8
+ .option("--set <string>", "set the secret value")
9
+ .option("--get", "get the secret value")
10
+ .option("--config <string>", "path to service definition")
9
11
  .action(secretsCommand);
package/dist/hosts.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- import { Host } from "@saws/host";
2
- import type { ServiceDefinition } from "@saws/core";
1
+ import { Host, type ServiceDefinition } from "@saws/core";
3
2
  export declare function findConfiguredHosts(root: ServiceDefinition): Host[];
4
- //# sourceMappingURL=hosts.d.ts.map
package/dist/hosts.js CHANGED
@@ -1,16 +1,17 @@
1
- import { Host } from "@saws/host";
1
+ import { Host } from "@saws/core";
2
2
  export function findConfiguredHosts(root) {
3
3
  const hosts = new Set();
4
- const visited = new Set();
5
- const visit = (service) => {
6
- if (visited.has(service))
4
+ const visited = new WeakSet();
5
+ const visit = (value) => {
6
+ if (value == null || typeof value !== "object" || visited.has(value))
7
7
  return;
8
- visited.add(service);
9
- const host = service.docker?.host;
10
- if (host instanceof Host)
11
- hosts.add(host);
12
- for (const dependency of service.dependencies)
13
- visit(dependency);
8
+ visited.add(value);
9
+ if (value instanceof Host) {
10
+ hosts.add(value);
11
+ return;
12
+ }
13
+ for (const child of Object.values(value))
14
+ visit(child);
14
15
  };
15
16
  visit(root);
16
17
  return [...hosts];
package/package.json CHANGED
@@ -1,34 +1,24 @@
1
1
  {
2
2
  "name": "@saws/cli",
3
- "version": "2.0.0-beta.0",
4
- "description": "Command-line interface for SAWS",
3
+ "version": "2.0.0-beta.11",
4
+ "description": "",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/shichongrui/saws.git",
8
- "directory": "packages/cli"
7
+ "url": "git+https://github.com/shichongrui/saws.git"
9
8
  },
10
- "type": "module",
11
9
  "bin": {
12
- "saws": "dist/bin/saws.js"
10
+ "saws": "./dist/bin/saws.js"
13
11
  },
14
12
  "files": [
15
- "dist"
13
+ "./dist"
16
14
  ],
17
- "scripts": {
18
- "prebuild": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
19
- "build": "tsc -p tsconfig.json",
20
- "postbuild": "chmod +x dist/bin/saws.js",
21
- "test": "npm run build && node --test dist/commands/**/*.test.js",
22
- "typecheck": "tsc -p tsconfig.json --noEmit"
23
- },
15
+ "type": "module",
24
16
  "dependencies": {
25
- "@saws/core": "2.0.0-beta.0",
26
- "@saws/host": "2.0.0-beta.0",
27
- "@saws/secrets": "2.0.0-beta.0",
28
- "commander": "^14.0.3"
17
+ "@saws/core": "2.0.0-beta.11",
18
+ "commander": "^15.0.0",
19
+ "find-package-json": "^1.2.0"
29
20
  },
30
21
  "devDependencies": {
31
- "@types/node": "^20.11.19",
32
- "typescript": "^5.3.3"
22
+ "@types/find-package-json": "^1.2.7"
33
23
  }
34
24
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"saws.d.ts","sourceRoot":"","sources":["../../src/bin/saws.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy/command.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,oBAAoB,iBA2B9B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,eAOA,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/commands/dev/command.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,iBAAiB,iBAoD3B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/dev/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,eAMH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dev-tui.d.ts","sourceRoot":"","sources":["../../../../src/commands/dev/tui/dev-tui.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,YAAY,CAAC;AAkBlE,qBAAa,MAAM;IACjB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAiC;IAEjE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,QAAQ,EAAE,MAAM,EAAE;IAQ9B,KAAK;IAkBL,IAAI;IAUJ,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,GAAG,QAAmB;IAStE,OAAO,CAAC,cAAc,CAqBpB;IAEF,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,MAAM,CA6BZ;CACH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/commands/host/command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,2BAA2B,iBAOrC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,QAmBtD"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=command.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.test.d.ts","sourceRoot":"","sources":["../../../src/commands/host/command.test.ts"],"names":[],"mappings":""}
@@ -1,13 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { Host } from "@saws/host";
4
- import { selectHost } from "./command.js";
5
- const first = new Host({ name: "first", address: "first.example.test" });
6
- const second = new Host({ name: "second", address: "second.example.test" });
7
- test("selects the only configured host when its name is omitted", () => {
8
- assert.equal(selectHost([first]), first);
9
- });
10
- test("requires a valid name when several hosts are configured", () => {
11
- assert.throws(() => selectHost([second, first]), /Host name is required\. Available hosts: first, second/);
12
- assert.throws(() => selectHost([first, second], "missing"), /Host "missing" was not found\. Available hosts: first, second/);
13
- });
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/host/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,eAUrB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/commands/init/command.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,kBAAkB,iBAiB5B"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=command.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.test.d.ts","sourceRoot":"","sources":["../../../src/commands/init/command.test.ts"],"names":[],"mappings":""}
@@ -1,40 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { mkdtemp, readFile, writeFile } from "node:fs/promises";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import test from "node:test";
6
- import { pathToFileURL } from "node:url";
7
- import { initCommand } from "./command.js";
8
- test("initializes only the selected service branch in dependency order", async () => {
9
- const directory = await mkdtemp(path.join(os.tmpdir(), "saws-init-"));
10
- const configPath = path.join(directory, "saws.mjs");
11
- const packageUrl = pathToFileURL(path.resolve("../core/dist/index.js")).href;
12
- await writeFile(configPath, `
13
- import { appendFile } from "node:fs/promises";
14
- import path from "node:path";
15
- import { ServiceDefinition } from ${JSON.stringify(packageUrl)};
16
-
17
- class InitializableService extends ServiceDefinition {
18
- async onInit(context) {
19
- await appendFile(path.join(context.rootDir, "initialized.txt"), this.name + "\\n");
20
- }
21
- }
22
-
23
- const shared = new InitializableService({ name: "shared" });
24
- const api = new InitializableService({
25
- name: "api",
26
- dependencies: [shared],
27
- });
28
- const worker = new InitializableService({ name: "worker" });
29
-
30
- export default new InitializableService({
31
- name: "app",
32
- dependencies: [api, worker],
33
- });
34
- `);
35
- await initCommand("api", undefined, {
36
- config: configPath,
37
- rootDir: directory,
38
- });
39
- assert.equal(await readFile(path.join(directory, "initialized.txt"), "utf8"), "shared\napi\n");
40
- });
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,eAQF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/command.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,qBAAqB,iBAkB/B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,eAOC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,UAkB1D"}