@stll/oxlint-config 0.11.0 → 0.12.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/README.md CHANGED
@@ -92,9 +92,42 @@ part of major 26 fail.
92
92
  Release and publish workflows use exact patch version-file selectors for
93
93
  reproducible builds; this repository pins `.node-version` to `26.10.0`.
94
94
  The series policy accepts that patch without weakening release validation.
95
+ Runtime images may retain a full SHA256 digest alongside an exact stable patch
96
+ tag: Node must be inside its policy series and match tracked root `.node-version`
97
+ when present; Python must be a patch in its policy series; Bun must equal its
98
+ policy version. Supported image variants remain allowed.
99
+ Digest validation is declaration-only: the guard enforces the exact policy tag
100
+ and a full SHA256 digest, but does not verify that the digest belongs to the tag.
101
+ Dependabot refreshes digests per repository; a shared tag-to-digest map would
102
+ require a tooling release for every base-image digest bump across repositories,
103
+ which costs more than it buys.
95
104
  GitHub JavaScript action host runtimes (`runs.using`) are platform-managed
96
105
  and do not select the project toolchain Node version.
97
106
 
107
+ A published package can test the minimum Node major in its `engines.node`
108
+ support range in one declared workflow job. Add a scoped `engineFloors` entry
109
+ to tracked root `stll-toolchain.json`:
110
+
111
+ ```json
112
+ {
113
+ "engineFloors": [
114
+ {
115
+ "package": "packages/library",
116
+ "workflow": ".github/workflows/ci.yml",
117
+ "job": "node-floor"
118
+ }
119
+ ]
120
+ }
121
+ ```
122
+
123
+ That job may use a literal exact stable patch in setup-node's `node-version`
124
+ whose major matches the range's minimum major and whose release satisfies
125
+ the range (for example, `20.10.0` for `>=20.10.0`). The approved action SHA, version comment and input validation
126
+ also apply. Other jobs and runtime files follow the shared Node series.
127
+ Missing packages or jobs, private packages, absent setup-node selectors and
128
+ floor mismatches fail configuration validation. `optOuts` is optional when
129
+ only `engineFloors` is declared.
130
+
98
131
  Run the installed checker from the repository root in CI:
99
132
 
100
133
  ```sh
@@ -120,7 +153,21 @@ rule and a nonempty reason:
120
153
  }
121
154
  ```
122
155
 
123
- `node-engine` is mandatory: an opt-out cannot bypass the shared Node support range.
156
+ Workspace TypeScript toolchains combine the root and declared members' devDependencies.
157
+ An included member may declare the exact TypeScript 6 compatibility API across
158
+ dependencies, devDependencies, and peerDependencies when that shared install uses
159
+ the complete split layout. Ambiguous or partial layouts do not grant this allowance.
160
+ Peer ranges declare support: they must include the policy compiler release and the
161
+ compatibility release when the selected layout uses it. Ranges do not contribute
162
+ to the installed compiler inventory.
163
+
164
+ JavaScript update roots come from the repository root, declared workspace membership,
165
+ and directories with their own `bun.lock`, `package-lock.json`, `yarn.lock`, or
166
+ `pnpm-lock.yaml`. Other package manifests do not create update roots; directory names
167
+ have no special meaning. Workspace members share their owner's update entry.
168
+
169
+ `node-engine` and `cloud-setup-drift` are mandatory: opt-outs cannot bypass the
170
+ shared Node support range or generated cloud setup requirements.
124
171
 
125
172
  Opt-outs apply to the entire repository for that rule. Unknown or duplicate
126
173
  rules, empty reasons, and malformed configuration fail validation. See the
@@ -144,3 +191,68 @@ is unnecessary. Their original reference metadata is preserved without
144
191
  discovering or building referenced projects. Missing, unreadable, and zero-input
145
192
  selected configs fail the check. `--help` prints usage and exits successfully;
146
193
  unknown arguments fail.
