@bobbykim/manguito-cms-cli 0.9.0 → 0.10.0

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.
@@ -25075,6 +25075,7 @@ function findSchemaDeprecations(registry2) {
25075
25075
  ...Object.values(registry2.paragraph_types)
25076
25076
  ];
25077
25077
  for (const owner of owners) {
25078
+ const instead = owner.schema_type === "paragraph-type" ? 'Use "one-to-one": a paragraph type cannot hold a many-to-many reference.' : 'Use "one-to-one" for a single item, or "many-to-many" for a list.';
25078
25079
  for (const field of owner.fields) {
25079
25080
  if (field.field_type !== "reference") continue;
25080
25081
  const c = field.ui_component;
@@ -25083,7 +25084,7 @@ function findSchemaDeprecations(registry2) {
25083
25084
  source_file: owner.source_file,
25084
25085
  type_name: owner.name,
25085
25086
  field_name: field.name,
25086
- message: `${owner.name}.${field.name} uses "one-to-many", which is deprecated for references. It holds a single item, the same as "one-to-one". Use "one-to-one" for a single item, or "many-to-many" for a list.`
25087
+ message: `${owner.name}.${field.name} uses "one-to-many", which is deprecated for references. It holds a single item, the same as "one-to-one". ${instead}`
25087
25088
  });
25088
25089
  }
25089
25090
  }
@@ -25306,11 +25307,27 @@ function validateCrossReferences(registry2, globalMaxFileSize) {
25306
25307
  errors.push(...checkDuplicateSchemaNames(registry2.all_schemas));
25307
25308
  errors.push(...checkFieldRefs(registry2));
25308
25309
  errors.push(...checkCircularParagraphRefs(registry2));
25310
+ errors.push(...checkParagraphRelations(registry2));
25309
25311
  if (globalMaxFileSize !== void 0) {
25310
25312
  errors.push(...checkMaxSizeLimit(registry2, globalMaxFileSize));
25311
25313
  }
25312
25314
  return errors;
25313
25315
  }
25316
+ function checkParagraphRelations(registry2) {
25317
+ const errors = [];
25318
+ for (const paragraph of Object.values(registry2.paragraph_types)) {
25319
+ for (const field of paragraph.fields) {
25320
+ if (field.field_type !== "reference" || !field.db_column?.junction) continue;
25321
+ errors.push({
25322
+ file: paragraph.source_file,
25323
+ code: "UNSUPPORTED_RELATION",
25324
+ message: `Field "${field.name}" in "${paragraph.name}" is a many-to-many reference, which paragraph types do not support: a paragraph belongs to one parent and is replaced on every save, so it cannot own links. For a single item, use "rel": "one-to-one". For a list, put the many-to-many field on the content or taxonomy type this paragraph appears in, or make the paragraph field that embeds it "one-to-many" with a "one-to-one" reference in each item.`,
25325
+ path: `fields[${field.order}].rel`
25326
+ });
25327
+ }
25328
+ }
25329
+ return errors;
25330
+ }
25314
25331
  function checkDuplicateSchemaNames(allSchemas) {
25315
25332
  const errors = [];
25316
25333
  const seen = /* @__PURE__ */ new Map();
@@ -12,7 +12,7 @@ import {
12
12
  isColumnBacked,
13
13
  relationCardinality,
14
14
  resolveRelationField
15
- } from "./chunk-L36JYVXK.js";
15
+ } from "./chunk-X7D2QPPO.js";
16
16
 
17
17
  // ../../node_modules/.pnpm/@whatwg-node+fetch@0.10.13/node_modules/@whatwg-node/fetch/dist/shouldSkipPonyfill.js
