betterstart-cli 0.0.114 → 0.0.116

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/dist/cli.js CHANGED
@@ -18,6 +18,8 @@ import {
18
18
  LOCAL_PROTOCOL_PATTERN,
19
19
  LOCKFILE_MAP,
20
20
  MAIN_CSS_CANDIDATES,
21
+ PROXY_CONVENTION_FILE_NAMES,
22
+ PROXY_FILE_NAME,
21
23
  R2_ENV_KEYS,
22
24
  RAILWAY_BUCKET_ENV_KEYS,
23
25
  REDACTED,
@@ -83,7 +85,7 @@ import {
83
85
  trimDotSlash,
84
86
  usesIdentifier,
85
87
  validateAdminNamespace
86
- } from "./chunk-PSDUGFMD.js";
88
+ } from "./chunk-SG4U6EQY.js";
87
89
 
88
90
  // cli.ts
89
91
  import * as p66 from "@clack/prompts";
@@ -529,7 +531,7 @@ function unique(values) {
529
531
  return Array.from(new Set(values));
530
532
  }
531
533
  function arraysEqual(a, b) {
532
- return Boolean(a && a.length === b.length && a.every((value, index) => value === b[index]));
534
+ return Array.isArray(a) && a.length === b.length && a.every((value, index) => value === b[index]);
533
535
  }
