betterstart-cli 0.0.115 → 0.0.117

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
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ACCEPT_TERMS_URL_PATTERN,
4
+ ADMIN_CONTAINER_ROUTE_GROUP,
4
5
  BETTERSTART_ASSET_HOST,
5
6
  BETTERSTART_DIR,
6
7
  CLI_PACKAGE_NAME,
@@ -85,7 +86,7 @@ import {
85
86
  trimDotSlash,
86
87
  usesIdentifier,
87
88
  validateAdminNamespace
88
- } from "./chunk-SG4U6EQY.js";
89
+ } from "./chunk-FGEVDA53.js";
89
90
 
90
91
  // cli.ts
91
92
  import * as p66 from "@clack/prompts";
@@ -263,6 +264,14 @@ function redirectStdoutToStderr() {
263
264
  process.stdout.write = originalWrite;
264
265
  };
265
266
  }
267
+ function writeMachineJson(payload) {
268
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}
269
+ `);
270
+ }
271
+ function writeDiagnostic(message) {
272
+ process.stderr.write(`${message}
273
+ `);
274
+ }
266
275
  function renderTableRows(rows) {
267
276
  const widths = [];
268
277
  for (const row of rows) {
@@ -531,7 +540,7 @@ function unique(values) {
531
540
  return Array.from(new Set(values));
532
541
  }
533
542
  function arraysEqual(a, b) {
534
- return Boolean(a && a.length === b.length && a.every((value, index) => value === b[index]));
543
+ return Array.isArray(a) && a.length === b.length && a.every((value, index) => value === b[index]);
535
544
  }
536
545
  function isValidPort(port) {
537
546
  return Number.isInteger(port) && port > 0 && port <= 65535;
@@ -1125,25 +1134,41 @@ function flattenSlotLayout(slot) {
1125
1134
 
1126
1135
  // core-engine/schema/schema-reader/walk-slot-aware-field.ts
1127
1136
  function walkSlotAwareField(field, fieldPath, errors, options) {
1137
+ if (!isRecord(field)) {
1138
+ errors.push(`Field "${fieldPath}" must be an object.`);
1139
+ return;
1140
+ }
1128
1141
  options.checkField(field, fieldPath, errors);
1142
+ const childPath = (parentPath, child) => `${parentPath}.${isRecord(child) && isNonEmptyString(child.name) ? child.name : "unnamed"}`;
1129
1143
  const descend = (children, parentPath) => {
1144
+ if (!Array.isArray(children)) {
1145
+ errors.push(`Field "${parentPath}" has a "fields" value that must be an array.`);
1146
+ return;
1147
+ }
1130
1148
  for (const child of children) {
1131
- walkSlotAwareField(child, `${parentPath}.${child.name ?? "unnamed"}`, errors, options);
1149
+ walkSlotAwareField(child, childPath(parentPath, child), errors, options);
1132
1150
  }
1133
1151
  };
1134
- if (field.fields) {
1152
+ if (field.fields !== void 0) {
1135
1153
  descend(field.fields, fieldPath);
1136
1154
  }
1137
- if (field.tabs) {
1138
- for (const tab of field.tabs) {
1139
- const tabPath = `${fieldPath}.${tab.name ?? "unnamed"}`;
1140
- options.onTab?.(tab, tabPath, errors);
1141
- if (options.descendTabSlots && tab.slot !== void 0) {
1142
- descend(flattenSlotLayout(tab.slot), tabPath);
1143
- }
1144
- if (tab.fields) {
1145
- descend(tab.fields, tabPath);
1146
- }
1155
+ if (field.tabs === void 0) return;
1156
+ if (!Array.isArray(field.tabs)) {
1157
+ errors.push(`Field "${fieldPath}" has a "tabs" value that must be an array.`);
1158
+ return;
1159
+ }
1160
+ for (const tab of field.tabs) {
1161
+ const tabPath = childPath(fieldPath, tab);
1162
+ if (!isRecord(tab)) {
1163
+ errors.push(`Tab "${tabPath}" must be an object.`);
1164
+ continue;
1165
+ }
1166
+ options.onTab?.(tab, tabPath, errors);
1167
+ if (options.descendTabSlots && tab.slot !== void 0) {
1168
+ descend(flattenSlotLayout(tab.slot), tabPath);
1169
+ }
1170
+ if (tab.fields !== void 0) {
1171
+ descend(tab.fields, tabPath);
1147
1172
  }
1148
1173
  }
1149
1174
  }
@@ -1166,7 +1191,8 @@ function walkHeight(field, fieldPath, errors) {
1166
1191
  function collectInvalidHeightErrors(topLevelFields, rootPath, errors) {
1167
1192
  const prefix = rootPath ? `${rootPath}.` : "";
1168
1193
  for (const field of topLevelFields) {
1169
- walkHeight(field, `${prefix}${field.name ?? "unnamed"}`, errors);
1194
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1195
+ walkHeight(field, `${prefix}${name}`, errors);
1170
1196
  }
1171
1197
  }
1172
1198
 
@@ -1240,7 +1266,8 @@ function collectSlotAreaErrors(value, path113, errors) {
1240
1266
  return;
1241
1267
  }
1242
1268
  for (const field of fields) {
1243
- walkSlot(field, `${path113}.fields.${field.name ?? "unnamed"}`, errors);
1269
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1270
+ walkSlot(field, `${path113}.fields.${name}`, errors);
1244
1271
  }
1245
1272
  }
1246
1273
 
@@ -1297,7 +1324,8 @@ function walkSlot(field, fieldPath, errors) {
1297
1324
  function collectInvalidSlotErrors(fields, rootPath, errors) {
1298
1325
  const prefix = rootPath ? `${rootPath}.` : "";
1299
1326
  for (const field of fields) {
1300
- walkSlot(field, `${prefix}${field.name ?? "unnamed"}`, errors);
1327
+ const name = isRecord(field) && isNonEmptyString(field.name) ? field.name : "unnamed";
1328
+ walkSlot(field, `${prefix}${name}`, errors);
1301
1329
  }
1302
1330
  }
1303
1331
 
@@ -1914,6 +1942,7 @@ function resolveProjectPaths(config) {
1914
1942
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
1915
1943
  const adminDir = trimDotSlash(config.paths?.admin ?? "./admin");
1916
1944
  const pagesDir = trimDotSlash(config.paths?.pages ?? "./src/app/(admin)/admin/(authenticated)");
1945
+ const containerDir = path6.posix.join(pagesDir, ADMIN_CONTAINER_ROUTE_GROUP);
1917
1946
  const schemasDir = trimDotSlash(config.paths?.schemas ?? "./admin/schemas");
1918
1947
  const adminDbDir = path6.posix.join(adminDir, "lib", "db");
1919
1948
  const adminDbCoreDir = path6.posix.join(adminDbDir, "core");
@@ -1927,6 +1956,7 @@ function resolveProjectPaths(config) {
1927
1956
  return {
1928
1957
  adminDir,
1929
1958
  pagesDir,
1959
+ containerDir,
1930
1960
  schemasDir,
1931
1961
  adminDbDir,
1932
1962
  adminDbCoreDir,
@@ -2167,8 +2197,7 @@ function loadSchema(schemasDir, name) {
2167
2197
  const filePath = resolveSchemaFilePath(schemasDir, name);
2168
2198
  const content = fs10.readFileSync(filePath, "utf-8");
2169
2199
  const parsed = parseSchemaJson(content, filePath);
2170
- const obj = parsed;
2171
- switch (schemaKindFromType(name, obj.type)) {
2200
+ switch (schemaKindFromType(name, isRecord(parsed) ? parsed.type : void 0)) {
2172
2201
  case "form":
2173
2202
  return { type: "form", schema: parsed, filePath };
2174
2203
  case "single":
@@ -2287,7 +2316,7 @@ function detectPackageManager(cwd) {
2287
2316
  if (!fs14.existsSync(pkgPath)) return void 0;
2288
2317
  try {
2289
2318
  const pkg = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
2290
- if (typeof pkg.packageManager === "string") {
2319
+ if (isRecord(pkg) && typeof pkg.packageManager === "string") {
2291
2320
  const name = pkg.packageManager.split("@")[0];
2292
2321
  if (name === "pnpm" || name === "npm" || name === "yarn" || name === "bun") return name;
2293
2322
  }
@@ -5931,7 +5960,7 @@ function formatTsValue(value, indent = 0) {
5931
5960
  ${value.map((item) => `${childIndent}${formatTsValue(item, indent + 2)}`).join(",\n")}
5932
5961
  ${currentIndent}]`;