194
+
195
+ ## Shared cloud setup
196
+
197
+ Add an explicit declaration to tracked root `stll-toolchain.json`:
198
+
199
+ ```json
200
+ {
201
+ "optOuts": [],
202
+ "cloud": {
203
+ "services": ["postgres", "valkey"],
204
+ "install": "bun install --frozen-lockfile",
205
+ "envFile": ".env.cloud"
206
+ }
207
+ }
208
+ ```
209
+
210
+ Services are optional: omit `services` or use `[]` for runtimes and dependencies
211
+ only. No `cloud` declaration means no cloud setup script. `envFile` is required
212
+ with services and rejected without services; runtime-only scripts emit no
213
+ environment file code. With services, `envFile` must be a canonical
214
+ repository-relative path; its existing parent must be safe at runtime. Track an exact stable Node patch in root
215
+ `.node-version` within the shared Node series. Generate and commit the script:
216
+
217
+ ```sh
218
+ bunx --no-install stll-cloud-setup
219
+ ```
220
+
221
+ Generation uses the installed policy's Bun, Node, PostgreSQL, and Valkey pins.
222
+ PostgreSQL uses the PGDG major-version packages; minor updates within the pinned
223
+ major are accepted for the disposable database. Before adding PGDG, provisioning
224
+ reuses an existing source only after verifying its signing-key fingerprint;
225
+ conflicts identify the source file. Existing matching-major binaries are reused. Valkey uses official versioned
226
+ binary DEBs for the declared release and architecture, verifies the policy's
227
+ SHA256 pins, and installs those local files with apt. It does not resolve Valkey
228
+ from a mutable package index.
229
+ The command writes `.agents/cloud-setup.sh` with executable permissions and
230
+ refuses symlink parents or destinations and hard-linked destinations. `stll-toolchain-check` rejects missing,
231
+ drifted, or undeclared tracked scripts with mandatory `cloud-setup-drift`.
232
+ Regenerate after changing the policy or declaration. `stll-cloud-setup --help`
233
+ prints usage without reading repository configuration.
234
+
235
+ | Environment phase | Command |
236
+ | ----------------------- | ------------------------------------- |
237
+ | Networked install | `bash .agents/cloud-setup.sh install` |
238
+ | Offline session startup | `bash .agents/cloud-setup.sh start` |
239
+
240
+ Both commands can be rerun. Missing or unknown subcommands print usage and
241
+ exit 2; there is no implicit lifecycle mode. The script supports Ubuntu 24.04
242
+ with root access or passwordless sudo and fails when required capabilities
243
+ or pinned installations are unavailable. `install` provisions runtimes,
244
+ dependencies, and declared services; `start` restores local services after
245
+ cached environments lose running processes. Services bind only to localhost.
246
+ System provisioning runs as root; frozen dependencies run as the invoking user
247
+ with that user's home and a private, user-owned Bun cache. Package installation
248
+ does not permit automatic downgrades.
249
+ If a newer Valkey package is already installed, provisioning fails rather than
250
+ downgrading it; use an environment compatible with the pinned release.
251
+ The environment file contains `NODE_ENV=test` and declared local connection
252
+ URLs, carries a generated ownership marker, and refuses an unowned file or
253
+ symlink. Configure the repository's test runner to load that file; migration
254
+ commands and repository adoption are separate configuration steps.
255
+
256
+ Environments may cache filesystems without preserving service processes.
257
+ Run `start` at every session start, including sessions that reuse installed files.
258
+ The supported OS, privileges, and pinned runtime requirements are checked explicitly.
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_toolchain_guard = require("./toolchain-guard.cjs");
4
+ let node_fs = require("node:fs");
5
+ let node_path = require("node:path");
6
+ let node_fs_promises = require("node:fs/promises");
7
+ //#region src/cloud-setup-cli.ts
8
+ const usage = "Usage: stll-cloud-setup (run from repository root)\n stll-cloud-setup --help";
9
+ const optionalStat = async (path) => {
10
+ try {
11
+ return await (0, node_fs_promises.lstat)(path);
12
+ } catch (error) {
13
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
14
+ throw error;
15
+ }
16
+ };
17
+ const main = async () => {
18
+ const args = process.argv.slice(2);
19
+ if (args.length === 1 && args.at(0) === "--help") {
20
+ process.stdout.write(`${usage}\n`);
21
+ return;
22
+ }
23
+ if (args.length !== 0) throw new Error(usage);
24
+ const root = await (0, node_fs_promises.realpath)(process.cwd());
25
+ const { files, diagnostics } = require_toolchain_guard.readToolchainInputs(root);
26
+ if (diagnostics.length > 0) throw new Error(diagnostics.map(({ path, message }) => `${path}: ${message}`).join("\n"));
27
+ const text = files["stll-toolchain.json"];
28
+ if (text === void 0) throw new Error("requires tracked stll-toolchain.json");
29
+ const { cloud } = require_toolchain_guard.parseToolchainConfiguration(JSON.parse(text));
30
+ if (cloud === void 0) throw new Error("requires an explicit cloud declaration");
31
+ const nodeVersion = files[".node-version"];
32
+ if (nodeVersion === void 0) throw new Error("requires tracked root .node-version");
33
+ const script = require_toolchain_guard.generateCloudSetup({
34
+ policy: require_toolchain_guard.parseToolchainPolicy(JSON.parse(await (0, node_fs_promises.readFile)(new URL("../toolchain.json", require("url").pathToFileURL(__filename).href), "utf8"))),
35
+ cloud,
36
+ nodeVersion: nodeVersion.trim()
37
+ });
38
+ const destination = (0, node_path.join)(root, require_toolchain_guard.cloudSetupPath);
39
+ const parent = (0, node_path.dirname)(destination);
40
+ const parentStat = await optionalStat(parent);
41
+ if (parentStat === void 0) await (0, node_fs_promises.mkdir)(parent);
42
+ else if (parentStat.isSymbolicLink() || !parentStat.isDirectory()) throw new Error("cloud setup parent must be a real repository directory");
43
+ const destinationStat = await optionalStat(destination);
44
+ if (destinationStat !== void 0 && (destinationStat.isSymbolicLink() || !destinationStat.isFile() || destinationStat.nlink !== 1)) throw new Error("cloud setup destination must be a single-link regular repository file");
45
+ const output = await (0, node_fs_promises.open)(destination, node_fs.constants.O_WRONLY | node_fs.constants.O_CREAT | node_fs.constants.O_NOFOLLOW, 493);
46
+ try {
47
+ const opened = await output.stat();
48
+ if (!opened.isFile() || opened.nlink !== 1) throw new Error("cloud setup destination must be a single-link regular repository file");
49
+ await output.truncate(0);
50
+ await output.writeFile(script, "utf8");
51
+ await output.chmod(493);
52
+ } finally {
53
+ await output.close();
54
+ }
55
+ process.stdout.write(`Generated ${require_toolchain_guard.cloudSetupPath}\n`);
56
+ };
57
+ main().catch((error) => {
58
+ process.stderr.write(`cloud-setup: ${error instanceof Error ? error.message : String(error)}\n`);
59
+ process.exitCode = 1;
60
+ });
61
+ //#endregion
62
+
63
+ //# sourceMappingURL=cloud-setup-cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-setup-cli.cjs","names":["readToolchainInputs","parseToolchainConfiguration","generateCloudSetup","parseToolchainPolicy","cloudSetupPath","constants"],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { lstat, mkdir, open, readFile, realpath } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst optionalStat = async (path: string) => {\n try {\n return await lstat(path);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n if (diagnostics.length > 0)\n throw new Error(\n diagnostics.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud } = parseToolchainConfiguration(JSON.parse(text));\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const policy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n });\n const destination = join(root, cloudSetupPath);\n const parent = dirname(destination);\n const parentStat = await optionalStat(parent);\n if (parentStat === undefined) await mkdir(parent);\n else if (parentStat.isSymbolicLink() || !parentStat.isDirectory())\n throw new Error(\"cloud setup parent must be a real repository directory\");\n const destinationStat = await optionalStat(destination);\n if (\n destinationStat !== undefined &&\n (destinationStat.isSymbolicLink() ||\n !destinationStat.isFile() ||\n destinationStat.nlink !== 1)\n )\n throw new Error(\n \"cloud setup destination must be a single-link regular repository file\",\n );\n const output = await open(\n destination,\n constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW,\n 0o755,\n );\n try {\n const opened = await output.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"cloud setup destination must be a single-link regular repository file\",\n );\n await output.truncate(0);\n await output.writeFile(script, \"utf8\");\n await output.chmod(0o755);\n } finally {\n await output.close();\n }\n process.stdout.write(`Generated ${cloudSetupPath}\\n`);\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;AAYA,MAAM,QACJ;AACF,MAAM,eAAe,OAAO,SAAiB;CAC3C,IAAI;EACF,OAAO,OAAA,GAAA,iBAAA,MAAA,CAAY,IAAI;CACzB,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;EACT,MAAM;CACR;AACF;AAEA,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,OAAA,GAAA,iBAAA,SAAA,CAAe,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,gBAAgBA,wBAAAA,oBAAoB,IAAI;CACvD,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MACR,YAAY,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACzE;CACF,MAAM,OAAO,MAAM;CACnB,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,sCAAsC;CACxD,MAAM,EAAE,UAAUC,wBAAAA,4BAA4B,KAAK,MAAM,IAAI,CAAC;CAC9D,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,wCAAwC;CAC1D,MAAM,cAAc,MAAM;CAC1B,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,qCAAqC;CAMvD,MAAM,SAASC,wBAAAA,mBAAmB;EAChC,QANaC,wBAAAA,qBACb,KAAK,MACH,OAAA,GAAA,iBAAA,SAAA,CAAe,IAAI,IAAI,qBAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAAoC,GAAG,MAAM,CACtE,CAGK;EACL;EACA,aAAa,YAAY,KAAK;CAChC,CAAC;CACD,MAAM,eAAA,GAAA,UAAA,KAAA,CAAmB,MAAMC,wBAAAA,cAAc;CAC7C,MAAM,UAAA,GAAA,UAAA,QAAA,CAAiB,WAAW;CAClC,MAAM,aAAa,MAAM,aAAa,MAAM;CAC5C,IAAI,eAAe,KAAA,GAAW,OAAA,GAAA,iBAAA,MAAA,CAAY,MAAM;MAC3C,IAAI,WAAW,eAAe,KAAK,CAAC,WAAW,YAAY,GAC9D,MAAM,IAAI,MAAM,wDAAwD;CAC1E,MAAM,kBAAkB,MAAM,aAAa,WAAW;CACtD,IACE,oBAAoB,KAAA,MACnB,gBAAgB,eAAe,KAC9B,CAAC,gBAAgB,OAAO,KACxB,gBAAgB,UAAU,IAE5B,MAAM,IAAI,MACR,uEACF;CACF,MAAM,SAAS,OAAA,GAAA,iBAAA,KAAA,CACb,aACAC,QAAAA,UAAU,WAAWA,QAAAA,UAAU,UAAUA,QAAAA,UAAU,YACnD,GACF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,KAAK;EACjC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,uEACF;EACF,MAAM,OAAO,SAAS,CAAC;EACvB,MAAM,OAAO,UAAU,QAAQ,MAAM;EACrC,MAAM,OAAO,MAAM,GAAK;CAC1B,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;CACA,QAAQ,OAAO,MAAM,aAAaD,wBAAAA,eAAe,GAAG;AACtD;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACzE;CACA,QAAQ,WAAW;AACrB,CAAC"}
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import { a as cloudSetupPath, i as parseToolchainPolicy, n as parseToolchainConfiguration, o as generateCloudSetup, r as readToolchainInputs } from "./toolchain-guard.mjs";
3
+ import { constants } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { lstat, mkdir, open, readFile, realpath } from "node:fs/promises";
6
+ //#region src/cloud-setup-cli.ts
7
+ const usage = "Usage: stll-cloud-setup (run from repository root)\n stll-cloud-setup --help";
8
+ const optionalStat = async (path) => {
9
+ try {
10
+ return await lstat(path);
11
+ } catch (error) {
12
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
13
+ throw error;
14
+ }
15
+ };
16
+ const main = async () => {
17
+ const args = process.argv.slice(2);
18
+ if (args.length === 1 && args.at(0) === "--help") {
19
+ process.stdout.write(`${usage}\n`);
20
+ return;
21
+ }
22
+ if (args.length !== 0) throw new Error(usage);
23
+ const root = await realpath(process.cwd());
24
+ const { files, diagnostics } = readToolchainInputs(root);
25
+ if (diagnostics.length > 0) throw new Error(diagnostics.map(({ path, message }) => `${path}: ${message}`).join("\n"));
26
+ const text = files["stll-toolchain.json"];
27
+ if (text === void 0) throw new Error("requires tracked stll-toolchain.json");
28
+ const { cloud } = parseToolchainConfiguration(JSON.parse(text));
29
+ if (cloud === void 0) throw new Error("requires an explicit cloud declaration");
30
+ const nodeVersion = files[".node-version"];
31
+ if (nodeVersion === void 0) throw new Error("requires tracked root .node-version");
32
+ const script = generateCloudSetup({
33
+ policy: parseToolchainPolicy(JSON.parse(await readFile(new URL("../toolchain.json", import.meta.url), "utf8"))),
34
+ cloud,
35
+ nodeVersion: nodeVersion.trim()
36
+ });
37
+ const destination = join(root, cloudSetupPath);
38
+ const parent = dirname(destination);
39
+ const parentStat = await optionalStat(parent);
40
+ if (parentStat === void 0) await mkdir(parent);
41
+ else if (parentStat.isSymbolicLink() || !parentStat.isDirectory()) throw new Error("cloud setup parent must be a real repository directory");
42
+ const destinationStat = await optionalStat(destination);
43
+ if (destinationStat !== void 0 && (destinationStat.isSymbolicLink() || !destinationStat.isFile() || destinationStat.nlink !== 1)) throw new Error("cloud setup destination must be a single-link regular repository file");
44
+ const output = await open(destination, constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW, 493);
45
+ try {
46
+ const opened = await output.stat();
47
+ if (!opened.isFile() || opened.nlink !== 1) throw new Error("cloud setup destination must be a single-link regular repository file");
48
+ await output.truncate(0);
49
+ await output.writeFile(script, "utf8");
50
+ await output.chmod(493);
51
+ } finally {
52
+ await output.close();
53
+ }
54
+ process.stdout.write(`Generated ${cloudSetupPath}\n`);
55
+ };
56
+ main().catch((error) => {
57
+ process.stderr.write(`cloud-setup: ${error instanceof Error ? error.message : String(error)}\n`);
58
+ process.exitCode = 1;
59
+ });
60
+ //#endregion
61
+ export {};
62
+
63
+ //# sourceMappingURL=cloud-setup-cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-setup-cli.mjs","names":[],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { lstat, mkdir, open, readFile, realpath } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst optionalStat = async (path: string) => {\n try {\n return await lstat(path);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n if (diagnostics.length > 0)\n throw new Error(\n diagnostics.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud } = parseToolchainConfiguration(JSON.parse(text));\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const policy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n });\n const destination = join(root, cloudSetupPath);\n const parent = dirname(destination);\n const parentStat = await optionalStat(parent);\n if (parentStat === undefined) await mkdir(parent);\n else if (parentStat.isSymbolicLink() || !parentStat.isDirectory())\n throw new Error(\"cloud setup parent must be a real repository directory\");\n const destinationStat = await optionalStat(destination);\n if (\n destinationStat !== undefined &&\n (destinationStat.isSymbolicLink() ||\n !destinationStat.isFile() ||\n destinationStat.nlink !== 1)\n )\n throw new Error(\n \"cloud setup destination must be a single-link regular repository file\",\n );\n const output = await open(\n destination,\n constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW,\n 0o755,\n );\n try {\n const opened = await output.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"cloud setup destination must be a single-link regular repository file\",\n );\n await output.truncate(0);\n await output.writeFile(script, \"utf8\");\n await output.chmod(0o755);\n } finally {\n await output.close();\n }\n process.stdout.write(`Generated ${cloudSetupPath}\\n`);\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;AAYA,MAAM,QACJ;AACF,MAAM,eAAe,OAAO,SAAiB;CAC3C,IAAI;EACF,OAAO,MAAM,MAAM,IAAI;CACzB,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;EACT,MAAM;CACR;AACF;AAEA,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,gBAAgB,oBAAoB,IAAI;CACvD,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MACR,YAAY,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACzE;CACF,MAAM,OAAO,MAAM;CACnB,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,sCAAsC;CACxD,MAAM,EAAE,UAAU,4BAA4B,KAAK,MAAM,IAAI,CAAC;CAC9D,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,wCAAwC;CAC1D,MAAM,cAAc,MAAM;CAC1B,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,qCAAqC;CAMvD,MAAM,SAAS,mBAAmB;EAChC,QANa,qBACb,KAAK,MACH,MAAM,SAAS,IAAI,IAAI,qBAAqB,OAAO,KAAK,GAAG,GAAG,MAAM,CACtE,CAGK;EACL;EACA,aAAa,YAAY,KAAK;CAChC,CAAC;CACD,MAAM,cAAc,KAAK,MAAM,cAAc;CAC7C,MAAM,SAAS,QAAQ,WAAW;CAClC,MAAM,aAAa,MAAM,aAAa,MAAM;CAC5C,IAAI,eAAe,KAAA,GAAW,MAAM,MAAM,MAAM;MAC3C,IAAI,WAAW,eAAe,KAAK,CAAC,WAAW,YAAY,GAC9D,MAAM,IAAI,MAAM,wDAAwD;CAC1E,MAAM,kBAAkB,MAAM,aAAa,WAAW;CACtD,IACE,oBAAoB,KAAA,MACnB,gBAAgB,eAAe,KAC9B,CAAC,gBAAgB,OAAO,KACxB,gBAAgB,UAAU,IAE5B,MAAM,IAAI,MACR,uEACF;CACF,MAAM,SAAS,MAAM,KACnB,aACA,UAAU,WAAW,UAAU,UAAU,UAAU,YACnD,GACF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,KAAK;EACjC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,uEACF;EACF,MAAM,OAAO,SAAS,CAAC;EACvB,MAAM,OAAO,UAAU,QAAQ,MAAM;EACrC,MAAM,OAAO,MAAM,GAAK;CAC1B,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;CACA,QAAQ,OAAO,MAAM,aAAa,eAAe,GAAG;AACtD;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACzE;CACA,QAAQ,WAAW;AACrB,CAAC"}