betterstart-cli 0.0.41 → 0.0.43
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/assets/adapters/next/{plugins/blog/plugin.ts → presets/blog/preset.ts} +2 -2
- package/dist/assets/adapters/next/{plugins/portfolio/plugin.ts → presets/portfolio/preset.ts} +2 -2
- package/dist/cli.js +281 -260
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- /package/dist/assets/adapters/next/{plugins → presets}/blog/schemas/menus.json +0 -0
- /package/dist/assets/adapters/next/{plugins → presets}/blog/schemas/posts.json +0 -0
- /package/dist/assets/adapters/next/{plugins → presets}/portfolio/schemas/portfolio.json +0 -0
package/dist/cli.js
CHANGED
|
@@ -70,9 +70,9 @@ function requireInitializedProject(command) {
|
|
|
70
70
|
import { Argument, Command } from "commander";
|
|
71
71
|
var CREATE_SCHEMA_KINDS = ["entity", "single", "form"];
|
|
72
72
|
function createAddCommand(runtime) {
|
|
73
|
-
return new Command("add").description("Install BetterStart
|
|
73
|
+
return new Command("add").description("Install BetterStart presets or integrations into an existing Admin").argument("<items...>", "Preset or integration IDs to install (e.g. blog, r2)").option("-y, --yes", "Skip interactive configuration prompts", false).option("--integration", "Install integration IDs instead of content preset IDs", false).option(
|
|
74
74
|
"--skip-migration",
|
|
75
|
-
"Skip running db:push after installing schema-backed
|
|
75
|
+
"Skip running db:push after installing schema-backed presets",
|
|
76
76
|
false
|
|
77
77
|
).option("--cwd <path>", "Project root path").action((items, options) => runtime.runAdd(items, options));
|
|
78
78
|
}
|
|
@@ -109,21 +109,21 @@ function createGenerateCommand(runtime) {
|
|
|
109
109
|
);
|
|
110
110
|
}
|
|
111
111
|
function createInitCommand(runtime) {
|
|
112
|
-
return new Command("init").description("Scaffold Admin into a new or existing Next.js app").argument("[name]", "Project name (creates new directory if fresh project)").option("--
|
|
112
|
+
return new Command("init").description("Scaffold Admin into a new or existing Next.js app").argument("[name]", "Project name (creates new directory if fresh project)").option("--presets <presets>", "Comma-separated content preset IDs (e.g. blog)").option("--integrations <integrations>", "Comma-separated integration IDs (e.g. r2,resend)").option("--namespace <name>", "Generated admin namespace (e.g. admin, dashboard)").option("-y, --yes", "Skip all prompts (accept defaults)").option("--skip-migration", "Skip running drizzle-kit push after scaffolding").option("--skip-admin-creation", "Skip prompting to create the initial admin user").option("--skip-dev-server-start", "Skip prompting to start the development server").option(
|
|
113
113
|
"--database-url <url>",
|
|
114
114
|
"PostgreSQL database connection string (postgres:// or postgresql://)"
|
|
115
115
|
).option("--no-vercel", "Disable the Vercel (Neon) provisioning flow (manual connection only)").option("--vercel-plan <id>", "Neon plan id passed to `vercel integration add neon`").option("--skip-deploy", "Skip the post-scaffold deploy to the linked Vercel project").option("--force", "Overwrite all existing Admin files (nuclear option)").action(
|
|
116
116
|
(name, options) => runtime.runInit(name, options)
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
|
-
function
|
|
120
|
-
return new Command("list-
|
|
119
|
+
function createListPresetsCommand(runtime) {
|
|
120
|
+
return new Command("list-presets").description("List available BetterStart presets").option("--cwd <path>", "Project root path").action((options) => runtime.runListPresets(options));
|
|
121
121
|
}
|
|
122
122
|
function createListIntegrationsCommand(runtime) {
|
|
123
123
|
return new Command("list-integrations").description("List available BetterStart integrations").option("--cwd <path>", "Project root path").action((options) => runtime.runListIntegrations(options));
|
|
124
124
|
}
|
|
125
125
|
function createRemoveCommand(runtime) {
|
|
126
|
-
return new Command("remove").description("Remove installed BetterStart
|
|
126
|
+
return new Command("remove").description("Remove installed BetterStart presets or integrations").argument("<items...>", "Preset or integration IDs to remove (e.g. blog r2)").option("-f, --force", "Skip confirmation prompt", false).option("--integration", "Remove integration IDs instead of content preset IDs", false).option("--cwd <path>", "Project root path").action((items, options) => runtime.runRemove(items, options));
|
|
127
127
|
}
|
|
128
128
|
function createRemoveSchemaCommand(runtime) {
|
|
129
129
|
return new Command("remove-schema").description("Remove generated files for a user-authored schema").argument("<schema>", "Schema name to remove (e.g. posts, categories, contact)").option("-f, --force", "Skip confirmation prompt", false).option("--cwd <path>", "Project root path").action(
|
|
@@ -191,8 +191,8 @@ export default defineConfig({
|
|
|
191
191
|
migrationsDir: ${quote(config.database.migrationsDir)},
|
|
192
192
|
},
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
installed: ${formatArray(config.
|
|
194
|
+
presets: {
|
|
195
|
+
installed: ${formatArray(config.presets.installed)},
|
|
196
196
|
},
|
|
197
197
|
|
|
198
198
|
integrations: {
|
|
@@ -442,7 +442,7 @@ function getDefaultConfig(srcDir, nextMajorVersion = 16) {
|
|
|
442
442
|
provider: "postgres",
|
|
443
443
|
migrationsDir: deriveMigrationsDir(namespace)
|
|
444
444
|
},
|
|
445
|
-
|
|
445
|
+
presets: {
|
|
446
446
|
installed: []
|
|
447
447
|
},
|
|
448
448
|
integrations: {
|
|
@@ -507,7 +507,7 @@ async function resolveConfig(cwd) {
|
|
|
507
507
|
provider: "postgres",
|
|
508
508
|
migrationsDir: loadedDatabase.migrationsDir
|
|
509
509
|
},
|
|
510
|
-
|
|
510
|
+
presets: loadedConfig.presets ?? defaultConfig.presets,
|
|
511
511
|
integrations: loadedConfig.integrations ?? defaultConfig.integrations,
|
|
512
512
|
email: loadedConfig.email ?? defaultConfig.email,
|
|
513
513
|
storage: loadedConfig.storage ?? defaultConfig.storage,
|
|
@@ -899,8 +899,8 @@ function formatUnknownIntegrationMessage(integrationIds) {
|
|
|
899
899
|
return `Unknown integration(s): ${integrationIds.join(", ")}. Available for next: ${Object.keys(integrationRegistry).join(", ")}`;
|
|
900
900
|
}
|
|
901
901
|
|
|
902
|
-
// adapters/next/
|
|
903
|
-
var
|
|
902
|
+
// adapters/next/presets/blog/preset.ts
|
|
903
|
+
var blogPreset = {
|
|
904
904
|
id: "blog",
|
|
905
905
|
title: "Blog",
|
|
906
906
|
description: "Posts content module",
|
|
@@ -916,8 +916,8 @@ var blogPlugin = {
|
|
|
916
916
|
configure: "none"
|
|
917
917
|
};
|
|
918
918
|
|
|
919
|
-
// adapters/next/
|
|
920
|
-
var
|
|
919
|
+
// adapters/next/presets/portfolio/preset.ts
|
|
920
|
+
var portfolioPreset = {
|
|
921
921
|
id: "portfolio",
|
|
922
922
|
title: "Portfolio",
|
|
923
923
|
description: "Portfolio content module",
|
|
@@ -933,26 +933,26 @@ var portfolioPlugin = {
|
|
|
933
933
|
configure: "none"
|
|
934
934
|
};
|
|
935
935
|
|
|
936
|
-
// adapters/next/
|
|
937
|
-
var
|
|
938
|
-
blog:
|
|
939
|
-
portfolio:
|
|
936
|
+
// adapters/next/preset-registry.ts
|
|
937
|
+
var presetRegistry = {
|
|
938
|
+
blog: blogPreset,
|
|
939
|
+
portfolio: portfolioPreset
|
|
940
940
|
};
|
|
941
|
-
function
|
|
942
|
-
return Object.values(
|
|
941
|
+
function listPresetDefinitions() {
|
|
942
|
+
return Object.values(presetRegistry);
|
|
943
943
|
}
|
|
944
|
-
function
|
|
945
|
-
const definition =
|
|
944
|
+
function getPresetDefinition(presetId) {
|
|
945
|
+
const definition = presetRegistry[presetId];
|
|
946
946
|
if (!definition) {
|
|
947
|
-
throw new Error(
|
|
947
|
+
throw new Error(formatUnknownPresetMessage([presetId]));
|
|
948
948
|
}
|
|
949
949
|
return definition;
|
|
950
950
|
}
|
|
951
|
-
function
|
|
952
|
-
return value in
|
|
951
|
+
function isPresetId(value) {
|
|
952
|
+
return value in presetRegistry;
|
|
953
953
|
}
|
|
954
|
-
function
|
|
955
|
-
return `Unknown
|
|
954
|
+
function formatUnknownPresetMessage(presetIds) {
|
|
955
|
+
return `Unknown preset(s): ${presetIds.join(", ")}. Available for next: ${Object.keys(presetRegistry).join(", ")}`;
|
|
956
956
|
}
|
|
957
957
|
|
|
958
958
|
// shared-assets/react-admin/dependencies.ts
|
|
@@ -1313,12 +1313,12 @@ function spawnAsync(cmd, args, cwd) {
|
|
|
1313
1313
|
function unique(values) {
|
|
1314
1314
|
return Array.from(new Set(values));
|
|
1315
1315
|
}
|
|
1316
|
-
function getDependencyPlan(
|
|
1317
|
-
const
|
|
1318
|
-
(
|
|
1316
|
+
function getDependencyPlan(presetIds, integrationIds, includeBiome) {
|
|
1317
|
+
const presetDependencies = presetIds.flatMap(
|
|
1318
|
+
(presetId) => getPresetDefinition(presetId).packageDependencies
|
|
1319
1319
|
);
|
|
1320
|
-
const
|
|
1321
|
-
(
|
|
1320
|
+
const presetDevDependencies = presetIds.flatMap(
|
|
1321
|
+
(presetId) => getPresetDefinition(presetId).devDependencies
|
|
1322
1322
|
);
|
|
1323
1323
|
const integrationDependencies = integrationIds.flatMap(
|
|
1324
1324
|
(integrationId) => getIntegrationDefinition(integrationId).packageDependencies
|
|
@@ -1327,10 +1327,10 @@ function getDependencyPlan(pluginIds, integrationIds, includeBiome) {
|
|
|
1327
1327
|
(integrationId) => getIntegrationDefinition(integrationId).devDependencies
|
|
1328
1328
|
);
|
|
1329
1329
|
return {
|
|
1330
|
-
dependencies: unique([...CORE_DEPS, ...
|
|
1330
|
+
dependencies: unique([...CORE_DEPS, ...presetDependencies, ...integrationDependencies]),
|
|
1331
1331
|
devDependencies: unique([
|
|
1332
1332
|
...DEV_DEPS,
|
|
1333
|
-
...
|
|
1333
|
+
...presetDevDependencies,
|
|
1334
1334
|
...integrationDevDependencies,
|
|
1335
1335
|
...includeBiome ? BIOME_DEV_DEPS : []
|
|
1336
1336
|
])
|
|
@@ -1508,8 +1508,15 @@ function runDrizzlePush(cwd, options = {}) {
|
|
|
1508
1508
|
});
|
|
1509
1509
|
let stdout = "";
|
|
1510
1510
|
let stderr = "";
|
|
1511
|
+
let outputNotified = false;
|
|
1512
|
+
const notifyOutput = () => {
|
|
1513
|
+
if (outputNotified) return;
|
|
1514
|
+
outputNotified = true;
|
|
1515
|
+
options.onOutput?.();
|
|
1516
|
+
};
|
|
1511
1517
|
const stderrFilter = createDrizzleNoiseFilter((chunk) => {
|
|
1512
1518
|
if (options.interactive) {
|
|
1519
|
+
notifyOutput();
|
|
1513
1520
|
process.stderr.write(chunk);
|
|
1514
1521
|
return;
|
|
1515
1522
|
}
|
|
@@ -1517,6 +1524,7 @@ function runDrizzlePush(cwd, options = {}) {
|
|
|
1517
1524
|
});
|
|
1518
1525
|
const stdoutFilter = createDrizzleNoiseFilter((chunk) => {
|
|
1519
1526
|
if (options.interactive) {
|
|
1527
|
+
notifyOutput();
|
|
1520
1528
|
process.stdout.write(chunk);
|
|
1521
1529
|
return;
|
|
1522
1530
|
}
|
|
@@ -2908,7 +2916,7 @@ function readIntegrationTemplate(integrationId, relativePath) {
|
|
|
2908
2916
|
return fs12.readFileSync(path15.join(integrationTemplateRoot(integrationId), relativePath), "utf-8");
|
|
2909
2917
|
}
|
|
2910
2918
|
|
|
2911
|
-
//
|
|
2919
|
+
// preset-engine/ownership.ts
|
|
2912
2920
|
import fs13 from "fs";
|
|
2913
2921
|
import path16 from "path";
|
|
2914
2922
|
function ownershipPath(cwd) {
|
|
@@ -3491,16 +3499,16 @@ function getUnusedIntegrationDependencies(config, remainingIntegrations, removed
|
|
|
3491
3499
|
const remainingIntegrationDefinitions = remainingIntegrations.map(
|
|
3492
3500
|
(integrationId) => getIntegrationDefinition(integrationId)
|
|
3493
3501
|
);
|
|
3494
|
-
const
|
|
3495
|
-
(
|
|
3502
|
+
const remainingPresetDefinitions = config.presets.installed.map(
|
|
3503
|
+
(presetId) => getPresetDefinition(presetId)
|
|
3496
3504
|
);
|
|
3497
3505
|
const remainingDependencies = /* @__PURE__ */ new Set([
|
|
3498
3506
|
...remainingIntegrationDefinitions.flatMap((definition) => definition.packageDependencies),
|
|
3499
|
-
...
|
|
3507
|
+
...remainingPresetDefinitions.flatMap((definition) => definition.packageDependencies)
|
|
3500
3508
|
]);
|
|
3501
3509
|
const remainingDevDependencies = /* @__PURE__ */ new Set([
|
|
3502
3510
|
...remainingIntegrationDefinitions.flatMap((definition) => definition.devDependencies),
|
|
3503
|
-
...
|
|
3511
|
+
...remainingPresetDefinitions.flatMap((definition) => definition.devDependencies)
|
|
3504
3512
|
]);
|
|
3505
3513
|
const corePlan = getDependencyPlan([], [], false);
|
|
3506
3514
|
const removedDefinition = getIntegrationDefinition(removedIntegrationId);
|
|
@@ -3658,12 +3666,12 @@ async function installIntegrations({
|
|
|
3658
3666
|
ensureIntegrationDirectFileTargetsAvailable(cwd, config, definition);
|
|
3659
3667
|
const configureResult = await configureIntegration(definition, cwd, interactive);
|
|
3660
3668
|
const dependencyPlan = getDependencyPlan(
|
|
3661
|
-
config.
|
|
3669
|
+
config.presets.installed,
|
|
3662
3670
|
[...installedIntegrationIds, integrationId],
|
|
3663
3671
|
includeBiome
|
|
3664
3672
|
);
|
|
3665
3673
|
const currentPlan = getDependencyPlan(
|
|
3666
|
-
config.
|
|
3674
|
+
config.presets.installed,
|
|
3667
3675
|
installedIntegrationIds,
|
|
3668
3676
|
includeBiome
|
|
3669
3677
|
);
|
|
@@ -3821,7 +3829,7 @@ function listAvailableIntegrations() {
|
|
|
3821
3829
|
return listIntegrationDefinitions();
|
|
3822
3830
|
}
|
|
3823
3831
|
|
|
3824
|
-
// adapters/next/
|
|
3832
|
+
// adapters/next/preset-runtime.ts
|
|
3825
3833
|
import fs22 from "fs";
|
|
3826
3834
|
import path26 from "path";
|
|
3827
3835
|
|
|
@@ -17339,14 +17347,14 @@ function runSinglePipeline(schema, cwd, config, options = {}) {
|
|
|
17339
17347
|
};
|
|
17340
17348
|
}
|
|
17341
17349
|
|
|
17342
|
-
// adapters/next/
|
|
17350
|
+
// adapters/next/preset-template-reader.ts
|
|
17343
17351
|
import fs16 from "fs";
|
|
17344
17352
|
import path20 from "path";
|
|
17345
|
-
function
|
|
17346
|
-
return resolveCliAssetPath("adapters", "next", "
|
|
17353
|
+
function presetTemplateRoot(presetId) {
|
|
17354
|
+
return resolveCliAssetPath("adapters", "next", "presets", presetId);
|
|
17347
17355
|
}
|
|
17348
|
-
function
|
|
17349
|
-
return fs16.readFileSync(path20.join(
|
|
17356
|
+
function readPresetTemplate(presetId, relativePath) {
|
|
17357
|
+
return fs16.readFileSync(path20.join(presetTemplateRoot(presetId), relativePath), "utf-8");
|
|
17350
17358
|
}
|
|
17351
17359
|
|
|
17352
17360
|
// adapters/next/snapshots/apply.ts
|
|
@@ -18259,62 +18267,62 @@ async function applyGeneratedFiles({
|
|
|
18259
18267
|
return summary;
|
|
18260
18268
|
}
|
|
18261
18269
|
|
|
18262
|
-
//
|
|
18270
|
+
// preset-engine/manifests.ts
|
|
18263
18271
|
import fs21 from "fs";
|
|
18264
18272
|
import path25 from "path";
|
|
18265
|
-
function
|
|
18266
|
-
return path25.join(cwd, ".betterstart", "
|
|
18273
|
+
function presetsDir(cwd) {
|
|
18274
|
+
return path25.join(cwd, ".betterstart", "presets");
|
|
18267
18275
|
}
|
|
18268
|
-
function
|
|
18269
|
-
return path25.join(
|
|
18276
|
+
function presetManifestPath(cwd, presetId) {
|
|
18277
|
+
return path25.join(presetsDir(cwd), presetId, "manifest.json");
|
|
18270
18278
|
}
|
|
18271
|
-
function
|
|
18272
|
-
const filePath =
|
|
18279
|
+
function loadInstalledPresetManifest(cwd, presetId) {
|
|
18280
|
+
const filePath = presetManifestPath(cwd, presetId);
|
|
18273
18281
|
if (!fs21.existsSync(filePath)) {
|
|
18274
18282
|
return null;
|
|
18275
18283
|
}
|
|
18276
18284
|
return JSON.parse(fs21.readFileSync(filePath, "utf-8"));
|
|
18277
18285
|
}
|
|
18278
|
-
function
|
|
18279
|
-
const filePath =
|
|
18286
|
+
function saveInstalledPresetManifest(cwd, manifest) {
|
|
18287
|
+
const filePath = presetManifestPath(cwd, manifest.id);
|
|
18280
18288
|
fs21.mkdirSync(path25.dirname(filePath), { recursive: true });
|
|
18281
18289
|
fs21.writeFileSync(filePath, stringifyProjectJson(manifest), "utf-8");
|
|
18282
18290
|
}
|
|
18283
|
-
function
|
|
18284
|
-
fs21.rmSync(path25.dirname(
|
|
18291
|
+
function deleteInstalledPresetManifest(cwd, presetId) {
|
|
18292
|
+
fs21.rmSync(path25.dirname(presetManifestPath(cwd, presetId)), {
|
|
18285
18293
|
recursive: true,
|
|
18286
18294
|
force: true
|
|
18287
18295
|
});
|
|
18288
18296
|
}
|
|
18289
18297
|
|
|
18290
|
-
// adapters/next/
|
|
18298
|
+
// adapters/next/preset-runtime.ts
|
|
18291
18299
|
function unique3(values) {
|
|
18292
18300
|
return Array.from(new Set(values));
|
|
18293
18301
|
}
|
|
18294
|
-
function
|
|
18295
|
-
return unique3((config.
|
|
18302
|
+
function normalizeInstalledPresets(config) {
|
|
18303
|
+
return unique3((config.presets.installed ?? []).filter(isPresetId)).sort();
|
|
18296
18304
|
}
|
|
18297
|
-
function
|
|
18305
|
+
function resolvePresetInstallOrder(presetIds) {
|
|
18298
18306
|
const ordered = [];
|
|
18299
18307
|
const visiting = /* @__PURE__ */ new Set();
|
|
18300
18308
|
const visited = /* @__PURE__ */ new Set();
|
|
18301
|
-
function visit(
|
|
18302
|
-
if (visited.has(
|
|
18309
|
+
function visit(presetId) {
|
|
18310
|
+
if (visited.has(presetId)) {
|
|
18303
18311
|
return;
|
|
18304
18312
|
}
|
|
18305
|
-
if (visiting.has(
|
|
18306
|
-
throw new Error(`Circular
|
|
18313
|
+
if (visiting.has(presetId)) {
|
|
18314
|
+
throw new Error(`Circular preset dependency detected at "${presetId}".`);
|
|
18307
18315
|
}
|
|
18308
|
-
visiting.add(
|
|
18309
|
-
for (const dependency of
|
|
18316
|
+
visiting.add(presetId);
|
|
18317
|
+
for (const dependency of getPresetDefinition(presetId).dependencies) {
|
|
18310
18318
|
visit(dependency);
|
|
18311
18319
|
}
|
|
18312
|
-
visiting.delete(
|
|
18313
|
-
visited.add(
|
|
18314
|
-
ordered.push(
|
|
18320
|
+
visiting.delete(presetId);
|
|
18321
|
+
visited.add(presetId);
|
|
18322
|
+
ordered.push(presetId);
|
|
18315
18323
|
}
|
|
18316
|
-
for (const
|
|
18317
|
-
visit(
|
|
18324
|
+
for (const presetId of presetIds) {
|
|
18325
|
+
visit(presetId);
|
|
18318
18326
|
}
|
|
18319
18327
|
return ordered;
|
|
18320
18328
|
}
|
|
@@ -18373,14 +18381,14 @@ async function regenerateBarrels(cwd, config) {
|
|
|
18373
18381
|
interactive: false
|
|
18374
18382
|
});
|
|
18375
18383
|
}
|
|
18376
|
-
function
|
|
18384
|
+
function resolvePresetProjectPath(config, outputPath) {
|
|
18377
18385
|
const namespacedOutputPath = applyAdminNamespaceToPath(
|
|
18378
18386
|
outputPath,
|
|
18379
18387
|
config.frameworkConfig.next.namespace
|
|
18380
18388
|
);
|
|
18381
18389
|
return path26.posix.join(config.paths.admin.replace(/^\.\//, ""), namespacedOutputPath);
|
|
18382
18390
|
}
|
|
18383
|
-
function
|
|
18391
|
+
function namespacePresetContent(config, content) {
|
|
18384
18392
|
return applyAdminNamespaceToContent(content, config.frameworkConfig.next.namespace);
|
|
18385
18393
|
}
|
|
18386
18394
|
function flattenEnvKeys2(definition) {
|
|
@@ -18396,7 +18404,7 @@ function tryReadCoreManagedTemplate2(relativeOutputPath) {
|
|
|
18396
18404
|
return null;
|
|
18397
18405
|
}
|
|
18398
18406
|
}
|
|
18399
|
-
function
|
|
18407
|
+
function configurePreset(definition, cwd) {
|
|
18400
18408
|
const envResult = appendEnvVars(cwd, definition.envSections);
|
|
18401
18409
|
return {
|
|
18402
18410
|
configured: true,
|
|
@@ -18404,7 +18412,7 @@ function configurePlugin(definition, cwd) {
|
|
|
18404
18412
|
updatedEnvKeys: envResult.updated
|
|
18405
18413
|
};
|
|
18406
18414
|
}
|
|
18407
|
-
function
|
|
18415
|
+
function ensurePresetSchemaTargetsAvailable(cwd, config, definition) {
|
|
18408
18416
|
const schemasDir = getSchemasDir(cwd, config);
|
|
18409
18417
|
for (const schemaFile of definition.schemaFiles) {
|
|
18410
18418
|
const schemaName = schemaFile.replace(/\.json$/, "");
|
|
@@ -18413,21 +18421,21 @@ function ensurePluginSchemaTargetsAvailable(cwd, config, definition) {
|
|
|
18413
18421
|
continue;
|
|
18414
18422
|
}
|
|
18415
18423
|
const owner = getSchemaOwner(cwd, schemaName);
|
|
18416
|
-
if (owner && owner !== `
|
|
18424
|
+
if (owner && owner !== `preset:${definition.id}`) {
|
|
18417
18425
|
throw new Error(
|
|
18418
18426
|
`Schema "${schemaName}" is already owned by "${owner}". Remove or rename it before installing ${definition.id}.`
|
|
18419
18427
|
);
|
|
18420
18428
|
}
|
|
18421
18429
|
if (!owner) {
|
|
18422
18430
|
throw new Error(
|
|
18423
|
-
`Schema "${schemaName}" already exists and is not
|
|
18431
|
+
`Schema "${schemaName}" already exists and is not preset-owned. Remove or rename it before installing ${definition.id}.`
|
|
18424
18432
|
);
|
|
18425
18433
|
}
|
|
18426
18434
|
}
|
|
18427
18435
|
}
|
|
18428
|
-
function
|
|
18436
|
+
function ensurePresetDirectFileTargetsAvailable(cwd, config, definition) {
|
|
18429
18437
|
for (const file of definition.files) {
|
|
18430
|
-
const projectRelativePath =
|
|
18438
|
+
const projectRelativePath = resolvePresetProjectPath(config, file.outputPath);
|
|
18431
18439
|
const fullPath = path26.join(cwd, ...projectRelativePath.split("/"));
|
|
18432
18440
|
if (!fs22.existsSync(fullPath)) {
|
|
18433
18441
|
continue;
|
|
@@ -18439,14 +18447,14 @@ function ensurePluginDirectFileTargetsAvailable(cwd, config, definition) {
|
|
|
18439
18447
|
);
|
|
18440
18448
|
}
|
|
18441
18449
|
const existingContent = normalizeManagedFileContent2(fs22.readFileSync(fullPath, "utf-8"));
|
|
18442
|
-
const
|
|
18443
|
-
|
|
18450
|
+
const presetTemplate = normalizeManagedFileContent2(
|
|
18451
|
+
namespacePresetContent(config, readPresetTemplate(definition.id, file.templatePath))
|
|
18444
18452
|
);
|
|
18445
|
-
if (existingContent ===
|
|
18453
|
+
if (existingContent === presetTemplate) {
|
|
18446
18454
|
continue;
|
|
18447
18455
|
}
|
|
18448
18456
|
const coreTemplate = tryReadCoreManagedTemplate2(file.outputPath);
|
|
18449
|
-
if (coreTemplate && existingContent === normalizeManagedFileContent2(
|
|
18457
|
+
if (coreTemplate && existingContent === normalizeManagedFileContent2(namespacePresetContent(config, coreTemplate))) {
|
|
18450
18458
|
continue;
|
|
18451
18459
|
}
|
|
18452
18460
|
throw new Error(
|
|
@@ -18454,15 +18462,15 @@ function ensurePluginDirectFileTargetsAvailable(cwd, config, definition) {
|
|
|
18454
18462
|
);
|
|
18455
18463
|
}
|
|
18456
18464
|
}
|
|
18457
|
-
function
|
|
18465
|
+
function writePresetDirectFiles(cwd, config, definition) {
|
|
18458
18466
|
const writtenFiles = [];
|
|
18459
18467
|
for (const file of definition.files) {
|
|
18460
|
-
const projectRelativePath =
|
|
18468
|
+
const projectRelativePath = resolvePresetProjectPath(config, file.outputPath);
|
|
18461
18469
|
const fullPath = path26.join(cwd, ...projectRelativePath.split("/"));
|
|
18462
18470
|
fs22.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
18463
18471
|
fs22.writeFileSync(
|
|
18464
18472
|
fullPath,
|
|
18465
|
-
|
|
18473
|
+
namespacePresetContent(config, readPresetTemplate(definition.id, file.templatePath)),
|
|
18466
18474
|
"utf-8"
|
|
18467
18475
|
);
|
|
18468
18476
|
writtenFiles.push(projectRelativePath);
|
|
@@ -18485,7 +18493,7 @@ function cleanupEmptyDirs2(cwd, deletedPaths, config) {
|
|
|
18485
18493
|
toProjectAbsolutePath2(cwd, paths.pagesDir),
|
|
18486
18494
|
toProjectAbsolutePath2(cwd, paths.schemasDir),
|
|
18487
18495
|
path26.join(projectRoot, ".betterstart"),
|
|
18488
|
-
path26.join(projectRoot, ".betterstart", "
|
|
18496
|
+
path26.join(projectRoot, ".betterstart", "presets"),
|
|
18489
18497
|
path26.join(projectRoot, ".betterstart", "snapshots")
|
|
18490
18498
|
]);
|
|
18491
18499
|
for (const deletedPath of deletedPaths) {
|
|
@@ -18503,13 +18511,13 @@ function cleanupEmptyDirs2(cwd, deletedPaths, config) {
|
|
|
18503
18511
|
}
|
|
18504
18512
|
}
|
|
18505
18513
|
}
|
|
18506
|
-
function
|
|
18507
|
-
const projectRelativePath =
|
|
18514
|
+
function restoreOrDeletePresetFile(cwd, config, relativeOutputPath) {
|
|
18515
|
+
const projectRelativePath = resolvePresetProjectPath(config, relativeOutputPath);
|
|
18508
18516
|
const fullPath = toProjectAbsolutePath2(cwd, projectRelativePath);
|
|
18509
18517
|
try {
|
|
18510
18518
|
const coreTemplate = readTemplate(relativeOutputPath);
|
|
18511
18519
|
fs22.mkdirSync(path26.dirname(fullPath), { recursive: true });
|
|
18512
|
-
fs22.writeFileSync(fullPath,
|
|
18520
|
+
fs22.writeFileSync(fullPath, namespacePresetContent(config, coreTemplate), "utf-8");
|
|
18513
18521
|
return null;
|
|
18514
18522
|
} catch {
|
|
18515
18523
|
const existed = fs22.existsSync(fullPath);
|
|
@@ -18517,7 +18525,7 @@ function restoreOrDeletePluginFile(cwd, config, relativeOutputPath) {
|
|
|
18517
18525
|
return existed ? projectRelativePath : null;
|
|
18518
18526
|
}
|
|
18519
18527
|
}
|
|
18520
|
-
function
|
|
18528
|
+
function writePresetSchemas(cwd, config, definition) {
|
|
18521
18529
|
const schemasDir = getSchemasDir(cwd, config);
|
|
18522
18530
|
const writtenSchemaNames = [];
|
|
18523
18531
|
for (const schemaFile of definition.schemaFiles) {
|
|
@@ -18525,7 +18533,7 @@ function writePluginSchemas(cwd, config, definition) {
|
|
|
18525
18533
|
fs22.mkdirSync(path26.dirname(outputPath), { recursive: true });
|
|
18526
18534
|
fs22.writeFileSync(
|
|
18527
18535
|
outputPath,
|
|
18528
|
-
|
|
18536
|
+
readPresetTemplate(definition.id, `schemas/${schemaFile}`),
|
|
18529
18537
|
"utf-8"
|
|
18530
18538
|
);
|
|
18531
18539
|
writtenSchemaNames.push(schemaFile.replace(/\.json$/, ""));
|
|
@@ -18538,7 +18546,7 @@ function removePath(cwd, filePath) {
|
|
|
18538
18546
|
fs22.rmSync(fullPath, { recursive: true, force: true });
|
|
18539
18547
|
return existed;
|
|
18540
18548
|
}
|
|
18541
|
-
function
|
|
18549
|
+
function removePresetSchemas(cwd, config, manifest) {
|
|
18542
18550
|
const paths = resolveProjectPaths(config);
|
|
18543
18551
|
const deletedPaths = [];
|
|
18544
18552
|
const manifestsBySchema = /* @__PURE__ */ new Map();
|
|
@@ -18553,9 +18561,9 @@ function removePluginSchemas(cwd, config, manifest) {
|
|
|
18553
18561
|
}
|
|
18554
18562
|
if (missingManifests.length > 0) {
|
|
18555
18563
|
throw new Error(
|
|
18556
|
-
`Cannot remove ${manifest.id}. Missing snapshot manifest${missingManifests.length === 1 ? "" : "s"} for
|
|
18564
|
+
`Cannot remove ${manifest.id}. Missing snapshot manifest${missingManifests.length === 1 ? "" : "s"} for preset-owned schema${missingManifests.length === 1 ? "" : "s"}: ${missingManifests.join(
|
|
18557
18565
|
", "
|
|
18558
|
-
)}. Re-run \`pnpm betterstart init --force\` to restore snapshot state before removing the
|
|
18566
|
+
)}. Re-run \`pnpm betterstart init --force\` to restore snapshot state before removing the preset.`
|
|
18559
18567
|
);
|
|
18560
18568
|
}
|
|
18561
18569
|
for (const schemaName of manifest.ownedSchemas) {
|
|
@@ -18638,14 +18646,14 @@ function findBlockingSchemaDependencies(cwd, config, ownedSchemas) {
|
|
|
18638
18646
|
);
|
|
18639
18647
|
if (relationshipTargets.length > 0) {
|
|
18640
18648
|
blockers.push(
|
|
18641
|
-
`${schemaName} references
|
|
18649
|
+
`${schemaName} references preset-owned schema(s): ${relationshipTargets.join(", ")}`
|
|
18642
18650
|
);
|
|
18643
18651
|
}
|
|
18644
18652
|
}
|
|
18645
18653
|
return blockers;
|
|
18646
18654
|
}
|
|
18647
|
-
function
|
|
18648
|
-
const remainingDefinitions =
|
|
18655
|
+
function getUnusedPresetDependencies(remainingPresets, removedPresetId, installedIntegrations) {
|
|
18656
|
+
const remainingDefinitions = remainingPresets.map((presetId) => getPresetDefinition(presetId));
|
|
18649
18657
|
const integrationDefinitions = installedIntegrations.map(
|
|
18650
18658
|
(integrationId) => getIntegrationDefinition(integrationId)
|
|
18651
18659
|
);
|
|
@@ -18658,7 +18666,7 @@ function getUnusedPluginDependencies(remainingPlugins, removedPluginId, installe
|
|
|
18658
18666
|
...integrationDefinitions.flatMap((definition) => definition.devDependencies)
|
|
18659
18667
|
]);
|
|
18660
18668
|
const corePlan = getDependencyPlan([], [], false);
|
|
18661
|
-
const removedDefinition =
|
|
18669
|
+
const removedDefinition = getPresetDefinition(removedPresetId);
|
|
18662
18670
|
return {
|
|
18663
18671
|
dependencies: removedDefinition.packageDependencies.filter(
|
|
18664
18672
|
(dependency) => !remainingDependencies.has(dependency) && !corePlan.dependencies.includes(dependency)
|
|
@@ -18668,39 +18676,39 @@ function getUnusedPluginDependencies(remainingPlugins, removedPluginId, installe
|
|
|
18668
18676
|
)
|
|
18669
18677
|
};
|
|
18670
18678
|
}
|
|
18671
|
-
function
|
|
18679
|
+
function parsePresetList(value) {
|
|
18672
18680
|
if (!value) {
|
|
18673
18681
|
return [];
|
|
18674
18682
|
}
|
|
18675
|
-
const
|
|
18676
|
-
const invalid =
|
|
18683
|
+
const presetIds = value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
18684
|
+
const invalid = presetIds.filter((presetId) => !isPresetId(presetId));
|
|
18677
18685
|
if (invalid.length > 0) {
|
|
18678
|
-
throw new Error(
|
|
18686
|
+
throw new Error(formatUnknownPresetMessage(invalid));
|
|
18679
18687
|
}
|
|
18680
|
-
return unique3(
|
|
18688
|
+
return unique3(presetIds);
|
|
18681
18689
|
}
|
|
18682
|
-
function
|
|
18683
|
-
return
|
|
18690
|
+
function getInstalledPresets(config) {
|
|
18691
|
+
return normalizeInstalledPresets(config);
|
|
18684
18692
|
}
|
|
18685
|
-
function
|
|
18686
|
-
for (const
|
|
18687
|
-
const manifest =
|
|
18693
|
+
function syncInstalledPresetManifests(cwd, config) {
|
|
18694
|
+
for (const presetId of normalizeInstalledPresets(config)) {
|
|
18695
|
+
const manifest = loadInstalledPresetManifest(cwd, presetId);
|
|
18688
18696
|
if (!manifest) {
|
|
18689
18697
|
continue;
|
|
18690
18698
|
}
|
|
18691
|
-
const definition =
|
|
18699
|
+
const definition = getPresetDefinition(presetId);
|
|
18692
18700
|
const nextManifest = {
|
|
18693
18701
|
...manifest,
|
|
18694
18702
|
version: definition.version,
|
|
18695
18703
|
kind: definition.kind,
|
|
18696
|
-
ownedFiles: definition.files.map((file) =>
|
|
18704
|
+
ownedFiles: definition.files.map((file) => resolvePresetProjectPath(config, file.outputPath)),
|
|
18697
18705
|
packageDependencies: definition.packageDependencies,
|
|
18698
18706
|
devDependencies: definition.devDependencies,
|
|
18699
18707
|
dependencies: definition.dependencies,
|
|
18700
18708
|
conflicts: definition.conflicts
|
|
18701
18709
|
};
|
|
18702
18710
|
if (JSON.stringify(nextManifest) !== JSON.stringify(manifest)) {
|
|
18703
|
-
|
|
18711
|
+
saveInstalledPresetManifest(cwd, nextManifest);
|
|
18704
18712
|
}
|
|
18705
18713
|
}
|
|
18706
18714
|
}
|
|
@@ -18717,35 +18725,35 @@ function ensureUserSchemaOwnership(cwd, schemaName) {
|
|
|
18717
18725
|
setSchemaOwner(cwd, schemaName, "user");
|
|
18718
18726
|
}
|
|
18719
18727
|
}
|
|
18720
|
-
async function
|
|
18728
|
+
async function installPresets({
|
|
18721
18729
|
cwd,
|
|
18722
18730
|
config,
|
|
18723
18731
|
pm,
|
|
18724
|
-
|
|
18732
|
+
presetIds,
|
|
18725
18733
|
includeBiome
|
|
18726
18734
|
}) {
|
|
18727
|
-
const
|
|
18728
|
-
const
|
|
18735
|
+
const orderedPresetIds = resolvePresetInstallOrder(presetIds);
|
|
18736
|
+
const installedPresetIds = normalizeInstalledPresets(config);
|
|
18729
18737
|
const skipped = [];
|
|
18730
18738
|
const installed2 = [];
|
|
18731
18739
|
const warnings = [];
|
|
18732
18740
|
ensureSnapshotGitFiles(cwd);
|
|
18733
|
-
for (const
|
|
18734
|
-
if (
|
|
18735
|
-
skipped.push(
|
|
18741
|
+
for (const presetId of orderedPresetIds) {
|
|
18742
|
+
if (installedPresetIds.includes(presetId)) {
|
|
18743
|
+
skipped.push(presetId);
|
|
18736
18744
|
continue;
|
|
18737
18745
|
}
|
|
18738
|
-
const definition =
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
const configureResult =
|
|
18746
|
+
const definition = getPresetDefinition(presetId);
|
|
18747
|
+
ensurePresetSchemaTargetsAvailable(cwd, config, definition);
|
|
18748
|
+
ensurePresetDirectFileTargetsAvailable(cwd, config, definition);
|
|
18749
|
+
const configureResult = configurePreset(definition, cwd);
|
|
18742
18750
|
const dependencyPlan = getDependencyPlan(
|
|
18743
|
-
[...
|
|
18751
|
+
[...installedPresetIds, presetId],
|
|
18744
18752
|
config.integrations.installed,
|
|
18745
18753
|
includeBiome
|
|
18746
18754
|
);
|
|
18747
18755
|
const currentPlan = getDependencyPlan(
|
|
18748
|
-
|
|
18756
|
+
installedPresetIds,
|
|
18749
18757
|
config.integrations.installed,
|
|
18750
18758
|
includeBiome
|
|
18751
18759
|
);
|
|
@@ -18765,23 +18773,23 @@ async function installPlugins({
|
|
|
18765
18773
|
devDependencies: dependencyDiff.devDependencies
|
|
18766
18774
|
});
|
|
18767
18775
|
if (!result.success) {
|
|
18768
|
-
throw new Error(result.error ?? `Failed to install dependencies for ${
|
|
18776
|
+
throw new Error(result.error ?? `Failed to install dependencies for ${presetId}.`);
|
|
18769
18777
|
}
|
|
18770
18778
|
}
|
|
18771
|
-
const writtenFiles =
|
|
18772
|
-
const writtenSchemas =
|
|
18779
|
+
const writtenFiles = writePresetDirectFiles(cwd, config, definition);
|
|
18780
|
+
const writtenSchemas = writePresetSchemas(cwd, config, definition);
|
|
18773
18781
|
for (const schemaName of writtenSchemas) {
|
|
18774
18782
|
const loaded = loadSchema(getSchemasDir(cwd, config), schemaName);
|
|
18775
|
-
await applyGeneratedSchema(cwd, config, loaded,
|
|
18776
|
-
setSchemaOwner(cwd, schemaName, `
|
|
18783
|
+
await applyGeneratedSchema(cwd, config, loaded, presetId);
|
|
18784
|
+
setSchemaOwner(cwd, schemaName, `preset:${presetId}`);
|
|
18777
18785
|
}
|
|
18778
18786
|
if (writtenSchemas.length > 0) {
|
|
18779
18787
|
await regenerateBarrels(cwd, config);
|
|
18780
18788
|
}
|
|
18781
|
-
|
|
18782
|
-
config.
|
|
18789
|
+
installedPresetIds.push(presetId);
|
|
18790
|
+
config.presets.installed = unique3(installedPresetIds).sort();
|
|
18783
18791
|
const manifest = {
|
|
18784
|
-
id:
|
|
18792
|
+
id: presetId,
|
|
18785
18793
|
version: definition.version,
|
|
18786
18794
|
kind: definition.kind,
|
|
18787
18795
|
ownedSchemas: writtenSchemas,
|
|
@@ -18794,9 +18802,9 @@ async function installPlugins({
|
|
|
18794
18802
|
conflicts: definition.conflicts,
|
|
18795
18803
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
18796
18804
|
};
|
|
18797
|
-
|
|
18805
|
+
saveInstalledPresetManifest(cwd, manifest);
|
|
18798
18806
|
writeConfigFile(cwd, config);
|
|
18799
|
-
installed2.push(
|
|
18807
|
+
installed2.push(presetId);
|
|
18800
18808
|
}
|
|
18801
18809
|
return {
|
|
18802
18810
|
installed: installed2,
|
|
@@ -18805,58 +18813,58 @@ async function installPlugins({
|
|
|
18805
18813
|
config
|
|
18806
18814
|
};
|
|
18807
18815
|
}
|
|
18808
|
-
async function
|
|
18816
|
+
async function removePresets({
|
|
18809
18817
|
cwd,
|
|
18810
18818
|
config,
|
|
18811
18819
|
pm,
|
|
18812
|
-
|
|
18820
|
+
presetIds
|
|
18813
18821
|
}) {
|
|
18814
|
-
const
|
|
18822
|
+
const installedPresets = normalizeInstalledPresets(config);
|
|
18815
18823
|
const removed = [];
|
|
18816
18824
|
const warnings = [];
|
|
18817
|
-
for (const
|
|
18818
|
-
if (!
|
|
18819
|
-
warnings.push(`${
|
|
18825
|
+
for (const presetId of presetIds) {
|
|
18826
|
+
if (!installedPresets.includes(presetId)) {
|
|
18827
|
+
warnings.push(`${presetId} is not installed.`);
|
|
18820
18828
|
continue;
|
|
18821
18829
|
}
|
|
18822
|
-
const manifest =
|
|
18830
|
+
const manifest = loadInstalledPresetManifest(cwd, presetId);
|
|
18823
18831
|
if (!manifest) {
|
|
18824
|
-
throw new Error(`Missing manifest for installed
|
|
18832
|
+
throw new Error(`Missing manifest for installed preset "${presetId}".`);
|
|
18825
18833
|
}
|
|
18826
|
-
const dependents =
|
|
18827
|
-
if (
|
|
18834
|
+
const dependents = installedPresets.filter((installedPresetId) => {
|
|
18835
|
+
if (installedPresetId === presetId) {
|
|
18828
18836
|
return false;
|
|
18829
18837
|
}
|
|
18830
|
-
return
|
|
18838
|
+
return getPresetDefinition(installedPresetId).dependencies.includes(presetId);
|
|
18831
18839
|
});
|
|
18832
18840
|
if (dependents.length > 0) {
|
|
18833
18841
|
throw new Error(
|
|
18834
|
-
`Cannot remove ${
|
|
18842
|
+
`Cannot remove ${presetId}. The following presets depend on it: ${dependents.join(", ")}`
|
|
18835
18843
|
);
|
|
18836
18844
|
}
|
|
18837
18845
|
const blockers = findBlockingSchemaDependencies(cwd, config, manifest.ownedSchemas);
|
|
18838
18846
|
if (blockers.length > 0) {
|
|
18839
|
-
throw new Error(`Cannot remove ${
|
|
18847
|
+
throw new Error(`Cannot remove ${presetId}:
|
|
18840
18848
|
- ${blockers.join("\n- ")}`);
|
|
18841
18849
|
}
|
|
18842
|
-
const deletedPaths =
|
|
18850
|
+
const deletedPaths = removePresetSchemas(cwd, config, manifest);
|
|
18843
18851
|
for (const filePath of manifest.ownedFiles) {
|
|
18844
18852
|
const relativeOutputPath = filePath.replace(`${config.paths.admin.replace(/^\.\//, "")}/`, "");
|
|
18845
|
-
const deletedPath =
|
|
18853
|
+
const deletedPath = restoreOrDeletePresetFile(cwd, config, relativeOutputPath);
|
|
18846
18854
|
if (deletedPath) {
|
|
18847
18855
|
deletedPaths.push(deletedPath);
|
|
18848
18856
|
}
|
|
18849
18857
|
}
|
|
18850
|
-
|
|
18851
|
-
const
|
|
18852
|
-
(
|
|
18858
|
+
deleteInstalledPresetManifest(cwd, presetId);
|
|
18859
|
+
const nextInstalledPresets = installedPresets.filter(
|
|
18860
|
+
(installedPresetId) => installedPresetId !== presetId
|
|
18853
18861
|
);
|
|
18854
|
-
|
|
18855
|
-
config.
|
|
18856
|
-
const
|
|
18857
|
-
const dependencyDiff =
|
|
18858
|
-
|
|
18859
|
-
|
|
18862
|
+
installedPresets.splice(0, installedPresets.length, ...nextInstalledPresets);
|
|
18863
|
+
config.presets.installed = [...nextInstalledPresets].sort();
|
|
18864
|
+
const remainingPresets = normalizeInstalledPresets(config);
|
|
18865
|
+
const dependencyDiff = getUnusedPresetDependencies(
|
|
18866
|
+
remainingPresets,
|
|
18867
|
+
presetId,
|
|
18860
18868
|
config.integrations.installed
|
|
18861
18869
|
);
|
|
18862
18870
|
if (dependencyDiff.dependencies.length > 0 || dependencyDiff.devDependencies.length > 0) {
|
|
@@ -18867,12 +18875,12 @@ async function removePlugins({
|
|
|
18867
18875
|
devDependencies: dependencyDiff.devDependencies
|
|
18868
18876
|
});
|
|
18869
18877
|
if (!result.success) {
|
|
18870
|
-
warnings.push(result.error ?? `Failed to remove dependencies for ${
|
|
18878
|
+
warnings.push(result.error ?? `Failed to remove dependencies for ${presetId}.`);
|
|
18871
18879
|
}
|
|
18872
18880
|
}
|
|
18873
18881
|
const usedEnvKeys = new Set(
|
|
18874
|
-
|
|
18875
|
-
(
|
|
18882
|
+
remainingPresets.flatMap(
|
|
18883
|
+
(installedPresetId) => flattenEnvKeys2(getPresetDefinition(installedPresetId))
|
|
18876
18884
|
)
|
|
18877
18885
|
);
|
|
18878
18886
|
const removableEnvKeys = manifest.envKeys.filter((envKey) => !usedEnvKeys.has(envKey));
|
|
@@ -18884,7 +18892,7 @@ async function removePlugins({
|
|
|
18884
18892
|
}
|
|
18885
18893
|
cleanupEmptyDirs2(cwd, deletedPaths, config);
|
|
18886
18894
|
writeConfigFile(cwd, config);
|
|
18887
|
-
removed.push(
|
|
18895
|
+
removed.push(presetId);
|
|
18888
18896
|
}
|
|
18889
18897
|
return {
|
|
18890
18898
|
removed,
|
|
@@ -18892,8 +18900,8 @@ async function removePlugins({
|
|
|
18892
18900
|
config
|
|
18893
18901
|
};
|
|
18894
18902
|
}
|
|
18895
|
-
function
|
|
18896
|
-
return
|
|
18903
|
+
function listAvailablePresets() {
|
|
18904
|
+
return listPresetDefinitions();
|
|
18897
18905
|
}
|
|
18898
18906
|
|
|
18899
18907
|
// adapters/next/commands/add.ts
|
|
@@ -18909,7 +18917,7 @@ function printAddNextSteps(installKind, hasSchemaChanges, result, adminRoutePath
|
|
|
18909
18917
|
}
|
|
18910
18918
|
async function runAddCommand(items, options) {
|
|
18911
18919
|
const installIntegrationsMode = Boolean(options.integration);
|
|
18912
|
-
const
|
|
18920
|
+
const presetIds = items.filter(isPresetId);
|
|
18913
18921
|
const integrationIds = items.filter(isIntegrationId);
|
|
18914
18922
|
if (!installIntegrationsMode && integrationIds.length > 0) {
|
|
18915
18923
|
p4.log.error(
|
|
@@ -18917,14 +18925,14 @@ async function runAddCommand(items, options) {
|
|
|
18917
18925
|
);
|
|
18918
18926
|
process.exit(1);
|
|
18919
18927
|
}
|
|
18920
|
-
if (installIntegrationsMode &&
|
|
18921
|
-
p4.log.error(`
|
|
18928
|
+
if (installIntegrationsMode && presetIds.length > 0) {
|
|
18929
|
+
p4.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
|
|
18922
18930
|
process.exit(1);
|
|
18923
18931
|
}
|
|
18924
|
-
const invalidItems = installIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((
|
|
18932
|
+
const invalidItems = installIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
|
|
18925
18933
|
if (invalidItems.length > 0) {
|
|
18926
18934
|
p4.log.error(
|
|
18927
|
-
installIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) :
|
|
18935
|
+
installIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
|
|
18928
18936
|
);
|
|
18929
18937
|
process.exit(1);
|
|
18930
18938
|
}
|
|
@@ -18976,16 +18984,16 @@ async function runAddCommand(items, options) {
|
|
|
18976
18984
|
p4.outro(messages.join("\n"));
|
|
18977
18985
|
return;
|
|
18978
18986
|
}
|
|
18979
|
-
const
|
|
18980
|
-
if (
|
|
18981
|
-
p4.log.error(
|
|
18987
|
+
const invalidPresets = items.filter((presetId) => !isPresetId(presetId));
|
|
18988
|
+
if (invalidPresets.length > 0) {
|
|
18989
|
+
p4.log.error(formatUnknownPresetMessage(invalidPresets));
|
|
18982
18990
|
process.exit(1);
|
|
18983
18991
|
}
|
|
18984
|
-
const result = await
|
|
18992
|
+
const result = await installPresets({
|
|
18985
18993
|
cwd,
|
|
18986
18994
|
config,
|
|
18987
18995
|
pm,
|
|
18988
|
-
|
|
18996
|
+
presetIds,
|
|
18989
18997
|
interactive: !options.yes,
|
|
18990
18998
|
includeBiome: false
|
|
18991
18999
|
});
|
|
@@ -18998,7 +19006,7 @@ async function runAddCommand(items, options) {
|
|
|
18998
19006
|
p4.note(result.warnings.join("\n"), "Warnings");
|
|
18999
19007
|
}
|
|
19000
19008
|
const installedSchemaNames = result.installed.flatMap(
|
|
19001
|
-
(
|
|
19009
|
+
(presetId) => getPresetDefinition(presetId).schemaFiles.map((schemaFile) => schemaFile.replace(/\.json$/, ""))
|
|
19002
19010
|
);
|
|
19003
19011
|
const hasSchemaChanges = installedSchemaNames.length > 0;
|
|
19004
19012
|
const conflictPaths = scanConflictPaths(cwd);
|
|
@@ -19010,10 +19018,10 @@ async function runAddCommand(items, options) {
|
|
|
19010
19018
|
showNextSteps: false
|
|
19011
19019
|
});
|
|
19012
19020
|
if (conflictPaths.length === 0) {
|
|
19013
|
-
printAddNextSteps("
|
|
19021
|
+
printAddNextSteps("preset", hasSchemaChanges, postGenerateResult, adminRoutePath);
|
|
19014
19022
|
}
|
|
19015
19023
|
p4.outro(
|
|
19016
|
-
`Installed
|
|
19024
|
+
`Installed preset${result.installed.length === 1 ? "" : "s"}: ${result.installed.join(", ")}`
|
|
19017
19025
|
);
|
|
19018
19026
|
}
|
|
19019
19027
|
|
|
@@ -20121,7 +20129,7 @@ function validateIntegrationRequirements(loaded, config) {
|
|
|
20121
20129
|
}
|
|
20122
20130
|
function runPipeline(loaded, cwd, config, options) {
|
|
20123
20131
|
const owner = getSchemaOwner(cwd, loaded.schema.name);
|
|
20124
|
-
const outputNamespace = owner === "core" ? "core" : owner?.startsWith("
|
|
20132
|
+
const outputNamespace = owner === "core" ? "core" : owner?.startsWith("preset:") ? owner.replace(/^preset:/, "") : void 0;
|
|
20125
20133
|
if (loaded.type === "form") {
|
|
20126
20134
|
return runFormPipeline(loaded.schema, cwd, config, {
|
|
20127
20135
|
force: options.force,
|
|
@@ -21090,8 +21098,8 @@ function schemaNameFromLoaded(loaded) {
|
|
|
21090
21098
|
function resolveSchemaOwner(cwd, schemaName) {
|
|
21091
21099
|
return getSchemaOwner(cwd, schemaName) ?? (schemaName === "settings" ? "core" : "user");
|
|
21092
21100
|
}
|
|
21093
|
-
function
|
|
21094
|
-
return owner.startsWith("
|
|
21101
|
+
function presetIdFromOwner(owner) {
|
|
21102
|
+
return owner.startsWith("preset:") ? owner.replace(/^preset:/, "") : null;
|
|
21095
21103
|
}
|
|
21096
21104
|
async function promptConfirm3(message, initialValue = true) {
|
|
21097
21105
|
return promptConfirm2(ADD_FIELD_PROMPT_CONTEXT, message, initialValue);
|
|
@@ -21162,7 +21170,7 @@ async function createInteractiveInsertion2(loaded, schemasDir) {
|
|
|
21162
21170
|
return createInteractiveInsertion(ADD_FIELD_PROMPT_CONTEXT, loaded, schemasDir);
|
|
21163
21171
|
}
|
|
21164
21172
|
function printPreview(loaded, owner, firstTimeGeneration, insertion, options) {
|
|
21165
|
-
const
|
|
21173
|
+
const presetId = presetIdFromOwner(owner);
|
|
21166
21174
|
const lines = [
|
|
21167
21175
|
`schema: ${loaded.name} (${formatKind(loaded.kind)})`,
|
|
21168
21176
|
`display: ${getSchemaDisplayName(loaded)}`,
|
|
@@ -21172,9 +21180,9 @@ function printPreview(loaded, owner, firstTimeGeneration, insertion, options) {
|
|
|
21172
21180
|
`migration: ${options.skipMigration ? "skip db:push" : "run post-generate default"}`,
|
|
21173
21181
|
`merge conflicts: ${options.acceptGenerated || options.yes ? "accept generated output" : "write conflict markers"}`
|
|
21174
21182
|
];
|
|
21175
|
-
if (
|
|
21183
|
+
if (presetId) {
|
|
21176
21184
|
lines.push(
|
|
21177
|
-
`warning:
|
|
21185
|
+
`warning: preset-owned schema; uninstalling "${presetId}" can remove this schema and generated output`
|
|
21178
21186
|
);
|
|
21179
21187
|
}
|
|
21180
21188
|
if (firstTimeGeneration) {
|
|
@@ -21194,10 +21202,10 @@ ${stringifyProjectJson(insertion.field).trim()}`,
|
|
|
21194
21202
|
}
|
|
21195
21203
|
async function confirmWarningCases(owner, firstTimeGeneration, requiredPersistedField, nonInteractive, yes, extraWarnings = []) {
|
|
21196
21204
|
const warnings = [...extraWarnings];
|
|
21197
|
-
const
|
|
21198
|
-
if (
|
|
21205
|
+
const presetId = presetIdFromOwner(owner);
|
|
21206
|
+
if (presetId) {
|
|
21199
21207
|
warnings.push(
|
|
21200
|
-
`Schema is
|
|
21208
|
+
`Schema is preset-owned by "${presetId}". Removing that preset can remove the customized schema JSON, generated files, snapshots, and ownership entry.`
|
|
21201
21209
|
);
|
|
21202
21210
|
}
|
|
21203
21211
|
if (firstTimeGeneration) {
|
|
@@ -21232,8 +21240,8 @@ function collectRelationshipTargetWarnings(cwd, owner, field) {
|
|
|
21232
21240
|
collectRelationshipTargets(field, targetNames);
|
|
21233
21241
|
return Array.from(targetNames).map((targetName) => {
|
|
21234
21242
|
const targetOwner = getSchemaOwner(cwd, targetName);
|
|
21235
|
-
const
|
|
21236
|
-
return
|
|
21243
|
+
const presetId = targetOwner ? presetIdFromOwner(targetOwner) : null;
|
|
21244
|
+
return presetId ? `This user-owned schema references preset-owned schema "${targetName}". Removing preset "${presetId}" may affect that relationship.` : null;
|
|
21237
21245
|
}).filter((warning) => Boolean(warning));
|
|
21238
21246
|
}
|
|
21239
21247
|
function collectRelationshipTargets(field, targets) {
|
|
@@ -22024,7 +22032,7 @@ function openBrowser(url) {
|
|
|
22024
22032
|
}
|
|
22025
22033
|
}
|
|
22026
22034
|
|
|
22027
|
-
// adapters/next/init/prompts/
|
|
22035
|
+
// adapters/next/init/prompts/presets.ts
|
|
22028
22036
|
import { styleText } from "util";
|
|
22029
22037
|
import * as p12 from "@clack/prompts";
|
|
22030
22038
|
|
|
@@ -22175,13 +22183,13 @@ function scaffoldEnv(cwd, options) {
|
|
|
22175
22183
|
return appendEnvVars(cwd, sections, overwrite);
|
|
22176
22184
|
}
|
|
22177
22185
|
|
|
22178
|
-
// adapters/next/init/prompts/
|
|
22186
|
+
// adapters/next/init/prompts/presets.ts
|
|
22179
22187
|
function maskBlobToken(token) {
|
|
22180
22188
|
const match = /^(vercel_blob_rw_[A-Za-z0-9]+)_/.exec(token);
|
|
22181
22189
|
if (match) return `${match[1]}_***`;
|
|
22182
22190
|
return `${token.slice(0, 8)}***`;
|
|
22183
22191
|
}
|
|
22184
|
-
async function
|
|
22192
|
+
async function promptPresets(cwd, options = {}) {
|
|
22185
22193
|
const sections = [];
|
|
22186
22194
|
const overwriteKeys = /* @__PURE__ */ new Set();
|
|
22187
22195
|
const mergeIntegrationConfig = (collected) => {
|
|
@@ -22253,7 +22261,7 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22253
22261
|
} else {
|
|
22254
22262
|
storageStep.confirm();
|
|
22255
22263
|
}
|
|
22256
|
-
const
|
|
22264
|
+
const selectedPresets = await p12.multiselect({
|
|
22257
22265
|
message: "Select presets",
|
|
22258
22266
|
options: [
|
|
22259
22267
|
{
|
|
@@ -22265,7 +22273,7 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22265
22273
|
required: false,
|
|
22266
22274
|
initialValues: ["blog"]
|
|
22267
22275
|
});
|
|
22268
|
-
if (p12.isCancel(
|
|
22276
|
+
if (p12.isCancel(selectedPresets)) {
|
|
22269
22277
|
p12.cancel("Setup cancelled.");
|
|
22270
22278
|
process.exit(0);
|
|
22271
22279
|
}
|
|
@@ -22283,7 +22291,7 @@ async function promptPlugins(cwd, options = {}) {
|
|
|
22283
22291
|
integrations.push("vercel-blob");
|
|
22284
22292
|
}
|
|
22285
22293
|
return {
|
|
22286
|
-
|
|
22294
|
+
presets: selectedPresets,
|
|
22287
22295
|
integrations,
|
|
22288
22296
|
storage,
|
|
22289
22297
|
integrationConfig: { sections, overwriteKeys }
|
|
@@ -25814,9 +25822,9 @@ async function runInitCommand(name, options) {
|
|
|
25814
25822
|
databaseStep.confirm();
|
|
25815
25823
|
}
|
|
25816
25824
|
}
|
|
25817
|
-
const
|
|
25818
|
-
if (options.
|
|
25819
|
-
return
|
|
25825
|
+
const selectedPresets = (() => {
|
|
25826
|
+
if (options.presets) {
|
|
25827
|
+
return parsePresetList(options.presets);
|
|
25820
25828
|
}
|
|
25821
25829
|
return [];
|
|
25822
25830
|
})();
|
|
@@ -25830,15 +25838,15 @@ async function runInitCommand(name, options) {
|
|
|
25830
25838
|
sections: [],
|
|
25831
25839
|
overwriteKeys: /* @__PURE__ */ new Set()
|
|
25832
25840
|
};
|
|
25833
|
-
let
|
|
25841
|
+
let presetSelection;
|
|
25834
25842
|
const vercelBlobAllowed = options.vercel !== false;
|
|
25835
|
-
if (
|
|
25836
|
-
|
|
25837
|
-
|
|
25843
|
+
if (selectedPresets.length > 0 || selectedIntegrations.length > 0) {
|
|
25844
|
+
presetSelection = {
|
|
25845
|
+
presets: selectedPresets,
|
|
25838
25846
|
integrations: selectedIntegrations,
|
|
25839
25847
|
storage: selectedIntegrations.includes("vercel-blob") ? "vercel-blob" : selectedIntegrations.includes("r2") ? "r2" : "local"
|
|
25840
25848
|
};
|
|
25841
|
-
if (
|
|
25849
|
+
if (presetSelection.storage === "vercel-blob" && !readEnvVar(cwd, "BLOB_READ_WRITE_TOKEN")?.trim() && vercelBlobAllowed && (!options.yes || process.env.VERCEL_TOKEN)) {
|
|
25842
25850
|
const flow = await runVercelBlobFlow({
|
|
25843
25851
|
cwd,
|
|
25844
25852
|
projectName,
|
|
@@ -25863,15 +25871,15 @@ async function runInitCommand(name, options) {
|
|
|
25863
25871
|
}
|
|
25864
25872
|
}
|
|
25865
25873
|
} else if (options.yes) {
|
|
25866
|
-
|
|
25874
|
+
presetSelection = { presets: [], integrations: [], storage: "local" };
|
|
25867
25875
|
} else {
|
|
25868
25876
|
dismissVercelSignedInNote?.();
|
|
25869
|
-
const promptResult = await
|
|
25877
|
+
const promptResult = await promptPresets(cwd, {
|
|
25870
25878
|
provisionVercelBlob: vercelBlobAllowed ? () => runVercelBlobFlow({ cwd, projectName, interactive: true, env: process.env }) : void 0
|
|
25871
25879
|
});
|
|
25872
25880
|
collectedIntegrationConfig = promptResult.integrationConfig;
|
|
25873
|
-
|
|
25874
|
-
|
|
25881
|
+
presetSelection = {
|
|
25882
|
+
presets: promptResult.presets,
|
|
25875
25883
|
integrations: promptResult.integrations,
|
|
25876
25884
|
storage: promptResult.storage
|
|
25877
25885
|
};
|
|
@@ -25889,7 +25897,7 @@ async function runInitCommand(name, options) {
|
|
|
25889
25897
|
scaffoldBase({
|
|
25890
25898
|
cwd,
|
|
25891
25899
|
config,
|
|
25892
|
-
includeEmailTemplatesDir:
|
|
25900
|
+
includeEmailTemplatesDir: presetSelection.integrations.some(isEmailProviderIntegration)
|
|
25893
25901
|
});
|
|
25894
25902
|
s.message("TypeScript aliases");
|
|
25895
25903
|
scaffoldTsconfig(cwd, config);
|
|
@@ -25988,29 +25996,29 @@ async function runInitCommand(name, options) {
|
|
|
25988
25996
|
const coreSchemasResult = scaffoldCoreSchemas({ cwd, config });
|
|
25989
25997
|
s.stop("");
|
|
25990
25998
|
process.stdout.write("\x1B[2A\x1B[J");
|
|
25991
|
-
const
|
|
25992
|
-
s.start(`Installing
|
|
25993
|
-
return
|
|
25999
|
+
const presetInstallResult = presetSelection.presets.length > 0 ? (() => {
|
|
26000
|
+
s.start(`Installing presets: ${presetSelection.presets.join(", ")}`);
|
|
26001
|
+
return installPresets({
|
|
25994
26002
|
cwd,
|
|
25995
26003
|
config,
|
|
25996
26004
|
pm,
|
|
25997
|
-
|
|
26005
|
+
presetIds: presetSelection.presets,
|
|
25998
26006
|
interactive: !options.yes,
|
|
25999
26007
|
includeBiome: project2.linter.type === "none"
|
|
26000
26008
|
});
|
|
26001
26009
|
})() : Promise.resolve({ installed: [], skipped: [], warnings: [], config });
|
|
26002
|
-
const
|
|
26003
|
-
if (
|
|
26010
|
+
const resolvedPresetInstallResult = await presetInstallResult;
|
|
26011
|
+
if (presetSelection.presets.length > 0) {
|
|
26004
26012
|
s.stop("");
|
|
26005
26013
|
process.stdout.write("\x1B[2A\x1B[J");
|
|
26006
26014
|
}
|
|
26007
|
-
const integrationInstallResult =
|
|
26008
|
-
s.start(`Installing integrations: ${
|
|
26015
|
+
const integrationInstallResult = presetSelection.integrations.length > 0 ? (() => {
|
|
26016
|
+
s.start(`Installing integrations: ${presetSelection.integrations.join(", ")}`);
|
|
26009
26017
|
return installIntegrations({
|
|
26010
26018
|
cwd,
|
|
26011
|
-
config:
|
|
26019
|
+
config: resolvedPresetInstallResult.config,
|
|
26012
26020
|
pm,
|
|
26013
|
-
integrationIds:
|
|
26021
|
+
integrationIds: presetSelection.integrations,
|
|
26014
26022
|
// Secrets were already collected up front and persisted/written to
|
|
26015
26023
|
// .env.local, so the install runs without prompting (rule: no
|
|
26016
26024
|
// mid-scaffold input).
|
|
@@ -26021,10 +26029,10 @@ async function runInitCommand(name, options) {
|
|
|
26021
26029
|
installed: [],
|
|
26022
26030
|
skipped: [],
|
|
26023
26031
|
warnings: [],
|
|
26024
|
-
config:
|
|
26032
|
+
config: resolvedPresetInstallResult.config
|
|
26025
26033
|
});
|
|
26026
26034
|
const resolvedIntegrationInstallResult = await integrationInstallResult;
|
|
26027
|
-
if (
|
|
26035
|
+
if (presetSelection.integrations.length > 0) {
|
|
26028
26036
|
s.stop("");
|
|
26029
26037
|
process.stdout.write("\x1B[2A\x1B[J");
|
|
26030
26038
|
}
|
|
@@ -26033,7 +26041,7 @@ async function runInitCommand(name, options) {
|
|
|
26033
26041
|
for (const err of coreSchemasResult.errors) {
|
|
26034
26042
|
p18.log.warn(`Core schemas: ${err}`);
|
|
26035
26043
|
}
|
|
26036
|
-
for (const warning of
|
|
26044
|
+
for (const warning of resolvedPresetInstallResult.warnings) {
|
|
26037
26045
|
p18.log.warn(warning);
|
|
26038
26046
|
}
|
|
26039
26047
|
for (const warning of resolvedIntegrationInstallResult.warnings) {
|
|
@@ -26072,24 +26080,35 @@ async function runInitCommand(name, options) {
|
|
|
26072
26080
|
}
|
|
26073
26081
|
if (driverReady) {
|
|
26074
26082
|
const useTerminalForDbPush = shouldUseTerminalForDbPush(options);
|
|
26075
|
-
|
|
26076
|
-
|
|
26077
|
-
|
|
26078
|
-
|
|
26083
|
+
let dbSpinnerVisible = true;
|
|
26084
|
+
const clearDbSpinner = () => {
|
|
26085
|
+
if (!dbSpinnerVisible) return;
|
|
26086
|
+
dbSpinnerVisible = false;
|
|
26087
|
+
s.clear();
|
|
26088
|
+
};
|
|
26089
|
+
s.start(
|
|
26090
|
+
useTerminalForDbPush ? "Setting up database" : "Pushing database schema (drizzle-kit push)"
|
|
26091
|
+
);
|
|
26092
|
+
const pushResult = await runDrizzlePush(cwd, {
|
|
26093
|
+
interactive: useTerminalForDbPush,
|
|
26094
|
+
onOutput: clearDbSpinner
|
|
26095
|
+
});
|
|
26079
26096
|
if (pushResult.success) {
|
|
26080
26097
|
if (useTerminalForDbPush) {
|
|
26081
26098
|
const verification = await verifyDatabaseReachable(cwd);
|
|
26099
|
+
clearDbSpinner();
|
|
26082
26100
|
if (!verification.success) {
|
|
26083
26101
|
p18.log.warning(verification.error);
|
|
26084
26102
|
p18.log.error("Database was not reachable. Aborting setup.");
|
|
26085
26103
|
process.exit(1);
|
|
26086
26104
|
}
|
|
26087
26105
|
} else {
|
|
26088
|
-
|
|
26106
|
+
clearDbSpinner();
|
|
26089
26107
|
}
|
|
26090
26108
|
dbPushed = true;
|
|
26091
26109
|
} else {
|
|
26092
|
-
if (
|
|
26110
|
+
if (dbSpinnerVisible) {
|
|
26111
|
+
dbSpinnerVisible = false;
|
|
26093
26112
|
s.stop("Database push failed");
|
|
26094
26113
|
}
|
|
26095
26114
|
const pushError = pushResult.error ?? "Unknown error";
|
|
@@ -26115,7 +26134,9 @@ async function runInitCommand(name, options) {
|
|
|
26115
26134
|
const adminDir = config.paths?.admin ?? "./admin";
|
|
26116
26135
|
const authBasePath = `${resolveAdminNamespace(namespace).apiPath}/auth`;
|
|
26117
26136
|
let replaceExistingAdmin = false;
|
|
26137
|
+
s.start("Setting up database");
|
|
26118
26138
|
const adminCheck = await checkExistingAdmin(cwd, adminDir, authBasePath);
|
|
26139
|
+
s.clear();
|
|
26119
26140
|
if (adminCheck.error) {
|
|
26120
26141
|
p18.log.warning(`Could not verify existing admin account ${pc7.dim(`(${adminCheck.error})`)}`);
|
|
26121
26142
|
if (isDatabaseReachabilityError(adminCheck.error)) {
|
|
@@ -26783,19 +26804,19 @@ async function runListIntegrationsCommand(options) {
|
|
|
26783
26804
|
);
|
|
26784
26805
|
}
|
|
26785
26806
|
|
|
26786
|
-
// adapters/next/commands/list-
|
|
26807
|
+
// adapters/next/commands/list-presets.ts
|
|
26787
26808
|
import path52 from "path";
|
|
26788
26809
|
import * as p20 from "@clack/prompts";
|
|
26789
|
-
async function
|
|
26810
|
+
async function runListPresetsCommand(options) {
|
|
26790
26811
|
const cwd = options.cwd ? path52.resolve(options.cwd) : process.cwd();
|
|
26791
26812
|
const config = await resolveConfig(cwd);
|
|
26792
|
-
const
|
|
26793
|
-
const lines =
|
|
26794
|
-
const status =
|
|
26795
|
-
return `${
|
|
26813
|
+
const installedPresets = new Set(config.presets.installed);
|
|
26814
|
+
const lines = listAvailablePresets().map((preset) => {
|
|
26815
|
+
const status = installedPresets.has(preset.id) ? "installed" : "available";
|
|
26816
|
+
return `${preset.id.padEnd(10)} ${status.padEnd(10)} ${preset.kind.padEnd(12)} ${preset.description}`;
|
|
26796
26817
|
});
|
|
26797
|
-
p20.note(lines.join("\n"), "BetterStart
|
|
26798
|
-
p20.outro(`${
|
|
26818
|
+
p20.note(lines.join("\n"), "BetterStart presets");
|
|
26819
|
+
p20.outro(`${installedPresets.size} installed, ${lines.length - installedPresets.size} available`);
|
|
26799
26820
|
}
|
|
26800
26821
|
|
|
26801
26822
|
// adapters/next/commands/remove.ts
|
|
@@ -26807,7 +26828,7 @@ async function runRemoveCommand(items, options) {
|
|
|
26807
26828
|
p21.log.error("The core Admin cannot be removed.");
|
|
26808
26829
|
process.exit(1);
|
|
26809
26830
|
}
|
|
26810
|
-
const
|
|
26831
|
+
const presetIds = items.filter(isPresetId);
|
|
26811
26832
|
const integrationIds = items.filter(isIntegrationId);
|
|
26812
26833
|
if (!removeIntegrationsMode && integrationIds.length > 0) {
|
|
26813
26834
|
p21.log.error(
|
|
@@ -26815,14 +26836,14 @@ async function runRemoveCommand(items, options) {
|
|
|
26815
26836
|
);
|
|
26816
26837
|
process.exit(1);
|
|
26817
26838
|
}
|
|
26818
|
-
if (removeIntegrationsMode &&
|
|
26819
|
-
p21.log.error(`
|
|
26839
|
+
if (removeIntegrationsMode && presetIds.length > 0) {
|
|
26840
|
+
p21.log.error(`Preset IDs cannot be removed with --integration: ${presetIds.join(", ")}`);
|
|
26820
26841
|
process.exit(1);
|
|
26821
26842
|
}
|
|
26822
|
-
const invalidItems = removeIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((
|
|
26843
|
+
const invalidItems = removeIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
|
|
26823
26844
|
if (invalidItems.length > 0) {
|
|
26824
26845
|
p21.log.error(
|
|
26825
|
-
removeIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) :
|
|
26846
|
+
removeIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
|
|
26826
26847
|
);
|
|
26827
26848
|
process.exit(1);
|
|
26828
26849
|
}
|
|
@@ -26831,11 +26852,11 @@ async function runRemoveCommand(items, options) {
|
|
|
26831
26852
|
const pm = detectPackageManager(cwd);
|
|
26832
26853
|
if (!options.force) {
|
|
26833
26854
|
const confirmed = await p21.confirm({
|
|
26834
|
-
message: `Remove ${removeIntegrationsMode ? "integration" : "
|
|
26855
|
+
message: `Remove ${removeIntegrationsMode ? "integration" : "preset"}${items.length === 1 ? "" : "s"} ${items.join(", ")}?`,
|
|
26835
26856
|
initialValue: false
|
|
26836
26857
|
});
|
|
26837
26858
|
if (p21.isCancel(confirmed) || !confirmed) {
|
|
26838
|
-
p21.cancel(`${removeIntegrationsMode ? "Integration" : "
|
|
26859
|
+
p21.cancel(`${removeIntegrationsMode ? "Integration" : "Preset"} removal cancelled.`);
|
|
26839
26860
|
process.exit(0);
|
|
26840
26861
|
}
|
|
26841
26862
|
}
|
|
@@ -26859,21 +26880,21 @@ async function runRemoveCommand(items, options) {
|
|
|
26859
26880
|
);
|
|
26860
26881
|
return;
|
|
26861
26882
|
}
|
|
26862
|
-
const result = await
|
|
26883
|
+
const result = await removePresets({
|
|
26863
26884
|
cwd,
|
|
26864
26885
|
config,
|
|
26865
26886
|
pm,
|
|
26866
|
-
|
|
26887
|
+
presetIds
|
|
26867
26888
|
});
|
|
26868
26889
|
writeConfigFile(cwd, result.config);
|
|
26869
26890
|
if (result.removed.length === 0) {
|
|
26870
|
-
p21.outro("No
|
|
26891
|
+
p21.outro("No presets were removed.");
|
|
26871
26892
|
return;
|
|
26872
26893
|
}
|
|
26873
26894
|
if (result.warnings.length > 0) {
|
|
26874
26895
|
p21.note(result.warnings.join("\n"), "Warnings");
|
|
26875
26896
|
}
|
|
26876
|
-
p21.outro(`Removed
|
|
26897
|
+
p21.outro(`Removed preset${result.removed.length === 1 ? "" : "s"}: ${result.removed.join(", ")}`);
|
|
26877
26898
|
}
|
|
26878
26899
|
|
|
26879
26900
|
// adapters/next/commands/remove-schema.ts
|
|
@@ -26942,8 +26963,8 @@ async function runRemoveSchemaCommand(schemaName, options) {
|
|
|
26942
26963
|
);
|
|
26943
26964
|
process.exit(1);
|
|
26944
26965
|
}
|
|
26945
|
-
if (owner.startsWith("
|
|
26946
|
-
console.error(` "${schemaName}" is owned by ${owner}. Remove the owning
|
|
26966
|
+
if (owner.startsWith("preset:")) {
|
|
26967
|
+
console.error(` "${schemaName}" is owned by ${owner}. Remove the owning preset instead.`);
|
|
26947
26968
|
process.exit(1);
|
|
26948
26969
|
}
|
|
26949
26970
|
const cwd = options.cwd ? path54.resolve(options.cwd) : process.cwd();
|
|
@@ -27625,8 +27646,8 @@ function copyNamespacedDirectory(srcDir, destDir, namespace) {
|
|
|
27625
27646
|
writeNamespacedFile(srcPath, destPath, namespace);
|
|
27626
27647
|
}
|
|
27627
27648
|
}
|
|
27628
|
-
function
|
|
27629
|
-
return config.
|
|
27649
|
+
function hasPreset(config, presetId) {
|
|
27650
|
+
return config.presets.installed.includes(presetId);
|
|
27630
27651
|
}
|
|
27631
27652
|
function hasIntegration(config, integrationId) {
|
|
27632
27653
|
return config.integrations.installed.includes(integrationId);
|
|
@@ -29203,7 +29224,7 @@ function getAllComponentNamesForConfig(config) {
|
|
|
29203
29224
|
const staticUi = getStaticUiComponents();
|
|
29204
29225
|
const staticCustom = getStaticCustomComponents();
|
|
29205
29226
|
const templateKeys = Object.entries(TEMPLATE_REGISTRY).filter(
|
|
29206
|
-
([, entry]) => (!entry.
|
|
29227
|
+
([, entry]) => (!entry.requiredPreset || hasPreset(config, entry.requiredPreset)) && (!entry.requiredIntegration || hasIntegration(config, entry.requiredIntegration))
|
|
29207
29228
|
).map(([name]) => name);
|
|
29208
29229
|
return [.../* @__PURE__ */ new Set([...staticUi, ...staticCustom, ...templateKeys, "tiptap"])].sort();
|
|
29209
29230
|
}
|
|
@@ -29292,8 +29313,8 @@ async function runUpdateCommand(components, options) {
|
|
|
29292
29313
|
if (updatedTemplateNames.has(name)) {
|
|
29293
29314
|
return false;
|
|
29294
29315
|
}
|
|
29295
|
-
if (entry.
|
|
29296
|
-
clack2.log.warning(`${name} requires the ${entry.
|
|
29316
|
+
if (entry.requiredPreset && !hasPreset(config, entry.requiredPreset)) {
|
|
29317
|
+
clack2.log.warning(`${name} requires the ${entry.requiredPreset} preset and was skipped.`);
|
|
29297
29318
|
skipped++;
|
|
29298
29319
|
return false;
|
|
29299
29320
|
}
|
|
@@ -29445,7 +29466,7 @@ async function runUpdateCommand(components, options) {
|
|
|
29445
29466
|
clack2.log.warning(`Unknown component: ${name}`);
|
|
29446
29467
|
skipped++;
|
|
29447
29468
|
}
|
|
29448
|
-
|
|
29469
|
+
syncInstalledPresetManifests(cwd, config);
|
|
29449
29470
|
syncInstalledIntegrationManifests(cwd, config);
|
|
29450
29471
|
const projectPackageJson = readProjectPackageJson2(cwd);
|
|
29451
29472
|
const missingPackageDependencies = Array.from(requiredPackageDependencies).filter(
|
|
@@ -29640,7 +29661,7 @@ async function runUpdateDepsCommand(options) {
|
|
|
29640
29661
|
clack3.log.info(`Package manager: ${pm}`);
|
|
29641
29662
|
const config = await resolveConfig(cwd);
|
|
29642
29663
|
const dependencyPlan = getDependencyPlan(
|
|
29643
|
-
|
|
29664
|
+
getInstalledPresets(config),
|
|
29644
29665
|
getInstalledIntegrations(config),
|
|
29645
29666
|
false
|
|
29646
29667
|
);
|
|
@@ -29699,7 +29720,7 @@ var nextCommandRuntime = {
|
|
|
29699
29720
|
runGenerate: runGenerateCommand,
|
|
29700
29721
|
runInit: runInitCommand,
|
|
29701
29722
|
runListIntegrations: runListIntegrationsCommand,
|
|
29702
|
-
|
|
29723
|
+
runListPresets: runListPresetsCommand,
|
|
29703
29724
|
runRemove: runRemoveCommand,
|
|
29704
29725
|
runRemoveSchema: runRemoveSchemaCommand,
|
|
29705
29726
|
runSeed: runSeedCommand,
|
|
@@ -29715,7 +29736,7 @@ var { version } = JSON.parse(
|
|
|
29715
29736
|
readFileSync(new URL("../package.json", import.meta.url), "utf-8")
|
|
29716
29737
|
);
|
|
29717
29738
|
var program = new Command2();
|
|
29718
|
-
program.name("betterstart").description("Scaffold a
|
|
29739
|
+
program.name("betterstart").description("Scaffold a preset and integration based Admin into any Next.js 16 application").version(version);
|
|
29719
29740
|
program.hook("preAction", (_command, actionCommand) => {
|
|
29720
29741
|
requireInitializedProject(actionCommand);
|
|
29721
29742
|
});
|
|
@@ -29724,7 +29745,7 @@ program.addCommand(createAddFieldCommand(nextCommandRuntime));
|
|
|
29724
29745
|
program.addCommand(createCreateCommand(nextCommandRuntime));
|
|
29725
29746
|
program.addCommand(createInitCommand(nextCommandRuntime));
|
|
29726
29747
|
program.addCommand(createListIntegrationsCommand(nextCommandRuntime));
|
|
29727
|
-
program.addCommand(
|
|
29748
|
+
program.addCommand(createListPresetsCommand(nextCommandRuntime));
|
|
29728
29749
|
program.addCommand(createGenerateCommand(nextCommandRuntime));
|
|
29729
29750
|
program.addCommand(createRemoveCommand(nextCommandRuntime));
|
|
29730
29751
|
program.addCommand(createRemoveSchemaCommand(nextCommandRuntime));
|