18
18
  var require_shouldSkipPonyfill = __commonJS({
package/dist/index.js CHANGED
@@ -54,7 +54,7 @@ import {
54
54
  validateCrossReferences,
55
55
  verifyPassword,
56
56
  walkSchemaDirectory
57
- } from "./chunk-L36JYVXK.js";
57
+ } from "./chunk-X7D2QPPO.js";
58
58
 
59
59
  // ../../node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js
60
60
  var require_postgres_array = __commonJS({
@@ -17530,11 +17530,18 @@ function fieldToZodSchema(field, registry) {
17530
17530
  return "z.unknown()";
17531
17531
  }
17532
17532
  }
17533
+ function acceptsNull(f) {
17534
+ if (relationCardinality(f) === "many") return false;
17535
+ return f.db_column ? f.db_column.nullable : f.nullable;
17536
+ }
17537
+ function fieldEntrySchema(f, registry) {
17538
+ let s = fieldToZodSchema(f, registry);
17539
+ if (acceptsNull(f)) s += ".nullable()";
17540
+ if (!f.required) s += ".optional()";
17541
+ return s;
17542
+ }
17533
17543
  function generateParagraphObjectSchema(paragraph, registry) {
17534
- const entries = paragraph.fields.map((f) => {
17535
- const zodType = fieldToZodSchema(f, registry);
17536
- return `${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
17537
- });
17544
+ const entries = paragraph.fields.map((f) => `${f.name}: ${fieldEntrySchema(f, registry)}`);
17538
17545
  if (entries.length === 0) return "z.object({})";
17539
17546
  return `z.object({ ${entries.join(", ")} })`;
17540
17547
  }
@@ -17549,10 +17556,7 @@ function systemFieldEntries(schema) {
17549
17556
  return entries;
17550
17557
  }
17551
17558
  function schemaFieldEntries(fields, registry) {
17552
- return fields.map((f) => {
17553
- const zodType = fieldToZodSchema(f, registry);
17554
- return ` ${f.name}: ${f.required ? zodType : `${zodType}.optional()`}`;
17555
- });
17559
+ return fields.map((f) => ` ${f.name}: ${fieldEntrySchema(f, registry)}`);
17556
17560
  }
17557
17561
  function generateContentSchema(schema, registry) {
17558
17562
  const name = schemaVar(schema.name);
@@ -17615,6 +17619,10 @@ var ADMIN_LIST_QUERY = `z.object({
17615
17619
  })`;
17616
17620
  var SLUG_PARAMS = `z.object({ slug: z.string() })`;
17617
17621
  var ID_PARAMS = `z.object({ id: z.string().uuid() })`;
17622
+ var ITEM_IN_USE_RESPONSE = `{
17623
+ content: { 'application/json': { schema: ErrorResponseSchema } },
17624
+ description: 'ITEM_IN_USE: a required reference elsewhere still points at this item',
17625
+ }`;
17618
17626
  var INCLUDE_QUERY = `z.object({ include: z.string().optional().describe('Comma-separated relation field names to expand') })`;
17619
17627
  function generateContentRoutes(contentType) {
17620
17628
  const sVar = schemaVar(contentType.name);
@@ -17774,6 +17782,7 @@ function generateContentRoutes(contentType) {
17774
17782
  content: { 'application/json': { schema: ErrorResponseSchema } },
17775
17783
  description: '${label} not found',
17776
17784
  },
17785
+ 409: ${ITEM_IN_USE_RESPONSE},
17777
17786
  },
17778
17787
  })`
17779
17788
  );
@@ -18035,6 +18044,7 @@ function generateTaxonomyRoutes(taxonomyType) {
18035
18044
  content: { 'application/json': { schema: ErrorResponseSchema } },
18036
18045
  description: '${label} not found',
18037
18046
  },
18047
+ 409: ${ITEM_IN_USE_RESPONSE},
18038
18048
  },
18039
18049
  })`
18040
18050
  );
@@ -18711,6 +18721,11 @@ async function runBuild(options, deps) {
18711
18721
  parsedRoles
18712
18722
  );
18713
18723
  printSchemaDeprecations(findSchemaDeprecations(registry));
18724
+ const crossRefErrors = validateCrossReferences(registry, config2.api.media?.max_file_size);
18725
+ if (crossRefErrors.length > 0) {
18726
+ printValidationErrors(crossRefErrors, "Schema reference errors", "manguito build");
18727
+ process.exit(1);
18728
+ }
18714
18729
  const versions = loadProjectVersionModel(resolveSchemaConfig(cwd, config2), registry);
18715
18730
  if (!versions.ok) {
18716
18731
  printValidationErrors(versions.errors, "Version model errors", "manguito build");
@@ -24594,7 +24609,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
24594
24609
  }
24595
24610
  var API_VERSION = (() => {
24596
24611
  try {
24597
- return "0.8.2";
24612
+ return "0.8.4";
24598
24613
  } catch {
24599
24614
  return "0.0.0";
24600
24615
  }
@@ -25277,7 +25292,7 @@ function createCmsApp(options) {
25277
25292
  handler: null,
25278
25293
  error: null
25279
25294
  }));
25280
- const ready = import("./handler-VEOWJRAL-6WUFNANJ.js").then(({ createGraphQLHandler }) => {
25295
+ const ready = import("./handler-VEOWJRAL-OU66YS5U.js").then(({ createGraphQLHandler }) => {
25281
25296
  gqlPasses.forEach((pass, i) => {
25282
25297
  const mount = mounts[i];
25283
25298
  try {
@@ -25556,6 +25571,11 @@ async function runDev(options, deps) {
25556
25571
  const drizzleConfigPath = resolve6(manguitoDir, "drizzle.config.ts");
25557
25572
  const needsSeed = !await db.tableExists("users");
25558
25573
  const bootstrapRegistry = await parseAllSchemas(cwd, config2);
25574
+ const crossRefErrors = validateCrossReferences(bootstrapRegistry, config2.api.media?.max_file_size);
25575
+ if (crossRefErrors.length > 0) {
25576
+ printValidationErrors(crossRefErrors, "Schema reference errors", "manguito validate");
25577
+ process.exit(1);
25578
+ }
25559
25579
  await generateDrizzleConfig(config2, manguitoDir);
25560
25580
  await writeFile9(join11(manguitoDir, "schema.ts"), generateSchemaFile(bootstrapRegistry), "utf8");
25561
25581
  await runDevMigration(drizzleConfigPath);
@@ -25743,6 +25763,12 @@ async function onSchemaFileChange(args) {
25743
25763
  process.stderr.write("\u26A0 Schema parse error \u2014 changes not applied.\n");
25744
25764
  return;
25745
25765
  }
25766
+ const crossRefErrors = validateCrossReferences(registry, config2.api.media?.max_file_size);
25767
+ if (crossRefErrors.length > 0) {
25768
+ printValidationErrors(crossRefErrors, "Schema reference errors", "manguito validate");
25769
+ process.stderr.write("\u26A0 Changes not applied.\n");
25770
+ return;
25771
+ }
25746
25772
  await generateDrizzleConfig(config2, manguitoDir);
25747
25773
  await writeFile9(join11(manguitoDir, "schema.ts"), generateSchemaFile(registry), "utf8");
25748
25774
  await generateSchemaRegistry(registry, manguitoDir);
@@ -26534,7 +26560,13 @@ function loadWorkingRegistry(cwd, config2, command) {
26534
26560
  printValidationErrors(allErrors, "Schema parse errors", command);
26535
26561
  process.exit(1);
26536
26562
  }
26537
- return buildSchemaRegistry(parsedSchemas, parsedRoutes, parsedRoles);
26563
+ const registry = buildSchemaRegistry(parsedSchemas, parsedRoutes, parsedRoles);
26564
+ const crossRefErrors = validateCrossReferences(registry, config2.api.media?.max_file_size);
26565
+ if (crossRefErrors.length > 0) {
26566
+ printValidationErrors(crossRefErrors, "Schema reference errors", command);
26567
+ process.exit(1);
26568
+ }
26569
+ return registry;
26538
26570
  }
26539
26571
 
26540
26572
  // src/commands/version-report.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobbykim/manguito-cms-cli",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "license": "MIT",
5
5
  "author": "Bobby Kim <bobby.sihun.kim@gmail.com>",
6
6
  "homepage": "https://github.com/bobbykim89/manguito-cms",
@@ -29,10 +29,10 @@
29
29
  "tsup": "^8.5.1",
30
30
  "typescript": "^6.0.3",
31
31
  "vite": "^8.1.3",
32
- "@bobbykim/manguito-cms-admin": "0.5.2",
33
- "@bobbykim/manguito-cms-api": "0.8.2",
34
- "@bobbykim/manguito-cms-db": "0.1.8",
35
- "@bobbykim/manguito-cms-core": "0.8.0"
32
+ "@bobbykim/manguito-cms-admin": "0.5.3",
33
+ "@bobbykim/manguito-cms-api": "0.8.4",
34
+ "@bobbykim/manguito-cms-core": "0.9.0",
35
+ "@bobbykim/manguito-cms-db": "0.1.9"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^25.9.5",
@@ -43,7 +43,7 @@
43
43
  "build": "tsup",
44
44
  "dev": "tsup --watch",
45
45
  "test": "dotenv -e ../../.env.test -- vitest run",
46
- "lint": "eslint src",
46
+ "lint": "eslint src tests",
47
47
  "typecheck": "tsc --noEmit"
48
48
  }
49
49
  }