@bobbykim/manguito-cms-api 0.8.1 → 0.8.3

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/index.js CHANGED
@@ -2506,6 +2506,46 @@ async function loadParagraphRows(db, registry, pType, parentId, fieldName) {
2506
2506
  }
2507
2507
  return rows;
2508
2508
  }
2509
+ async function loadRelationsForEdit(db, registry, fields, id, row) {
2510
+ for (const f of fields) {
2511
+ if (f.db_column === null) {
2512
+ const comp = f.ui_component;
2513
+ if (comp.component !== "paragraph-embed" || !comp.ref) continue;
2514
+ const pType = registry.paragraph_types[comp.ref];
2515
+ if (!pType) continue;
2516
+ row[f.name] = oneOrMany((0, import_manguito_cms_core4.relationCardinality)(f) ?? "many", await loadParagraphRows(db, registry, pType, id, f.name));
2517
+ } else if (f.db_column.junction) {
2518
+ const j = f.db_column.junction;
2519
+ const r = await db.execute(
2520
+ import_drizzle_orm5.sql`SELECT ${import_drizzle_orm5.sql.raw(quoteIdent4(j.right_column))} FROM ${import_drizzle_orm5.sql.raw(quoteIdent4(j.table_name))} WHERE ${import_drizzle_orm5.sql.raw(quoteIdent4(j.left_column))} = ${id}`
2521
+ );
2522
+ row[f.name] = r.rows.map((linked) => linked[j.right_column]);
2523
+ }
2524
+ }
2525
+ }
2526
+ async function valuesForPublishCheck(db, registry, requiredFields, id, storedLabels, body) {
2527
+ const stored = { ...storedLabels };
2528
+ if (db) await loadRelationsForEdit(db, registry, requiredFields.filter((f) => !(f.name in body)), id, stored);
2529
+ return { ...stored, ...body };
2530
+ }
2531
+ async function persistRelationFields(db, registry, fields, body, itemId, ownerTable) {
2532
+ const deltas = [];
2533
+ for (const f of fields) {
2534
+ if (!(f.name in body)) continue;
2535
+ if (f.db_column === null) {
2536
+ const comp = f.ui_component;
2537
+ if (comp.component !== "paragraph-embed" || !comp.ref) continue;
2538
+ const pType = registry.paragraph_types[comp.ref];
2539
+ if (!pType) continue;
2540
+ deltas.push(await persistParagraphField(db, itemId, ownerTable, f.name, pType, paragraphItems(f, body[f.name]), registry));
2541
+ } else if (f.db_column.junction) {
2542
+ const value = body[f.name];
2543
+ const relatedIds = Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
2544
+ await persistJunctionField(db, itemId, f.db_column.junction, relatedIds);
2545
+ }
2546
+ }
2547
+ return deltas;
2548
+ }
2509
2549
  async function lookupBasePathId(db, pathOrName) {
2510
2550
  const r = await db.execute(
2511
2551
  import_drizzle_orm5.sql`SELECT id FROM base_paths WHERE path = ${pathOrName} OR name = ${pathOrName} LIMIT 1`
@@ -2661,26 +2701,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2661
2701
  404
2662
2702
  );
2663
2703
  }
2664
- if (db) {
2665
- const row = item;
2666
- for (const f of contentType.fields) {
2667
- if (f.db_column === null) {
2668
- const comp = f.ui_component;
2669
- if (comp.component !== "paragraph-embed" || !comp.ref) continue;
2670
- const pType = registry.paragraph_types[comp.ref];
2671
- if (!pType) continue;
2672
- row[f.name] = oneOrMany((0, import_manguito_cms_core4.relationCardinality)(f) ?? "many", await loadParagraphRows(db, registry, pType, id, f.name));
2673
- } else if (f.db_column.junction) {
2674
- const j = f.db_column.junction;
2675
- const r = await db.execute(
2676
- import_drizzle_orm5.sql`SELECT ${import_drizzle_orm5.sql.raw(quoteIdent4(j.right_column))} FROM ${import_drizzle_orm5.sql.raw(quoteIdent4(j.table_name))} WHERE ${import_drizzle_orm5.sql.raw(quoteIdent4(j.left_column))} = ${id}`
2677
- );
2678
- row[f.name] = r.rows.map(
2679
- (row2) => row2[j.right_column]
2680
- );
2681
- }
2682
- }
2683
- }
2704
+ if (db) await loadRelationsForEdit(db, registry, contentType.fields, id, item);
2684
2705
  const data = projectRow(item, typeName, projectors);