534
536
  function isValidPort(port) {
535
537
  return Number.isInteger(port) && port > 0 && port <= 65535;
@@ -1123,25 +1125,41 @@ function flattenSlotLayout(slot) {
1123
1125
 
1124
1126
  // core-engine/schema/schema-reader/walk-slot-aware-field.ts
1125
1127
  function walkSlotAwareField(field, fieldPath, errors, options) {
1128
+ if (!isRecord(field)) {
1129
+ errors.push(`Field "${fieldPath}" must be an object.`);
1130
+ return;
1131
+ }
1126
1132
  options.checkField(field, fieldPath, errors);
1133
+ const childPath = (parentPath, child) => `${parentPath}.${isRecord(child) && isNonEmptyString(child.name) ? child.name : "unnamed"}`;
1127
1134
  const descend = (children, parentPath) => {
1135
+ if (!Array.isArray(children)) {
1136
+ errors.push(`Field "${parentPath}" has a "fields" value that must be an array.`);
1137
+ return;
1138
+ }
1128
1139
  for (const child of children) {
1129
- walkSlotAwareField(child, `${parentPath}.${child.name ?? "unnamed"}`, errors, options);
1140
+ walkSlotAwareField(child, childPath(parentPath, child), errors, options);
1130
1141
  }
1131
1142
  };
1132
- if (field.fields) {
1143
+ if (field.fields !== void 0) {
1133
1144
  descend(field.fields, fieldPath);
1134
1145
  }
1135
- if (field.tabs) {
1136
- for (const tab of field.tabs) {
1137
- const tabPath = `${fieldPath}.${tab.name ?? "unnamed"}`;
1138
- options.onTab?.(tab, tabPath, errors);
1139
- if (options.descendTabSlots && tab.slot !== void 0) {
1140
- descend(flattenSlotLayout(tab.slot), tabPath);
1141
- }
1142
- if (tab.fields) {
1143
- descend(tab.fields, tabPath);
1144
- }
1146
+ if (field.tabs === void 0) return;
1147
+ if (!Array.isArray(field.tabs)) {
1148
+ errors.push(`Field "${fieldPath}" has a "tabs" value that must be an array.`);
1149
+ return;
1150
+ }
1151
+ for (const tab of field.tabs) {
1152
+ const tabPath = childPath(fieldPath, tab);
1153
+ if (!isRecord(tab)) {
1154
+ errors.push(`Tab "${tabPath}" must be an object.`);
1155
+ continue;
1156
+ }
1157
+ options.onTab?.(tab, tabPath, errors);
1158
+ if (options.descendTabSlots && tab.slot !== void 0) {
1159
+ descend(flattenSlotLayout(tab.slot), tabPath);
1160
+ }
1161
+ if (tab.fields !== void 0) {
1162
+ descend(tab.fields, tabPath);
1145
1163
  }
1146
1164
  }
1147
1165
  }
@@ -1164,7 +1182,8 @@ function walkHeight(field, fieldPath, errors) {
1164
1182
  function collectInvalidHeightErrors(topLevelFields, rootPath, errors) {
1165
1183
  const prefix = rootPath ? `${rootPath}.` : "";
1166
1184
  for (const field of topLevelFields) {
1167
- walkHeight(field, `${prefix}${field.name ?? "unnamed"}`, errors);
1185
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1186
+ walkHeight(field, `${prefix}${name}`, errors);
1168
1187
  }
1169
1188
  }
1170
1189
 
@@ -1227,31 +1246,32 @@ function collectInvalidSchemaFieldTypeErrors(fields, errors) {
1227
1246
  }
1228
1247
 
1229
1248
  // core-engine/schema/schema-reader/collect-slot-area-errors.ts
1230
- function collectSlotAreaErrors(value, path112, errors) {
1249
+ function collectSlotAreaErrors(value, path113, errors) {
1231
1250
  if (!isRecord(value)) {
1232
- errors.push(`${path112} must be an object with a "fields" array.`);
1251
+ errors.push(`${path113} must be an object with a "fields" array.`);
1233
1252
  return;
1234
1253
  }
1235
1254
  const fields = value.fields;
1236
1255
  if (!Array.isArray(fields)) {
1237
- errors.push(`${path112}.fields must be an array.`);
1256
+ errors.push(`${path113}.fields must be an array.`);
1238
1257
  return;
1239
1258
  }
1240
1259
  for (const field of fields) {
1241
- walkSlot(field, `${path112}.fields.${field.name ?? "unnamed"}`, errors);
1260
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1261
+ walkSlot(field, `${path113}.fields.${name}`, errors);
1242
1262
  }
1243
1263
  }
1244
1264
 
1245
1265
  // core-engine/schema/schema-reader/collect-slot-layout-errors.ts
1246
- function collectSlotLayoutErrors(value, path112, errors) {
1266
+ function collectSlotLayoutErrors(value, path113, errors) {
1247
1267
  if (!isRecord(value)) {
1248
- errors.push(`${path112} must be an object with "main" and/or "sidebar" field groups.`);
1268
+ errors.push(`${path113} must be an object with "main" and/or "sidebar" field groups.`);
1249
1269
  return;
1250
1270
  }
1251
1271
  const validKeys = /* @__PURE__ */ new Set(["main", "sidebar"]);
1252
1272
  for (const key of Object.keys(value)) {
1253
1273
  if (!validKeys.has(key)) {
1254
- errors.push(`${path112} has unsupported key "${key}". Expected "main" or "sidebar".`);
1274
+ errors.push(`${path113} has unsupported key "${key}". Expected "main" or "sidebar".`);
1255
1275
  }
1256
1276
  }
1257
1277
  const areas = [
@@ -1262,10 +1282,10 @@ function collectSlotLayoutErrors(value, path112, errors) {
1262
1282
  for (const [name, area] of areas) {
1263
1283
  if (area === void 0) continue;
1264
1284
  hasArea = true;
1265
- collectSlotAreaErrors(area, `${path112}.${name}`, errors);
1285
+ collectSlotAreaErrors(area, `${path113}.${name}`, errors);
1266
1286
  }
1267
1287
  if (!hasArea) {
1268
- errors.push(`${path112} must define at least one of "main" or "sidebar".`);
1288
+ errors.push(`${path113} must define at least one of "main" or "sidebar".`);
1269
1289
  }
1270
1290
  }
1271
1291
 
@@ -1295,7 +1315,8 @@ function walkSlot(field, fieldPath, errors) {
1295
1315
  function collectInvalidSlotErrors(fields, rootPath, errors) {
1296
1316
  const prefix = rootPath ? `${rootPath}.` : "";
1297
1317
  for (const field of fields) {
1298
- walkSlot(field, `${prefix}${field.name ?? "unnamed"}`, errors);
1318
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1319
+ walkSlot(field, `${prefix}${name}`, errors);
1299
1320
  }
1300
1321
  }
1301
1322
 
@@ -2165,8 +2186,7 @@ function loadSchema(schemasDir, name) {
2165
2186
  const filePath = resolveSchemaFilePath(schemasDir, name);
2166
2187
  const content = fs10.readFileSync(filePath, "utf-8");
2167
2188
  const parsed = parseSchemaJson(content, filePath);
2168
- const obj = parsed;
2169
- switch (schemaKindFromType(name, obj.type)) {
2189
+ switch (schemaKindFromType(name, isRecord(parsed) ? parsed.type : void 0)) {
2170
2190
  case "form":
2171
2191
  return { type: "form", schema: parsed, filePath };
2172
2192
  case "single":
@@ -2285,7 +2305,7 @@ function detectPackageManager(cwd) {
2285
2305
  if (!fs14.existsSync(pkgPath)) return void 0;
2286
2306
  try {
2287
2307
  const pkg = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
2288
- if (typeof pkg.packageManager === "string") {
2308
+ if (isRecord(pkg) && typeof pkg.packageManager === "string") {
2289
2309
  const name = pkg.packageManager.split("@")[0];
2290
2310
  if (name === "pnpm" || name === "npm" || name === "yarn" || name === "bun") return name;
2291
2311
  }
@@ -3707,7 +3727,7 @@ function buildEditsForSourceFile(sourceFile, filePath, plan) {
3707
3727
  }
3708
3728
 
3709
3729
  // core-engine/snapshots/ast-substitution/collect-preview-changes.ts
3710
- function collectPreviewChanges(path112, beforeContent, afterContent) {
3730
+ function collectPreviewChanges(path113, beforeContent, afterContent) {
3711
3731
  const beforeLines = beforeContent.split("\n");
3712
3732
  const afterLines = afterContent.split("\n");
3713
3733
  const maxLength = Math.max(beforeLines.length, afterLines.length);
@@ -3719,7 +3739,7 @@ function collectPreviewChanges(path112, beforeContent, afterContent) {
3719
3739
  continue;
3720
3740
  }
3721
3741
  changes.push({
3722
- path: path112,
3742
+ path: path113,
3723
3743
  line: index + 1,
3724
3744
  before: before.trim(),
3725
3745
  after: after.trim()
@@ -5929,7 +5949,7 @@ function formatTsValue(value, indent = 0) {
5929
5949
  ${value.map((item) => `${childIndent}${formatTsValue(item, indent + 2)}`).join(",\n")}
5930
5950
  ${currentIndent}]`;
5931
5951
  }
5932
- if (value && typeof value === "object") {
5952
+ if (isRecord(value)) {
5933
5953
  return formatTsObject(value, indent);
5934
5954
  }
5935
5955
  return JSON.stringify(value);
@@ -9235,11 +9255,13 @@ function genBarrelContent(files, ctx) {
9235
9255
  `${ctx.Singular}UpdateInput`,
9236
9256
  `${ctx.Singular}UpdateResult`,
9237
9257
  `${ctx.Singular}DeleteResult`,
9238
- ctx.hasCreatableSelectFields ? `${ctx.Singular}SelectOption` : null,
9239
- ctx.hasCreatableSelectFields ? `${ctx.Singular}SelectOptionFieldName` : null,
9240
- ctx.hasCreatableSelectFields ? `Create${ctx.Singular}SelectOptionInput` : null,
9241
- ctx.hasCreatableSelectFields ? `Create${ctx.Singular}SelectOptionResult` : null
9242
- ].filter(Boolean);
9258
+ ...ctx.hasCreatableSelectFields ? [
9259
+ `${ctx.Singular}SelectOption`,
9260
+ `${ctx.Singular}SelectOptionFieldName`,
9261
+ `Create${ctx.Singular}SelectOptionInput`,
9262
+ `Create${ctx.Singular}SelectOptionResult`
9263
+ ] : []
9264
+ ];
9243
9265
  lines.push(`export type { ${typeNames.join(", ")} } from './types'`);
9244
9266
  lines.push("");
9245
9267
  for (const file of files) {
@@ -12350,9 +12372,9 @@ ${mappings}
12350
12372
  }
12351
12373
 
12352
12374
  // adapters/next/generators/actions/action-helpers/collect-read-select-fields.ts
12353
- function collectReadSelectFields(fields, path112 = []) {
12375
+ function collectReadSelectFields(fields, path113 = []) {
12354
12376
  const matches = fields.flatMap((field) => {
12355
- const currentPath = [...path112, field.name];
12377
+ const currentPath = [...path113, field.name];
12356
12378
  const matches2 = field.type === "select" ? [{ field, path: currentPath }] : [];
12357
12379
  if (field.fields) {
12358
12380
  matches2.push(...collectReadSelectFields(field.fields, currentPath));
@@ -17205,16 +17227,16 @@ function renderNestedFieldRenderer(request) {
17205
17227
  }
17206
17228
 
17207
17229
  // adapters/next/generators/form/field-jsx-nested/path-expression.ts
17208
- function pathExpression(path112) {
17209
- return `\`${path112.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(".")}\``;
17230
+ function pathExpression(path113) {
17231
+ return `\`${path113.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(".")}\``;
17210
17232
  }
17211
17233
 
17212
17234
  // adapters/next/generators/form/field-jsx-nested/path-name-prop.ts
17213
- function pathNameProp(path112) {
17214
- if (path112.every((part) => typeof part === "string")) {
17215
- return `"${path112.map((part) => part).join(".")}"`;
17235
+ function pathNameProp(path113) {
17236
+ if (path113.every((part) => typeof part === "string")) {
17237
+ return `"${path113.map((part) => part).join(".")}"`;
17216
17238
  }
17217
- return `{${pathExpression(path112)}}`;
17239
+ return `{${pathExpression(path113)}}`;
17218
17240
  }
17219
17241
 
17220
17242
  // adapters/next/templates/renderers/generators/form/field-jsx-nested/render-nested-object-list-field.ts
@@ -17272,17 +17294,17 @@ function renderNestedObjectListFieldRenderer(request) {
17272
17294
  function requiredLeafPaths(fields, prefix = []) {
17273
17295
  return fields.flatMap((field) => {
17274
17296
  if (field.hidden) return [];
17275
- const path112 = [...prefix, field.name];
17297
+ const path113 = [...prefix, field.name];
17276
17298
  if ((field.type === "group" || field.type === "section") && field.fields?.length) {
17277
- return requiredLeafPaths(field.fields, path112);
17299
+ return requiredLeafPaths(field.fields, path113);
17278
17300
  }
17279
- if (field.required) return [path112.join(".")];
17301
+ if (field.required) return [path113.join(".")];
17280
17302
  return [];
17281
17303
  });
17282
17304
  }
17283
17305
 
17284
17306
  // adapters/next/generators/form/field-jsx-nested/render-nested-object-list-field.ts
17285
- function renderNestedObjectListField(field, indent, label, path112, depth) {
17307
+ function renderNestedObjectListField(field, indent, label, path113, depth) {
17286
17308
  const singularLabel = singularize(label);
17287
17309
  const itemIndexVar = `${safeIdentifier(field.name, "nestedList")}Index${depth}`;
17288
17310
  const titlePath = findTitlePath(field.fields ?? []);
@@ -17292,7 +17314,7 @@ function renderNestedObjectListField(field, indent, label, path112, depth) {
17292
17314
  props: {
17293
17315
  indent,
17294
17316
  itemIndexVar,
17295
- pathString: path112.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join("."),
17317
+ pathString: path113.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join("."),
17296
17318
  titlePathSuffix,
17297
17319
  singularLabel
17298
17320
  }
@@ -17301,7 +17323,7 @@ function renderNestedObjectListField(field, indent, label, path112, depth) {
17301
17323
  (child) => renderNestedField(
17302
17324
  child,
17303
17325
  `${indent} `,
17304
- [...path112, { expression: itemIndexVar }, child.name],
17326
+ [...path113, { expression: itemIndexVar }, child.name],
17305
17327
  depth + 1
17306
17328
  )
17307
17329
  ).filter(Boolean).join("\n");
@@ -17319,7 +17341,7 @@ ${indent} validatePaths={${JSON.stringify(validatePaths)}}` : "";
17319
17341
  kind: "renderNestedObjectListFieldNestedObjectListFieldTemplate",
17320
17342
  props: {
17321
17343
  indent,
17322
- pathExpression: pathExpression(path112),
17344
+ pathExpression: pathExpression(path113),
17323
17345
  stringify: JSON.stringify(label),
17324
17346
  stringifySerializedValue: JSON.stringify(singularLabel),
17325
17347
  defaultItem,
@@ -17358,10 +17380,10 @@ ${indent}/>`;
17358
17380
  }
17359
17381
 
17360
17382
  // adapters/next/generators/form/field-jsx-nested/render-text-input-field.ts
17361
- function renderTextInputField(field, indent, label, nestedHint, path112) {
17383
+ function renderTextInputField(field, indent, label, nestedHint, path113) {
17362
17384
  return renderTextInputFieldFormFieldTemplate({
17363
17385
  indent,
17364
- pathNameProp: pathNameProp(path112),
17386
+ pathNameProp: pathNameProp(path113),
17365
17387
  formItemProps: formItemProps(field),
17366
17388
  labelWithDescription: labelWithDescription(
17367
17389
  formLabel(field, label),
@@ -17373,11 +17395,11 @@ function renderTextInputField(field, indent, label, nestedHint, path112) {
17373
17395
  }
17374
17396
 
17375
17397
  // adapters/next/generators/form/field-jsx-nested/render-nested-field.ts
17376
- function renderNestedField(field, indent, path112, depth) {
17398
+ function renderNestedField(field, indent, path113, depth) {
17377
17399
  const nestedLabel = field.label || field.name;
17378
17400
  const nestedHint = field.hint ? `<FormDescription>${field.hint}</FormDescription>` : "";
17379
17401
  if ((field.type === "group" || field.type === "section") && field.fields?.length) {
17380
- const groupFields = field.fields.map((child) => renderNestedField(child, `${indent} `, [...path112, child.name], depth)).filter(Boolean).join("\n");
17402
+ const groupFields = field.fields.map((child) => renderNestedField(child, `${indent} `, [...path113, child.name], depth)).filter(Boolean).join("\n");
17381
17403
  if (!groupFields) return "";
17382
17404
  const heading = nestedLabel && nestedLabel !== field.name ? `${indent}<h3 className="text-base font-medium">${nestedLabel}</h3>
17383
17405
  ` : "";
@@ -17393,7 +17415,7 @@ function renderNestedField(field, indent, path112, depth) {
17393
17415
  });
17394
17416
  }
17395
17417
  if (field.type === "list" && field.fields?.length) {
17396
- return renderNestedObjectListField(field, indent, nestedLabel, path112, depth);
17418
+ return renderNestedObjectListField(field, indent, nestedLabel, path113, depth);
17397
17419
  }
17398
17420
  if (field.type === "list") {
17399
17421
  const hideLabelProp = field.label ? "" : `
@@ -17404,7 +17426,7 @@ ${indent} description={${JSON.stringify(field.hint)}}` : "";
17404
17426
  kind: "renderNestedFieldDynamicListFieldTemplate",
17405
17427
  props: {
17406
17428
  indent,
17407
- pathExpression: pathExpression(path112),
17429
+ pathExpression: pathExpression(path113),
17408
17430
  nestedLabel,
17409
17431
  hideLabelProp,
17410
17432
  descriptionProp,
@@ -17418,7 +17440,7 @@ ${indent} maxItems={${field.maxItems}}` : ""
17418
17440
  kind: "renderNestedFieldFormFieldTemplate",
17419
17441
  props: {
17420
17442
  indent,
17421
- pathNameProp: pathNameProp(path112),
17443
+ pathNameProp: pathNameProp(path113),
17422
17444
  formItemProps: formItemProps(field, "flex flex-row items-start space-x-3 space-y-0"),
17423
17445
  labelWithDescription: labelWithDescription(
17424
17446
  `<FormLabel>${nestedLabel}</FormLabel>`,
@@ -17434,7 +17456,7 @@ ${indent} maxItems={${field.maxItems}}` : ""
17434
17456
  kind: "renderNestedFieldFormFieldDetailsTemplate",
17435
17457
  props: {
17436
17458
  indent,
17437
- pathNameProp: pathNameProp(path112),
17459
+ pathNameProp: pathNameProp(path113),
17438
17460
  formItemProps: formItemProps(field),
17439
17461
  labelWithDescription: labelWithDescription(
17440
17462
  formLabel(field, nestedLabel),
@@ -17450,7 +17472,7 @@ ${indent} maxItems={${field.maxItems}}` : ""
17450
17472
  kind: "renderNestedFieldFormFieldDetailsBranchTemplate",
17451
17473
  props: {
17452
17474
  indent,
17453
- pathNameProp: pathNameProp(path112),
17475
+ pathNameProp: pathNameProp(path113),
17454
17476
  formItemProps: formItemProps(field),
17455
17477
  labelWithDescription: labelWithDescription(
17456
17478
  formLabel(field, nestedLabel),
@@ -17468,7 +17490,7 @@ ${indent} maxItems={${field.maxItems}}` : ""
17468
17490
  kind: "renderNestedFieldFormFieldDetailsBranchBodyTemplate",
17469
17491
  props: {
17470
17492
  indent,
17471
- pathNameProp: pathNameProp(path112),
17493
+ pathNameProp: pathNameProp(path113),
17472
17494
  formItemProps: formItemProps(field),
17473
17495
  labelWithDescription: labelWithDescription(
17474
17496
  formLabel(field, nestedLabel),
@@ -17481,13 +17503,13 @@ ${indent} maxItems={${field.maxItems}}` : ""
17481
17503
  }
17482
17504
  });
17483
17505
  }
17484
- return renderTextInputField(field, indent, nestedLabel, nestedHint, path112);
17506
+ return renderTextInputField(field, indent, nestedLabel, nestedHint, path113);
17485
17507
  }
17486
17508
 
17487
17509
  // adapters/next/generators/form/field-jsx-nested/validation-trigger-expression.ts
17488
17510
  function validationTriggerExpression(basePath, requiredPaths) {
17489
17511
  if (requiredPaths.length === 0) return `\`${basePath}.\${expandedIndex}\` as never`;
17490
- const paths = requiredPaths.map((path112) => `\`${basePath}.\${expandedIndex}.${path112}\``).join(", ");
17512
+ const paths = requiredPaths.map((path113) => `\`${basePath}.\${expandedIndex}.${path113}\``).join(", ");
17491
17513
  return `[${paths}] as never`;
17492
17514
  }
17493
17515
 
@@ -25963,36 +25985,26 @@ function buildLeafField(input) {
25963
25985
  if (errors.length > 0) {
25964
25986
  throw new Error(errors.join("\n"));
25965
25987
  }
25966
- const field = {
25988
+ if (input.kind === "form") {
25989
+ return {
25990
+ name: input.name,
25991
+ type: input.type,
25992
+ label: input.label,
25993
+ ...input.required ? { required: true } : {},
25994
+ ...input.multiple && input.type === "file" ? { multiple: true } : {},
25995
+ ...input.options?.length ? { options: input.options } : {}
25996
+ };
25997
+ }
25998
+ return {
25967
25999
  name: input.name,
25968
26000
  type: input.type,
25969
- label: input.label
26001
+ label: input.label,
26002
+ ...input.required ? { required: true } : {},
26003
+ ...input.multiple && ["select", "relationship"].includes(input.type) ? { multiple: true } : {},
26004
+ ...input.creatable && input.type === "select" ? { creatable: true } : {},
26005
+ ...input.options?.length ? { options: input.options } : {},
26006
+ ...input.relationship && input.type === "relationship" ? { relationship: input.relationship } : {}
25970
26007
  };
25971
- if (input.required) {
25972
- field.required = true;
25973
- }
25974
- if (input.kind === "form") {
25975
- if (input.multiple && input.type === "file") {
25976
- field.multiple = true;
25977
- }
25978
- if (input.options && input.options.length > 0) {
25979
- field.options = input.options;
25980
- }
25981
- return field;
25982
- }
25983
- if (input.multiple && ["select", "relationship"].includes(input.type)) {
25984
- field.multiple = true;
25985
- }
25986
- if (input.creatable && input.type === "select") {
25987
- field.creatable = true;
25988
- }
25989
- if (input.options && input.options.length > 0) {
25990
- field.options = input.options;
25991
- }
25992
- if (input.relationship && input.type === "relationship") {
25993
- field.relationship = input.relationship;
25994
- }
25995
- return field;
25996
26008
  }
25997
26009
 
25998
26010
  // adapters/next/commands/schema-prompts/apply-advanced-options.ts
@@ -26110,14 +26122,12 @@ function applyDerivedFieldDefaults(field, type, options) {
26110
26122
  if (!options.derivePlaceholder) {
26111
26123
  return;
26112
26124
  }
26113
- const record = field;
26114
- if (typeof record.placeholder === "string" && record.placeholder.trim()) {
26125
+ if (typeof field.placeholder === "string" && field.placeholder.trim()) {
26115
26126
  return;
26116
26127
  }
26117
- const label = typeof record.label === "string" ? record.label : "";
26118
- const placeholder = derivePlaceholderFromLabel(type, label);
26128
+ const placeholder = derivePlaceholderFromLabel(type, field.label ?? "");
26119
26129
  if (placeholder) {
26120
- record.placeholder = placeholder;
26130
+ field.placeholder = placeholder;
26121
26131
  }
26122
26132
  }
26123
26133
 
@@ -29263,8 +29273,8 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
29263
29273
  // adapters/next/commands/init/run-init-command-internal.ts
29264
29274
  import * as p61 from "@clack/prompts";
29265
29275
  import { execFileSync as execFileSync3 } from "child_process";
29266
- import fs78 from "fs";
29267
- import path91 from "path";
29276
+ import fs79 from "fs";
29277
+ import path92 from "path";
29268
29278
 
29269
29279
  // adapters/next/config/detect/detect-project.ts
29270
29280
  import fs52 from "fs";
@@ -29828,17 +29838,19 @@ function guardPackageJson(cwd, restores) {
29828
29838
  } catch {
29829
29839
  return { localSpecDeps: [], removedCliDep: false };
29830
29840
  }
29841
+ if (!isRecord(parsed)) {
29842
+ return { localSpecDeps: [], removedCliDep: false };
29843
+ }
29831
29844
  const localSpecDeps = [];
29832
29845
  let removedCliDep = false;
29833
29846
  for (const section of ["dependencies", "devDependencies"]) {
29834
29847
  const deps = parsed[section];
29835
- if (!deps || typeof deps !== "object") continue;
29836
- const record = deps;
29837
- if ("betterstart-cli" in record) {
29838
- Reflect.deleteProperty(record, "betterstart-cli");
29848
+ if (!isRecord(deps)) continue;
29849
+ if ("betterstart-cli" in deps) {
29850
+ Reflect.deleteProperty(deps, "betterstart-cli");
29839
29851
  removedCliDep = true;
29840
29852
  }
29841
- for (const [name, spec] of Object.entries(record)) {
29853
+ for (const [name, spec] of Object.entries(deps)) {
29842
29854
  if (typeof spec === "string" && LOCAL_PROTOCOL_PATTERN.test(spec)) {
29843
29855
  localSpecDeps.push(name);
29844
29856
  }
@@ -30005,13 +30017,12 @@ function parseRailwayJson(output) {
30005
30017
 
30006
30018
  // adapters/next/init/railway/resources/parse-service.ts
30007
30019
  function parseService(value) {
30008
- if (!value || typeof value !== "object") return void 0;
30009
- const service = value;
30010
- if (!isNonEmptyString(service.id) || !isNonEmptyString(service.name)) return void 0;
30011
- const replicas = service.replicas && typeof service.replicas === "object" ? service.replicas : void 0;
30020
+ if (!isRecord(value)) return void 0;
30021
+ if (!isNonEmptyString(value.id) || !isNonEmptyString(value.name)) return void 0;
30022
+ const replicas = isRecord(value.replicas) ? value.replicas : void 0;
30012
30023
  return {
30013
- id: service.id,
30014
- name: service.name,
30024
+ id: value.id,
30025
+ name: value.name,
30015
30026
  replicaCount: typeof replicas?.configured === "number" ? replicas.configured : void 0
30016
30027
  };
30017
30028
  }
@@ -30037,8 +30048,8 @@ ${result.stderr}`) ?? "Could not list Railway services."
30037
30048
  if (!Array.isArray(payload)) {
30038
30049
  throw new Error("Railway returned an invalid service list response.");
30039
30050
  }
30040
- const services = payload.map(parseService);
30041
- if (services.some((service) => !service)) {
30051
+ const services = payload.map(parseService).filter((service) => service !== void 0);
30052
+ if (services.length !== payload.length) {
30042
30053
  throw new Error("Railway returned an invalid service list response.");
30043
30054
  }
30044
30055
  return services;
@@ -30074,7 +30085,7 @@ function deploymentLine(line) {
30074
30085
  let message = line;
30075
30086
  try {
30076
30087
  const parsed = JSON.parse(line);
30077
- const jsonMessage = parsed.message ?? parsed.status;
30088
+ const jsonMessage = isRecord(parsed) ? parsed.message ?? parsed.status : void 0;
30078
30089
  if (typeof jsonMessage === "string") message = jsonMessage;
30079
30090
  } catch {
30080
30091
  }
@@ -30092,26 +30103,21 @@ function parseDomainUrl(value) {
30092
30103
  return void 0;
30093
30104
  }
30094
30105
  }
30095
- if (!value || typeof value !== "object") return void 0;
30096
- const record = value;
30097
- return parseDomainUrl(record.domain);
30106
+ return isRecord(value) ? parseDomainUrl(value.domain) : void 0;
30098
30107
  }
30099
30108
 
30100
30109
  // adapters/next/init/railway/deploy/first-domain-url.ts
30101
30110
  function firstDomainUrl(payload) {
30102
30111
  const direct = parseDomainUrl(payload);
30103
30112
  if (direct) return direct;
30104
- if (!payload || typeof payload !== "object") return void 0;
30105
- const domains = payload.domains;
30106
- return Array.isArray(domains) ? domains.map(parseDomainUrl).find((domain) => Boolean(domain)) : void 0;
30113
+ if (!isRecord(payload) || !Array.isArray(payload.domains)) return void 0;
30114
+ return payload.domains.map(parseDomainUrl).find((domain) => Boolean(domain));
30107
30115
  }
30108
30116
 
30109
30117
  // adapters/next/init/railway/deploy/parse-domain-list.ts
30110
30118
  function parseDomainList(payload) {
30111
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) return void 0;
30112
- const domains = payload.domains;
30113
- if (!Array.isArray(domains)) return void 0;
30114
- const parsed = domains.map(parseDomainUrl);
30119
+ if (!isRecord(payload) || !Array.isArray(payload.domains)) return void 0;
30120
+ const parsed = payload.domains.map(parseDomainUrl);
30115
30121
  return parsed.every((domain) => Boolean(domain)) ? parsed : void 0;
30116
30122
  }
30117
30123
 
@@ -30196,14 +30202,17 @@ ${result.stderr}`) ?? `Could not read Railway variables for ${service}.`
30196
30202
  );
30197
30203
  }
30198
30204
  const payload = parseRailwayJson(result.stdout);
30199
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
30205
+ if (!isRecord(payload)) {
30200
30206
  throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30201
30207
  }
30202
- const entries = Object.entries(payload);
30203
- if (entries.some(([, value]) => typeof value !== "string")) {
30204
- throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30208
+ const variables = {};
30209
+ for (const [name, value] of Object.entries(payload)) {
30210
+ if (typeof value !== "string") {
30211
+ throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30212
+ }
30213
+ variables[name] = value;
30205
30214
  }
30206
- return Object.fromEntries(entries);
30215
+ return variables;
30207
30216
  }
30208
30217
 
30209
30218
  // adapters/next/init/railway/deploy/collect-railway-deploy-env-vars.ts
@@ -30410,32 +30419,18 @@ ${deploy.stderr}`) ?? deploy.errorMessage
30410
30419
 
30411
30420
  // adapters/next/init/railway/resources/parse-bucket-credentials.ts
30412
30421
  function parseBucketCredentials(value) {
30413
- if (!value || typeof value !== "object") return void 0;
30414
- const credentials = value;
30415
- const keys = [
30416
- "endpoint",
30417
- "accessKeyId",
30418
- "secretAccessKey",
30419
- "bucketName",
30420
- "region",
30421
- "urlStyle"
30422
- ];
30423
- if (!keys.every((key) => isNonEmptyString(credentials[key]))) return void 0;
30424
- return {
30425
- endpoint: credentials.endpoint,
30426
- accessKeyId: credentials.accessKeyId,
30427
- secretAccessKey: credentials.secretAccessKey,
30428
- bucketName: credentials.bucketName,
30429
- region: credentials.region,
30430
- urlStyle: credentials.urlStyle
30431
- };
30422
+ if (!isRecord(value)) return void 0;
30423
+ const { endpoint, accessKeyId, secretAccessKey, bucketName, region, urlStyle } = value;
30424
+ if (!isNonEmptyString(endpoint) || !isNonEmptyString(accessKeyId) || !isNonEmptyString(secretAccessKey) || !isNonEmptyString(bucketName) || !isNonEmptyString(region) || !isNonEmptyString(urlStyle)) {
30425
+ return void 0;
30426
+ }
30427
+ return { endpoint, accessKeyId, secretAccessKey, bucketName, region, urlStyle };
30432
30428
  }
30433
30429
 
30434
30430
  // adapters/next/init/railway/resources/parse-bucket.ts
30435
30431
  function parseBucket(value) {
30436
- if (!value || typeof value !== "object") return void 0;
30437
- const bucket = value;
30438
- return isNonEmptyString(bucket.id) && isNonEmptyString(bucket.name) ? { id: bucket.id, name: bucket.name } : void 0;
30432
+ if (!isRecord(value)) return void 0;
30433
+ return isNonEmptyString(value.id) && isNonEmptyString(value.name) ? { id: value.id, name: value.name } : void 0;
30439
30434
  }
30440
30435
 
30441
30436
  // adapters/next/init/railway/resources/provision-railway-bucket-resource.ts
@@ -30571,10 +30566,9 @@ import pc5 from "picocolors";
30571
30566
 
30572
30567
  // adapters/next/init/railway/auth/is-railway-account.ts
30573
30568
  function isRailwayAccount(value) {
30574
- if (!value || typeof value !== "object") return false;
30575
- const account = value;
30576
- return typeof account.email === "string" && Array.isArray(account.workspaces) && account.workspaces.every(
30577
- (workspace) => workspace !== null && typeof workspace === "object" && typeof workspace.id === "string" && typeof workspace.name === "string"
30569
+ if (!isRecord(value)) return false;
30570
+ return typeof value.email === "string" && Array.isArray(value.workspaces) && value.workspaces.every(
30571
+ (workspace) => isRecord(workspace) && typeof workspace.id === "string" && typeof workspace.name === "string"
30578
30572
  );
30579
30573
  }
30580
30574
 
@@ -30605,9 +30599,7 @@ async function checkRailwayProjectToken(runner, cwd, env) {
30605
30599
  return { authed: false, reason: result.timedOut ? "timeout" : "invalid-token" };
30606
30600
  }
30607
30601
  const project2 = parseRailwayJson(result.stdout);
30608
- if (!project2 || typeof project2 !== "object") return { authed: false, reason: "failed" };
30609
- const record = project2;
30610
- return typeof record.id === "string" && typeof record.name === "string" ? { authed: true } : { authed: false, reason: "failed" };
30602
+ return isRecord(project2) && typeof project2.id === "string" && typeof project2.name === "string" ? { authed: true } : { authed: false, reason: "failed" };
30611
30603
  }
30612
30604
 
30613
30605
  // adapters/next/init/railway/auth/ensure-railway-auth.ts
@@ -30684,18 +30676,14 @@ function isRailwayProjectNameConflict(detail) {
30684
30676
 
30685
30677
  // adapters/next/init/railway/project/parse-project-summary.ts
30686
30678
  function parseProjectSummary(value) {
30687
- if (!value || typeof value !== "object") return void 0;
30688
- const project2 = value;
30689
- if (!isNonEmptyString(project2.id) || !isNonEmptyString(project2.name)) return void 0;
30690
- const workspaceValue = project2.workspace;
30679
+ if (!isRecord(value)) return void 0;
30680
+ if (!isNonEmptyString(value.id) || !isNonEmptyString(value.name)) return void 0;
30681
+ const candidate = value.workspace;
30691
30682
  let workspace;
30692
- if (workspaceValue && typeof workspaceValue === "object") {
30693
- const candidate = workspaceValue;
30694
- if (isNonEmptyString(candidate.id) && isNonEmptyString(candidate.name)) {
30695
- workspace = { id: candidate.id, name: candidate.name };
30696
- }
30683
+ if (isRecord(candidate) && isNonEmptyString(candidate.id) && isNonEmptyString(candidate.name)) {
30684
+ workspace = { id: candidate.id, name: candidate.name };
30697
30685
  }
30698
- return { id: project2.id, name: project2.name, workspace };
30686
+ return { id: value.id, name: value.name, workspace };
30699
30687
  }
30700
30688
 
30701
30689
  // adapters/next/init/railway/project/railway-project-name-is-taken.ts
@@ -30733,9 +30721,7 @@ ${result.stderr}`);
30733
30721
 
30734
30722
  // adapters/next/init/railway/project/is-deleted-railway-project.ts
30735
30723
  function isDeletedRailwayProject(value) {
30736
- if (!value || typeof value !== "object") return false;
30737
- const deletedAt = value.deletedAt;
30738
- return isNonEmptyString(deletedAt);
30724
+ return isRecord(value) && isNonEmptyString(value.deletedAt);
30739
30725
  }
30740
30726
 
30741
30727
  // adapters/next/init/railway/project/list-railway-projects.ts
@@ -30755,8 +30741,9 @@ ${result.stderr}`) ?? "Could not list Railway projects."
30755
30741
  if (!Array.isArray(payload)) {
30756
30742
  throw new Error("Railway returned an invalid project list response.");
30757
30743
  }
30758
- const projects = payload.filter((project2) => !isDeletedRailwayProject(project2)).map(parseProjectSummary);
30759
- if (projects.some((project2) => !project2)) {
30744
+ const live = payload.filter((project2) => !isDeletedRailwayProject(project2));
30745
+ const projects = live.map(parseProjectSummary).filter((project2) => project2 !== void 0);
30746
+ if (projects.length !== live.length) {
30760
30747
  throw new Error("Railway returned an invalid project list response.");
30761
30748
  }
30762
30749
  return projects;
@@ -33128,16 +33115,36 @@ function scaffoldOxfmt(cwd, linter, adminDir) {
33128
33115
  return { installed: true, skippedReason: null };
33129
33116
  }
33130
33117
 
33118
+ // adapters/next/init/scaffolders/proxy.ts
33119
+ import fs65 from "fs";
33120
+ import path78 from "path";
33121
+ function scaffoldProxy({ cwd, config }) {
33122
+ const conventionDir = config.srcDir ? "src" : "";
33123
+ for (const fileName of PROXY_CONVENTION_FILE_NAMES) {
33124
+ const relPath2 = path78.join(conventionDir, fileName);
33125
+ if (fs65.existsSync(path78.resolve(cwd, relPath2))) {
33126
+ return { status: "existing", path: relPath2 };
33127
+ }
33128
+ }
33129
+ const relPath = path78.join(conventionDir, PROXY_FILE_NAME);
33130
+ const content = applyAdminNamespaceToContent(
33131
+ readTemplate(PROXY_FILE_NAME),
33132
+ config.frameworkConfig.next.namespace
33133
+ );
33134
+ safeWriteFile(path78.resolve(cwd, relPath), content);
33135
+ return { status: "created", path: relPath };
33136
+ }
33137
+
33131
33138
  // adapters/next/init/scaffolders/tailwind/scaffold-tailwind.ts
33132
- import fs66 from "fs";
33139
+ import fs67 from "fs";
33133
33140
 
33134
33141
  // adapters/next/main-css.ts
33135
- import fs65 from "fs";
33136
- import path78 from "path";
33142
+ import fs66 from "fs";
33143
+ import path79 from "path";
33137
33144
  function findMainCss(cwd) {
33138
33145
  for (const candidate of MAIN_CSS_CANDIDATES) {
33139
- const filePath = path78.join(cwd, candidate);
33140
- if (fs65.existsSync(filePath)) return filePath;
33146
+ const filePath = path79.join(cwd, candidate);
33147
+ if (fs66.existsSync(filePath)) return filePath;
33141
33148
  }
33142
33149
  return void 0;
33143
33150
  }
@@ -33221,7 +33228,7 @@ function scaffoldTailwind(cwd, hasSrcDir, namespace = "admin") {
33221
33228
  if (!cssFile) {
33222
33229
  return { file: null, appended: false };
33223
33230
  }
33224
- let content = fs66.readFileSync(cssFile, "utf-8");
33231
+ let content = fs67.readFileSync(cssFile, "utf-8");
33225
33232
  let changed = false;
33226
33233
  const sourceLines = getSourceLines(namespace, hasSrcDir);
33227
33234
  const missingLines = sourceLines.filter((sl) => !content.includes(sl));
@@ -33274,14 +33281,14 @@ ${renderAdminShadowInputUtility()}
33274
33281
  changed = true;
33275
33282
  }
33276
33283
  if (changed) {
33277
- fs66.writeFileSync(cssFile, content, "utf-8");
33284
+ fs67.writeFileSync(cssFile, content, "utf-8");
33278
33285
  }
33279
33286
  return { file: cssFile, appended: changed };
33280
33287
  }
33281
33288
 
33282
33289
  // adapters/next/init/scaffolders/tsconfig/scaffold-tsconfig.ts
33283
- import fs67 from "fs";
33284
- import path79 from "path";
33290
+ import fs68 from "fs";
33291
+ import path80 from "path";
33285
33292
 
33286
33293
  // adapters/next/init/scaffolders/tsconfig/create-admin-path-aliases.ts
33287
33294
  function createAdminPathAliases(config) {
@@ -33305,14 +33312,14 @@ function createAdminPathAliases(config) {
33305
33312
 
33306
33313
  // adapters/next/init/scaffolders/tsconfig/scaffold-tsconfig.ts
33307
33314
  function scaffoldTsconfig(cwd, config) {
33308
- const tsconfigPath = path79.join(cwd, "tsconfig.json");
33315
+ const tsconfigPath = path80.join(cwd, "tsconfig.json");
33309
33316
  const added = [];
33310
33317
  const skipped = [];
33311
- if (!fs67.existsSync(tsconfigPath)) {
33318
+ if (!fs68.existsSync(tsconfigPath)) {
33312
33319
  skipped.push("tsconfig.json not found");
33313
33320
  return { added, skipped };
33314
33321
  }
33315
- const raw = fs67.readFileSync(tsconfigPath, "utf-8");
33322
+ const raw = fs68.readFileSync(tsconfigPath, "utf-8");
33316
33323
  const stripped = toStrictJson(raw);
33317
33324
  let tsconfig;
33318
33325
  try {
@@ -33321,8 +33328,12 @@ function scaffoldTsconfig(cwd, config) {
33321
33328
  skipped.push("Failed to parse tsconfig.json");
33322
33329
  return { added, skipped };
33323
33330
  }
33324
- const compilerOptions = tsconfig.compilerOptions ?? {};
33325
- const paths = compilerOptions.paths ?? {};
33331
+ if (!isRecord(tsconfig)) {
33332
+ skipped.push("Failed to parse tsconfig.json");
33333
+ return { added, skipped };
33334
+ }
33335
+ const compilerOptions = isRecord(tsconfig.compilerOptions) ? tsconfig.compilerOptions : {};
33336
+ const paths = isRecord(compilerOptions.paths) ? compilerOptions.paths : {};
33326
33337
  if (compilerOptions.resolveJsonModule === true) {
33327
33338
  skipped.push("compilerOptions.resolveJsonModule");
33328
33339
  } else {
@@ -33351,7 +33362,7 @@ function scaffoldTsconfig(cwd, config) {
33351
33362
  }
33352
33363
  compilerOptions.paths = paths;
33353
33364
  tsconfig.compilerOptions = compilerOptions;
33354
- fs67.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
33365
+ fs68.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
33355
33366
  `, "utf-8");
33356
33367
  return { added, skipped };
33357
33368
  }
@@ -33596,25 +33607,25 @@ async function ensureVercelAuth(runner, cwd, options) {
33596
33607
  }
33597
33608
 
33598
33609
  // adapters/next/init/vercel/env-guard.ts
33599
- import fs68 from "fs";
33600
- import path80 from "path";
33610
+ import fs69 from "fs";
33611
+ import path81 from "path";
33601
33612
  function guardEnvLocal(cwd) {
33602
- const envPath = path80.join(cwd, ".env.local");
33613
+ const envPath = path81.join(cwd, ".env.local");
33603
33614
  let original;
33604
33615
  try {
33605
- original = fs68.readFileSync(envPath, "utf-8");
33616
+ original = fs69.readFileSync(envPath, "utf-8");
33606
33617
  } catch {
33607
33618
  original = void 0;
33608
33619
  }
33609
33620
  return {
33610
33621
  restore() {
33611
33622
  try {
33612
- const current = fs68.existsSync(envPath) ? fs68.readFileSync(envPath, "utf-8") : void 0;
33623
+ const current = fs69.existsSync(envPath) ? fs69.readFileSync(envPath, "utf-8") : void 0;
33613
33624
  if (current === original) return;
33614
33625
  if (original === void 0) {
33615
- fs68.rmSync(envPath, { force: true });
33626
+ fs69.rmSync(envPath, { force: true });
33616
33627
  } else {
33617
- fs68.writeFileSync(envPath, original);
33628
+ fs69.writeFileSync(envPath, original);
33618
33629
  }
33619
33630
  } catch {
33620
33631
  }
@@ -33674,17 +33685,19 @@ function blobFailureMessage(reason) {
33674
33685
  import pc9 from "picocolors";
33675
33686
 
33676
33687
  // adapters/next/init/vercel/project/create-and-link-project.ts
33677
- import fs70 from "fs";
33678
- import path82 from "path";
33688
+ import fs71 from "fs";
33689
+ import path83 from "path";
33679
33690
 
33680
33691
  // adapters/next/init/vercel/project/read-linked-project-json.ts
33681
- import fs69 from "fs";
33682
- import path81 from "path";
33692
+ import fs70 from "fs";
33693
+ import path82 from "path";
33683
33694
  function readLinkedProjectJson(cwd) {
33684
33695
  try {
33685
- const projectJsonPath = path81.join(cwd, ".vercel", "project.json");
33686
- if (!fs69.existsSync(projectJsonPath)) return void 0;
33687
- return JSON.parse(fs69.readFileSync(projectJsonPath, "utf-8"));
33696
+ const projectJsonPath = path82.join(cwd, ".vercel", "project.json");
33697
+ if (!fs70.existsSync(projectJsonPath)) return void 0;
33698
+ const parsed = JSON.parse(fs70.readFileSync(projectJsonPath, "utf-8"));
33699
+ if (!isRecord(parsed)) return void 0;
33700
+ return typeof parsed.projectId === "string" ? { projectId: parsed.projectId } : {};
33688
33701
  } catch {
33689
33702
  return void 0;
33690
33703
  }
@@ -33755,7 +33768,7 @@ ${add.stderr}`)) continue;
33755
33768
  break;
33756
33769
  }
33757
33770
  try {
33758
- fs70.rmSync(path82.join(cwd, ".vercel", "project.json"), { force: true });
33771
+ fs71.rmSync(path83.join(cwd, ".vercel", "project.json"), { force: true });
33759
33772
  } catch {
33760
33773
  }
33761
33774
  let link = await runVercel(
@@ -33872,12 +33885,12 @@ ${result.stderr}`
33872
33885
  }
33873
33886
 
33874
33887
  // adapters/next/init/vercel/env-pull.ts
33875
- import fs71 from "fs";
33888
+ import fs72 from "fs";
33876
33889
  import os from "os";
33877
- import path83 from "path";
33890
+ import path84 from "path";
33878
33891
  async function pullVercelEnvValue(runner, cwd, read, env, environment = "development") {
33879
- const tmpDir = fs71.mkdtempSync(path83.join(os.tmpdir(), "betterstart-vercel-"));
33880
- const tmpEnv = path83.join(tmpDir, ".env.pull");
33892
+ const tmpDir = fs72.mkdtempSync(path84.join(os.tmpdir(), "betterstart-vercel-"));
33893
+ const tmpEnv = path84.join(tmpDir, ".env.pull");
33881
33894
  try {
33882
33895
  const pull = await runVercel(
33883
33896
  runner,
@@ -33888,7 +33901,7 @@ async function pullVercelEnvValue(runner, cwd, read, env, environment = "develop
33888
33901
  return read(tmpEnv);
33889
33902
  } finally {
33890
33903
  try {
33891
- fs71.rmSync(tmpDir, { recursive: true, force: true });
33904
+ fs72.rmSync(tmpDir, { recursive: true, force: true });
33892
33905
  } catch {
33893
33906
  }
33894
33907
  }
@@ -34103,14 +34116,14 @@ ${deploy.stderr}`, DETAIL_MAX_LINES)
34103
34116
  }
34104
34117
 
34105
34118
  // adapters/next/init/vercel/deploy/ensure-vercel-json-framework.ts
34106
- import fs72 from "fs";
34107
- import path84 from "path";
34119
+ import fs73 from "fs";
34120
+ import path85 from "path";
34108
34121
  function ensureVercelJsonFramework(cwd) {
34109
- const vercelJsonPath = path84.join(cwd, "vercel.json");
34110
- if (fs72.existsSync(vercelJsonPath)) {
34122
+ const vercelJsonPath = path85.join(cwd, "vercel.json");
34123
+ if (fs73.existsSync(vercelJsonPath)) {
34111
34124
  return "exists";
34112
34125
  }
34113
- fs72.writeFileSync(
34126
+ fs73.writeFileSync(
34114
34127
  vercelJsonPath,
34115
34128
  `${JSON.stringify({ $schema: "https://openapi.vercel.sh/vercel.json", framework: "nextjs" }, null, 2)}
34116
34129
  `,
@@ -34120,9 +34133,9 @@ function ensureVercelJsonFramework(cwd) {
34120
34133
  }
34121
34134
 
34122
34135
  // adapters/next/init/vercel/deploy/collect-deploy-env-vars.ts
34123
- import path85 from "path";
34136
+ import path86 from "path";
34124
34137
  function collectDeployEnvVars(cwd, existingProductionKeys) {
34125
- const local = parseDotenvFile(path85.join(cwd, ".env.local"));
34138
+ const local = parseDotenvFile(path86.join(cwd, ".env.local"));
34126
34139
  const vars = [];
34127
34140
  for (const [key, value] of local) {
34128
34141
  if (VERCEL_ENV_SYNC_SKIP_KEYS.has(key)) continue;
@@ -34456,11 +34469,11 @@ function parseIdList(value, isId, formatUnknownMessage) {
34456
34469
  return [];
34457
34470
  }
34458
34471
  const ids = value.split(",").map((entry) => entry.trim()).filter(Boolean);
34459
- const invalid = ids.filter((id) => !isId(id));
34460
- if (invalid.length > 0) {
34461
- throw new Error(formatUnknownMessage(invalid));
34472
+ const valid = ids.filter(isId);
34473
+ if (valid.length !== ids.length) {
34474
+ throw new Error(formatUnknownMessage(ids.filter((id) => !isId(id))));
34462
34475
  }
34463
- return unique(ids);
34476
+ return unique(valid);
34464
34477
  }
34465
34478
 
34466
34479
  // adapters/next/integration-runtime/parse-integration-list.ts
@@ -34520,8 +34533,8 @@ ${stderr}`;
34520
34533
 
34521
34534
  // adapters/next/commands/init/run-seed-script.ts
34522
34535
  import { spawn as spawn7 } from "child_process";
34523
- import fs73 from "fs";
34524
- import path86 from "path";
34536
+ import fs74 from "fs";
34537
+ import path87 from "path";
34525
34538
 
34526
34539
  // adapters/next/templates/renderers/commands/seed/build-seed-script.ts
34527
34540
  function renderBuildSeedScriptEnvFileTemplate({
@@ -34701,23 +34714,23 @@ function buildSeedScript(authBasePath = "/api/admin/auth") {
34701
34714
 
34702
34715
  // adapters/next/commands/init/run-seed-script.ts
34703
34716
  function runSeedScript(cwd, adminDir, authBasePath, envOverrides) {
34704
- const scriptsDir = path86.join(cwd, adminDir, "scripts");
34705
- const seedPath = path86.join(scriptsDir, "seed.ts");
34706
- if (!fs73.existsSync(scriptsDir)) {
34707
- fs73.mkdirSync(scriptsDir, { recursive: true });
34717
+ const scriptsDir = path87.join(cwd, adminDir, "scripts");
34718
+ const seedPath = path87.join(scriptsDir, "seed.ts");
34719
+ if (!fs74.existsSync(scriptsDir)) {
34720
+ fs74.mkdirSync(scriptsDir, { recursive: true });
34708
34721
  }
34709
- fs73.writeFileSync(seedPath, buildSeedScript(authBasePath), "utf-8");
34722
+ fs74.writeFileSync(seedPath, buildSeedScript(authBasePath), "utf-8");
34710
34723
  const cleanup = () => {
34711
34724
  try {
34712
- fs73.unlinkSync(seedPath);
34713
- if (fs73.existsSync(scriptsDir) && fs73.readdirSync(scriptsDir).length === 0) {
34714
- fs73.rmdirSync(scriptsDir);
34725
+ fs74.unlinkSync(seedPath);
34726
+ if (fs74.existsSync(scriptsDir) && fs74.readdirSync(scriptsDir).length === 0) {
34727
+ fs74.rmdirSync(scriptsDir);
34715
34728
  }
34716
34729
  } catch {
34717
34730
  }
34718
34731
  };
34719
34732
  return new Promise((resolve) => {
34720
- const tsxBin = path86.join(cwd, "node_modules", ".bin", "tsx");
34733
+ const tsxBin = path87.join(cwd, "node_modules", ".bin", "tsx");
34721
34734
  const child = spawn7(tsxBin, [seedPath], {
34722
34735
  cwd,
34723
34736
  stdio: "pipe",
@@ -34787,12 +34800,12 @@ function formatAdminIdentity(admin) {
34787
34800
  }
34788
34801
 
34789
34802
  // adapters/next/commands/init/has-db-url.ts
34790
- import fs74 from "fs";
34791
- import path87 from "path";
34803
+ import fs75 from "fs";
34804
+ import path88 from "path";
34792
34805
  function hasDbUrl(cwd) {
34793
- const envPath = path87.join(cwd, ".env.local");
34794
- if (!fs74.existsSync(envPath)) return false;
34795
- const content = fs74.readFileSync(envPath, "utf-8");
34806
+ const envPath = path88.join(cwd, ".env.local");
34807
+ if (!fs75.existsSync(envPath)) return false;
34808
+ const content = fs75.readFileSync(envPath, "utf-8");
34796
34809
  for (const line of content.split("\n")) {
34797
34810
  const trimmed = line.trim();
34798
34811
  if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
@@ -34854,8 +34867,8 @@ function readExistingDbUrl(cwd) {
34854
34867
  }
34855
34868
 
34856
34869
  // adapters/next/commands/init/remove-existing-admin-paths.ts
34857
- import fs75 from "fs";
34858
- import path88 from "path";
34870
+ import fs76 from "fs";
34871
+ import path89 from "path";
34859
34872
 
34860
34873
  // adapters/next/commands/init/normalize-namespace-for-removal.ts
34861
34874
  function normalizeNamespaceForRemoval(value) {
@@ -34883,16 +34896,16 @@ function removeExistingAdminPaths(cwd, namespaces) {
34883
34896
  const nukeFiles = [CONFIG_FILE_NAME, "ADMIN.md", "drizzle.config.ts"];
34884
34897
  let removed = 0;
34885
34898
  for (const dir of nukeDirs) {
34886
- const fullPath = path88.resolve(cwd, dir);
34887
- if (fs75.existsSync(fullPath)) {
34888
- fs75.rmSync(fullPath, { recursive: true, force: true });
34899
+ const fullPath = path89.resolve(cwd, dir);
34900
+ if (fs76.existsSync(fullPath)) {
34901
+ fs76.rmSync(fullPath, { recursive: true, force: true });
34889
34902
  removed++;
34890
34903
  }
34891
34904
  }
34892
34905
  for (const file of nukeFiles) {
34893
- const fullPath = path88.resolve(cwd, file);
34894
- if (fs75.existsSync(fullPath)) {
34895
- fs75.unlinkSync(fullPath);
34906
+ const fullPath = path89.resolve(cwd, file);
34907
+ if (fs76.existsSync(fullPath)) {
34908
+ fs76.unlinkSync(fullPath);
34896
34909
  removed++;
34897
34910
  }
34898
34911
  }
@@ -34930,12 +34943,12 @@ function renderInitBanner() {
34930
34943
  }
34931
34944
 
34932
34945
  // adapters/next/commands/init/resolve-force-init-namespaces.ts
34933
- import fs77 from "fs";
34934
- import path90 from "path";
34946
+ import fs78 from "fs";
34947
+ import path91 from "path";
34935
34948
 
34936
34949
  // adapters/next/commands/init/read-existing-config-namespace.ts
34937
- import fs76 from "fs";
34938
- import path89 from "path";
34950
+ import fs77 from "fs";
34951
+ import path90 from "path";
34939
34952
 
34940
34953
  // adapters/next/commands/init/read-namespace-from-config-source.ts
34941
34954
  function readNamespaceFromConfigSource(source) {
@@ -34945,11 +34958,11 @@ function readNamespaceFromConfigSource(source) {
34945
34958
 
34946
34959
  // adapters/next/commands/init/read-existing-config-namespace.ts
34947
34960
  async function readExistingConfigNamespace(cwd) {
34948
- const configPath = path89.resolve(cwd, CONFIG_FILE_NAME);
34949
- if (!fs76.existsSync(configPath)) {
34961
+ const configPath = path90.resolve(cwd, CONFIG_FILE_NAME);
34962
+ if (!fs77.existsSync(configPath)) {
34950
34963
  return;
34951
34964
  }
34952
- const sourceNamespace = readNamespaceFromConfigSource(fs76.readFileSync(configPath, "utf-8"));
34965
+ const sourceNamespace = readNamespaceFromConfigSource(fs77.readFileSync(configPath, "utf-8"));
34953
34966
  if (sourceNamespace) {
34954
34967
  return sourceNamespace;
34955
34968
  }
@@ -34964,7 +34977,7 @@ async function readExistingConfigNamespace(cwd) {
34964
34977
  // adapters/next/commands/init/resolve-force-init-namespaces.ts
34965
34978
  async function resolveForceInitNamespaces(cwd, targetNamespace) {
34966
34979
  const namespaces = /* @__PURE__ */ new Set([validateAdminNamespace(targetNamespace)]);
34967
- const hasConfig = fs77.existsSync(path90.resolve(cwd, CONFIG_FILE_NAME));
34980
+ const hasConfig = fs78.existsSync(path91.resolve(cwd, CONFIG_FILE_NAME));
34968
34981
  const existingNamespace = await readExistingConfigNamespace(cwd);
34969
34982
  if (existingNamespace) {
34970
34983
  namespaces.add(existingNamespace);
@@ -35255,7 +35268,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35255
35268
  exitInit("validation", message, "INVALID_OPTIONS");
35256
35269
  }
35257
35270
  let cwd = process.cwd();
35258
- let projectName = path91.basename(cwd);
35271
+ let projectName = path92.basename(cwd);
35259
35272
  let forceMode = Boolean(options.force);
35260
35273
  let namespace = DEFAULT_ADMIN_NAMESPACE;
35261
35274
  if (options.namespace) {
@@ -35364,7 +35377,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35364
35377
  }
35365
35378
  pm = pmChoice;
35366
35379
  }
35367
- const displayName = freshProject.projectName === "." ? path91.basename(cwd) : freshProject.projectName;
35380
+ const displayName = freshProject.projectName === "." ? path92.basename(cwd) : freshProject.projectName;
35368
35381
  projectName = displayName;
35369
35382
  const { bin, prefix } = createNextAppCommand();
35370
35383
  const cnaArgs = [
@@ -35402,10 +35415,10 @@ async function runInitCommandInternal(name, options, jsonContext) {
35402
35415
  );
35403
35416
  exitInit("project", createNextAppResult.error, "CREATE_NEXT_APP_FAILED");
35404
35417
  }
35405
- cwd = path91.resolve(cwd, freshProject.projectName);
35406
- const hasPackageJson = fs78.existsSync(path91.join(cwd, "package.json"));
35418
+ cwd = path92.resolve(cwd, freshProject.projectName);
35419
+ const hasPackageJson = fs79.existsSync(path92.join(cwd, "package.json"));
35407
35420
  const hasNextConfig = ["next.config.ts", "next.config.js", "next.config.mjs"].some(
35408
- (f) => fs78.existsSync(path91.join(cwd, f))
35421
+ (f) => fs79.existsSync(path92.join(cwd, f))
35409
35422
  );
35410
35423
  if (!hasPackageJson || !hasNextConfig) {
35411
35424
  createNextAppSpinner.stop(`Failed to create Next.js app: ${displayName}`);
@@ -35730,6 +35743,8 @@ async function runInitCommandInternal(name, options, jsonContext) {
35730
35743
  scaffoldLayout({ cwd, config });
35731
35744
  s.message("API routes");
35732
35745
  scaffoldApiRoutes({ cwd, config });
35746
+ s.message("Route protection");
35747
+ const proxyResult = scaffoldProxy({ cwd, config });
35733
35748
  s.message("Linter");
35734
35749
  if (project2.linter.type === "none") {
35735
35750
  scaffoldOxfmt(cwd, project2.linter, config.paths.admin);
@@ -35740,11 +35755,16 @@ async function runInitCommandInternal(name, options, jsonContext) {
35740
35755
  if (nextConfigResult.status === "unsupported") {
35741
35756
  p61.log.warn("The Next.js config could not be updated automatically \u2014 review it manually.");
35742
35757
  }
35743
- const drizzleConfigPath = path91.join(cwd, "drizzle.config.ts");
35744
- if (!dbFiles.includes("drizzle.config.ts") && fs78.existsSync(drizzleConfigPath)) {
35758
+ if (proxyResult.status === "existing") {
35759
+ p61.log.warn(
35760
+ `Existing ${proxyResult.path} left in place \u2014 add the admin session-cookie redirect to it so logged-out visitors never render the admin routes.`
35761
+ );
35762
+ }
35763
+ const drizzleConfigPath = path92.join(cwd, "drizzle.config.ts");
35764
+ if (!dbFiles.includes("drizzle.config.ts") && fs79.existsSync(drizzleConfigPath)) {
35745
35765
  if (forceMode) {
35746
- const { readNamespacedTemplate } = await import("./read-namespaced-template-TSATYQPP.js");
35747
- fs78.writeFileSync(
35766
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-D2CD4Q7U.js");
35767
+ fs79.writeFileSync(
35748
35768
  drizzleConfigPath,
35749
35769
  readNamespacedTemplate("drizzle.config.ts", namespace),
35750
35770
  "utf-8"
@@ -35756,8 +35776,8 @@ async function runInitCommandInternal(name, options, jsonContext) {
35756
35776
  initialValue: true
35757
35777
  });
35758
35778
  if (!p61.isCancel(overwrite) && overwrite) {
35759
- const { readNamespacedTemplate } = await import("./read-namespaced-template-TSATYQPP.js");
35760
- fs78.writeFileSync(
35779
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-D2CD4Q7U.js");
35780
+ fs79.writeFileSync(
35761
35781
  drizzleConfigPath,
35762
35782
  readNamespacedTemplate("drizzle.config.ts", namespace),
35763
35783
  "utf-8"
@@ -36174,7 +36194,7 @@ async function runInitCommand(name, options) {
36174
36194
 
36175
36195
  // adapters/next/commands/list-integrations.ts
36176
36196
  import * as p62 from "@clack/prompts";
36177
- import path92 from "path";
36197
+ import path93 from "path";
36178
36198
 
36179
36199
  // adapters/next/integration-runtime/list-available-integrations.ts
36180
36200
  function listAvailableIntegrations() {
@@ -36183,7 +36203,7 @@ function listAvailableIntegrations() {
36183
36203
 
36184
36204
  // adapters/next/commands/list-integrations.ts
36185
36205
  async function runListIntegrationsCommand(options) {
36186
- const cwd = options.cwd ? path92.resolve(options.cwd) : process.cwd();
36206
+ const cwd = options.cwd ? path93.resolve(options.cwd) : process.cwd();
36187
36207
  if (options.json) {
36188
36208
  let installed2;
36189
36209
  try {
@@ -36219,7 +36239,7 @@ async function runListIntegrationsCommand(options) {
36219
36239
 
36220
36240
  // adapters/next/commands/list-presets.ts
36221
36241
  import * as p63 from "@clack/prompts";
36222
- import path93 from "path";
36242
+ import path94 from "path";
36223
36243
 
36224
36244
  // adapters/next/preset-runtime/list-available-presets.ts
36225
36245
  function listAvailablePresets() {
@@ -36228,7 +36248,7 @@ function listAvailablePresets() {
36228
36248
 
36229
36249
  // adapters/next/commands/list-presets.ts
36230
36250
  async function runListPresetsCommand(options) {
36231
- const cwd = options.cwd ? path93.resolve(options.cwd) : process.cwd();
36251
+ const cwd = options.cwd ? path94.resolve(options.cwd) : process.cwd();
36232
36252
  if (options.json) {
36233
36253
  let installed2;
36234
36254
  try {
@@ -36261,13 +36281,13 @@ async function runListPresetsCommand(options) {
36261
36281
  }
36262
36282
 
36263
36283
  // adapters/next/commands/update-component/get-static-asset-component-entries.ts
36264
- import fs79 from "fs";
36265
- import path94 from "path";
36284
+ import fs80 from "fs";
36285
+ import path95 from "path";
36266
36286
  function getStaticAssetComponentEntries(assetDirectory) {
36267
36287
  const assetDir = resolveCliAssetPath("shared-assets", "react-admin", assetDirectory);
36268
- if (!fs79.existsSync(assetDir)) return [];
36288
+ if (!fs80.existsSync(assetDir)) return [];
36269
36289
  const components = [];
36270
- for (const entry of fs79.readdirSync(assetDir, { withFileTypes: true })) {
36290
+ for (const entry of fs80.readdirSync(assetDir, { withFileTypes: true })) {
36271
36291
  if (entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts"))) {
36272
36292
  components.push({
36273
36293
  name: entry.name.replace(/\.(tsx|ts)$/, ""),
@@ -36279,12 +36299,12 @@ function getStaticAssetComponentEntries(assetDirectory) {
36279
36299
  continue;
36280
36300
  }
36281
36301
  const indexFile = ["index.tsx", "index.ts"].find(
36282
- (file) => fs79.existsSync(path94.join(assetDir, entry.name, file))
36302
+ (file) => fs80.existsSync(path95.join(assetDir, entry.name, file))
36283
36303
  );
36284
36304
  if (indexFile) {
36285
36305
  components.push({
36286
36306
  name: entry.name,
36287
- file: path94.join(entry.name, indexFile)
36307
+ file: path95.join(entry.name, indexFile)
36288
36308
  });
36289
36309
  }
36290
36310
  }
@@ -37987,6 +38007,12 @@ var TEMPLATE_REGISTRY = {
37987
38007
  base: "cwd",
37988
38008
  dependencies: ["admin-sidebar", "auth-session"]
37989
38009
  },
38010
+ proxy: {
38011
+ relPath: ({ config }) => config.srcDir ? "src/proxy.ts" : "proxy.ts",
38012
+ displayPath: "proxy.ts",
38013
+ content: () => readTemplate("proxy.ts"),
38014
+ base: "cwd"
38015
+ },
37990
38016
  "account-layout": {
37991
38017
  relPath: "app/(admin)/admin/(account)/layout.tsx",
37992
38018
  content: () => readTemplate("pages/account-layout.tsx"),
@@ -39032,28 +39058,28 @@ async function listInstallableChoices(cwd) {
39032
39058
  }
39033
39059
 
39034
39060
  // adapters/next/commands/menu-choices/list-schema-choices.ts
39035
- import path95 from "path";
39061
+ import path96 from "path";
39036
39062
  async function listSchemaChoices(cwd) {
39037
39063
  const config = await resolveConfigOrExit(cwd);
39038
39064
  const paths = resolveProjectPaths(config);
39039
- return listSchemaNames(path95.join(cwd, ...paths.schemasDir.split("/")));
39065
+ return listSchemaNames(path96.join(cwd, ...paths.schemasDir.split("/")));
39040
39066
  }
39041
39067
 
39042
39068
  // adapters/next/commands/remove-schema/run-remove-schema-command.ts
39043
39069
  import * as clack2 from "@clack/prompts";
39044
- import path96 from "path";
39070
+ import path97 from "path";
39045
39071
 
39046
39072
  // core-engine/snapshots/store/delete-snapshot.ts
39047
- import fs80 from "fs";
39073
+ import fs81 from "fs";
39048
39074
  function deleteSnapshot(cwd, scope) {
39049
- fs80.rmSync(scopeDir(cwd, scope), { recursive: true, force: true });
39075
+ fs81.rmSync(scopeDir(cwd, scope), { recursive: true, force: true });
39050
39076
  }
39051
39077
 
39052
39078
  // core-engine/snapshots/store/write-tombstone.ts
39053
- import fs81 from "fs";
39079
+ import fs82 from "fs";
39054
39080
  function writeTombstone(cwd, scope) {
39055
- fs81.mkdirSync(removedDir(cwd), { recursive: true });
39056
- fs81.writeFileSync(tombstonePath(cwd, scope), "", "utf-8");
39081
+ fs82.mkdirSync(removedDir(cwd), { recursive: true });
39082
+ fs82.writeFileSync(tombstonePath(cwd, scope), "", "utf-8");
39057
39083
  }
39058
39084
 
39059
39085
  // adapters/next/commands/remove-schema/cleanup-schema-empty-dirs.ts
@@ -39081,7 +39107,7 @@ function resolveSchemaOwnerForRemoval(cwd, schemaName) {
39081
39107
  // adapters/next/commands/remove-schema/run-remove-schema-command.ts
39082
39108
  async function runRemoveSchemaCommand(schemaName, options) {
39083
39109
  const owner = resolveSchemaOwnerForRemoval(
39084
- options.cwd ? path96.resolve(options.cwd) : process.cwd(),
39110
+ options.cwd ? path97.resolve(options.cwd) : process.cwd(),
39085
39111
  schemaName
39086
39112
  );
39087
39113
  if (owner === "core") {
@@ -39094,7 +39120,7 @@ async function runRemoveSchemaCommand(schemaName, options) {
39094
39120
  clack2.log.error(`"${schemaName}" is owned by ${owner}. Remove the owning preset instead.`);
39095
39121
  process.exit(1);
39096
39122
  }
39097
- const cwd = options.cwd ? path96.resolve(options.cwd) : process.cwd();
39123
+ const cwd = options.cwd ? path97.resolve(options.cwd) : process.cwd();
39098
39124
  const config = await resolveConfigOrExit(cwd);
39099
39125
  const paths = resolveProjectPaths(config);
39100
39126
  const manifest = loadManifest(cwd, schemaName);
@@ -39130,7 +39156,7 @@ async function runRemoveSchemaCommand(schemaName, options) {
39130
39156
  }
39131
39157
  const loaded = (() => {
39132
39158
  try {
39133
- return loadSchema(path96.join(cwd, ...paths.schemasDir.split("/")), schemaName);
39159
+ return loadSchema(path97.join(cwd, ...paths.schemasDir.split("/")), schemaName);
39134
39160
  } catch {
39135
39161
  return null;
39136
39162
  }
@@ -39175,7 +39201,7 @@ Schema JSON preserved.`
39175
39201
 
39176
39202
  // adapters/next/commands/remove.ts
39177
39203
  import * as p64 from "@clack/prompts";
39178
- import path100 from "path";
39204
+ import path101 from "path";
39179
39205
 
39180
39206
  // adapters/next/init/scaffolders/dependencies/build-remove-args.ts
39181
39207
  function buildRemoveArgs(pm, deps, dev) {
@@ -39219,11 +39245,11 @@ async function removeDependenciesAsync({
39219
39245
  }
39220
39246
 
39221
39247
  // adapters/next/integration-runtime/find-blocking-integration-dependencies.ts
39222
- import path98 from "path";
39248
+ import path99 from "path";
39223
39249
 
39224
39250
  // adapters/next/integration-runtime/schema-manifest-contains-mailchimp-imports.ts
39225
- import fs82 from "fs";
39226
- import path97 from "path";
39251
+ import fs83 from "fs";
39252
+ import path98 from "path";
39227
39253
  function schemaManifestContainsMailchimpImports(cwd, config, schemaName) {
39228
39254
  const manifest = loadManifest(cwd, schemaName);
39229
39255
  if (!manifest) {
@@ -39240,11 +39266,11 @@ function schemaManifestContainsMailchimpImports(cwd, config, schemaName) {
39240
39266
  ...manifest.skipped
39241
39267
  ]);
39242
39268
  return liveManifestPaths.some((filePath) => {
39243
- const fullPath = path97.join(cwd, ...filePath.split("/"));
39244
- if (!fs82.existsSync(fullPath) || !fs82.statSync(fullPath).isFile()) {
39269
+ const fullPath = path98.join(cwd, ...filePath.split("/"));
39270
+ if (!fs83.existsSync(fullPath) || !fs83.statSync(fullPath).isFile()) {
39245
39271
  return false;
39246
39272
  }
39247
- const content = fs82.readFileSync(fullPath, "utf-8");
39273
+ const content = fs83.readFileSync(fullPath, "utf-8");
39248
39274
  return markers.some((marker) => content.includes(marker));
39249
39275
  });
39250
39276
  }
@@ -39253,7 +39279,7 @@ function schemaManifestContainsMailchimpImports(cwd, config, schemaName) {
39253
39279
  function findBlockingIntegrationDependencies(cwd, config, integrationId) {
39254
39280
  const blockers = [];
39255
39281
  const paths = resolveProjectPaths(config);
39256
- const schemasDir = path98.join(cwd, ...paths.schemasDir.split("/"));
39282
+ const schemasDir = path99.join(cwd, ...paths.schemasDir.split("/"));
39257
39283
  const ownership = loadSchemaOwnershipIndex(cwd);
39258
39284
  for (const schemaName of listSchemaNames(schemasDir)) {
39259
39285
  if (ownership.schemas[schemaName] !== "user") {
@@ -39276,12 +39302,12 @@ function findBlockingIntegrationDependencies(cwd, config, integrationId) {
39276
39302
  }
39277
39303
 
39278
39304
  // adapters/next/integration-runtime/remove-email-templates-dir-if-empty.ts
39279
- import fs83 from "fs";
39305
+ import fs84 from "fs";
39280
39306
  function removeEmailTemplatesDirIfEmpty(cwd, config) {
39281
39307
  const dir = getEmailTemplatesDir(cwd, config);
39282
- if (!fs83.existsSync(dir)) return;
39283
- if (fs83.readdirSync(dir).length === 0) {
39284
- fs83.rmdirSync(dir);
39308
+ if (!fs84.existsSync(dir)) return;
39309
+ if (fs84.readdirSync(dir).length === 0) {
39310
+ fs84.rmdirSync(dir);
39285
39311
  }
39286
39312
  }
39287
39313
 
@@ -39391,21 +39417,18 @@ function collectSchemaRelationshipTargets(loaded) {
39391
39417
  function walkFields2(fields) {
39392
39418
  if (!Array.isArray(fields)) return;
39393
39419
  for (const field of fields) {
39394
- if (!field || typeof field !== "object") {
39420
+ if (!isRecord(field)) {
39395
39421
  continue;
39396
39422
  }
39397
- const fieldRecord = field;
39398
- const relationship = typeof fieldRecord.relationship === "string" ? fieldRecord.relationship : void 0;
39399
- if (relationship) {
39400
- targets.add(relationship);
39423
+ if (typeof field.relationship === "string") {
39424
+ targets.add(field.relationship);
39401
39425
  }
39402
- walkFields2(fieldRecord.fields);
39403
- if (Array.isArray(fieldRecord.tabs)) {
39404
- for (const tab of fieldRecord.tabs) {
39405
- if (!tab || typeof tab !== "object") {
39406
- continue;
39426
+ walkFields2(field.fields);
39427
+ if (Array.isArray(field.tabs)) {
39428
+ for (const tab of field.tabs) {
39429
+ if (isRecord(tab)) {
39430
+ walkFields2(tab.fields);
39407
39431
  }
39408
- walkFields2(tab.fields);
39409
39432
  }
39410
39433
  }
39411
39434
  }
@@ -39446,8 +39469,8 @@ function findBlockingSchemaDependencies(cwd, config, ownedSchemas) {
39446
39469
  }
39447
39470
 
39448
39471
  // adapters/next/preset-runtime/remove-preset-schemas.ts
39449
- import fs84 from "fs";
39450
- import path99 from "path";
39472
+ import fs85 from "fs";
39473
+ import path100 from "path";
39451
39474
 
39452
39475
  // preset-engine/ownership/remove-schema-owner.ts
39453
39476
  function removeSchemaOwner(cwd, schemaName) {
@@ -39488,8 +39511,8 @@ function removePresetSchemas(cwd, config, manifest) {
39488
39511
  }
39489
39512
  deleteSnapshot(cwd, schemaName);
39490
39513
  }
39491
- const schemaPath = path99.posix.join(paths.schemasDir, `${schemaName}.json`);
39492
- const formsSchemaPath = path99.posix.join(paths.schemasDir, "forms", `${schemaName}.json`);
39514
+ const schemaPath = path100.posix.join(paths.schemasDir, `${schemaName}.json`);
39515
+ const formsSchemaPath = path100.posix.join(paths.schemasDir, "forms", `${schemaName}.json`);
39493
39516
  if (removePath(cwd, schemaPath)) {
39494
39517
  deletedPaths.push(schemaPath);
39495
39518
  }
@@ -39497,7 +39520,7 @@ function removePresetSchemas(cwd, config, manifest) {
39497
39520
  deletedPaths.push(formsSchemaPath);
39498
39521
  }
39499
39522
  if (hasTombstone(cwd, schemaName)) {
39500
- fs84.rmSync(betterstartDir(cwd, "snapshots", "_removed", schemaName), {
39523
+ fs85.rmSync(betterstartDir(cwd, "snapshots", "_removed", schemaName), {
39501
39524
  force: true
39502
39525
  });
39503
39526
  }
@@ -39621,7 +39644,7 @@ async function runRemoveCommand(items, options) {
39621
39644
  );
39622
39645
  process.exit(1);
39623
39646
  }
39624
- const cwd = options.cwd ? path100.resolve(options.cwd) : process.cwd();
39647
+ const cwd = options.cwd ? path101.resolve(options.cwd) : process.cwd();
39625
39648
  const config = await resolveConfigOrExit(cwd);
39626
39649
  const pm = detectPackageManager(cwd);
39627
39650
  if (!options.force) {
@@ -39673,10 +39696,10 @@ async function runRemoveCommand(items, options) {
39673
39696
 
39674
39697
  // adapters/next/commands/seed/run-seed-command.ts
39675
39698
  import * as clack3 from "@clack/prompts";
39676
- import fs85 from "fs";
39677
- import path101 from "path";
39699
+ import fs86 from "fs";
39700
+ import path102 from "path";
39678
39701
  async function runSeedCommand(options) {
39679
- const cwd = options.cwd ? path101.resolve(options.cwd) : process.cwd();
39702
+ const cwd = options.cwd ? path102.resolve(options.cwd) : process.cwd();
39680
39703
  clack3.intro("BetterStart Seed");
39681
39704
  let config;
39682
39705
  try {
@@ -39752,15 +39775,15 @@ async function runSeedCommand(options) {
39752
39775
  }
39753
39776
  name = nameInput;
39754
39777
  }
39755
- const scriptsDir = path101.join(cwd, adminDir, "scripts");
39756
- const seedPath = path101.join(scriptsDir, "seed.ts");
39757
- if (!fs85.existsSync(scriptsDir)) {
39758
- fs85.mkdirSync(scriptsDir, { recursive: true });
39778
+ const scriptsDir = path102.join(cwd, adminDir, "scripts");
39779
+ const seedPath = path102.join(scriptsDir, "seed.ts");
39780
+ if (!fs86.existsSync(scriptsDir)) {
39781
+ fs86.mkdirSync(scriptsDir, { recursive: true });
39759
39782
  }
39760
39783
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
39761
- fs85.writeFileSync(seedPath, buildSeedScript(`${namespace.apiPath}/auth`), "utf-8");
39784
+ fs86.writeFileSync(seedPath, buildSeedScript(`${namespace.apiPath}/auth`), "utf-8");
39762
39785
  const { execFile: execFile2 } = await import("child_process");
39763
- const tsxBin = path101.join(cwd, "node_modules", ".bin", "tsx");
39786
+ const tsxBin = path102.join(cwd, "node_modules", ".bin", "tsx");
39764
39787
  const runSeed2 = (overwrite) => new Promise((resolve, reject) => {
39765
39788
  execFile2(
39766
39789
  tsxBin,
@@ -39798,7 +39821,7 @@ async function runSeedCommand(options) {
39798
39821
  `An admin account (${existingName}) already exists for ${email}. Replacing it needs a terminal.`
39799
39822
  );
39800
39823
  try {
39801
- fs85.unlinkSync(seedPath);
39824
+ fs86.unlinkSync(seedPath);
39802
39825
  } catch {
39803
39826
  }
39804
39827
  process.exit(1);
@@ -39809,7 +39832,7 @@ async function runSeedCommand(options) {
39809
39832
  if (clack3.isCancel(overwrite) || !overwrite) {
39810
39833
  clack3.cancel("Seed cancelled.");
39811
39834
  try {
39812
- fs85.unlinkSync(seedPath);
39835
+ fs86.unlinkSync(seedPath);
39813
39836
  } catch {
39814
39837
  }
39815
39838
  return;
@@ -39826,15 +39849,15 @@ async function runSeedCommand(options) {
39826
39849
  clack3.log.error(errMsg);
39827
39850
  clack3.log.info("You can run the seed script manually:");
39828
39851
  clack3.log.info(
39829
- ` SEED_EMAIL="${email}" SEED_PASSWORD="..." npx tsx ${path101.relative(cwd, seedPath)}`
39852
+ ` SEED_EMAIL="${email}" SEED_PASSWORD="..." npx tsx ${path102.relative(cwd, seedPath)}`
39830
39853
  );
39831
39854
  clack3.outro("");
39832
39855
  process.exit(1);
39833
39856
  }
39834
39857
  try {
39835
- fs85.unlinkSync(seedPath);
39836
- if (fs85.existsSync(scriptsDir) && fs85.readdirSync(scriptsDir).length === 0) {
39837
- fs85.rmdirSync(scriptsDir);
39858
+ fs86.unlinkSync(seedPath);
39859
+ if (fs86.existsSync(scriptsDir) && fs86.readdirSync(scriptsDir).length === 0) {
39860
+ fs86.rmdirSync(scriptsDir);
39838
39861
  }
39839
39862
  } catch {
39840
39863
  }
@@ -39843,18 +39866,18 @@ async function runSeedCommand(options) {
39843
39866
 
39844
39867
  // adapters/next/commands/uninstall/run-uninstall-command.ts
39845
39868
  import * as p65 from "@clack/prompts";
39846
- import path103 from "path";
39869
+ import path104 from "path";
39847
39870
  import pc19 from "picocolors";
39848
39871
 
39849
39872
  // adapters/next/commands/uninstall/build-uninstall-plan.ts
39850
- import fs90 from "fs";
39851
- import path102 from "path";
39873
+ import fs91 from "fs";
39874
+ import path103 from "path";
39852
39875
 
39853
39876
  // adapters/next/commands/uninstall-cleaners/clean-css.ts
39854
- import fs86 from "fs";
39877
+ import fs87 from "fs";
39855
39878
  function cleanCss(cssPath, namespace = "admin") {
39856
- if (!fs86.existsSync(cssPath)) return [];
39857
- const content = fs86.readFileSync(cssPath, "utf-8");
39879
+ if (!fs87.existsSync(cssPath)) return [];
39880
+ const content = fs87.readFileSync(cssPath, "utf-8");
39858
39881
  const lines = content.split("\n");
39859
39882
  const sourcePattern = new RegExp(`^@source\\s+"[^"]*(?:admin|${namespace})[^"]*";\\s*$`);
39860
39883
  const removed = [];
@@ -39868,15 +39891,15 @@ function cleanCss(cssPath, namespace = "admin") {
39868
39891
  }
39869
39892
  if (removed.length === 0) return [];
39870
39893
  const cleaned = kept.join("\n").replace(/\n{3,}/g, "\n\n");
39871
- fs86.writeFileSync(cssPath, cleaned, "utf-8");
39894
+ fs87.writeFileSync(cssPath, cleaned, "utf-8");
39872
39895
  return removed;
39873
39896
  }
39874
39897
 
39875
39898
  // adapters/next/commands/uninstall-cleaners/clean-env-file.ts
39876
- import fs87 from "fs";
39899
+ import fs88 from "fs";
39877
39900
  function cleanEnvFile(envPath) {
39878
- if (!fs87.existsSync(envPath)) return [];
39879
- const content = fs87.readFileSync(envPath, "utf-8");
39901
+ if (!fs88.existsSync(envPath)) return [];
39902
+ const content = fs88.readFileSync(envPath, "utf-8");
39880
39903
  const lines = content.split("\n");
39881
39904
  const removed = [];
39882
39905
  const kept = [];
@@ -39909,19 +39932,19 @@ function cleanEnvFile(envPath) {
39909
39932
  if (removed.length === 0) return [];
39910
39933
  const result = kept.join("\n").replace(/\n{3,}/g, "\n\n").trim();
39911
39934
  if (result === "") {
39912
- fs87.unlinkSync(envPath);
39935
+ fs88.unlinkSync(envPath);
39913
39936
  } else {
39914
- fs87.writeFileSync(envPath, `${result}
39937
+ fs88.writeFileSync(envPath, `${result}
39915
39938
  `, "utf-8");
39916
39939
  }
39917
39940
  return removed;
39918
39941
  }
39919
39942
 
39920
39943
  // adapters/next/commands/uninstall-cleaners/clean-tsconfig.ts
39921
- import fs88 from "fs";
39944
+ import fs89 from "fs";
39922
39945
  function cleanTsconfig(tsconfigPath, aliasRoot = "@admin") {
39923
- if (!fs88.existsSync(tsconfigPath)) return [];
39924
- const raw = fs88.readFileSync(tsconfigPath, "utf-8");
39946
+ if (!fs89.existsSync(tsconfigPath)) return [];
39947
+ const raw = fs89.readFileSync(tsconfigPath, "utf-8");
39925
39948
  const stripped = toStrictJson(raw);
39926
39949
  let tsconfig;
39927
39950
  try {
@@ -39929,8 +39952,9 @@ function cleanTsconfig(tsconfigPath, aliasRoot = "@admin") {
39929
39952
  } catch {
39930
39953
  return [];
39931
39954
  }
39932
- const compilerOptions = tsconfig.compilerOptions ?? {};
39933
- const paths = compilerOptions.paths ?? {};
39955
+ if (!isRecord(tsconfig)) return [];
39956
+ const compilerOptions = isRecord(tsconfig.compilerOptions) ? tsconfig.compilerOptions : {};
39957
+ const paths = isRecord(compilerOptions.paths) ? compilerOptions.paths : {};
39934
39958
  const removed = [];
39935
39959
  for (const key of Object.keys(paths)) {
39936
39960
  if (key.startsWith("@admin/") || key === "@admin/*" || key.startsWith(`${aliasRoot}/`) || key === `${aliasRoot}/*`) {
@@ -39945,17 +39969,17 @@ function cleanTsconfig(tsconfigPath, aliasRoot = "@admin") {
39945
39969
  compilerOptions.paths = paths;
39946
39970
  }
39947
39971
  tsconfig.compilerOptions = compilerOptions;
39948
- fs88.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
39972
+ fs89.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
39949
39973
  `, "utf-8");
39950
39974
  return removed;
39951
39975
  }
39952
39976
 
39953
39977
  // adapters/next/commands/uninstall/is-cli-created-oxc-config.ts
39954
- import fs89 from "fs";
39978
+ import fs90 from "fs";
39955
39979
  function isCLICreatedOxcConfig(configPath) {
39956
- if (!fs89.existsSync(configPath)) return false;
39980
+ if (!fs90.existsSync(configPath)) return false;
39957
39981
  try {
39958
- const content = JSON.parse(fs89.readFileSync(configPath, "utf-8"));
39982
+ const content = JSON.parse(fs90.readFileSync(configPath, "utf-8"));
39959
39983
  return typeof content.$schema === "string" && content.$schema.includes("node_modules/ox") && Array.isArray(content.ignorePatterns) && content.ignorePatterns.includes("**/.betterstart/snapshots/**/files/**");
39960
39984
  } catch {
39961
39985
  return false;
@@ -39966,17 +39990,17 @@ function isCLICreatedOxcConfig(configPath) {
39966
39990
  function buildUninstallPlan(cwd, namespaceValue) {
39967
39991
  const steps = [];
39968
39992
  const namespace = resolveAdminNamespace(namespaceValue);
39969
- const hasSrc = fs90.existsSync(path102.join(cwd, "src"));
39993
+ const hasSrc = fs91.existsSync(path103.join(cwd, "src"));
39970
39994
  const appBase = hasSrc ? "src/app" : "app";
39971
39995
  const dirs = [];
39972
- const adminDir = path102.join(cwd, namespace.segment);
39973
- const legacyAdminDir = path102.join(cwd, "admin");
39974
- const adminRouteGroup = path102.join(cwd, appBase, namespace.routeGroup);
39975
- const legacyAdminRouteGroup = path102.join(cwd, appBase, "(admin)");
39976
- if (fs90.existsSync(adminDir)) dirs.push(`${namespace.segment}/`);
39977
- if (namespace.segment !== "admin" && fs90.existsSync(legacyAdminDir)) dirs.push("admin/");
39978
- if (fs90.existsSync(adminRouteGroup)) dirs.push(`${appBase}/${namespace.routeGroup}/`);
39979
- if (namespace.segment !== "admin" && fs90.existsSync(legacyAdminRouteGroup))
39996
+ const adminDir = path103.join(cwd, namespace.segment);
39997
+ const legacyAdminDir = path103.join(cwd, "admin");
39998
+ const adminRouteGroup = path103.join(cwd, appBase, namespace.routeGroup);
39999
+ const legacyAdminRouteGroup = path103.join(cwd, appBase, "(admin)");
40000
+ if (fs91.existsSync(adminDir)) dirs.push(`${namespace.segment}/`);
40001
+ if (namespace.segment !== "admin" && fs91.existsSync(legacyAdminDir)) dirs.push("admin/");
40002
+ if (fs91.existsSync(adminRouteGroup)) dirs.push(`${appBase}/${namespace.routeGroup}/`);
40003
+ if (namespace.segment !== "admin" && fs91.existsSync(legacyAdminRouteGroup))
39980
40004
  dirs.push(`${appBase}/(admin)/`);
39981
40005
  if (dirs.length > 0) {
39982
40006
  steps.push({
@@ -39985,14 +40009,14 @@ function buildUninstallPlan(cwd, namespaceValue) {
39985
40009
  count: dirs.length,
39986
40010
  unit: dirs.length === 1 ? "directory" : "directories",
39987
40011
  execute() {
39988
- if (fs90.existsSync(adminDir)) fs90.rmSync(adminDir, { recursive: true, force: true });
39989
- if (fs90.existsSync(legacyAdminDir))
39990
- fs90.rmSync(legacyAdminDir, { recursive: true, force: true });
39991
- if (fs90.existsSync(adminRouteGroup)) {
39992
- fs90.rmSync(adminRouteGroup, { recursive: true, force: true });
40012
+ if (fs91.existsSync(adminDir)) fs91.rmSync(adminDir, { recursive: true, force: true });
40013
+ if (fs91.existsSync(legacyAdminDir))
40014
+ fs91.rmSync(legacyAdminDir, { recursive: true, force: true });
40015
+ if (fs91.existsSync(adminRouteGroup)) {
40016
+ fs91.rmSync(adminRouteGroup, { recursive: true, force: true });
39993
40017
  }
39994
- if (fs90.existsSync(legacyAdminRouteGroup)) {
39995
- fs90.rmSync(legacyAdminRouteGroup, { recursive: true, force: true });
40018
+ if (fs91.existsSync(legacyAdminRouteGroup)) {
40019
+ fs91.rmSync(legacyAdminRouteGroup, { recursive: true, force: true });
39996
40020
  }
39997
40021
  }
39998
40022
  });
@@ -40000,18 +40024,18 @@ function buildUninstallPlan(cwd, namespaceValue) {
40000
40024
  const configFiles = [];
40001
40025
  const configPaths = [];
40002
40026
  const candidates = [
40003
- [CONFIG_FILE_NAME, path102.join(cwd, CONFIG_FILE_NAME)],
40004
- ["drizzle.config.ts", path102.join(cwd, "drizzle.config.ts")],
40005
- ["ADMIN.md", path102.join(cwd, "ADMIN.md")]
40027
+ [CONFIG_FILE_NAME, path103.join(cwd, CONFIG_FILE_NAME)],
40028
+ ["drizzle.config.ts", path103.join(cwd, "drizzle.config.ts")],
40029
+ ["ADMIN.md", path103.join(cwd, "ADMIN.md")]
40006
40030
  ];
40007
40031
  for (const [label, fullPath] of candidates) {
40008
- if (fs90.existsSync(fullPath)) {
40032
+ if (fs91.existsSync(fullPath)) {
40009
40033
  configFiles.push(label);
40010
40034
  configPaths.push(fullPath);
40011
40035
  }
40012
40036
  }
40013
40037
  for (const fileName of [".oxfmtrc.json", ".oxlintrc.json"]) {
40014
- const configPath = path102.join(cwd, fileName);
40038
+ const configPath = path103.join(cwd, fileName);
40015
40039
  if (isCLICreatedOxcConfig(configPath)) {
40016
40040
  configFiles.push(`${fileName} (CLI-created)`);
40017
40041
  configPaths.push(configPath);
@@ -40025,14 +40049,14 @@ function buildUninstallPlan(cwd, namespaceValue) {
40025
40049
  unit: configFiles.length === 1 ? "file" : "files",
40026
40050
  execute() {
40027
40051
  for (const p67 of configPaths) {
40028
- if (fs90.existsSync(p67)) fs90.unlinkSync(p67);
40052
+ if (fs91.existsSync(p67)) fs91.unlinkSync(p67);
40029
40053
  }
40030
40054
  }
40031
40055
  });
40032
40056
  }
40033
- const tsconfigPath = path102.join(cwd, "tsconfig.json");
40034
- if (fs90.existsSync(tsconfigPath)) {
40035
- const content = fs90.readFileSync(tsconfigPath, "utf-8");
40057
+ const tsconfigPath = path103.join(cwd, "tsconfig.json");
40058
+ if (fs91.existsSync(tsconfigPath)) {
40059
+ const content = fs91.readFileSync(tsconfigPath, "utf-8");
40036
40060
  const aliasMatches = [
40037
40061
  ...content.match(/"@admin\//g) ?? [],
40038
40062
  ...content.match(new RegExp(`"${namespace.alias}/`, "g")) ?? []
@@ -40052,12 +40076,12 @@ function buildUninstallPlan(cwd, namespaceValue) {
40052
40076
  }
40053
40077
  const cssFile = findMainCss(cwd);
40054
40078
  if (cssFile) {
40055
- const cssContent = fs90.readFileSync(cssFile, "utf-8");
40079
+ const cssContent = fs91.readFileSync(cssFile, "utf-8");
40056
40080
  const sourceLines = cssContent.split("\n").filter(
40057
40081
  (l) => new RegExp(`^@source\\s+"[^"]*(?:admin|${namespace.segment})[^"]*";\\s*$`).test(l)
40058
40082
  );
40059
40083
  if (sourceLines.length > 0) {
40060
- const relCss = path102.relative(cwd, cssFile);
40084
+ const relCss = path103.relative(cwd, cssFile);
40061
40085
  steps.push({
40062
40086
  label: `CSS @source lines (${relCss})`,
40063
40087
  items: [`@source lines in ${relCss}`],
@@ -40069,9 +40093,9 @@ function buildUninstallPlan(cwd, namespaceValue) {
40069
40093
  });
40070
40094
  }
40071
40095
  }
40072
- const envPath = path102.join(cwd, ".env.local");
40073
- if (fs90.existsSync(envPath)) {
40074
- const envContent = fs90.readFileSync(envPath, "utf-8");
40096
+ const envPath = path103.join(cwd, ".env.local");
40097
+ if (fs91.existsSync(envPath)) {
40098
+ const envContent = fs91.readFileSync(envPath, "utf-8");
40075
40099
  const bsVars = envContent.split("\n").filter((l) => l.trim().match(/^BETTERSTART_\w+=/)).map((l) => l.split("=")[0]);
40076
40100
  if (bsVars.length > 0) {
40077
40101
  steps.push({
@@ -40090,7 +40114,7 @@ function buildUninstallPlan(cwd, namespaceValue) {
40090
40114
 
40091
40115
  // adapters/next/commands/uninstall/run-uninstall-command.ts
40092
40116
  async function runUninstallCommand(options) {
40093
- const cwd = options.cwd ? path103.resolve(options.cwd) : process.cwd();
40117
+ const cwd = options.cwd ? path104.resolve(options.cwd) : process.cwd();
40094
40118
  p65.intro(pc19.bgRed(pc19.white(" BetterStart Uninstall ")));
40095
40119
  let namespace = DEFAULT_ADMIN_NAMESPACE;
40096
40120
  try {
@@ -40134,8 +40158,8 @@ async function runUninstallCommand(options) {
40134
40158
 
40135
40159
  // adapters/next/commands/update-component/run-update-command.ts
40136
40160
  import * as clack8 from "@clack/prompts";
40137
- import fs96 from "fs";
40138
- import path109 from "path";
40161
+ import fs97 from "fs";
40162
+ import path110 from "path";
40139
40163
 
40140
40164
  // adapters/next/integration-runtime/sync-installed-integration-manifests.ts
40141
40165
  function syncInstalledIntegrationManifests(cwd, config) {
@@ -40165,63 +40189,63 @@ function applyNamespaceToTemplateEntry(entry, config, cwd) {
40165
40189
  }
40166
40190
 
40167
40191
  // adapters/next/commands/update-component/copy-namespaced-directory.ts
40168
- import fs92 from "fs";
40169
- import path104 from "path";
40192
+ import fs93 from "fs";
40193
+ import path105 from "path";
40170
40194
  import fsExtra from "fs-extra";
40171
40195
 
40172
40196
  // adapters/next/commands/update-component/write-namespaced-file.ts
40173
- import fs91 from "fs";
40197
+ import fs92 from "fs";
40174
40198
  function writeNamespacedFile(srcPath, destPath, namespace) {
40175
- fs91.writeFileSync(
40199
+ fs92.writeFileSync(
40176
40200
  destPath,
40177
- applyAdminNamespaceToContent(fs91.readFileSync(srcPath, "utf-8"), namespace),
40201
+ applyAdminNamespaceToContent(fs92.readFileSync(srcPath, "utf-8"), namespace),
40178
40202
  "utf-8"
40179
40203
  );
40180
40204
  }
40181
40205
 
40182
40206
  // adapters/next/commands/update-component/copy-namespaced-directory.ts
40183
40207
  function copyNamespacedDirectory(srcDir, destDir, namespace) {
40184
- const entries = fs92.readdirSync(srcDir, { withFileTypes: true });
40208
+ const entries = fs93.readdirSync(srcDir, { withFileTypes: true });
40185
40209
  for (const entry of entries) {
40186
40210
  const namespacedName = applyAdminNamespaceToPath(entry.name, namespace);
40187
- const srcPath = path104.join(srcDir, entry.name);
40188
- const destPath = path104.join(destDir, namespacedName);
40211
+ const srcPath = path105.join(srcDir, entry.name);
40212
+ const destPath = path105.join(destDir, namespacedName);
40189
40213
  if (entry.isDirectory()) {
40190
40214
  fsExtra.ensureDirSync(destPath);
40191
40215
  copyNamespacedDirectory(srcPath, destPath, namespace);
40192
40216
  continue;
40193
40217
  }
40194
- fsExtra.ensureDirSync(path104.dirname(destPath));
40218
+ fsExtra.ensureDirSync(path105.dirname(destPath));
40195
40219
  writeNamespacedFile(srcPath, destPath, namespace);
40196
40220
  }
40197
40221
  }
40198
40222
 
40199
40223
  // adapters/next/commands/update-component/find-static-asset-file.ts
40200
- import fs93 from "fs";
40201
- import path105 from "path";
40224
+ import fs94 from "fs";
40225
+ import path106 from "path";
40202
40226
  function findStaticAssetFile(assetDir, componentName) {
40203
- if (!fs93.existsSync(assetDir)) return void 0;
40227
+ if (!fs94.existsSync(assetDir)) return void 0;
40204
40228
  const isNestedComponentName = /[\\/]/.test(componentName);
40205
- const nestedComponentName = componentName.split(/[\\/]/).filter(Boolean).join(path105.sep);
40206
- if (isNestedComponentName && nestedComponentName && !path105.isAbsolute(componentName) && !nestedComponentName.split(path105.sep).includes("..")) {
40229
+ const nestedComponentName = componentName.split(/[\\/]/).filter(Boolean).join(path106.sep);
40230
+ if (isNestedComponentName && nestedComponentName && !path106.isAbsolute(componentName) && !nestedComponentName.split(path106.sep).includes("..")) {
40207
40231
  for (const extension of [".tsx", ".ts"]) {
40208
40232
  const relPath = `${nestedComponentName}${extension}`;
40209
- const filePath = path105.join(assetDir, relPath);
40210
- if (fs93.existsSync(filePath) && fs93.statSync(filePath).isFile()) {
40233
+ const filePath = path106.join(assetDir, relPath);
40234
+ if (fs94.existsSync(filePath) && fs94.statSync(filePath).isFile()) {
40211
40235
  return relPath;
40212
40236
  }
40213
40237
  }
40214
40238
  }
40215
- if (!isNestedComponentName && !componentName.includes("..") && !path105.isAbsolute(componentName)) {
40239
+ if (!isNestedComponentName && !componentName.includes("..") && !path106.isAbsolute(componentName)) {
40216
40240
  for (const extension of [".tsx", ".ts"]) {
40217
- const relPath = path105.join(componentName, `index${extension}`);
40218
- const filePath = path105.join(assetDir, relPath);
40219
- if (fs93.existsSync(filePath) && fs93.statSync(filePath).isFile()) {
40241
+ const relPath = path106.join(componentName, `index${extension}`);
40242
+ const filePath = path106.join(assetDir, relPath);
40243
+ if (fs94.existsSync(filePath) && fs94.statSync(filePath).isFile()) {
40220
40244
  return relPath;
40221
40245
  }
40222
40246
  }
40223
40247
  }
40224
- return fs93.readdirSync(assetDir, { withFileTypes: true }).find(
40248
+ return fs94.readdirSync(assetDir, { withFileTypes: true }).find(
40225
40249
  (entry) => entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts")) && entry.name.replace(/\.(tsx|ts)$/, "") === componentName
40226
40250
  )?.name;
40227
40251
  }
@@ -40263,8 +40287,8 @@ function normalizeShadcnPresetOnly(value) {
40263
40287
  // adapters/next/commands/update-component/run-shadcn-preset-update.ts
40264
40288
  import * as clack6 from "@clack/prompts";
40265
40289
  import { execFileSync as execFileSync4 } from "child_process";
40266
- import fs95 from "fs";
40267
- import path108 from "path";
40290
+ import fs96 from "fs";
40291
+ import path109 from "path";
40268
40292
 
40269
40293
  // adapters/next/commands/update-component/create-admin-shadcn-components-json.ts
40270
40294
  function createAdminShadcnComponentsJson(config) {
@@ -40295,7 +40319,7 @@ function createAdminShadcnComponentsJson(config) {
40295
40319
  }
40296
40320
 
40297
40321
  // adapters/next/commands/update-component/get-host-project-files-to-restore.ts
40298
- import path106 from "path";
40322
+ import path107 from "path";
40299
40323
  function getHostProjectFilesToRestore(cwd) {
40300
40324
  const hostRelativePaths = [
40301
40325
  "app/layout.tsx",
@@ -40309,17 +40333,17 @@ function getHostProjectFilesToRestore(cwd) {
40309
40333
  "app/globals.css",
40310
40334
  "src/app/globals.css"
40311
40335
  ];
40312
- return hostRelativePaths.map((relativePath) => path106.join(cwd, relativePath));
40336
+ return hostRelativePaths.map((relativePath) => path107.join(cwd, relativePath));
40313
40337
  }
40314
40338
 
40315
40339
  // adapters/next/commands/update-component/resolve-local-shadcn-bin.ts
40316
40340
  import * as clack5 from "@clack/prompts";
40317
- import fs94 from "fs";
40318
- import path107 from "path";
40341
+ import fs95 from "fs";
40342
+ import path108 from "path";
40319
40343
  function resolveLocalShadcnBin(cwd) {
40320
40344
  const binName = process.platform === "win32" ? "shadcn.cmd" : "shadcn";
40321
- const shadcnBin = path107.join(cwd, "node_modules", ".bin", binName);
40322
- if (!fs94.existsSync(shadcnBin)) {
40345
+ const shadcnBin = path108.join(cwd, "node_modules", ".bin", binName);
40346
+ if (!fs95.existsSync(shadcnBin)) {
40323
40347
  clack5.cancel(
40324
40348
  `shadcn is not installed in this project. Run 'betterstart update-deps' and try again.`
40325
40349
  );
@@ -40336,22 +40360,22 @@ function runShadcnPresetUpdate({
40336
40360
  only
40337
40361
  }) {
40338
40362
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
40339
- const adminGlobalsPath = path108.join(cwd, config.paths.admin, namespace.globalsFile);
40340
- const componentsJsonPath = path108.join(cwd, "components.json");
40363
+ const adminGlobalsPath = path109.join(cwd, config.paths.admin, namespace.globalsFile);
40364
+ const componentsJsonPath = path109.join(cwd, "components.json");
40341
40365
  const shadcnBackupPath = `${componentsJsonPath}.bak`;
40342
40366
  const restoreAfterApplyPaths = [
40343
40367
  componentsJsonPath,
40344
40368
  shadcnBackupPath,
40345
- path108.join(cwd, config.paths.admin, "lib", "utils.ts"),
40369
+ path109.join(cwd, config.paths.admin, "lib", "utils.ts"),
40346
40370
  ...getHostProjectFilesToRestore(cwd)
40347
40371
  ];
40348
40372
  if (!preset) {
40349
40373
  clack6.cancel("--shadcn-preset requires a preset code, preset name, or preset URL.");
40350
40374
  process.exit(1);
40351
40375
  }
40352
- if (!fs95.existsSync(adminGlobalsPath)) {
40376
+ if (!fs96.existsSync(adminGlobalsPath)) {
40353
40377
  clack6.cancel(
40354
- `Admin globals file not found at ${path108.relative(cwd, adminGlobalsPath)}. Run 'betterstart update admin-globals' first.`
40378
+ `Admin globals file not found at ${path109.relative(cwd, adminGlobalsPath)}. Run 'betterstart update admin-globals' first.`
40355
40379
  );
40356
40380
  process.exit(1);
40357
40381
  }
@@ -40361,10 +40385,10 @@ function runShadcnPresetUpdate({
40361
40385
  snapshot: captureFile(filePath)
40362
40386
  }));
40363
40387
  clack6.intro("BetterStart Shadcn Preset");
40364
- clack6.log.info(`Applying preset to ${path108.join(config.paths.admin, "components/ui")}`);
40388
+ clack6.log.info(`Applying preset to ${path109.join(config.paths.admin, "components/ui")}`);
40365
40389
  let failed = false;
40366
40390
  try {
40367
- fs95.writeFileSync(
40391
+ fs96.writeFileSync(
40368
40392
  componentsJsonPath,
40369
40393
  `${JSON.stringify(createAdminShadcnComponentsJson(config), null, 2)}
40370
40394
  `,
@@ -40417,7 +40441,7 @@ function validateShadcnPresetOptions(components, options) {
40417
40441
 
40418
40442
  // adapters/next/commands/update-component/run-update-command.ts
40419
40443
  async function runUpdateCommand(components, options) {
40420
- const cwd = options.cwd ? path109.resolve(options.cwd) : process.cwd();
40444
+ const cwd = options.cwd ? path110.resolve(options.cwd) : process.cwd();
40421
40445
  const normalizedOnly = normalizeShadcnPresetOnly(options.only);
40422
40446
  validateShadcnPresetOptions(components, options);
40423
40447
  if (options.json && !options.list) {
@@ -40478,8 +40502,8 @@ async function runUpdateCommand(components, options) {
40478
40502
  return;
40479
40503
  }
40480
40504
  const config = await resolveConfigOrExit(cwd);
40481
- const admin = path109.resolve(cwd, config.paths.admin);
40482
- if (!fs96.existsSync(admin)) {
40505
+ const admin = path110.resolve(cwd, config.paths.admin);
40506
+ if (!fs97.existsSync(admin)) {
40483
40507
  clack8.cancel(
40484
40508
  `Admin directory not found at ${config.paths.admin}. Run 'betterstart init' first.`
40485
40509
  );
@@ -40533,8 +40557,8 @@ async function runUpdateCommand(components, options) {
40533
40557
  }
40534
40558
  const { relPath, content } = applyNamespaceToTemplateEntry(entry, config, cwd);
40535
40559
  const baseDir = entry.base === "cwd" ? cwd : admin;
40536
- const destPath = path109.join(baseDir, relPath);
40537
- if (entry.preserveExisting && fs96.existsSync(destPath)) {
40560
+ const destPath = path110.join(baseDir, relPath);
40561
+ if (entry.preserveExisting && fs97.existsSync(destPath)) {
40538
40562
  clack8.log.info(`Preserved ${relPath}`);
40539
40563
  updatedTemplateNames.add(name);
40540
40564
  skipped++;
@@ -40543,8 +40567,8 @@ async function runUpdateCommand(components, options) {
40543
40567
  pendingWrites.push({
40544
40568
  displayPath: relPath,
40545
40569
  write: () => {
40546
- fsExtra2.ensureDirSync(path109.dirname(destPath));
40547
- fs96.writeFileSync(destPath, content, "utf-8");
40570
+ fsExtra2.ensureDirSync(path110.dirname(destPath));
40571
+ fs97.writeFileSync(destPath, content, "utf-8");
40548
40572
  clack8.log.success(`Updated ${relPath}`);
40549
40573
  }
40550
40574
  });
@@ -40575,20 +40599,20 @@ async function runUpdateCommand(components, options) {
40575
40599
  }
40576
40600
  const namespace = config.frameworkConfig.next.namespace;
40577
40601
  const namespacedAssetFile = applyAdminNamespaceToPath(assetFile, namespace);
40578
- const destPath = path109.join(admin, "components", assetDirectory, namespacedAssetFile);
40602
+ const destPath = path110.join(admin, "components", assetDirectory, namespacedAssetFile);
40579
40603
  pendingWrites.push({
40580
40604
  displayPath: `components/${assetDirectory}/${namespacedAssetFile}`,
40581
40605
  write: () => {
40582
- fsExtra2.ensureDirSync(path109.dirname(destPath));
40583
- writeNamespacedFile(path109.join(assetDir, assetFile), destPath, namespace);
40606
+ fsExtra2.ensureDirSync(path110.dirname(destPath));
40607
+ writeNamespacedFile(path110.join(assetDir, assetFile), destPath, namespace);
40584
40608
  clack8.log.success(`Updated components/${assetDirectory}/${namespacedAssetFile}`);
40585
40609
  }
40586
40610
  });
40587
40611
  if (assetDirectory === "custom") {
40588
- const assetSubdir = path109.join(assetDir, name);
40589
- if (fs96.existsSync(assetSubdir) && fs96.statSync(assetSubdir).isDirectory()) {
40612
+ const assetSubdir = path110.join(assetDir, name);
40613
+ if (fs97.existsSync(assetSubdir) && fs97.statSync(assetSubdir).isDirectory()) {
40590
40614
  const namespacedName = applyAdminNamespaceToPath(name, namespace);
40591
- const destSubdir = path109.join(admin, "components", assetDirectory, namespacedName);
40615
+ const destSubdir = path110.join(admin, "components", assetDirectory, namespacedName);
40592
40616
  pendingWrites.push({
40593
40617
  displayPath: `components/${assetDirectory}/${namespacedName}/ (template files)`,
40594
40618
  write: () => {
@@ -40623,19 +40647,19 @@ async function runUpdateCommand(components, options) {
40623
40647
  "content-editor"
40624
40648
  );
40625
40649
  const namespace = config.frameworkConfig.next.namespace;
40626
- const destBaseDir = path109.join(admin, "components", "custom", "content-editor");
40627
- if (!fs96.existsSync(srcBaseDir)) {
40650
+ const destBaseDir = path110.join(admin, "components", "custom", "content-editor");
40651
+ if (!fs97.existsSync(srcBaseDir)) {
40628
40652
  return false;
40629
40653
  }
40630
40654
  const dirsToCopy = [];
40631
40655
  for (const directory of TIPTAP_CONTENT_EDITOR_DIRECTORIES) {
40632
- const srcDir = path109.join(srcBaseDir, directory);
40633
- if (!fs96.existsSync(srcDir)) {
40656
+ const srcDir = path110.join(srcBaseDir, directory);
40657
+ if (!fs97.existsSync(srcDir)) {
40634
40658
  continue;
40635
40659
  }
40636
40660
  dirsToCopy.push({
40637
40661
  srcDir,
40638
- destDir: path109.join(destBaseDir, applyAdminNamespaceToPath(directory, namespace))
40662
+ destDir: path110.join(destBaseDir, applyAdminNamespaceToPath(directory, namespace))
40639
40663
  });
40640
40664
  }
40641
40665
  if (dirsToCopy.length === 0) {
@@ -40649,7 +40673,7 @@ async function runUpdateCommand(components, options) {
40649
40673
  copyNamespacedDirectory(srcDir, destDir, namespace);
40650
40674
  }
40651
40675
  clack8.log.success("Updated components/custom/content-editor/tiptap-*/ (template files)");
40652
- removePath(admin, path109.join(admin, "components", "custom", "tiptap"));
40676
+ removePath(admin, path110.join(admin, "components", "custom", "tiptap"));
40653
40677
  }
40654
40678
  });
40655
40679
  updatedStaticNames.add(key);
@@ -40746,7 +40770,7 @@ async function runUpdateCommand(components, options) {
40746
40770
 
40747
40771
  // adapters/next/commands/update-deps.ts
40748
40772
  import * as clack9 from "@clack/prompts";
40749
- import path110 from "path";
40773
+ import path111 from "path";
40750
40774
 
40751
40775
  // adapters/next/integration-runtime/get-installed-integrations.ts
40752
40776
  function getInstalledIntegrations(config) {
@@ -40760,7 +40784,7 @@ function getInstalledPresets(config) {
40760
40784
 
40761
40785
  // adapters/next/commands/update-deps.ts
40762
40786
  async function runUpdateDepsCommand(options) {
40763
- const cwd = options.cwd ? path110.resolve(options.cwd) : process.cwd();
40787
+ const cwd = options.cwd ? path111.resolve(options.cwd) : process.cwd();
40764
40788
  clack9.intro("BetterStart Update Dependencies");
40765
40789
  const pm = detectPackageManager(cwd);
40766
40790
  clack9.log.info(`Package manager: ${pm}`);
@@ -40795,25 +40819,25 @@ async function runUpdateDepsCommand(options) {
40795
40819
 
40796
40820
  // adapters/next/commands/update-styles.ts
40797
40821
  import * as clack10 from "@clack/prompts";
40798
- import fs97 from "fs";
40799
- import path111 from "path";
40822
+ import fs98 from "fs";
40823
+ import path112 from "path";
40800
40824
  async function runUpdateStylesCommand(options) {
40801
- const cwd = options.cwd ? path111.resolve(options.cwd) : process.cwd();
40825
+ const cwd = options.cwd ? path112.resolve(options.cwd) : process.cwd();
40802
40826
  clack10.intro("BetterStart Update Styles");
40803
40827
  const config = await resolveConfigOrExit(cwd);
40804
40828
  const adminDir = config.paths.admin;
40805
40829
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
40806
- const targetPath = path111.join(cwd, adminDir, namespace.globalsFile);
40807
- if (!fs97.existsSync(targetPath)) {
40808
- clack10.cancel(`${namespace.globalsFile} not found at ${path111.relative(cwd, targetPath)}`);
40830
+ const targetPath = path112.join(cwd, adminDir, namespace.globalsFile);
40831
+ if (!fs98.existsSync(targetPath)) {
40832
+ clack10.cancel(`${namespace.globalsFile} not found at ${path112.relative(cwd, targetPath)}`);
40809
40833
  process.exit(1);
40810
40834
  }
40811
- fs97.writeFileSync(
40835
+ fs98.writeFileSync(
40812
40836
  targetPath,
40813
40837
  applyAdminNamespaceToContent(readTemplate("admin-globals.css"), namespace.segment),
40814
40838
  "utf-8"
40815
40839
  );
40816
- clack10.log.success(`Updated ${path111.relative(cwd, targetPath)}`);
40840
+ clack10.log.success(`Updated ${path112.relative(cwd, targetPath)}`);
40817
40841
  clack10.outro("Styles updated");
40818
40842
  }
40819
40843