@bobbykim/manguito-cms-api 0.6.0 → 0.7.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.
@@ -269,29 +269,22 @@ function scalarFieldResolver(field, fallback) {
269
269
  function relationFieldResolver(typeName, schemaFieldName) {
270
270
  return (parent, _args, ctx) => ctx.loaders.load(typeName, schemaFieldName, parent);
271
271
  }
272
- function programmaticFieldResolver(typeName, schemaFieldName, mediaFields = [], fieldKeys) {
272
+ function programmaticFieldResolver(typeName, schemaFieldName, mediaFieldNames = [], fieldKeys) {
273
273
  return async (parent, _args, ctx) => {
274
274
  let p = ctx.programmaticMemo.get(parent);
275
275
  if (!p) {
276
- p = resolveProgrammaticRow(typeName, parent, ctx, mediaFields, fieldKeys);
276
+ p = resolveProgrammaticRow(typeName, parent, ctx, mediaFieldNames, fieldKeys);
277
277
  ctx.programmaticMemo.set(parent, p);
278
278
  }
279
279
  return (await p)[schemaFieldName];
280
280
  };
281
281
  }
282
- async function resolveProgrammaticRow(typeName, parent, ctx, mediaFields, fieldKeys) {
282
+ async function resolveProgrammaticRow(typeName, parent, ctx, mediaFieldNames, fieldKeys) {
283
283
  const toLabels = (row) => fieldKeys ? fieldKeys.toLabels(row) : row;
284
- if (mediaFields.length === 0) return ctx.resolver.resolveItem(typeName, toLabels(parent));
284
+ if (mediaFieldNames.length === 0) return ctx.resolver.resolveItem(typeName, toLabels(parent));
285
285
  const enriched = { ...parent };
286
- await Promise.all(mediaFields.map((m) => ctx.loaders.load(typeName, m.name, enriched)));
287
- return ctx.resolver.resolveItem(typeName, relabelMedia(toLabels(enriched), enriched, mediaFields));
288
- }
289
- function relabelMedia(record, enriched, mediaFields) {
290
- for (const { name, exposedAs } of mediaFields) {
291
- if (!(name in enriched)) continue;
292
- record[exposedAs] = enriched[name];
293
- }
294
- return record;
286
+ await Promise.all(mediaFieldNames.map((name) => ctx.loaders.load(typeName, name, enriched)));
287
+ return ctx.resolver.resolveItem(typeName, toLabels(enriched));
295
288
  }
296
289
  function collectionResolver(typeName, nameMap, fieldKeys) {
297
290
  return async (_root, args, ctx) => {
@@ -365,7 +358,7 @@ var MEDIA = new import_graphql5.GraphQLObjectType({
365
358
  duration: { type: import_graphql5.GraphQLInt, resolve: (m) => m.duration }
366
359
  }
367
360
  });
368
- function buildGraphQLSchema(registry, fieldKeyMaps = {}, view) {
361
+ function buildGraphQLSchema(registry, fieldKeyMaps = {}, view, programmaticKeyMaps = fieldKeyMaps) {
369
362
  const objectTypes = /* @__PURE__ */ new Map();
370
363
  const enumTypes = /* @__PURE__ */ new Map();
371
364
  for (const [name, enumType] of Object.entries(registry.enum_types)) {
@@ -429,9 +422,9 @@ function buildGraphQLSchema(registry, fieldKeyMaps = {}, view) {
429
422
  }
430
423
  function buildObjectType(machineName, type) {
431
424
  const visible = viewFieldsFor(machineName, type);
432
- const mediaFields = visible.filter(
433
- (v) => v.field.field_type === "image" || v.field.field_type === "video" || v.field.field_type === "file"
434
- ).map((v) => ({ name: v.field.name, exposedAs: v.exposedAs }));
425
+ const mediaFieldNames = type.fields.filter(
426
+ (f) => f.removed !== true && (f.field_type === "image" || f.field_type === "video" || f.field_type === "file")
427
+ ).map((f) => f.name);
435
428
  return new import_graphql5.GraphQLObjectType({
436
429
  name: graphqlTypeName(machineName),
437
430
  fields: () => {
@@ -451,7 +444,7 @@ function buildGraphQLSchema(registry, fieldKeyMaps = {}, view) {
451
444
  const outType = outputTypeForField(field, vf.required);
452
445
  let resolve;
453
446
  if (field.field_type === "programmatic") {
454
- resolve = programmaticFieldResolver(machineName, field.name, mediaFields, fieldKeyMaps[machineName]);
447
+ resolve = programmaticFieldResolver(machineName, field.name, mediaFieldNames, programmaticKeyMaps[machineName]);
455
448
  } else if (field.field_type === "reference" || field.field_type === "paragraph" || field.field_type === "image" || field.field_type === "video" || field.field_type === "file") {
456
449
  resolve = relationFieldResolver(machineName, field.name);
457
450
  } else {
@@ -496,7 +489,10 @@ function buildGraphQLSchema(registry, fieldKeyMaps = {}, view) {
496
489
  for (const [name, ct] of Object.entries(registry.content_types)) {
497
490
  const objType = objectTypes.get(name);
498
491
  const visible = viewFieldsFor(name, ct);
499
- const nameMap = buildFieldNameMap(visible.map((v) => v.exposedAs));
492
+ const nameMap = buildFieldNameMap([
493
+ ...visible.map((v) => v.exposedAs),
494
+ ...ct.system_fields.map((s) => s.name)
495
+ ]);
500
496
  if (ct.only_one) {
501
497
  queryFields[singleQueryName(name)] = { type: objType, resolve: singletonResolver(name) };
502
498
  continue;
@@ -672,9 +668,8 @@ function groupBy(items, key) {
672
668
  }
673
669
  return result;
674
670
  }
675
- function needsFkResolution(row, fkColumn, fieldName) {
676
- if (fkColumn !== fieldName && !(fkColumn in row)) return false;
677
- const current = row[fieldName];
671
+ function needsFkResolution(row, fkColumn) {
672
+ const current = row[fkColumn];
678
673
  return !(typeof current === "object" && current !== null);
679
674
  }
680
675
  async function resolveRelationField(db, rows, fieldName, rel, cache, publishedOnly = false) {
@@ -691,15 +686,11 @@ async function resolveRelationField(db, rows, fieldName, rel, cache, publishedOn
691
686
  row[fieldName] = byParent[row["id"]] ?? [];
692
687
  }
693
688
  } else if (rel.type === "reference") {
694
- const dropFk = rel.fk_column !== fieldName;
695
- const pending = batch.filter((r) => needsFkResolution(r, rel.fk_column, fieldName));
689
+ const pending = batch.filter((r) => needsFkResolution(r, rel.fk_column));
696
690
  if (pending.length === 0) return;
697
691
  const fkValues = pending.map((r) => r[rel.fk_column]).filter(Boolean);
698
692
  if (fkValues.length === 0) {
699
- for (const row of pending) {
700
- row[fieldName] = null;
701
- if (dropFk) delete row[rel.fk_column];
702
- }
693
+ for (const row of pending) row[rel.fk_column] = null;
703
694
  return;
704
695
  }
705
696
  const unique = [...new Set(fkValues)];
@@ -716,8 +707,7 @@ async function resolveRelationField(db, rows, fieldName, rel, cache, publishedOn
716
707
  }
717
708
  for (const row of pending) {
718
709
  const fkVal = row[rel.fk_column];
719
- row[fieldName] = fkVal ? cache.get(`${rel.table}:${fkVal}`) ?? null : null;
720
- if (dropFk) delete row[rel.fk_column];
710
+ row[rel.fk_column] = fkVal ? cache.get(`${rel.table}:${fkVal}`) ?? null : null;
721
711
  }
722
712
  } else if (rel.type === "junction") {
723
713
  const parentIds = batch.map((r) => r["id"]);
@@ -745,15 +735,11 @@ async function resolveRelationField(db, rows, fieldName, rel, cache, publishedOn
745
735
  row[fieldName] = jEntries.map((jr) => cache.get(`${rel.table}:${jr[rel.right_column]}`)).filter(Boolean);
746
736
  }
747
737
  } else if (rel.type === "media") {
748
- const dropFk = rel.fk_column !== fieldName;
749
- const pending = batch.filter((r) => needsFkResolution(r, rel.fk_column, fieldName));
738
+ const pending = batch.filter((r) => needsFkResolution(r, rel.fk_column));
750
739
  if (pending.length === 0) return;
751
740
  const fkValues = pending.map((r) => r[rel.fk_column]).filter(Boolean);
752
741
  if (fkValues.length === 0) {
753
- for (const row of pending) {
754
- row[fieldName] = null;
755
- if (dropFk) delete row[rel.fk_column];
756
- }
742
+ for (const row of pending) row[rel.fk_column] = null;
757
743
  return;
758
744
  }
759
745
  const unique = [...new Set(fkValues)];
@@ -767,8 +753,7 @@ async function resolveRelationField(db, rows, fieldName, rel, cache, publishedOn
767
753
  }
768
754
  for (const row of pending) {
769
755
  const fkVal = row[rel.fk_column];
770
- row[fieldName] = fkVal ? cache.get(`media:${fkVal}`) ?? null : null;
771
- if (dropFk) delete row[rel.fk_column];
756
+ row[rel.fk_column] = fkVal ? cache.get(`media:${fkVal}`) ?? null : null;
772
757
  }
773
758
  }
774
759
  }
@@ -795,7 +780,8 @@ function createRelationLoaders(db, registry) {
795
780
  async (parents) => {
796
781
  const rows = parents;
797
782
  await resolveRelationField(db, rows, fieldName, rel, cache, true);
798
- return rows.map((r) => r[fieldName]);
783
+ const resultKey = rel.type === "reference" || rel.type === "media" ? rel.fk_column : fieldName;
784
+ return rows.map((r) => r[resultKey]);
799
785
  },
800
786
  // Batch within a tick; do not memoize by parent identity (rows are mutated
801
787
  // and may recur across nesting levels).
@@ -862,7 +848,7 @@ function createGraphQLHandler(registry, repos, fieldKeyMaps, resolver, db, optio
862
848
  currentVersion: versioning.currentVersion
863
849
  });
864
850
  }
865
- const schema = buildGraphQLSchema(registry, fieldKeyMaps, view);
851
+ const schema = buildGraphQLSchema(registry, fieldKeyMaps, view, versioning.currentFieldKeyMaps ?? fieldKeyMaps);
866
852
  const { plugins } = buildArmorPlugin({
867
853
  maxDepth: options.maxDepth,
868
854
  maxComplexity: options.maxComplexity