@tinacms/graphql 1.4.12 → 1.4.14

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.
@@ -18,6 +18,7 @@ export declare type BinaryFilter = {
18
18
  operator: OP.EQ | OP.GT | OP.LT | OP.GTE | OP.LTE | OP.STARTS_WITH | OP.IN;
19
19
  type: string;
20
20
  pad?: PadDefinition;
21
+ list: boolean;
21
22
  };
22
23
  export declare type TernaryFilter = {
23
24
  pathExpression: string;
@@ -27,12 +28,14 @@ export declare type TernaryFilter = {
27
28
  rightOperator: OP.LT | OP.LTE;
28
29
  type: string;
29
30
  pad?: PadDefinition;
31
+ list: boolean;
30
32
  };
31
33
  export declare type IndexDefinition = {
32
34
  fields: {
33
35
  name: string;
34
36
  type?: string;
35
37
  pad?: PadDefinition;
38
+ list: boolean;
36
39
  }[];
37
40
  };
38
41
  export declare type PadDefinition = {
@@ -16,6 +16,7 @@ export declare type DelOp = {
16
16
  sublevel?: AbstractSublevel<Level, Buffer | Uint8Array | string, string, Record<string, Record<string, any>>>;
17
17
  };
18
18
  export declare type BatchOp = PutOp | DelOp;
19
+ export declare const ARRAY_ITEM_VALUE_SEPARATOR = ",";
19
20
  export declare const INDEX_KEY_FIELD_SEPARATOR = "\u001D";
20
21
  export declare const CONTENT_ROOT_PREFIX = "~";
21
22
  export declare const SUBLEVEL_OPTIONS: AbstractSublevelOptions<string, Record<string, any>>;
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.12",
2528
+ version: "1.4.14",
2529
2529
  main: "dist/index.js",
2530
2530
  module: "dist/index.es.js",
2531
2531
  typings: "dist/index.d.ts",
@@ -3001,6 +3001,7 @@ var collectConditionsForField = (fieldName, field, filterNode, pathExpression, c
3001
3001
  filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
3002
3002
  filterExpression: {
3003
3003
  _type: field.type,
3004
+ _list: !!field.list,
3004
3005
  ...filterNode
3005
3006
  }
3006
3007
  });
@@ -3087,6 +3088,7 @@ import { JSONPath } from "jsonpath-plus";
3087
3088
  import sha from "js-sha1";
3088
3089
 
3089
3090
  // src/database/level.ts
3091
+ var ARRAY_ITEM_VALUE_SEPARATOR = ",";
3090
3092
  var INDEX_KEY_FIELD_SEPARATOR = "";
3091
3093
  var CONTENT_ROOT_PREFIX = "~";
3092
3094
  var SUBLEVEL_OPTIONS = {
@@ -3133,6 +3135,97 @@ var LevelProxy = class {
3133
3135
 
3134
3136
  // src/database/datalayer.ts
3135
3137
  import path from "path";
3138
+
3139
+ // src/database/util.ts
3140
+ import toml from "@iarna/toml";
3141
+ import yaml from "js-yaml";
3142
+ import matter from "gray-matter";
3143
+ import { normalizePath } from "@tinacms/schema-tools";
3144
+ var matterEngines = {
3145
+ toml: {
3146
+ parse: (val) => toml.parse(val),
3147
+ stringify: (val) => toml.stringify(val)
3148
+ }
3149
+ };
3150
+ var stringifyFile = (content, format, keepTemplateKey, markdownParseConfig) => {
3151
+ const {
3152
+ _relativePath,
3153
+ _keepTemplateKey,
3154
+ _id,
3155
+ _template,
3156
+ _collection,
3157
+ $_body,
3158
+ ...rest
3159
+ } = content;
3160
+ const extra = {};
3161
+ if (keepTemplateKey) {
3162
+ extra["_template"] = _template;
3163
+ }
3164
+ const strippedContent = { ...rest, ...extra };
3165
+ switch (format) {
3166
+ case ".markdown":
3167
+ case ".mdx":
3168
+ case ".md":
3169
+ const ok = matter.stringify(
3170
+ typeof $_body === "undefined" ? "" : `
3171
+ ${$_body}`,
3172
+ strippedContent,
3173
+ {
3174
+ language: markdownParseConfig?.frontmatterFormat ?? "yaml",
3175
+ engines: matterEngines,
3176
+ delimiters: markdownParseConfig?.frontmatterDelimiters ?? "---"
3177
+ }
3178
+ );
3179
+ return ok;
3180
+ case ".json":
3181
+ return JSON.stringify(strippedContent, null, 2);
3182
+ case ".yaml":
3183
+ case ".yml":
3184
+ return yaml.safeDump(strippedContent);
3185
+ case ".toml":
3186
+ return toml.stringify(strippedContent);
3187
+ default:
3188
+ throw new Error(`Must specify a valid format, got ${format}`);
3189
+ }
3190
+ };
3191
+ var parseFile = (content, format, yupSchema, markdownParseConfig) => {
3192
+ switch (format) {
3193
+ case ".markdown":
3194
+ case ".mdx":
3195
+ case ".md":
3196
+ const contentJSON = matter(content || "", {
3197
+ language: markdownParseConfig?.frontmatterFormat ?? "yaml",
3198
+ delimiters: markdownParseConfig?.frontmatterDelimiters ?? "---",
3199
+ engines: matterEngines
3200
+ });
3201
+ const markdownData = {
3202
+ ...contentJSON.data,
3203
+ $_body: contentJSON.content
3204
+ };
3205
+ assertShape(markdownData, yupSchema);
3206
+ return markdownData;
3207
+ case ".json":
3208
+ if (!content) {
3209
+ return {};
3210
+ }
3211
+ return JSON.parse(content);
3212
+ case ".toml":
3213
+ if (!content) {
3214
+ return {};
3215
+ }
3216
+ return toml.parse(content);
3217
+ case ".yaml":
3218
+ case ".yml":
3219
+ if (!content) {
3220
+ return {};
3221
+ }
3222
+ return yaml.safeLoad(content);
3223
+ default:
3224
+ throw new Error(`Must specify a valid format, got ${format}`);
3225
+ }
3226
+ };
3227
+
3228
+ // src/database/datalayer.ts
3136
3229
  var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
3137
3230
  var DEFAULT_NUMERIC_LPAD = 4;
3138
3231
  var applyPadding = (input, pad) => {
@@ -3179,10 +3272,24 @@ var makeKeyForField = (definition, data, stringEscaper2, maxStringLength = 100)
3179
3272
  for (const field of definition.fields) {
3180
3273
  if (field.name in data && data[field.name] !== void 0 && data[field.name] !== null) {
3181
3274
  const rawValue = data[field.name];
3182
- const resolvedValue = String(
3183
- field.type === "datetime" ? new Date(rawValue).getTime() : field.type === "string" ? stringEscaper2(rawValue) : rawValue
3184
- ).substring(0, maxStringLength);
3185
- valueParts.push(applyPadding(resolvedValue, field.pad));
3275
+ let resolvedValue;
3276
+ if (field.type === "datetime") {
3277
+ resolvedValue = String(new Date(rawValue).getTime());
3278
+ } else {
3279
+ if (field.type === "string") {
3280
+ const escapedString = stringEscaper2(rawValue);
3281
+ if (Array.isArray(escapedString)) {
3282
+ resolvedValue = escapedString.sort().join(ARRAY_ITEM_VALUE_SEPARATOR);
3283
+ } else {
3284
+ resolvedValue = escapedString;
3285
+ }
3286
+ } else {
3287
+ resolvedValue = String(rawValue);
3288
+ }
3289
+ }
3290
+ valueParts.push(
3291
+ applyPadding(resolvedValue.substring(0, maxStringLength), field.pad)
3292
+ );
3186
3293
  } else {
3187
3294
  return null;
3188
3295
  }
@@ -3249,12 +3356,96 @@ var coerceFilterChainOperands = (filterChain, escapeString = stringEscaper) => {
3249
3356
  }
3250
3357
  return result;
3251
3358
  };
3359
+ function operatorMatchesBinaryFilter(operator, operands, filter) {
3360
+ let matches = false;
3361
+ switch (operator) {
3362
+ case "eq" /* EQ */:
3363
+ if (operands.findIndex((operand) => operand === filter.rightOperand) >= 0) {
3364
+ matches = true;
3365
+ }
3366
+ break;
3367
+ case "gt" /* GT */:
3368
+ for (const operand of operands) {
3369
+ if (operand > filter.rightOperand) {
3370
+ matches = true;
3371
+ break;
3372
+ }
3373
+ }
3374
+ break;
3375
+ case "lt" /* LT */:
3376
+ for (const operand of operands) {
3377
+ if (operand < filter.rightOperand) {
3378
+ matches = true;
3379
+ break;
3380
+ }
3381
+ }
3382
+ break;
3383
+ case "gte" /* GTE */:
3384
+ for (const operand of operands) {
3385
+ if (operand >= filter.rightOperand) {
3386
+ matches = true;
3387
+ break;
3388
+ }
3389
+ }
3390
+ break;
3391
+ case "lte" /* LTE */:
3392
+ for (const operand of operands) {
3393
+ if (operand <= filter.rightOperand) {
3394
+ matches = true;
3395
+ break;
3396
+ }
3397
+ }
3398
+ break;
3399
+ case "in" /* IN */:
3400
+ for (const operand of operands) {
3401
+ if (filter.rightOperand.indexOf(operand) >= 0) {
3402
+ matches = true;
3403
+ break;
3404
+ }
3405
+ }
3406
+ break;
3407
+ case "startsWith" /* STARTS_WITH */:
3408
+ for (const operand of operands) {
3409
+ if (operand.startsWith(filter.rightOperand)) {
3410
+ matches = true;
3411
+ break;
3412
+ }
3413
+ }
3414
+ break;
3415
+ default:
3416
+ throw new Error(`unexpected operator ${operator}`);
3417
+ }
3418
+ return matches;
3419
+ }
3420
+ function operatorMatchesTernaryFilter(operands, rightOperator, rightOperand, leftOperator, leftOperand) {
3421
+ let matches = false;
3422
+ for (const operand of operands) {
3423
+ let rightMatches = false;
3424
+ let leftMatches = false;
3425
+ if (rightOperator === "lte" /* LTE */ && operand <= rightOperand) {
3426
+ rightMatches = true;
3427
+ } else if (rightOperator === "lt" /* LT */ && operand < rightOperand) {
3428
+ rightMatches = true;
3429
+ }
3430
+ if (leftOperator === "gte" /* GTE */ && operand >= leftOperand) {
3431
+ leftMatches = true;
3432
+ } else if (leftOperator === "gt" /* GT */ && operand > leftOperand) {
3433
+ leftMatches = true;
3434
+ }
3435
+ if (rightMatches && leftMatches) {
3436
+ matches = true;
3437
+ break;
3438
+ }
3439
+ }
3440
+ return matches;
3441
+ }
3252
3442
  var makeFilter = ({
3253
3443
  filterChain
3254
3444
  }) => {
3255
3445
  return (values) => {
3256
3446
  for (const filter of filterChain) {
3257
3447
  const dataType = filter.type;
3448
+ const isList = filter.list;
3258
3449
  const resolvedValues = JSONPath({
3259
3450
  path: filter.pathExpression,
3260
3451
  json: values
@@ -3266,99 +3457,74 @@ var makeFilter = ({
3266
3457
  if (dataType === "string" || dataType === "reference") {
3267
3458
  operands = resolvedValues;
3268
3459
  } else if (dataType === "number") {
3269
- operands = resolvedValues.map((resolvedValue) => Number(resolvedValue));
3460
+ operands = resolvedValues.map((resolvedValue) => {
3461
+ if (isList) {
3462
+ return resolvedValue.map((listValue) => Number(listValue));
3463
+ }
3464
+ return Number(resolvedValue);
3465
+ });
3270
3466
  } else if (dataType === "datetime") {
3271
3467
  operands = resolvedValues.map((resolvedValue) => {
3468
+ if (isList) {
3469
+ return resolvedValue.map((listValue) => {
3470
+ const coerced2 = new Date(listValue).getTime();
3471
+ return isNaN(coerced2) ? Number(listValue) : coerced2;
3472
+ });
3473
+ }
3272
3474
  const coerced = new Date(resolvedValue).getTime();
3273
3475
  return isNaN(coerced) ? Number(resolvedValue) : coerced;
3274
3476
  });
3275
3477
  } else if (dataType === "boolean") {
3276
- operands = resolvedValues.map(
3277
- (resolvedValue) => typeof resolvedValue === "boolean" && resolvedValue || resolvedValue === "true" || resolvedValue === "1"
3278
- );
3478
+ operands = resolvedValues.map((resolvedValue) => {
3479
+ if (isList) {
3480
+ return resolvedValue.map((listValue) => {
3481
+ return typeof listValue === "boolean" && listValue || listValue === "true" || listValue === "1";
3482
+ });
3483
+ }
3484
+ return typeof resolvedValue === "boolean" && resolvedValue || resolvedValue === "true" || resolvedValue === "1";
3485
+ });
3279
3486
  } else {
3280
3487
  throw new Error(`Unexpected datatype ${dataType}`);
3281
3488
  }
3282
3489
  const { operator } = filter;
3283
3490
  let matches = false;
3284
3491
  if (operator) {
3285
- switch (operator) {
3286
- case "eq" /* EQ */:
3287
- if (operands.findIndex(
3288
- (operand) => operand === filter.rightOperand
3289
- ) >= 0) {
3492
+ if (isList) {
3493
+ for (const operand of operands) {
3494
+ if (operatorMatchesBinaryFilter(operator, operand, filter)) {
3290
3495
  matches = true;
3496
+ break;
3291
3497
  }
3292
- break;
3293
- case "gt" /* GT */:
3294
- for (const operand of operands) {
3295
- if (operand > filter.rightOperand) {
3296
- matches = true;
3297
- break;
3298
- }
3299
- }
3300
- break;
3301
- case "lt" /* LT */:
3302
- for (const operand of operands) {
3303
- if (operand < filter.rightOperand) {
3304
- matches = true;
3305
- break;
3306
- }
3307
- }
3308
- break;
3309
- case "gte" /* GTE */:
3310
- for (const operand of operands) {
3311
- if (operand >= filter.rightOperand) {
3312
- matches = true;
3313
- break;
3314
- }
3315
- }
3316
- break;
3317
- case "lte" /* LTE */:
3318
- for (const operand of operands) {
3319
- if (operand <= filter.rightOperand) {
3320
- matches = true;
3321
- break;
3322
- }
3323
- }
3324
- break;
3325
- case "in" /* IN */:
3326
- for (const operand of operands) {
3327
- if (filter.rightOperand.indexOf(operand) >= 0) {
3328
- matches = true;
3329
- break;
3330
- }
3331
- }
3332
- break;
3333
- case "startsWith" /* STARTS_WITH */:
3334
- for (const operand of operands) {
3335
- if (operand.startsWith(filter.rightOperand)) {
3336
- matches = true;
3337
- break;
3338
- }
3339
- }
3340
- break;
3341
- default:
3342
- throw new Error(`unexpected operator ${operator}`);
3498
+ }
3499
+ } else {
3500
+ if (operatorMatchesBinaryFilter(operator, operands, filter)) {
3501
+ matches = true;
3502
+ }
3343
3503
  }
3344
3504
  } else {
3345
3505
  const { rightOperator, leftOperator, rightOperand, leftOperand } = filter;
3346
- for (const operand of operands) {
3347
- let rightMatches = false;
3348
- let leftMatches = false;
3349
- if (rightOperator === "lte" /* LTE */ && operand <= rightOperand) {
3350
- rightMatches = true;
3351
- } else if (rightOperator === "lt" /* LT */ && operand < rightOperand) {
3352
- rightMatches = true;
3353
- }
3354
- if (leftOperator === "gte" /* GTE */ && operand >= leftOperand) {
3355
- leftMatches = true;
3356
- } else if (leftOperator === "gt" /* GT */ && operand > leftOperand) {
3357
- leftMatches = true;
3506
+ if (isList) {
3507
+ for (const operand of operands) {
3508
+ if (operatorMatchesTernaryFilter(
3509
+ operand,
3510
+ rightOperator,
3511
+ rightOperand,
3512
+ leftOperator,
3513
+ leftOperand
3514
+ )) {
3515
+ matches = true;
3516
+ break;
3517
+ }
3358
3518
  }
3359
- if (rightMatches && leftMatches) {
3519
+ } else {
3520
+ if (operatorMatchesTernaryFilter(
3521
+ operands,
3522
+ rightOperator,
3523
+ rightOperand,
3524
+ leftOperator,
3525
+ leftOperand
3526
+ )) {
3360
3527
  matches = true;
3361
- break;
3362
3528
  }
3363
3529
  }
3364
3530
  }
@@ -3378,7 +3544,7 @@ var makeFilterChain = ({
3378
3544
  }
3379
3545
  for (const condition of conditions) {
3380
3546
  const { filterPath, filterExpression } = condition;
3381
- const { _type, ...keys } = filterExpression;
3547
+ const { _type, _list, ...keys } = filterExpression;
3382
3548
  const [key1, key2, ...extraKeys] = Object.keys(keys);
3383
3549
  if (extraKeys.length) {
3384
3550
  throw new Error(
@@ -3387,6 +3553,7 @@ var makeFilterChain = ({
3387
3553
  }
3388
3554
  if (key1 && !key2) {
3389
3555
  filterChain.push({
3556
+ list: _list,
3390
3557
  pathExpression: filterPath,
3391
3558
  rightOperand: filterExpression[key1],
3392
3559
  operator: inferOperatorFromFilter(key1),
@@ -3407,6 +3574,7 @@ var makeFilterChain = ({
3407
3574
  leftOperand = filterExpression[key2];
3408
3575
  }
3409
3576
  filterChain.push({
3577
+ list: _list,
3410
3578
  pathExpression: filterPath,
3411
3579
  rightOperand,
3412
3580
  leftOperand,
@@ -3516,7 +3684,7 @@ var FolderTreeBuilder = class {
3516
3684
  return this._tree;
3517
3685
  }
3518
3686
  update(documentPath, collectionPath) {
3519
- let folderPath = path.dirname(documentPath);
3687
+ let folderPath = path.dirname(normalizePath(documentPath));
3520
3688
  if (folderPath === ".") {
3521
3689
  folderPath = "";
3522
3690
  }
@@ -3529,7 +3697,7 @@ var FolderTreeBuilder = class {
3529
3697
  if (!this._tree[current2]) {
3530
3698
  this._tree[current2] = /* @__PURE__ */ new Set();
3531
3699
  }
3532
- this._tree[current2].add(path.join(current2, part));
3700
+ this._tree[current2].add(normalizePath(path.join(current2, part)));
3533
3701
  parent.push(part);
3534
3702
  });
3535
3703
  const current = parent.join("/");
@@ -4184,9 +4352,13 @@ var Resolver = class {
4184
4352
  case "string":
4185
4353
  case "boolean":
4186
4354
  case "number":
4187
- case "reference":
4188
4355
  accumulator[field.name] = value;
4189
4356
  break;
4357
+ case "reference":
4358
+ if (value) {
4359
+ accumulator[field.name] = value;
4360
+ }
4361
+ break;
4190
4362
  case "image":
4191
4363
  accumulator[field.name] = resolveMediaRelativeToCloud(
4192
4364
  value,
@@ -4451,7 +4623,7 @@ var resolve = async ({
4451
4623
  );
4452
4624
  return resolver.getDocument(args.id);
4453
4625
  case "multiCollectionDocument":
4454
- if (typeof value === "string") {
4626
+ if (typeof value === "string" && value !== "") {
4455
4627
  return resolver.getDocument(value);
4456
4628
  }
4457
4629
  if (args && args.collection && info.fieldName === "addPendingDocument") {
@@ -4581,95 +4753,6 @@ import path3 from "path";
4581
4753
  import { GraphQLError as GraphQLError4 } from "graphql";
4582
4754
  import micromatch from "micromatch";
4583
4755
 
4584
- // src/database/util.ts
4585
- import toml from "@iarna/toml";
4586
- import yaml from "js-yaml";
4587
- import matter from "gray-matter";
4588
- import { normalizePath } from "@tinacms/schema-tools";
4589
- var matterEngines = {
4590
- toml: {
4591
- parse: (val) => toml.parse(val),
4592
- stringify: (val) => toml.stringify(val)
4593
- }
4594
- };
4595
- var stringifyFile = (content, format, keepTemplateKey, markdownParseConfig) => {
4596
- const {
4597
- _relativePath,
4598
- _keepTemplateKey,
4599
- _id,
4600
- _template,
4601
- _collection,
4602
- $_body,
4603
- ...rest
4604
- } = content;
4605
- const extra = {};
4606
- if (keepTemplateKey) {
4607
- extra["_template"] = _template;
4608
- }
4609
- const strippedContent = { ...rest, ...extra };
4610
- switch (format) {
4611
- case ".markdown":
4612
- case ".mdx":
4613
- case ".md":
4614
- const ok = matter.stringify(
4615
- typeof $_body === "undefined" ? "" : `
4616
- ${$_body}`,
4617
- strippedContent,
4618
- {
4619
- language: markdownParseConfig?.frontmatterFormat ?? "yaml",
4620
- engines: matterEngines,
4621
- delimiters: markdownParseConfig?.frontmatterDelimiters ?? "---"
4622
- }
4623
- );
4624
- return ok;
4625
- case ".json":
4626
- return JSON.stringify(strippedContent, null, 2);
4627
- case ".yaml":
4628
- case ".yml":
4629
- return yaml.safeDump(strippedContent);
4630
- case ".toml":
4631
- return toml.stringify(strippedContent);
4632
- default:
4633
- throw new Error(`Must specify a valid format, got ${format}`);
4634
- }
4635
- };
4636
- var parseFile = (content, format, yupSchema, markdownParseConfig) => {
4637
- switch (format) {
4638
- case ".markdown":
4639
- case ".mdx":
4640
- case ".md":
4641
- const contentJSON = matter(content || "", {
4642
- language: markdownParseConfig?.frontmatterFormat ?? "yaml",
4643
- delimiters: markdownParseConfig?.frontmatterDelimiters ?? "---",
4644
- engines: matterEngines
4645
- });
4646
- const markdownData = {
4647
- ...contentJSON.data,
4648
- $_body: contentJSON.content
4649
- };
4650
- assertShape(markdownData, yupSchema);
4651
- return markdownData;
4652
- case ".json":
4653
- if (!content) {
4654
- return {};
4655
- }
4656
- return JSON.parse(content);
4657
- case ".toml":
4658
- if (!content) {
4659
- return {};
4660
- }
4661
- return toml.parse(content);
4662
- case ".yaml":
4663
- case ".yml":
4664
- if (!content) {
4665
- return {};
4666
- }
4667
- return yaml.safeLoad(content);
4668
- default:
4669
- throw new Error(`Must specify a valid format, got ${format}`);
4670
- }
4671
- };
4672
-
4673
4756
  // src/database/alias-utils.ts
4674
4757
  var replaceBlockAliases = (template, item) => {
4675
4758
  const output = { ...item };
@@ -5169,6 +5252,7 @@ var Database = class {
5169
5252
  {
5170
5253
  name: field.name,
5171
5254
  type: field.type,
5255
+ list: !!field.list,
5172
5256
  pad: field.type === "number" ? { fillString: "0", maxLength: DEFAULT_NUMERIC_LPAD } : void 0
5173
5257
  }
5174
5258
  ]
@@ -5178,12 +5262,16 @@ var Database = class {
5178
5262
  if (collection.indexes) {
5179
5263
  for (const index of collection.indexes) {
5180
5264
  indexDefinitions[index.name] = {
5181
- fields: index.fields.map((indexField) => ({
5182
- name: indexField.name,
5183
- type: collection.fields.find(
5184
- (field) => indexField.name === field.name
5185
- )?.type
5186
- }))
5265
+ fields: index.fields.map((indexField) => {
5266
+ const field = collection.fields.find(
5267
+ (field2) => indexField.name === field2.name
5268
+ );
5269
+ return {
5270
+ name: indexField.name,
5271
+ type: field?.type,
5272
+ list: !!field?.list
5273
+ };
5274
+ })
5187
5275
  };
5188
5276
  }
5189
5277
  }
@@ -5268,10 +5356,27 @@ var Database = class {
5268
5356
  if (!matcher || indexDefinition && matcher.length !== indexDefinition.fields.length + 2) {
5269
5357
  continue;
5270
5358
  }
5271
- const filepath = matcher.groups["_filepath_"];
5272
- if (!itemFilter(
5273
- filterSuffixes ? matcher.groups : indexDefinition ? await rootLevel.get(filepath) : value
5274
- )) {
5359
+ let filepath = matcher.groups["_filepath_"];
5360
+ let itemRecord;
5361
+ if (filterSuffixes) {
5362
+ itemRecord = matcher.groups;
5363
+ for (const field of indexDefinition.fields) {
5364
+ if (itemRecord[field.name]) {
5365
+ if (field.list) {
5366
+ itemRecord[field.name] = itemRecord[field.name].split(
5367
+ ARRAY_ITEM_VALUE_SEPARATOR
5368
+ );
5369
+ }
5370
+ }
5371
+ }
5372
+ } else {
5373
+ if (indexDefinition) {
5374
+ itemRecord = await rootLevel.get(filepath);
5375
+ } else {
5376
+ itemRecord = value;
5377
+ }
5378
+ }
5379
+ if (!itemFilter(itemRecord)) {
5275
5380
  continue;
5276
5381
  }
5277
5382
  if (limit !== -1 && edges.length >= limit) {
@@ -5328,13 +5433,24 @@ var Database = class {
5328
5433
  let nextLevel;
5329
5434
  return await this.indexStatusCallbackWrapper(
5330
5435
  async () => {
5331
- const lookup = lookupFromLockFile || JSON.parse(
5332
- await this.bridge.get(
5333
- normalizePath(
5334
- path3.join(this.getGeneratedFolder(), "_lookup.json")
5436
+ let lookup;
5437
+ try {
5438
+ lookup = lookupFromLockFile || JSON.parse(
5439
+ await this.bridge.get(
5440
+ normalizePath(
5441
+ path3.join(this.getGeneratedFolder(), "_lookup.json")
5442
+ )
5335
5443
  )
5336
- )
5337
- );
5444
+ );
5445
+ } catch (error) {
5446
+ console.error("Error: Unable to find generated lookup file");
5447
+ if (this.tinaDirectory === "tina") {
5448
+ console.error(
5449
+ 'If you are using the .tina folder. Please set {tinaDirectory: ".tina"} in your createDatabase options or migrate to the new tina folder: https://tina.io/blog/tina-config-rearrangements/'
5450
+ );
5451
+ }
5452
+ throw error;
5453
+ }
5338
5454
  let nextVersion;
5339
5455
  if (!this.config.version) {
5340
5456
  await this.level.clear();
@@ -5525,7 +5641,7 @@ This will be an error in the future. See https://tina.io/docs/errors/file-in-mut
5525
5641
  }
5526
5642
  return { warnings };
5527
5643
  };
5528
- this.tinaDirectory = config.tinaDirectory || ".tina";
5644
+ this.tinaDirectory = config.tinaDirectory || "tina";
5529
5645
  this.bridge = config.bridge;
5530
5646
  this.rootLevel = config.level && new LevelProxy(config.level);
5531
5647
  this.indexStatusCallback = config.indexStatusCallback || defaultStatusCallback;
package/dist/index.js CHANGED
@@ -2577,7 +2577,7 @@ var validateField = async (field) => {
2577
2577
  // package.json
2578
2578
  var package_default = {
2579
2579
  name: "@tinacms/graphql",
2580
- version: "1.4.12",
2580
+ version: "1.4.14",
2581
2581
  main: "dist/index.js",
2582
2582
  module: "dist/index.es.js",
2583
2583
  typings: "dist/index.d.ts",
@@ -3047,6 +3047,7 @@ var collectConditionsForField = (fieldName, field, filterNode, pathExpression, c
3047
3047
  filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
3048
3048
  filterExpression: {
3049
3049
  _type: field.type,
3050
+ _list: !!field.list,
3050
3051
  ...filterNode
3051
3052
  }
3052
3053
  });
@@ -3134,6 +3135,7 @@ var import_jsonpath_plus = require("jsonpath-plus");
3134
3135
  var import_js_sha1 = __toESM(require("js-sha1"));
3135
3136
 
3136
3137
  // src/database/level.ts
3138
+ var ARRAY_ITEM_VALUE_SEPARATOR = ",";
3137
3139
  var INDEX_KEY_FIELD_SEPARATOR = "";
3138
3140
  var CONTENT_ROOT_PREFIX = "~";
3139
3141
  var SUBLEVEL_OPTIONS = {
@@ -3180,6 +3182,99 @@ var LevelProxy = class {
3180
3182
 
3181
3183
  // src/database/datalayer.ts
3182
3184
  var import_path = __toESM(require("path"));
3185
+
3186
+ // src/database/util.ts
3187
+ var import_toml = __toESM(require("@iarna/toml"));
3188
+ var import_js_yaml = __toESM(require("js-yaml"));
3189
+ var import_gray_matter = __toESM(require("gray-matter"));
3190
+ var import_schema_tools3 = require("@tinacms/schema-tools");
3191
+ var matterEngines = {
3192
+ toml: {
3193
+ parse: (val) => import_toml.default.parse(val),
3194
+ stringify: (val) => import_toml.default.stringify(val)
3195
+ }
3196
+ };
3197
+ var stringifyFile = (content, format, keepTemplateKey, markdownParseConfig) => {
3198
+ var _a, _b;
3199
+ const {
3200
+ _relativePath,
3201
+ _keepTemplateKey,
3202
+ _id,
3203
+ _template,
3204
+ _collection,
3205
+ $_body,
3206
+ ...rest
3207
+ } = content;
3208
+ const extra = {};
3209
+ if (keepTemplateKey) {
3210
+ extra["_template"] = _template;
3211
+ }
3212
+ const strippedContent = { ...rest, ...extra };
3213
+ switch (format) {
3214
+ case ".markdown":
3215
+ case ".mdx":
3216
+ case ".md":
3217
+ const ok = import_gray_matter.default.stringify(
3218
+ typeof $_body === "undefined" ? "" : `
3219
+ ${$_body}`,
3220
+ strippedContent,
3221
+ {
3222
+ language: (_a = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterFormat) != null ? _a : "yaml",
3223
+ engines: matterEngines,
3224
+ delimiters: (_b = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterDelimiters) != null ? _b : "---"
3225
+ }
3226
+ );
3227
+ return ok;
3228
+ case ".json":
3229
+ return JSON.stringify(strippedContent, null, 2);
3230
+ case ".yaml":
3231
+ case ".yml":
3232
+ return import_js_yaml.default.safeDump(strippedContent);
3233
+ case ".toml":
3234
+ return import_toml.default.stringify(strippedContent);
3235
+ default:
3236
+ throw new Error(`Must specify a valid format, got ${format}`);
3237
+ }
3238
+ };
3239
+ var parseFile = (content, format, yupSchema, markdownParseConfig) => {
3240
+ var _a, _b;
3241
+ switch (format) {
3242
+ case ".markdown":
3243
+ case ".mdx":
3244
+ case ".md":
3245
+ const contentJSON = (0, import_gray_matter.default)(content || "", {
3246
+ language: (_a = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterFormat) != null ? _a : "yaml",
3247
+ delimiters: (_b = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterDelimiters) != null ? _b : "---",
3248
+ engines: matterEngines
3249
+ });
3250
+ const markdownData = {
3251
+ ...contentJSON.data,
3252
+ $_body: contentJSON.content
3253
+ };
3254
+ assertShape(markdownData, yupSchema);
3255
+ return markdownData;
3256
+ case ".json":
3257
+ if (!content) {
3258
+ return {};
3259
+ }
3260
+ return JSON.parse(content);
3261
+ case ".toml":
3262
+ if (!content) {
3263
+ return {};
3264
+ }
3265
+ return import_toml.default.parse(content);
3266
+ case ".yaml":
3267
+ case ".yml":
3268
+ if (!content) {
3269
+ return {};
3270
+ }
3271
+ return import_js_yaml.default.safeLoad(content);
3272
+ default:
3273
+ throw new Error(`Must specify a valid format, got ${format}`);
3274
+ }
3275
+ };
3276
+
3277
+ // src/database/datalayer.ts
3183
3278
  var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
3184
3279
  var DEFAULT_NUMERIC_LPAD = 4;
3185
3280
  var applyPadding = (input, pad) => {
@@ -3226,10 +3321,24 @@ var makeKeyForField = (definition, data, stringEscaper2, maxStringLength = 100)
3226
3321
  for (const field of definition.fields) {
3227
3322
  if (field.name in data && data[field.name] !== void 0 && data[field.name] !== null) {
3228
3323
  const rawValue = data[field.name];
3229
- const resolvedValue = String(
3230
- field.type === "datetime" ? new Date(rawValue).getTime() : field.type === "string" ? stringEscaper2(rawValue) : rawValue
3231
- ).substring(0, maxStringLength);
3232
- valueParts.push(applyPadding(resolvedValue, field.pad));
3324
+ let resolvedValue;
3325
+ if (field.type === "datetime") {
3326
+ resolvedValue = String(new Date(rawValue).getTime());
3327
+ } else {
3328
+ if (field.type === "string") {
3329
+ const escapedString = stringEscaper2(rawValue);
3330
+ if (Array.isArray(escapedString)) {
3331
+ resolvedValue = escapedString.sort().join(ARRAY_ITEM_VALUE_SEPARATOR);
3332
+ } else {
3333
+ resolvedValue = escapedString;
3334
+ }
3335
+ } else {
3336
+ resolvedValue = String(rawValue);
3337
+ }
3338
+ }
3339
+ valueParts.push(
3340
+ applyPadding(resolvedValue.substring(0, maxStringLength), field.pad)
3341
+ );
3233
3342
  } else {
3234
3343
  return null;
3235
3344
  }
@@ -3296,12 +3405,96 @@ var coerceFilterChainOperands = (filterChain, escapeString = stringEscaper) => {
3296
3405
  }
3297
3406
  return result;
3298
3407
  };
3408
+ function operatorMatchesBinaryFilter(operator, operands, filter) {
3409
+ let matches = false;
3410
+ switch (operator) {
3411
+ case "eq" /* EQ */:
3412
+ if (operands.findIndex((operand) => operand === filter.rightOperand) >= 0) {
3413
+ matches = true;
3414
+ }
3415
+ break;
3416
+ case "gt" /* GT */:
3417
+ for (const operand of operands) {
3418
+ if (operand > filter.rightOperand) {
3419
+ matches = true;
3420
+ break;
3421
+ }
3422
+ }
3423
+ break;
3424
+ case "lt" /* LT */:
3425
+ for (const operand of operands) {
3426
+ if (operand < filter.rightOperand) {
3427
+ matches = true;
3428
+ break;
3429
+ }
3430
+ }
3431
+ break;
3432
+ case "gte" /* GTE */:
3433
+ for (const operand of operands) {
3434
+ if (operand >= filter.rightOperand) {
3435
+ matches = true;
3436
+ break;
3437
+ }
3438
+ }
3439
+ break;
3440
+ case "lte" /* LTE */:
3441
+ for (const operand of operands) {
3442
+ if (operand <= filter.rightOperand) {
3443
+ matches = true;
3444
+ break;
3445
+ }
3446
+ }
3447
+ break;
3448
+ case "in" /* IN */:
3449
+ for (const operand of operands) {
3450
+ if (filter.rightOperand.indexOf(operand) >= 0) {
3451
+ matches = true;
3452
+ break;
3453
+ }
3454
+ }
3455
+ break;
3456
+ case "startsWith" /* STARTS_WITH */:
3457
+ for (const operand of operands) {
3458
+ if (operand.startsWith(filter.rightOperand)) {
3459
+ matches = true;
3460
+ break;
3461
+ }
3462
+ }
3463
+ break;
3464
+ default:
3465
+ throw new Error(`unexpected operator ${operator}`);
3466
+ }
3467
+ return matches;
3468
+ }
3469
+ function operatorMatchesTernaryFilter(operands, rightOperator, rightOperand, leftOperator, leftOperand) {
3470
+ let matches = false;
3471
+ for (const operand of operands) {
3472
+ let rightMatches = false;
3473
+ let leftMatches = false;
3474
+ if (rightOperator === "lte" /* LTE */ && operand <= rightOperand) {
3475
+ rightMatches = true;
3476
+ } else if (rightOperator === "lt" /* LT */ && operand < rightOperand) {
3477
+ rightMatches = true;
3478
+ }
3479
+ if (leftOperator === "gte" /* GTE */ && operand >= leftOperand) {
3480
+ leftMatches = true;
3481
+ } else if (leftOperator === "gt" /* GT */ && operand > leftOperand) {
3482
+ leftMatches = true;
3483
+ }
3484
+ if (rightMatches && leftMatches) {
3485
+ matches = true;
3486
+ break;
3487
+ }
3488
+ }
3489
+ return matches;
3490
+ }
3299
3491
  var makeFilter = ({
3300
3492
  filterChain
3301
3493
  }) => {
3302
3494
  return (values) => {
3303
3495
  for (const filter of filterChain) {
3304
3496
  const dataType = filter.type;
3497
+ const isList = filter.list;
3305
3498
  const resolvedValues = (0, import_jsonpath_plus.JSONPath)({
3306
3499
  path: filter.pathExpression,
3307
3500
  json: values
@@ -3313,99 +3506,74 @@ var makeFilter = ({
3313
3506
  if (dataType === "string" || dataType === "reference") {
3314
3507
  operands = resolvedValues;
3315
3508
  } else if (dataType === "number") {
3316
- operands = resolvedValues.map((resolvedValue) => Number(resolvedValue));
3509
+ operands = resolvedValues.map((resolvedValue) => {
3510
+ if (isList) {
3511
+ return resolvedValue.map((listValue) => Number(listValue));
3512
+ }
3513
+ return Number(resolvedValue);
3514
+ });
3317
3515
  } else if (dataType === "datetime") {
3318
3516
  operands = resolvedValues.map((resolvedValue) => {
3517
+ if (isList) {
3518
+ return resolvedValue.map((listValue) => {
3519
+ const coerced2 = new Date(listValue).getTime();
3520
+ return isNaN(coerced2) ? Number(listValue) : coerced2;
3521
+ });
3522
+ }
3319
3523
  const coerced = new Date(resolvedValue).getTime();
3320
3524
  return isNaN(coerced) ? Number(resolvedValue) : coerced;
3321
3525
  });
3322
3526
  } else if (dataType === "boolean") {
3323
- operands = resolvedValues.map(
3324
- (resolvedValue) => typeof resolvedValue === "boolean" && resolvedValue || resolvedValue === "true" || resolvedValue === "1"
3325
- );
3527
+ operands = resolvedValues.map((resolvedValue) => {
3528
+ if (isList) {
3529
+ return resolvedValue.map((listValue) => {
3530
+ return typeof listValue === "boolean" && listValue || listValue === "true" || listValue === "1";
3531
+ });
3532
+ }
3533
+ return typeof resolvedValue === "boolean" && resolvedValue || resolvedValue === "true" || resolvedValue === "1";
3534
+ });
3326
3535
  } else {
3327
3536
  throw new Error(`Unexpected datatype ${dataType}`);
3328
3537
  }
3329
3538
  const { operator } = filter;
3330
3539
  let matches = false;
3331
3540
  if (operator) {
3332
- switch (operator) {
3333
- case "eq" /* EQ */:
3334
- if (operands.findIndex(
3335
- (operand) => operand === filter.rightOperand
3336
- ) >= 0) {
3541
+ if (isList) {
3542
+ for (const operand of operands) {
3543
+ if (operatorMatchesBinaryFilter(operator, operand, filter)) {
3337
3544
  matches = true;
3545
+ break;
3338
3546
  }
3339
- break;
3340
- case "gt" /* GT */:
3341
- for (const operand of operands) {
3342
- if (operand > filter.rightOperand) {
3343
- matches = true;
3344
- break;
3345
- }
3346
- }
3347
- break;
3348
- case "lt" /* LT */:
3349
- for (const operand of operands) {
3350
- if (operand < filter.rightOperand) {
3351
- matches = true;
3352
- break;
3353
- }
3354
- }
3355
- break;
3356
- case "gte" /* GTE */:
3357
- for (const operand of operands) {
3358
- if (operand >= filter.rightOperand) {
3359
- matches = true;
3360
- break;
3361
- }
3362
- }
3363
- break;
3364
- case "lte" /* LTE */:
3365
- for (const operand of operands) {
3366
- if (operand <= filter.rightOperand) {
3367
- matches = true;
3368
- break;
3369
- }
3370
- }
3371
- break;
3372
- case "in" /* IN */:
3373
- for (const operand of operands) {
3374
- if (filter.rightOperand.indexOf(operand) >= 0) {
3375
- matches = true;
3376
- break;
3377
- }
3378
- }
3379
- break;
3380
- case "startsWith" /* STARTS_WITH */:
3381
- for (const operand of operands) {
3382
- if (operand.startsWith(filter.rightOperand)) {
3383
- matches = true;
3384
- break;
3385
- }
3386
- }
3387
- break;
3388
- default:
3389
- throw new Error(`unexpected operator ${operator}`);
3547
+ }
3548
+ } else {
3549
+ if (operatorMatchesBinaryFilter(operator, operands, filter)) {
3550
+ matches = true;
3551
+ }
3390
3552
  }
3391
3553
  } else {
3392
3554
  const { rightOperator, leftOperator, rightOperand, leftOperand } = filter;
3393
- for (const operand of operands) {
3394
- let rightMatches = false;
3395
- let leftMatches = false;
3396
- if (rightOperator === "lte" /* LTE */ && operand <= rightOperand) {
3397
- rightMatches = true;
3398
- } else if (rightOperator === "lt" /* LT */ && operand < rightOperand) {
3399
- rightMatches = true;
3400
- }
3401
- if (leftOperator === "gte" /* GTE */ && operand >= leftOperand) {
3402
- leftMatches = true;
3403
- } else if (leftOperator === "gt" /* GT */ && operand > leftOperand) {
3404
- leftMatches = true;
3555
+ if (isList) {
3556
+ for (const operand of operands) {
3557
+ if (operatorMatchesTernaryFilter(
3558
+ operand,
3559
+ rightOperator,
3560
+ rightOperand,
3561
+ leftOperator,
3562
+ leftOperand
3563
+ )) {
3564
+ matches = true;
3565
+ break;
3566
+ }
3405
3567
  }
3406
- if (rightMatches && leftMatches) {
3568
+ } else {
3569
+ if (operatorMatchesTernaryFilter(
3570
+ operands,
3571
+ rightOperator,
3572
+ rightOperand,
3573
+ leftOperator,
3574
+ leftOperand
3575
+ )) {
3407
3576
  matches = true;
3408
- break;
3409
3577
  }
3410
3578
  }
3411
3579
  }
@@ -3425,7 +3593,7 @@ var makeFilterChain = ({
3425
3593
  }
3426
3594
  for (const condition of conditions) {
3427
3595
  const { filterPath, filterExpression } = condition;
3428
- const { _type, ...keys } = filterExpression;
3596
+ const { _type, _list, ...keys } = filterExpression;
3429
3597
  const [key1, key2, ...extraKeys] = Object.keys(keys);
3430
3598
  if (extraKeys.length) {
3431
3599
  throw new Error(
@@ -3434,6 +3602,7 @@ var makeFilterChain = ({
3434
3602
  }
3435
3603
  if (key1 && !key2) {
3436
3604
  filterChain.push({
3605
+ list: _list,
3437
3606
  pathExpression: filterPath,
3438
3607
  rightOperand: filterExpression[key1],
3439
3608
  operator: inferOperatorFromFilter(key1),
@@ -3454,6 +3623,7 @@ var makeFilterChain = ({
3454
3623
  leftOperand = filterExpression[key2];
3455
3624
  }
3456
3625
  filterChain.push({
3626
+ list: _list,
3457
3627
  pathExpression: filterPath,
3458
3628
  rightOperand,
3459
3629
  leftOperand,
@@ -3563,7 +3733,7 @@ var FolderTreeBuilder = class {
3563
3733
  return this._tree;
3564
3734
  }
3565
3735
  update(documentPath, collectionPath) {
3566
- let folderPath = import_path.default.dirname(documentPath);
3736
+ let folderPath = import_path.default.dirname((0, import_schema_tools3.normalizePath)(documentPath));
3567
3737
  if (folderPath === ".") {
3568
3738
  folderPath = "";
3569
3739
  }
@@ -3576,7 +3746,7 @@ var FolderTreeBuilder = class {
3576
3746
  if (!this._tree[current2]) {
3577
3747
  this._tree[current2] = /* @__PURE__ */ new Set();
3578
3748
  }
3579
- this._tree[current2].add(import_path.default.join(current2, part));
3749
+ this._tree[current2].add((0, import_schema_tools3.normalizePath)(import_path.default.join(current2, part)));
3580
3750
  parent.push(part);
3581
3751
  });
3582
3752
  const current = parent.join("/");
@@ -4232,9 +4402,13 @@ var Resolver = class {
4232
4402
  case "string":
4233
4403
  case "boolean":
4234
4404
  case "number":
4235
- case "reference":
4236
4405
  accumulator[field.name] = value;
4237
4406
  break;
4407
+ case "reference":
4408
+ if (value) {
4409
+ accumulator[field.name] = value;
4410
+ }
4411
+ break;
4238
4412
  case "image":
4239
4413
  accumulator[field.name] = resolveMediaRelativeToCloud(
4240
4414
  value,
@@ -4503,7 +4677,7 @@ var resolve = async ({
4503
4677
  );
4504
4678
  return resolver.getDocument(args.id);
4505
4679
  case "multiCollectionDocument":
4506
- if (typeof value === "string") {
4680
+ if (typeof value === "string" && value !== "") {
4507
4681
  return resolver.getDocument(value);
4508
4682
  }
4509
4683
  if (args && args.collection && info.fieldName === "addPendingDocument") {
@@ -4633,97 +4807,6 @@ var import_path3 = __toESM(require("path"));
4633
4807
  var import_graphql5 = require("graphql");
4634
4808
  var import_micromatch = __toESM(require("micromatch"));
4635
4809
 
4636
- // src/database/util.ts
4637
- var import_toml = __toESM(require("@iarna/toml"));
4638
- var import_js_yaml = __toESM(require("js-yaml"));
4639
- var import_gray_matter = __toESM(require("gray-matter"));
4640
- var import_schema_tools3 = require("@tinacms/schema-tools");
4641
- var matterEngines = {
4642
- toml: {
4643
- parse: (val) => import_toml.default.parse(val),
4644
- stringify: (val) => import_toml.default.stringify(val)
4645
- }
4646
- };
4647
- var stringifyFile = (content, format, keepTemplateKey, markdownParseConfig) => {
4648
- var _a, _b;
4649
- const {
4650
- _relativePath,
4651
- _keepTemplateKey,
4652
- _id,
4653
- _template,
4654
- _collection,
4655
- $_body,
4656
- ...rest
4657
- } = content;
4658
- const extra = {};
4659
- if (keepTemplateKey) {
4660
- extra["_template"] = _template;
4661
- }
4662
- const strippedContent = { ...rest, ...extra };
4663
- switch (format) {
4664
- case ".markdown":
4665
- case ".mdx":
4666
- case ".md":
4667
- const ok = import_gray_matter.default.stringify(
4668
- typeof $_body === "undefined" ? "" : `
4669
- ${$_body}`,
4670
- strippedContent,
4671
- {
4672
- language: (_a = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterFormat) != null ? _a : "yaml",
4673
- engines: matterEngines,
4674
- delimiters: (_b = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterDelimiters) != null ? _b : "---"
4675
- }
4676
- );
4677
- return ok;
4678
- case ".json":
4679
- return JSON.stringify(strippedContent, null, 2);
4680
- case ".yaml":
4681
- case ".yml":
4682
- return import_js_yaml.default.safeDump(strippedContent);
4683
- case ".toml":
4684
- return import_toml.default.stringify(strippedContent);
4685
- default:
4686
- throw new Error(`Must specify a valid format, got ${format}`);
4687
- }
4688
- };
4689
- var parseFile = (content, format, yupSchema, markdownParseConfig) => {
4690
- var _a, _b;
4691
- switch (format) {
4692
- case ".markdown":
4693
- case ".mdx":
4694
- case ".md":
4695
- const contentJSON = (0, import_gray_matter.default)(content || "", {
4696
- language: (_a = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterFormat) != null ? _a : "yaml",
4697
- delimiters: (_b = markdownParseConfig == null ? void 0 : markdownParseConfig.frontmatterDelimiters) != null ? _b : "---",
4698
- engines: matterEngines
4699
- });
4700
- const markdownData = {
4701
- ...contentJSON.data,
4702
- $_body: contentJSON.content
4703
- };
4704
- assertShape(markdownData, yupSchema);
4705
- return markdownData;
4706
- case ".json":
4707
- if (!content) {
4708
- return {};
4709
- }
4710
- return JSON.parse(content);
4711
- case ".toml":
4712
- if (!content) {
4713
- return {};
4714
- }
4715
- return import_toml.default.parse(content);
4716
- case ".yaml":
4717
- case ".yml":
4718
- if (!content) {
4719
- return {};
4720
- }
4721
- return import_js_yaml.default.safeLoad(content);
4722
- default:
4723
- throw new Error(`Must specify a valid format, got ${format}`);
4724
- }
4725
- };
4726
-
4727
4810
  // src/database/alias-utils.ts
4728
4811
  var replaceBlockAliases = (template, item) => {
4729
4812
  const output = { ...item };
@@ -5226,6 +5309,7 @@ var Database = class {
5226
5309
  {
5227
5310
  name: field.name,
5228
5311
  type: field.type,
5312
+ list: !!field.list,
5229
5313
  pad: field.type === "number" ? { fillString: "0", maxLength: DEFAULT_NUMERIC_LPAD } : void 0
5230
5314
  }
5231
5315
  ]
@@ -5236,12 +5320,13 @@ var Database = class {
5236
5320
  for (const index of collection.indexes) {
5237
5321
  indexDefinitions[index.name] = {
5238
5322
  fields: index.fields.map((indexField) => {
5239
- var _a;
5323
+ const field = collection.fields.find(
5324
+ (field2) => indexField.name === field2.name
5325
+ );
5240
5326
  return {
5241
5327
  name: indexField.name,
5242
- type: (_a = collection.fields.find(
5243
- (field) => indexField.name === field.name
5244
- )) == null ? void 0 : _a.type
5328
+ type: field == null ? void 0 : field.type,
5329
+ list: !!(field == null ? void 0 : field.list)
5245
5330
  };
5246
5331
  })
5247
5332
  };
@@ -5329,10 +5414,27 @@ var Database = class {
5329
5414
  if (!matcher || indexDefinition && matcher.length !== indexDefinition.fields.length + 2) {
5330
5415
  continue;
5331
5416
  }
5332
- const filepath = matcher.groups["_filepath_"];
5333
- if (!itemFilter(
5334
- filterSuffixes ? matcher.groups : indexDefinition ? await rootLevel.get(filepath) : value
5335
- )) {
5417
+ let filepath = matcher.groups["_filepath_"];
5418
+ let itemRecord;
5419
+ if (filterSuffixes) {
5420
+ itemRecord = matcher.groups;
5421
+ for (const field of indexDefinition.fields) {
5422
+ if (itemRecord[field.name]) {
5423
+ if (field.list) {
5424
+ itemRecord[field.name] = itemRecord[field.name].split(
5425
+ ARRAY_ITEM_VALUE_SEPARATOR
5426
+ );
5427
+ }
5428
+ }
5429
+ }
5430
+ } else {
5431
+ if (indexDefinition) {
5432
+ itemRecord = await rootLevel.get(filepath);
5433
+ } else {
5434
+ itemRecord = value;
5435
+ }
5436
+ }
5437
+ if (!itemFilter(itemRecord)) {
5336
5438
  continue;
5337
5439
  }
5338
5440
  if (limit !== -1 && edges.length >= limit) {
@@ -5389,13 +5491,24 @@ var Database = class {
5389
5491
  let nextLevel;
5390
5492
  return await this.indexStatusCallbackWrapper(
5391
5493
  async () => {
5392
- const lookup = lookupFromLockFile || JSON.parse(
5393
- await this.bridge.get(
5394
- (0, import_schema_tools3.normalizePath)(
5395
- import_path3.default.join(this.getGeneratedFolder(), "_lookup.json")
5494
+ let lookup;
5495
+ try {
5496
+ lookup = lookupFromLockFile || JSON.parse(
5497
+ await this.bridge.get(
5498
+ (0, import_schema_tools3.normalizePath)(
5499
+ import_path3.default.join(this.getGeneratedFolder(), "_lookup.json")
5500
+ )
5396
5501
  )
5397
- )
5398
- );
5502
+ );
5503
+ } catch (error) {
5504
+ console.error("Error: Unable to find generated lookup file");
5505
+ if (this.tinaDirectory === "tina") {
5506
+ console.error(
5507
+ 'If you are using the .tina folder. Please set {tinaDirectory: ".tina"} in your createDatabase options or migrate to the new tina folder: https://tina.io/blog/tina-config-rearrangements/'
5508
+ );
5509
+ }
5510
+ throw error;
5511
+ }
5399
5512
  let nextVersion;
5400
5513
  if (!this.config.version) {
5401
5514
  await this.level.clear();
@@ -5586,7 +5699,7 @@ This will be an error in the future. See https://tina.io/docs/errors/file-in-mut
5586
5699
  }
5587
5700
  return { warnings };
5588
5701
  };
5589
- this.tinaDirectory = config.tinaDirectory || ".tina";
5702
+ this.tinaDirectory = config.tinaDirectory || "tina";
5590
5703
  this.bridge = config.bridge;
5591
5704
  this.rootLevel = config.level && new LevelProxy(config.level);
5592
5705
  this.indexStatusCallback = config.indexStatusCallback || defaultStatusCallback;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/graphql",
3
- "version": "1.4.12",
3
+ "version": "1.4.14",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.es.js",
6
6
  "typings": "dist/index.d.ts",