5933
5962
  }
5934
- if (value && typeof value === "object") {
5963
+ if (isRecord(value)) {
5935
5964
  return formatTsObject(value, indent);
5936
5965
  }
5937
5966
  return JSON.stringify(value);
@@ -9194,7 +9223,7 @@ function runFormPipeline(schema, cwd, config, options = {}) {
9194
9223
  },
9195
9224
  {
9196
9225
  name: "Admin pages",
9197
- run: () => generateFormAdminPages(schema, paths.pagesDir, namespacedOptions).files
9226
+ run: () => generateFormAdminPages(schema, paths.containerDir, namespacedOptions).files
9198
9227
  },
9199
9228
  {
9200
9229
  name: "Navigation",
@@ -9237,11 +9266,13 @@ function genBarrelContent(files, ctx) {
9237
9266
  `${ctx.Singular}UpdateInput`,
9238
9267
  `${ctx.Singular}UpdateResult`,
9239
9268
  `${ctx.Singular}DeleteResult`,
9240
- ctx.hasCreatableSelectFields ? `${ctx.Singular}SelectOption` : null,
9241
- ctx.hasCreatableSelectFields ? `${ctx.Singular}SelectOptionFieldName` : null,
9242
- ctx.hasCreatableSelectFields ? `Create${ctx.Singular}SelectOptionInput` : null,
9243
- ctx.hasCreatableSelectFields ? `Create${ctx.Singular}SelectOptionResult` : null
9244
- ].filter(Boolean);
9269
+ ...ctx.hasCreatableSelectFields ? [
9270
+ `${ctx.Singular}SelectOption`,
9271
+ `${ctx.Singular}SelectOptionFieldName`,
9272
+ `Create${ctx.Singular}SelectOptionInput`,
9273
+ `Create${ctx.Singular}SelectOptionResult`
9274
+ ] : []
9275
+ ];
9245
9276
  lines.push(`export type { ${typeNames.join(", ")} } from './types'`);
9246
9277
  lines.push("");
9247
9278
  for (const file of files) {
@@ -21762,37 +21793,37 @@ function runEntityPipeline(schema, cwd, config, options = {}) {
21762
21793
  },
21763
21794
  {
21764
21795
  name: "Column definitions",
21765
- run: () => generateColumns2(normalizedSchema, paths.pagesDir, namespacedOptions).files
21796
+ run: () => generateColumns2(normalizedSchema, paths.containerDir, namespacedOptions).files
21766
21797
  },
21767
21798
  {
21768
21799
  name: "Table component",
21769
- run: () => generateTable2(normalizedSchema, paths.pagesDir, namespacedOptions).files
21800
+ run: () => generateTable2(normalizedSchema, paths.containerDir, namespacedOptions).files
21770
21801
  },
21771
21802
  {
21772
21803
  name: "Page content",
21773
- run: () => generatePageContent2(normalizedSchema, paths.pagesDir, namespacedOptions).files
21804
+ run: () => generatePageContent2(normalizedSchema, paths.containerDir, namespacedOptions).files
21774
21805
  },
21775
21806
  {
21776
21807
  name: "Page (server)",
21777
- run: () => generatePage2(normalizedSchema, paths.pagesDir, namespacedOptions).files
21808
+ run: () => generatePage2(normalizedSchema, paths.containerDir, namespacedOptions).files
21778
21809
  }
21779
21810
  ];
21780
21811
  if (normalizedSchema.actions?.create || normalizedSchema.actions?.edit) {
21781
21812
  steps.push({
21782
21813
  name: "Form",
21783
- run: () => generateForm(normalizedSchema, paths.pagesDir, namespacedOptions).files
21814
+ run: () => generateForm(normalizedSchema, paths.containerDir, namespacedOptions).files
21784
21815
  });
21785
21816
  }
21786
21817
  if (normalizedSchema.actions?.create) {
21787
21818
  steps.push({
21788
21819
  name: "Create page",
21789
- run: () => generateCreatePage(normalizedSchema, paths.pagesDir, namespacedOptions).files
21820
+ run: () => generateCreatePage(normalizedSchema, paths.containerDir, namespacedOptions).files
21790
21821
  });
21791
21822
  }
21792
21823
  if (normalizedSchema.actions?.edit) {
21793
21824
  steps.push({
21794
21825
  name: "Edit page",
21795
- run: () => generateEditPage(normalizedSchema, paths.pagesDir, namespacedOptions).files
21826
+ run: () => generateEditPage(normalizedSchema, paths.containerDir, namespacedOptions).files
21796
21827
  });
21797
21828
  }
21798
21829
  steps.push({
@@ -23537,11 +23568,11 @@ function runSinglePipeline(schema, cwd, config, options = {}) {
23537
23568
  },
23538
23569
  {
23539
23570
  name: "Form",
23540
- run: () => generateSingleForm(normalizedSchema, paths.pagesDir, namespacedOptions).files
23571
+ run: () => generateSingleForm(normalizedSchema, paths.containerDir, namespacedOptions).files
23541
23572
  },
23542
23573
  {
23543
23574
  name: "Single page",
23544
- run: () => generateSinglePage(normalizedSchema, paths.pagesDir, namespacedOptions).files
23575
+ run: () => generateSinglePage(normalizedSchema, paths.containerDir, namespacedOptions).files
23545
23576
  },
23546
23577
  {
23547
23578
  name: "Navigation",
@@ -24460,7 +24491,7 @@ async function maybeBuildRenamePlan(loaded, cwd, config, generatedFiles, options
24460
24491
  plan.customCells.push(
24461
24492
  buildCustomCellRenameSelection(
24462
24493
  loaded.schema.name,
24463
- paths.pagesDir,
24494
+ paths.containerDir,
24464
24495
  candidate.before,
24465
24496
  candidate.after
24466
24497
  )
@@ -25965,36 +25996,26 @@ function buildLeafField(input) {
25965
25996
  if (errors.length > 0) {
25966
25997
  throw new Error(errors.join("\n"));
25967
25998
  }
25968
- const field = {
25999
+ if (input.kind === "form") {
26000
+ return {
26001
+ name: input.name,
26002
+ type: input.type,
26003
+ label: input.label,
26004
+ ...input.required ? { required: true } : {},
26005
+ ...input.multiple && input.type === "file" ? { multiple: true } : {},
26006
+ ...input.options?.length ? { options: input.options } : {}
26007
+ };
26008
+ }
26009
+ return {
25969
26010
  name: input.name,
25970
26011
  type: input.type,
25971
- label: input.label
26012
+ label: input.label,
26013
+ ...input.required ? { required: true } : {},
26014
+ ...input.multiple && ["select", "relationship"].includes(input.type) ? { multiple: true } : {},
26015
+ ...input.creatable && input.type === "select" ? { creatable: true } : {},
26016
+ ...input.options?.length ? { options: input.options } : {},
26017
+ ...input.relationship && input.type === "relationship" ? { relationship: input.relationship } : {}
25972
26018
  };
25973
- if (input.required) {
25974
- field.required = true;
25975
- }
25976
- if (input.kind === "form") {
25977
- if (input.multiple && input.type === "file") {
25978
- field.multiple = true;
25979
- }
25980
- if (input.options && input.options.length > 0) {
25981
- field.options = input.options;
25982
- }
25983
- return field;
25984
- }
25985
- if (input.multiple && ["select", "relationship"].includes(input.type)) {
25986
- field.multiple = true;
25987
- }
25988
- if (input.creatable && input.type === "select") {
25989
- field.creatable = true;
25990
- }
25991
- if (input.options && input.options.length > 0) {
25992
- field.options = input.options;
25993
- }
25994
- if (input.relationship && input.type === "relationship") {
25995
- field.relationship = input.relationship;
25996
- }
25997
- return field;
25998
26019
  }
25999
26020
 
26000
26021
  // adapters/next/commands/schema-prompts/apply-advanced-options.ts
@@ -26112,14 +26133,12 @@ function applyDerivedFieldDefaults(field, type, options) {
26112
26133
  if (!options.derivePlaceholder) {
26113
26134
  return;
26114
26135
  }
26115
- const record = field;
26116
- if (typeof record.placeholder === "string" && record.placeholder.trim()) {
26136
+ if (typeof field.placeholder === "string" && field.placeholder.trim()) {
26117
26137
  return;
26118
26138
  }
26119
- const label = typeof record.label === "string" ? record.label : "";
26120
- const placeholder = derivePlaceholderFromLabel(type, label);
26139
+ const placeholder = derivePlaceholderFromLabel(type, field.label ?? "");
26121
26140
  if (placeholder) {
26122
- record.placeholder = placeholder;
26141
+ field.placeholder = placeholder;
26123
26142
  }
26124
26143
  }
26125
26144
 
@@ -29830,17 +29849,19 @@ function guardPackageJson(cwd, restores) {
29830
29849
  } catch {
29831
29850
  return { localSpecDeps: [], removedCliDep: false };
29832
29851
  }
29852
+ if (!isRecord(parsed)) {
29853
+ return { localSpecDeps: [], removedCliDep: false };
29854
+ }
29833
29855
  const localSpecDeps = [];
29834
29856
  let removedCliDep = false;
29835
29857
  for (const section of ["dependencies", "devDependencies"]) {
29836
29858
  const deps = parsed[section];
29837
- if (!deps || typeof deps !== "object") continue;
29838
- const record = deps;
29839
- if ("betterstart-cli" in record) {
29840
- Reflect.deleteProperty(record, "betterstart-cli");
29859
+ if (!isRecord(deps)) continue;
29860
+ if ("betterstart-cli" in deps) {
29861
+ Reflect.deleteProperty(deps, "betterstart-cli");
29841
29862
  removedCliDep = true;
29842
29863
  }
29843
- for (const [name, spec] of Object.entries(record)) {
29864
+ for (const [name, spec] of Object.entries(deps)) {
29844
29865
  if (typeof spec === "string" && LOCAL_PROTOCOL_PATTERN.test(spec)) {
29845
29866
  localSpecDeps.push(name);
29846
29867
  }
@@ -30007,13 +30028,12 @@ function parseRailwayJson(output) {
30007
30028
 
30008
30029
  // adapters/next/init/railway/resources/parse-service.ts
30009
30030
  function parseService(value) {
30010
- if (!value || typeof value !== "object") return void 0;
30011
- const service = value;
30012
- if (!isNonEmptyString(service.id) || !isNonEmptyString(service.name)) return void 0;
30013
- const replicas = service.replicas && typeof service.replicas === "object" ? service.replicas : void 0;
30031
+ if (!isRecord(value)) return void 0;
30032
+ if (!isNonEmptyString(value.id) || !isNonEmptyString(value.name)) return void 0;
30033
+ const replicas = isRecord(value.replicas) ? value.replicas : void 0;
30014
30034
  return {
30015
- id: service.id,
30016
- name: service.name,
30035
+ id: value.id,
30036
+ name: value.name,
30017
30037
  replicaCount: typeof replicas?.configured === "number" ? replicas.configured : void 0
30018
30038
  };
30019
30039
  }
@@ -30039,8 +30059,8 @@ ${result.stderr}`) ?? "Could not list Railway services."
30039
30059
  if (!Array.isArray(payload)) {
30040
30060
  throw new Error("Railway returned an invalid service list response.");
30041
30061
  }
30042
- const services = payload.map(parseService);
30043
- if (services.some((service) => !service)) {
30062
+ const services = payload.map(parseService).filter((service) => service !== void 0);
30063
+ if (services.length !== payload.length) {
30044
30064
  throw new Error("Railway returned an invalid service list response.");
30045
30065
  }
30046
30066
  return services;
@@ -30076,7 +30096,7 @@ function deploymentLine(line) {
30076
30096
  let message = line;
30077
30097
  try {
30078
30098
  const parsed = JSON.parse(line);
30079
- const jsonMessage = parsed.message ?? parsed.status;
30099
+ const jsonMessage = isRecord(parsed) ? parsed.message ?? parsed.status : void 0;
30080
30100
  if (typeof jsonMessage === "string") message = jsonMessage;
30081
30101
  } catch {
30082
30102
  }
@@ -30094,26 +30114,21 @@ function parseDomainUrl(value) {
30094
30114
  return void 0;
30095
30115
  }
30096
30116
  }
30097
- if (!value || typeof value !== "object") return void 0;
30098
- const record = value;
30099
- return parseDomainUrl(record.domain);
30117
+ return isRecord(value) ? parseDomainUrl(value.domain) : void 0;
30100
30118
  }
30101
30119
 
30102
30120
  // adapters/next/init/railway/deploy/first-domain-url.ts
30103
30121
  function firstDomainUrl(payload) {
30104
30122
  const direct = parseDomainUrl(payload);
30105
30123
  if (direct) return direct;
30106
- if (!payload || typeof payload !== "object") return void 0;
30107
- const domains = payload.domains;
30108
- return Array.isArray(domains) ? domains.map(parseDomainUrl).find((domain) => Boolean(domain)) : void 0;
30124
+ if (!isRecord(payload) || !Array.isArray(payload.domains)) return void 0;
30125
+ return payload.domains.map(parseDomainUrl).find((domain) => Boolean(domain));
30109
30126
  }
30110
30127
 
30111
30128
  // adapters/next/init/railway/deploy/parse-domain-list.ts
30112
30129
  function parseDomainList(payload) {
30113
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) return void 0;
30114
- const domains = payload.domains;
30115
- if (!Array.isArray(domains)) return void 0;
30116
- const parsed = domains.map(parseDomainUrl);
30130
+ if (!isRecord(payload) || !Array.isArray(payload.domains)) return void 0;
30131
+ const parsed = payload.domains.map(parseDomainUrl);
30117
30132
  return parsed.every((domain) => Boolean(domain)) ? parsed : void 0;
30118
30133
  }
30119
30134
 
@@ -30198,14 +30213,17 @@ ${result.stderr}`) ?? `Could not read Railway variables for ${service}.`
30198
30213
  );
30199
30214
  }
30200
30215
  const payload = parseRailwayJson(result.stdout);
30201
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
30216
+ if (!isRecord(payload)) {
30202
30217
  throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30203
30218
  }
30204
- const entries = Object.entries(payload);
30205
- if (entries.some(([, value]) => typeof value !== "string")) {
30206
- throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30219
+ const variables = {};
30220
+ for (const [name, value] of Object.entries(payload)) {
30221
+ if (typeof value !== "string") {
30222
+ throw new Error(`Railway returned an invalid variable list response for ${service}.`);
30223
+ }
30224
+ variables[name] = value;
30207
30225
  }
30208
- return Object.fromEntries(entries);
30226
+ return variables;
30209
30227
  }
30210
30228
 
30211
30229
  // adapters/next/init/railway/deploy/collect-railway-deploy-env-vars.ts
@@ -30412,32 +30430,18 @@ ${deploy.stderr}`) ?? deploy.errorMessage
30412
30430
 
30413
30431
  // adapters/next/init/railway/resources/parse-bucket-credentials.ts
30414
30432
  function parseBucketCredentials(value) {
30415
- if (!value || typeof value !== "object") return void 0;
30416
- const credentials = value;
30417
- const keys = [
30418
- "endpoint",
30419
- "accessKeyId",
30420
- "secretAccessKey",
30421
- "bucketName",
30422
- "region",
30423
- "urlStyle"
30424
- ];
30425
- if (!keys.every((key) => isNonEmptyString(credentials[key]))) return void 0;
30426
- return {
30427
- endpoint: credentials.endpoint,
30428
- accessKeyId: credentials.accessKeyId,
30429
- secretAccessKey: credentials.secretAccessKey,
30430
- bucketName: credentials.bucketName,
30431
- region: credentials.region,
30432
- urlStyle: credentials.urlStyle
30433
- };
30433
+ if (!isRecord(value)) return void 0;
30434
+ const { endpoint, accessKeyId, secretAccessKey, bucketName, region, urlStyle } = value;
30435
+ if (!isNonEmptyString(endpoint) || !isNonEmptyString(accessKeyId) || !isNonEmptyString(secretAccessKey) || !isNonEmptyString(bucketName) || !isNonEmptyString(region) || !isNonEmptyString(urlStyle)) {
30436
+ return void 0;
30437
+ }
30438
+ return { endpoint, accessKeyId, secretAccessKey, bucketName, region, urlStyle };
30434
30439
  }
30435
30440
 
30436
30441
  // adapters/next/init/railway/resources/parse-bucket.ts
30437
30442
  function parseBucket(value) {
30438
- if (!value || typeof value !== "object") return void 0;
30439
- const bucket = value;
30440
- return isNonEmptyString(bucket.id) && isNonEmptyString(bucket.name) ? { id: bucket.id, name: bucket.name } : void 0;
30443
+ if (!isRecord(value)) return void 0;
30444
+ return isNonEmptyString(value.id) && isNonEmptyString(value.name) ? { id: value.id, name: value.name } : void 0;
30441
30445
  }
30442
30446
 
30443
30447
  // adapters/next/init/railway/resources/provision-railway-bucket-resource.ts
@@ -30573,10 +30577,9 @@ import pc5 from "picocolors";
30573
30577
 
30574
30578
  // adapters/next/init/railway/auth/is-railway-account.ts
30575
30579
  function isRailwayAccount(value) {
30576
- if (!value || typeof value !== "object") return false;
30577
- const account = value;
30578
- return typeof account.email === "string" && Array.isArray(account.workspaces) && account.workspaces.every(
30579
- (workspace) => workspace !== null && typeof workspace === "object" && typeof workspace.id === "string" && typeof workspace.name === "string"
30580
+ if (!isRecord(value)) return false;
30581
+ return typeof value.email === "string" && Array.isArray(value.workspaces) && value.workspaces.every(
30582
+ (workspace) => isRecord(workspace) && typeof workspace.id === "string" && typeof workspace.name === "string"
30580
30583
  );
30581
30584
  }
30582
30585
 
@@ -30607,9 +30610,7 @@ async function checkRailwayProjectToken(runner, cwd, env) {
30607
30610
  return { authed: false, reason: result.timedOut ? "timeout" : "invalid-token" };
30608
30611
  }
30609
30612
  const project2 = parseRailwayJson(result.stdout);
30610
- if (!project2 || typeof project2 !== "object") return { authed: false, reason: "failed" };
30611
- const record = project2;
30612
- return typeof record.id === "string" && typeof record.name === "string" ? { authed: true } : { authed: false, reason: "failed" };
30613
+ return isRecord(project2) && typeof project2.id === "string" && typeof project2.name === "string" ? { authed: true } : { authed: false, reason: "failed" };
30613
30614
  }
30614
30615
 
30615
30616
  // adapters/next/init/railway/auth/ensure-railway-auth.ts
@@ -30686,18 +30687,14 @@ function isRailwayProjectNameConflict(detail) {
30686
30687
 
30687
30688
  // adapters/next/init/railway/project/parse-project-summary.ts
30688
30689
  function parseProjectSummary(value) {
30689
- if (!value || typeof value !== "object") return void 0;
30690
- const project2 = value;
30691
- if (!isNonEmptyString(project2.id) || !isNonEmptyString(project2.name)) return void 0;
30692
- const workspaceValue = project2.workspace;
30690
+ if (!isRecord(value)) return void 0;
30691
+ if (!isNonEmptyString(value.id) || !isNonEmptyString(value.name)) return void 0;
30692
+ const candidate = value.workspace;
30693
30693
  let workspace;
30694
- if (workspaceValue && typeof workspaceValue === "object") {
30695
- const candidate = workspaceValue;
30696
- if (isNonEmptyString(candidate.id) && isNonEmptyString(candidate.name)) {
30697
- workspace = { id: candidate.id, name: candidate.name };
30698
- }
30694
+ if (isRecord(candidate) && isNonEmptyString(candidate.id) && isNonEmptyString(candidate.name)) {
30695
+ workspace = { id: candidate.id, name: candidate.name };
30699
30696
  }
30700
- return { id: project2.id, name: project2.name, workspace };
30697
+ return { id: value.id, name: value.name, workspace };
30701
30698
  }
30702
30699
 
30703
30700
  // adapters/next/init/railway/project/railway-project-name-is-taken.ts
@@ -30735,9 +30732,7 @@ ${result.stderr}`);
30735
30732
 
30736
30733
  // adapters/next/init/railway/project/is-deleted-railway-project.ts
30737
30734
  function isDeletedRailwayProject(value) {
30738
- if (!value || typeof value !== "object") return false;
30739
- const deletedAt = value.deletedAt;
30740
- return isNonEmptyString(deletedAt);
30735
+ return isRecord(value) && isNonEmptyString(value.deletedAt);
30741
30736
  }
30742
30737
 
30743
30738
  // adapters/next/init/railway/project/list-railway-projects.ts
@@ -30757,8 +30752,9 @@ ${result.stderr}`) ?? "Could not list Railway projects."
30757
30752
  if (!Array.isArray(payload)) {
30758
30753
  throw new Error("Railway returned an invalid project list response.");
30759
30754
  }
30760
- const projects = payload.filter((project2) => !isDeletedRailwayProject(project2)).map(parseProjectSummary);
30761
- if (projects.some((project2) => !project2)) {
30755
+ const live = payload.filter((project2) => !isDeletedRailwayProject(project2));
30756
+ const projects = live.map(parseProjectSummary).filter((project2) => project2 !== void 0);
30757
+ if (projects.length !== live.length) {
30762
30758
  throw new Error("Railway returned an invalid project list response.");
30763
30759
  }
30764
30760
  return projects;
@@ -32246,7 +32242,9 @@ function scaffoldLayout({ cwd, config }) {
32246
32242
  readTemplate("pages/reset-password-form.tsx")
32247
32243
  );
32248
32244
  write(path74.join(config.paths.pages, "page.tsx"), readTemplate("pages/dashboard-page.tsx"));
32249
- const usersDir = path74.join(config.paths.pages, "users");
32245
+ const containerDir = path74.join(config.paths.pages, ADMIN_CONTAINER_ROUTE_GROUP);
32246
+ write(path74.join(containerDir, "layout.tsx"), readTemplate("pages/container-layout.tsx"));
32247
+ const usersDir = path74.join(containerDir, "users");
32250
32248
  write(path74.join(usersDir, "page.tsx"), readTemplate("pages/users/users-page.tsx"));
32251
32249
  write(
32252
32250
  path74.join(usersDir, "users-page-skeleton.tsx"),
@@ -32354,7 +32352,7 @@ function scaffoldLayout({ cwd, config }) {
32354
32352
  path74.join(settingsWebhooksDir, "logs", "page.tsx"),
32355
32353
  readTemplate("pages/settings/webhooks/webhooks-logs-page.tsx")
32356
32354
  );
32357
- const mediaDir = path74.join(config.paths.pages, "media");
32355
+ const mediaDir = path74.join(containerDir, "media");
32358
32356
  write(path74.join(mediaDir, "page.tsx"), readTemplate("pages/media/media-page.tsx"));
32359
32357
  write(
32360
32358
  path74.join(mediaDir, "media-page-skeleton.tsx"),
@@ -33343,8 +33341,12 @@ function scaffoldTsconfig(cwd, config) {
33343
33341
  skipped.push("Failed to parse tsconfig.json");
33344
33342
  return { added, skipped };
33345
33343
  }
33346
- const compilerOptions = tsconfig.compilerOptions ?? {};
33347
- const paths = compilerOptions.paths ?? {};
33344
+ if (!isRecord(tsconfig)) {
33345
+ skipped.push("Failed to parse tsconfig.json");
33346
+ return { added, skipped };
33347
+ }
33348
+ const compilerOptions = isRecord(tsconfig.compilerOptions) ? tsconfig.compilerOptions : {};
33349
+ const paths = isRecord(compilerOptions.paths) ? compilerOptions.paths : {};
33348
33350
  if (compilerOptions.resolveJsonModule === true) {
33349
33351
  skipped.push("compilerOptions.resolveJsonModule");
33350
33352
  } else {
@@ -33706,7 +33708,9 @@ function readLinkedProjectJson(cwd) {
33706
33708
  try {
33707
33709
  const projectJsonPath = path82.join(cwd, ".vercel", "project.json");
33708
33710
  if (!fs70.existsSync(projectJsonPath)) return void 0;
33709
- return JSON.parse(fs70.readFileSync(projectJsonPath, "utf-8"));
33711
+ const parsed = JSON.parse(fs70.readFileSync(projectJsonPath, "utf-8"));
33712
+ if (!isRecord(parsed)) return void 0;
33713
+ return typeof parsed.projectId === "string" ? { projectId: parsed.projectId } : {};
33710
33714
  } catch {
33711
33715
  return void 0;
33712
33716
  }
@@ -34478,11 +34482,11 @@ function parseIdList(value, isId, formatUnknownMessage) {
34478
34482
  return [];
34479
34483
  }
34480
34484
  const ids = value.split(",").map((entry) => entry.trim()).filter(Boolean);
34481
- const invalid = ids.filter((id) => !isId(id));
34482
- if (invalid.length > 0) {
34483
- throw new Error(formatUnknownMessage(invalid));
34485
+ const valid = ids.filter(isId);
34486
+ if (valid.length !== ids.length) {
34487
+ throw new Error(formatUnknownMessage(ids.filter((id) => !isId(id))));
34484
34488
  }
34485
- return unique(ids);
34489
+ return unique(valid);
34486
34490
  }
34487
34491
 
34488
34492
  // adapters/next/integration-runtime/parse-integration-list.ts
@@ -34643,7 +34647,7 @@ async function main() {
34643
34647
 
34644
34648
  if (CHECK_ADMIN_ONLY) {
34645
34649
  if (existingAdmin) {
34646
- console.log(\`EXISTING_ADMIN:\${JSON.stringify(existingAdmin)}\`)
34650
+ process.stdout.write(\`EXISTING_ADMIN:\${JSON.stringify(existingAdmin)}\\n\`)
34647
34651
  process.exit(3)
34648
34652
  }
34649
34653
  process.exit(0)
@@ -34654,7 +34658,7 @@ async function main() {
34654
34658
  const NAME = process.env.SEED_NAME || 'Admin'
34655
34659
 
34656
34660
  if (!EMAIL || !PASSWORD) {
34657
- console.error(' SEED_EMAIL and SEED_PASSWORD are required.')
34661
+ process.stderr.write(' SEED_EMAIL and SEED_PASSWORD are required.\\n')
34658
34662
  process.exit(1)
34659
34663
  }
34660
34664
 
@@ -34669,15 +34673,15 @@ async function main() {
34669
34673
 
34670
34674
  if (existingUser && !replaceTarget) {
34671
34675
  // Exit code 2 signals "user exists" to the CLI
34672
- console.log(\`EXISTING_USER:\${existingUser.name}\`)
34676
+ process.stdout.write(\`EXISTING_USER:\${existingUser.name}\\n\`)
34673
34677
  process.exit(2)
34674
34678
  }
34675
34679
 
34676
34680
  if (replaceTarget) {
34677
- console.log(
34681
+ process.stdout.write(
34678
34682
  OVERWRITE_MODE === 'admin'
34679
- ? '\\n Replacing existing admin user...'
34680
- : '\\n Replacing existing account...'
34683
+ ? '\\n Replacing existing admin user...\\n'
34684
+ : '\\n Replacing existing account...\\n'
34681
34685
  )
34682
34686
  await clearAuthorshipReferences(replaceTarget.id)
34683
34687
  // Remove existing account + session rows first (foreign key refs)
@@ -34685,17 +34689,17 @@ async function main() {
34685
34689
  await db.delete(schema.account).where(eq(schema.account.userId, replaceTarget.id))
34686
34690
  await db.delete(schema.user).where(eq(schema.user.id, replaceTarget.id))
34687
34691
  } else {
34688
- console.log('\\n Creating admin user...')
34692
+ process.stdout.write('\\n Creating admin user...\\n')
34689
34693
  }
34690
34694
 
34691
- console.log(\` Email: \${EMAIL}\\n\`)
34695
+ process.stdout.write(\` Email: \${EMAIL}\\n\\n\`)
34692
34696
 
34693
34697
  const result = await auth.api.signUpEmail({
34694
34698
  body: { email: EMAIL, password: PASSWORD, name: NAME },
34695
34699
  })
34696
34700
 
34697
34701
  if (!result?.user) {
34698
- console.error(' Failed to create user.')
34702
+ process.stderr.write(' Failed to create user.\\n')
34699
34703
  process.exit(1)
34700
34704
  }
34701
34705
 
@@ -34704,13 +34708,13 @@ async function main() {
34704
34708
  .set({ role: 'admin' })
34705
34709
  .where(eq(schema.user.id, result.user.id))
34706
34710
 
34707
- console.log(\` Admin user \${replaceTarget ? 'replaced' : 'created'}: \${EMAIL}\`)
34708
- console.log(' Role: admin\\n')
34711
+ process.stdout.write(\` Admin user \${replaceTarget ? 'replaced' : 'created'}: \${EMAIL}\\n\`)
34712
+ process.stdout.write(' Role: admin\\n\\n')
34709
34713
  process.exit(0)
34710
34714
  }
34711
34715
 
34712
34716
  main().catch((err) => {
34713
- console.error(' Seed failed:', err.message || err)
34717
+ process.stderr.write(\` Seed failed: \${err.message || err}\\n\`)
34714
34718
  process.exit(1)
34715
34719
  })
34716
34720
  `;
@@ -35232,7 +35236,7 @@ function writeInitJson(context, payload) {
35232
35236
  context.restoreStdout?.();
35233
35237
  context.restoreStdout = void 0;
35234
35238
  context.written = true;
35235
- console.log(JSON.stringify(payload, null, 2));
35239
+ writeMachineJson(payload);
35236
35240
  }
35237
35241
 
35238
35242
  // adapters/next/commands/init/run-init-command-internal.ts
@@ -35772,7 +35776,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35772
35776
  const drizzleConfigPath = path92.join(cwd, "drizzle.config.ts");
35773
35777
  if (!dbFiles.includes("drizzle.config.ts") && fs79.existsSync(drizzleConfigPath)) {
35774
35778
  if (forceMode) {
35775
- const { readNamespacedTemplate } = await import("./read-namespaced-template-D2CD4Q7U.js");
35779
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-KUENIIDC.js");
35776
35780
  fs79.writeFileSync(
35777
35781
  drizzleConfigPath,
35778
35782
  readNamespacedTemplate("drizzle.config.ts", namespace),
@@ -35785,7 +35789,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35785
35789
  initialValue: true
35786
35790
  });
35787
35791
  if (!p61.isCancel(overwrite) && overwrite) {
35788
- const { readNamespacedTemplate } = await import("./read-namespaced-template-D2CD4Q7U.js");
35792
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-KUENIIDC.js");
35789
35793
  fs79.writeFileSync(
35790
35794
  drizzleConfigPath,
35791
35795
  readNamespacedTemplate("drizzle.config.ts", namespace),
@@ -36218,7 +36222,7 @@ async function runListIntegrationsCommand(options) {
36218
36222
  try {
36219
36223
  installed2 = new Set((await resolveConfig(cwd)).integrations.installed);
36220
36224
  } catch (error) {
36221
- console.error(
36225
+ writeDiagnostic(
36222
36226
  `Error loading config: ${error instanceof Error ? error.message : String(error)}`
36223
36227
  );
36224
36228
  process.exit(1);
@@ -36229,7 +36233,7 @@ async function runListIntegrationsCommand(options) {
36229
36233
  kind: integration.kind,
36230
36234
  description: integration.description
36231
36235
  }));
36232
- console.log(JSON.stringify(items, null, 2));
36236
+ writeMachineJson(items);
36233
36237
  return;
36234
36238
  }
36235
36239
  const config = await resolveConfigOrExit(cwd);
@@ -36263,7 +36267,7 @@ async function runListPresetsCommand(options) {
36263
36267
  try {
36264
36268
  installed2 = new Set((await resolveConfig(cwd)).presets.installed);
36265
36269
  } catch (error) {
36266
- console.error(
36270
+ writeDiagnostic(
36267
36271
  `Error loading config: ${error instanceof Error ? error.message : String(error)}`
36268
36272
  );
36269
36273
  process.exit(1);
@@ -36274,7 +36278,7 @@ async function runListPresetsCommand(options) {
36274
36278
  kind: preset.kind,
36275
36279
  description: preset.description
36276
36280
  }));
36277
- console.log(JSON.stringify(items, null, 2));
36281
+ writeMachineJson(items);
36278
36282
  return;
36279
36283
  }
36280
36284
  const config = await resolveConfigOrExit(cwd);
@@ -38010,6 +38014,11 @@ var TEMPLATE_REGISTRY = {
38010
38014
  base: "cwd",
38011
38015
  dependencies: ["auth-gate"]
38012
38016
  },
38017
+ "container-layout": {
38018
+ relPath: "app/(admin)/admin/(authenticated)/(container)/layout.tsx",
38019
+ content: () => readTemplate("pages/container-layout.tsx"),
38020
+ base: "cwd"
38021
+ },
38013
38022
  "auth-gate": {
38014
38023
  relPath: "app/(admin)/admin/(authenticated)/auth-gate.tsx",
38015
38024
  content: () => readTemplate("pages/auth-gate.tsx"),
@@ -39175,15 +39184,15 @@ async function runRemoveSchemaCommand(schemaName, options) {
39175
39184
  if (removePath(cwd, `${paths.adminActionsDir}/${schemaName}`)) {
39176
39185
  deletedPaths.push(`${paths.adminActionsDir}/${schemaName}`);
39177
39186
  }
39178
- if (removePath(cwd, `${paths.pagesDir}/forms/${kebabName}`)) {
39179
- deletedPaths.push(`${paths.pagesDir}/forms/${kebabName}`);
39187
+ if (removePath(cwd, `${paths.containerDir}/forms/${kebabName}`)) {
39188
+ deletedPaths.push(`${paths.containerDir}/forms/${kebabName}`);
39180
39189
  }
39181
39190
  } else {
39182
39191
  if (removePath(cwd, `${paths.adminActionsDir}/${schemaName}`)) {
39183
39192
  deletedPaths.push(`${paths.adminActionsDir}/${schemaName}`);
39184
39193
  }
39185
- if (removePath(cwd, `${paths.pagesDir}/${schemaName}`)) {
39186
- deletedPaths.push(`${paths.pagesDir}/${schemaName}`);
39194
+ if (removePath(cwd, `${paths.containerDir}/${schemaName}`)) {
39195
+ deletedPaths.push(`${paths.containerDir}/${schemaName}`);
39187
39196
  }
39188
39197
  }
39189
39198
  cleanupSchemaEmptyDirs(cwd, deletedPaths, paths);
@@ -39426,21 +39435,18 @@ function collectSchemaRelationshipTargets(loaded) {
39426
39435
  function walkFields2(fields) {
39427
39436
  if (!Array.isArray(fields)) return;
39428
39437
  for (const field of fields) {
39429
- if (!field || typeof field !== "object") {
39438
+ if (!isRecord(field)) {
39430
39439
  continue;
39431
39440
  }
39432
- const fieldRecord = field;
39433
- const relationship = typeof fieldRecord.relationship === "string" ? fieldRecord.relationship : void 0;
39434
- if (relationship) {
39435
- targets.add(relationship);
39441
+ if (typeof field.relationship === "string") {
39442
+ targets.add(field.relationship);
39436
39443
  }
39437
- walkFields2(fieldRecord.fields);
39438
- if (Array.isArray(fieldRecord.tabs)) {
39439
- for (const tab of fieldRecord.tabs) {
39440
- if (!tab || typeof tab !== "object") {
39441
- continue;
39444
+ walkFields2(field.fields);
39445
+ if (Array.isArray(field.tabs)) {
39446
+ for (const tab of field.tabs) {
39447
+ if (isRecord(tab)) {
39448
+ walkFields2(tab.fields);
39442
39449
  }
39443
- walkFields2(tab.fields);
39444
39450
  }
39445
39451
  }
39446
39452
  }
@@ -39964,8 +39970,9 @@ function cleanTsconfig(tsconfigPath, aliasRoot = "@admin") {
39964
39970
  } catch {
39965
39971
  return [];
39966
39972
  }
39967
- const compilerOptions = tsconfig.compilerOptions ?? {};
39968
- const paths = compilerOptions.paths ?? {};
39973
+ if (!isRecord(tsconfig)) return [];
39974
+ const compilerOptions = isRecord(tsconfig.compilerOptions) ? tsconfig.compilerOptions : {};
39975
+ const paths = isRecord(compilerOptions.paths) ? compilerOptions.paths : {};
39969
39976
  const removed = [];
39970
39977
  for (const key of Object.keys(paths)) {
39971
39978
  if (key.startsWith("@admin/") || key === "@admin/*" || key.startsWith(`${aliasRoot}/`) || key === `${aliasRoot}/*`) {
@@ -40482,7 +40489,7 @@ async function runUpdateCommand(components, options) {
40482
40489
  ...templateKeys.map((name) => ({ name, path: templatePath(name), kind: "template" })),
40483
40490
  { name: "tiptap", path: "components/custom/content-editor/tiptap-*/", kind: "special" }
40484
40491
  ];
40485
- console.log(JSON.stringify(items, null, 2));
40492
+ writeMachineJson(items);
40486
40493
  return;
40487
40494
  }
40488
40495
  const all = getAllComponentNames();