@procedures/tailscale 0.28.0 → 0.28.1

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.
package/dist/module.d.ts CHANGED
@@ -2,8 +2,18 @@
2
2
  * The procedures of @procedures/tailscale as data. Importing this file registers nothing.
3
3
  */
4
4
  import { type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
5
+ import { type TailscaleProceduresOptions } from "./procedures.js";
5
6
  export declare const tailscaleModule: ProcedureModule;
6
7
  export default tailscaleModule;
8
+ /**
9
+ * This function gives the module with the settings of the host: the tailscale program. Without
10
+ * options, it gives `tailscaleModule`.
11
+ *
12
+ * ```ts
13
+ * createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
14
+ * ```
15
+ */
16
+ export declare function createTailscaleModule(options?: TailscaleProceduresOptions): ProcedureModule;
7
17
  /**
8
18
  * This function registers the procedures of @procedures/tailscale in a registry. The default is the
9
19
  * global registry.
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqD,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGrI,eAAO,MAAM,eAAe,EAAE,eAA4E,CAAC;eAE5F,eAAe;AAE9B;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,GAAE,iBAAsC,GAAG,IAAI,CAElG"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqD,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAkD,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAElH,eAAO,MAAM,eAAe,EAAE,eAA4E,CAAC;eAE5F,eAAe;AAE9B;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,0BAA+B,GAAG,eAAe,CAG/F;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,GAAE,iBAAsC,GAAG,IAAI,CAElG"}
package/dist/module.js CHANGED
@@ -2,9 +2,22 @@
2
2
  * The procedures of @procedures/tailscale as data. Importing this file registers nothing.
3
3
  */
4
4
  import { defineModule, registerModules, PROCEDURE_REGISTRY } from "@procedures/client";
5
- import { tailscaleProcedures } from "./procedures.js";
5
+ import { createTailscaleProcedures, tailscaleProcedures } from "./procedures.js";
6
6
  export const tailscaleModule = defineModule("@procedures/tailscale", tailscaleProcedures);
7
7
  export default tailscaleModule;
8
+ /**
9
+ * This function gives the module with the settings of the host: the tailscale program. Without
10
+ * options, it gives `tailscaleModule`.
11
+ *
12
+ * ```ts
13
+ * createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
14
+ * ```
15
+ */
16
+ export function createTailscaleModule(options = {}) {
17
+ if (options.executable === undefined)
18
+ return tailscaleModule;
19
+ return defineModule("@procedures/tailscale", createTailscaleProcedures(options));
20
+ }
8
21
  /**
9
22
  * This function registers the procedures of @procedures/tailscale in a registry. The default is the
10
23
  * global registry.
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAgD,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,CAAC,MAAM,eAAe,GAAoB,YAAY,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAC;AAE3G,eAAe,eAAe,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAQ,GAAsB,kBAAkB;IAC1F,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAgD,MAAM,oBAAoB,CAAC;AACrI,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAmC,MAAM,iBAAiB,CAAC;AAElH,MAAM,CAAC,MAAM,eAAe,GAAoB,YAAY,CAAC,uBAAuB,EAAE,mBAAmB,CAAC,CAAC;AAE3G,eAAe,eAAe,CAAC;AAE/B;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAO,GAA+B,EAAE;IAC5E,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC7D,OAAO,YAAY,CAAC,uBAAuB,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAQ,GAAsB,kBAAkB;IAC1F,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -1,10 +1,26 @@
1
1
  /**
2
2
  * The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
3
3
  * command (`status`, `ip`, `serve`, `up`, `down`).
4
+ *
5
+ * The program comes from the host (audit pass 2, O55): the `executable` option of
6
+ * `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
7
+ * The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
8
+ * notice. Version 0.30.0 removes it, because it lets the caller start any program.
4
9
  */
5
10
  import { type AnyProcedure } from "@procedures/client";
6
- /** This function gives the tailscale program: the input, TAILSCALE_EXE, the Windows install folder, then tailscale. */
11
+ /** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
7
12
  export declare function tailscaleExecutable(explicit?: string): string;
8
- export declare const tailscaleRunProcedure: AnyProcedure;
13
+ /** The settings of the host for the procedures of this package. The procedure input cannot change them. */
14
+ export interface TailscaleProceduresOptions {
15
+ /** The tailscale program. The default is `TAILSCALE_EXE`, then the Windows install folder, then `tailscale`. */
16
+ readonly executable?: string | undefined;
17
+ }
18
+ /**
19
+ * This function gives the procedures of this package with the settings of the host. The program
20
+ * of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
21
+ * deprecated input `executable` wins over both, with a deprecation notice.
22
+ */
23
+ export declare function createTailscaleProcedures(options?: TailscaleProceduresOptions): AnyProcedure[];
9
24
  export declare const tailscaleProcedures: AnyProcedure[];
25
+ export declare const tailscaleRunProcedure: AnyProcedure;
10
26
  //# sourceMappingURL=procedures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAA+B,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAQ3G,uHAAuH;AACvH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7D;AAoCD,eAAO,MAAM,qBAAqB,EAAE,YAiCV,CAAC;AAE3B,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAA4B,CAAC"}
1
+ {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAA+B,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAuB3G,gIAAgI;AAChI,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7D;AA8CD,2GAA2G;AAC3G,MAAM,WAAW,0BAA0B;IACzC,gHAAgH;IAChH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,YAAY,EAAE,CAsClG;AAED,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAAgC,CAAC;AAE/E,eAAO,MAAM,qBAAqB,EAAE,YAAsC,CAAC"}
@@ -1,15 +1,32 @@
1
1
  /**
2
2
  * The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
3
3
  * command (`status`, `ip`, `serve`, `up`, `down`).
4
+ *
5
+ * The program comes from the host (audit pass 2, O55): the `executable` option of
6
+ * `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
7
+ * The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
8
+ * notice. Version 0.30.0 removes it, because it lets the caller start any program.
4
9
  */
5
10
  import { existsSync } from "node:fs";
6
11
  import { createProcedure, zodAdapter } from "@procedures/client";
7
12
  import { runCommand } from "@procedures/shell/command";
8
13
  import { z } from "zod";
9
14
  import { buildArgv, parseJsonOutput } from "./argv.js";
15
+ /** The codes of the deprecation notices that this process emitted. */
16
+ const emitted = new Set();
17
+ /** This function emits a deprecation notice one time in each process. */
18
+ function deprecationNotice(code, message) {
19
+ if (emitted.has(code))
20
+ return;
21
+ emitted.add(code);
22
+ process.emitWarning(message, { type: "DeprecationWarning", code });
23
+ }
24
+ /** The notice of the deprecated input `executable` of `tailscale.run`. */
25
+ const EXECUTABLE_INPUT_NOTICE = "The input executable of tailscale.run is deprecated. @procedures/tailscale 0.30.0 refuses it. " +
26
+ "Give the program to the host: createTailscaleModule({ executable }), or set TAILSCALE_EXE.";
10
27
  /** The Windows installer does not put tailscale on the PATH. */
11
28
  const WINDOWS_PATH = "C:\\Program Files\\Tailscale\\tailscale.exe";
12
- /** This function gives the tailscale program: the input, TAILSCALE_EXE, the Windows install folder, then tailscale. */
29
+ /** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
13
30
  export function tailscaleExecutable(explicit) {
14
31
  if (explicit !== undefined)
15
32
  return explicit;
@@ -29,7 +46,17 @@ const RunInputSchema = z.object({
29
46
  .optional()
30
47
  .describe('The flags, for example { bg: true }'),
31
48
  json: z.boolean().default(false).describe("Ask for JSON output (--json) and read it. Only some commands have it (status, serve status)."),
32
- executable: z.string().min(1).optional().describe("The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
49
+ /**
50
+ * The tailscale program.
51
+ *
52
+ * @deprecated Give `executable` to `createTailscaleModule()`, or set `TAILSCALE_EXE`. Version
53
+ * 0.30.0 refuses this input (audit pass 2, O55), because it lets the caller start any program.
54
+ */
55
+ executable: z
56
+ .string()
57
+ .min(1)
58
+ .optional()
59
+ .describe("Deprecated: give executable to createTailscaleModule(), or set TAILSCALE_EXE. The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
33
60
  timeout: z.number().int().positive().default(60_000).describe("The time limit, in milliseconds (default: 60000)"),
34
61
  });
35
62
  const RunOutputSchema = z.object({
@@ -40,40 +67,52 @@ const RunOutputSchema = z.object({
40
67
  json: z.unknown().optional(),
41
68
  actionUrl: z.string().optional(),
42
69
  });
43
- export const tailscaleRunProcedure = createProcedure()
44
- .path(["tailscale", "run"])
45
- .input(zodAdapter(RunInputSchema))
46
- .output(zodAdapter(RunOutputSchema))
47
- .meta({
48
- description: "Run a tailscale command (status, ip, serve, up, down)",
49
- args: ["path"],
50
- shorts: { timeout: "t" },
51
- output: "json",
52
- // up, down and serve change the network of the host. ssh starts a program on another host.
53
- effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
54
- })
55
- .handler(async (input, ctx) => {
56
- const argv = buildArgv({
57
- path: input.path,
58
- flags: input.json ? ["--json"] : [],
59
- args: input.args,
60
- positional: input.positional,
61
- });
62
- const result = await runCommand(tailscaleExecutable(input.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
63
- if (result.error)
64
- throw new Error(`tailscale did not start: ${result.error}`);
65
- const json = input.json ? parseJsonOutput(result.stdout) : undefined;
66
- // tailscale prints an address to open when a login or a feature needs the owner
67
- const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
68
- return {
69
- exitCode: result.exitCode,
70
- success: result.exitCode === 0,
71
- stdout: result.stdout,
72
- stderr: result.stderr,
73
- ...(json !== undefined ? { json } : {}),
74
- ...(actionUrl !== undefined ? { actionUrl } : {}),
75
- };
76
- })
77
- .build();
78
- export const tailscaleProcedures = [tailscaleRunProcedure];
70
+ /**
71
+ * This function gives the procedures of this package with the settings of the host. The program
72
+ * of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
73
+ * deprecated input `executable` wins over both, with a deprecation notice.
74
+ */
75
+ export function createTailscaleProcedures(options = {}) {
76
+ const run = createProcedure()
77
+ .path(["tailscale", "run"])
78
+ .input(zodAdapter(RunInputSchema))
79
+ .output(zodAdapter(RunOutputSchema))
80
+ .meta({
81
+ description: "Run a tailscale command (status, ip, serve, up, down)",
82
+ args: ["path"],
83
+ shorts: { timeout: "t" },
84
+ output: "json",
85
+ // up, down and serve change the network of the host. ssh starts a program on another host.
86
+ effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
87
+ })
88
+ .handler(async (input, ctx) => {
89
+ const argv = buildArgv({
90
+ path: input.path,
91
+ flags: input.json ? ["--json"] : [],
92
+ args: input.args,
93
+ positional: input.positional,
94
+ });
95
+ // The deprecated input wins over the module, as before (O55: 0.30.0 removes it)
96
+ if (input.executable !== undefined)
97
+ deprecationNotice("PROCEDURES_TAILSCALE_EXECUTABLE_INPUT", EXECUTABLE_INPUT_NOTICE);
98
+ const result = await runCommand(tailscaleExecutable(input.executable ?? options.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
99
+ if (result.error)
100
+ throw new Error(`tailscale did not start: ${result.error}`);
101
+ const json = input.json ? parseJsonOutput(result.stdout) : undefined;
102
+ // tailscale prints an address to open when a login or a feature needs the owner
103
+ const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
104
+ return {
105
+ exitCode: result.exitCode,
106
+ success: result.exitCode === 0,
107
+ stdout: result.stdout,
108
+ stderr: result.stderr,
109
+ ...(json !== undefined ? { json } : {}),
110
+ ...(actionUrl !== undefined ? { actionUrl } : {}),
111
+ };
112
+ })
113
+ .build();
114
+ return [run];
115
+ }
116
+ export const tailscaleProcedures = createTailscaleProcedures();
117
+ export const tailscaleRunProcedure = tailscaleProcedures[0];
79
118
  //# sourceMappingURL=procedures.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@procedures/tailscale",
4
- "version": "0.28.0",
4
+ "version": "0.28.1",
5
5
  "description": "The tailscale CLI as one procedure: status, ip, serve, up and down, with JSON output.",
6
6
  "keywords": [
7
7
  "tailscale",
@@ -56,9 +56,9 @@
56
56
  "provenance": true
57
57
  },
58
58
  "dependencies": {
59
- "@procedures/client": "0.28.0",
59
+ "@procedures/client": "0.28.1",
60
60
  "zod": "^4.6.5",
61
- "@procedures/shell": "0.28.0"
61
+ "@procedures/shell": "0.28.1"
62
62
  },
63
63
  "devDependencies": {
64
64
  "typescript": "^7.0.2",
package/src/module.ts CHANGED
@@ -3,12 +3,25 @@
3
3
  */
4
4
 
5
5
  import { defineModule, registerModules, PROCEDURE_REGISTRY, type ProcedureModule, type ProcedureRegistry } from "@procedures/client";
6
- import { tailscaleProcedures } from "./procedures.js";
6
+ import { createTailscaleProcedures, tailscaleProcedures, type TailscaleProceduresOptions } from "./procedures.js";
7
7
 
8
8
  export const tailscaleModule: ProcedureModule = defineModule("@procedures/tailscale", tailscaleProcedures);
9
9
 
10
10
  export default tailscaleModule;
11
11
 
12
+ /**
13
+ * This function gives the module with the settings of the host: the tailscale program. Without
14
+ * options, it gives `tailscaleModule`.
15
+ *
16
+ * ```ts
17
+ * createRegistry(createTailscaleModule({ executable: "/opt/tailscale/bin/tailscale" }));
18
+ * ```
19
+ */
20
+ export function createTailscaleModule(options: TailscaleProceduresOptions = {}): ProcedureModule {
21
+ if (options.executable === undefined) return tailscaleModule;
22
+ return defineModule("@procedures/tailscale", createTailscaleProcedures(options));
23
+ }
24
+
12
25
  /**
13
26
  * This function registers the procedures of @procedures/tailscale in a registry. The default is the
14
27
  * global registry.
package/src/procedures.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  /**
2
2
  * The procedure of `@procedures/tailscale`: `tailscale.run`, one procedure for each tailscale
3
3
  * command (`status`, `ip`, `serve`, `up`, `down`).
4
+ *
5
+ * The program comes from the host (audit pass 2, O55): the `executable` option of
6
+ * `createTailscaleModule()`, then `TAILSCALE_EXE`, then the install folder, then `tailscale`.
7
+ * The input `executable` is deprecated: it still names the program in 0.28, with a deprecation
8
+ * notice. Version 0.30.0 removes it, because it lets the caller start any program.
4
9
  */
5
10
 
6
11
  import { existsSync } from "node:fs";
@@ -9,10 +14,25 @@ import { runCommand } from "@procedures/shell/command";
9
14
  import { z } from "zod";
10
15
  import { buildArgv, parseJsonOutput, type ArgValue } from "./argv.js";
11
16
 
17
+ /** The codes of the deprecation notices that this process emitted. */
18
+ const emitted = new Set<string>();
19
+
20
+ /** This function emits a deprecation notice one time in each process. */
21
+ function deprecationNotice(code: string, message: string): void {
22
+ if (emitted.has(code)) return;
23
+ emitted.add(code);
24
+ process.emitWarning(message, { type: "DeprecationWarning", code });
25
+ }
26
+
27
+ /** The notice of the deprecated input `executable` of `tailscale.run`. */
28
+ const EXECUTABLE_INPUT_NOTICE =
29
+ "The input executable of tailscale.run is deprecated. @procedures/tailscale 0.30.0 refuses it. " +
30
+ "Give the program to the host: createTailscaleModule({ executable }), or set TAILSCALE_EXE.";
31
+
12
32
  /** The Windows installer does not put tailscale on the PATH. */
13
33
  const WINDOWS_PATH = "C:\\Program Files\\Tailscale\\tailscale.exe";
14
34
 
15
- /** This function gives the tailscale program: the input, TAILSCALE_EXE, the Windows install folder, then tailscale. */
35
+ /** This function gives the tailscale program: the explicit value, TAILSCALE_EXE, the Windows install folder, then tailscale. */
16
36
  export function tailscaleExecutable(explicit?: string): string {
17
37
  if (explicit !== undefined) return explicit;
18
38
  const fromEnv = process.env["TAILSCALE_EXE"];
@@ -31,7 +51,17 @@ const RunInputSchema = z.object({
31
51
  .optional()
32
52
  .describe('The flags, for example { bg: true }'),
33
53
  json: z.boolean().default(false).describe("Ask for JSON output (--json) and read it. Only some commands have it (status, serve status)."),
34
- executable: z.string().min(1).optional().describe("The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
54
+ /**
55
+ * The tailscale program.
56
+ *
57
+ * @deprecated Give `executable` to `createTailscaleModule()`, or set `TAILSCALE_EXE`. Version
58
+ * 0.30.0 refuses this input (audit pass 2, O55), because it lets the caller start any program.
59
+ */
60
+ executable: z
61
+ .string()
62
+ .min(1)
63
+ .optional()
64
+ .describe("Deprecated: give executable to createTailscaleModule(), or set TAILSCALE_EXE. The tailscale program (default: TAILSCALE_EXE, then the install folder, then tailscale)"),
35
65
  timeout: z.number().int().positive().default(60_000).describe("The time limit, in milliseconds (default: 60000)"),
36
66
  });
37
67
  type RunInput = z.infer<typeof RunInputSchema>;
@@ -54,39 +84,57 @@ const RunOutputSchema = z.object({
54
84
  actionUrl: z.string().optional(),
55
85
  });
56
86
 
57
- export const tailscaleRunProcedure: AnyProcedure = createProcedure()
58
- .path(["tailscale", "run"])
59
- .input(zodAdapter<RunInput>(RunInputSchema))
60
- .output(zodAdapter<RunOutput>(RunOutputSchema))
61
- .meta({
62
- description: "Run a tailscale command (status, ip, serve, up, down)",
63
- args: ["path"],
64
- shorts: { timeout: "t" },
65
- output: "json",
66
- // up, down and serve change the network of the host. ssh starts a program on another host.
67
- effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
68
- })
69
- .handler(async (input: RunInput, ctx?: ProcedureContext): Promise<RunOutput> => {
70
- const argv = buildArgv({
71
- path: input.path,
72
- flags: input.json ? ["--json"] : [],
73
- args: input.args as Record<string, ArgValue> | undefined,
74
- positional: input.positional,
75
- });
76
- const result = await runCommand(tailscaleExecutable(input.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
77
- if (result.error) throw new Error(`tailscale did not start: ${result.error}`);
78
- const json = input.json ? parseJsonOutput(result.stdout) : undefined;
79
- // tailscale prints an address to open when a login or a feature needs the owner
80
- const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
81
- return {
82
- exitCode: result.exitCode,
83
- success: result.exitCode === 0,
84
- stdout: result.stdout,
85
- stderr: result.stderr,
86
- ...(json !== undefined ? { json } : {}),
87
- ...(actionUrl !== undefined ? { actionUrl } : {}),
88
- };
89
- })
90
- .build() as AnyProcedure;
87
+ /** The settings of the host for the procedures of this package. The procedure input cannot change them. */
88
+ export interface TailscaleProceduresOptions {
89
+ /** The tailscale program. The default is `TAILSCALE_EXE`, then the Windows install folder, then `tailscale`. */
90
+ readonly executable?: string | undefined;
91
+ }
92
+
93
+ /**
94
+ * This function gives the procedures of this package with the settings of the host. The program
95
+ * of `tailscale.run` is `executable`, or the default of `tailscaleExecutable()` at each call. The
96
+ * deprecated input `executable` wins over both, with a deprecation notice.
97
+ */
98
+ export function createTailscaleProcedures(options: TailscaleProceduresOptions = {}): AnyProcedure[] {
99
+ const run = createProcedure()
100
+ .path(["tailscale", "run"])
101
+ .input(zodAdapter<RunInput>(RunInputSchema))
102
+ .output(zodAdapter<RunOutput>(RunOutputSchema))
103
+ .meta({
104
+ description: "Run a tailscale command (status, ip, serve, up, down)",
105
+ args: ["path"],
106
+ shorts: { timeout: "t" },
107
+ output: "json",
108
+ // up, down and serve change the network of the host. ssh starts a program on another host.
109
+ effects: { reads: ["network"], writes: ["network", "process"], destructive: true },
110
+ })
111
+ .handler(async (input: RunInput, ctx?: ProcedureContext): Promise<RunOutput> => {
112
+ const argv = buildArgv({
113
+ path: input.path,
114
+ flags: input.json ? ["--json"] : [],
115
+ args: input.args as Record<string, ArgValue> | undefined,
116
+ positional: input.positional,
117
+ });
118
+ // The deprecated input wins over the module, as before (O55: 0.30.0 removes it)
119
+ if (input.executable !== undefined) deprecationNotice("PROCEDURES_TAILSCALE_EXECUTABLE_INPUT", EXECUTABLE_INPUT_NOTICE);
120
+ const result = await runCommand(tailscaleExecutable(input.executable ?? options.executable), { args: argv, timeout: input.timeout, signal: ctx?.signal });
121
+ if (result.error) throw new Error(`tailscale did not start: ${result.error}`);
122
+ const json = input.json ? parseJsonOutput(result.stdout) : undefined;
123
+ // tailscale prints an address to open when a login or a feature needs the owner
124
+ const actionUrl = /https:\/\/login\.tailscale\.com\/\S+/.exec(`${result.stdout}\n${result.stderr}`)?.[0];
125
+ return {
126
+ exitCode: result.exitCode,
127
+ success: result.exitCode === 0,
128
+ stdout: result.stdout,
129
+ stderr: result.stderr,
130
+ ...(json !== undefined ? { json } : {}),
131
+ ...(actionUrl !== undefined ? { actionUrl } : {}),
132
+ };
133
+ })
134
+ .build() as AnyProcedure;
135
+ return [run];
136
+ }
137
+
138
+ export const tailscaleProcedures: AnyProcedure[] = createTailscaleProcedures();
91
139
 
92
- export const tailscaleProcedures: AnyProcedure[] = [tailscaleRunProcedure];
140
+ export const tailscaleRunProcedure: AnyProcedure = tailscaleProcedures[0]!;