@outfitter/tooling 0.2.4 → 0.3.3
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 +69 -1
- package/biome.json +1 -1
- package/dist/cli/index.js +163 -24
- package/dist/index.d.ts +79 -4
- package/dist/index.js +17 -6
- package/dist/shared/chunk-cmde0fwx.js +421 -0
- package/package.json +14 -7
- package/registry/registry.json +6 -6
- package/dist/cli/check-boundary-invocations.d.ts +0 -34
- package/dist/cli/check-boundary-invocations.js +0 -14
- package/dist/cli/check-bunup-registry.d.ts +0 -36
- package/dist/cli/check-bunup-registry.js +0 -12
- package/dist/cli/check-changeset.d.ts +0 -64
- package/dist/cli/check-changeset.js +0 -14
- package/dist/cli/check-clean-tree.d.ts +0 -36
- package/dist/cli/check-clean-tree.js +0 -14
- package/dist/cli/check-exports.d.ts +0 -2
- package/dist/cli/check-exports.js +0 -14
- package/dist/cli/check-readme-imports.d.ts +0 -61
- package/dist/cli/check-readme-imports.js +0 -198
- package/dist/cli/check.d.ts +0 -19
- package/dist/cli/check.js +0 -10
- package/dist/cli/fix.d.ts +0 -19
- package/dist/cli/fix.js +0 -10
- package/dist/cli/init.d.ts +0 -31
- package/dist/cli/init.js +0 -12
- package/dist/cli/pre-push.d.ts +0 -41
- package/dist/cli/pre-push.js +0 -20
- package/dist/cli/upgrade-bun.d.ts +0 -8
- package/dist/cli/upgrade-bun.js +0 -8
- package/dist/registry/build.d.ts +0 -6
- package/dist/registry/build.js +0 -147
- package/dist/registry/index.d.ts +0 -3
- package/dist/registry/index.js +0 -13
- package/dist/registry/schema.d.ts +0 -2
- package/dist/registry/schema.js +0 -12
- package/dist/shared/@outfitter/tooling-0x5q15ec.js +0 -21
- package/dist/shared/@outfitter/tooling-1y8w5ahg.js +0 -70
- package/dist/shared/@outfitter/tooling-3w8vr2w3.js +0 -94
- package/dist/shared/@outfitter/tooling-8sd32ts6.js +0 -277
- package/dist/shared/@outfitter/tooling-9errkcvk.js +0 -21
- package/dist/shared/@outfitter/tooling-9vs606gq.d.ts +0 -3
- package/dist/shared/@outfitter/tooling-9yzd08v1.js +0 -146
- package/dist/shared/@outfitter/tooling-ctmgnap5.js +0 -19
- package/dist/shared/@outfitter/tooling-dvwh9qve.js +0 -4
- package/dist/shared/@outfitter/tooling-enjcenja.js +0 -229
- package/dist/shared/@outfitter/tooling-g83d0kjv.js +0 -23
- package/dist/shared/@outfitter/tooling-kcvs6mys.js +0 -1
- package/dist/shared/@outfitter/tooling-mxwc1n8w.js +0 -68
- package/dist/shared/@outfitter/tooling-r9976n43.js +0 -100
- package/dist/shared/@outfitter/tooling-sjm8nebx.d.ts +0 -109
- package/dist/shared/@outfitter/tooling-t17gnh9b.js +0 -78
- package/dist/shared/@outfitter/tooling-wesswf21.d.ts +0 -59
- package/dist/shared/chunk-8aenrm6f.js +0 -18
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -8
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/cli/upgrade-bun.ts
|
|
3
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
4
|
-
import { join } from "path";
|
|
5
|
-
var COLORS = {
|
|
6
|
-
reset: "\x1B[0m",
|
|
7
|
-
red: "\x1B[31m",
|
|
8
|
-
green: "\x1B[32m",
|
|
9
|
-
yellow: "\x1B[33m",
|
|
10
|
-
blue: "\x1B[34m"
|
|
11
|
-
};
|
|
12
|
-
function log(msg) {
|
|
13
|
-
process.stdout.write(`${msg}
|
|
14
|
-
`);
|
|
15
|
-
}
|
|
16
|
-
function info(msg) {
|
|
17
|
-
process.stdout.write(`${COLORS.blue}\u25B8${COLORS.reset} ${msg}
|
|
18
|
-
`);
|
|
19
|
-
}
|
|
20
|
-
function success(msg) {
|
|
21
|
-
process.stdout.write(`${COLORS.green}\u2713${COLORS.reset} ${msg}
|
|
22
|
-
`);
|
|
23
|
-
}
|
|
24
|
-
function warn(msg) {
|
|
25
|
-
process.stdout.write(`${COLORS.yellow}!${COLORS.reset} ${msg}
|
|
26
|
-
`);
|
|
27
|
-
}
|
|
28
|
-
async function fetchLatestVersion() {
|
|
29
|
-
const response = await fetch("https://api.github.com/repos/oven-sh/bun/releases/latest");
|
|
30
|
-
const data = await response.json();
|
|
31
|
-
const match = data.tag_name.match(/bun-v(.+)/);
|
|
32
|
-
if (!match?.[1]) {
|
|
33
|
-
throw new Error(`Could not parse version from tag: ${data.tag_name}`);
|
|
34
|
-
}
|
|
35
|
-
return match[1];
|
|
36
|
-
}
|
|
37
|
-
function findPackageJsonFiles(dir) {
|
|
38
|
-
const results = [];
|
|
39
|
-
const glob = new Bun.Glob("**/package.json");
|
|
40
|
-
for (const path of glob.scanSync({ cwd: dir })) {
|
|
41
|
-
if (!path.includes("node_modules")) {
|
|
42
|
-
results.push(join(dir, path));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return results;
|
|
46
|
-
}
|
|
47
|
-
function updateEnginesBun(filePath, version) {
|
|
48
|
-
const content = readFileSync(filePath, "utf-8");
|
|
49
|
-
const pattern = /"bun":\s*">=[\d.]+"/;
|
|
50
|
-
if (!pattern.test(content)) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
const updated = content.replace(pattern, `"bun": ">=${version}"`);
|
|
54
|
-
if (updated !== content) {
|
|
55
|
-
writeFileSync(filePath, updated);
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
function updateTypesBun(filePath, version) {
|
|
61
|
-
const content = readFileSync(filePath, "utf-8");
|
|
62
|
-
const pattern = /"@types\/bun":\s*"\^[\d.]+"/;
|
|
63
|
-
if (!pattern.test(content)) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
const updated = content.replace(pattern, `"@types/bun": "^${version}"`);
|
|
67
|
-
if (updated !== content) {
|
|
68
|
-
writeFileSync(filePath, updated);
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
async function runUpgradeBun(targetVersion, options = {}) {
|
|
74
|
-
const cwd = process.cwd();
|
|
75
|
-
const bunVersionFile = join(cwd, ".bun-version");
|
|
76
|
-
let version = targetVersion;
|
|
77
|
-
if (!version) {
|
|
78
|
-
info("Fetching latest Bun version...");
|
|
79
|
-
version = await fetchLatestVersion();
|
|
80
|
-
log(`Latest version: ${version}`);
|
|
81
|
-
}
|
|
82
|
-
const currentVersion = existsSync(bunVersionFile) ? readFileSync(bunVersionFile, "utf-8").trim() : "unknown";
|
|
83
|
-
log(`Current version: ${currentVersion}`);
|
|
84
|
-
if (currentVersion === version) {
|
|
85
|
-
success(`Already on version ${version}`);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
log("");
|
|
89
|
-
info(`Upgrading Bun: ${currentVersion} \u2192 ${version}`);
|
|
90
|
-
log("");
|
|
91
|
-
writeFileSync(bunVersionFile, `${version}
|
|
92
|
-
`);
|
|
93
|
-
success("Updated .bun-version");
|
|
94
|
-
const packageFiles = findPackageJsonFiles(cwd);
|
|
95
|
-
info("Updating engines.bun...");
|
|
96
|
-
for (const file of packageFiles) {
|
|
97
|
-
if (updateEnginesBun(file, version)) {
|
|
98
|
-
log(` ${file.replace(`${cwd}/`, "")}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
info("Updating @types/bun...");
|
|
102
|
-
for (const file of packageFiles) {
|
|
103
|
-
if (updateTypesBun(file, version)) {
|
|
104
|
-
log(` ${file.replace(`${cwd}/`, "")}`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (options.install !== false) {
|
|
108
|
-
log("");
|
|
109
|
-
info(`Installing Bun ${version}...`);
|
|
110
|
-
const installResult = Bun.spawnSync([
|
|
111
|
-
"bash",
|
|
112
|
-
"-c",
|
|
113
|
-
`curl -fsSL https://bun.sh/install | bash -s "bun-v${version}"`
|
|
114
|
-
]);
|
|
115
|
-
if (installResult.exitCode !== 0) {
|
|
116
|
-
warn("Could not install Bun automatically");
|
|
117
|
-
log("Install manually: curl -fsSL https://bun.sh/install | bash");
|
|
118
|
-
} else {
|
|
119
|
-
success(`Bun ${version} installed`);
|
|
120
|
-
log("");
|
|
121
|
-
info("Updating lockfile...");
|
|
122
|
-
const bunInstall = Bun.spawnSync(["bun", "install"], {
|
|
123
|
-
cwd,
|
|
124
|
-
env: {
|
|
125
|
-
...process.env,
|
|
126
|
-
BUN_INSTALL: `${process.env["HOME"]}/.bun`,
|
|
127
|
-
PATH: `${process.env["HOME"]}/.bun/bin:${process.env["PATH"]}`
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
if (bunInstall.exitCode === 0) {
|
|
131
|
-
success("Lockfile updated");
|
|
132
|
-
} else {
|
|
133
|
-
warn("Could not update lockfile - run 'bun install' manually");
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
log("");
|
|
138
|
-
success("Done! Changes ready to commit:");
|
|
139
|
-
log(" - .bun-version");
|
|
140
|
-
log(" - package.json files (engines.bun, @types/bun)");
|
|
141
|
-
log(" - bun.lock");
|
|
142
|
-
log("");
|
|
143
|
-
log(`Commit with: git add -A && git commit -m 'chore: upgrade Bun to ${version}'`);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export { runUpgradeBun };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/version.ts
|
|
3
|
-
import { readFileSync } from "fs";
|
|
4
|
-
import { createRequire } from "module";
|
|
5
|
-
var DEFAULT_VERSION = "0.0.0";
|
|
6
|
-
function readPackageVersion() {
|
|
7
|
-
try {
|
|
8
|
-
const require2 = createRequire(import.meta.url);
|
|
9
|
-
const pkgPath = require2.resolve("@outfitter/tooling/package.json");
|
|
10
|
-
const packageJson = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
11
|
-
if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
|
|
12
|
-
return packageJson.version;
|
|
13
|
-
}
|
|
14
|
-
} catch {}
|
|
15
|
-
return DEFAULT_VERSION;
|
|
16
|
-
}
|
|
17
|
-
var VERSION = readPackageVersion();
|
|
18
|
-
|
|
19
|
-
export { VERSION };
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/cli/check-exports.ts
|
|
3
|
-
import { resolve } from "path";
|
|
4
|
-
function entryToSubpath(entry) {
|
|
5
|
-
const stripped = entry.replace(/^src\//, "").replace(/\.[cm]?[jt]sx?$/, "");
|
|
6
|
-
if (stripped === "index") {
|
|
7
|
-
return ".";
|
|
8
|
-
}
|
|
9
|
-
if (stripped.endsWith("/index")) {
|
|
10
|
-
return `./${stripped.slice(0, -"/index".length)}`;
|
|
11
|
-
}
|
|
12
|
-
return `./${stripped}`;
|
|
13
|
-
}
|
|
14
|
-
function compareExports(input) {
|
|
15
|
-
const { name, actual, expected, path } = input;
|
|
16
|
-
const actualKeys = new Set(Object.keys(actual));
|
|
17
|
-
const expectedKeys = new Set(Object.keys(expected));
|
|
18
|
-
const added = [];
|
|
19
|
-
const removed = [];
|
|
20
|
-
const changed = [];
|
|
21
|
-
for (const key of expectedKeys) {
|
|
22
|
-
if (!actualKeys.has(key)) {
|
|
23
|
-
added.push(key);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
for (const key of actualKeys) {
|
|
27
|
-
if (!expectedKeys.has(key)) {
|
|
28
|
-
removed.push(key);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
for (const key of actualKeys) {
|
|
32
|
-
if (expectedKeys.has(key)) {
|
|
33
|
-
const actualValue = actual[key];
|
|
34
|
-
const expectedValue = expected[key];
|
|
35
|
-
if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {
|
|
36
|
-
changed.push({ key, expected: expectedValue, actual: actualValue });
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
added.sort();
|
|
41
|
-
removed.sort();
|
|
42
|
-
changed.sort((a, b) => a.key.localeCompare(b.key));
|
|
43
|
-
if (added.length === 0 && removed.length === 0 && changed.length === 0) {
|
|
44
|
-
return { name, status: "ok" };
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
name,
|
|
48
|
-
status: "drift",
|
|
49
|
-
drift: {
|
|
50
|
-
package: name,
|
|
51
|
-
path: path ?? "",
|
|
52
|
-
added,
|
|
53
|
-
removed,
|
|
54
|
-
changed
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function matchesExclude(subpath, excludes) {
|
|
59
|
-
return excludes.some((pattern) => new Bun.Glob(pattern).match(subpath));
|
|
60
|
-
}
|
|
61
|
-
var CLI_EXCLUSION_PATTERNS = [
|
|
62
|
-
"**/cli.ts",
|
|
63
|
-
"**/cli/index.ts",
|
|
64
|
-
"**/bin.ts",
|
|
65
|
-
"**/bin/index.ts"
|
|
66
|
-
];
|
|
67
|
-
function isCliEntrypoint(entry) {
|
|
68
|
-
return CLI_EXCLUSION_PATTERNS.some((pattern) => new Bun.Glob(pattern).match(entry));
|
|
69
|
-
}
|
|
70
|
-
function buildExportValue(entry) {
|
|
71
|
-
const distPath = entry.replace(/^src\//, "").replace(/\.[cm]?[jt]sx?$/, "");
|
|
72
|
-
return {
|
|
73
|
-
import: {
|
|
74
|
-
types: `./dist/${distPath}.d.ts`,
|
|
75
|
-
default: `./dist/${distPath}.js`
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function discoverEntries(packageRoot) {
|
|
80
|
-
const glob = new Bun.Glob("src/**/*.ts");
|
|
81
|
-
const entries = [];
|
|
82
|
-
for (const match of glob.scanSync({ cwd: packageRoot, dot: false })) {
|
|
83
|
-
if (match.includes("__tests__") || match.endsWith(".test.ts")) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
entries.push(match);
|
|
87
|
-
}
|
|
88
|
-
return entries.sort();
|
|
89
|
-
}
|
|
90
|
-
function addConfigFileExports(expected, pkg) {
|
|
91
|
-
const CONFIG_RE = /\.(json|jsonc|yml|yaml|toml)$/;
|
|
92
|
-
const configFiles = (pkg.files ?? []).filter((file) => CONFIG_RE.test(file) && file !== "package.json");
|
|
93
|
-
for (const file of configFiles) {
|
|
94
|
-
expected[`./${file}`] = `./${file}`;
|
|
95
|
-
let base = file.replace(CONFIG_RE, "");
|
|
96
|
-
const match = base.match(/^(.+)\.preset(?:\.(.+))?$/);
|
|
97
|
-
if (match?.[1]) {
|
|
98
|
-
base = match[2] ? `${match[1]}-${match[2]}` : match[1];
|
|
99
|
-
}
|
|
100
|
-
if (base !== file) {
|
|
101
|
-
expected[`./${base}`] = `./${file}`;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function computeExpectedExports(packageRoot, workspace, pkg) {
|
|
106
|
-
const entries = discoverEntries(packageRoot);
|
|
107
|
-
const exportsConfig = typeof workspace.config?.exports === "object" ? workspace.config.exports : undefined;
|
|
108
|
-
const excludes = exportsConfig?.exclude ?? [];
|
|
109
|
-
const customExports = exportsConfig?.customExports ?? {};
|
|
110
|
-
const expected = {};
|
|
111
|
-
const subpathEntries = new Map;
|
|
112
|
-
for (const entry of entries) {
|
|
113
|
-
if (isCliEntrypoint(entry))
|
|
114
|
-
continue;
|
|
115
|
-
const subpath = entryToSubpath(entry);
|
|
116
|
-
if (matchesExclude(subpath, excludes))
|
|
117
|
-
continue;
|
|
118
|
-
const existing = subpathEntries.get(subpath);
|
|
119
|
-
if (existing) {
|
|
120
|
-
if (!existing.endsWith("/index.ts") && entry.endsWith("/index.ts")) {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
subpathEntries.set(subpath, entry);
|
|
125
|
-
}
|
|
126
|
-
for (const [subpath, entry] of subpathEntries) {
|
|
127
|
-
expected[subpath] = buildExportValue(entry);
|
|
128
|
-
}
|
|
129
|
-
for (const [key, value] of Object.entries(customExports)) {
|
|
130
|
-
expected[`./${key.replace(/^\.\//, "")}`] = value;
|
|
131
|
-
}
|
|
132
|
-
addConfigFileExports(expected, pkg);
|
|
133
|
-
expected["./package.json"] = "./package.json";
|
|
134
|
-
return expected;
|
|
135
|
-
}
|
|
136
|
-
var COLORS = {
|
|
137
|
-
reset: "\x1B[0m",
|
|
138
|
-
red: "\x1B[31m",
|
|
139
|
-
green: "\x1B[32m",
|
|
140
|
-
yellow: "\x1B[33m",
|
|
141
|
-
blue: "\x1B[34m",
|
|
142
|
-
dim: "\x1B[2m"
|
|
143
|
-
};
|
|
144
|
-
function resolveJsonMode(options = {}) {
|
|
145
|
-
return options.json ?? process.env["OUTFITTER_JSON"] === "1";
|
|
146
|
-
}
|
|
147
|
-
async function runCheckExports(options = {}) {
|
|
148
|
-
const cwd = process.cwd();
|
|
149
|
-
const configPath = resolve(cwd, "bunup.config.ts");
|
|
150
|
-
let workspaces;
|
|
151
|
-
try {
|
|
152
|
-
const configModule = await import(configPath);
|
|
153
|
-
const rawConfig = configModule.default;
|
|
154
|
-
if (!Array.isArray(rawConfig)) {
|
|
155
|
-
process.stderr.write(`bunup.config.ts must export a workspace array
|
|
156
|
-
`);
|
|
157
|
-
process.exit(1);
|
|
158
|
-
}
|
|
159
|
-
workspaces = rawConfig;
|
|
160
|
-
} catch {
|
|
161
|
-
process.stderr.write(`Could not load bunup.config.ts from ${cwd}
|
|
162
|
-
`);
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
165
|
-
const results = [];
|
|
166
|
-
for (const workspace of workspaces) {
|
|
167
|
-
const packageRoot = resolve(cwd, workspace.root);
|
|
168
|
-
const pkgPath = resolve(packageRoot, "package.json");
|
|
169
|
-
let pkg;
|
|
170
|
-
try {
|
|
171
|
-
pkg = await Bun.file(pkgPath).json();
|
|
172
|
-
} catch {
|
|
173
|
-
results.push({ name: workspace.name, status: "ok" });
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
const actual = typeof pkg.exports === "object" && pkg.exports !== null ? pkg.exports : {};
|
|
177
|
-
const expected = computeExpectedExports(packageRoot, workspace, pkg);
|
|
178
|
-
results.push(compareExports({
|
|
179
|
-
name: workspace.name,
|
|
180
|
-
actual,
|
|
181
|
-
expected,
|
|
182
|
-
path: workspace.root
|
|
183
|
-
}));
|
|
184
|
-
}
|
|
185
|
-
const checkResult = {
|
|
186
|
-
ok: results.every((r) => r.status === "ok"),
|
|
187
|
-
packages: results
|
|
188
|
-
};
|
|
189
|
-
if (resolveJsonMode(options)) {
|
|
190
|
-
process.stdout.write(`${JSON.stringify(checkResult, null, 2)}
|
|
191
|
-
`);
|
|
192
|
-
} else {
|
|
193
|
-
const drifted = results.filter((r) => r.status === "drift");
|
|
194
|
-
if (drifted.length === 0) {
|
|
195
|
-
process.stdout.write(`${COLORS.green}All ${results.length} packages have exports in sync.${COLORS.reset}
|
|
196
|
-
`);
|
|
197
|
-
} else {
|
|
198
|
-
process.stderr.write(`${COLORS.red}Export drift detected in ${drifted.length} package(s):${COLORS.reset}
|
|
199
|
-
|
|
200
|
-
`);
|
|
201
|
-
for (const result of drifted) {
|
|
202
|
-
const drift = result.drift;
|
|
203
|
-
if (!drift)
|
|
204
|
-
continue;
|
|
205
|
-
process.stderr.write(` ${COLORS.yellow}${result.name}${COLORS.reset} ${COLORS.dim}(${drift.path})${COLORS.reset}
|
|
206
|
-
`);
|
|
207
|
-
for (const key of drift.added) {
|
|
208
|
-
process.stderr.write(` ${COLORS.green}+ ${key}${COLORS.reset} ${COLORS.dim}(missing from package.json)${COLORS.reset}
|
|
209
|
-
`);
|
|
210
|
-
}
|
|
211
|
-
for (const key of drift.removed) {
|
|
212
|
-
process.stderr.write(` ${COLORS.red}- ${key}${COLORS.reset} ${COLORS.dim}(not in source)${COLORS.reset}
|
|
213
|
-
`);
|
|
214
|
-
}
|
|
215
|
-
for (const entry of drift.changed) {
|
|
216
|
-
process.stderr.write(` ${COLORS.yellow}~ ${entry.key}${COLORS.reset} ${COLORS.dim}(value mismatch)${COLORS.reset}
|
|
217
|
-
`);
|
|
218
|
-
}
|
|
219
|
-
process.stderr.write(`
|
|
220
|
-
`);
|
|
221
|
-
}
|
|
222
|
-
process.stderr.write(`Run ${COLORS.blue}bun run build${COLORS.reset} to regenerate exports.
|
|
223
|
-
`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
process.exit(checkResult.ok ? 0 : 1);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export { entryToSubpath, compareExports, resolveJsonMode, runCheckExports };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/registry/schema.ts
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
var FileEntrySchema = z.object({
|
|
5
|
-
path: z.string().min(1),
|
|
6
|
-
content: z.string(),
|
|
7
|
-
executable: z.boolean().optional(),
|
|
8
|
-
template: z.boolean().optional()
|
|
9
|
-
});
|
|
10
|
-
var BlockSchema = z.object({
|
|
11
|
-
name: z.string().min(1),
|
|
12
|
-
description: z.string().min(1),
|
|
13
|
-
files: z.array(FileEntrySchema).optional(),
|
|
14
|
-
dependencies: z.record(z.string()).optional(),
|
|
15
|
-
devDependencies: z.record(z.string()).optional(),
|
|
16
|
-
extends: z.array(z.string()).optional()
|
|
17
|
-
});
|
|
18
|
-
var RegistrySchema = z.object({
|
|
19
|
-
version: z.string(),
|
|
20
|
-
blocks: z.record(BlockSchema)
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
export { FileEntrySchema, BlockSchema, RegistrySchema };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/cli/init.ts
|
|
3
|
-
var FRAMEWORK_DETECTORS = {
|
|
4
|
-
react: ["react", "react-dom"],
|
|
5
|
-
next: ["next"],
|
|
6
|
-
vue: ["vue"],
|
|
7
|
-
nuxt: ["nuxt"],
|
|
8
|
-
svelte: ["svelte"],
|
|
9
|
-
angular: ["@angular/core"],
|
|
10
|
-
solid: ["solid-js"],
|
|
11
|
-
astro: ["astro"],
|
|
12
|
-
remix: ["@remix-run/react"],
|
|
13
|
-
qwik: ["@builder.io/qwik"]
|
|
14
|
-
};
|
|
15
|
-
function detectFrameworks(pkg) {
|
|
16
|
-
const allDeps = {
|
|
17
|
-
...pkg.dependencies,
|
|
18
|
-
...pkg.devDependencies
|
|
19
|
-
};
|
|
20
|
-
const detected = [];
|
|
21
|
-
for (const [framework, packages] of Object.entries(FRAMEWORK_DETECTORS)) {
|
|
22
|
-
if (packages.some((p) => (p in allDeps))) {
|
|
23
|
-
detected.push(framework);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (detected.length === 0) {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
return ["--frameworks", ...detected];
|
|
30
|
-
}
|
|
31
|
-
function buildUltraciteCommand(options) {
|
|
32
|
-
const cmd = [
|
|
33
|
-
"ultracite",
|
|
34
|
-
"init",
|
|
35
|
-
"--linter",
|
|
36
|
-
"biome",
|
|
37
|
-
"--pm",
|
|
38
|
-
"bun",
|
|
39
|
-
"--quiet"
|
|
40
|
-
];
|
|
41
|
-
if (options.frameworks && options.frameworks.length > 0) {
|
|
42
|
-
cmd.push("--frameworks", ...options.frameworks);
|
|
43
|
-
}
|
|
44
|
-
return cmd;
|
|
45
|
-
}
|
|
46
|
-
async function runInit(cwd = process.cwd()) {
|
|
47
|
-
const pkgPath = `${cwd}/package.json`;
|
|
48
|
-
const pkgFile = Bun.file(pkgPath);
|
|
49
|
-
if (!await pkgFile.exists()) {
|
|
50
|
-
process.stderr.write(`No package.json found in current directory
|
|
51
|
-
`);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
const pkg = await pkgFile.json();
|
|
55
|
-
const frameworkFlags = detectFrameworks(pkg);
|
|
56
|
-
const frameworks = frameworkFlags.length > 0 ? frameworkFlags.slice(1) : [];
|
|
57
|
-
const cmd = buildUltraciteCommand({ frameworks });
|
|
58
|
-
process.stdout.write(`Running: bun x ${cmd.join(" ")}
|
|
59
|
-
`);
|
|
60
|
-
const proc = Bun.spawn(["bun", "x", ...cmd], {
|
|
61
|
-
cwd,
|
|
62
|
-
stdio: ["inherit", "inherit", "inherit"]
|
|
63
|
-
});
|
|
64
|
-
const exitCode = await proc.exited;
|
|
65
|
-
process.exit(exitCode);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export { detectFrameworks, buildUltraciteCommand, runInit };
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// packages/tooling/src/cli/check-boundary-invocations.ts
|
|
3
|
-
import { relative, resolve } from "path";
|
|
4
|
-
var ROOT_RUNS_PACKAGE_SRC = /\bbun(?:x)?\s+(?:run\s+)?(?:\.\.\/|\.\/)?packages\/[^/\s]+\/src\/\S+/;
|
|
5
|
-
var CD_PACKAGE_THEN_RUNS_SRC = /\bcd\s+(?:\.\.\/|\.\/)?packages\/[^/\s]+\s*&&\s*bun(?:x)?\s+(?:run\s+)?(?:\.\.\/|\.\/)?src\/\S+/;
|
|
6
|
-
function detectBoundaryViolation(location) {
|
|
7
|
-
if (ROOT_RUNS_PACKAGE_SRC.test(location.command)) {
|
|
8
|
-
return { ...location, rule: "root-runs-package-src" };
|
|
9
|
-
}
|
|
10
|
-
if (CD_PACKAGE_THEN_RUNS_SRC.test(location.command)) {
|
|
11
|
-
return { ...location, rule: "cd-package-then-runs-src" };
|
|
12
|
-
}
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
function findBoundaryViolations(entries) {
|
|
16
|
-
const violations = [];
|
|
17
|
-
for (const entry of entries) {
|
|
18
|
-
for (const [scriptName, command] of Object.entries(entry.scripts)) {
|
|
19
|
-
const violation = detectBoundaryViolation({
|
|
20
|
-
file: entry.file,
|
|
21
|
-
scriptName,
|
|
22
|
-
command
|
|
23
|
-
});
|
|
24
|
-
if (violation) {
|
|
25
|
-
violations.push(violation);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return violations.sort((a, b) => {
|
|
30
|
-
const fileCompare = a.file.localeCompare(b.file);
|
|
31
|
-
if (fileCompare !== 0) {
|
|
32
|
-
return fileCompare;
|
|
33
|
-
}
|
|
34
|
-
return a.scriptName.localeCompare(b.scriptName);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
async function readScriptEntries(cwd, options = {}) {
|
|
38
|
-
const entries = [];
|
|
39
|
-
const rootPackagePath = resolve(cwd, "package.json");
|
|
40
|
-
const candidatePaths = [rootPackagePath];
|
|
41
|
-
if (options.appManifestRelativePaths) {
|
|
42
|
-
for (const file of options.appManifestRelativePaths) {
|
|
43
|
-
candidatePaths.push(resolve(cwd, file));
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
const appPackageGlob = new Bun.Glob("apps/*/package.json");
|
|
47
|
-
for (const match of appPackageGlob.scanSync({ cwd })) {
|
|
48
|
-
candidatePaths.push(resolve(cwd, match));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const readPackageJson = options.readPackageJson ?? (async (filePath) => await Bun.file(filePath).json());
|
|
52
|
-
for (const filePath of candidatePaths) {
|
|
53
|
-
const isRootManifest = filePath === rootPackagePath;
|
|
54
|
-
try {
|
|
55
|
-
const pkg = await readPackageJson(filePath);
|
|
56
|
-
if (!pkg.scripts) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
entries.push({
|
|
60
|
-
file: relative(cwd, filePath),
|
|
61
|
-
scripts: pkg.scripts
|
|
62
|
-
});
|
|
63
|
-
} catch (error) {
|
|
64
|
-
if (isRootManifest) {
|
|
65
|
-
const message = error instanceof Error ? error.message : "unknown parse error";
|
|
66
|
-
throw new Error(`Failed to read root package manifest (${filePath}): ${message}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return entries;
|
|
71
|
-
}
|
|
72
|
-
async function runCheckBoundaryInvocations() {
|
|
73
|
-
const cwd = process.cwd();
|
|
74
|
-
let entries;
|
|
75
|
-
try {
|
|
76
|
-
entries = await readScriptEntries(cwd);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
const message = error instanceof Error ? error.message : "unknown read failure";
|
|
79
|
-
process.stderr.write(`Boundary invocation check failed before evaluation: ${message}
|
|
80
|
-
`);
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
const violations = findBoundaryViolations(entries);
|
|
84
|
-
if (violations.length === 0) {
|
|
85
|
-
process.stdout.write(`No boundary invocation violations detected in root/apps scripts.
|
|
86
|
-
`);
|
|
87
|
-
process.exit(0);
|
|
88
|
-
}
|
|
89
|
-
process.stderr.write(`Boundary invocation violations detected:
|
|
90
|
-
|
|
91
|
-
`);
|
|
92
|
-
for (const violation of violations) {
|
|
93
|
-
process.stderr.write(`- ${violation.file}#${violation.scriptName}: ${violation.command}
|
|
94
|
-
`);
|
|
95
|
-
}
|
|
96
|
-
process.stderr.write("\nUse canonical command surfaces (e.g. `outfitter repo ...` or package bins) instead of executing packages/*/src directly.\n");
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export { detectBoundaryViolation, findBoundaryViolations, readScriptEntries, runCheckBoundaryInvocations };
|