rsetup 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-6SOBVOJQ.js → chunk-D3YJGGEE.js} +355 -158
- package/dist/index.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ npx rsetup --help
|
|
|
8
8
|
|
|
9
9
|
This is the public npm name for RepoSetup. After `npm install -g rsetup`, both `rsetup` and `reposetup` work.
|
|
10
10
|
|
|
11
|
-
This is the `0.2.
|
|
11
|
+
This is the `0.2.1` CLI. It requires Node.js 24 or later. Python recipes require Python 3.12 or later and uv; 3.12 and 3.13 are in the qualification matrix. Integrations are not all equally mature. Use `--dry-run` before changing an important project.
|
|
12
12
|
|
|
13
13
|
The workspace libraries `@reposetup/core`, `@reposetup/registry`, and `@reposetup/integrations` are bundled into this package. They are not published separately.
|
|
14
14
|
|
package/dist/bin.js
CHANGED
|
@@ -288,10 +288,10 @@ function mergeDefs(...defs) {
|
|
|
288
288
|
function cloneDef(schema) {
|
|
289
289
|
return mergeDefs(schema._zod.def);
|
|
290
290
|
}
|
|
291
|
-
function getElementAtPath(obj,
|
|
292
|
-
if (!
|
|
291
|
+
function getElementAtPath(obj, path13) {
|
|
292
|
+
if (!path13)
|
|
293
293
|
return obj;
|
|
294
|
-
return
|
|
294
|
+
return path13.reduce((acc, key) => acc?.[key], obj);
|
|
295
295
|
}
|
|
296
296
|
function promiseAllObject(promisesObj) {
|
|
297
297
|
const keys = Object.keys(promisesObj);
|
|
@@ -631,11 +631,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
631
631
|
}
|
|
632
632
|
return false;
|
|
633
633
|
}
|
|
634
|
-
function prefixIssues(
|
|
634
|
+
function prefixIssues(path13, issues) {
|
|
635
635
|
return issues.map((iss) => {
|
|
636
636
|
var _a3;
|
|
637
637
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
638
|
-
iss.path.unshift(
|
|
638
|
+
iss.path.unshift(path13);
|
|
639
639
|
return iss;
|
|
640
640
|
});
|
|
641
641
|
}
|
|
@@ -1081,16 +1081,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
|
1081
1081
|
}
|
|
1082
1082
|
function formatError(error2, mapper = (issue2) => issue2.message) {
|
|
1083
1083
|
const fieldErrors = { _errors: [] };
|
|
1084
|
-
const processError = (error3,
|
|
1084
|
+
const processError = (error3, path13 = []) => {
|
|
1085
1085
|
for (const issue2 of error3.issues) {
|
|
1086
1086
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1087
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1087
|
+
issue2.errors.map((issues) => processError({ issues }, [...path13, ...issue2.path]));
|
|
1088
1088
|
} else if (issue2.code === "invalid_key") {
|
|
1089
|
-
processError({ issues: issue2.issues }, [...
|
|
1089
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1090
1090
|
} else if (issue2.code === "invalid_element") {
|
|
1091
|
-
processError({ issues: issue2.issues }, [...
|
|
1091
|
+
processError({ issues: issue2.issues }, [...path13, ...issue2.path]);
|
|
1092
1092
|
} else {
|
|
1093
|
-
const fullpath = [...
|
|
1093
|
+
const fullpath = [...path13, ...issue2.path];
|
|
1094
1094
|
if (fullpath.length === 0) {
|
|
1095
1095
|
fieldErrors._errors.push(mapper(issue2));
|
|
1096
1096
|
} else {
|
|
@@ -5977,9 +5977,10 @@ import path from "path";
|
|
|
5977
5977
|
import { access as access2 } from "fs/promises";
|
|
5978
5978
|
import path2 from "path";
|
|
5979
5979
|
import path3 from "path";
|
|
5980
|
+
import path4 from "path";
|
|
5981
|
+
import path7 from "path";
|
|
5980
5982
|
import path6 from "path";
|
|
5981
5983
|
import path5 from "path";
|
|
5982
|
-
import path4 from "path";
|
|
5983
5984
|
import { createHash as createHash2 } from "crypto";
|
|
5984
5985
|
var INTEGRATION_CATEGORIES = [
|
|
5985
5986
|
"runtime",
|
|
@@ -6265,10 +6266,10 @@ async function firstExistingPath(files, candidates) {
|
|
|
6265
6266
|
}
|
|
6266
6267
|
return void 0;
|
|
6267
6268
|
}
|
|
6268
|
-
function evidence(kind, detail,
|
|
6269
|
+
function evidence(kind, detail, path82) {
|
|
6269
6270
|
const item = { kind, detail };
|
|
6270
|
-
if (
|
|
6271
|
-
item.path =
|
|
6271
|
+
if (path82 !== void 0) {
|
|
6272
|
+
item.path = path82;
|
|
6272
6273
|
}
|
|
6273
6274
|
return item;
|
|
6274
6275
|
}
|
|
@@ -7092,6 +7093,7 @@ var runCommandOperationSchema = strictObject({
|
|
|
7092
7093
|
requiresNetwork: boolean2().optional(),
|
|
7093
7094
|
interactive: boolean2().optional(),
|
|
7094
7095
|
longRunning: boolean2().optional(),
|
|
7096
|
+
skipsDependencyInstall: boolean2().optional(),
|
|
7095
7097
|
requiresLockfile: _enum(["package-lock.json", "pnpm-lock.yaml", "bun.lock", "uv.lock"]).optional()
|
|
7096
7098
|
});
|
|
7097
7099
|
var createDirectoryOperationSchema = strictObject({
|
|
@@ -8410,9 +8412,14 @@ function isProjectInstallCommand(operation) {
|
|
|
8410
8412
|
}
|
|
8411
8413
|
function ensureScaffoldDependencyInstall(operations, packageManager, projectRoot) {
|
|
8412
8414
|
const output = [];
|
|
8415
|
+
let pendingInstall;
|
|
8413
8416
|
for (const [index, operation] of operations.entries()) {
|
|
8417
|
+
if (pendingInstall !== void 0 && (operation.type === "run_command" || operation.type === "verify")) {
|
|
8418
|
+
output.push(pendingInstall);
|
|
8419
|
+
pendingInstall = void 0;
|
|
8420
|
+
}
|
|
8414
8421
|
output.push(operation);
|
|
8415
|
-
if (operation.type !== "run_command" || !operation.args.includes("--skip-install")) {
|
|
8422
|
+
if (operation.type !== "run_command" || operation.skipsDependencyInstall !== true && !operation.args.includes("--skip-install")) {
|
|
8416
8423
|
continue;
|
|
8417
8424
|
}
|
|
8418
8425
|
if (segmentCoversScaffoldInstall(operations, index + 1)) {
|
|
@@ -8438,8 +8445,9 @@ function ensureScaffoldDependencyInstall(operations, packageManager, projectRoot
|
|
|
8438
8445
|
if (!installed.ok) {
|
|
8439
8446
|
return { ok: false, error: installed.error };
|
|
8440
8447
|
}
|
|
8441
|
-
|
|
8448
|
+
pendingInstall = installed.operation;
|
|
8442
8449
|
}
|
|
8450
|
+
if (pendingInstall !== void 0) output.push(pendingInstall);
|
|
8443
8451
|
return { ok: true, operations: output };
|
|
8444
8452
|
}
|
|
8445
8453
|
function segmentCoversScaffoldInstall(operations, start) {
|
|
@@ -8501,7 +8509,23 @@ function planResolvedIds(resolved, registry2, ids) {
|
|
|
8501
8509
|
return {
|
|
8502
8510
|
...resolved,
|
|
8503
8511
|
orderedIntegrations: ordered,
|
|
8504
|
-
operations: validation.operations
|
|
8512
|
+
operations: projectRoot === "." ? validation.operations : [
|
|
8513
|
+
{
|
|
8514
|
+
type: "create_directory",
|
|
8515
|
+
path: projectRoot,
|
|
8516
|
+
behavior: "create_if_missing",
|
|
8517
|
+
description: "Create the selected project directory"
|
|
8518
|
+
},
|
|
8519
|
+
...validation.operations.map(
|
|
8520
|
+
(operation) => "path" in operation ? {
|
|
8521
|
+
...operation,
|
|
8522
|
+
path: path4.posix.join(
|
|
8523
|
+
projectRoot.replaceAll("\\", "/"),
|
|
8524
|
+
operation.path.replaceAll("\\", "/")
|
|
8525
|
+
)
|
|
8526
|
+
} : operation
|
|
8527
|
+
)
|
|
8528
|
+
]
|
|
8505
8529
|
};
|
|
8506
8530
|
}
|
|
8507
8531
|
function withBatchedInstalls(result) {
|
|
@@ -9240,10 +9264,10 @@ function resolveInsideRoot(rootDir, relativePath) {
|
|
|
9240
9264
|
})
|
|
9241
9265
|
};
|
|
9242
9266
|
}
|
|
9243
|
-
const root =
|
|
9244
|
-
const absolutePath =
|
|
9245
|
-
const relative =
|
|
9246
|
-
if (relative.startsWith("..") ||
|
|
9267
|
+
const root = path5.resolve(rootDir);
|
|
9268
|
+
const absolutePath = path5.resolve(root, relativePath);
|
|
9269
|
+
const relative = path5.relative(root, absolutePath);
|
|
9270
|
+
if (relative.startsWith("..") || path5.isAbsolute(relative)) {
|
|
9247
9271
|
return {
|
|
9248
9272
|
ok: false,
|
|
9249
9273
|
error: createRepoSetupError({
|
|
@@ -9261,8 +9285,8 @@ async function assertRealPathInsideRoot(rootDir, absolutePath, fs) {
|
|
|
9261
9285
|
const root = await fs.realpath(rootDir);
|
|
9262
9286
|
const existingAncestor = await nearestExistingAncestor(absolutePath, fs);
|
|
9263
9287
|
const resolvedAncestor = await fs.realpath(existingAncestor);
|
|
9264
|
-
const relative =
|
|
9265
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
9288
|
+
const relative = path5.relative(root, resolvedAncestor);
|
|
9289
|
+
if (relative === "" || !relative.startsWith("..") && !path5.isAbsolute(relative)) {
|
|
9266
9290
|
return { ok: true };
|
|
9267
9291
|
}
|
|
9268
9292
|
return escapedPathError(absolutePath, rootDir);
|
|
@@ -9282,9 +9306,9 @@ async function assertRealPathInsideRoot(rootDir, absolutePath, fs) {
|
|
|
9282
9306
|
}
|
|
9283
9307
|
}
|
|
9284
9308
|
async function nearestExistingAncestor(pathToCheck, fs) {
|
|
9285
|
-
let current =
|
|
9309
|
+
let current = path5.resolve(pathToCheck);
|
|
9286
9310
|
while (!await fs.exists(current)) {
|
|
9287
|
-
const parent =
|
|
9311
|
+
const parent = path5.dirname(current);
|
|
9288
9312
|
if (parent === current) {
|
|
9289
9313
|
return current;
|
|
9290
9314
|
}
|
|
@@ -9460,7 +9484,8 @@ async function executeModifyText(operation, context) {
|
|
|
9460
9484
|
}
|
|
9461
9485
|
const crlfOldText = operation.oldText.replaceAll("\n", "\r\n");
|
|
9462
9486
|
const matchedText = content.includes(operation.oldText) ? operation.oldText : content.includes(crlfOldText) ? crlfOldText : operation.oldText;
|
|
9463
|
-
const
|
|
9487
|
+
const usesCrlf = operation.oldText.includes("\n") ? matchedText === crlfOldText && crlfOldText !== operation.oldText : content.includes("\r\n");
|
|
9488
|
+
const replacementText = usesCrlf ? operation.newText.replaceAll("\n", "\r\n") : operation.newText;
|
|
9464
9489
|
const matches = content.split(matchedText).length - 1;
|
|
9465
9490
|
if (matches === 0) {
|
|
9466
9491
|
return mutationFailed(`Text to replace was not found in "${operation.path}".`, {
|
|
@@ -9544,9 +9569,9 @@ async function executeAddEnvExample(operation, context) {
|
|
|
9544
9569
|
return void 0;
|
|
9545
9570
|
}
|
|
9546
9571
|
async function ensureParentDirectory(absoluteFilePath, context) {
|
|
9547
|
-
const parent =
|
|
9548
|
-
const relative =
|
|
9549
|
-
if (relative.startsWith("..") ||
|
|
9572
|
+
const parent = path6.dirname(absoluteFilePath);
|
|
9573
|
+
const relative = path6.relative(context.rootDir, parent);
|
|
9574
|
+
if (relative.startsWith("..") || path6.isAbsolute(relative)) {
|
|
9550
9575
|
return createRepoSetupError({
|
|
9551
9576
|
code: "PLAN_INVALID",
|
|
9552
9577
|
message: "Refusing to create a parent directory outside the project root.",
|
|
@@ -9994,7 +10019,15 @@ async function checkRequiredLockfile(operations, context) {
|
|
|
9994
10019
|
if (operation.type !== "run_command" || operation.requiresLockfile === void 0) {
|
|
9995
10020
|
continue;
|
|
9996
10021
|
}
|
|
9997
|
-
|
|
10022
|
+
const directory = resolveInsideRoot(context.rootDir, operation.cwd);
|
|
10023
|
+
if (!directory.ok) return directory.error;
|
|
10024
|
+
const realPath = await assertRealPathInsideRoot(
|
|
10025
|
+
context.rootDir,
|
|
10026
|
+
directory.absolutePath,
|
|
10027
|
+
context.fs
|
|
10028
|
+
);
|
|
10029
|
+
if (!realPath.ok) return realPath.error;
|
|
10030
|
+
if (await context.fs.exists(`${directory.absolutePath}/${operation.requiresLockfile}`)) {
|
|
9998
10031
|
continue;
|
|
9999
10032
|
}
|
|
10000
10033
|
return createRepoSetupError({
|
|
@@ -10007,41 +10040,52 @@ async function checkRequiredLockfile(operations, context) {
|
|
|
10007
10040
|
return void 0;
|
|
10008
10041
|
}
|
|
10009
10042
|
function packageManagersInPlan(operations) {
|
|
10010
|
-
const
|
|
10043
|
+
const directories = /* @__PURE__ */ new Map();
|
|
10011
10044
|
for (const operation of operations) {
|
|
10045
|
+
let manager;
|
|
10012
10046
|
if (operation.type === "install_package") {
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10047
|
+
manager = operation.packageManager;
|
|
10048
|
+
} else if (operation.type === "run_command") {
|
|
10049
|
+
if (operation.skipsDependencyInstall === true || operation.args.includes("--skip-install"))
|
|
10050
|
+
continue;
|
|
10051
|
+
if (operation.command === "npm" || operation.command === "npx") manager = "npm";
|
|
10052
|
+
else if (operation.command === "pnpm") manager = "pnpm";
|
|
10053
|
+
else if (operation.command === "uv") manager = "uv";
|
|
10018
10054
|
}
|
|
10019
|
-
if (
|
|
10020
|
-
managers.
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
} else if (operation.command === "uv") {
|
|
10024
|
-
managers.add("uv");
|
|
10055
|
+
if (manager !== void 0 && "cwd" in operation) {
|
|
10056
|
+
const managers = directories.get(operation.cwd) ?? /* @__PURE__ */ new Set();
|
|
10057
|
+
managers.add(manager);
|
|
10058
|
+
directories.set(operation.cwd, managers);
|
|
10025
10059
|
}
|
|
10026
10060
|
}
|
|
10027
|
-
return
|
|
10061
|
+
return directories;
|
|
10028
10062
|
}
|
|
10029
10063
|
async function checkLockfileCompatibility(operations, context) {
|
|
10030
|
-
const
|
|
10064
|
+
const directories = packageManagersInPlan(operations);
|
|
10031
10065
|
const lockfiles = [
|
|
10032
10066
|
{ manager: "npm", file: "package-lock.json" },
|
|
10033
10067
|
{ manager: "pnpm", file: "pnpm-lock.yaml" },
|
|
10034
10068
|
{ manager: "bun", file: "bun.lock" },
|
|
10035
10069
|
{ manager: "uv", file: "uv.lock" }
|
|
10036
10070
|
];
|
|
10037
|
-
for (const
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
|
|
10044
|
-
|
|
10071
|
+
for (const [cwd, managers] of directories) {
|
|
10072
|
+
const directory = resolveInsideRoot(context.rootDir, cwd);
|
|
10073
|
+
if (!directory.ok) return directory.error;
|
|
10074
|
+
const realPath = await assertRealPathInsideRoot(
|
|
10075
|
+
context.rootDir,
|
|
10076
|
+
directory.absolutePath,
|
|
10077
|
+
context.fs
|
|
10078
|
+
);
|
|
10079
|
+
if (!realPath.ok) return realPath.error;
|
|
10080
|
+
for (const lockfile of lockfiles) {
|
|
10081
|
+
if (managers.size > 0 && !managers.has(lockfile.manager) && await context.fs.exists(`${directory.absolutePath}/${lockfile.file}`))
|
|
10082
|
+
return createRepoSetupError({
|
|
10083
|
+
code: "LOCKFILE_CONFLICT",
|
|
10084
|
+
message: `Found ${lockfile.file}, which conflicts with this plan's package manager.`,
|
|
10085
|
+
details: { lockfile: lockfile.file, cwd, managers: [...managers] },
|
|
10086
|
+
suggestion: "Use the package manager recorded by the existing lockfile or remove the conflicting lockfile deliberately."
|
|
10087
|
+
});
|
|
10088
|
+
}
|
|
10045
10089
|
}
|
|
10046
10090
|
return void 0;
|
|
10047
10091
|
}
|
|
@@ -10133,7 +10177,7 @@ var silentLogger = {
|
|
|
10133
10177
|
};
|
|
10134
10178
|
async function executeInstallation(operations, options) {
|
|
10135
10179
|
const context = {
|
|
10136
|
-
rootDir:
|
|
10180
|
+
rootDir: path7.resolve(options.rootDir),
|
|
10137
10181
|
fs: options.fs,
|
|
10138
10182
|
runProcess: options.runProcess,
|
|
10139
10183
|
logger: options.logger ?? silentLogger,
|
|
@@ -10354,7 +10398,7 @@ import {
|
|
|
10354
10398
|
unlink,
|
|
10355
10399
|
writeFile
|
|
10356
10400
|
} from "fs/promises";
|
|
10357
|
-
import
|
|
10401
|
+
import path8 from "path";
|
|
10358
10402
|
import os from "os";
|
|
10359
10403
|
var DEFAULT_COMMAND_TIMEOUT_MS = 5 * 6e4;
|
|
10360
10404
|
var DEFAULT_LONG_RUNNING_COMMAND_TIMEOUT_MS = 30 * 6e4;
|
|
@@ -10363,9 +10407,9 @@ var DEFAULT_MINIMUM_FREE_DISK_BYTES = 512 * 1024 * 1024;
|
|
|
10363
10407
|
function createDefaultExecutionLock() {
|
|
10364
10408
|
return {
|
|
10365
10409
|
async acquire(rootDir) {
|
|
10366
|
-
const lockRoot =
|
|
10410
|
+
const lockRoot = path8.join(os.tmpdir(), "reposetup-locks");
|
|
10367
10411
|
const lockId = createHash("sha256").update(rootDir).digest("hex");
|
|
10368
|
-
const lockPath =
|
|
10412
|
+
const lockPath = path8.join(lockRoot, lockId);
|
|
10369
10413
|
try {
|
|
10370
10414
|
await mkdir(lockRoot, { recursive: true, mode: 448 });
|
|
10371
10415
|
await mkdir(lockPath, { mode: 448 });
|
|
@@ -10388,12 +10432,12 @@ function createDefaultExecutionLock() {
|
|
|
10388
10432
|
}
|
|
10389
10433
|
function createDefaultExecutionJournal(options = {}) {
|
|
10390
10434
|
let journalPath;
|
|
10391
|
-
const directory = options.directory ??
|
|
10435
|
+
const directory = options.directory ?? path8.join(os.tmpdir(), "reposetup-journals");
|
|
10392
10436
|
return {
|
|
10393
10437
|
async start(rootDir) {
|
|
10394
10438
|
const rootHash = createHash("sha256").update(rootDir).digest("hex");
|
|
10395
10439
|
await mkdir(directory, { recursive: true, mode: 448 });
|
|
10396
|
-
journalPath =
|
|
10440
|
+
journalPath = path8.join(directory, `${rootHash}-${randomUUID()}.jsonl`);
|
|
10397
10441
|
await writeFile(
|
|
10398
10442
|
journalPath,
|
|
10399
10443
|
`${JSON.stringify({ version: 1, rootHash, status: "started" })}
|
|
@@ -10464,9 +10508,9 @@ function createDefaultExecutorFileSystem() {
|
|
|
10464
10508
|
await writeFile(filePath, content, "utf8");
|
|
10465
10509
|
},
|
|
10466
10510
|
async writeFileAtomic(filePath, content) {
|
|
10467
|
-
const temporaryPath =
|
|
10468
|
-
|
|
10469
|
-
`.${
|
|
10511
|
+
const temporaryPath = path8.join(
|
|
10512
|
+
path8.dirname(filePath),
|
|
10513
|
+
`.${path8.basename(filePath)}.reposetup-${randomUUID()}.tmp`
|
|
10470
10514
|
);
|
|
10471
10515
|
try {
|
|
10472
10516
|
await writeFile(temporaryPath, content, { encoding: "utf8", flag: "wx" });
|
|
@@ -10484,6 +10528,18 @@ function createDefaultExecutorFileSystem() {
|
|
|
10484
10528
|
}
|
|
10485
10529
|
};
|
|
10486
10530
|
}
|
|
10531
|
+
function childProcessEnvironment(environment) {
|
|
10532
|
+
const outerLaunchKeys = /* @__PURE__ */ new Set([
|
|
10533
|
+
"npm_config_package",
|
|
10534
|
+
"npm_config_call",
|
|
10535
|
+
"npm_config_user_agent",
|
|
10536
|
+
"npm_execpath",
|
|
10537
|
+
"npm_node_execpath"
|
|
10538
|
+
]);
|
|
10539
|
+
return Object.fromEntries(
|
|
10540
|
+
Object.entries(environment).filter(([key]) => !outerLaunchKeys.has(key.toLowerCase()))
|
|
10541
|
+
);
|
|
10542
|
+
}
|
|
10487
10543
|
function createDefaultProcessRunner() {
|
|
10488
10544
|
return (request) => {
|
|
10489
10545
|
if (request.signal?.aborted === true) {
|
|
@@ -10496,7 +10552,7 @@ function createDefaultProcessRunner() {
|
|
|
10496
10552
|
return new Promise((resolve) => {
|
|
10497
10553
|
const child = spawn(launch.command, [...launch.args], {
|
|
10498
10554
|
cwd: request.cwd,
|
|
10499
|
-
env: process.env,
|
|
10555
|
+
env: childProcessEnvironment(process.env),
|
|
10500
10556
|
shell: false,
|
|
10501
10557
|
stdio: ["ignore", "pipe", "pipe"],
|
|
10502
10558
|
windowsHide: true,
|
|
@@ -10600,7 +10656,7 @@ function findWindowsExecutable(command, environment, exists) {
|
|
|
10600
10656
|
].filter(Boolean);
|
|
10601
10657
|
for (const directory of directories) {
|
|
10602
10658
|
for (const extension of extensions) {
|
|
10603
|
-
const candidate =
|
|
10659
|
+
const candidate = path8.win32.join(directory, `${command}${extension}`);
|
|
10604
10660
|
if (exists(candidate)) {
|
|
10605
10661
|
return candidate;
|
|
10606
10662
|
}
|
|
@@ -10609,7 +10665,7 @@ function findWindowsExecutable(command, environment, exists) {
|
|
|
10609
10665
|
return void 0;
|
|
10610
10666
|
}
|
|
10611
10667
|
function isNativeWindowsExecutable(filePath) {
|
|
10612
|
-
const extension =
|
|
10668
|
+
const extension = path8.win32.extname(filePath).toLowerCase();
|
|
10613
10669
|
return extension === ".exe" || extension === ".com";
|
|
10614
10670
|
}
|
|
10615
10671
|
function isSimpleExecutableName(value) {
|
|
@@ -10785,8 +10841,8 @@ function createDefaultIo() {
|
|
|
10785
10841
|
}
|
|
10786
10842
|
function createDefaultFs() {
|
|
10787
10843
|
return {
|
|
10788
|
-
async readFile(
|
|
10789
|
-
return readFile3(
|
|
10844
|
+
async readFile(path13) {
|
|
10845
|
+
return readFile3(path13, "utf8");
|
|
10790
10846
|
}
|
|
10791
10847
|
};
|
|
10792
10848
|
}
|
|
@@ -10798,7 +10854,7 @@ function writeLine(write, text) {
|
|
|
10798
10854
|
// src/prompt-create.ts
|
|
10799
10855
|
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
10800
10856
|
var PACKAGE_MANAGERS_BY_RUNTIME = {
|
|
10801
|
-
node: ["npm", "pnpm"
|
|
10857
|
+
node: ["npm", "pnpm"],
|
|
10802
10858
|
python: ["uv", "pip"]
|
|
10803
10859
|
};
|
|
10804
10860
|
var OPTIONAL_PROMPT_GROUPS = [
|
|
@@ -11210,7 +11266,7 @@ async function confirmCreate() {
|
|
|
11210
11266
|
}
|
|
11211
11267
|
|
|
11212
11268
|
// src/create.ts
|
|
11213
|
-
import
|
|
11269
|
+
import path10 from "path";
|
|
11214
11270
|
|
|
11215
11271
|
// src/presets.ts
|
|
11216
11272
|
var BUNDLED_PRESETS = [
|
|
@@ -11362,9 +11418,9 @@ function copySelection(selection) {
|
|
|
11362
11418
|
}
|
|
11363
11419
|
|
|
11364
11420
|
// src/load-config.ts
|
|
11365
|
-
import
|
|
11421
|
+
import path9 from "path";
|
|
11366
11422
|
async function loadRepoSetupConfigFile(configPath, deps) {
|
|
11367
|
-
const resolvedPath =
|
|
11423
|
+
const resolvedPath = path9.resolve(deps.cwd, configPath);
|
|
11368
11424
|
let raw;
|
|
11369
11425
|
try {
|
|
11370
11426
|
raw = await deps.fs.readFile(resolvedPath);
|
|
@@ -11418,12 +11474,12 @@ function postCreateCommands(config2) {
|
|
|
11418
11474
|
return config2.packageManager === "uv" ? ["uv run flask run", ...integrationIds.has("pytest") ? ["uv run pytest"] : []] : ["flask run", ...integrationIds.has("pytest") ? ["pytest"] : []];
|
|
11419
11475
|
case "fastify":
|
|
11420
11476
|
case "express":
|
|
11421
|
-
return config2.framework.options?.typescript
|
|
11477
|
+
return config2.framework.options?.typescript !== false ? [
|
|
11422
11478
|
`${packageRun} dev`,
|
|
11423
11479
|
`${packageRun} build`,
|
|
11424
11480
|
`${packageRun} start`,
|
|
11425
11481
|
...integrationIds.has("vitest") ? [`${config2.packageManager} exec vitest run`] : []
|
|
11426
|
-
] : ["node app.js"];
|
|
11482
|
+
] : [config2.framework.id === "fastify" ? "node server.js" : "node app.js"];
|
|
11427
11483
|
default:
|
|
11428
11484
|
return [];
|
|
11429
11485
|
}
|
|
@@ -11516,7 +11572,7 @@ async function handleCreate(input2) {
|
|
|
11516
11572
|
writeLine(input2.deps.io.writeOut, `Elapsed: ${elapsedSeconds}s.`);
|
|
11517
11573
|
writeLine(
|
|
11518
11574
|
input2.deps.io.writeOut,
|
|
11519
|
-
`Project directory: ${
|
|
11575
|
+
`Project directory: ${path10.resolve(input2.deps.cwd, planned.config.project.path ?? ".")}`
|
|
11520
11576
|
);
|
|
11521
11577
|
for (const command of postCreateCommands(planned.config)) {
|
|
11522
11578
|
writeLine(input2.deps.io.writeOut, `Next: ${command}`);
|
|
@@ -11683,18 +11739,18 @@ function findRequirementCycles(definitions) {
|
|
|
11683
11739
|
}
|
|
11684
11740
|
return [...cycles.values()];
|
|
11685
11741
|
}
|
|
11686
|
-
function visit(node2,
|
|
11742
|
+
function visit(node2, path13, edges, color, cycles) {
|
|
11687
11743
|
color.set(node2, "gray");
|
|
11688
11744
|
for (const next of edges.get(node2) ?? []) {
|
|
11689
11745
|
const nextColor = color.get(next);
|
|
11690
11746
|
if (nextColor === "gray") {
|
|
11691
|
-
const start =
|
|
11692
|
-
const cycle = canonicalizeCycle([...
|
|
11747
|
+
const start = path13.indexOf(next);
|
|
11748
|
+
const cycle = canonicalizeCycle([...path13.slice(start), next]);
|
|
11693
11749
|
cycles.set(cycle.join("\0"), cycle);
|
|
11694
11750
|
continue;
|
|
11695
11751
|
}
|
|
11696
11752
|
if (nextColor === "white") {
|
|
11697
|
-
visit(next, [...
|
|
11753
|
+
visit(next, [...path13, next], edges, color, cycles);
|
|
11698
11754
|
}
|
|
11699
11755
|
}
|
|
11700
11756
|
color.set(node2, "black");
|
|
@@ -12023,8 +12079,8 @@ function hasSelectedIntegration(context, id) {
|
|
|
12023
12079
|
return context.config.framework.id === id || context.config.integrations.some((integration) => integration.id === id);
|
|
12024
12080
|
}
|
|
12025
12081
|
var QUALIFIED_VERSIONS = {
|
|
12026
|
-
createNextApp: "16.3.
|
|
12027
|
-
eslintConfigNext: "16.3.
|
|
12082
|
+
createNextApp: "16.3.6",
|
|
12083
|
+
eslintConfigNext: "16.3.6",
|
|
12028
12084
|
vite: "8.3.0",
|
|
12029
12085
|
eslint: "9.39.5",
|
|
12030
12086
|
eslintJs: "9.39.5",
|
|
@@ -12110,11 +12166,13 @@ var DIRECT_VERSIONS = {
|
|
|
12110
12166
|
zod: [npmPin("zod", QUALIFIED_VERSIONS.zod)],
|
|
12111
12167
|
vitest: [
|
|
12112
12168
|
npmPin("vitest", QUALIFIED_VERSIONS.vitest),
|
|
12169
|
+
npmPin("vite", QUALIFIED_VERSIONS.vite),
|
|
12113
12170
|
npmPin("@vitejs/plugin-react", QUALIFIED_VERSIONS.vitePluginReact),
|
|
12114
12171
|
npmPin("jsdom", QUALIFIED_VERSIONS.jsdom),
|
|
12115
12172
|
npmPin("@testing-library/react", QUALIFIED_VERSIONS.testingLibraryReact),
|
|
12116
12173
|
npmPin("@testing-library/dom", QUALIFIED_VERSIONS.testingLibraryDom),
|
|
12117
|
-
npmPin("vite-tsconfig-paths", QUALIFIED_VERSIONS.viteTsconfigPaths)
|
|
12174
|
+
npmPin("vite-tsconfig-paths", QUALIFIED_VERSIONS.viteTsconfigPaths),
|
|
12175
|
+
npmPin("@types/node", QUALIFIED_VERSIONS.typesNode)
|
|
12118
12176
|
],
|
|
12119
12177
|
"testing-library": [
|
|
12120
12178
|
npmPin("@testing-library/react", QUALIFIED_VERSIONS.testingLibraryReact),
|
|
@@ -12374,11 +12432,11 @@ var dockerComposeIntegration = defineIntegration({
|
|
|
12374
12432
|
return { supported: true };
|
|
12375
12433
|
},
|
|
12376
12434
|
async detect(context) {
|
|
12377
|
-
const
|
|
12378
|
-
if (
|
|
12435
|
+
const path13 = await firstExistingPath2(context.files, COMPOSE_PATHS);
|
|
12436
|
+
if (path13 === void 0) {
|
|
12379
12437
|
return notDetected();
|
|
12380
12438
|
}
|
|
12381
|
-
return detectedResult("certain", [evidence("file", `Found ${
|
|
12439
|
+
return detectedResult("certain", [evidence("file", `Found ${path13}`, path13)]);
|
|
12382
12440
|
},
|
|
12383
12441
|
plan(context) {
|
|
12384
12442
|
if (!hasSelectedIntegration(context, "postgresql")) {
|
|
@@ -12420,11 +12478,19 @@ var dockerIntegration = defineIntegration({
|
|
|
12420
12478
|
return supportsNodeOrPython(context);
|
|
12421
12479
|
},
|
|
12422
12480
|
async detect(context) {
|
|
12423
|
-
const dockerfile = await context.files
|
|
12424
|
-
|
|
12481
|
+
const dockerfile = await firstExistingPath2(context.files, [
|
|
12482
|
+
"Dockerfile",
|
|
12483
|
+
"compose.yaml",
|
|
12484
|
+
"compose.yml",
|
|
12485
|
+
"docker-compose.yaml",
|
|
12486
|
+
"docker-compose.yml"
|
|
12487
|
+
]);
|
|
12488
|
+
if (dockerfile === void 0) {
|
|
12425
12489
|
return notDetected();
|
|
12426
12490
|
}
|
|
12427
|
-
return detectedResult("likely", [
|
|
12491
|
+
return detectedResult("likely", [
|
|
12492
|
+
evidence("file", `Found Docker configuration: ${dockerfile}`, dockerfile)
|
|
12493
|
+
]);
|
|
12428
12494
|
},
|
|
12429
12495
|
plan() {
|
|
12430
12496
|
return [
|
|
@@ -12837,6 +12903,7 @@ var expressOptionsSchema = strictObject({
|
|
|
12837
12903
|
var EXPRESS_TSCONFIG = `{
|
|
12838
12904
|
"compilerOptions": {
|
|
12839
12905
|
"target": "esnext",
|
|
12906
|
+
"rootDir": ".",
|
|
12840
12907
|
"module": "nodenext",
|
|
12841
12908
|
"rewriteRelativeImportExtensions": true,
|
|
12842
12909
|
"erasableSyntaxOnly": true,
|
|
@@ -12855,7 +12922,20 @@ app.get("/", (req: Request, res: Response) => {
|
|
|
12855
12922
|
});
|
|
12856
12923
|
|
|
12857
12924
|
if (process.env.REPOSETUP_NO_LISTEN !== "1") {
|
|
12858
|
-
app.listen(
|
|
12925
|
+
const server = app.listen(
|
|
12926
|
+
Number(process.env.PORT ?? "3000"),
|
|
12927
|
+
(error?: Error) => {
|
|
12928
|
+
if (error !== undefined) {
|
|
12929
|
+
console.error(error);
|
|
12930
|
+
process.exitCode = 1;
|
|
12931
|
+
return;
|
|
12932
|
+
}
|
|
12933
|
+
const address = server.address();
|
|
12934
|
+
if (address !== null && typeof address !== "string") {
|
|
12935
|
+
console.log("http://localhost:" + address.port);
|
|
12936
|
+
}
|
|
12937
|
+
},
|
|
12938
|
+
);
|
|
12859
12939
|
}
|
|
12860
12940
|
`;
|
|
12861
12941
|
var EXPRESS_ENDPOINT_TEST = `import type { Server } from "node:http";
|
|
@@ -12889,14 +12969,6 @@ it("returns the Hello World response", async () => {
|
|
|
12889
12969
|
expect(await response.text()).toBe("Hello World!");
|
|
12890
12970
|
});
|
|
12891
12971
|
`;
|
|
12892
|
-
var EXPRESS_README = `# Express app
|
|
12893
|
-
|
|
12894
|
-
Run the JavaScript entry with:
|
|
12895
|
-
|
|
12896
|
-
\`node app.js\`
|
|
12897
|
-
|
|
12898
|
-
For the TypeScript entry, use \`npm run dev\` while developing, then run \`npm run build\` and \`npm start\`.
|
|
12899
|
-
`;
|
|
12900
12972
|
var EXPRESS_APP_JS = `import express from "express";
|
|
12901
12973
|
|
|
12902
12974
|
const app = express();
|
|
@@ -12905,7 +12977,17 @@ app.get("/", (req, res) => {
|
|
|
12905
12977
|
res.send("Hello World!");
|
|
12906
12978
|
});
|
|
12907
12979
|
|
|
12908
|
-
app.listen(3000)
|
|
12980
|
+
const server = app.listen(3000, (error) => {
|
|
12981
|
+
if (error !== undefined) {
|
|
12982
|
+
console.error(error);
|
|
12983
|
+
process.exitCode = 1;
|
|
12984
|
+
return;
|
|
12985
|
+
}
|
|
12986
|
+
const address = server.address();
|
|
12987
|
+
if (address !== null && typeof address !== "string") {
|
|
12988
|
+
console.log("http://localhost:" + address.port);
|
|
12989
|
+
}
|
|
12990
|
+
});
|
|
12909
12991
|
`;
|
|
12910
12992
|
var expressIntegration = defineIntegration({
|
|
12911
12993
|
id: "express",
|
|
@@ -12956,7 +13038,8 @@ var expressIntegration = defineIntegration({
|
|
|
12956
13038
|
],
|
|
12957
13039
|
{
|
|
12958
13040
|
description: "Install TypeScript, tsx, and Express type packages",
|
|
12959
|
-
dev: true
|
|
13041
|
+
dev: true,
|
|
13042
|
+
allowBuild: ["esbuild"]
|
|
12960
13043
|
}
|
|
12961
13044
|
),
|
|
12962
13045
|
{
|
|
@@ -12986,7 +13069,7 @@ var expressIntegration = defineIntegration({
|
|
|
12986
13069
|
scripts: {
|
|
12987
13070
|
dev: "tsx watch src/app.ts",
|
|
12988
13071
|
build: "tsc --outDir dist",
|
|
12989
|
-
start: "node dist/app.js"
|
|
13072
|
+
start: "node dist/src/app.js"
|
|
12990
13073
|
}
|
|
12991
13074
|
},
|
|
12992
13075
|
behavior: "merge",
|
|
@@ -13014,7 +13097,14 @@ var expressIntegration = defineIntegration({
|
|
|
13014
13097
|
operations.push({
|
|
13015
13098
|
type: "create_file",
|
|
13016
13099
|
path: "README.md",
|
|
13017
|
-
content:
|
|
13100
|
+
content: [
|
|
13101
|
+
"# Express app",
|
|
13102
|
+
"",
|
|
13103
|
+
"From this directory:",
|
|
13104
|
+
"",
|
|
13105
|
+
typescript ? "Develop with `" + (context.config.packageManager === "npm" ? "npm run" : "pnpm") + " dev`, then build with `" + (context.config.packageManager === "npm" ? "npm run" : "pnpm") + " build` and run `" + (context.config.packageManager === "npm" ? "npm run" : "pnpm") + " start`." : "Run the JavaScript entry with `node app.js`.",
|
|
13106
|
+
""
|
|
13107
|
+
].join("\n"),
|
|
13018
13108
|
behavior: "fail_if_exists",
|
|
13019
13109
|
description: "Add Express run instructions"
|
|
13020
13110
|
});
|
|
@@ -13027,14 +13117,22 @@ var expressIntegration = defineIntegration({
|
|
|
13027
13117
|
]);
|
|
13028
13118
|
}
|
|
13029
13119
|
});
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13120
|
+
function pythonAppReadme(context, title, command) {
|
|
13121
|
+
const prefix = context.config.packageManager === "uv" ? "uv run " : "";
|
|
13122
|
+
const lines = [
|
|
13123
|
+
`# ${title} app`,
|
|
13124
|
+
"",
|
|
13125
|
+
"From this directory, start the development server with:",
|
|
13126
|
+
"",
|
|
13127
|
+
`\`${prefix}${command}\``,
|
|
13128
|
+
""
|
|
13129
|
+
];
|
|
13130
|
+
if (context.config.packageManager === "pip")
|
|
13131
|
+
lines.push("Activate the Python environment used during installation first.", "");
|
|
13132
|
+
if (hasSelectedIntegration(context, "pytest"))
|
|
13133
|
+
lines.push(`Run the generated endpoint test with \`${prefix}pytest\`.`, "");
|
|
13134
|
+
return lines.join("\n");
|
|
13135
|
+
}
|
|
13038
13136
|
var FASTAPI_MAIN = `from fastapi import FastAPI
|
|
13039
13137
|
|
|
13040
13138
|
app = FastAPI()
|
|
@@ -13109,7 +13207,7 @@ var fastapiIntegration = defineIntegration({
|
|
|
13109
13207
|
{
|
|
13110
13208
|
type: "create_file",
|
|
13111
13209
|
path: "README.md",
|
|
13112
|
-
content:
|
|
13210
|
+
content: pythonAppReadme(context, "FastAPI", "fastapi dev"),
|
|
13113
13211
|
behavior: "fail_if_exists",
|
|
13114
13212
|
description: "Add FastAPI run instructions"
|
|
13115
13213
|
},
|
|
@@ -13134,6 +13232,7 @@ var fastifyOptionsSchema = strictObject({
|
|
|
13134
13232
|
var FASTIFY_TSCONFIG = `{
|
|
13135
13233
|
"compilerOptions": {
|
|
13136
13234
|
"target": "esnext",
|
|
13235
|
+
"rootDir": ".",
|
|
13137
13236
|
"module": "nodenext",
|
|
13138
13237
|
"rewriteRelativeImportExtensions": true,
|
|
13139
13238
|
"erasableSyntaxOnly": true,
|
|
@@ -13152,11 +13251,12 @@ app.get("/", function () {
|
|
|
13152
13251
|
});
|
|
13153
13252
|
|
|
13154
13253
|
if (process.env.REPOSETUP_NO_LISTEN !== "1") {
|
|
13155
|
-
app.listen({ port: Number(process.env.PORT ?? "3000"), host: "127.0.0.1" }, (error) => {
|
|
13254
|
+
app.listen({ port: Number(process.env.PORT ?? "3000"), host: "127.0.0.1" }, (error, address) => {
|
|
13156
13255
|
if (error) {
|
|
13157
|
-
|
|
13256
|
+
console.error(error);
|
|
13158
13257
|
process.exit(1);
|
|
13159
13258
|
}
|
|
13259
|
+
console.log(address);
|
|
13160
13260
|
});
|
|
13161
13261
|
}
|
|
13162
13262
|
`;
|
|
@@ -13271,7 +13371,7 @@ var fastifyIntegration = defineIntegration({
|
|
|
13271
13371
|
scripts: {
|
|
13272
13372
|
dev: "tsx watch src/server.ts",
|
|
13273
13373
|
build: "tsc --outDir dist",
|
|
13274
|
-
start: "node dist/server.js"
|
|
13374
|
+
start: "node dist/src/server.js"
|
|
13275
13375
|
}
|
|
13276
13376
|
},
|
|
13277
13377
|
behavior: "merge",
|
|
@@ -13309,14 +13409,6 @@ var fastifyIntegration = defineIntegration({
|
|
|
13309
13409
|
]);
|
|
13310
13410
|
}
|
|
13311
13411
|
});
|
|
13312
|
-
var FLASK_README = `# Flask app
|
|
13313
|
-
|
|
13314
|
-
From this directory, start the development server with:
|
|
13315
|
-
|
|
13316
|
-
\`uv run flask run\`
|
|
13317
|
-
|
|
13318
|
-
Run the generated endpoint test with \`uv run pytest\`.
|
|
13319
|
-
`;
|
|
13320
13412
|
var FLASK_APP = `from flask import Flask
|
|
13321
13413
|
|
|
13322
13414
|
app = Flask(__name__)
|
|
@@ -13388,7 +13480,7 @@ var flaskIntegration = defineIntegration({
|
|
|
13388
13480
|
{
|
|
13389
13481
|
type: "create_file",
|
|
13390
13482
|
path: "README.md",
|
|
13391
|
-
content:
|
|
13483
|
+
content: pythonAppReadme(context, "Flask", "flask run"),
|
|
13392
13484
|
behavior: "fail_if_exists",
|
|
13393
13485
|
description: "Add Flask run instructions"
|
|
13394
13486
|
},
|
|
@@ -13817,7 +13909,7 @@ var nextjsIntegration = defineIntegration({
|
|
|
13817
13909
|
context.config.packageManager === "pnpm" ? "--use-pnpm" : "--use-npm",
|
|
13818
13910
|
// Official create-next-app flag: skip the generator's install so later
|
|
13819
13911
|
// install_package ops (or a deferred project install) own node_modules.
|
|
13820
|
-
// Verified for create-next-app@16.3.
|
|
13912
|
+
// Verified for create-next-app@16.3.6 via --help and
|
|
13821
13913
|
// https://nextjs.org/docs/app/api-reference/cli/create-next-app
|
|
13822
13914
|
"--skip-install",
|
|
13823
13915
|
"--yes"
|
|
@@ -13848,7 +13940,7 @@ var nextjsIntegration = defineIntegration({
|
|
|
13848
13940
|
};
|
|
13849
13941
|
const usesPrisma = context.config.integrations.some(({ id }) => id === "prisma");
|
|
13850
13942
|
const pnpmBuildPolicy = context.config.packageManager === "pnpm" ? {
|
|
13851
|
-
// create-next-app 16.3.
|
|
13943
|
+
// create-next-app 16.3.6 writes this placeholder policy when its
|
|
13852
13944
|
// install is skipped. Replace it before RepoSetup's consolidated
|
|
13853
13945
|
// install so the generator's known native dependencies can build.
|
|
13854
13946
|
type: "modify_text",
|
|
@@ -13870,7 +13962,7 @@ var nextjsIntegration = defineIntegration({
|
|
|
13870
13962
|
description: "Enable create-next-app's declared pnpm dependency builds"
|
|
13871
13963
|
} : void 0;
|
|
13872
13964
|
const standaloneTypecheckFix = typescript ? {
|
|
13873
|
-
// create-next-app 16.3.
|
|
13965
|
+
// create-next-app 16.3.6's default LayoutProps global is emitted
|
|
13874
13966
|
// by Next's type generation. Use an explicit type so `tsc --noEmit`
|
|
13875
13967
|
// works before a development server or build has run.
|
|
13876
13968
|
type: "modify_text",
|
|
@@ -14458,7 +14550,8 @@ function sqlitePlan(context) {
|
|
|
14458
14550
|
execLocalBin(
|
|
14459
14551
|
context,
|
|
14460
14552
|
"prisma",
|
|
14461
|
-
|
|
14553
|
+
// Verified Prisma 7.10.0 CLI flag: avoid fetching unrelated agent instructions.
|
|
14554
|
+
["init", "--datasource-provider", "sqlite", "--output", "../generated/prisma", "--no-skills"],
|
|
14462
14555
|
{ description: "Initialize Prisma with the SQLite provider" }
|
|
14463
14556
|
),
|
|
14464
14557
|
{
|
|
@@ -14509,7 +14602,14 @@ function postgresPlan(context) {
|
|
|
14509
14602
|
execLocalBin(
|
|
14510
14603
|
context,
|
|
14511
14604
|
"prisma",
|
|
14512
|
-
[
|
|
14605
|
+
[
|
|
14606
|
+
"init",
|
|
14607
|
+
"--datasource-provider",
|
|
14608
|
+
"postgresql",
|
|
14609
|
+
"--output",
|
|
14610
|
+
"../generated/prisma",
|
|
14611
|
+
"--no-skills"
|
|
14612
|
+
],
|
|
14513
14613
|
{ description: "Initialize Prisma with the PostgreSQL provider" }
|
|
14514
14614
|
),
|
|
14515
14615
|
{
|
|
@@ -14820,6 +14920,9 @@ var reactViteIntegration = defineIntegration({
|
|
|
14820
14920
|
const hasVite = pkg !== void 0 && hasPackageDependency(pkg, "vite");
|
|
14821
14921
|
const hasReact = pkg !== void 0 && hasPackageDependency(pkg, "react");
|
|
14822
14922
|
const config2 = await firstExistingPath2(context.files, VITE_CONFIG_PATHS);
|
|
14923
|
+
if (pkg !== void 0 && hasPackageDependency(pkg, "next") && config2 === void 0) {
|
|
14924
|
+
return notDetected();
|
|
14925
|
+
}
|
|
14823
14926
|
if (!hasReact || !hasVite && config2 === void 0) {
|
|
14824
14927
|
return notDetected();
|
|
14825
14928
|
}
|
|
@@ -14841,12 +14944,15 @@ var reactViteIntegration = defineIntegration({
|
|
|
14841
14944
|
const vite = `vite@${QUALIFIED_VERSIONS.vite}`;
|
|
14842
14945
|
return [
|
|
14843
14946
|
requireNodeRange(NODE_ENGINE_RANGES.vite, `Vite ${QUALIFIED_VERSIONS.vite}`),
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14947
|
+
{
|
|
14948
|
+
...pnpmOrNpmCreate(
|
|
14949
|
+
context,
|
|
14950
|
+
{ pnpmName: vite, npmName: vite },
|
|
14951
|
+
["--template", template, "--no-interactive"],
|
|
14952
|
+
{ description: "Scaffold React with create-vite", longRunning: true }
|
|
14953
|
+
),
|
|
14954
|
+
skipsDependencyInstall: true
|
|
14955
|
+
},
|
|
14850
14956
|
...context.config.packageManager === "pnpm" ? [pnpmViteBuildApproval()] : []
|
|
14851
14957
|
];
|
|
14852
14958
|
},
|
|
@@ -14915,7 +15021,7 @@ var shadcnIntegration = defineIntegration({
|
|
|
14915
15021
|
status: "experimental",
|
|
14916
15022
|
documentationUrl: "https://ui.shadcn.com/docs/cli",
|
|
14917
15023
|
keywords: ["ui", "components", "radix"],
|
|
14918
|
-
verification: { verifiedAt: "2026-
|
|
15024
|
+
verification: { verifiedAt: "2026-10-08" },
|
|
14919
15025
|
requirements: [
|
|
14920
15026
|
{
|
|
14921
15027
|
kind: "requires",
|
|
@@ -14944,17 +15050,78 @@ var shadcnIntegration = defineIntegration({
|
|
|
14944
15050
|
},
|
|
14945
15051
|
plan(context) {
|
|
14946
15052
|
const template = context.config.framework.id === "react-vite" ? "vite" : "next";
|
|
15053
|
+
const viteAliases = template === "vite" ? viteAliasOperations(context) : [];
|
|
14947
15054
|
return [
|
|
15055
|
+
...viteAliases,
|
|
14948
15056
|
requireNodeRange(NODE_ENGINE_RANGES.shadcn, `shadcn ${QUALIFIED_VERSIONS.shadcn}`),
|
|
14949
|
-
dlx(
|
|
14950
|
-
|
|
14951
|
-
|
|
15057
|
+
dlx(
|
|
15058
|
+
context,
|
|
15059
|
+
npmPin("shadcn", QUALIFIED_VERSIONS.shadcn),
|
|
15060
|
+
["init", "--yes", "--defaults", "-t", template],
|
|
15061
|
+
{
|
|
15062
|
+
description: "Initialize shadcn/ui in the existing app"
|
|
15063
|
+
}
|
|
15064
|
+
),
|
|
15065
|
+
{
|
|
15066
|
+
type: "verify",
|
|
15067
|
+
cwd: context.projectRoot,
|
|
15068
|
+
command: "node",
|
|
15069
|
+
args: [
|
|
15070
|
+
"-e",
|
|
15071
|
+
"const fs = require('node:fs'); if (!fs.existsSync('components.json')) { console.error('shadcn did not initialize components.json. Review the initialization output before retrying.'); process.exit(1); }"
|
|
15072
|
+
],
|
|
15073
|
+
description: "Require shadcn initialization to produce components.json"
|
|
15074
|
+
}
|
|
14952
15075
|
];
|
|
14953
15076
|
},
|
|
14954
15077
|
async verify(context) {
|
|
14955
15078
|
return mergeVerify([await missingAnyFile(context, ["components.json"], "components.json")]);
|
|
14956
15079
|
}
|
|
14957
15080
|
});
|
|
15081
|
+
function viteAliasOperations(context) {
|
|
15082
|
+
const compilerOptions = { baseUrl: ".", paths: { "@/*": ["./src/*"] } };
|
|
15083
|
+
return [
|
|
15084
|
+
...usesTypescript(context) ? [
|
|
15085
|
+
{
|
|
15086
|
+
type: "modify_json",
|
|
15087
|
+
path: "tsconfig.json",
|
|
15088
|
+
merge: { compilerOptions },
|
|
15089
|
+
behavior: "merge",
|
|
15090
|
+
description: "Configure the root TypeScript shadcn alias"
|
|
15091
|
+
},
|
|
15092
|
+
{
|
|
15093
|
+
// create-vite's app tsconfig contains comments; preserve JSONC.
|
|
15094
|
+
type: "modify_text",
|
|
15095
|
+
path: "tsconfig.app.json",
|
|
15096
|
+
oldText: '"compilerOptions": {',
|
|
15097
|
+
newText: '"compilerOptions": {\n "baseUrl": ".",\n "paths": { "@/*": ["./src/*"] },',
|
|
15098
|
+
description: "Configure the app TypeScript shadcn alias"
|
|
15099
|
+
}
|
|
15100
|
+
] : [
|
|
15101
|
+
{
|
|
15102
|
+
type: "create_file",
|
|
15103
|
+
path: "jsconfig.json",
|
|
15104
|
+
content: JSON.stringify({ compilerOptions }, null, 2) + "\n",
|
|
15105
|
+
behavior: "fail_if_exists",
|
|
15106
|
+
description: "Configure the JavaScript shadcn alias"
|
|
15107
|
+
}
|
|
15108
|
+
],
|
|
15109
|
+
{
|
|
15110
|
+
type: "modify_text",
|
|
15111
|
+
path: usesTypescript(context) ? "vite.config.ts" : "vite.config.js",
|
|
15112
|
+
oldText: "import { defineConfig } from 'vite'",
|
|
15113
|
+
newText: "import { defineConfig } from 'vite'\nimport { fileURLToPath } from 'node:url'",
|
|
15114
|
+
description: "Resolve the Vite source alias on every supported platform"
|
|
15115
|
+
},
|
|
15116
|
+
{
|
|
15117
|
+
type: "modify_text",
|
|
15118
|
+
path: usesTypescript(context) ? "vite.config.ts" : "vite.config.js",
|
|
15119
|
+
oldText: "export default defineConfig({",
|
|
15120
|
+
newText: "export default defineConfig({\n resolve: {\n alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) },\n },",
|
|
15121
|
+
description: "Enable the shadcn Vite source alias"
|
|
15122
|
+
}
|
|
15123
|
+
];
|
|
15124
|
+
}
|
|
14958
15125
|
var sqlalchemyIntegration = defineIntegration({
|
|
14959
15126
|
id: "sqlalchemy",
|
|
14960
15127
|
name: "SQLAlchemy",
|
|
@@ -15067,7 +15234,7 @@ var sqliteIntegration = defineIntegration({
|
|
|
15067
15234
|
}
|
|
15068
15235
|
});
|
|
15069
15236
|
var POSTCSS_CONFIG_PATHS = ["postcss.config.mjs", "postcss.config.js"];
|
|
15070
|
-
var GLOBAL_CSS_PATHS = ["app/globals.css", "src/app/globals.css"];
|
|
15237
|
+
var GLOBAL_CSS_PATHS = ["app/globals.css", "src/app/globals.css", "src/index.css"];
|
|
15071
15238
|
var POSTCSS_CONFIG = `const config = {
|
|
15072
15239
|
plugins: {
|
|
15073
15240
|
"@tailwindcss/postcss": {},
|
|
@@ -15110,7 +15277,7 @@ var tailwindIntegration = defineIntegration({
|
|
|
15110
15277
|
const postcss = await firstExistingPath2(context.files, POSTCSS_CONFIG_PATHS);
|
|
15111
15278
|
const cssPath = await firstExistingPath2(context.files, GLOBAL_CSS_PATHS);
|
|
15112
15279
|
const css = cssPath === void 0 ? void 0 : await context.files.readText(cssPath);
|
|
15113
|
-
const hasImport = css !== void 0 &&
|
|
15280
|
+
const hasImport = css !== void 0 && /@import\s+["']tailwindcss["']/.test(css);
|
|
15114
15281
|
if (!hasTailwind && postcss === void 0 && !hasImport && !hasVitePlugin) {
|
|
15115
15282
|
return notDetected();
|
|
15116
15283
|
}
|
|
@@ -15144,9 +15311,25 @@ var tailwindIntegration = defineIntegration({
|
|
|
15144
15311
|
}
|
|
15145
15312
|
),
|
|
15146
15313
|
{
|
|
15147
|
-
type: "
|
|
15148
|
-
|
|
15149
|
-
|
|
15314
|
+
type: "modify_text",
|
|
15315
|
+
path: usesTypescript(context) ? "vite.config.ts" : "vite.config.js",
|
|
15316
|
+
oldText: "import react from '@vitejs/plugin-react'",
|
|
15317
|
+
newText: "import react from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'",
|
|
15318
|
+
description: "Import the official Tailwind Vite plugin"
|
|
15319
|
+
},
|
|
15320
|
+
{
|
|
15321
|
+
type: "modify_text",
|
|
15322
|
+
path: usesTypescript(context) ? "vite.config.ts" : "vite.config.js",
|
|
15323
|
+
oldText: "plugins: [react()],",
|
|
15324
|
+
newText: "plugins: [react(), tailwindcss()],",
|
|
15325
|
+
description: "Enable the Tailwind Vite plugin"
|
|
15326
|
+
},
|
|
15327
|
+
{
|
|
15328
|
+
type: "modify_text",
|
|
15329
|
+
path: "src/index.css",
|
|
15330
|
+
oldText: ":root {\n font-family:",
|
|
15331
|
+
newText: "@import 'tailwindcss';\n\n:root {\n font-family:",
|
|
15332
|
+
description: "Import Tailwind without removing existing Vite styles"
|
|
15150
15333
|
}
|
|
15151
15334
|
];
|
|
15152
15335
|
}
|
|
@@ -15189,11 +15372,14 @@ var tailwindIntegration = defineIntegration({
|
|
|
15189
15372
|
async verify(context) {
|
|
15190
15373
|
const cssPath = await firstExistingPath2(context.files, GLOBAL_CSS_PATHS);
|
|
15191
15374
|
const css = cssPath === void 0 ? void 0 : await context.files.readText(cssPath);
|
|
15192
|
-
const
|
|
15375
|
+
const hasVitePlugin = context.packageJson !== void 0 && hasPackageDependency(context.packageJson, "@tailwindcss/vite");
|
|
15376
|
+
const missingImport = cssPath === void 0 && hasVitePlugin ? failVerify(
|
|
15377
|
+
"The Vite project is missing a known Tailwind CSS entry file.",
|
|
15378
|
+
'Add @import "tailwindcss"; to src/index.css. Doctor does not edit CSS.'
|
|
15379
|
+
) : cssPath !== void 0 && (css === void 0 || !/@import\s+["']tailwindcss["']/.test(css)) ? failVerify(
|
|
15193
15380
|
`${cssPath} does not import Tailwind.`,
|
|
15194
15381
|
`Add @import "tailwindcss"; to ${cssPath}. Doctor does not edit CSS.`
|
|
15195
15382
|
) : void 0;
|
|
15196
|
-
const hasVitePlugin = context.packageJson !== void 0 && hasPackageDependency(context.packageJson, "@tailwindcss/vite");
|
|
15197
15383
|
const missingPostcss = hasVitePlugin ? void 0 : await missingAnyFile(
|
|
15198
15384
|
context,
|
|
15199
15385
|
POSTCSS_CONFIG_PATHS,
|
|
@@ -15490,21 +15676,27 @@ var uvIntegration = defineIntegration({
|
|
|
15490
15676
|
];
|
|
15491
15677
|
}
|
|
15492
15678
|
});
|
|
15493
|
-
var VITEST_CONFIG_TS = `import {
|
|
15679
|
+
var VITEST_CONFIG_TS = `import { realpathSync } from 'node:fs'
|
|
15680
|
+
import { fileURLToPath } from 'node:url'
|
|
15681
|
+
import { defineConfig } from 'vitest/config'
|
|
15494
15682
|
import react from '@vitejs/plugin-react'
|
|
15495
15683
|
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
15496
15684
|
|
|
15497
15685
|
export default defineConfig({
|
|
15686
|
+
root: realpathSync.native(fileURLToPath(new URL('.', import.meta.url))),
|
|
15498
15687
|
plugins: [tsconfigPaths(), react()],
|
|
15499
15688
|
test: {
|
|
15500
15689
|
environment: 'jsdom',
|
|
15501
15690
|
},
|
|
15502
15691
|
})
|
|
15503
15692
|
`;
|
|
15504
|
-
var VITEST_CONFIG_JS = `import {
|
|
15693
|
+
var VITEST_CONFIG_JS = `import { realpathSync } from 'node:fs'
|
|
15694
|
+
import { fileURLToPath } from 'node:url'
|
|
15695
|
+
import { defineConfig } from 'vitest/config'
|
|
15505
15696
|
import react from '@vitejs/plugin-react'
|
|
15506
15697
|
|
|
15507
15698
|
export default defineConfig({
|
|
15699
|
+
root: realpathSync.native(fileURLToPath(new URL('.', import.meta.url))),
|
|
15508
15700
|
plugins: [react()],
|
|
15509
15701
|
test: {
|
|
15510
15702
|
environment: 'jsdom',
|
|
@@ -15653,13 +15845,17 @@ export default defineConfig({})
|
|
|
15653
15845
|
const typescript = context.config.framework.options?.typescript !== false;
|
|
15654
15846
|
const packages = typescript ? [
|
|
15655
15847
|
npmPin("vitest", QUALIFIED_VERSIONS.vitest),
|
|
15848
|
+
npmPin("vite", QUALIFIED_VERSIONS.vite),
|
|
15656
15849
|
npmPin("@vitejs/plugin-react", QUALIFIED_VERSIONS.vitePluginReact),
|
|
15657
15850
|
npmPin("jsdom", QUALIFIED_VERSIONS.jsdom),
|
|
15658
15851
|
npmPin("@testing-library/react", QUALIFIED_VERSIONS.testingLibraryReact),
|
|
15659
15852
|
npmPin("@testing-library/dom", QUALIFIED_VERSIONS.testingLibraryDom),
|
|
15660
|
-
npmPin("vite-tsconfig-paths", QUALIFIED_VERSIONS.viteTsconfigPaths)
|
|
15853
|
+
npmPin("vite-tsconfig-paths", QUALIFIED_VERSIONS.viteTsconfigPaths),
|
|
15854
|
+
// create-next-app defaults to Node 20 types, outside Vitest 5's peer range.
|
|
15855
|
+
npmPin("@types/node", QUALIFIED_VERSIONS.typesNode)
|
|
15661
15856
|
] : [
|
|
15662
15857
|
npmPin("vitest", QUALIFIED_VERSIONS.vitest),
|
|
15858
|
+
npmPin("vite", QUALIFIED_VERSIONS.vite),
|
|
15663
15859
|
npmPin("@vitejs/plugin-react", QUALIFIED_VERSIONS.vitePluginReact),
|
|
15664
15860
|
npmPin("jsdom", QUALIFIED_VERSIONS.jsdom),
|
|
15665
15861
|
npmPin("@testing-library/react", QUALIFIED_VERSIONS.testingLibraryReact),
|
|
@@ -15671,7 +15867,8 @@ export default defineConfig({})
|
|
|
15671
15867
|
addPackages(context, packages, {
|
|
15672
15868
|
description: "Install Vitest and the official Next.js test packages",
|
|
15673
15869
|
dev: true,
|
|
15674
|
-
allowBuild: ["esbuild"]
|
|
15870
|
+
allowBuild: ["esbuild"],
|
|
15871
|
+
exact: true
|
|
15675
15872
|
}),
|
|
15676
15873
|
{
|
|
15677
15874
|
type: "create_file",
|
|
@@ -15879,7 +16076,7 @@ async function handleDoctor(input2) {
|
|
|
15879
16076
|
|
|
15880
16077
|
// src/export.ts
|
|
15881
16078
|
import { access as access4, writeFile as writeFile2 } from "fs/promises";
|
|
15882
|
-
import
|
|
16079
|
+
import path11 from "path";
|
|
15883
16080
|
var EXPORT_FILE_NAME = "reposetup.json";
|
|
15884
16081
|
async function handleExport(input2) {
|
|
15885
16082
|
if (input2.packageManager !== void 0 && !isKnownPackageManager(input2.packageManager)) {
|
|
@@ -15912,7 +16109,7 @@ async function handleExport(input2) {
|
|
|
15912
16109
|
}
|
|
15913
16110
|
return EXIT_CODES.SUCCESS;
|
|
15914
16111
|
}
|
|
15915
|
-
const outputPath =
|
|
16112
|
+
const outputPath = path11.join(exported.projectRoot, EXPORT_FILE_NAME);
|
|
15916
16113
|
if (!input2.yes && await fileExists(outputPath)) {
|
|
15917
16114
|
writeLine(
|
|
15918
16115
|
input2.deps.io.writeErr,
|
|
@@ -16213,15 +16410,15 @@ function renderStack(stack, verbose) {
|
|
|
16213
16410
|
for (const item of allItems(stack)) {
|
|
16214
16411
|
lines.push("", `${item.name} evidence:`);
|
|
16215
16412
|
for (const entry of item.evidence) {
|
|
16216
|
-
const
|
|
16217
|
-
lines.push(` - ${entry.detail}${
|
|
16413
|
+
const path13 = entry.path === void 0 ? "" : ` (${entry.path})`;
|
|
16414
|
+
lines.push(` - ${entry.detail}${path13}`);
|
|
16218
16415
|
}
|
|
16219
16416
|
}
|
|
16220
16417
|
if (stack.language !== void 0) {
|
|
16221
16418
|
lines.push("", `Language evidence:`);
|
|
16222
16419
|
for (const entry of stack.language.evidence) {
|
|
16223
|
-
const
|
|
16224
|
-
lines.push(` - ${entry.detail}${
|
|
16420
|
+
const path13 = entry.path === void 0 ? "" : ` (${entry.path})`;
|
|
16421
|
+
lines.push(` - ${entry.detail}${path13}`);
|
|
16225
16422
|
}
|
|
16226
16423
|
}
|
|
16227
16424
|
}
|
|
@@ -16305,15 +16502,15 @@ async function handleStack(input2) {
|
|
|
16305
16502
|
|
|
16306
16503
|
// src/version.ts
|
|
16307
16504
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
16308
|
-
import
|
|
16505
|
+
import path12 from "path";
|
|
16309
16506
|
import { fileURLToPath } from "url";
|
|
16310
16507
|
var PACKAGE_NAME = "rsetup";
|
|
16311
16508
|
function cliVersion() {
|
|
16312
|
-
const here =
|
|
16509
|
+
const here = path12.dirname(fileURLToPath(import.meta.url));
|
|
16313
16510
|
const candidates = [
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16511
|
+
path12.join(here, "..", "package.json"),
|
|
16512
|
+
path12.join(here, "package.json"),
|
|
16513
|
+
path12.join(here, "..", "..", "package.json")
|
|
16317
16514
|
];
|
|
16318
16515
|
for (const file of candidates) {
|
|
16319
16516
|
if (!existsSync2(file)) {
|
|
@@ -16483,4 +16680,4 @@ export {
|
|
|
16483
16680
|
EXIT_CODES,
|
|
16484
16681
|
runCli
|
|
16485
16682
|
};
|
|
16486
|
-
//# sourceMappingURL=chunk-
|
|
16683
|
+
//# sourceMappingURL=chunk-D3YJGGEE.js.map
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rsetup",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"LICENSE"
|
|
48
48
|
],
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@reposetup/core": "0.
|
|
51
|
-
"@reposetup/integrations": "0.
|
|
52
|
-
"@reposetup/registry": "0.
|
|
50
|
+
"@reposetup/core": "0.2.1",
|
|
51
|
+
"@reposetup/integrations": "0.2.1",
|
|
52
|
+
"@reposetup/registry": "0.2.1",
|
|
53
53
|
"@types/node": "^22.20.4",
|
|
54
54
|
"tsup": "^8.5.1",
|
|
55
55
|
"typescript": "^5.9.3",
|