2685
2706
  return c.json({ ok: true, data });
2686
2707
  }
@@ -2771,10 +2792,6 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2771
2792
  });
2772
2793
  if (publishDeny) return publishDeny;
2773
2794
  }
2774
- const paragraphFields = contentType.fields.filter((f) => f.db_column === null);
2775
- const junctionFields = contentType.fields.filter(
2776
- (f) => f.db_column !== null && f.db_column.junction !== void 0
2777
- );
2778
2795
  const columnBackedFields = contentType.fields.filter(isColumnBacked);
2779
2796
  const columnData = {
2780
2797
  published: body["published"] ?? false
@@ -2809,19 +2826,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2809
2826
  const itemId = item["id"];
2810
2827
  const mediaDeltas = [topLevelMediaDelta(mediaFields, null, storageBody)];
2811
2828
  if (db) {
2812
- for (const f of paragraphFields) {
2813
- const comp = f.ui_component;
2814
- if (comp.component !== "paragraph-embed" || !comp.ref) continue;
2815
- const pType = registry.paragraph_types[comp.ref];
2816
- if (!pType) continue;
2817
- const items = paragraphItems(f, body[f.name]);
2818
- mediaDeltas.push(await persistParagraphField(db, itemId, contentType.db.table_name, f.name, pType, items, registry));
2819
- }
2820
- for (const f of junctionFields) {
2821
- const junction = f.db_column.junction;
2822
- const relatedIds = Array.isArray(body[f.name]) ? body[f.name].filter((v) => typeof v === "string") : [];
2823
- await persistJunctionField(db, itemId, junction, relatedIds);
2824
- }
2829
+ mediaDeltas.push(...await persistRelationFields(db, registry, contentType.fields, body, itemId, contentType.db.table_name));
2825
2830
  }
2826
2831
  await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
2827
2832
  const data = projectRow(item, typeName, projectors);
@@ -2892,7 +2897,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2892
2897
  const publishDeny = await requirePermission("content:edit")(c, async () => {
2893
2898
  });
2894
2899
  if (publishDeny) return publishDeny;
2895
- const merged = { ...fieldKeys.toLabels(existing), ...body };
2900
+ const merged = await valuesForPublishCheck(db, registry, requiredFields, id, fieldKeys.toLabels(existing), body);
2896
2901
  const fieldErrors = checkRequiredFields(requiredFields, merged);
2897
2902
  if (fieldErrors.length > 0) {
2898
2903
  return c.json(
@@ -2908,10 +2913,6 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2908
2913
  );
2909
2914
  }
2910
2915
  }
2911
- const patchParagraphFields = contentType.fields.filter((f) => f.db_column === null);
2912
- const patchJunctionFields = contentType.fields.filter(
2913
- (f) => f.db_column !== null && f.db_column.junction !== void 0
2914
- );
2915
2916
  const patchColumnBackedFields = contentType.fields.filter(isColumnBacked);
2916
2917
  const patchData = {};
2917
2918
  if (!contentType.only_one && "slug" in body) patchData["slug"] = body["slug"];
@@ -2932,21 +2933,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
2932
2933
  topLevelMediaDelta(mediaFields, existing, storageBody)
2933
2934
  ];
2934
2935
  if (db) {
2935
- for (const f of patchParagraphFields) {
2936
- if (!(f.name in body)) continue;
2937
- const comp = f.ui_component;
2938
- if (comp.component !== "paragraph-embed" || !comp.ref) continue;
2939
- const pType = registry.paragraph_types[comp.ref];
2940
- if (!pType) continue;
2941
- const items = paragraphItems(f, body[f.name]);
2942
- mediaDeltas.push(await persistParagraphField(db, id, contentType.db.table_name, f.name, pType, items, registry));
2943
- }
2944
- for (const f of patchJunctionFields) {
2945
- if (!(f.name in body)) continue;
2946
- const junction = f.db_column.junction;
2947
- const relatedIds = Array.isArray(body[f.name]) ? body[f.name].filter((v) => typeof v === "string") : [];
2948
- await persistJunctionField(db, id, junction, relatedIds);
2949
- }
2936
+ mediaDeltas.push(...await persistRelationFields(db, registry, contentType.fields, body, id, contentType.db.table_name));
2950
2937
  }
