@tinacms/graphql 0.0.0-dced6ab-20250611061422 → 0.0.0-dd2089d-20251128055623

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -66,7 +66,7 @@ module.exports = __toCommonJS(index_exports);
66
66
 
67
67
  // src/build.ts
68
68
  var import_graphql2 = require("graphql");
69
- var import_lodash3 = __toESM(require("lodash.uniqby"));
69
+ var import_es_toolkit3 = require("es-toolkit");
70
70
 
71
71
  // src/util.ts
72
72
  var yup = __toESM(require("yup"));
@@ -122,7 +122,7 @@ var flattenDeep = (arr) => arr.flatMap(
122
122
  );
123
123
 
124
124
  // src/ast-builder/index.ts
125
- var import_lodash = __toESM(require("lodash.uniqby"));
125
+ var import_es_toolkit = require("es-toolkit");
126
126
  var SysFieldDefinition = {
127
127
  kind: "Field",
128
128
  name: {
@@ -1037,12 +1037,13 @@ var astBuilder = {
1037
1037
  };
1038
1038
  },
1039
1039
  toGraphQLAst: (ast) => {
1040
- const definitions = (0, import_lodash.default)(
1040
+ const definitions = (0, import_es_toolkit.uniqBy)(
1041
1041
  [
1042
1042
  ...extractInlineTypes(ast.query),
1043
1043
  ...extractInlineTypes(ast.globalTemplates),
1044
1044
  ...ast.definitions
1045
1045
  ],
1046
+ // @ts-ignore - all nodes have a name property in practice
1046
1047
  (field) => field.name.value
1047
1048
  );
1048
1049
  return {
@@ -1065,7 +1066,7 @@ var extractInlineTypes = (item) => {
1065
1066
  const accumulator = [item];
1066
1067
  for (const node of walk(item)) {
1067
1068
  if (node.kind === "UnionTypeDefinition") {
1068
- node.types = (0, import_lodash.default)(node.types, (type) => type.name.value);
1069
+ node.types = (0, import_es_toolkit.uniqBy)(node.types, (type) => type.name.value);
1069
1070
  }
1070
1071
  if (node.kind === "NamedType") {
1071
1072
  if (typeof node.name.value !== "string") {
@@ -2777,7 +2778,7 @@ var Builder = class {
2777
2778
  this._buildDataField = async (field) => {
2778
2779
  const listWarningMsg = `
2779
2780
  WARNING: The user interface for ${field.type} does not support \`list: true\`
2780
- Visit https://tina.io/docs/errors/ui-not-supported/ for more information
2781
+ Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
2781
2782
 
2782
2783
  `;
2783
2784
  switch (field.type) {
@@ -2930,8 +2931,8 @@ var import_schema_tools3 = require("@tinacms/schema-tools");
2930
2931
 
2931
2932
  // src/schema/validate.ts
2932
2933
  var import_schema_tools = require("@tinacms/schema-tools");
2933
- var import_lodash2 = __toESM(require("lodash.clonedeep"));
2934
2934
  var yup2 = __toESM(require("yup"));
2935
+ var import_es_toolkit2 = require("es-toolkit");
2935
2936
  var import_schema_tools2 = require("@tinacms/schema-tools");
2936
2937
  var FIELD_TYPES = [
2937
2938
  "string",
@@ -2946,7 +2947,7 @@ var FIELD_TYPES = [
2946
2947
  ];
2947
2948
  var validateSchema = async (schema) => {
2948
2949
  const schema2 = (0, import_schema_tools.addNamespaceToSchema)(
2949
- (0, import_lodash2.default)(schema)
2950
+ (0, import_es_toolkit2.cloneDeep)(schema)
2950
2951
  );
2951
2952
  const collections = await sequential(
2952
2953
  schema2.collections,
@@ -3083,7 +3084,7 @@ var validateField = async (field) => {
3083
3084
  // package.json
3084
3085
  var package_default = {
3085
3086
  name: "@tinacms/graphql",
3086
- version: "1.5.18",
3087
+ version: "1.6.2",
3087
3088
  main: "dist/index.js",
3088
3089
  module: "dist/index.mjs",
3089
3090
  typings: "dist/index.d.ts",
@@ -3118,6 +3119,7 @@ var package_default = {
3118
3119
  "@tinacms/schema-tools": "workspace:*",
3119
3120
  "abstract-level": "catalog:",
3120
3121
  "date-fns": "^2.30.0",
3122
+ "es-toolkit": "^1.42.0",
3121
3123
  "fast-glob": "catalog:",
3122
3124
  "fs-extra": "catalog:",
3123
3125
  "glob-parent": "catalog:",
@@ -3127,15 +3129,12 @@ var package_default = {
3127
3129
  "js-sha1": "catalog:",
3128
3130
  "js-yaml": "^3.14.1",
3129
3131
  "jsonpath-plus": "catalog:",
3130
- "lodash.clonedeep": "catalog:",
3131
- "lodash.set": "catalog:",
3132
- "lodash.uniqby": "catalog:",
3133
3132
  "many-level": "catalog:",
3134
3133
  micromatch: "catalog:",
3135
3134
  "normalize-path": "catalog:",
3136
3135
  "readable-stream": "catalog:",
3137
3136
  scmp: "catalog:",
3138
- yup: "^0.32.11"
3137
+ yup: "^1.6.1"
3139
3138
  },
3140
3139
  publishConfig: {
3141
3140
  registry: "https://registry.npmjs.org"
@@ -3152,21 +3151,18 @@ var package_default = {
3152
3151
  "@types/express": "catalog:",
3153
3152
  "@types/fs-extra": "^9.0.13",
3154
3153
  "@types/js-yaml": "^3.12.10",
3155
- "@types/lodash.camelcase": "catalog:",
3156
- "@types/lodash.upperfirst": "catalog:",
3157
3154
  "@types/lru-cache": "catalog:",
3158
3155
  "@types/mdast": "catalog:",
3159
3156
  "@types/micromatch": "catalog:",
3160
3157
  "@types/node": "^22.13.1",
3161
3158
  "@types/normalize-path": "catalog:",
3162
3159
  "@types/ws": "catalog:",
3163
- "@types/yup": "^0.29.14",
3164
3160
  "jest-file-snapshot": "^0.5.0",
3165
3161
  "memory-level": "catalog:",
3166
3162
  typescript: "^5.7.3",
3167
3163
  vite: "^4.5.9",
3168
3164
  vitest: "^0.32.4",
3169
- zod: "^3.24.2"
3165
+ zod: "catalog:"
3170
3166
  }
3171
3167
  };
3172
3168
 
@@ -3236,9 +3232,9 @@ var _buildFragments = async (builder, tinaSchema) => {
3236
3232
  });
3237
3233
  const fragDoc = {
3238
3234
  kind: "Document",
3239
- definitions: (0, import_lodash3.default)(
3240
- // @ts-ignore
3235
+ definitions: (0, import_es_toolkit3.uniqBy)(
3241
3236
  extractInlineTypes(fragmentDefinitionsFields),
3237
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3242
3238
  (node) => node.name.value
3243
3239
  )
3244
3240
  };
@@ -3269,9 +3265,9 @@ var _buildQueries = async (builder, tinaSchema) => {
3269
3265
  });
3270
3266
  const queryDoc = {
3271
3267
  kind: "Document",
3272
- definitions: (0, import_lodash3.default)(
3273
- // @ts-ignore
3268
+ definitions: (0, import_es_toolkit3.uniqBy)(
3274
3269
  extractInlineTypes(operationsDefinitions),
3270
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3275
3271
  (node) => node.name.value
3276
3272
  )
3277
3273
  };
@@ -3358,14 +3354,15 @@ var _buildSchema = async (builder, tinaSchema) => {
3358
3354
  fields: mutationTypeDefinitionFields
3359
3355
  })
3360
3356
  );
3361
- return {
3357
+ const schema = {
3362
3358
  kind: "Document",
3363
- definitions: (0, import_lodash3.default)(
3364
- // @ts-ignore
3359
+ definitions: (0, import_es_toolkit3.uniqBy)(
3365
3360
  extractInlineTypes(definitions),
3361
+ // @ts-ignore - all nodes returned by extractInlineTypes have a name property
3366
3362
  (node) => node.name.value
3367
3363
  )
3368
3364
  };
3365
+ return schema;
3369
3366
  };
3370
3367
 
3371
3368
  // src/resolve.ts
@@ -3374,250 +3371,11 @@ var import_graphql5 = require("graphql");
3374
3371
  // src/resolver/index.ts
3375
3372
  var import_path3 = __toESM(require("path"));
3376
3373
  var import_isValid = __toESM(require("date-fns/isValid/index.js"));
3374
+ var import_jsonpath_plus2 = require("jsonpath-plus");
3377
3375
 
3378
3376
  // src/mdx/index.ts
3379
3377
  var import_mdx = require("@tinacms/mdx");
3380
3378
 
3381
- // src/resolver/index.ts
3382
- var import_jsonpath_plus2 = require("jsonpath-plus");
3383
-
3384
- // src/resolver/error.ts
3385
- var TinaGraphQLError = class extends Error {
3386
- constructor(message, extensions) {
3387
- super(message);
3388
- if (!this.name) {
3389
- Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
3390
- }
3391
- this.extensions = { ...extensions };
3392
- }
3393
- };
3394
- var TinaFetchError = class extends Error {
3395
- constructor(message, args) {
3396
- super(message);
3397
- this.name = "TinaFetchError";
3398
- this.collection = args.collection;
3399
- this.stack = args.stack;
3400
- this.file = args.file;
3401
- this.originalError = args.originalError;
3402
- }
3403
- };
3404
- var TinaQueryError = class extends TinaFetchError {
3405
- constructor(args) {
3406
- super(
3407
- `Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
3408
- args
3409
- );
3410
- }
3411
- };
3412
- var TinaParseDocumentError = class extends TinaFetchError {
3413
- constructor(args) {
3414
- super(
3415
- `Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
3416
- args
3417
- );
3418
- }
3419
- toString() {
3420
- return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
3421
- }
3422
- };
3423
- var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
3424
- var handleFetchErrorError = (e, verbose) => {
3425
- if (e instanceof Error) {
3426
- if (e instanceof TinaFetchError) {
3427
- if (verbose) {
3428
- console.log(e.toString());
3429
- console.log(e);
3430
- console.log(e.stack);
3431
- }
3432
- }
3433
- } else {
3434
- console.error(e);
3435
- }
3436
- throw e;
3437
- };
3438
-
3439
- // src/resolver/filter-utils.ts
3440
- var resolveReferences = async (filter, fields, resolver) => {
3441
- for (const fieldKey of Object.keys(filter)) {
3442
- const fieldDefinition = fields.find(
3443
- (f) => f.name === fieldKey
3444
- );
3445
- if (fieldDefinition) {
3446
- if (fieldDefinition.type === "reference") {
3447
- const { edges, values } = await resolver(filter, fieldDefinition);
3448
- if (edges.length === 1) {
3449
- filter[fieldKey] = {
3450
- eq: values[0]
3451
- };
3452
- } else if (edges.length > 1) {
3453
- filter[fieldKey] = {
3454
- in: values
3455
- };
3456
- } else {
3457
- filter[fieldKey] = {
3458
- eq: "___null___"
3459
- };
3460
- }
3461
- } else if (fieldDefinition.type === "object") {
3462
- if (fieldDefinition.templates) {
3463
- for (const templateName of Object.keys(filter[fieldKey])) {
3464
- const template = fieldDefinition.templates.find(
3465
- (template2) => !(typeof template2 === "string") && template2.name === templateName
3466
- );
3467
- if (template) {
3468
- await resolveReferences(
3469
- filter[fieldKey][templateName],
3470
- template.fields,
3471
- resolver
3472
- );
3473
- } else {
3474
- throw new Error(`Template ${templateName} not found`);
3475
- }
3476
- }
3477
- } else {
3478
- await resolveReferences(
3479
- filter[fieldKey],
3480
- fieldDefinition.fields,
3481
- resolver
3482
- );
3483
- }
3484
- }
3485
- } else {
3486
- throw new Error(`Unable to find field ${fieldKey}`);
3487
- }
3488
- }
3489
- };
3490
- var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
3491
- for (const childFieldName of Object.keys(filterNode)) {
3492
- const childField = fields.find((field) => field.name === childFieldName);
3493
- if (!childField) {
3494
- throw new Error(`Unable to find type for field ${childFieldName}`);
3495
- }
3496
- collectConditionsForField(
3497
- childFieldName,
3498
- childField,
3499
- filterNode[childFieldName],
3500
- pathExpression,
3501
- collectCondition
3502
- );
3503
- }
3504
- };
3505
- var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
3506
- if (field.list && field.templates) {
3507
- for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
3508
- const template = field.templates.find(
3509
- (template2) => !(typeof template2 === "string") && template2.name === filterKey
3510
- );
3511
- const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
3512
- const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
3513
- collectConditionsForChildFields(
3514
- childFilterNode,
3515
- template.fields,
3516
- filterPath,
3517
- collectCondition
3518
- );
3519
- }
3520
- } else {
3521
- const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
3522
- const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
3523
- collectConditionsForChildFields(
3524
- filterNode,
3525
- field.fields,
3526
- filterPath,
3527
- collectCondition
3528
- );
3529
- }
3530
- };
3531
- var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
3532
- if (field.type === "object") {
3533
- collectConditionsForObjectField(
3534
- fieldName,
3535
- field,
3536
- filterNode,
3537
- pathExpression,
3538
- collectCondition
3539
- );
3540
- } else {
3541
- collectCondition({
3542
- filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
3543
- filterExpression: {
3544
- _type: field.type,
3545
- _list: !!field.list,
3546
- ...filterNode
3547
- }
3548
- });
3549
- }
3550
- };
3551
-
3552
- // src/resolver/media-utils.ts
3553
- var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
3554
- if (config && value) {
3555
- if (config.useRelativeMedia === true) {
3556
- return value;
3557
- }
3558
- if (hasTinaMediaConfig(schema) === true) {
3559
- const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
3560
- if (typeof value === "string" && value.includes(assetsURL)) {
3561
- const cleanMediaRoot = cleanUpSlashes(
3562
- schema.config.media.tina.mediaRoot
3563
- );
3564
- const strippedURL = value.replace(assetsURL, "");
3565
- return `${cleanMediaRoot}${strippedURL}`;
3566
- }
3567
- if (Array.isArray(value)) {
3568
- return value.map((v) => {
3569
- if (!v || typeof v !== "string") return v;
3570
- const cleanMediaRoot = cleanUpSlashes(
3571
- schema.config.media.tina.mediaRoot
3572
- );
3573
- const strippedURL = v.replace(assetsURL, "");
3574
- return `${cleanMediaRoot}${strippedURL}`;
3575
- });
3576
- }
3577
- return value;
3578
- }
3579
- return value;
3580
- } else {
3581
- return value;
3582
- }
3583
- };
3584
- var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
3585
- if (config && value) {
3586
- if (config.useRelativeMedia === true) {
3587
- return value;
3588
- }
3589
- if (hasTinaMediaConfig(schema) === true) {
3590
- const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
3591
- if (typeof value === "string") {
3592
- const strippedValue = value.replace(cleanMediaRoot, "");
3593
- return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
3594
- }
3595
- if (Array.isArray(value)) {
3596
- return value.map((v) => {
3597
- if (!v || typeof v !== "string") return v;
3598
- const strippedValue = v.replace(cleanMediaRoot, "");
3599
- return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
3600
- });
3601
- }
3602
- }
3603
- return value;
3604
- } else {
3605
- return value;
3606
- }
3607
- };
3608
- var cleanUpSlashes = (path7) => {
3609
- if (path7) {
3610
- return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
3611
- }
3612
- return "";
3613
- };
3614
- var hasTinaMediaConfig = (schema) => {
3615
- if (!schema.config?.media?.tina) return false;
3616
- if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
3617
- return false;
3618
- return true;
3619
- };
3620
-
3621
3379
  // src/resolver/index.ts
3622
3380
  var import_graphql3 = require("graphql");
3623
3381
 
@@ -3679,11 +3437,11 @@ var import_path2 = __toESM(require("path"));
3679
3437
 
3680
3438
  // src/database/util.ts
3681
3439
  var import_toml = __toESM(require("@iarna/toml"));
3682
- var import_js_yaml = __toESM(require("js-yaml"));
3683
- var import_gray_matter = __toESM(require("gray-matter"));
3684
3440
  var import_schema_tools4 = require("@tinacms/schema-tools");
3685
- var import_micromatch = __toESM(require("micromatch"));
3441
+ var import_gray_matter = __toESM(require("gray-matter"));
3442
+ var import_js_yaml = __toESM(require("js-yaml"));
3686
3443
  var import_path = __toESM(require("path"));
3444
+ var import_micromatch = __toESM(require("micromatch"));
3687
3445
 
3688
3446
  // src/database/alias-utils.ts
3689
3447
  var replaceBlockAliases = (template, item) => {
@@ -4570,106 +4328,342 @@ var makeFolderOpsForCollection = (folderTree, collection, indexDefinitions, opTy
4570
4328
  });
4571
4329
  }
4572
4330
  }
4573
- return result;
4331
+ return result;
4332
+ };
4333
+ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opType, level, escapeStr = stringEscaper) => {
4334
+ const result = [];
4335
+ if (collection) {
4336
+ const collectionSublevel = level.sublevel(collection, SUBLEVEL_OPTIONS);
4337
+ for (const [sort, definition] of Object.entries(indexDefinitions)) {
4338
+ const indexedValue = makeKeyForField(definition, data, escapeStr);
4339
+ const indexSublevel = collectionSublevel.sublevel(sort, SUBLEVEL_OPTIONS);
4340
+ if (sort === DEFAULT_COLLECTION_SORT_KEY) {
4341
+ result.push({
4342
+ type: opType,
4343
+ key: filepath,
4344
+ sublevel: indexSublevel,
4345
+ value: opType === "put" ? {} : void 0
4346
+ });
4347
+ } else {
4348
+ if (indexedValue) {
4349
+ result.push({
4350
+ type: opType,
4351
+ key: `${indexedValue}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4352
+ sublevel: indexSublevel,
4353
+ value: opType === "put" ? {} : void 0
4354
+ });
4355
+ }
4356
+ }
4357
+ }
4358
+ }
4359
+ return result;
4360
+ };
4361
+ var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
4362
+ const result = [];
4363
+ if (collection) {
4364
+ for (const [c, referencePaths] of Object.entries(references || {})) {
4365
+ if (!referencePaths.length) {
4366
+ continue;
4367
+ }
4368
+ const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
4369
+ const refSublevel = collectionSublevel.sublevel(
4370
+ REFS_COLLECTIONS_SORT_KEY,
4371
+ SUBLEVEL_OPTIONS
4372
+ );
4373
+ const references2 = {};
4374
+ for (const path7 of referencePaths) {
4375
+ const ref = (0, import_jsonpath_plus.JSONPath)({ path: path7, json: data });
4376
+ if (!ref) {
4377
+ continue;
4378
+ }
4379
+ if (Array.isArray(ref)) {
4380
+ for (const r of ref) {
4381
+ if (!r) {
4382
+ continue;
4383
+ }
4384
+ if (references2[r]) {
4385
+ references2[r].push(path7);
4386
+ } else {
4387
+ references2[r] = [path7];
4388
+ }
4389
+ }
4390
+ } else {
4391
+ if (references2[ref]) {
4392
+ references2[ref].push(path7);
4393
+ } else {
4394
+ references2[ref] = [path7];
4395
+ }
4396
+ }
4397
+ }
4398
+ for (const ref of Object.keys(references2)) {
4399
+ for (const path7 of references2[ref]) {
4400
+ result.push({
4401
+ type: opType,
4402
+ key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4403
+ sublevel: refSublevel,
4404
+ value: opType === "put" ? {} : void 0
4405
+ });
4406
+ }
4407
+ }
4408
+ }
4409
+ }
4410
+ return result;
4411
+ };
4412
+ var makeStringEscaper = (regex, replacement) => {
4413
+ return (input) => {
4414
+ if (Array.isArray(input)) {
4415
+ return input.map(
4416
+ (val) => val.replace(regex, replacement)
4417
+ );
4418
+ } else {
4419
+ if (typeof input === "string") {
4420
+ return input.replace(regex, replacement);
4421
+ } else {
4422
+ return input;
4423
+ }
4424
+ }
4425
+ };
4426
+ };
4427
+ var stringEscaper = makeStringEscaper(
4428
+ new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
4429
+ encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
4430
+ );
4431
+
4432
+ // src/resolver/error.ts
4433
+ var TinaGraphQLError = class extends Error {
4434
+ constructor(message, extensions) {
4435
+ super(message);
4436
+ if (!this.name) {
4437
+ Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
4438
+ }
4439
+ this.extensions = { ...extensions };
4440
+ }
4441
+ };
4442
+ var TinaFetchError = class extends Error {
4443
+ constructor(message, args) {
4444
+ super(message);
4445
+ this.name = "TinaFetchError";
4446
+ this.collection = args.collection;
4447
+ this.file = args.file;
4448
+ this.originalError = args.originalError;
4449
+ }
4450
+ };
4451
+ var TinaQueryError = class extends TinaFetchError {
4452
+ constructor(args) {
4453
+ super(
4454
+ `Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
4455
+ args
4456
+ );
4457
+ }
4458
+ };
4459
+ var TinaParseDocumentError = class extends TinaFetchError {
4460
+ constructor(args) {
4461
+ super(
4462
+ `Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
4463
+ args
4464
+ );
4465
+ }
4466
+ toString() {
4467
+ return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
4468
+ }
4469
+ };
4470
+ var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
4471
+ var handleFetchErrorError = (e, verbose) => {
4472
+ if (e instanceof Error) {
4473
+ if (e instanceof TinaFetchError) {
4474
+ if (verbose) {
4475
+ console.log(e.toString());
4476
+ console.log(e);
4477
+ console.log(e.stack);
4478
+ }
4479
+ }
4480
+ } else {
4481
+ console.error(e);
4482
+ }
4483
+ throw e;
4484
+ };
4485
+
4486
+ // src/resolver/filter-utils.ts
4487
+ var resolveReferences = async (filter, fields, resolver) => {
4488
+ for (const fieldKey of Object.keys(filter)) {
4489
+ const fieldDefinition = fields.find(
4490
+ (f) => f.name === fieldKey
4491
+ );
4492
+ if (fieldDefinition) {
4493
+ if (fieldDefinition.type === "reference") {
4494
+ const { edges, values } = await resolver(filter, fieldDefinition);
4495
+ if (edges.length === 1) {
4496
+ filter[fieldKey] = {
4497
+ eq: values[0]
4498
+ };
4499
+ } else if (edges.length > 1) {
4500
+ filter[fieldKey] = {
4501
+ in: values
4502
+ };
4503
+ } else {
4504
+ filter[fieldKey] = {
4505
+ eq: "___null___"
4506
+ };
4507
+ }
4508
+ } else if (fieldDefinition.type === "object") {
4509
+ if (fieldDefinition.templates) {
4510
+ for (const templateName of Object.keys(filter[fieldKey])) {
4511
+ const template = fieldDefinition.templates.find(
4512
+ (template2) => !(typeof template2 === "string") && template2.name === templateName
4513
+ );
4514
+ if (template) {
4515
+ await resolveReferences(
4516
+ filter[fieldKey][templateName],
4517
+ template.fields,
4518
+ resolver
4519
+ );
4520
+ } else {
4521
+ throw new Error(`Template ${templateName} not found`);
4522
+ }
4523
+ }
4524
+ } else {
4525
+ await resolveReferences(
4526
+ filter[fieldKey],
4527
+ fieldDefinition.fields,
4528
+ resolver
4529
+ );
4530
+ }
4531
+ }
4532
+ } else {
4533
+ throw new Error(`Unable to find field ${fieldKey}`);
4534
+ }
4535
+ }
4536
+ };
4537
+ var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
4538
+ for (const childFieldName of Object.keys(filterNode)) {
4539
+ const childField = fields.find((field) => field.name === childFieldName);
4540
+ if (!childField) {
4541
+ throw new Error(`Unable to find type for field ${childFieldName}`);
4542
+ }
4543
+ collectConditionsForField(
4544
+ childFieldName,
4545
+ childField,
4546
+ filterNode[childFieldName],
4547
+ pathExpression,
4548
+ collectCondition
4549
+ );
4550
+ }
4551
+ };
4552
+ var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
4553
+ if (field.list && field.templates) {
4554
+ for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
4555
+ const template = field.templates.find(
4556
+ (template2) => !(typeof template2 === "string") && template2.name === filterKey
4557
+ );
4558
+ const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
4559
+ const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
4560
+ collectConditionsForChildFields(
4561
+ childFilterNode,
4562
+ template.fields,
4563
+ filterPath,
4564
+ collectCondition
4565
+ );
4566
+ }
4567
+ } else {
4568
+ const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
4569
+ const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
4570
+ collectConditionsForChildFields(
4571
+ filterNode,
4572
+ field.fields,
4573
+ filterPath,
4574
+ collectCondition
4575
+ );
4576
+ }
4574
4577
  };
4575
- var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opType, level, escapeStr = stringEscaper) => {
4576
- const result = [];
4577
- if (collection) {
4578
- const collectionSublevel = level.sublevel(collection, SUBLEVEL_OPTIONS);
4579
- for (const [sort, definition] of Object.entries(indexDefinitions)) {
4580
- const indexedValue = makeKeyForField(definition, data, escapeStr);
4581
- const indexSublevel = collectionSublevel.sublevel(sort, SUBLEVEL_OPTIONS);
4582
- if (sort === DEFAULT_COLLECTION_SORT_KEY) {
4583
- result.push({
4584
- type: opType,
4585
- key: filepath,
4586
- sublevel: indexSublevel,
4587
- value: opType === "put" ? {} : void 0
4588
- });
4589
- } else {
4590
- if (indexedValue) {
4591
- result.push({
4592
- type: opType,
4593
- key: `${indexedValue}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4594
- sublevel: indexSublevel,
4595
- value: opType === "put" ? {} : void 0
4596
- });
4597
- }
4578
+ var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
4579
+ if (field.type === "object") {
4580
+ collectConditionsForObjectField(
4581
+ fieldName,
4582
+ field,
4583
+ filterNode,
4584
+ pathExpression,
4585
+ collectCondition
4586
+ );
4587
+ } else {
4588
+ collectCondition({
4589
+ filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
4590
+ filterExpression: {
4591
+ _type: field.type,
4592
+ _list: !!field.list,
4593
+ ...filterNode
4598
4594
  }
4599
- }
4595
+ });
4600
4596
  }
4601
- return result;
4602
4597
  };
4603
- var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
4604
- const result = [];
4605
- if (collection) {
4606
- for (const [c, referencePaths] of Object.entries(references || {})) {
4607
- if (!referencePaths.length) {
4608
- continue;
4609
- }
4610
- const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
4611
- const refSublevel = collectionSublevel.sublevel(
4612
- REFS_COLLECTIONS_SORT_KEY,
4613
- SUBLEVEL_OPTIONS
4614
- );
4615
- const references2 = {};
4616
- for (const path7 of referencePaths) {
4617
- const ref = (0, import_jsonpath_plus.JSONPath)({ path: path7, json: data });
4618
- if (!ref) {
4619
- continue;
4620
- }
4621
- if (Array.isArray(ref)) {
4622
- for (const r of ref) {
4623
- if (!r) {
4624
- continue;
4625
- }
4626
- if (references2[r]) {
4627
- references2[r].push(path7);
4628
- } else {
4629
- references2[r] = [path7];
4630
- }
4631
- }
4632
- } else {
4633
- if (references2[ref]) {
4634
- references2[ref].push(path7);
4635
- } else {
4636
- references2[ref] = [path7];
4637
- }
4638
- }
4598
+
4599
+ // src/resolver/media-utils.ts
4600
+ var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
4601
+ if (config && value) {
4602
+ if (config.useRelativeMedia === true) {
4603
+ return value;
4604
+ }
4605
+ if (hasTinaMediaConfig(schema) === true) {
4606
+ const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
4607
+ if (typeof value === "string" && value.includes(assetsURL)) {
4608
+ const cleanMediaRoot = cleanUpSlashes(
4609
+ schema.config.media.tina.mediaRoot
4610
+ );
4611
+ const strippedURL = value.replace(assetsURL, "");
4612
+ return `${cleanMediaRoot}${strippedURL}`;
4639
4613
  }
4640
- for (const ref of Object.keys(references2)) {
4641
- for (const path7 of references2[ref]) {
4642
- result.push({
4643
- type: opType,
4644
- key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
4645
- sublevel: refSublevel,
4646
- value: opType === "put" ? {} : void 0
4647
- });
4648
- }
4614
+ if (Array.isArray(value)) {
4615
+ return value.map((v) => {
4616
+ if (!v || typeof v !== "string") return v;
4617
+ const cleanMediaRoot = cleanUpSlashes(
4618
+ schema.config.media.tina.mediaRoot
4619
+ );
4620
+ const strippedURL = v.replace(assetsURL, "");
4621
+ return `${cleanMediaRoot}${strippedURL}`;
4622
+ });
4649
4623
  }
4624
+ return value;
4650
4625
  }
4626
+ return value;
4627
+ } else {
4628
+ return value;
4651
4629
  }
4652
- return result;
4653
4630
  };
4654
- var makeStringEscaper = (regex, replacement) => {
4655
- return (input) => {
4656
- if (Array.isArray(input)) {
4657
- return input.map(
4658
- (val) => val.replace(regex, replacement)
4659
- );
4660
- } else {
4661
- if (typeof input === "string") {
4662
- return input.replace(regex, replacement);
4663
- } else {
4664
- return input;
4631
+ var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
4632
+ if (config && value) {
4633
+ if (config.useRelativeMedia === true) {
4634
+ return value;
4635
+ }
4636
+ if (hasTinaMediaConfig(schema) === true) {
4637
+ const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
4638
+ if (typeof value === "string") {
4639
+ const strippedValue = value.replace(cleanMediaRoot, "");
4640
+ return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
4641
+ }
4642
+ if (Array.isArray(value)) {
4643
+ return value.map((v) => {
4644
+ if (!v || typeof v !== "string") return v;
4645
+ const strippedValue = v.replace(cleanMediaRoot, "");
4646
+ return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
4647
+ });
4665
4648
  }
4666
4649
  }
4667
- };
4650
+ return value;
4651
+ } else {
4652
+ return value;
4653
+ }
4654
+ };
4655
+ var cleanUpSlashes = (path7) => {
4656
+ if (path7) {
4657
+ return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
4658
+ }
4659
+ return "";
4660
+ };
4661
+ var hasTinaMediaConfig = (schema) => {
4662
+ if (!schema.config?.media?.tina) return false;
4663
+ if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
4664
+ return false;
4665
+ return true;
4668
4666
  };
4669
- var stringEscaper = makeStringEscaper(
4670
- new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
4671
- encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
4672
- );
4673
4667
 
4674
4668
  // src/resolver/index.ts
4675
4669
  var createResolver = (args) => {
@@ -4831,8 +4825,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
4831
4825
  originalError: e,
4832
4826
  collection: collection.name,
4833
4827
  includeAuditMessage: !isAudit,
4834
- file: relativePath,
4835
- stack: e.stack
4828
+ file: relativePath
4836
4829
  });
4837
4830
  }
4838
4831
  const titleField = template.fields.find((x) => {
@@ -5636,7 +5629,7 @@ var Resolver = class {
5636
5629
  }
5637
5630
  break;
5638
5631
  case "rich-text":
5639
- accum[fieldName] = (0, import_mdx.stringifyMDX)(
5632
+ accum[fieldName] = (0, import_mdx.serializeMDX)(
5640
5633
  fieldValue,
5641
5634
  field,
5642
5635
  (fieldValue2) => resolveMediaCloudToRelative(
@@ -5743,8 +5736,129 @@ var resolveDateInput = (value) => {
5743
5736
  return date;
5744
5737
  };
5745
5738
 
5746
- // src/resolve.ts
5747
- var import_lodash4 = __toESM(require("lodash.set"));
5739
+ // src/resolver/auth-fields.ts
5740
+ var import_compat = require("es-toolkit/compat");
5741
+ async function getUserDocumentContext(tinaSchema, resolver) {
5742
+ const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5743
+ if (!collection) {
5744
+ throw new Error("Auth collection not found");
5745
+ }
5746
+ const userFields = mapUserFields(collection, ["_rawData"]);
5747
+ if (!userFields.length) {
5748
+ throw new Error(`No user field found in collection ${collection.name}`);
5749
+ }
5750
+ if (userFields.length > 1) {
5751
+ throw new Error(
5752
+ `Multiple user fields found in collection ${collection.name}`
5753
+ );
5754
+ }
5755
+ const userField = userFields[0];
5756
+ const realPath = `${collection.path}/index.json`;
5757
+ const userDoc = await resolver.getDocument(realPath);
5758
+ const users = get(userDoc, userField.path);
5759
+ if (!users) {
5760
+ throw new Error("No users found");
5761
+ }
5762
+ return { collection, userField, users, userDoc, realPath };
5763
+ }
5764
+ function findUserInCollection(users, userField, userSub) {
5765
+ const { idFieldName } = userField;
5766
+ if (!idFieldName) {
5767
+ throw new Error("No uid field found on user field");
5768
+ }
5769
+ return users.find((u) => u[idFieldName] === userSub) || null;
5770
+ }
5771
+ async function handleAuthenticate({
5772
+ tinaSchema,
5773
+ resolver,
5774
+ sub,
5775
+ password,
5776
+ ctxUser
5777
+ }) {
5778
+ const userSub = sub || ctxUser?.sub;
5779
+ const { userField, users } = await getUserDocumentContext(
5780
+ tinaSchema,
5781
+ resolver
5782
+ );
5783
+ const user = findUserInCollection(users, userField, userSub);
5784
+ if (!user) {
5785
+ return null;
5786
+ }
5787
+ const { passwordFieldName } = userField;
5788
+ const saltedHash = get(user, [passwordFieldName || "", "value"]);
5789
+ if (!saltedHash) {
5790
+ throw new Error("No password field found on user field");
5791
+ }
5792
+ const matches = await checkPasswordHash({
5793
+ saltedHash,
5794
+ password
5795
+ });
5796
+ return matches ? user : null;
5797
+ }
5798
+ async function handleAuthorize({
5799
+ tinaSchema,
5800
+ resolver,
5801
+ sub,
5802
+ ctxUser
5803
+ }) {
5804
+ const userSub = sub || ctxUser?.sub;
5805
+ const { userField, users } = await getUserDocumentContext(
5806
+ tinaSchema,
5807
+ resolver
5808
+ );
5809
+ const user = findUserInCollection(users, userField, userSub);
5810
+ return user ? user : null;
5811
+ }
5812
+ async function handleUpdatePassword({
5813
+ tinaSchema,
5814
+ resolver,
5815
+ password,
5816
+ ctxUser
5817
+ }) {
5818
+ if (!ctxUser?.sub) {
5819
+ throw new Error("Not authorized");
5820
+ }
5821
+ if (!password) {
5822
+ throw new Error("No password provided");
5823
+ }
5824
+ const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
5825
+ const { idFieldName, passwordFieldName } = userField;
5826
+ const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5827
+ if (!user) {
5828
+ throw new Error("Not authorized");
5829
+ }
5830
+ user[passwordFieldName] = {
5831
+ value: password,
5832
+ passwordChangeRequired: false
5833
+ };
5834
+ const params = {};
5835
+ (0, import_compat.set)(
5836
+ params,
5837
+ userField.path.slice(1),
5838
+ // remove _rawData from users path
5839
+ users.map((u) => {
5840
+ if (user[idFieldName] === u[idFieldName]) {
5841
+ return user;
5842
+ }
5843
+ return {
5844
+ // don't overwrite other users' passwords
5845
+ ...u,
5846
+ [passwordFieldName]: {
5847
+ ...u[passwordFieldName],
5848
+ value: ""
5849
+ }
5850
+ };
5851
+ })
5852
+ );
5853
+ await resolver.updateResolveDocument({
5854
+ collection,
5855
+ args: { params },
5856
+ realPath,
5857
+ isCollectionSpecific: true,
5858
+ isAddPendingDocument: false
5859
+ });
5860
+ return true;
5861
+ }
5748
5862
 
5749
5863
  // src/error.ts
5750
5864
  var import_graphql4 = require("graphql");
@@ -5854,119 +5968,33 @@ var resolve = async ({
5854
5968
  );
5855
5969
  }
5856
5970
  }
5857
- if (info.fieldName === "authenticate" || info.fieldName === "authorize") {
5858
- const sub = args.sub || ctxUser?.sub;
5859
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5860
- if (!collection) {
5861
- throw new Error("Auth collection not found");
5862
- }
5863
- const userFields = mapUserFields(collection, ["_rawData"]);
5864
- if (!userFields.length) {
5865
- throw new Error(
5866
- `No user field found in collection ${collection.name}`
5867
- );
5868
- }
5869
- if (userFields.length > 1) {
5870
- throw new Error(
5871
- `Multiple user fields found in collection ${collection.name}`
5872
- );
5873
- }
5874
- const userField = userFields[0];
5875
- const realPath = `${collection.path}/index.json`;
5876
- const userDoc = await resolver.getDocument(realPath);
5877
- const users = get(userDoc, userField.path);
5878
- if (!users) {
5879
- throw new Error("No users found");
5880
- }
5881
- const { idFieldName, passwordFieldName } = userField;
5882
- if (!idFieldName) {
5883
- throw new Error("No uid field found on user field");
5884
- }
5885
- const user = users.find((u) => u[idFieldName] === sub);
5886
- if (!user) {
5887
- return null;
5888
- }
5889
- if (info.fieldName === "authenticate") {
5890
- const saltedHash = get(user, [passwordFieldName || "", "value"]);
5891
- if (!saltedHash) {
5892
- throw new Error("No password field found on user field");
5893
- }
5894
- const matches = await checkPasswordHash({
5895
- saltedHash,
5896
- password: args.password
5897
- });
5898
- if (matches) {
5899
- return user;
5900
- }
5901
- return null;
5902
- }
5903
- return user;
5971
+ if (info.fieldName === "authenticate") {
5972
+ return handleAuthenticate({
5973
+ tinaSchema,
5974
+ resolver,
5975
+ sub: args.sub,
5976
+ password: args.password,
5977
+ info,
5978
+ ctxUser
5979
+ });
5980
+ }
5981
+ if (info.fieldName === "authorize") {
5982
+ return handleAuthorize({
5983
+ tinaSchema,
5984
+ resolver,
5985
+ sub: args.sub,
5986
+ info,
5987
+ ctxUser
5988
+ });
5904
5989
  }
5905
5990
  if (info.fieldName === "updatePassword") {
5906
- if (!ctxUser?.sub) {
5907
- throw new Error("Not authorized");
5908
- }
5909
- if (!args.password) {
5910
- throw new Error("No password provided");
5911
- }
5912
- const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
5913
- if (!collection) {
5914
- throw new Error("Auth collection not found");
5915
- }
5916
- const userFields = mapUserFields(collection, ["_rawData"]);
5917
- if (!userFields.length) {
5918
- throw new Error(
5919
- `No user field found in collection ${collection.name}`
5920
- );
5921
- }
5922
- if (userFields.length > 1) {
5923
- throw new Error(
5924
- `Multiple user fields found in collection ${collection.name}`
5925
- );
5926
- }
5927
- const userField = userFields[0];
5928
- const realPath = `${collection.path}/index.json`;
5929
- const userDoc = await resolver.getDocument(realPath);
5930
- const users = get(userDoc, userField.path);
5931
- if (!users) {
5932
- throw new Error("No users found");
5933
- }
5934
- const { idFieldName, passwordFieldName } = userField;
5935
- const user = users.find((u) => u[idFieldName] === ctxUser.sub);
5936
- if (!user) {
5937
- throw new Error("Not authorized");
5938
- }
5939
- user[passwordFieldName] = {
5940
- value: args.password,
5941
- passwordChangeRequired: false
5942
- };
5943
- const params = {};
5944
- (0, import_lodash4.default)(
5945
- params,
5946
- userField.path.slice(1),
5947
- // remove _rawData from users path
5948
- users.map((u) => {
5949
- if (user[idFieldName] === u[idFieldName]) {
5950
- return user;
5951
- }
5952
- return {
5953
- // don't overwrite other users' passwords
5954
- ...u,
5955
- [passwordFieldName]: {
5956
- ...u[passwordFieldName],
5957
- value: ""
5958
- }
5959
- };
5960
- })
5961
- );
5962
- await resolver.updateResolveDocument({
5963
- collection,
5964
- args: { params },
5965
- realPath,
5966
- isCollectionSpecific: true,
5967
- isAddPendingDocument: false
5991
+ return handleUpdatePassword({
5992
+ tinaSchema,
5993
+ resolver,
5994
+ password: args.password,
5995
+ info,
5996
+ ctxUser
5968
5997
  });
5969
- return true;
5970
5998
  }
5971
5999
  if (!lookup) {
5972
6000
  return value;
@@ -6179,7 +6207,7 @@ var import_node_path = __toESM(require("node:path"));
6179
6207
  var import_graphql6 = require("graphql");
6180
6208
  var import_micromatch2 = __toESM(require("micromatch"));
6181
6209
  var import_js_sha12 = __toESM(require("js-sha1"));
6182
- var import_lodash5 = __toESM(require("lodash.set"));
6210
+ var import_compat2 = require("es-toolkit/compat");
6183
6211
  var createLocalDatabase = (config) => {
6184
6212
  const level = new TinaLevelClient(config?.port);
6185
6213
  level.openConnection();
@@ -6554,8 +6582,7 @@ var Database = class {
6554
6582
  throw new TinaFetchError(`Error in PUT for ${filepath}`, {
6555
6583
  originalError: error,
6556
6584
  file: filepath,
6557
- collection: collectionName,
6558
- stack: error.stack
6585
+ collection: collectionName
6559
6586
  });
6560
6587
  }
6561
6588
  };
@@ -6915,8 +6942,7 @@ var Database = class {
6915
6942
  throw new TinaQueryError({
6916
6943
  originalError: error,
6917
6944
  file: path7,
6918
- collection: collection.name,
6919
- stack: error.stack
6945
+ collection: collection.name
6920
6946
  });
6921
6947
  }
6922
6948
  throw error;
@@ -7292,7 +7318,7 @@ var hashPasswordVisitor = async (node, path7) => {
7292
7318
  const passwordValuePath = [...path7, "value"];
7293
7319
  const plaintextPassword = get(node, passwordValuePath);
7294
7320
  if (plaintextPassword) {
7295
- (0, import_lodash5.default)(
7321
+ (0, import_compat2.set)(
7296
7322
  node,
7297
7323
  passwordValuePath,
7298
7324
  await generatePasswordHash({ password: plaintextPassword })
@@ -7446,8 +7472,7 @@ var _indexContent = async ({
7446
7472
  throw new TinaFetchError(`Unable to seed ${filepath}`, {
7447
7473
  originalError: error,
7448
7474
  file: filepath,
7449
- collection: collection?.name,
7450
- stack: error.stack
7475
+ collection: collection?.name
7451
7476
  });
7452
7477
  }
7453
7478
  });