@oxiul/configs 0.0.0-stage → 0.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 +66 -2
- package/dist/bin.d.mts +1 -0
- package/dist/bin.mjs +99 -0
- package/dist/common-B9SE4GL9.mjs +11 -0
- package/dist/generate-BGCgStVl.mjs +103 -0
- package/dist/hook/install.d.mts +1 -0
- package/dist/hook/install.mjs +37 -0
- package/dist/hook/pre-commit.d.mts +1 -0
- package/dist/hook/pre-commit.mjs +51 -0
- package/dist/index-DqMadVlO.d.mts +44 -0
- package/dist/index.d.mts +168 -0
- package/dist/index.mjs +479 -0
- package/dist/parse-DnOcFJT0.mjs +14 -0
- package/dist/schema-BuCl21uv.mjs +23 -0
- package/dist/workflows/index.d.mts +2 -0
- package/dist/workflows/index.mjs +1 -0
- package/package.json +84 -5
- package/scripts/postinstall.mjs +39 -0
package/README.md
CHANGED
|
@@ -1,3 +1,67 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Configs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Lint config
|
|
4
|
+
|
|
5
|
+
A shared config for oxlint
|
|
6
|
+
|
|
7
|
+
## Format config
|
|
8
|
+
|
|
9
|
+
A shared config for oxfmt
|
|
10
|
+
|
|
11
|
+
## GitHub Actions
|
|
12
|
+
|
|
13
|
+
Configure generation in `oxiul.config.ts`:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import type { Config } from "@oxiul/configs";
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
workflows: {
|
|
20
|
+
workflows: [], // Optional { name, workflow } objects for project workflows.
|
|
21
|
+
jobs: {}, // Optional { jobName: <job> } object with CI jobs descriptions.
|
|
22
|
+
},
|
|
23
|
+
} satisfies Config;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Package.json verification
|
|
27
|
+
|
|
28
|
+
Run `oxiul verify` to require a pinned Bun version of at least 1.4.4,
|
|
29
|
+
a Node.js engine range starting at 26 or higher, and these exact scripts:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"lint": "oxlint",
|
|
34
|
+
"lint:fix": "oxlint --fix",
|
|
35
|
+
"format": "oxfmt --write",
|
|
36
|
+
"format:verify": "oxfmt --check",
|
|
37
|
+
"workflows": "oxiul workflows --verify",
|
|
38
|
+
"workflows:generate": "oxiul workflows --generate",
|
|
39
|
+
"typecheck": "bun check",
|
|
40
|
+
"deps": "knip",
|
|
41
|
+
"oxiul:verify": "oxiul verify"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Add requirements or override commands in `oxiul.config.ts`:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
export default {
|
|
49
|
+
verify: {
|
|
50
|
+
scripts: {
|
|
51
|
+
build: "bun build src/index.ts",
|
|
52
|
+
test: "*", // Required script, any command.
|
|
53
|
+
lint: "oxlint --deny-warnings",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
} satisfies Config;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Other scripts are allowed and left unchecked. Verification reads `package.json`
|
|
60
|
+
from the current directory and never modifies it.
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
### Prerequisites
|
|
65
|
+
|
|
66
|
+
- Node.js (from `engines.node` field in `package.json`)
|
|
67
|
+
- Bun (from `packageManager` field in `package.json`)
|
package/dist/bin.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/bin.mjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { t as parse } from "./parse-DnOcFJT0.mjs";
|
|
3
|
+
import { a as getDepsJob, c as getPackageJsonVerifyJob, d as getWorkflowsVerifyJob, i as getDefaultWorkflow, l as getSetupAction, o as getFormatVerifyJob, s as getLintJob, t as generateWorkflows, u as getTypecheckJob } from "./generate-BGCgStVl.mjs";
|
|
4
|
+
import { gte, subset, valid, validRange } from "semver";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { Crust, defineCommand } from "@crustjs/core";
|
|
7
|
+
import { help } from "@crustjs/extensions";
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
//#region src/schemas.ts
|
|
10
|
+
const packageJsonSchema = z.object({
|
|
11
|
+
engines: z.object({ node: z.string() }),
|
|
12
|
+
packageManager: z.string(),
|
|
13
|
+
scripts: z.record(z.string(), z.string())
|
|
14
|
+
}).partial();
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/verify/package-json.ts
|
|
17
|
+
const defaultScripts = {
|
|
18
|
+
deps: "knip",
|
|
19
|
+
format: "oxfmt --write",
|
|
20
|
+
"format:verify": "oxfmt --check",
|
|
21
|
+
lint: "oxlint",
|
|
22
|
+
"lint:fix": "oxlint --fix",
|
|
23
|
+
"oxiul:verify": "oxiul verify",
|
|
24
|
+
typecheck: "bun check",
|
|
25
|
+
workflows: "oxiul workflows --verify",
|
|
26
|
+
"workflows:generate": "oxiul workflows --generate"
|
|
27
|
+
};
|
|
28
|
+
const verifyPackageJson = (packageJson, { scripts: extraScripts, minBunVersion, minNodeVersion }) => {
|
|
29
|
+
const { scripts = {}, packageManager = "", engines: { node: nodeVersionRaw = "" } = { node: "" } } = packageJson;
|
|
30
|
+
const errors = [];
|
|
31
|
+
const bunVersion = /^bun@(?<version>[^+]+)(?:\+sha\d+\.[a-f\d]+)?$/u.exec(packageManager)?.groups?.version;
|
|
32
|
+
if (!bunVersion || !valid(bunVersion) || !gte(bunVersion, minBunVersion)) errors.push(`packageManager must pin bun@${minBunVersion} or higher`);
|
|
33
|
+
const nodeRange = validRange(nodeVersionRaw);
|
|
34
|
+
if (!nodeRange || !subset(nodeRange, `>=${minNodeVersion}`)) errors.push(`engines.node must require Node.js ${minNodeVersion} or higher`);
|
|
35
|
+
for (const [name, command] of Object.entries({
|
|
36
|
+
...defaultScripts,
|
|
37
|
+
...extraScripts
|
|
38
|
+
})) if (!scripts[name]) errors.push(`Missing script: ${name}`);
|
|
39
|
+
else if (command !== "*" && scripts[name] !== command) errors.push(`scripts[${name}] must be ${JSON.stringify(command)}`);
|
|
40
|
+
if (errors.length !== 0) throw new Error(`Package.json verification failed:\n${errors.join("\n")}`);
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/verify/bin.ts
|
|
44
|
+
const command$1 = defineCommand("verify", { description: "Verify package.json" }, (def) => def.action(async ({ stdout }) => {
|
|
45
|
+
stdout("Verifying package.json...");
|
|
46
|
+
const config = await parse();
|
|
47
|
+
const parseResult = packageJsonSchema.safeParse(JSON.parse(await readFile("package.json", "utf8")));
|
|
48
|
+
if (!parseResult.success) throw new Error(`Invalid package.json: ${parseResult.error.message}`);
|
|
49
|
+
verifyPackageJson(parseResult.data, config.verify);
|
|
50
|
+
stdout("package.json verified successfully!");
|
|
51
|
+
}));
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/workflows/bin.ts
|
|
54
|
+
const command = defineCommand("workflows", { description: "Workflows" }, (def) => def.flags({
|
|
55
|
+
name: "verify",
|
|
56
|
+
short: "r",
|
|
57
|
+
type: "boolean"
|
|
58
|
+
}).flags({
|
|
59
|
+
name: "generate",
|
|
60
|
+
short: "g",
|
|
61
|
+
type: "boolean"
|
|
62
|
+
}).action(async ({ flags, stdout }) => {
|
|
63
|
+
const config = await parse();
|
|
64
|
+
const options = {
|
|
65
|
+
actions: { "setup-env": getSetupAction() },
|
|
66
|
+
workflows: [getDefaultWorkflow({
|
|
67
|
+
jobs: {
|
|
68
|
+
deps: getDepsJob(),
|
|
69
|
+
format: getFormatVerifyJob(),
|
|
70
|
+
lint: getLintJob(),
|
|
71
|
+
typecheck: getTypecheckJob(),
|
|
72
|
+
verify: getPackageJsonVerifyJob(),
|
|
73
|
+
workflows: getWorkflowsVerifyJob(),
|
|
74
|
+
...config.workflows?.jobs
|
|
75
|
+
},
|
|
76
|
+
name: "CI"
|
|
77
|
+
}), ...config.workflows?.workflows ?? []]
|
|
78
|
+
};
|
|
79
|
+
if (flags.generate) {
|
|
80
|
+
stdout(`Generating the workflows..`);
|
|
81
|
+
await generateWorkflows({
|
|
82
|
+
...options,
|
|
83
|
+
check: false
|
|
84
|
+
});
|
|
85
|
+
stdout(`Workflows generated successfully!`);
|
|
86
|
+
} else {
|
|
87
|
+
stdout(`Verifying the workflows..`);
|
|
88
|
+
await generateWorkflows({
|
|
89
|
+
...options,
|
|
90
|
+
check: true
|
|
91
|
+
});
|
|
92
|
+
stdout(`Workflows verified successfully!`);
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/bin.ts
|
|
97
|
+
await new Crust("oxiul", { description: "Oxiul runner" }).add(command$1).add(command).extend(help()).execute();
|
|
98
|
+
//#endregion
|
|
99
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/common.ts
|
|
2
|
+
const baseIgnorePatterns = [
|
|
3
|
+
".history/",
|
|
4
|
+
"bun.lock",
|
|
5
|
+
"**/*.gen.ts"
|
|
6
|
+
];
|
|
7
|
+
const arraify = (input) => input === void 0 ? [] : Array.isArray(input) ? input : [input];
|
|
8
|
+
const moduleName = "oxiul";
|
|
9
|
+
const packageName = "@oxiul/configs";
|
|
10
|
+
//#endregion
|
|
11
|
+
export { packageName as i, baseIgnorePatterns as n, moduleName as r, arraify as t };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { stringify } from "yaml";
|
|
4
|
+
//#region src/workflows/default.ts
|
|
5
|
+
const DEFAULT_MACHINE = "ubuntu-26.04";
|
|
6
|
+
const getSetupAction = () => ({
|
|
7
|
+
description: "Setup runtime",
|
|
8
|
+
name: "Runtime setup",
|
|
9
|
+
runs: {
|
|
10
|
+
steps: [
|
|
11
|
+
{
|
|
12
|
+
name: "Setup Node.js",
|
|
13
|
+
uses: "actions/setup-node@v7",
|
|
14
|
+
with: { "node-version-file": "package.json" }
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "Setup Bun",
|
|
18
|
+
uses: "oven-sh/setup-bun@v2",
|
|
19
|
+
with: { "bun-version-file": "package.json" }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "Install dependencies",
|
|
23
|
+
run: "bun install --frozen-lockfile",
|
|
24
|
+
shell: "bash"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
using: "composite"
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const getDefaultWorkflow = ({ concurrency, on, name = "Default workflow", ...rest }) => ({
|
|
31
|
+
concurrency: {
|
|
32
|
+
"cancel-in-progress": true,
|
|
33
|
+
group: "${{ github.workflow }}-${{ github.ref }}",
|
|
34
|
+
...concurrency
|
|
35
|
+
},
|
|
36
|
+
name,
|
|
37
|
+
on: {
|
|
38
|
+
pull_request: {},
|
|
39
|
+
push: { branches: ["main"] },
|
|
40
|
+
workflow_dispatch: {},
|
|
41
|
+
...on
|
|
42
|
+
},
|
|
43
|
+
...rest
|
|
44
|
+
});
|
|
45
|
+
const getCheckJob = ({ "runs-on": runsOn = DEFAULT_MACHINE, steps, overrideSteps = false, ...rest }) => ({
|
|
46
|
+
"runs-on": runsOn,
|
|
47
|
+
steps: overrideSteps ? steps : [
|
|
48
|
+
{ uses: "actions/checkout@v7" },
|
|
49
|
+
{ uses: "./.github/actions/setup-env" },
|
|
50
|
+
...steps
|
|
51
|
+
],
|
|
52
|
+
...rest
|
|
53
|
+
});
|
|
54
|
+
const getFormatVerifyJob = () => getCheckJob({
|
|
55
|
+
name: "Format verification",
|
|
56
|
+
steps: [{ run: "bun run format:verify" }]
|
|
57
|
+
});
|
|
58
|
+
const getDepsJob = () => getCheckJob({
|
|
59
|
+
name: "Dependencies check",
|
|
60
|
+
steps: [{ run: "bun run deps" }]
|
|
61
|
+
});
|
|
62
|
+
const getTypecheckJob = () => getCheckJob({
|
|
63
|
+
name: "Typecheck",
|
|
64
|
+
steps: [{ run: "bun run typecheck" }]
|
|
65
|
+
});
|
|
66
|
+
const getLintJob = () => getCheckJob({
|
|
67
|
+
name: "Lint",
|
|
68
|
+
steps: [{ run: "bun run lint" }]
|
|
69
|
+
});
|
|
70
|
+
const getWorkflowsVerifyJob = () => getCheckJob({
|
|
71
|
+
name: "Workflows verification",
|
|
72
|
+
steps: [{ run: "bun run workflows" }]
|
|
73
|
+
});
|
|
74
|
+
const getPackageJsonVerifyJob = () => getCheckJob({
|
|
75
|
+
name: "Package.json verification",
|
|
76
|
+
steps: [{ run: "bun run oxiul:verify" }]
|
|
77
|
+
});
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/workflows/generate.ts
|
|
80
|
+
const generateWorkflows = async ({ workflows = [], actions = {}, directory = ".", check = false }) => {
|
|
81
|
+
const files = /* @__PURE__ */ new Map();
|
|
82
|
+
const addFile = (name, filePath, value) => {
|
|
83
|
+
if (!name || !/^[\w-]+$/u.test(name)) throw new Error(`Invalid generated file name: ${name}`);
|
|
84
|
+
if (files.has(filePath)) throw new Error(`Duplicate generated file: ${filePath}`);
|
|
85
|
+
files.set(filePath, `# Generated by @oxiul/configs/workflows. Do not edit.\n${stringify(value, { lineWidth: 0 })}`);
|
|
86
|
+
};
|
|
87
|
+
for (const workflow of workflows) addFile(workflow.name, `.github/workflows/${workflow.name.toLowerCase()}.yml`, workflow);
|
|
88
|
+
for (const [name, action] of Object.entries(actions)) addFile(name, `.github/actions/${name}/action.yml`, action);
|
|
89
|
+
for (const [filePath, content] of files) {
|
|
90
|
+
const target = path.resolve(directory, filePath);
|
|
91
|
+
if (check) {
|
|
92
|
+
if (await readFile(target, "utf8").catch((error) => {
|
|
93
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
|
|
94
|
+
throw error;
|
|
95
|
+
}) !== content) throw new Error(`Generated file is out of date: ${filePath}`);
|
|
96
|
+
} else {
|
|
97
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
98
|
+
await writeFile(target, content);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
103
|
+
export { getDepsJob as a, getPackageJsonVerifyJob as c, getWorkflowsVerifyJob as d, getDefaultWorkflow as i, getSetupAction as l, DEFAULT_MACHINE as n, getFormatVerifyJob as o, getCheckJob as r, getLintJob as s, generateWorkflows as t, getTypecheckJob as u };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { i as packageName } from "../common-B9SE4GL9.mjs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { exec } from "node:child_process";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
//#region src/hook/install.ts
|
|
7
|
+
const promisifiedExec = promisify(exec);
|
|
8
|
+
const { stdout: rawGitRepositoryRoot } = await promisifiedExec("git rev-parse --show-toplevel");
|
|
9
|
+
const gitRepositoryRoot = rawGitRepositoryRoot.trim();
|
|
10
|
+
const { stdout: rawHooksDirectory } = await promisifiedExec("git rev-parse --path-format=absolute --git-path hooks");
|
|
11
|
+
const hooksDirectory = rawHooksDirectory.trim();
|
|
12
|
+
const packageJson = await fs.readFile(path.join(gitRepositoryRoot, "package.json"), "utf8");
|
|
13
|
+
const { name } = JSON.parse(packageJson);
|
|
14
|
+
const HOOK_CONTENT = ["#!/bin/bash", `node ${name === "@oxiul/configs" ? "." : `./node_modules/${packageName}`}/dist/hook/pre-commit.mjs`].join("\n");
|
|
15
|
+
await fs.mkdir(hooksDirectory, { recursive: true });
|
|
16
|
+
const preCommitPath = path.join(hooksDirectory, "pre-commit");
|
|
17
|
+
let oldHook = "";
|
|
18
|
+
if (await fs.stat(preCommitPath).then(() => true).catch(() => false)) {
|
|
19
|
+
if ((await fs.lstat(preCommitPath)).isSymbolicLink()) {
|
|
20
|
+
console.log("Detected an existing git pre-commit hook");
|
|
21
|
+
await fs.unlink(preCommitPath);
|
|
22
|
+
} else {
|
|
23
|
+
oldHook = await fs.readFile(preCommitPath, "utf8");
|
|
24
|
+
if (oldHook !== HOOK_CONTENT) {
|
|
25
|
+
console.log(`Found hooks path: "${hooksDirectory}"`);
|
|
26
|
+
console.log("Detected an existing git pre-commit hook");
|
|
27
|
+
await fs.writeFile(`${preCommitPath}.old`, oldHook);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (oldHook !== HOOK_CONTENT) {
|
|
32
|
+
console.log(`Found hooks path: "${hooksDirectory}"`);
|
|
33
|
+
await fs.writeFile(preCommitPath, HOOK_CONTENT, { mode: 493 });
|
|
34
|
+
console.log("Hook saved");
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { t as parse } from "../parse-DnOcFJT0.mjs";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { Listr } from "listr2";
|
|
4
|
+
//#region src/hook/pre-commit.ts
|
|
5
|
+
const failedOutputs = /* @__PURE__ */ new Map();
|
|
6
|
+
const run = (command, task) => new Promise((resolve, reject) => {
|
|
7
|
+
const child = spawn(command, {
|
|
8
|
+
env: {
|
|
9
|
+
...process.env,
|
|
10
|
+
FORCE_COLOR: "1"
|
|
11
|
+
},
|
|
12
|
+
shell: true,
|
|
13
|
+
stdio: [
|
|
14
|
+
"ignore",
|
|
15
|
+
"pipe",
|
|
16
|
+
"pipe"
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
const window = task.stdout();
|
|
20
|
+
let output = "";
|
|
21
|
+
const onData = (chunk) => {
|
|
22
|
+
output += chunk;
|
|
23
|
+
window.write(chunk);
|
|
24
|
+
};
|
|
25
|
+
child.stdout.on("data", onData);
|
|
26
|
+
child.stderr.on("data", onData);
|
|
27
|
+
child.on("error", reject);
|
|
28
|
+
child.on("close", (code, signal) => {
|
|
29
|
+
if (code === 0) return resolve();
|
|
30
|
+
failedOutputs.set(command, output);
|
|
31
|
+
reject(/* @__PURE__ */ new Error(signal ? `killed by ${signal}` : `exited with code ${code}`));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
try {
|
|
35
|
+
const config = await parse();
|
|
36
|
+
if (config.preCommitCommands && config.preCommitCommands.length !== 0) await new Listr(config.preCommitCommands.map((command) => ({
|
|
37
|
+
rendererOptions: {
|
|
38
|
+
outputBar: 5,
|
|
39
|
+
persistentOutput: false
|
|
40
|
+
},
|
|
41
|
+
task: (_ctx, task) => run(command, task),
|
|
42
|
+
title: command
|
|
43
|
+
})), { concurrent: false }).run();
|
|
44
|
+
else console.log(`No commands in pre-commit list found`);
|
|
45
|
+
} catch {
|
|
46
|
+
for (const [command, output] of failedOutputs) console.error(`\n✖ Output of "${command}"\n${output}`);
|
|
47
|
+
console.error(`${failedOutputs.size} tasks failed: ${[...failedOutputs.keys()].join(", ")}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GeneratedWorkflowTypes, GeneratedWorkflowTypes as GeneratedWorkflowTypes$1 } from "@github-actions-workflow-ts/lib";
|
|
2
|
+
//#region src/workflows/types.d.ts
|
|
3
|
+
type CompositeAction = {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
runs: {
|
|
7
|
+
using: "composite";
|
|
8
|
+
steps: GeneratedWorkflowTypes.Step[];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
type Workflow = GeneratedWorkflowTypes.Workflow;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/workflows/default.d.ts
|
|
14
|
+
declare const DEFAULT_MACHINE = "ubuntu-26.04";
|
|
15
|
+
declare const getSetupAction: () => CompositeAction;
|
|
16
|
+
declare const getDefaultWorkflow: ({ concurrency, on, name, ...rest }: Omit<GeneratedWorkflowTypes.Workflow, "on" | "concurrency"> & {
|
|
17
|
+
on?: Exclude<GeneratedWorkflowTypes.Workflow["on"], GeneratedWorkflowTypes.Event | GeneratedWorkflowTypes.Event[]>;
|
|
18
|
+
concurrency?: Exclude<GeneratedWorkflowTypes.Workflow["concurrency"], string>;
|
|
19
|
+
}) => Omit<GeneratedWorkflowTypes.Workflow, "name"> & {
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
declare const getCheckJob: ({ "runs-on": runsOn, steps, overrideSteps, ...rest }: Omit<GeneratedWorkflowTypes.NormalJob, "runs-on"> & {
|
|
23
|
+
overrideSteps?: boolean;
|
|
24
|
+
"runs-on"?: GeneratedWorkflowTypes.NormalJob["runs-on"];
|
|
25
|
+
steps: Exclude<GeneratedWorkflowTypes.NormalJob["steps"], undefined>;
|
|
26
|
+
}) => GeneratedWorkflowTypes.NormalJob;
|
|
27
|
+
declare const getFormatVerifyJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
28
|
+
declare const getDepsJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
29
|
+
declare const getTypecheckJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
30
|
+
declare const getLintJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
31
|
+
declare const getWorkflowsVerifyJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
32
|
+
declare const getPackageJsonVerifyJob: () => GeneratedWorkflowTypes.NormalJob;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/workflows/generate.d.ts
|
|
35
|
+
declare const generateWorkflows: ({ workflows, actions, directory, check }: {
|
|
36
|
+
workflows?: (Omit<GeneratedWorkflowTypes.Workflow, "name"> & {
|
|
37
|
+
name: string;
|
|
38
|
+
})[];
|
|
39
|
+
actions?: Record<string, CompositeAction>;
|
|
40
|
+
directory?: string;
|
|
41
|
+
check?: boolean;
|
|
42
|
+
}) => Promise<void>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { getDefaultWorkflow as a, getLintJob as c, getTypecheckJob as d, getWorkflowsVerifyJob as f, getCheckJob as i, getPackageJsonVerifyJob as l, Workflow as m, generateWorkflows as n, getDepsJob as o, CompositeAction as p, DEFAULT_MACHINE as r, getFormatVerifyJob as s, GeneratedWorkflowTypes$1 as t, getSetupAction as u };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { t as GeneratedWorkflowTypes } from "./index-DqMadVlO.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { OxlintConfig } from "oxlint";
|
|
4
|
+
import { OxfmtConfig } from "oxfmt";
|
|
5
|
+
import { KnipConfig } from "knip";
|
|
6
|
+
//#region src/oxlint.d.ts
|
|
7
|
+
export declare const disabledRules: OxlintConfig["rules"];
|
|
8
|
+
export declare const overridenRules: OxlintConfig["rules"];
|
|
9
|
+
type MergableConfig$1 = Omit<OxlintConfig, "plugins"> & {
|
|
10
|
+
plugins?: Partial<Record<NonNullable<OxlintConfig["plugins"]>[number], boolean>>;
|
|
11
|
+
};
|
|
12
|
+
type TailwindConfig = {
|
|
13
|
+
entryPoint: string;
|
|
14
|
+
};
|
|
15
|
+
type VitestConfig = {
|
|
16
|
+
files?: string[];
|
|
17
|
+
};
|
|
18
|
+
type TanstackRouterConfig = {
|
|
19
|
+
routes: string[];
|
|
20
|
+
};
|
|
21
|
+
type PackageJsonConfig = boolean;
|
|
22
|
+
type PlaywrightConfig = {
|
|
23
|
+
files: string[];
|
|
24
|
+
assertFunctionNames?: string[];
|
|
25
|
+
};
|
|
26
|
+
type ServerSideConfig = {
|
|
27
|
+
files: string[];
|
|
28
|
+
allowConsole?: string[];
|
|
29
|
+
allowProcess?: string[];
|
|
30
|
+
};
|
|
31
|
+
type RestrictedSyntaxRule = {
|
|
32
|
+
selector: string;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
type RestrictedSyntaxOverride = {
|
|
36
|
+
files: string[];
|
|
37
|
+
rules: RestrictedSyntaxRule[];
|
|
38
|
+
};
|
|
39
|
+
type RestrictedSyntaxConfig = {
|
|
40
|
+
banBarrelImport?: boolean;
|
|
41
|
+
banReactMemo?: boolean;
|
|
42
|
+
overrides?: RestrictedSyntaxOverride[];
|
|
43
|
+
rulesOverrides?: RestrictedSyntaxRule[];
|
|
44
|
+
previousRules?: RestrictedSyntaxRule[];
|
|
45
|
+
previousOverrides?: RestrictedSyntaxOverride[];
|
|
46
|
+
};
|
|
47
|
+
type RestrictedConfig = {
|
|
48
|
+
globals?: {
|
|
49
|
+
name: string;
|
|
50
|
+
message: string;
|
|
51
|
+
}[];
|
|
52
|
+
properties?: {
|
|
53
|
+
object: string;
|
|
54
|
+
property: string;
|
|
55
|
+
message: string;
|
|
56
|
+
}[];
|
|
57
|
+
syntaxOverrides?: RestrictedSyntaxConfig["overrides"];
|
|
58
|
+
syntaxRulesOverrides?: RestrictedSyntaxConfig["rulesOverrides"];
|
|
59
|
+
};
|
|
60
|
+
type ReactConfig = {
|
|
61
|
+
allowedStrings?: string[];
|
|
62
|
+
additionalHooks?: string[];
|
|
63
|
+
banMemo?: boolean;
|
|
64
|
+
};
|
|
65
|
+
type I18nConfig = {
|
|
66
|
+
ignore?: string[] | true;
|
|
67
|
+
};
|
|
68
|
+
type ImportConfig = {
|
|
69
|
+
allowDefault?: string[];
|
|
70
|
+
banBarrel?: boolean;
|
|
71
|
+
};
|
|
72
|
+
type ConfigOptions$2 = {
|
|
73
|
+
jsPlugins?: Exclude<OxlintConfig["jsPlugins"], null>;
|
|
74
|
+
plugins?: MergableConfig$1["plugins"];
|
|
75
|
+
tailwind?: TailwindConfig;
|
|
76
|
+
vitest?: VitestConfig;
|
|
77
|
+
tanstackRouter?: TanstackRouterConfig;
|
|
78
|
+
packageJson?: PackageJsonConfig;
|
|
79
|
+
playwright?: PlaywrightConfig;
|
|
80
|
+
serverSide?: ServerSideConfig;
|
|
81
|
+
restricted?: RestrictedConfig;
|
|
82
|
+
react?: ReactConfig;
|
|
83
|
+
i18n?: I18nConfig;
|
|
84
|
+
import?: ImportConfig;
|
|
85
|
+
} & Pick<OxlintConfig, "env" | "rules" | "options" | "ignorePatterns" | "categories" | "settings" | "overrides" | "globals"> & ReactConfig;
|
|
86
|
+
declare const getConfig$2: ({ tailwind, tanstackRouter, vitest, packageJson, playwright, serverSide, restricted, react, i18n, import: importOptions, ...config }?: ConfigOptions$2) => Promise<OxlintConfig>;
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/oxfmt.d.ts
|
|
89
|
+
type ConfigOptions$1 = OxfmtConfig & {
|
|
90
|
+
tailwind?: {
|
|
91
|
+
stylesheet: string;
|
|
92
|
+
functions?: string[];
|
|
93
|
+
};
|
|
94
|
+
imports?: Exclude<OxfmtConfig["sortImports"], boolean>;
|
|
95
|
+
};
|
|
96
|
+
declare const getConfig: ({ ignorePatterns, tailwind, imports, sortImports, ...rest }?: ConfigOptions$1) => Promise<{
|
|
97
|
+
readonly arrowParens?: import("oxfmt").ArrowParensConfig;
|
|
98
|
+
readonly associations?: import("oxfmt").OxfmtAssociationConfig[];
|
|
99
|
+
astro: import("oxfmt").AstroUserConfig;
|
|
100
|
+
readonly bracketSameLine?: boolean;
|
|
101
|
+
readonly bracketSpacing?: boolean;
|
|
102
|
+
readonly embeddedLanguageFormatting?: import("oxfmt").EmbeddedLanguageFormattingConfig;
|
|
103
|
+
readonly endOfLine?: import("oxfmt").EndOfLineConfig;
|
|
104
|
+
readonly experimentalOperatorPosition?: import("oxfmt").OperatorPositionConfig;
|
|
105
|
+
readonly htmlWhitespaceSensitivity?: import("oxfmt").HtmlWhitespaceSensitivityConfig;
|
|
106
|
+
readonly insertFinalNewline?: boolean;
|
|
107
|
+
readonly jsdoc?: import("oxfmt").JsdocUserConfig;
|
|
108
|
+
readonly jsxSingleQuote?: boolean;
|
|
109
|
+
readonly objectWrap?: import("oxfmt").ObjectWrapConfig;
|
|
110
|
+
readonly overrides?: import("oxfmt").OxfmtOverrideConfig[];
|
|
111
|
+
printWidth: number;
|
|
112
|
+
readonly proseWrap?: import("oxfmt").ProseWrapConfig;
|
|
113
|
+
readonly quoteProps?: import("oxfmt").QuotePropsConfig;
|
|
114
|
+
readonly semi?: boolean;
|
|
115
|
+
readonly singleAttributePerLine?: boolean;
|
|
116
|
+
readonly singleQuote?: boolean;
|
|
117
|
+
sortPackageJson: boolean | import("oxfmt").SortPackageJsonConfig | {
|
|
118
|
+
readonly sortScripts: true;
|
|
119
|
+
};
|
|
120
|
+
sortTailwindcss: import("oxfmt").SortTailwindcssUserConfig;
|
|
121
|
+
readonly svelte?: import("oxfmt").SvelteUserConfig;
|
|
122
|
+
readonly tabWidth?: number;
|
|
123
|
+
readonly trailingComma?: import("oxfmt").TrailingCommaConfig;
|
|
124
|
+
useTabs: boolean;
|
|
125
|
+
readonly vueIndentScriptAndStyle?: boolean;
|
|
126
|
+
readonly ignorePatterns: string[];
|
|
127
|
+
readonly sortImports: import("oxfmt").SortImportsUserConfig;
|
|
128
|
+
}>;
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/knip.d.ts
|
|
131
|
+
type KnipConfig$1 = Exclude<KnipConfig, Function>;
|
|
132
|
+
type MergableConfig = Omit<KnipConfig$1, "include"> & {
|
|
133
|
+
include?: Partial<Record<NonNullable<KnipConfig$1["include"]>[number], boolean>>;
|
|
134
|
+
};
|
|
135
|
+
type BaseOptions = {
|
|
136
|
+
vitest?: boolean;
|
|
137
|
+
reactNative?: boolean;
|
|
138
|
+
opencode?: boolean;
|
|
139
|
+
eslint?: boolean;
|
|
140
|
+
workspaces?: boolean;
|
|
141
|
+
};
|
|
142
|
+
type ConfigOptions = {
|
|
143
|
+
options?: BaseOptions;
|
|
144
|
+
} & MergableConfig;
|
|
145
|
+
declare const getConfig$1: ({ options, ...overrides }?: ConfigOptions) => Promise<KnipConfig$1>;
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/config/schema.d.ts
|
|
148
|
+
export declare const configSchema: z.ZodObject<{
|
|
149
|
+
preCommitCommands: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
150
|
+
verify: z.ZodDefault<z.ZodObject<{
|
|
151
|
+
minBunVersion: z.ZodDefault<z.ZodString>;
|
|
152
|
+
minNodeVersion: z.ZodDefault<z.ZodString>;
|
|
153
|
+
scripts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
154
|
+
}, z.core.$strip>>;
|
|
155
|
+
workflows: z.ZodOptional<z.ZodObject<{
|
|
156
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
157
|
+
jobs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<GeneratedWorkflowTypes.NormalJob, GeneratedWorkflowTypes.NormalJob>>>;
|
|
158
|
+
workflows: z.ZodOptional<z.ZodArray<z.ZodCustom<Omit<GeneratedWorkflowTypes.Workflow, "name"> & {
|
|
159
|
+
name: string;
|
|
160
|
+
}, Omit<GeneratedWorkflowTypes.Workflow, "name"> & {
|
|
161
|
+
name: string;
|
|
162
|
+
}>>>;
|
|
163
|
+
}, z.core.$strip>>;
|
|
164
|
+
}, z.core.$strip>;
|
|
165
|
+
type ConfigInput = z.input<typeof configSchema>;
|
|
166
|
+
type ConfigOutput = z.output<typeof configSchema>;
|
|
167
|
+
//#endregion
|
|
168
|
+
export { type ConfigInput as Config, type ConfigOutput, getConfig as getFormatConfig, getConfig$1 as getKnipConfig, getConfig$2 as getLintConfig };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import { n as baseIgnorePatterns, t as arraify } from "./common-B9SE4GL9.mjs";
|
|
2
|
+
import { t as configSchema } from "./schema-BuCl21uv.mjs";
|
|
3
|
+
import { isNonNullish, mapValues, omitBy } from "remeda";
|
|
4
|
+
//#region src/oxlint.ts
|
|
5
|
+
const disabledRules = {
|
|
6
|
+
"eslint/capitalized-comments": "off",
|
|
7
|
+
"eslint/default-case": "off",
|
|
8
|
+
"eslint/id-length": "off",
|
|
9
|
+
"eslint/max-lines": "off",
|
|
10
|
+
"eslint/max-lines-per-function": "off",
|
|
11
|
+
"eslint/max-params": "off",
|
|
12
|
+
"eslint/max-statements": "off",
|
|
13
|
+
"eslint/no-await-in-loop": "off",
|
|
14
|
+
"eslint/no-continue": "off",
|
|
15
|
+
"eslint/no-duplicate-imports": "off",
|
|
16
|
+
"eslint/no-inline-comments": "off",
|
|
17
|
+
"eslint/no-nested-ternary": "off",
|
|
18
|
+
"eslint/no-ternary": "off",
|
|
19
|
+
"eslint/no-undefined": "off",
|
|
20
|
+
"eslint/no-warning-comments": "off",
|
|
21
|
+
"eslint/one-var": "off",
|
|
22
|
+
"eslint/require-await": "off",
|
|
23
|
+
"import/exports-last": "off",
|
|
24
|
+
"import/group-exports": "off",
|
|
25
|
+
"import/max-dependencies": "off",
|
|
26
|
+
"import/no-named-export": "off",
|
|
27
|
+
"import/no-namespace": "off",
|
|
28
|
+
"import/no-unassigned-import": "off",
|
|
29
|
+
"import/prefer-default-export": "off",
|
|
30
|
+
"import/unambiguous": "off",
|
|
31
|
+
"oxc/no-accumulating-spread": "off",
|
|
32
|
+
"oxc/no-async-await": "off",
|
|
33
|
+
"oxc/no-map-spread": "off",
|
|
34
|
+
"oxc/no-optional-chaining": "off",
|
|
35
|
+
"oxc/no-rest-spread-properties": "off",
|
|
36
|
+
"promise/avoid-new": "off",
|
|
37
|
+
"promise/prefer-await-to-callbacks": "off",
|
|
38
|
+
"promise/prefer-await-to-then": "off",
|
|
39
|
+
"react-perf/jsx-no-jsx-as-prop": "off",
|
|
40
|
+
"react-perf/jsx-no-new-array-as-prop": "off",
|
|
41
|
+
"react-perf/jsx-no-new-function-as-prop": "off",
|
|
42
|
+
"react-perf/jsx-no-new-object-as-prop": "off",
|
|
43
|
+
"react/display-name": "off",
|
|
44
|
+
"react/forbid-component-props": "off",
|
|
45
|
+
"react/jsx-filename-extension": "off",
|
|
46
|
+
"react/jsx-handler-names": "off",
|
|
47
|
+
"react/jsx-max-depth": "off",
|
|
48
|
+
"react/jsx-props-no-spreading": "off",
|
|
49
|
+
"react/no-multi-comp": "off",
|
|
50
|
+
"react/only-export-components": "off",
|
|
51
|
+
"react/react-in-jsx-scope": "off",
|
|
52
|
+
"react/rule-suppression": "off",
|
|
53
|
+
"typescript/consistent-return": "off",
|
|
54
|
+
"typescript/explicit-function-return-type": "off",
|
|
55
|
+
"typescript/explicit-module-boundary-types": "off",
|
|
56
|
+
"typescript/no-confusing-void-expression": "off",
|
|
57
|
+
"typescript/no-dynamic-delete": "off",
|
|
58
|
+
"typescript/no-invalid-void-type": "off",
|
|
59
|
+
"typescript/no-unnecessary-type-parameters": "off",
|
|
60
|
+
"typescript/no-unsafe-type-assertion": "off",
|
|
61
|
+
"typescript/prefer-nullish-coalescing": "off",
|
|
62
|
+
"typescript/prefer-readonly-parameter-types": "off",
|
|
63
|
+
"typescript/promise-function-async": "off",
|
|
64
|
+
"unicorn/no-array-callback-reference": "off",
|
|
65
|
+
"unicorn/no-array-reduce": "off",
|
|
66
|
+
"unicorn/no-nested-ternary": "off",
|
|
67
|
+
"unicorn/no-null": "off",
|
|
68
|
+
"unicorn/no-useless-undefined": "off",
|
|
69
|
+
"unicorn/number-literal-case": "off",
|
|
70
|
+
"unicorn/prefer-global-this": "off",
|
|
71
|
+
"unicorn/prefer-spread": "off",
|
|
72
|
+
"vitest/max-expects": "off",
|
|
73
|
+
"vitest/no-conditional-in-test": "off",
|
|
74
|
+
"vitest/no-hooks": "off",
|
|
75
|
+
"vitest/no-importing-vitest-globals": "off",
|
|
76
|
+
"vitest/no-standalone-expect": "off",
|
|
77
|
+
"vitest/prefer-called-once": "off",
|
|
78
|
+
"vitest/prefer-expect-assertions": "off",
|
|
79
|
+
"vitest/prefer-importing-vitest-globals": "off",
|
|
80
|
+
"vitest/prefer-lowercase-title": "off",
|
|
81
|
+
"vitest/prefer-to-be": "off",
|
|
82
|
+
"vitest/prefer-to-be-falsy": "off",
|
|
83
|
+
"vitest/prefer-to-be-truthy": "off",
|
|
84
|
+
"vitest/require-hook": "off",
|
|
85
|
+
"vitest/require-test-timeout": "off"
|
|
86
|
+
};
|
|
87
|
+
const disabledTailwindRules = {
|
|
88
|
+
"better-tailwindcss/enforce-consistent-class-order": "off",
|
|
89
|
+
"better-tailwindcss/enforce-consistent-line-wrapping": "off"
|
|
90
|
+
};
|
|
91
|
+
const overridenRules = {
|
|
92
|
+
"eslint/no-magic-numbers": ["error", { ignore: [
|
|
93
|
+
0,
|
|
94
|
+
1,
|
|
95
|
+
-1
|
|
96
|
+
] }],
|
|
97
|
+
"eslint/no-void": ["error", { allowAsStatement: true }],
|
|
98
|
+
"eslint/sort-imports": ["error", { ignoreDeclarationSort: true }],
|
|
99
|
+
"react/function-component-definition": ["error", {
|
|
100
|
+
namedComponents: "arrow-function",
|
|
101
|
+
unnamedComponents: "arrow-function"
|
|
102
|
+
}],
|
|
103
|
+
"react/jsx-no-useless-fragment": ["error", { allowExpressions: true }],
|
|
104
|
+
"typescript/consistent-type-definitions": ["error", "type"],
|
|
105
|
+
"typescript/no-misused-promises": ["error", { checksVoidReturn: {
|
|
106
|
+
arguments: false,
|
|
107
|
+
attributes: false
|
|
108
|
+
} }],
|
|
109
|
+
"typescript/no-unnecessary-condition": ["error", { allowConstantLoopConditions: true }],
|
|
110
|
+
"typescript/restrict-template-expressions": ["error", { allowNumber: true }],
|
|
111
|
+
"typescript/strict-boolean-expressions": ["error", {
|
|
112
|
+
allowNullableBoolean: true,
|
|
113
|
+
allowNullableNumber: true,
|
|
114
|
+
allowNullableString: true,
|
|
115
|
+
allowNumber: true,
|
|
116
|
+
allowString: true
|
|
117
|
+
}],
|
|
118
|
+
"typescript/switch-exhaustiveness-check": ["error", { considerDefaultExhaustiveForUnions: true }],
|
|
119
|
+
"unicorn/explicit-length-check": ["error", { "non-zero": "not-equal" }],
|
|
120
|
+
"unicorn/max-nested-calls": ["error", { max: 5 }],
|
|
121
|
+
"unicorn/switch-case-braces": ["error", "avoid"],
|
|
122
|
+
"vitest/consistent-test-it": ["error", { fn: "test" }]
|
|
123
|
+
};
|
|
124
|
+
const mergeConfigs$1 = (...configs) => configs.reduce(({ categories, env, globals, ignorePatterns, jsPlugins, options, overrides, plugins, rules, settings, ...rest }, { categories: configCategories, env: configEnv, globals: configGlobals, ignorePatterns: configIgnorePatterns, jsPlugins: configJsPlugins, options: configOptions, overrides: configOverrides, plugins: configPlugins, rules: configRules, settings: configSettings, ...configRest }) => ({
|
|
125
|
+
categories: {
|
|
126
|
+
...categories,
|
|
127
|
+
...configCategories
|
|
128
|
+
},
|
|
129
|
+
env: {
|
|
130
|
+
...env,
|
|
131
|
+
...configEnv
|
|
132
|
+
},
|
|
133
|
+
globals: {
|
|
134
|
+
...globals,
|
|
135
|
+
...configGlobals
|
|
136
|
+
},
|
|
137
|
+
ignorePatterns: [...ignorePatterns ?? [], ...configIgnorePatterns ?? []],
|
|
138
|
+
jsPlugins: [...jsPlugins ?? [], ...configJsPlugins ?? []],
|
|
139
|
+
options: {
|
|
140
|
+
...options,
|
|
141
|
+
...configOptions
|
|
142
|
+
},
|
|
143
|
+
overrides: [...overrides ?? [], ...configOverrides ?? []],
|
|
144
|
+
plugins: {
|
|
145
|
+
...plugins,
|
|
146
|
+
...configPlugins
|
|
147
|
+
},
|
|
148
|
+
rules: {
|
|
149
|
+
...rules,
|
|
150
|
+
...configRules
|
|
151
|
+
},
|
|
152
|
+
settings: {
|
|
153
|
+
...settings,
|
|
154
|
+
...configSettings
|
|
155
|
+
},
|
|
156
|
+
...rest,
|
|
157
|
+
...configRest
|
|
158
|
+
}), {});
|
|
159
|
+
const getTailwindConfig = async (config) => {
|
|
160
|
+
if (!config) return {};
|
|
161
|
+
const tailwindPlugin = await import("eslint-plugin-better-tailwindcss");
|
|
162
|
+
return {
|
|
163
|
+
jsPlugins: [{
|
|
164
|
+
name: "better-tailwindcss",
|
|
165
|
+
specifier: "eslint-plugin-better-tailwindcss"
|
|
166
|
+
}],
|
|
167
|
+
rules: {
|
|
168
|
+
...Object.fromEntries(Object.keys(tailwindPlugin.default.rules).map((key) => [`better-tailwindcss/${key}`, "error"])),
|
|
169
|
+
...disabledTailwindRules
|
|
170
|
+
},
|
|
171
|
+
settings: { "better-tailwindcss": { entryPoint: config.entryPoint } }
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
const getVitestConfig = (config) => {
|
|
175
|
+
if (!config) return {};
|
|
176
|
+
return {
|
|
177
|
+
overrides: config.files ? [{
|
|
178
|
+
files: config.files,
|
|
179
|
+
rules: { "react/rules-of-hooks": "off" }
|
|
180
|
+
}] : [],
|
|
181
|
+
plugins: { vitest: true }
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
const getTanstackRouterConfig = async (config) => {
|
|
185
|
+
if (!config) return {};
|
|
186
|
+
const plugin = await import("@tanstack/eslint-plugin-router");
|
|
187
|
+
return {
|
|
188
|
+
jsPlugins: [{
|
|
189
|
+
name: "@tanstack/router",
|
|
190
|
+
specifier: "@tanstack/eslint-plugin-router"
|
|
191
|
+
}],
|
|
192
|
+
overrides: [{
|
|
193
|
+
files: config.routes,
|
|
194
|
+
rules: { "no-use-before-define": "off" }
|
|
195
|
+
}],
|
|
196
|
+
rules: plugin.default.configs["flat/recommended"][0].rules
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
const getPackageJsonConfig = async (config) => {
|
|
200
|
+
if (!config) return {};
|
|
201
|
+
return {
|
|
202
|
+
jsPlugins: [{
|
|
203
|
+
name: "package-json",
|
|
204
|
+
specifier: "eslint-plugin-package-json"
|
|
205
|
+
}],
|
|
206
|
+
rules: (await import("eslint-plugin-package-json")).configs.recommended.rules
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
const getPlaywrightConfig = async (config) => {
|
|
210
|
+
if (!config) return {};
|
|
211
|
+
const plugin = await import("eslint-plugin-playwright");
|
|
212
|
+
return {
|
|
213
|
+
jsPlugins: [{
|
|
214
|
+
name: "playwright",
|
|
215
|
+
specifier: "eslint-plugin-playwright"
|
|
216
|
+
}],
|
|
217
|
+
overrides: [{
|
|
218
|
+
files: config.files,
|
|
219
|
+
rules: {
|
|
220
|
+
...plugin.default.configs["flat/recommended"].rules,
|
|
221
|
+
...config.assertFunctionNames ? { "playwright/expect-expect": ["error", { assertFunctionNames: config.assertFunctionNames }] } : {},
|
|
222
|
+
"react/rules-of-hooks": "off",
|
|
223
|
+
"vitest/consistent-test-filename": "off",
|
|
224
|
+
"vitest/prefer-each": "off",
|
|
225
|
+
"vitest/valid-expect": "off"
|
|
226
|
+
}
|
|
227
|
+
}]
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
const getServerSideConfig = (config) => {
|
|
231
|
+
if (!config) return {};
|
|
232
|
+
return { overrides: [
|
|
233
|
+
{
|
|
234
|
+
files: config.files,
|
|
235
|
+
rules: { "import/no-nodejs-modules": "off" }
|
|
236
|
+
},
|
|
237
|
+
config.allowConsole ? {
|
|
238
|
+
files: config.allowConsole,
|
|
239
|
+
rules: { "no-console": "off" }
|
|
240
|
+
} : null,
|
|
241
|
+
config.allowProcess ? {
|
|
242
|
+
files: config.allowProcess,
|
|
243
|
+
rules: { "node/no-process-env": "off" }
|
|
244
|
+
} : null
|
|
245
|
+
].filter(isNonNullish) };
|
|
246
|
+
};
|
|
247
|
+
const getRestrictedSyntaxConfig = (config) => {
|
|
248
|
+
if (!config) return {};
|
|
249
|
+
const overrides = config.overrides ?? [];
|
|
250
|
+
const rawRules = [config.banBarrelImport ? {
|
|
251
|
+
message: "Do not use barrel export, prefer named export",
|
|
252
|
+
selector: "ExportAllDeclaration"
|
|
253
|
+
} : null, config.banReactMemo ? {
|
|
254
|
+
message: "No need to use `React.memo`, we have a react compiler turned on",
|
|
255
|
+
selector: "MemberExpression[object.name='React'][property.name='memo']"
|
|
256
|
+
} : null].filter(isNonNullish);
|
|
257
|
+
return {
|
|
258
|
+
overrides: overrides.map(({ files, rules }) => ({
|
|
259
|
+
files,
|
|
260
|
+
rules: { "eslint-js/no-restricted-syntax": ["error", [
|
|
261
|
+
...rawRules,
|
|
262
|
+
...rules,
|
|
263
|
+
...config.rulesOverrides ?? []
|
|
264
|
+
]] }
|
|
265
|
+
})),
|
|
266
|
+
rules: { "eslint-js/no-restricted-syntax": [
|
|
267
|
+
"error",
|
|
268
|
+
...rawRules,
|
|
269
|
+
...config.rulesOverrides ?? []
|
|
270
|
+
] }
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
const getRestrictedConfig = (config) => {
|
|
274
|
+
if (!config) return {};
|
|
275
|
+
return { rules: {
|
|
276
|
+
"eslint/no-restricted-globals": config.globals ? ["error", ...config.globals] : "error",
|
|
277
|
+
"eslint/no-restricted-properties": config.properties ? ["error", ...config.properties] : "error"
|
|
278
|
+
} };
|
|
279
|
+
};
|
|
280
|
+
const getReactConfig = (config) => {
|
|
281
|
+
if (!config) return {};
|
|
282
|
+
return { rules: {
|
|
283
|
+
"react/exhaustive-deps": config.additionalHooks ? ["error", { additionalHooks: `(${config.additionalHooks.join(",")})` }] : "error",
|
|
284
|
+
"react/jsx-no-literals": ["error", {
|
|
285
|
+
allowedStrings: config.allowedStrings,
|
|
286
|
+
ignoreProps: true,
|
|
287
|
+
noAttributeStrings: true,
|
|
288
|
+
noStrings: true
|
|
289
|
+
}]
|
|
290
|
+
} };
|
|
291
|
+
};
|
|
292
|
+
const getI18nConfig = (config) => {
|
|
293
|
+
if (!config) return {};
|
|
294
|
+
return {
|
|
295
|
+
overrides: Array.isArray(config.ignore) ? [{
|
|
296
|
+
files: config.ignore,
|
|
297
|
+
rules: { "react/jsx-no-literals": "off" }
|
|
298
|
+
}] : [],
|
|
299
|
+
rules: config.ignore === true ? { "react/jsx-no-literals": "off" } : {}
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
const getImportConfig = (config) => {
|
|
303
|
+
if (!config) return {};
|
|
304
|
+
return { overrides: [config.allowDefault ? {
|
|
305
|
+
files: config.allowDefault,
|
|
306
|
+
rules: { "import/no-default-export": "off" }
|
|
307
|
+
} : null].filter(isNonNullish) };
|
|
308
|
+
};
|
|
309
|
+
const getBaseConfig$1 = () => ({
|
|
310
|
+
categories: {
|
|
311
|
+
correctness: "error",
|
|
312
|
+
nursery: "error",
|
|
313
|
+
pedantic: "error",
|
|
314
|
+
perf: "error",
|
|
315
|
+
restriction: "error",
|
|
316
|
+
style: "error",
|
|
317
|
+
suspicious: "error"
|
|
318
|
+
},
|
|
319
|
+
env: {
|
|
320
|
+
browser: true,
|
|
321
|
+
es2026: true
|
|
322
|
+
},
|
|
323
|
+
ignorePatterns: baseIgnorePatterns,
|
|
324
|
+
jsPlugins: [{
|
|
325
|
+
name: "eslint-js",
|
|
326
|
+
specifier: "oxlint-plugin-eslint"
|
|
327
|
+
}],
|
|
328
|
+
options: {
|
|
329
|
+
denyWarnings: true,
|
|
330
|
+
reportUnusedDisableDirectives: "error",
|
|
331
|
+
typeAware: true
|
|
332
|
+
},
|
|
333
|
+
overrides: [
|
|
334
|
+
{
|
|
335
|
+
files: ["**/*.config.{j,t}s"],
|
|
336
|
+
rules: {
|
|
337
|
+
"import/no-default-export": "off",
|
|
338
|
+
"import/no-nodejs-modules": "off",
|
|
339
|
+
"node/no-top-level-await": "off"
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
files: ["**/*.d.ts"],
|
|
344
|
+
rules: { "typescript/triple-slash-reference": "off" }
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
files: ["workflows.config.ts"],
|
|
348
|
+
rules: { "eslint/no-template-curly-in-string": "off" }
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
plugins: {
|
|
352
|
+
eslint: true,
|
|
353
|
+
import: true,
|
|
354
|
+
"jsx-a11y": true,
|
|
355
|
+
node: true,
|
|
356
|
+
oxc: true,
|
|
357
|
+
promise: true,
|
|
358
|
+
react: true,
|
|
359
|
+
"react-perf": true,
|
|
360
|
+
typescript: true,
|
|
361
|
+
unicorn: true
|
|
362
|
+
},
|
|
363
|
+
rules: {
|
|
364
|
+
...disabledRules,
|
|
365
|
+
...overridenRules
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
const getConfig$2 = async ({ tailwind, tanstackRouter, vitest, packageJson = true, playwright, serverSide, restricted, react, i18n, import: importOptions, ...config } = {}) => {
|
|
369
|
+
const baseConfig = getBaseConfig$1();
|
|
370
|
+
const tailwindConfig = await getTailwindConfig(tailwind);
|
|
371
|
+
const tanstackRouterConfig = await getTanstackRouterConfig(tanstackRouter);
|
|
372
|
+
const vitestConfig = getVitestConfig(vitest);
|
|
373
|
+
const packageJsonConfig = await getPackageJsonConfig(packageJson);
|
|
374
|
+
const playwrightConfig = await getPlaywrightConfig(playwright);
|
|
375
|
+
const serverSideConfig = getServerSideConfig(serverSide);
|
|
376
|
+
const reactConfig = getReactConfig(react);
|
|
377
|
+
const i18nConfig = getI18nConfig(i18n);
|
|
378
|
+
const importConfig = getImportConfig(importOptions);
|
|
379
|
+
const restrictedConfig = getRestrictedConfig(restricted);
|
|
380
|
+
const rawMergedConfig = mergeConfigs$1(baseConfig, vitestConfig, tanstackRouterConfig, packageJsonConfig, playwrightConfig, tailwindConfig, serverSideConfig, restrictedConfig, reactConfig, i18nConfig, importConfig, config);
|
|
381
|
+
const restrictedSyntaxConfig = getRestrictedSyntaxConfig({
|
|
382
|
+
banBarrelImport: importOptions?.banBarrel,
|
|
383
|
+
banReactMemo: react?.banMemo,
|
|
384
|
+
overrides: restricted?.syntaxOverrides,
|
|
385
|
+
previousOverrides: rawMergedConfig.overrides?.map((override) => override.rules?.["eslint-js/no-restricted-syntax"] === void 0 ? void 0 : {
|
|
386
|
+
files: override.files,
|
|
387
|
+
rules: override.rules["eslint-js/no-restricted-syntax"].slice(1)
|
|
388
|
+
}).filter(isNonNullish),
|
|
389
|
+
previousRules: (rawMergedConfig.rules?.["eslint-js/no-restricted-syntax"])?.slice(1),
|
|
390
|
+
rulesOverrides: restricted?.syntaxRulesOverrides
|
|
391
|
+
});
|
|
392
|
+
const { plugins: pluginsRecord = {}, ...mergedConfig } = mergeConfigs$1(rawMergedConfig, restrictedSyntaxConfig);
|
|
393
|
+
return {
|
|
394
|
+
...mergedConfig,
|
|
395
|
+
plugins: Object.entries(pluginsRecord).filter(([, value]) => value).map(([key]) => key)
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/oxfmt.ts
|
|
400
|
+
const getConfig = async ({ ignorePatterns = [], tailwind, imports, sortImports, ...rest } = {}) => ({
|
|
401
|
+
astro: true,
|
|
402
|
+
ignorePatterns: [...baseIgnorePatterns, ...ignorePatterns],
|
|
403
|
+
printWidth: 80,
|
|
404
|
+
sortImports: sortImports ?? (imports ? {
|
|
405
|
+
newlinesBetween: false,
|
|
406
|
+
order: "asc",
|
|
407
|
+
...imports
|
|
408
|
+
} : true),
|
|
409
|
+
sortPackageJson: { sortScripts: true },
|
|
410
|
+
sortTailwindcss: tailwind ? {
|
|
411
|
+
functions: tailwind.functions,
|
|
412
|
+
stylesheet: tailwind.stylesheet
|
|
413
|
+
} : void 0,
|
|
414
|
+
useTabs: true,
|
|
415
|
+
...rest
|
|
416
|
+
});
|
|
417
|
+
//#endregion
|
|
418
|
+
//#region src/knip.ts
|
|
419
|
+
const mergeConfigs = (...configs) => configs.reduce(({ include, ignore, ignoreDependencies, entry, ignoreIssues, workspaces = {}, ...rest }, { include: configInclude, ignore: configIgnore, ignoreDependencies: configIgnoreDependencies, entry: configEntry, ignoreIssues: configIgnoreIssues, workspaces: configWorkspaces = {}, ...configRest }) => ({
|
|
420
|
+
entry: [...arraify(entry), ...arraify(configEntry)],
|
|
421
|
+
ignore: [...arraify(ignore), ...arraify(configIgnore)],
|
|
422
|
+
ignoreDependencies: [...arraify(ignoreDependencies), ...arraify(configIgnoreDependencies)],
|
|
423
|
+
ignoreIssues: {
|
|
424
|
+
...ignoreIssues,
|
|
425
|
+
...configIgnoreIssues
|
|
426
|
+
},
|
|
427
|
+
include: {
|
|
428
|
+
...include,
|
|
429
|
+
...configInclude
|
|
430
|
+
},
|
|
431
|
+
workspaces: {
|
|
432
|
+
...mapValues(workspaces, (workspace, key) => ({
|
|
433
|
+
...workspace,
|
|
434
|
+
...configWorkspaces[key]
|
|
435
|
+
})),
|
|
436
|
+
...omitBy(configWorkspaces, (_value, key) => Boolean(workspaces[key]))
|
|
437
|
+
},
|
|
438
|
+
...rest,
|
|
439
|
+
...configRest
|
|
440
|
+
}), {});
|
|
441
|
+
const getBaseConfig = ({ opencode = false, reactNative = false, eslint = true, vitest = true, workspaces = false } = {}) => ({
|
|
442
|
+
entry: workspaces ? [] : ["**/*.config.ts"],
|
|
443
|
+
ignore: [process.env.CI ? void 0 : ".history/**", opencode ? ".opencode/**" : void 0].filter(isNonNullish),
|
|
444
|
+
ignoreDependencies: [
|
|
445
|
+
reactNative ? "expo-doctor" : void 0,
|
|
446
|
+
vitest ? "@vitest/coverage-v8" : void 0,
|
|
447
|
+
eslint ? "oxlint-plugin-eslint" : void 0
|
|
448
|
+
].filter(isNonNullish),
|
|
449
|
+
ignoreIssues: { "**/*.gen.ts": ["types"] },
|
|
450
|
+
include: {
|
|
451
|
+
catalog: true,
|
|
452
|
+
catalogReferences: true,
|
|
453
|
+
cycles: true,
|
|
454
|
+
dependencies: true,
|
|
455
|
+
duplicates: true,
|
|
456
|
+
enumMembers: true,
|
|
457
|
+
exports: true,
|
|
458
|
+
files: true,
|
|
459
|
+
namespaceMembers: true,
|
|
460
|
+
nsExports: true,
|
|
461
|
+
nsTypes: true,
|
|
462
|
+
types: true,
|
|
463
|
+
unlisted: true,
|
|
464
|
+
unresolved: true
|
|
465
|
+
},
|
|
466
|
+
treatConfigHintsAsErrors: true,
|
|
467
|
+
treatTagHintsAsErrors: true,
|
|
468
|
+
workspaces: workspaces ? { ".": { entry: ["**/*.config.ts"] } } : {}
|
|
469
|
+
});
|
|
470
|
+
const getConfig$1 = async ({ options, ...overrides } = {}) => {
|
|
471
|
+
const baseConfig = getBaseConfig(options);
|
|
472
|
+
const { include: includeRecord = {}, ...mergedConfig } = mergeConfigs(baseConfig, overrides);
|
|
473
|
+
return {
|
|
474
|
+
...mergedConfig,
|
|
475
|
+
include: Object.entries(includeRecord).filter(([, value]) => value).map(([key]) => key)
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
//#endregion
|
|
479
|
+
export { configSchema, disabledRules, getConfig as getFormatConfig, getConfig$1 as getKnipConfig, getConfig$2 as getLintConfig, overridenRules };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { r as moduleName } from "./common-B9SE4GL9.mjs";
|
|
2
|
+
import { t as configSchema } from "./schema-BuCl21uv.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { cosmiconfig } from "cosmiconfig";
|
|
5
|
+
//#region src/config/parse.ts
|
|
6
|
+
const explorer = cosmiconfig(moduleName);
|
|
7
|
+
const parse = async () => {
|
|
8
|
+
const rawConfig = await explorer.search();
|
|
9
|
+
const parsedConfig = z.safeParse(configSchema, rawConfig?.config ?? {});
|
|
10
|
+
if (!parsedConfig.success) throw new Error(`Validation error: ${parsedConfig.error.message}`);
|
|
11
|
+
return parsedConfig.data;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { parse as t };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { valid } from "semver";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/config/schema.ts
|
|
4
|
+
const MIN_NODE_VERSION = "26.0.0";
|
|
5
|
+
const MIN_BUN_VERSION = "1.4.4";
|
|
6
|
+
const configSchema = z.object({
|
|
7
|
+
preCommitCommands: z.string().array().optional(),
|
|
8
|
+
verify: z.object({
|
|
9
|
+
minBunVersion: z.string().refine((version) => valid(version)).default(() => MIN_BUN_VERSION),
|
|
10
|
+
minNodeVersion: z.string().refine((version) => valid(version)).default(() => MIN_NODE_VERSION),
|
|
11
|
+
scripts: z.record(z.string(), z.string()).optional()
|
|
12
|
+
}).default(() => ({
|
|
13
|
+
minBunVersion: MIN_BUN_VERSION,
|
|
14
|
+
minNodeVersion: MIN_NODE_VERSION
|
|
15
|
+
})),
|
|
16
|
+
workflows: z.object({
|
|
17
|
+
branch: z.string().optional(),
|
|
18
|
+
jobs: z.record(z.string(), z.custom()).optional(),
|
|
19
|
+
workflows: z.custom().array().optional()
|
|
20
|
+
}).optional()
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { configSchema as t };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as getDefaultWorkflow, c as getLintJob, d as getTypecheckJob, f as getWorkflowsVerifyJob, i as getCheckJob, l as getPackageJsonVerifyJob, m as Workflow, n as generateWorkflows, o as getDepsJob, p as CompositeAction, r as DEFAULT_MACHINE, s as getFormatVerifyJob, t as GeneratedWorkflowTypes, u as getSetupAction } from "../index-DqMadVlO.mjs";
|
|
2
|
+
export { type CompositeAction, DEFAULT_MACHINE, type GeneratedWorkflowTypes, type Workflow, generateWorkflows, getCheckJob, getDefaultWorkflow, getDepsJob, getFormatVerifyJob, getLintJob, getPackageJsonVerifyJob, getSetupAction, getTypecheckJob, getWorkflowsVerifyJob };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { n as DEFAULT_MACHINE, t as generateWorkflows, r as getCheckJob, i as getDefaultWorkflow, a as getDepsJob, o as getFormatVerifyJob, s as getLintJob, c as getPackageJsonVerifyJob, l as getSetupAction, u as getTypecheckJob, d as getWorkflowsVerifyJob } from "../generate-BGCgStVl.mjs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,85 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@oxiul/configs",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/oxiul/configs.git"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"oxiul": "./dist/bin.mjs"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/**",
|
|
14
|
+
"scripts/postinstall.mjs"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"main": "./dist/index.mjs",
|
|
19
|
+
"module": "./dist/index.mjs",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./workflows": {
|
|
26
|
+
"types": "./dist/workflows/index.d.mts",
|
|
27
|
+
"default": "./dist/workflows/index.mjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsdown",
|
|
35
|
+
"changeset": "changeset add",
|
|
36
|
+
"deps": "knip",
|
|
37
|
+
"format": "oxfmt --write",
|
|
38
|
+
"format:verify": "oxfmt --check",
|
|
39
|
+
"lint": "oxlint",
|
|
40
|
+
"lint:fix": "oxlint --fix",
|
|
41
|
+
"oxiul:verify": "bun src/bin.ts verify",
|
|
42
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
43
|
+
"typecheck": "bun check",
|
|
44
|
+
"workflows": "bun src/bin.ts workflows --verify",
|
|
45
|
+
"workflows:generate": "bun src/bin.ts workflows --generate"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@crustjs/core": "^0.5.6",
|
|
49
|
+
"@crustjs/extensions": "^0.5.6",
|
|
50
|
+
"@github-actions-workflow-ts/lib": "^2.6.1",
|
|
51
|
+
"cosmiconfig": "^10.0.1",
|
|
52
|
+
"listr2": "^11.4.0",
|
|
53
|
+
"oxlint-plugin-eslint": "^1.88.0",
|
|
54
|
+
"semver": "^7.8.5",
|
|
55
|
+
"yaml": "^2.9.1",
|
|
56
|
+
"zod": "^4.6.7"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@arethetypeswrong/core": "^0.18.5",
|
|
60
|
+
"@changesets/changelog-github": "^1.0.1",
|
|
61
|
+
"@changesets/cli": "^3.0.3",
|
|
62
|
+
"@tanstack/eslint-plugin-router": "^1.162.0",
|
|
63
|
+
"@types/bun": "1.4.3",
|
|
64
|
+
"@types/semver": "^7.8.0",
|
|
65
|
+
"eslint-plugin-better-tailwindcss": "^4.9.1",
|
|
66
|
+
"eslint-plugin-package-json": "^1.10.1",
|
|
67
|
+
"eslint-plugin-playwright": "^2.12.1",
|
|
68
|
+
"knip": "^6.42.0",
|
|
69
|
+
"oxfmt": "^0.73.0",
|
|
70
|
+
"oxlint": "^1.88.0",
|
|
71
|
+
"oxlint-tsgolint": "^7.0.2004",
|
|
72
|
+
"publint": "^0.3.25",
|
|
73
|
+
"remeda": "^2.52.0",
|
|
74
|
+
"tsdown": "^0.23.1"
|
|
75
|
+
},
|
|
76
|
+
"peerDependencies": {
|
|
77
|
+
"knip": "^6.42.0",
|
|
78
|
+
"oxfmt": "^0.73.0",
|
|
79
|
+
"oxlint": "^1.88.0"
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": "26"
|
|
83
|
+
},
|
|
84
|
+
"packageManager": "bun@1.4.4"
|
|
85
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
if (process.env.CI) {
|
|
6
|
+
process.exit(0);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const readName = (dir) => {
|
|
10
|
+
try {
|
|
11
|
+
// oxlint-disable-next-line typescript/no-unsafe-argument
|
|
12
|
+
const fileContent = readFileSync(path.join(dir, "package.json"), "utf8");
|
|
13
|
+
// oxlint-disable-next-line typescript/no-unsafe-return typescript/no-unsafe-member-access
|
|
14
|
+
return JSON.parse(fileContent).name;
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// oxlint-disable-next-line typescript/no-unsafe-assignment
|
|
21
|
+
const ownName = readName(process.cwd());
|
|
22
|
+
|
|
23
|
+
let gitRoot = "";
|
|
24
|
+
try {
|
|
25
|
+
gitRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
26
|
+
encoding: "utf8",
|
|
27
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
28
|
+
}).trim();
|
|
29
|
+
} catch {
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const [cmd, ...args] =
|
|
34
|
+
readName(gitRoot) === ownName
|
|
35
|
+
? ["bun", "src/hook/install.ts"]
|
|
36
|
+
: ["node", "dist/hook/install.mjs"];
|
|
37
|
+
|
|
38
|
+
const result = spawnSync(cmd, args, { stdio: "inherit" });
|
|
39
|
+
process.exit(result.status ?? 1);
|