2951
2938
  await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
2952
2939
  const data = projectRow(updated, typeName, projectors);
@@ -3075,6 +3062,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3075
3062
  404
3076
3063
  );
3077
3064
  }
3065
+ if (db) await loadRelationsForEdit(db, registry, taxonomyType.fields, id, item);
3078
3066
  const data = projectRow(item, typeName, projectors);
3079
3067
  return c.json({ ok: true, data });
3080
3068
  }
@@ -3106,7 +3094,6 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3106
3094
  });
3107
3095
  if (publishDeny) return publishDeny;
3108
3096
  }
3109
- const taxParagraphFields = taxonomyType.fields.filter((f) => f.db_column === null);
3110
3097
  const taxColumnBackedFields = taxonomyType.fields.filter(isColumnBacked);
3111
3098
  const taxColumnData = {
3112
3099
  published: body["published"] ?? false
@@ -3120,14 +3107,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3120
3107
  const taxItemId = item["id"];
3121
3108
  const mediaDeltas = [topLevelMediaDelta(mediaFields, null, storageBody)];
3122
3109
  if (db) {
3123
- for (const f of taxParagraphFields) {
3124
- const comp = f.ui_component;
3125
- if (comp.component !== "paragraph-embed" || !comp.ref) continue;
3126
- const pType = registry.paragraph_types[comp.ref];
3127
- if (!pType) continue;
3128
- const items = paragraphItems(f, body[f.name]);
3129
- mediaDeltas.push(await persistParagraphField(db, taxItemId, taxonomyType.db.table_name, f.name, pType, items, registry));
3130
- }
3110
+ mediaDeltas.push(...await persistRelationFields(db, registry, taxonomyType.fields, body, taxItemId, taxonomyType.db.table_name));
3131
3111
  }
3132
3112
  await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
3133
3113
  const data = projectRow(item, typeName, projectors);
@@ -3154,7 +3134,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3154
3134
  const publishDeny = await requirePermission("content:edit")(c, async () => {
3155
3135
  });
3156
3136
  if (publishDeny) return publishDeny;
3157
- const merged = { ...fieldKeys.toLabels(existing), ...body };
3137
+ const merged = await valuesForPublishCheck(db, registry, requiredFields, id, fieldKeys.toLabels(existing), body);
3158
3138
  const fieldErrors = checkRequiredFields(requiredFields, merged);
3159
3139
  if (fieldErrors.length > 0) {
3160
3140
  return c.json(
@@ -3170,7 +3150,6 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3170
3150
  );
3171
3151
  }
3172
3152
  }
3173
- const taxPatchParagraphFields = taxonomyType.fields.filter((f) => f.db_column === null);
3174
3153
  const taxPatchColumnBackedFields = taxonomyType.fields.filter(isColumnBacked);
3175
3154
  const taxPatchData = {};
3176
3155
  if ("published" in body) taxPatchData["published"] = body["published"];
@@ -3190,15 +3169,7 @@ function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo,
3190
3169
  topLevelMediaDelta(mediaFields, existing, storageBody)
3191
3170
  ];
3192
3171
  if (db) {
3193
- for (const f of taxPatchParagraphFields) {
3194
- if (!(f.name in body)) continue;
3195
- const comp = f.ui_component;
3196
- if (comp.component !== "paragraph-embed" || !comp.ref) continue;
3197
- const pType = registry.paragraph_types[comp.ref];
3198
- if (!pType) continue;
3199
- const items = paragraphItems(f, body[f.name]);
3200
- mediaDeltas.push(await persistParagraphField(db, id, taxonomyType.db.table_name, f.name, pType, items, registry));
3201
- }
3172
+ mediaDeltas.push(...await persistRelationFields(db, registry, taxonomyType.fields, body, id, taxonomyType.db.table_name));
3202
3173
  }
3203
3174
  await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
3204
3175
  const data = projectRow(updated, typeName, projectors);
@@ -4205,7 +4176,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
4205
4176
  var import_drizzle_orm8 = require("drizzle-orm");
4206
4177
  var API_VERSION = (() => {
4207
4178
  try {
4208
- return "0.8.1";
4179
+ return "0.8.3";
4209
4180
  } catch {
4210
4181
  return "0.0.0";
4211
4182
  }