@tinacms/graphql 1.4.14 → 1.4.16

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.es.js CHANGED
@@ -2525,7 +2525,7 @@ var validateField = async (field) => {
2525
2525
  // package.json
2526
2526
  var package_default = {
2527
2527
  name: "@tinacms/graphql",
2528
- version: "1.4.14",
2528
+ version: "1.4.16",
2529
2529
  main: "dist/index.js",
2530
2530
  module: "dist/index.es.js",
2531
2531
  typings: "dist/index.d.ts",
@@ -2834,7 +2834,7 @@ import {
2834
2834
  } from "graphql";
2835
2835
 
2836
2836
  // src/resolver/index.ts
2837
- import path2 from "path";
2837
+ import path3 from "path";
2838
2838
  import isValid from "date-fns/isValid";
2839
2839
 
2840
2840
  // src/mdx/index.ts
@@ -3066,9 +3066,9 @@ var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, s
3066
3066
  return value;
3067
3067
  }
3068
3068
  };
3069
- var cleanUpSlashes = (path5) => {
3070
- if (path5) {
3071
- return `/${path5.replace(/^\/+|\/+$/gm, "")}`;
3069
+ var cleanUpSlashes = (path6) => {
3070
+ if (path6) {
3071
+ return `/${path6.replace(/^\/+|\/+$/gm, "")}`;
3072
3072
  }
3073
3073
  return "";
3074
3074
  };
@@ -3134,13 +3134,131 @@ var LevelProxy = class {
3134
3134
  };
3135
3135
 
3136
3136
  // src/database/datalayer.ts
3137
- import path from "path";
3137
+ import path2 from "path";
3138
3138
 
3139
3139
  // src/database/util.ts
3140
3140
  import toml from "@iarna/toml";
3141
3141
  import yaml from "js-yaml";
3142
3142
  import matter from "gray-matter";
3143
- import { normalizePath } from "@tinacms/schema-tools";
3143
+ import {
3144
+ normalizePath
3145
+ } from "@tinacms/schema-tools";
3146
+ import micromatch from "micromatch";
3147
+ import path from "path";
3148
+
3149
+ // src/database/alias-utils.ts
3150
+ var replaceBlockAliases = (template, item) => {
3151
+ const output = { ...item };
3152
+ const templateKey = template.templateKey || "_template";
3153
+ const templateName = output[templateKey];
3154
+ const matchingTemplate = template.templates.find(
3155
+ (t) => t.nameOverride == templateName || t.name == templateName
3156
+ );
3157
+ if (!matchingTemplate) {
3158
+ throw new Error(
3159
+ `Block template "${templateName}" is not defined for field "${template.name}"`
3160
+ );
3161
+ }
3162
+ output._template = matchingTemplate.name;
3163
+ if (templateKey != "_template") {
3164
+ delete output[templateKey];
3165
+ }
3166
+ return output;
3167
+ };
3168
+ var replaceNameOverrides = (template, obj) => {
3169
+ if (template.list) {
3170
+ return obj.map((item) => {
3171
+ if (isBlockField(template)) {
3172
+ item = replaceBlockAliases(template, item);
3173
+ }
3174
+ return _replaceNameOverrides(
3175
+ getTemplateForData(template, item).fields,
3176
+ item
3177
+ );
3178
+ });
3179
+ } else {
3180
+ return _replaceNameOverrides(getTemplateForData(template, obj).fields, obj);
3181
+ }
3182
+ };
3183
+ function isBlockField(field) {
3184
+ return field && field.type === "object" && field.templates?.length > 0;
3185
+ }
3186
+ var _replaceNameOverrides = (fields, obj) => {
3187
+ const output = {};
3188
+ Object.keys(obj).forEach((key) => {
3189
+ const field = fields.find(
3190
+ (fieldWithMatchingAlias) => (fieldWithMatchingAlias?.nameOverride || fieldWithMatchingAlias?.name) === key
3191
+ );
3192
+ output[field?.name || key] = field?.type == "object" ? replaceNameOverrides(field, obj[key]) : obj[key];
3193
+ });
3194
+ return output;
3195
+ };
3196
+ var getTemplateForData = (field, data) => {
3197
+ if (field.templates?.length) {
3198
+ const templateKey = "_template";
3199
+ if (data[templateKey]) {
3200
+ const result = field.templates.find(
3201
+ (template) => template.nameOverride === data[templateKey] || template.name === data[templateKey]
3202
+ );
3203
+ if (result) {
3204
+ return result;
3205
+ }
3206
+ throw new Error(
3207
+ `Template "${data[templateKey]}" is not defined for field "${field.name}"`
3208
+ );
3209
+ }
3210
+ throw new Error(
3211
+ `Missing required key "${templateKey}" on field "${field.name}"`
3212
+ );
3213
+ } else {
3214
+ return field;
3215
+ }
3216
+ };
3217
+ var applyBlockAliases = (template, item) => {
3218
+ const output = { ...item };
3219
+ const templateKey = template.templateKey || "_template";
3220
+ const templateName = output._template;
3221
+ const matchingTemplate = template.templates.find(
3222
+ (t) => t.nameOverride == templateName || t.name == templateName
3223
+ );
3224
+ if (!matchingTemplate) {
3225
+ throw new Error(
3226
+ `Block template "${templateName}" is not defined for field "${template.name}"`
3227
+ );
3228
+ }
3229
+ output[templateKey] = matchingTemplate.nameOverride || matchingTemplate.name;
3230
+ if (templateKey != "_template") {
3231
+ delete output._template;
3232
+ }
3233
+ return output;
3234
+ };
3235
+ var applyNameOverrides = (template, obj) => {
3236
+ if (template.list) {
3237
+ return obj.map((item) => {
3238
+ let result = _applyNameOverrides(
3239
+ getTemplateForData(template, item).fields,
3240
+ item
3241
+ );
3242
+ if (isBlockField(template)) {
3243
+ result = applyBlockAliases(template, result);
3244
+ }
3245
+ return result;
3246
+ });
3247
+ } else {
3248
+ return _applyNameOverrides(getTemplateForData(template, obj).fields, obj);
3249
+ }
3250
+ };
3251
+ var _applyNameOverrides = (fields, obj) => {
3252
+ const output = {};
3253
+ Object.keys(obj).forEach((key) => {
3254
+ const field = fields.find((field2) => field2.name === key);
3255
+ const outputKey = field?.nameOverride || key;
3256
+ output[outputKey] = field?.type === "object" ? applyNameOverrides(field, obj[key]) : obj[key];
3257
+ });
3258
+ return output;
3259
+ };
3260
+
3261
+ // src/database/util.ts
3144
3262
  var matterEngines = {
3145
3263
  toml: {
3146
3264
  parse: (val) => toml.parse(val),
@@ -3224,6 +3342,142 @@ var parseFile = (content, format, yupSchema, markdownParseConfig) => {
3224
3342
  throw new Error(`Must specify a valid format, got ${format}`);
3225
3343
  }
3226
3344
  };
3345
+ var scanAllContent = async (tinaSchema, bridge, callback) => {
3346
+ const warnings = [];
3347
+ const filesSeen = /* @__PURE__ */ new Map();
3348
+ const duplicateFiles = /* @__PURE__ */ new Set();
3349
+ await sequential(tinaSchema.getCollections(), async (collection) => {
3350
+ const normalPath = normalizePath(collection.path);
3351
+ const format = collection.format || "md";
3352
+ const documentPaths = await bridge.glob(normalPath, format);
3353
+ const matches = tinaSchema.getMatches({ collection });
3354
+ const filteredPaths = matches.length > 0 ? micromatch(documentPaths, matches) : documentPaths;
3355
+ filteredPaths.forEach((path6) => {
3356
+ if (filesSeen.has(path6)) {
3357
+ filesSeen.get(path6).push(collection.name);
3358
+ duplicateFiles.add(path6);
3359
+ } else {
3360
+ filesSeen.set(path6, [collection.name]);
3361
+ }
3362
+ });
3363
+ duplicateFiles.forEach((path6) => {
3364
+ warnings.push(
3365
+ `"${path6}" Found in multiple collections: ${filesSeen.get(path6).map((collection2) => `"${collection2}"`).join(
3366
+ ", "
3367
+ )}. This can cause unexpected behavior. We recommend updating the \`match\` property of those collections so that each file is in only one collection.
3368
+ This will be an error in the future. See https://tina.io/docs/errors/file-in-mutpliple-collections/
3369
+ `
3370
+ );
3371
+ });
3372
+ await callback(collection, filteredPaths);
3373
+ });
3374
+ return warnings;
3375
+ };
3376
+ var scanContentByPaths = async (tinaSchema, documentPaths, callback) => {
3377
+ const { pathsByCollection, nonCollectionPaths, collections } = await partitionPathsByCollection(tinaSchema, documentPaths);
3378
+ for (const collection of Object.keys(pathsByCollection)) {
3379
+ await callback(collections[collection], pathsByCollection[collection]);
3380
+ }
3381
+ if (nonCollectionPaths.length) {
3382
+ await callback(void 0, nonCollectionPaths);
3383
+ }
3384
+ };
3385
+ var partitionPathsByCollection = async (tinaSchema, documentPaths) => {
3386
+ const pathsByCollection = {};
3387
+ const nonCollectionPaths = [];
3388
+ const collections = {};
3389
+ for (const documentPath of documentPaths) {
3390
+ const collection = await tinaSchema.getCollectionByFullPath(documentPath);
3391
+ if (collection) {
3392
+ if (!pathsByCollection[collection.name]) {
3393
+ pathsByCollection[collection.name] = [];
3394
+ }
3395
+ collections[collection.name] = collection;
3396
+ pathsByCollection[collection.name].push(documentPath);
3397
+ } else {
3398
+ nonCollectionPaths.push(documentPath);
3399
+ }
3400
+ }
3401
+ return { pathsByCollection, nonCollectionPaths, collections };
3402
+ };
3403
+ var transformDocument = (filepath, contentObject, tinaSchema) => {
3404
+ const extension = path.extname(filepath);
3405
+ const templateName = hasOwnProperty(contentObject, "_template") && typeof contentObject._template === "string" ? contentObject._template : void 0;
3406
+ const { collection, template } = hasOwnProperty(contentObject, "__collection") ? {
3407
+ collection: tinaSchema.getCollection(
3408
+ contentObject["__collection"]
3409
+ ),
3410
+ template: void 0
3411
+ } : tinaSchema.getCollectionAndTemplateByFullPath(filepath, templateName);
3412
+ const field = template?.fields.find((field2) => {
3413
+ if (field2.type === "string" || field2.type === "rich-text") {
3414
+ if (field2.isBody) {
3415
+ return true;
3416
+ }
3417
+ }
3418
+ return false;
3419
+ });
3420
+ let data = contentObject;
3421
+ if ((extension === ".md" || extension === ".mdx") && field) {
3422
+ if (hasOwnProperty(contentObject, "$_body")) {
3423
+ const { $_body, ...rest } = contentObject;
3424
+ data = rest;
3425
+ data[field.name] = $_body;
3426
+ }
3427
+ }
3428
+ return {
3429
+ ...data,
3430
+ _collection: collection.name,
3431
+ _keepTemplateKey: !!collection.templates,
3432
+ _template: template?.namespace ? lastItem(template?.namespace) : void 0,
3433
+ _relativePath: filepath.replace(collection.path, "").replace(/^\/|\/$/g, ""),
3434
+ _id: filepath
3435
+ };
3436
+ };
3437
+ function hasOwnProperty(obj, prop) {
3438
+ return obj.hasOwnProperty(prop);
3439
+ }
3440
+ var getTemplateForFile = (templateInfo, data) => {
3441
+ if (templateInfo?.type === "object") {
3442
+ return templateInfo.template;
3443
+ }
3444
+ if (templateInfo?.type === "union") {
3445
+ if (hasOwnProperty(data, "_template")) {
3446
+ const template = templateInfo.templates.find(
3447
+ (t) => lastItem(t.namespace) === data._template
3448
+ );
3449
+ if (!template) {
3450
+ throw new Error(
3451
+ `Unable to find template "${data._template}". Possible templates are: ${templateInfo.templates.map((template2) => `"${template2.name}"`).join(", ")}.`
3452
+ );
3453
+ }
3454
+ return template;
3455
+ } else {
3456
+ return void 0;
3457
+ }
3458
+ }
3459
+ throw new Error(`Unable to determine template`);
3460
+ };
3461
+ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo) => {
3462
+ const dataString = await bridge.get(normalizePath(filepath));
3463
+ const data = parseFile(
3464
+ dataString,
3465
+ path.extname(filepath),
3466
+ (yup3) => yup3.object({}),
3467
+ {
3468
+ frontmatterDelimiters: collection?.frontmatterDelimiters,
3469
+ frontmatterFormat: collection?.frontmatterFormat
3470
+ }
3471
+ );
3472
+ const template = getTemplateForFile(templateInfo, data);
3473
+ if (!template) {
3474
+ console.warn(
3475
+ `Document: ${filepath} has an ambiguous template, skipping from indexing`
3476
+ );
3477
+ return;
3478
+ }
3479
+ return templateInfo ? replaceNameOverrides(template, data) : data;
3480
+ };
3227
3481
 
3228
3482
  // src/database/datalayer.ts
3229
3483
  var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
@@ -3668,9 +3922,9 @@ var makeFilterSuffixes = (filterChain, index) => {
3668
3922
  }
3669
3923
  };
3670
3924
  var FOLDER_ROOT = "~";
3671
- var stripCollectionFromPath = (collectionPath, path5) => {
3925
+ var stripCollectionFromPath = (collectionPath, path6) => {
3672
3926
  const collectionPathParts = collectionPath.split("/");
3673
- const pathParts = path5.split("/");
3927
+ const pathParts = path6.split("/");
3674
3928
  const strippedPathParts = pathParts.slice(collectionPathParts.length);
3675
3929
  return strippedPathParts.join("/");
3676
3930
  };
@@ -3684,7 +3938,7 @@ var FolderTreeBuilder = class {
3684
3938
  return this._tree;
3685
3939
  }
3686
3940
  update(documentPath, collectionPath) {
3687
- let folderPath = path.dirname(normalizePath(documentPath));
3941
+ let folderPath = path2.dirname(normalizePath(documentPath));
3688
3942
  if (folderPath === ".") {
3689
3943
  folderPath = "";
3690
3944
  }
@@ -3697,7 +3951,7 @@ var FolderTreeBuilder = class {
3697
3951
  if (!this._tree[current2]) {
3698
3952
  this._tree[current2] = /* @__PURE__ */ new Set();
3699
3953
  }
3700
- this._tree[current2].add(normalizePath(path.join(current2, part)));
3954
+ this._tree[current2].add(normalizePath(path2.join(current2, part)));
3701
3955
  parent.push(part);
3702
3956
  });
3703
3957
  const current = parent.join("/");
@@ -3725,13 +3979,13 @@ var makeFolderOpsForCollection = (folderTree, collection, indexDefinitions, opTy
3725
3979
  SUBLEVEL_OPTIONS
3726
3980
  );
3727
3981
  let folderSortingIdx = 0;
3728
- for (const path5 of Array.from(folder).sort()) {
3982
+ for (const path6 of Array.from(folder).sort()) {
3729
3983
  for (const [sort] of Object.entries(indexDefinitions)) {
3730
3984
  const indexSublevel = folderCollectionSublevel.sublevel(
3731
3985
  sort,
3732
3986
  SUBLEVEL_OPTIONS
3733
3987
  );
3734
- const subFolderKey = sha.hex(path5);
3988
+ const subFolderKey = sha.hex(path6);
3735
3989
  if (sort === DEFAULT_COLLECTION_SORT_KEY) {
3736
3990
  result.push({
3737
3991
  type: opType,
@@ -3759,7 +4013,7 @@ var makeFolderOpsForCollection = (folderTree, collection, indexDefinitions, opTy
3759
4013
  key: `${collection.path}/${parentFolderKey}.${collection.format}`,
3760
4014
  value: {
3761
4015
  __collection: collection.name,
3762
- __folderBasename: path.basename(folderName),
4016
+ __folderBasename: path2.basename(folderName),
3763
4017
  __folderPath: folderName
3764
4018
  },
3765
4019
  sublevel: level.sublevel(
@@ -3823,6 +4077,194 @@ var stringEscaper = makeStringEscaper(
3823
4077
  var createResolver = (args) => {
3824
4078
  return new Resolver(args);
3825
4079
  };
4080
+ var resolveFieldData = async ({ namespace, ...field }, rawData, accumulator, tinaSchema, config, isAudit) => {
4081
+ if (!rawData) {
4082
+ return void 0;
4083
+ }
4084
+ assertShape(rawData, (yup3) => yup3.object());
4085
+ const value = rawData[field.name];
4086
+ switch (field.type) {
4087
+ case "datetime":
4088
+ if (value instanceof Date) {
4089
+ accumulator[field.name] = value.toISOString();
4090
+ } else {
4091
+ accumulator[field.name] = value;
4092
+ }
4093
+ break;
4094
+ case "string":
4095
+ case "boolean":
4096
+ case "number":
4097
+ accumulator[field.name] = value;
4098
+ break;
4099
+ case "reference":
4100
+ if (value) {
4101
+ accumulator[field.name] = value;
4102
+ }
4103
+ break;
4104
+ case "image":
4105
+ accumulator[field.name] = resolveMediaRelativeToCloud(
4106
+ value,
4107
+ config,
4108
+ tinaSchema.schema
4109
+ );
4110
+ break;
4111
+ case "rich-text":
4112
+ const tree = parseMDX(
4113
+ value,
4114
+ field,
4115
+ (value2) => resolveMediaRelativeToCloud(value2, config, tinaSchema.schema)
4116
+ );
4117
+ if (tree?.children[0]?.type === "invalid_markdown") {
4118
+ if (isAudit) {
4119
+ const invalidNode = tree?.children[0];
4120
+ throw new GraphQLError2(
4121
+ `${invalidNode?.message}${invalidNode.position ? ` at line ${invalidNode.position.start.line}, column ${invalidNode.position.start.column}` : ""}`
4122
+ );
4123
+ }
4124
+ }
4125
+ accumulator[field.name] = tree;
4126
+ break;
4127
+ case "object":
4128
+ if (field.list) {
4129
+ if (!value) {
4130
+ return;
4131
+ }
4132
+ assertShape(
4133
+ value,
4134
+ (yup3) => yup3.array().of(yup3.object().required())
4135
+ );
4136
+ accumulator[field.name] = await sequential(value, async (item) => {
4137
+ const template = await tinaSchema.getTemplateForData({
4138
+ data: item,
4139
+ collection: {
4140
+ namespace,
4141
+ ...field
4142
+ }
4143
+ });
4144
+ const payload = {};
4145
+ await sequential(template.fields, async (field2) => {
4146
+ await resolveFieldData(
4147
+ field2,
4148
+ item,
4149
+ payload,
4150
+ tinaSchema,
4151
+ config,
4152
+ isAudit
4153
+ );
4154
+ });
4155
+ const isUnion = !!field.templates;
4156
+ return isUnion ? {
4157
+ _template: lastItem(template.namespace),
4158
+ ...payload
4159
+ } : payload;
4160
+ });
4161
+ } else {
4162
+ if (!value) {
4163
+ return;
4164
+ }
4165
+ const template = await tinaSchema.getTemplateForData({
4166
+ data: value,
4167
+ collection: {
4168
+ namespace,
4169
+ ...field
4170
+ }
4171
+ });
4172
+ const payload = {};
4173
+ await sequential(template.fields, async (field2) => {
4174
+ await resolveFieldData(
4175
+ field2,
4176
+ value,
4177
+ payload,
4178
+ tinaSchema,
4179
+ config,
4180
+ isAudit
4181
+ );
4182
+ });
4183
+ const isUnion = !!field.templates;
4184
+ accumulator[field.name] = isUnion ? {
4185
+ _template: lastItem(template.namespace),
4186
+ ...payload
4187
+ } : payload;
4188
+ }
4189
+ break;
4190
+ default:
4191
+ return field;
4192
+ }
4193
+ return accumulator;
4194
+ };
4195
+ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config, isAudit) => {
4196
+ const collection = tinaSchema.getCollection(rawData._collection);
4197
+ try {
4198
+ const template = tinaSchema.getTemplateForData({
4199
+ data: rawData,
4200
+ collection
4201
+ });
4202
+ const {
4203
+ base: basename,
4204
+ ext: extension,
4205
+ name: filename
4206
+ } = path3.parse(fullPath);
4207
+ const relativePath = fullPath.replace(/\\/g, "/").replace(collection.path, "").replace(/^\/|\/$/g, "");
4208
+ const breadcrumbs = relativePath.replace(extension, "").split("/");
4209
+ const data = {
4210
+ _collection: rawData._collection,
4211
+ _template: rawData._template
4212
+ };
4213
+ try {
4214
+ await sequential(template.fields, async (field) => {
4215
+ return resolveFieldData(
4216
+ field,
4217
+ rawData,
4218
+ data,
4219
+ tinaSchema,
4220
+ config,
4221
+ isAudit
4222
+ );
4223
+ });
4224
+ } catch (e) {
4225
+ throw new TinaParseDocumentError({
4226
+ originalError: e,
4227
+ collection: collection.name,
4228
+ includeAuditMessage: !isAudit,
4229
+ file: relativePath,
4230
+ stack: e.stack
4231
+ });
4232
+ }
4233
+ const titleField = template.fields.find((x) => {
4234
+ if (x.type === "string" && x?.isTitle) {
4235
+ return true;
4236
+ }
4237
+ });
4238
+ const titleFieldName = titleField?.name;
4239
+ const title = data[titleFieldName || " "] || null;
4240
+ return {
4241
+ __typename: collection.fields ? NAMER.documentTypeName(collection.namespace) : NAMER.documentTypeName(template.namespace),
4242
+ id: fullPath,
4243
+ ...data,
4244
+ _sys: {
4245
+ title: title || "",
4246
+ basename,
4247
+ filename,
4248
+ extension,
4249
+ path: fullPath,
4250
+ relativePath,
4251
+ breadcrumbs,
4252
+ collection,
4253
+ template: lastItem(template.namespace)
4254
+ },
4255
+ _values: data,
4256
+ _rawData: rawData
4257
+ };
4258
+ } catch (e) {
4259
+ if (e instanceof TinaGraphQLError) {
4260
+ throw new TinaGraphQLError(e.message, {
4261
+ requestedDocument: fullPath,
4262
+ ...e.extensions
4263
+ });
4264
+ }
4265
+ throw e;
4266
+ }
4267
+ };
3826
4268
  var Resolver = class {
3827
4269
  constructor(init) {
3828
4270
  this.init = init;
@@ -3855,7 +4297,13 @@ var Resolver = class {
3855
4297
  path: rawData["__folderPath"]
3856
4298
  };
3857
4299
  } else {
3858
- return this.transformDocumentIntoPayload(fullPath, rawData);
4300
+ return transformDocumentIntoPayload(
4301
+ fullPath,
4302
+ rawData,
4303
+ this.tinaSchema,
4304
+ this.config,
4305
+ this.isAudit
4306
+ );
3859
4307
  }
3860
4308
  };
3861
4309
  this.getDocument = async (fullPath) => {
@@ -3863,73 +4311,13 @@ var Resolver = class {
3863
4311
  throw new Error(`fullPath must be of type string for getDocument request`);
3864
4312
  }
3865
4313
  const rawData = await this.getRaw(fullPath);
3866
- return this.transformDocumentIntoPayload(fullPath, rawData);
3867
- };
3868
- this.transformDocumentIntoPayload = async (fullPath, rawData) => {
3869
- const collection = this.tinaSchema.getCollection(rawData._collection);
3870
- try {
3871
- const template = await this.tinaSchema.getTemplateForData({
3872
- data: rawData,
3873
- collection
3874
- });
3875
- const {
3876
- base: basename,
3877
- ext: extension,
3878
- name: filename
3879
- } = path2.parse(fullPath);
3880
- const relativePath = fullPath.replace(/\\/g, "/").replace(collection.path, "").replace(/^\/|\/$/g, "");
3881
- const breadcrumbs = relativePath.replace(extension, "").split("/");
3882
- const data = {
3883
- _collection: rawData._collection,
3884
- _template: rawData._template
3885
- };
3886
- try {
3887
- await sequential(template.fields, async (field) => {
3888
- return this.resolveFieldData(field, rawData, data);
3889
- });
3890
- } catch (e) {
3891
- throw new TinaParseDocumentError({
3892
- originalError: e,
3893
- collection: collection.name,
3894
- includeAuditMessage: !this.isAudit,
3895
- file: relativePath,
3896
- stack: e.stack
3897
- });
3898
- }
3899
- const titleField = template.fields.find((x) => {
3900
- if (x.type === "string" && x?.isTitle) {
3901
- return true;
3902
- }
3903
- });
3904
- const titleFieldName = titleField?.name;
3905
- const title = data[titleFieldName || " "] || null;
3906
- return {
3907
- __typename: collection.fields ? NAMER.documentTypeName(collection.namespace) : NAMER.documentTypeName(template.namespace),
3908
- id: fullPath,
3909
- ...data,
3910
- _sys: {
3911
- title: title || "",
3912
- basename,
3913
- filename,
3914
- extension,
3915
- path: fullPath,
3916
- relativePath,
3917
- breadcrumbs,
3918
- collection,
3919
- template: lastItem(template.namespace)
3920
- },
3921
- _values: data,
3922
- _rawData: rawData
3923
- };
3924
- } catch (e) {
3925
- if (e instanceof TinaGraphQLError) {
3926
- throw new TinaGraphQLError(e.message, {
3927
- requestedDocument: fullPath,
3928
- ...e.extensions
3929
- });
3930
- }
3931
- throw e;
3932
- }
4314
+ return transformDocumentIntoPayload(
4315
+ fullPath,
4316
+ rawData,
4317
+ this.tinaSchema,
4318
+ this.config,
4319
+ this.isAudit
4320
+ );
3933
4321
  };
3934
4322
  this.deleteDocument = async (fullPath) => {
3935
4323
  if (typeof fullPath !== "string") {
@@ -4119,7 +4507,7 @@ var Resolver = class {
4119
4507
  (yup3) => yup3.object({ relativePath: yup3.string().required() })
4120
4508
  );
4121
4509
  const collection = await this.tinaSchema.getCollection(collectionLookup);
4122
- const realPath = path2.join(collection?.path, args.relativePath);
4510
+ const realPath = path3.join(collection?.path, args.relativePath);
4123
4511
  const alreadyExists = await this.database.documentExists(realPath);
4124
4512
  if (isMutation) {
4125
4513
  if (isCreation) {
@@ -4160,7 +4548,7 @@ var Resolver = class {
4160
4548
  (yup3) => yup3.object({ relativePath: yup3.string().required() })
4161
4549
  );
4162
4550
  const doc = await this.getDocument(realPath);
4163
- const newRealPath = path2.join(
4551
+ const newRealPath = path3.join(
4164
4552
  collection?.path,
4165
4553
  args.params.relativePath
4166
4554
  );
@@ -4215,7 +4603,7 @@ var Resolver = class {
4215
4603
  first: -1
4216
4604
  },
4217
4605
  collection: referencedCollection,
4218
- hydrator: (path5) => path5
4606
+ hydrator: (path6) => path6
4219
4607
  }
4220
4608
  );
4221
4609
  const { edges } = resolvedCollectionConnection;
@@ -4335,111 +4723,6 @@ var Resolver = class {
4335
4723
  });
4336
4724
  return accum;
4337
4725
  };
4338
- this.resolveFieldData = async ({ namespace, ...field }, rawData, accumulator) => {
4339
- if (!rawData) {
4340
- return void 0;
4341
- }
4342
- assertShape(rawData, (yup3) => yup3.object());
4343
- const value = rawData[field.name];
4344
- switch (field.type) {
4345
- case "datetime":
4346
- if (value instanceof Date) {
4347
- accumulator[field.name] = value.toISOString();
4348
- } else {
4349
- accumulator[field.name] = value;
4350
- }
4351
- break;
4352
- case "string":
4353
- case "boolean":
4354
- case "number":
4355
- accumulator[field.name] = value;
4356
- break;
4357
- case "reference":
4358
- if (value) {
4359
- accumulator[field.name] = value;
4360
- }
4361
- break;
4362
- case "image":
4363
- accumulator[field.name] = resolveMediaRelativeToCloud(
4364
- value,
4365
- this.config,
4366
- this.tinaSchema.schema
4367
- );
4368
- break;
4369
- case "rich-text":
4370
- const tree = parseMDX(
4371
- value,
4372
- field,
4373
- (value2) => resolveMediaRelativeToCloud(
4374
- value2,
4375
- this.config,
4376
- this.tinaSchema.schema
4377
- )
4378
- );
4379
- if (tree?.children[0]?.type === "invalid_markdown") {
4380
- if (this.isAudit) {
4381
- const invalidNode = tree?.children[0];
4382
- throw new GraphQLError2(
4383
- `${invalidNode?.message}${invalidNode.position ? ` at line ${invalidNode.position.start.line}, column ${invalidNode.position.start.column}` : ""}`
4384
- );
4385
- }
4386
- }
4387
- accumulator[field.name] = tree;
4388
- break;
4389
- case "object":
4390
- if (field.list) {
4391
- if (!value) {
4392
- return;
4393
- }
4394
- assertShape(
4395
- value,
4396
- (yup3) => yup3.array().of(yup3.object().required())
4397
- );
4398
- accumulator[field.name] = await sequential(value, async (item) => {
4399
- const template = await this.tinaSchema.getTemplateForData({
4400
- data: item,
4401
- collection: {
4402
- namespace,
4403
- ...field
4404
- }
4405
- });
4406
- const payload = {};
4407
- await sequential(template.fields, async (field2) => {
4408
- await this.resolveFieldData(field2, item, payload);
4409
- });
4410
- const isUnion = !!field.templates;
4411
- return isUnion ? {
4412
- _template: lastItem(template.namespace),
4413
- ...payload
4414
- } : payload;
4415
- });
4416
- } else {
4417
- if (!value) {
4418
- return;
4419
- }
4420
- const template = await this.tinaSchema.getTemplateForData({
4421
- data: value,
4422
- collection: {
4423
- namespace,
4424
- ...field
4425
- }
4426
- });
4427
- const payload = {};
4428
- await sequential(template.fields, async (field2) => {
4429
- await this.resolveFieldData(field2, value, payload);
4430
- });
4431
- const isUnion = !!field.templates;
4432
- accumulator[field.name] = isUnion ? {
4433
- _template: lastItem(template.namespace),
4434
- ...payload
4435
- } : payload;
4436
- }
4437
- break;
4438
- default:
4439
- return field;
4440
- }
4441
- return accumulator;
4442
- };
4443
4726
  this.buildParams = (args) => {
4444
4727
  try {
4445
4728
  assertShape(
@@ -4521,6 +4804,9 @@ var resolve = async ({
4521
4804
  try {
4522
4805
  const verboseValue = verbose ?? true;
4523
4806
  const graphQLSchemaAst = await database.getGraphQLSchema();
4807
+ if (!graphQLSchemaAst) {
4808
+ throw new GraphQLError3(`GraphQL schema not found`);
4809
+ }
4524
4810
  const graphQLSchema = buildASTSchema(graphQLSchemaAst);
4525
4811
  const tinaConfig = await database.getTinaSchema();
4526
4812
  const tinaSchema = await createSchema({
@@ -4749,123 +5035,9 @@ var resolve = async ({
4749
5035
  };
4750
5036
 
4751
5037
  // src/database/index.ts
4752
- import path3 from "path";
5038
+ import path4 from "path";
4753
5039
  import { GraphQLError as GraphQLError4 } from "graphql";
4754
- import micromatch from "micromatch";
4755
-
4756
- // src/database/alias-utils.ts
4757
- var replaceBlockAliases = (template, item) => {
4758
- const output = { ...item };
4759
- const templateKey = template.templateKey || "_template";
4760
- const templateName = output[templateKey];
4761
- const matchingTemplate = template.templates.find(
4762
- (t) => t.nameOverride == templateName || t.name == templateName
4763
- );
4764
- if (!matchingTemplate) {
4765
- throw new Error(
4766
- `Block template "${templateName}" is not defined for field "${template.name}"`
4767
- );
4768
- }
4769
- output._template = matchingTemplate.name;
4770
- if (templateKey != "_template") {
4771
- delete output[templateKey];
4772
- }
4773
- return output;
4774
- };
4775
- var replaceNameOverrides = (template, obj) => {
4776
- if (template.list) {
4777
- return obj.map((item) => {
4778
- if (isBlockField(template)) {
4779
- item = replaceBlockAliases(template, item);
4780
- }
4781
- return _replaceNameOverrides(
4782
- getTemplateForData(template, item).fields,
4783
- item
4784
- );
4785
- });
4786
- } else {
4787
- return _replaceNameOverrides(getTemplateForData(template, obj).fields, obj);
4788
- }
4789
- };
4790
- function isBlockField(field) {
4791
- return field && field.type === "object" && field.templates?.length > 0;
4792
- }
4793
- var _replaceNameOverrides = (fields, obj) => {
4794
- const output = {};
4795
- Object.keys(obj).forEach((key) => {
4796
- const field = fields.find(
4797
- (fieldWithMatchingAlias) => (fieldWithMatchingAlias?.nameOverride || fieldWithMatchingAlias?.name) === key
4798
- );
4799
- output[field?.name || key] = field?.type == "object" ? replaceNameOverrides(field, obj[key]) : obj[key];
4800
- });
4801
- return output;
4802
- };
4803
- var getTemplateForData = (field, data) => {
4804
- if (field.templates?.length) {
4805
- const templateKey = "_template";
4806
- if (data[templateKey]) {
4807
- const result = field.templates.find(
4808
- (template) => template.nameOverride === data[templateKey] || template.name === data[templateKey]
4809
- );
4810
- if (result) {
4811
- return result;
4812
- }
4813
- throw new Error(
4814
- `Template "${data[templateKey]}" is not defined for field "${field.name}"`
4815
- );
4816
- }
4817
- throw new Error(
4818
- `Missing required key "${templateKey}" on field "${field.name}"`
4819
- );
4820
- } else {
4821
- return field;
4822
- }
4823
- };
4824
- var applyBlockAliases = (template, item) => {
4825
- const output = { ...item };
4826
- const templateKey = template.templateKey || "_template";
4827
- const templateName = output._template;
4828
- const matchingTemplate = template.templates.find(
4829
- (t) => t.nameOverride == templateName || t.name == templateName
4830
- );
4831
- if (!matchingTemplate) {
4832
- throw new Error(
4833
- `Block template "${templateName}" is not defined for field "${template.name}"`
4834
- );
4835
- }
4836
- output[templateKey] = matchingTemplate.nameOverride || matchingTemplate.name;
4837
- if (templateKey != "_template") {
4838
- delete output._template;
4839
- }
4840
- return output;
4841
- };
4842
- var applyNameOverrides = (template, obj) => {
4843
- if (template.list) {
4844
- return obj.map((item) => {
4845
- let result = _applyNameOverrides(
4846
- getTemplateForData(template, item).fields,
4847
- item
4848
- );
4849
- if (isBlockField(template)) {
4850
- result = applyBlockAliases(template, result);
4851
- }
4852
- return result;
4853
- });
4854
- } else {
4855
- return _applyNameOverrides(getTemplateForData(template, obj).fields, obj);
4856
- }
4857
- };
4858
- var _applyNameOverrides = (fields, obj) => {
4859
- const output = {};
4860
- Object.keys(obj).forEach((key) => {
4861
- const field = fields.find((field2) => field2.name === key);
4862
- const outputKey = field?.nameOverride || key;
4863
- output[outputKey] = field?.type === "object" ? applyNameOverrides(field, obj[key]) : obj[key];
4864
- });
4865
- return output;
4866
- };
4867
-
4868
- // src/database/index.ts
5040
+ import micromatch2 from "micromatch";
4869
5041
  import sha2 from "js-sha1";
4870
5042
  var createDatabase = (config) => {
4871
5043
  return new Database({
@@ -4883,16 +5055,17 @@ var Database = class {
4883
5055
  this.config = config;
4884
5056
  this.collectionForPath = async (filepath) => {
4885
5057
  const tinaSchema = await this.getSchema(this.level);
4886
- return tinaSchema.getCollectionByFullPath(filepath);
5058
+ try {
5059
+ return tinaSchema.getCollectionByFullPath(filepath);
5060
+ } catch (e) {
5061
+ }
4887
5062
  };
4888
- this.getGeneratedFolder = () => path3.join(this.tinaDirectory, "__generated__");
5063
+ this.getGeneratedFolder = () => path4.join(this.tinaDirectory, "__generated__");
4889
5064
  this.get = async (filepath) => {
4890
5065
  await this.initLevel();
4891
5066
  if (SYSTEM_FILES.includes(filepath)) {
4892
5067
  throw new Error(`Unexpected get for config file ${filepath}`);
4893
5068
  } else {
4894
- const tinaSchema = await this.getSchema(this.level);
4895
- const extension = path3.extname(filepath);
4896
5069
  const contentObject = await this.level.sublevel(
4897
5070
  CONTENT_ROOT_PREFIX,
4898
5071
  SUBLEVEL_OPTIONS
@@ -4900,56 +5073,27 @@ var Database = class {
4900
5073
  if (!contentObject) {
4901
5074
  throw new GraphQLError4(`Unable to find record ${filepath}`);
4902
5075
  }
4903
- const templateName = hasOwnProperty(contentObject, "_template") && typeof contentObject._template === "string" ? contentObject._template : void 0;
4904
- const { collection, template } = hasOwnProperty(
5076
+ return transformDocument(
5077
+ filepath,
4905
5078
  contentObject,
4906
- "__collection"
4907
- ) ? {
4908
- collection: tinaSchema.getCollection(
4909
- contentObject["__collection"]
4910
- ),
4911
- template: void 0
4912
- } : tinaSchema.getCollectionAndTemplateByFullPath(filepath, templateName);
4913
- const field = template?.fields.find((field2) => {
4914
- if (field2.type === "string" || field2.type === "rich-text") {
4915
- if (field2.isBody) {
4916
- return true;
4917
- }
4918
- }
4919
- return false;
4920
- });
4921
- let data = contentObject;
4922
- if ((extension === ".md" || extension === ".mdx") && field) {
4923
- if (hasOwnProperty(contentObject, "$_body")) {
4924
- const { $_body, ...rest } = contentObject;
4925
- data = rest;
4926
- data[field.name] = $_body;
4927
- }
4928
- }
4929
- return {
4930
- ...data,
4931
- _collection: collection.name,
4932
- _keepTemplateKey: !!collection.templates,
4933
- _template: template?.namespace ? lastItem(template?.namespace) : void 0,
4934
- _relativePath: filepath.replace(collection.path, "").replace(/^\/|\/$/g, ""),
4935
- _id: filepath
4936
- };
5079
+ await this.getSchema(this.level)
5080
+ );
4937
5081
  }
4938
5082
  };
4939
5083
  this.addPendingDocument = async (filepath, data) => {
4940
5084
  await this.initLevel();
4941
5085
  const dataFields = await this.formatBodyOnPayload(filepath, data);
4942
5086
  const collection = await this.collectionForPath(filepath);
5087
+ if (!collection) {
5088
+ throw new GraphQLError4(`Unable to find collection for ${filepath}`);
5089
+ }
4943
5090
  const stringifiedFile = await this.stringifyFile(
4944
5091
  filepath,
4945
5092
  dataFields,
4946
5093
  collection
4947
5094
  );
4948
- let collectionIndexDefinitions;
4949
- if (collection) {
4950
- const indexDefinitions = await this.getIndexDefinitions(this.level);
4951
- collectionIndexDefinitions = indexDefinitions?.[collection.name];
4952
- }
5095
+ const indexDefinitions = await this.getIndexDefinitions(this.level);
5096
+ const collectionIndexDefinitions = indexDefinitions?.[collection.name];
4953
5097
  const normalizedPath = normalizePath(filepath);
4954
5098
  if (this.bridge) {
4955
5099
  await this.bridge.put(normalizedPath, stringifiedFile);
@@ -5026,9 +5170,12 @@ var Database = class {
5026
5170
  const normalizedPath = normalizePath(filepath);
5027
5171
  const dataFields = await this.formatBodyOnPayload(filepath, data);
5028
5172
  const collection = await this.collectionForPath(filepath);
5173
+ if (!collection) {
5174
+ throw new GraphQLError4(`Unable to find collection for ${filepath}.`);
5175
+ }
5029
5176
  if (collection.match?.exclude || collection.match?.include) {
5030
5177
  const matches = this.tinaSchema.getMatches({ collection });
5031
- const match = micromatch.isMatch(filepath, matches);
5178
+ const match = micromatch2.isMatch(filepath, matches);
5032
5179
  if (!match) {
5033
5180
  throw new GraphQLError4(
5034
5181
  `File ${filepath} does not match collection ${collection.name} glob ${matches.join(
@@ -5117,8 +5264,10 @@ var Database = class {
5117
5264
  }
5118
5265
  };
5119
5266
  this.formatBodyOnPayload = async (filepath, data) => {
5120
- const tinaSchema = await this.getSchema(this.level);
5121
- const collection = tinaSchema.getCollectionByFullPath(filepath);
5267
+ const collection = await this.collectionForPath(filepath);
5268
+ if (!collection) {
5269
+ throw new Error(`Unable to find collection for path ${filepath}`);
5270
+ }
5122
5271
  const { template } = await this.getTemplateDetailsForFile(collection, data);
5123
5272
  const bodyField = template.fields.find((field) => {
5124
5273
  if (field.type === "string" || field.type === "rich-text") {
@@ -5148,7 +5297,7 @@ var Database = class {
5148
5297
  );
5149
5298
  const writeTemplateKey = templateDetails.info.type === "union";
5150
5299
  const aliasedData = applyNameOverrides(templateDetails.template, payload);
5151
- const extension = path3.extname(filepath);
5300
+ const extension = path4.extname(filepath);
5152
5301
  const stringifiedFile = stringifyFile(
5153
5302
  aliasedData,
5154
5303
  extension,
@@ -5164,6 +5313,9 @@ var Database = class {
5164
5313
  const data = await this.get(filepath);
5165
5314
  const dataFields = await this.formatBodyOnPayload(filepath, data);
5166
5315
  const collection = await this.collectionForPath(filepath);
5316
+ if (!collection) {
5317
+ throw new Error(`Unable to find collection for path ${filepath}`);
5318
+ }
5167
5319
  const stringifiedFile = await this.stringifyFile(
5168
5320
  filepath,
5169
5321
  dataFields,
@@ -5174,7 +5326,7 @@ var Database = class {
5174
5326
  this.getLookup = async (returnType) => {
5175
5327
  await this.initLevel();
5176
5328
  const lookupPath = normalizePath(
5177
- path3.join(this.getGeneratedFolder(), `_lookup.json`)
5329
+ path4.join(this.getGeneratedFolder(), `_lookup.json`)
5178
5330
  );
5179
5331
  if (!this._lookup) {
5180
5332
  const _lookup = await this.level.sublevel(
@@ -5188,7 +5340,7 @@ var Database = class {
5188
5340
  this.getGraphQLSchema = async () => {
5189
5341
  await this.initLevel();
5190
5342
  const graphqlPath = normalizePath(
5191
- path3.join(this.getGeneratedFolder(), `_graphql.json`)
5343
+ path4.join(this.getGeneratedFolder(), `_graphql.json`)
5192
5344
  );
5193
5345
  return await this.level.sublevel(
5194
5346
  CONTENT_ROOT_PREFIX,
@@ -5200,7 +5352,7 @@ var Database = class {
5200
5352
  throw new Error(`No bridge configured`);
5201
5353
  }
5202
5354
  const graphqlPath = normalizePath(
5203
- path3.join(this.getGeneratedFolder(), `_graphql.json`)
5355
+ path4.join(this.getGeneratedFolder(), `_graphql.json`)
5204
5356
  );
5205
5357
  const _graphql = await this.bridge.get(graphqlPath);
5206
5358
  return JSON.parse(_graphql);
@@ -5208,7 +5360,7 @@ var Database = class {
5208
5360
  this.getTinaSchema = async (level) => {
5209
5361
  await this.initLevel();
5210
5362
  const schemaPath = normalizePath(
5211
- path3.join(this.getGeneratedFolder(), `_schema.json`)
5363
+ path4.join(this.getGeneratedFolder(), `_schema.json`)
5212
5364
  );
5213
5365
  return await (level || this.level).sublevel(
5214
5366
  CONTENT_ROOT_PREFIX,
@@ -5224,7 +5376,7 @@ var Database = class {
5224
5376
  if (!schema) {
5225
5377
  throw new Error(
5226
5378
  `Unable to get schema from level db: ${normalizePath(
5227
- path3.join(this.getGeneratedFolder(), `_schema.json`)
5379
+ path4.join(this.getGeneratedFolder(), `_schema.json`)
5228
5380
  )}`
5229
5381
  );
5230
5382
  }
@@ -5438,7 +5590,7 @@ var Database = class {
5438
5590
  lookup = lookupFromLockFile || JSON.parse(
5439
5591
  await this.bridge.get(
5440
5592
  normalizePath(
5441
- path3.join(this.getGeneratedFolder(), "_lookup.json")
5593
+ path4.join(this.getGeneratedFolder(), "_lookup.json")
5442
5594
  )
5443
5595
  )
5444
5596
  );
@@ -5462,15 +5614,15 @@ var Database = class {
5462
5614
  }
5463
5615
  const contentRootLevel = nextLevel.sublevel(CONTENT_ROOT_PREFIX, SUBLEVEL_OPTIONS);
5464
5616
  await contentRootLevel.put(
5465
- normalizePath(path3.join(this.getGeneratedFolder(), "_graphql.json")),
5617
+ normalizePath(path4.join(this.getGeneratedFolder(), "_graphql.json")),
5466
5618
  graphQLSchema
5467
5619
  );
5468
5620
  await contentRootLevel.put(
5469
- normalizePath(path3.join(this.getGeneratedFolder(), "_schema.json")),
5621
+ normalizePath(path4.join(this.getGeneratedFolder(), "_schema.json")),
5470
5622
  tinaSchema.schema
5471
5623
  );
5472
5624
  await contentRootLevel.put(
5473
- normalizePath(path3.join(this.getGeneratedFolder(), "_lookup.json")),
5625
+ normalizePath(path4.join(this.getGeneratedFolder(), "_lookup.json")),
5474
5626
  lookup
5475
5627
  );
5476
5628
  const result = await this._indexAllContent(
@@ -5501,8 +5653,9 @@ var Database = class {
5501
5653
  await this.level.batch(operations.splice(0, 25));
5502
5654
  }
5503
5655
  };
5656
+ const tinaSchema = await this.getSchema(this.level);
5504
5657
  await this.indexStatusCallbackWrapper(async () => {
5505
- const { pathsByCollection, nonCollectionPaths, collections } = await this.partitionPathsByCollection(documentPaths);
5658
+ const { pathsByCollection, nonCollectionPaths, collections } = await partitionPathsByCollection(tinaSchema, documentPaths);
5506
5659
  for (const collection of Object.keys(pathsByCollection)) {
5507
5660
  await _deleteIndexContent(
5508
5661
  this,
@@ -5528,18 +5681,25 @@ var Database = class {
5528
5681
  await this.level.batch(operations.splice(0, 25));
5529
5682
  }
5530
5683
  };
5684
+ const tinaSchema = await this.getSchema(this.level);
5531
5685
  await this.indexStatusCallbackWrapper(async () => {
5532
- const { pathsByCollection, nonCollectionPaths, collections } = await this.partitionPathsByCollection(documentPaths);
5533
- for (const collection of Object.keys(pathsByCollection)) {
5534
- await _indexContent(
5535
- this,
5536
- this.level,
5537
- pathsByCollection[collection],
5538
- enqueueOps,
5539
- collections[collection]
5540
- );
5541
- }
5542
- await _indexContent(this, this.level, nonCollectionPaths, enqueueOps);
5686
+ await scanContentByPaths(
5687
+ tinaSchema,
5688
+ documentPaths,
5689
+ async (collection, documentPaths2) => {
5690
+ if (collection) {
5691
+ await _indexContent(
5692
+ this,
5693
+ this.level,
5694
+ documentPaths2,
5695
+ enqueueOps,
5696
+ collection
5697
+ );
5698
+ } else {
5699
+ await _indexContent(this, this.level, documentPaths2, enqueueOps);
5700
+ }
5701
+ }
5702
+ );
5543
5703
  });
5544
5704
  while (operations.length) {
5545
5705
  await this.level.batch(operations.splice(0, 25));
@@ -5548,11 +5708,11 @@ var Database = class {
5548
5708
  this.delete = async (filepath) => {
5549
5709
  await this.initLevel();
5550
5710
  const collection = await this.collectionForPath(filepath);
5551
- let collectionIndexDefinitions;
5552
- if (collection) {
5553
- const indexDefinitions = await this.getIndexDefinitions(this.level);
5554
- collectionIndexDefinitions = indexDefinitions?.[collection.name];
5711
+ if (!collection) {
5712
+ throw new Error(`No collection found for path: ${filepath}`);
5555
5713
  }
5714
+ const indexDefinitions = await this.getIndexDefinitions(this.level);
5715
+ const collectionIndexDefinitions = indexDefinitions?.[collection.name];
5556
5716
  this.level.sublevel(
5557
5717
  CONTENT_ROOT_PREFIX,
5558
5718
  SUBLEVEL_OPTIONS
@@ -5599,7 +5759,6 @@ var Database = class {
5599
5759
  await this.onDelete(normalizePath(filepath));
5600
5760
  };
5601
5761
  this._indexAllContent = async (level, schema) => {
5602
- const warnings = [];
5603
5762
  const tinaSchema = await this.getSchema(level, schema);
5604
5763
  const operations = [];
5605
5764
  const enqueueOps = async (ops) => {
@@ -5609,33 +5768,13 @@ var Database = class {
5609
5768
  await level.batch(batchOps);
5610
5769
  }
5611
5770
  };
5612
- const filesSeen = /* @__PURE__ */ new Map();
5613
- const duplicateFiles = /* @__PURE__ */ new Set();
5614
- await sequential(tinaSchema.getCollections(), async (collection) => {
5615
- const normalPath = normalizePath(collection.path);
5616
- const format = collection.format || "md";
5617
- const documentPaths = await this.bridge.glob(normalPath, format);
5618
- const matches = this.tinaSchema.getMatches({ collection });
5619
- const filteredPaths = matches.length > 0 ? micromatch(documentPaths, matches) : documentPaths;
5620
- filteredPaths.forEach((path5) => {
5621
- if (filesSeen.has(path5)) {
5622
- filesSeen.get(path5).push(collection.name);
5623
- duplicateFiles.add(path5);
5624
- } else {
5625
- filesSeen.set(path5, [collection.name]);
5626
- }
5627
- });
5628
- duplicateFiles.forEach((path5) => {
5629
- warnings.push(
5630
- `"${path5}" Found in multiple collections: ${filesSeen.get(path5).map((collection2) => `"${collection2}"`).join(
5631
- ", "
5632
- )}. This can cause unexpected behavior. We recommend updating the \`match\` property of those collections so that each file is in only one collection.
5633
- This will be an error in the future. See https://tina.io/docs/errors/file-in-mutpliple-collections/
5634
- `
5635
- );
5636
- });
5637
- await _indexContent(this, level, filteredPaths, enqueueOps, collection);
5638
- });
5771
+ const warnings = await scanAllContent(
5772
+ tinaSchema,
5773
+ this.bridge,
5774
+ async (collection, contentPaths) => {
5775
+ await _indexContent(this, level, contentPaths, enqueueOps, collection);
5776
+ }
5777
+ );
5639
5778
  while (operations.length) {
5640
5779
  await level.batch(operations.splice(0, 25));
5641
5780
  }
@@ -5648,24 +5787,6 @@ This will be an error in the future. See https://tina.io/docs/errors/file-in-mut
5648
5787
  this.onPut = config.onPut || defaultOnPut;
5649
5788
  this.onDelete = config.onDelete || defaultOnDelete;
5650
5789
  }
5651
- async partitionPathsByCollection(documentPaths) {
5652
- const pathsByCollection = {};
5653
- const nonCollectionPaths = [];
5654
- const collections = {};
5655
- for (const documentPath of documentPaths) {
5656
- const collection = await this.collectionForPath(documentPath);
5657
- if (collection) {
5658
- if (!pathsByCollection[collection.name]) {
5659
- pathsByCollection[collection.name] = [];
5660
- }
5661
- collections[collection.name] = collection;
5662
- pathsByCollection[collection.name].push(documentPath);
5663
- } else {
5664
- nonCollectionPaths.push(documentPath);
5665
- }
5666
- }
5667
- return { pathsByCollection, nonCollectionPaths, collections };
5668
- }
5669
5790
  async updateDatabaseVersion(version) {
5670
5791
  const metadataLevel = this.rootLevel.sublevel("_metadata", SUBLEVEL_OPTIONS);
5671
5792
  await metadataLevel.put("metadata", { version });
@@ -5685,7 +5806,10 @@ This will be an error in the future. See https://tina.io/docs/errors/file-in-mut
5685
5806
  let version = await this.getDatabaseVersion();
5686
5807
  if (!version) {
5687
5808
  version = "";
5688
- await this.updateDatabaseVersion(version);
5809
+ try {
5810
+ await this.updateDatabaseVersion(version);
5811
+ } catch (e) {
5812
+ }
5689
5813
  }
5690
5814
  this.level = this.rootLevel.sublevel(version, SUBLEVEL_OPTIONS);
5691
5815
  }
@@ -5738,9 +5862,6 @@ This will be an error in the future. See https://tina.io/docs/errors/file-in-mut
5738
5862
  }
5739
5863
  }
5740
5864
  };
5741
- function hasOwnProperty(obj, prop) {
5742
- return obj.hasOwnProperty(prop);
5743
- }
5744
5865
  var _indexContent = async (database, level, documentPaths, enqueueOps, collection) => {
5745
5866
  let collectionIndexDefinitions;
5746
5867
  let collectionPath;
@@ -5760,29 +5881,17 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
5760
5881
  const folderTreeBuilder = new FolderTreeBuilder();
5761
5882
  await sequential(documentPaths, async (filepath) => {
5762
5883
  try {
5763
- const dataString = await database.bridge.get(normalizePath(filepath));
5764
- const data = parseFile(
5765
- dataString,
5766
- path3.extname(filepath),
5767
- (yup3) => yup3.object({}),
5768
- {
5769
- frontmatterDelimiters: collection?.frontmatterDelimiters,
5770
- frontmatterFormat: collection?.frontmatterFormat
5771
- }
5884
+ const aliasedData = await loadAndParseWithAliases(
5885
+ database.bridge,
5886
+ filepath,
5887
+ collection,
5888
+ templateInfo
5772
5889
  );
5773
- const template = getTemplateForFile(templateInfo, data);
5774
- if (!template) {
5775
- console.warn(
5776
- `Document: ${filepath} has an ambiguous template, skipping from indexing`
5777
- );
5778
- return;
5779
- }
5780
5890
  const normalizedPath = normalizePath(filepath);
5781
5891
  const folderKey = folderTreeBuilder.update(
5782
5892
  normalizedPath,
5783
5893
  collectionPath || ""
5784
5894
  );
5785
- const aliasedData = templateInfo ? replaceNameOverrides(template, data) : data;
5786
5895
  await enqueueOps([
5787
5896
  ...makeIndexOpsForDocument(
5788
5897
  normalizedPath,
@@ -5814,7 +5923,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
5814
5923
  throw new TinaFetchError(`Unable to seed ${filepath}`, {
5815
5924
  originalError: error,
5816
5925
  file: filepath,
5817
- collection: collection.name,
5926
+ collection: collection?.name,
5818
5927
  stack: error.stack
5819
5928
  });
5820
5929
  }
@@ -5898,27 +6007,6 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
5898
6007
  );
5899
6008
  }
5900
6009
  };
5901
- var getTemplateForFile = (templateInfo, data) => {
5902
- if (templateInfo.type === "object") {
5903
- return templateInfo.template;
5904
- }
5905
- if (templateInfo.type === "union") {
5906
- if (hasOwnProperty(data, "_template")) {
5907
- const template = templateInfo.templates.find(
5908
- (t) => lastItem(t.namespace) === data._template
5909
- );
5910
- if (!template) {
5911
- throw new Error(
5912
- `Unable to find template "${data._template}". Possible templates are: ${templateInfo.templates.map((template2) => `"${template2.name}"`).join(", ")}.`
5913
- );
5914
- }
5915
- return template;
5916
- } else {
5917
- return void 0;
5918
- }
5919
- }
5920
- throw new Error(`Unable to determine template`);
5921
- };
5922
6010
 
5923
6011
  // src/level/tinaLevel.ts
5924
6012
  import { ManyLevelGuest } from "many-level";
@@ -5944,7 +6032,7 @@ var TinaLevelClient = class extends ManyLevelGuest {
5944
6032
  // src/database/bridge/filesystem.ts
5945
6033
  import fs from "fs-extra";
5946
6034
  import fg from "fast-glob";
5947
- import path4 from "path";
6035
+ import path5 from "path";
5948
6036
  import normalize from "normalize-path";
5949
6037
  var FilesystemBridge = class {
5950
6038
  constructor(rootPath, outputPath) {
@@ -5952,9 +6040,9 @@ var FilesystemBridge = class {
5952
6040
  this.outputPath = outputPath || rootPath;
5953
6041
  }
5954
6042
  async glob(pattern, extension) {
5955
- const basePath = path4.join(this.outputPath, ...pattern.split("/"));
6043
+ const basePath = path5.join(this.outputPath, ...pattern.split("/"));
5956
6044
  const items = await fg(
5957
- path4.join(basePath, "**", `/*.${extension}`).replace(/\\/g, "/"),
6045
+ path5.join(basePath, "**", `/*.${extension}`).replace(/\\/g, "/"),
5958
6046
  {
5959
6047
  dot: true,
5960
6048
  ignore: ["**/node_modules/**"]
@@ -5966,14 +6054,14 @@ var FilesystemBridge = class {
5966
6054
  });
5967
6055
  }
5968
6056
  async delete(filepath) {
5969
- await fs.remove(path4.join(this.outputPath, filepath));
6057
+ await fs.remove(path5.join(this.outputPath, filepath));
5970
6058
  }
5971
6059
  async get(filepath) {
5972
- return fs.readFileSync(path4.join(this.outputPath, filepath)).toString();
6060
+ return fs.readFileSync(path5.join(this.outputPath, filepath)).toString();
5973
6061
  }
5974
6062
  async put(filepath, data, basePathOverride) {
5975
6063
  const basePath = basePathOverride || this.outputPath;
5976
- await fs.outputFileSync(path4.join(basePath, filepath), data);
6064
+ await fs.outputFileSync(path5.join(basePath, filepath), data);
5977
6065
  }
5978
6066
  };
5979
6067
  var AuditFileSystemBridge = class extends FilesystemBridge {
@@ -6057,7 +6145,7 @@ var IsomorphicBridge = class {
6057
6145
  async listEntries({
6058
6146
  pattern,
6059
6147
  entry,
6060
- path: path5,
6148
+ path: path6,
6061
6149
  results
6062
6150
  }) {
6063
6151
  const treeResult = await git.readTree({
@@ -6067,7 +6155,7 @@ var IsomorphicBridge = class {
6067
6155
  });
6068
6156
  const children = [];
6069
6157
  for (const childEntry of treeResult.tree) {
6070
- const childPath = path5 ? `${path5}/${childEntry.path}` : childEntry.path;
6158
+ const childPath = path6 ? `${path6}/${childEntry.path}` : childEntry.path;
6071
6159
  if (childEntry.type === "tree") {
6072
6160
  children.push(childEntry);
6073
6161
  } else {
@@ -6077,7 +6165,7 @@ var IsomorphicBridge = class {
6077
6165
  }
6078
6166
  }
6079
6167
  for (const childEntry of children) {
6080
- const childPath = path5 ? `${path5}/${childEntry.path}` : childEntry.path;
6168
+ const childPath = path6 ? `${path6}/${childEntry.path}` : childEntry.path;
6081
6169
  await this.listEntries({
6082
6170
  pattern,
6083
6171
  entry: childEntry,
@@ -6086,17 +6174,17 @@ var IsomorphicBridge = class {
6086
6174
  });
6087
6175
  }
6088
6176
  }
6089
- async resolvePathEntries(path5, ref) {
6090
- let pathParts = path5.split("/");
6177
+ async resolvePathEntries(path6, ref) {
6178
+ let pathParts = path6.split("/");
6091
6179
  const result = await git.walk({
6092
6180
  ...this.isomorphicConfig,
6093
6181
  map: async (filepath, [head]) => {
6094
6182
  if (head._fullpath === ".") {
6095
6183
  return head;
6096
6184
  }
6097
- if (path5.startsWith(filepath)) {
6098
- if (dirname(path5) === dirname(filepath)) {
6099
- if (path5 === filepath) {
6185
+ if (path6.startsWith(filepath)) {
6186
+ if (dirname(path6) === dirname(filepath)) {
6187
+ if (path6 === filepath) {
6100
6188
  return head;
6101
6189
  }
6102
6190
  } else {
@@ -6116,7 +6204,7 @@ var IsomorphicBridge = class {
6116
6204
  }
6117
6205
  return { pathParts, pathEntries };
6118
6206
  }
6119
- async updateTreeHierarchy(existingOid, updatedOid, path5, type, pathEntries, pathParts) {
6207
+ async updateTreeHierarchy(existingOid, updatedOid, path6, type, pathEntries, pathParts) {
6120
6208
  const lastIdx = pathEntries.length - 1;
6121
6209
  const parentEntry = pathEntries[lastIdx];
6122
6210
  const parentPath = pathParts[lastIdx];
@@ -6131,7 +6219,7 @@ var IsomorphicBridge = class {
6131
6219
  cache: this.cache
6132
6220
  });
6133
6221
  tree = existingOid ? treeResult.tree.map((entry) => {
6134
- if (entry.path === path5) {
6222
+ if (entry.path === path6) {
6135
6223
  entry.oid = updatedOid;
6136
6224
  }
6137
6225
  return entry;
@@ -6140,7 +6228,7 @@ var IsomorphicBridge = class {
6140
6228
  {
6141
6229
  oid: updatedOid,
6142
6230
  type,
6143
- path: path5,
6231
+ path: path6,
6144
6232
  mode
6145
6233
  }
6146
6234
  ];
@@ -6149,7 +6237,7 @@ var IsomorphicBridge = class {
6149
6237
  {
6150
6238
  oid: updatedOid,
6151
6239
  type,
6152
- path: path5,
6240
+ path: path6,
6153
6241
  mode
6154
6242
  }
6155
6243
  ];
@@ -6250,7 +6338,7 @@ var IsomorphicBridge = class {
6250
6338
  path: parentPath,
6251
6339
  results
6252
6340
  });
6253
- return results.map((path5) => this.unqualifyPath(path5)).filter((path5) => path5.endsWith(extension));
6341
+ return results.map((path6) => this.unqualifyPath(path6)).filter((path6) => path6.endsWith(extension));
6254
6342
  }
6255
6343
  async delete(filepath) {
6256
6344
  const ref = await this.getRef();
@@ -6401,8 +6489,13 @@ export {
6401
6489
  createDatabase,
6402
6490
  createSchema,
6403
6491
  handleFetchErrorError,
6492
+ loadAndParseWithAliases,
6404
6493
  parseFile,
6405
6494
  resolve,
6495
+ scanAllContent,
6496
+ scanContentByPaths,
6406
6497
  sequential,
6407
- stringifyFile
6498
+ stringifyFile,
6499
+ transformDocument,
6500
+ transformDocumentIntoPayload
6408
6501
  };