@stll/oxlint-config 1.3.0 → 1.4.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.
- package/README.md +254 -17
- package/dist/cloud-setup-cli.cjs +18 -38
- package/dist/cloud-setup-cli.cjs.map +1 -1
- package/dist/cloud-setup-cli.mjs +21 -41
- package/dist/cloud-setup-cli.mjs.map +1 -1
- package/dist/consumer-compat-cli.cjs +50 -249
- package/dist/consumer-compat-cli.cjs.map +1 -1
- package/dist/consumer-compat-cli.mjs +6 -205
- package/dist/consumer-compat-cli.mjs.map +1 -1
- package/dist/consumer-node-support.cjs +497 -0
- package/dist/consumer-node-support.cjs.map +1 -0
- package/dist/consumer-node-support.mjs +381 -0
- package/dist/consumer-node-support.mjs.map +1 -0
- package/dist/dependabot-cli.cjs +67 -0
- package/dist/dependabot-cli.cjs.map +1 -0
- package/dist/dependabot-cli.d.cts +1 -0
- package/dist/dependabot-cli.d.mts +1 -0
- package/dist/dependabot-cli.mjs +67 -0
- package/dist/dependabot-cli.mjs.map +1 -0
- package/dist/dependabot.cjs +5 -0
- package/dist/dependabot.d.cts +108 -0
- package/dist/dependabot.d.mts +108 -0
- package/dist/dependabot.mjs +3 -0
- package/dist/generated-file.cjs +61 -0
- package/dist/generated-file.cjs.map +1 -0
- package/dist/generated-file.mjs +44 -0
- package/dist/generated-file.mjs.map +1 -0
- package/dist/publish-artifact-syntax.cjs +1309 -0
- package/dist/publish-artifact-syntax.cjs.map +1 -0
- package/dist/publish-artifact-syntax.mjs +1265 -0
- package/dist/publish-artifact-syntax.mjs.map +1 -0
- package/dist/publish-contract-cli.cjs +53 -12
- package/dist/publish-contract-cli.cjs.map +1 -1
- package/dist/publish-contract-cli.mjs +49 -8
- package/dist/publish-contract-cli.mjs.map +1 -1
- package/dist/toolchain-changed.cjs +5 -1
- package/dist/toolchain-changed.cjs.map +1 -1
- package/dist/toolchain-changed.mjs +6 -2
- package/dist/toolchain-changed.mjs.map +1 -1
- package/dist/toolchain-dependabot.cjs +455 -0
- package/dist/toolchain-dependabot.cjs.map +1 -0
- package/dist/toolchain-dependabot.mjs +423 -0
- package/dist/toolchain-dependabot.mjs.map +1 -0
- package/dist/toolchain-guard.cjs +1096 -424
- package/dist/toolchain-guard.cjs.map +1 -1
- package/dist/toolchain-guard.mjs +1085 -413
- package/dist/toolchain-guard.mjs.map +1 -1
- package/dist/toolchain-inputs.cjs +122 -22
- package/dist/toolchain-inputs.cjs.map +1 -1
- package/dist/toolchain-inputs.mjs +117 -23
- package/dist/toolchain-inputs.mjs.map +1 -1
- package/dist/toolchain-schema.cjs +0 -493
- package/dist/toolchain-schema.cjs.map +1 -1
- package/dist/toolchain-schema.mjs +3 -379
- package/dist/toolchain-schema.mjs.map +1 -1
- package/dist/typecheck-parity.cjs +1 -1
- package/dist/typecheck-probe-cli.cjs +1 -1
- package/dist/typecheck-probe-cli.cjs.map +1 -1
- package/dist/typecheck-probe-cli.mjs +1 -1
- package/dist/typecheck-probe-cli.mjs.map +1 -1
- package/package.json +13 -1
- package/dist/publish-contract.cjs +0 -431
- package/dist/publish-contract.cjs.map +0 -1
- package/dist/publish-contract.mjs +0 -396
- package/dist/publish-contract.mjs.map +0 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
//#region src/toolchain-dependabot.d.ts
|
|
2
|
+
type DependabotPolicy = {
|
|
3
|
+
schedule: {
|
|
4
|
+
interval: string;
|
|
5
|
+
day: string;
|
|
6
|
+
time: string;
|
|
7
|
+
timezone: string;
|
|
8
|
+
};
|
|
9
|
+
cooldown: {
|
|
10
|
+
defaultDays: number;
|
|
11
|
+
};
|
|
12
|
+
groups: Record<string, {
|
|
13
|
+
patterns: readonly string[];
|
|
14
|
+
updateTypes: readonly string[];
|
|
15
|
+
}>;
|
|
16
|
+
ignoredPackages: readonly string[];
|
|
17
|
+
ignoredActions: readonly string[];
|
|
18
|
+
ignoredImages: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
type CheckDependabotOptions = {
|
|
21
|
+
files: Record<string, string>;
|
|
22
|
+
policy: DependabotPolicy;
|
|
23
|
+
};
|
|
24
|
+
/** Generate canonical YAML from the same ecosystem enumeration used by the guard. */
|
|
25
|
+
declare const generateDependabotConfig: ({ files, policy }: CheckDependabotOptions) => string;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/toolchain-schema.d.ts
|
|
28
|
+
/** Reject unsupported or incomplete installed policies before inspecting a consumer. */
|
|
29
|
+
declare const parseToolchainPolicy: (input: unknown) => {
|
|
30
|
+
bun: string;
|
|
31
|
+
typescript: string;
|
|
32
|
+
node: string;
|
|
33
|
+
postgres: string;
|
|
34
|
+
valkey: string;
|
|
35
|
+
valkeyArtifacts: {
|
|
36
|
+
amd64: {
|
|
37
|
+
server: {
|
|
38
|
+
url: string;
|
|
39
|
+
sha256: string;
|
|
40
|
+
};
|
|
41
|
+
tools: {
|
|
42
|
+
url: string;
|
|
43
|
+
sha256: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
arm64: {
|
|
47
|
+
server: {
|
|
48
|
+
url: string;
|
|
49
|
+
sha256: string;
|
|
50
|
+
};
|
|
51
|
+
tools: {
|
|
52
|
+
url: string;
|
|
53
|
+
sha256: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
consumerNode: string;
|
|
58
|
+
consumerNpm: string;
|
|
59
|
+
consumerPnpm: string;
|
|
60
|
+
consumerTypescript: string;
|
|
61
|
+
python: string;
|
|
62
|
+
rust: string;
|
|
63
|
+
packages: Record<string, string>;
|
|
64
|
+
actions: Record<string, {
|
|
65
|
+
sha: string;
|
|
66
|
+
version: string;
|
|
67
|
+
}>;
|
|
68
|
+
typescriptInstallLayouts: ({
|
|
69
|
+
readonly type: "direct";
|
|
70
|
+
readonly compilerPackage: "typescript";
|
|
71
|
+
readonly compilerSpecifier: string;
|
|
72
|
+
readonly typecheckCommand: string;
|
|
73
|
+
readonly compatibilityPackage?: never;
|
|
74
|
+
readonly compatibilitySpecifier?: never;
|
|
75
|
+
} | {
|
|
76
|
+
readonly type: "split-compatibility";
|
|
77
|
+
readonly compilerPackage: string;
|
|
78
|
+
readonly compilerSpecifier: string;
|
|
79
|
+
readonly compatibilityPackage: string;
|
|
80
|
+
readonly compatibilitySpecifier: string;
|
|
81
|
+
readonly typecheckCommand: string;
|
|
82
|
+
})[];
|
|
83
|
+
typescript6Compatibility: {
|
|
84
|
+
version: string;
|
|
85
|
+
packageAlias: string;
|
|
86
|
+
};
|
|
87
|
+
dependabot: {
|
|
88
|
+
schedule: {
|
|
89
|
+
interval: string;
|
|
90
|
+
day: string;
|
|
91
|
+
time: string;
|
|
92
|
+
timezone: string;
|
|
93
|
+
};
|
|
94
|
+
cooldown: {
|
|
95
|
+
defaultDays: number;
|
|
96
|
+
};
|
|
97
|
+
groups: Record<string, {
|
|
98
|
+
patterns: string[];
|
|
99
|
+
updateTypes: string[];
|
|
100
|
+
}>;
|
|
101
|
+
ignoredPackages: string[];
|
|
102
|
+
ignoredActions: string[];
|
|
103
|
+
ignoredImages: string[];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
//#endregion
|
|
107
|
+
export { generateDependabotConfig, parseToolchainPolicy };
|
|
108
|
+
//# sourceMappingURL=dependabot.d.cts.map
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
//#region src/toolchain-dependabot.d.ts
|
|
2
|
+
type DependabotPolicy = {
|
|
3
|
+
schedule: {
|
|
4
|
+
interval: string;
|
|
5
|
+
day: string;
|
|
6
|
+
time: string;
|
|
7
|
+
timezone: string;
|
|
8
|
+
};
|
|
9
|
+
cooldown: {
|
|
10
|
+
defaultDays: number;
|
|
11
|
+
};
|
|
12
|
+
groups: Record<string, {
|
|
13
|
+
patterns: readonly string[];
|
|
14
|
+
updateTypes: readonly string[];
|
|
15
|
+
}>;
|
|
16
|
+
ignoredPackages: readonly string[];
|
|
17
|
+
ignoredActions: readonly string[];
|
|
18
|
+
ignoredImages: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
type CheckDependabotOptions = {
|
|
21
|
+
files: Record<string, string>;
|
|
22
|
+
policy: DependabotPolicy;
|
|
23
|
+
};
|
|
24
|
+
/** Generate canonical YAML from the same ecosystem enumeration used by the guard. */
|
|
25
|
+
declare const generateDependabotConfig: ({ files, policy }: CheckDependabotOptions) => string;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/toolchain-schema.d.ts
|
|
28
|
+
/** Reject unsupported or incomplete installed policies before inspecting a consumer. */
|
|
29
|
+
declare const parseToolchainPolicy: (input: unknown) => {
|
|
30
|
+
bun: string;
|
|
31
|
+
typescript: string;
|
|
32
|
+
node: string;
|
|
33
|
+
postgres: string;
|
|
34
|
+
valkey: string;
|
|
35
|
+
valkeyArtifacts: {
|
|
36
|
+
amd64: {
|
|
37
|
+
server: {
|
|
38
|
+
url: string;
|
|
39
|
+
sha256: string;
|
|
40
|
+
};
|
|
41
|
+
tools: {
|
|
42
|
+
url: string;
|
|
43
|
+
sha256: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
arm64: {
|
|
47
|
+
server: {
|
|
48
|
+
url: string;
|
|
49
|
+
sha256: string;
|
|
50
|
+
};
|
|
51
|
+
tools: {
|
|
52
|
+
url: string;
|
|
53
|
+
sha256: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
consumerNode: string;
|
|
58
|
+
consumerNpm: string;
|
|
59
|
+
consumerPnpm: string;
|
|
60
|
+
consumerTypescript: string;
|
|
61
|
+
python: string;
|
|
62
|
+
rust: string;
|
|
63
|
+
packages: Record<string, string>;
|
|
64
|
+
actions: Record<string, {
|
|
65
|
+
sha: string;
|
|
66
|
+
version: string;
|
|
67
|
+
}>;
|
|
68
|
+
typescriptInstallLayouts: ({
|
|
69
|
+
readonly type: "direct";
|
|
70
|
+
readonly compilerPackage: "typescript";
|
|
71
|
+
readonly compilerSpecifier: string;
|
|
72
|
+
readonly typecheckCommand: string;
|
|
73
|
+
readonly compatibilityPackage?: never;
|
|
74
|
+
readonly compatibilitySpecifier?: never;
|
|
75
|
+
} | {
|
|
76
|
+
readonly type: "split-compatibility";
|
|
77
|
+
readonly compilerPackage: string;
|
|
78
|
+
readonly compilerSpecifier: string;
|
|
79
|
+
readonly compatibilityPackage: string;
|
|
80
|
+
readonly compatibilitySpecifier: string;
|
|
81
|
+
readonly typecheckCommand: string;
|
|
82
|
+
})[];
|
|
83
|
+
typescript6Compatibility: {
|
|
84
|
+
version: string;
|
|
85
|
+
packageAlias: string;
|
|
86
|
+
};
|
|
87
|
+
dependabot: {
|
|
88
|
+
schedule: {
|
|
89
|
+
interval: string;
|
|
90
|
+
day: string;
|
|
91
|
+
time: string;
|
|
92
|
+
timezone: string;
|
|
93
|
+
};
|
|
94
|
+
cooldown: {
|
|
95
|
+
defaultDays: number;
|
|
96
|
+
};
|
|
97
|
+
groups: Record<string, {
|
|
98
|
+
patterns: string[];
|
|
99
|
+
updateTypes: string[];
|
|
100
|
+
}>;
|
|
101
|
+
ignoredPackages: string[];
|
|
102
|
+
ignoredActions: string[];
|
|
103
|
+
ignoredImages: string[];
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
//#endregion
|
|
107
|
+
export { generateDependabotConfig, parseToolchainPolicy };
|
|
108
|
+
//# sourceMappingURL=dependabot.d.mts.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let node_fs = require("node:fs");
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
let node_fs_promises = require("node:fs/promises");
|
|
4
|
+
//#region src/generated-file.ts
|
|
5
|
+
const optionalStat = async (path) => {
|
|
6
|
+
try {
|
|
7
|
+
return await (0, node_fs_promises.lstat)(path);
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const checkGeneratedOutput = async (destination) => {
|
|
14
|
+
const parent = (0, node_path.dirname)(destination);
|
|
15
|
+
const parentStat = await optionalStat(parent);
|
|
16
|
+
if (parentStat !== void 0 && (parentStat.isSymbolicLink() || !parentStat.isDirectory())) throw new Error("generated output parent must be a real repository directory");
|
|
17
|
+
const destinationStat = await optionalStat(destination);
|
|
18
|
+
if (destinationStat !== void 0 && (destinationStat.isSymbolicLink() || !destinationStat.isFile() || destinationStat.nlink !== 1)) throw new Error("generated output destination must be a single-link regular repository file");
|
|
19
|
+
return destinationStat;
|
|
20
|
+
};
|
|
21
|
+
/** Only absent owned outputs may be recovered while reading tracked inputs. */
|
|
22
|
+
const generationDiagnostics = async ({ diagnostics, outputs }) => {
|
|
23
|
+
const missing = /* @__PURE__ */ new Set();
|
|
24
|
+
for (const { relative, destination } of outputs) if (await checkGeneratedOutput(destination) === void 0) missing.add(relative);
|
|
25
|
+
return diagnostics.filter(({ path }) => !missing.has(path));
|
|
26
|
+
};
|
|
27
|
+
const writeGeneratedFile = async ({ destination, text, mode }) => {
|
|
28
|
+
await checkGeneratedOutput(destination);
|
|
29
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(destination), { recursive: true });
|
|
30
|
+
const output = await (0, node_fs_promises.open)(destination, node_fs.constants.O_WRONLY | node_fs.constants.O_CREAT | node_fs.constants.O_NOFOLLOW, mode);
|
|
31
|
+
try {
|
|
32
|
+
const opened = await output.stat();
|
|
33
|
+
if (!opened.isFile() || opened.nlink !== 1) throw new Error("generated output destination must be a single-link regular repository file");
|
|
34
|
+
await output.truncate(0);
|
|
35
|
+
await output.writeFile(text, "utf8");
|
|
36
|
+
await output.chmod(mode);
|
|
37
|
+
} finally {
|
|
38
|
+
await output.close();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
Object.defineProperty(exports, "checkGeneratedOutput", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function() {
|
|
45
|
+
return checkGeneratedOutput;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "generationDiagnostics", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function() {
|
|
51
|
+
return generationDiagnostics;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "writeGeneratedFile", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function() {
|
|
57
|
+
return writeGeneratedFile;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=generated-file.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated-file.cjs","names":["lstat","dirname","mkdir","open","constants"],"sources":["../src/generated-file.ts"],"sourcesContent":["import { constants } from \"node:fs\";\nimport { lstat, mkdir, open } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\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\nexport const checkGeneratedOutput = async (destination: string) => {\n const parent = dirname(destination);\n const parentStat = await optionalStat(parent);\n if (\n parentStat !== undefined &&\n (parentStat.isSymbolicLink() || !parentStat.isDirectory())\n )\n throw new Error(\n \"generated output parent must be a real repository directory\",\n );\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 \"generated output destination must be a single-link regular repository file\",\n );\n return destinationStat;\n};\n\ntype GenerationDiagnosticsOptions = {\n diagnostics: readonly { path: string; message: string }[];\n outputs: readonly { relative: string; destination: string }[];\n};\n\n/** Only absent owned outputs may be recovered while reading tracked inputs. */\nexport const generationDiagnostics = async ({\n diagnostics,\n outputs,\n}: GenerationDiagnosticsOptions) => {\n const missing = new Set<string>();\n for (const { relative, destination } of outputs) {\n if ((await checkGeneratedOutput(destination)) === undefined)\n missing.add(relative);\n }\n return diagnostics.filter(({ path }) => !missing.has(path));\n};\n\ntype GeneratedFileOptions = {\n destination: string;\n text: string;\n mode: number;\n};\n\nexport const writeGeneratedFile = async ({\n destination,\n text,\n mode,\n}: GeneratedFileOptions) => {\n await checkGeneratedOutput(destination);\n await mkdir(dirname(destination), { recursive: true });\n const output = await open(\n destination,\n constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW,\n mode,\n );\n try {\n const opened = await output.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"generated output destination must be a single-link regular repository file\",\n );\n await output.truncate(0);\n await output.writeFile(text, \"utf8\");\n await output.chmod(mode);\n } finally {\n await output.close();\n }\n};\n"],"mappings":";;;;AAIA,MAAM,eAAe,OAAO,SAAiB;CAC3C,IAAI;EACF,OAAO,OAAA,GAAMA,iBAAAA,MAAAA,CAAM,IAAI;CACzB,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;EACT,MAAM;CACR;AACF;AAEA,MAAa,uBAAuB,OAAO,gBAAwB;CACjE,MAAM,UAAA,GAASC,UAAAA,QAAAA,CAAQ,WAAW;CAClC,MAAM,aAAa,MAAM,aAAa,MAAM;CAC5C,IACE,eAAe,KAAA,MACd,WAAW,eAAe,KAAK,CAAC,WAAW,YAAY,IAExD,MAAM,IAAI,MACR,6DACF;CACF,MAAM,kBAAkB,MAAM,aAAa,WAAW;CACtD,IACE,oBAAoB,KAAA,MACnB,gBAAgB,eAAe,KAC9B,CAAC,gBAAgB,OAAO,KACxB,gBAAgB,UAAU,IAE5B,MAAM,IAAI,MACR,4EACF;CACF,OAAO;AACT;;AAQA,MAAa,wBAAwB,OAAO,EAC1C,aACA,cACkC;CAClC,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,EAAE,UAAU,iBAAiB,SACtC,IAAK,MAAM,qBAAqB,WAAW,MAAO,KAAA,GAChD,QAAQ,IAAI,QAAQ;CAExB,OAAO,YAAY,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,IAAI,CAAC;AAC5D;AAQA,MAAa,qBAAqB,OAAO,EACvC,aACA,MACA,WAC0B;CAC1B,MAAM,qBAAqB,WAAW;CACtC,OAAA,GAAMC,iBAAAA,MAAAA,EAAAA,GAAMD,UAAAA,QAAAA,CAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;CACrD,MAAM,SAAS,OAAA,GAAME,iBAAAA,KAAAA,CACnB,aACAC,QAAAA,UAAU,WAAWA,QAAAA,UAAU,UAAUA,QAAAA,UAAU,YACnD,IACF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,KAAK;EACjC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,4EACF;EACF,MAAM,OAAO,SAAS,CAAC;EACvB,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,MAAM,OAAO,MAAM,IAAI;CACzB,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;AACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { lstat, mkdir, open } from "node:fs/promises";
|
|
4
|
+
//#region src/generated-file.ts
|
|
5
|
+
const optionalStat = async (path) => {
|
|
6
|
+
try {
|
|
7
|
+
return await lstat(path);
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return void 0;
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const checkGeneratedOutput = async (destination) => {
|
|
14
|
+
const parent = dirname(destination);
|
|
15
|
+
const parentStat = await optionalStat(parent);
|
|
16
|
+
if (parentStat !== void 0 && (parentStat.isSymbolicLink() || !parentStat.isDirectory())) throw new Error("generated output parent must be a real repository directory");
|
|
17
|
+
const destinationStat = await optionalStat(destination);
|
|
18
|
+
if (destinationStat !== void 0 && (destinationStat.isSymbolicLink() || !destinationStat.isFile() || destinationStat.nlink !== 1)) throw new Error("generated output destination must be a single-link regular repository file");
|
|
19
|
+
return destinationStat;
|
|
20
|
+
};
|
|
21
|
+
/** Only absent owned outputs may be recovered while reading tracked inputs. */
|
|
22
|
+
const generationDiagnostics = async ({ diagnostics, outputs }) => {
|
|
23
|
+
const missing = /* @__PURE__ */ new Set();
|
|
24
|
+
for (const { relative, destination } of outputs) if (await checkGeneratedOutput(destination) === void 0) missing.add(relative);
|
|
25
|
+
return diagnostics.filter(({ path }) => !missing.has(path));
|
|
26
|
+
};
|
|
27
|
+
const writeGeneratedFile = async ({ destination, text, mode }) => {
|
|
28
|
+
await checkGeneratedOutput(destination);
|
|
29
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
30
|
+
const output = await open(destination, constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW, mode);
|
|
31
|
+
try {
|
|
32
|
+
const opened = await output.stat();
|
|
33
|
+
if (!opened.isFile() || opened.nlink !== 1) throw new Error("generated output destination must be a single-link regular repository file");
|
|
34
|
+
await output.truncate(0);
|
|
35
|
+
await output.writeFile(text, "utf8");
|
|
36
|
+
await output.chmod(mode);
|
|
37
|
+
} finally {
|
|
38
|
+
await output.close();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
export { generationDiagnostics as n, writeGeneratedFile as r, checkGeneratedOutput as t };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=generated-file.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated-file.mjs","names":[],"sources":["../src/generated-file.ts"],"sourcesContent":["import { constants } from \"node:fs\";\nimport { lstat, mkdir, open } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\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\nexport const checkGeneratedOutput = async (destination: string) => {\n const parent = dirname(destination);\n const parentStat = await optionalStat(parent);\n if (\n parentStat !== undefined &&\n (parentStat.isSymbolicLink() || !parentStat.isDirectory())\n )\n throw new Error(\n \"generated output parent must be a real repository directory\",\n );\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 \"generated output destination must be a single-link regular repository file\",\n );\n return destinationStat;\n};\n\ntype GenerationDiagnosticsOptions = {\n diagnostics: readonly { path: string; message: string }[];\n outputs: readonly { relative: string; destination: string }[];\n};\n\n/** Only absent owned outputs may be recovered while reading tracked inputs. */\nexport const generationDiagnostics = async ({\n diagnostics,\n outputs,\n}: GenerationDiagnosticsOptions) => {\n const missing = new Set<string>();\n for (const { relative, destination } of outputs) {\n if ((await checkGeneratedOutput(destination)) === undefined)\n missing.add(relative);\n }\n return diagnostics.filter(({ path }) => !missing.has(path));\n};\n\ntype GeneratedFileOptions = {\n destination: string;\n text: string;\n mode: number;\n};\n\nexport const writeGeneratedFile = async ({\n destination,\n text,\n mode,\n}: GeneratedFileOptions) => {\n await checkGeneratedOutput(destination);\n await mkdir(dirname(destination), { recursive: true });\n const output = await open(\n destination,\n constants.O_WRONLY | constants.O_CREAT | constants.O_NOFOLLOW,\n mode,\n );\n try {\n const opened = await output.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"generated output destination must be a single-link regular repository file\",\n );\n await output.truncate(0);\n await output.writeFile(text, \"utf8\");\n await output.chmod(mode);\n } finally {\n await output.close();\n }\n};\n"],"mappings":";;;;AAIA,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,MAAa,uBAAuB,OAAO,gBAAwB;CACjE,MAAM,SAAS,QAAQ,WAAW;CAClC,MAAM,aAAa,MAAM,aAAa,MAAM;CAC5C,IACE,eAAe,KAAA,MACd,WAAW,eAAe,KAAK,CAAC,WAAW,YAAY,IAExD,MAAM,IAAI,MACR,6DACF;CACF,MAAM,kBAAkB,MAAM,aAAa,WAAW;CACtD,IACE,oBAAoB,KAAA,MACnB,gBAAgB,eAAe,KAC9B,CAAC,gBAAgB,OAAO,KACxB,gBAAgB,UAAU,IAE5B,MAAM,IAAI,MACR,4EACF;CACF,OAAO;AACT;;AAQA,MAAa,wBAAwB,OAAO,EAC1C,aACA,cACkC;CAClC,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,EAAE,UAAU,iBAAiB,SACtC,IAAK,MAAM,qBAAqB,WAAW,MAAO,KAAA,GAChD,QAAQ,IAAI,QAAQ;CAExB,OAAO,YAAY,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,IAAI,CAAC;AAC5D;AAQA,MAAa,qBAAqB,OAAO,EACvC,aACA,MACA,WAC0B;CAC1B,MAAM,qBAAqB,WAAW;CACtC,MAAM,MAAM,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;CACrD,MAAM,SAAS,MAAM,KACnB,aACA,UAAU,WAAW,UAAU,UAAU,UAAU,YACnD,IACF;CACA,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,KAAK;EACjC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,4EACF;EACF,MAAM,OAAO,SAAS,CAAC;EACvB,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,MAAM,OAAO,MAAM,IAAI;CACzB,UAAU;EACR,MAAM,OAAO,MAAM;CACrB;AACF"}
|