@tinacms/graphql 0.0.0-d7c745e-20250102002342 → 0.0.0-d9487bf-20251119052214
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/README.md +144 -0
- package/dist/ast-builder/index.d.ts +0 -1
- package/dist/builder/index.d.ts +2 -2
- package/dist/database/bridge/filesystem.d.ts +1 -1
- package/dist/database/datalayer.d.ts +5 -1
- package/dist/database/index.d.ts +2 -0
- package/dist/database/util.d.ts +6 -9
- package/dist/index.js +992 -733
- package/dist/index.mjs +859 -578
- package/dist/mdx/index.d.ts +2 -7
- package/dist/resolver/auth-fields.d.ts +31 -0
- package/dist/resolver/error.d.ts +1 -2
- package/dist/resolver/index.d.ts +17 -6
- package/dist/resolver/media-utils.d.ts +3 -3
- package/dist/schema/createSchema.d.ts +0 -3
- package/dist/schema/validate.d.ts +0 -3
- package/package.json +16 -19
- package/readme.md +0 -194
package/dist/index.mjs
CHANGED
|
@@ -1029,41 +1029,6 @@ function* walk(maybeNode, visited = /* @__PURE__ */ new WeakSet()) {
|
|
|
1029
1029
|
yield maybeNode;
|
|
1030
1030
|
visited.add(maybeNode);
|
|
1031
1031
|
}
|
|
1032
|
-
function addNamespaceToSchema(maybeNode, namespace = []) {
|
|
1033
|
-
if (typeof maybeNode === "string") {
|
|
1034
|
-
return maybeNode;
|
|
1035
|
-
}
|
|
1036
|
-
if (typeof maybeNode === "boolean") {
|
|
1037
|
-
return maybeNode;
|
|
1038
|
-
}
|
|
1039
|
-
const newNode = maybeNode;
|
|
1040
|
-
const keys = Object.keys(maybeNode);
|
|
1041
|
-
Object.values(maybeNode).map((m, index) => {
|
|
1042
|
-
const key = keys[index];
|
|
1043
|
-
if (Array.isArray(m)) {
|
|
1044
|
-
newNode[key] = m.map((element) => {
|
|
1045
|
-
if (!element) {
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
if (!element.hasOwnProperty("name")) {
|
|
1049
|
-
return element;
|
|
1050
|
-
}
|
|
1051
|
-
const value = element.name || element.value;
|
|
1052
|
-
return addNamespaceToSchema(element, [...namespace, value]);
|
|
1053
|
-
});
|
|
1054
|
-
} else {
|
|
1055
|
-
if (!m) {
|
|
1056
|
-
return;
|
|
1057
|
-
}
|
|
1058
|
-
if (!m.hasOwnProperty("name")) {
|
|
1059
|
-
newNode[key] = m;
|
|
1060
|
-
} else {
|
|
1061
|
-
newNode[key] = addNamespaceToSchema(m, [...namespace, m.name]);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
});
|
|
1065
|
-
return { ...newNode, namespace };
|
|
1066
|
-
}
|
|
1067
1032
|
var generateNamespacedFieldName = (names, suffix = "") => {
|
|
1068
1033
|
return (suffix ? [...names, suffix] : names).map(capitalize).join("");
|
|
1069
1034
|
};
|
|
@@ -1882,7 +1847,7 @@ var Builder = class {
|
|
|
1882
1847
|
* ```
|
|
1883
1848
|
*
|
|
1884
1849
|
* @public
|
|
1885
|
-
* @param collection a
|
|
1850
|
+
* @param collection a TinaCloud collection
|
|
1886
1851
|
*/
|
|
1887
1852
|
this.collectionFragment = async (collection) => {
|
|
1888
1853
|
const name = NAMER.dataTypeName(collection.namespace);
|
|
@@ -2746,7 +2711,7 @@ var Builder = class {
|
|
|
2746
2711
|
this._buildDataField = async (field) => {
|
|
2747
2712
|
const listWarningMsg = `
|
|
2748
2713
|
WARNING: The user interface for ${field.type} does not support \`list: true\`
|
|
2749
|
-
Visit https://tina.io/docs/
|
|
2714
|
+
Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
|
|
2750
2715
|
|
|
2751
2716
|
`;
|
|
2752
2717
|
switch (field.type) {
|
|
@@ -2898,6 +2863,7 @@ var filterSelections = (arr) => {
|
|
|
2898
2863
|
import { TinaSchema } from "@tinacms/schema-tools";
|
|
2899
2864
|
|
|
2900
2865
|
// src/schema/validate.ts
|
|
2866
|
+
import { addNamespaceToSchema } from "@tinacms/schema-tools";
|
|
2901
2867
|
import deepClone from "lodash.clonedeep";
|
|
2902
2868
|
import * as yup2 from "yup";
|
|
2903
2869
|
import {
|
|
@@ -3053,7 +3019,7 @@ var validateField = async (field) => {
|
|
|
3053
3019
|
// package.json
|
|
3054
3020
|
var package_default = {
|
|
3055
3021
|
name: "@tinacms/graphql",
|
|
3056
|
-
version: "1.
|
|
3022
|
+
version: "1.6.1",
|
|
3057
3023
|
main: "dist/index.js",
|
|
3058
3024
|
module: "dist/index.mjs",
|
|
3059
3025
|
typings: "dist/index.d.ts",
|
|
@@ -3079,33 +3045,32 @@ var package_default = {
|
|
|
3079
3045
|
types: "pnpm tsc",
|
|
3080
3046
|
build: "tinacms-scripts build",
|
|
3081
3047
|
docs: "pnpm typedoc",
|
|
3082
|
-
|
|
3083
|
-
test: "
|
|
3084
|
-
"test-watch": "jest --watch"
|
|
3048
|
+
test: "vitest run",
|
|
3049
|
+
"test-watch": "vitest"
|
|
3085
3050
|
},
|
|
3086
3051
|
dependencies: {
|
|
3087
|
-
"@iarna/toml": "
|
|
3052
|
+
"@iarna/toml": "catalog:",
|
|
3088
3053
|
"@tinacms/mdx": "workspace:*",
|
|
3089
3054
|
"@tinacms/schema-tools": "workspace:*",
|
|
3090
|
-
"abstract-level": "
|
|
3055
|
+
"abstract-level": "catalog:",
|
|
3091
3056
|
"date-fns": "^2.30.0",
|
|
3092
|
-
"fast-glob": "
|
|
3093
|
-
"fs-extra": "
|
|
3094
|
-
"glob-parent": "
|
|
3057
|
+
"fast-glob": "catalog:",
|
|
3058
|
+
"fs-extra": "catalog:",
|
|
3059
|
+
"glob-parent": "catalog:",
|
|
3095
3060
|
graphql: "15.8.0",
|
|
3096
|
-
"gray-matter": "
|
|
3097
|
-
"isomorphic-git": "
|
|
3098
|
-
"js-sha1": "
|
|
3061
|
+
"gray-matter": "catalog:",
|
|
3062
|
+
"isomorphic-git": "catalog:",
|
|
3063
|
+
"js-sha1": "catalog:",
|
|
3099
3064
|
"js-yaml": "^3.14.1",
|
|
3100
|
-
"jsonpath-plus": "
|
|
3101
|
-
"lodash.clonedeep": "
|
|
3102
|
-
"lodash.set": "
|
|
3103
|
-
"lodash.uniqby": "
|
|
3104
|
-
"many-level": "
|
|
3105
|
-
micromatch: "
|
|
3106
|
-
"normalize-path": "
|
|
3107
|
-
"readable-stream": "
|
|
3108
|
-
scmp: "
|
|
3065
|
+
"jsonpath-plus": "catalog:",
|
|
3066
|
+
"lodash.clonedeep": "catalog:",
|
|
3067
|
+
"lodash.set": "catalog:",
|
|
3068
|
+
"lodash.uniqby": "catalog:",
|
|
3069
|
+
"many-level": "catalog:",
|
|
3070
|
+
micromatch: "catalog:",
|
|
3071
|
+
"normalize-path": "catalog:",
|
|
3072
|
+
"readable-stream": "catalog:",
|
|
3073
|
+
scmp: "catalog:",
|
|
3109
3074
|
yup: "^0.32.11"
|
|
3110
3075
|
},
|
|
3111
3076
|
publishConfig: {
|
|
@@ -3120,26 +3085,24 @@ var package_default = {
|
|
|
3120
3085
|
"@tinacms/scripts": "workspace:*",
|
|
3121
3086
|
"@types/cors": "^2.8.17",
|
|
3122
3087
|
"@types/estree": "^0.0.50",
|
|
3123
|
-
"@types/express": "
|
|
3088
|
+
"@types/express": "catalog:",
|
|
3124
3089
|
"@types/fs-extra": "^9.0.13",
|
|
3125
|
-
"@types/jest": "^26.0.24",
|
|
3126
3090
|
"@types/js-yaml": "^3.12.10",
|
|
3127
|
-
"@types/lodash.camelcase": "
|
|
3128
|
-
"@types/lodash.upperfirst": "
|
|
3129
|
-
"@types/lru-cache": "
|
|
3130
|
-
"@types/mdast": "
|
|
3131
|
-
"@types/micromatch": "
|
|
3132
|
-
"@types/node": "^22.
|
|
3133
|
-
"@types/normalize-path": "
|
|
3134
|
-
"@types/ws": "
|
|
3091
|
+
"@types/lodash.camelcase": "catalog:",
|
|
3092
|
+
"@types/lodash.upperfirst": "catalog:",
|
|
3093
|
+
"@types/lru-cache": "catalog:",
|
|
3094
|
+
"@types/mdast": "catalog:",
|
|
3095
|
+
"@types/micromatch": "catalog:",
|
|
3096
|
+
"@types/node": "^22.13.1",
|
|
3097
|
+
"@types/normalize-path": "catalog:",
|
|
3098
|
+
"@types/ws": "catalog:",
|
|
3135
3099
|
"@types/yup": "^0.29.14",
|
|
3136
|
-
jest: "^29.7.0",
|
|
3137
|
-
"jest-diff": "^29.7.0",
|
|
3138
3100
|
"jest-file-snapshot": "^0.5.0",
|
|
3139
|
-
"
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3101
|
+
"memory-level": "catalog:",
|
|
3102
|
+
typescript: "^5.7.3",
|
|
3103
|
+
vite: "^4.5.9",
|
|
3104
|
+
vitest: "^0.32.4",
|
|
3105
|
+
zod: "catalog:"
|
|
3143
3106
|
}
|
|
3144
3107
|
};
|
|
3145
3108
|
|
|
@@ -3295,7 +3258,9 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3295
3258
|
await builder.buildCreateCollectionFolderMutation()
|
|
3296
3259
|
);
|
|
3297
3260
|
await sequential(collections, async (collection) => {
|
|
3298
|
-
queryTypeDefinitionFields.push(
|
|
3261
|
+
queryTypeDefinitionFields.push(
|
|
3262
|
+
await builder.collectionDocument(collection)
|
|
3263
|
+
);
|
|
3299
3264
|
if (collection.isAuthCollection) {
|
|
3300
3265
|
queryTypeDefinitionFields.push(
|
|
3301
3266
|
await builder.authenticationCollectionDocument(collection)
|
|
@@ -3345,249 +3310,10 @@ import { graphql, buildASTSchema, getNamedType, GraphQLError as GraphQLError4 }
|
|
|
3345
3310
|
// src/resolver/index.ts
|
|
3346
3311
|
import path3 from "path";
|
|
3347
3312
|
import isValid from "date-fns/isValid/index.js";
|
|
3348
|
-
|
|
3349
|
-
// src/mdx/index.ts
|
|
3350
|
-
import { parseMDX, stringifyMDX } from "@tinacms/mdx";
|
|
3351
|
-
|
|
3352
|
-
// src/resolver/index.ts
|
|
3353
3313
|
import { JSONPath as JSONPath2 } from "jsonpath-plus";
|
|
3354
3314
|
|
|
3355
|
-
// src/
|
|
3356
|
-
|
|
3357
|
-
constructor(message, extensions) {
|
|
3358
|
-
super(message);
|
|
3359
|
-
if (!this.name) {
|
|
3360
|
-
Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
|
|
3361
|
-
}
|
|
3362
|
-
this.extensions = { ...extensions };
|
|
3363
|
-
}
|
|
3364
|
-
};
|
|
3365
|
-
var TinaFetchError = class extends Error {
|
|
3366
|
-
constructor(message, args) {
|
|
3367
|
-
super(message);
|
|
3368
|
-
this.name = "TinaFetchError";
|
|
3369
|
-
this.collection = args.collection;
|
|
3370
|
-
this.stack = args.stack;
|
|
3371
|
-
this.file = args.file;
|
|
3372
|
-
this.originalError = args.originalError;
|
|
3373
|
-
}
|
|
3374
|
-
};
|
|
3375
|
-
var TinaQueryError = class extends TinaFetchError {
|
|
3376
|
-
constructor(args) {
|
|
3377
|
-
super(
|
|
3378
|
-
`Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3379
|
-
args
|
|
3380
|
-
);
|
|
3381
|
-
}
|
|
3382
|
-
};
|
|
3383
|
-
var TinaParseDocumentError = class extends TinaFetchError {
|
|
3384
|
-
constructor(args) {
|
|
3385
|
-
super(
|
|
3386
|
-
`Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3387
|
-
args
|
|
3388
|
-
);
|
|
3389
|
-
}
|
|
3390
|
-
toString() {
|
|
3391
|
-
return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
|
|
3392
|
-
}
|
|
3393
|
-
};
|
|
3394
|
-
var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
|
|
3395
|
-
var handleFetchErrorError = (e, verbose) => {
|
|
3396
|
-
if (e instanceof Error) {
|
|
3397
|
-
if (e instanceof TinaFetchError) {
|
|
3398
|
-
if (verbose) {
|
|
3399
|
-
console.log(e.toString());
|
|
3400
|
-
console.log(e);
|
|
3401
|
-
console.log(e.stack);
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
} else {
|
|
3405
|
-
console.error(e);
|
|
3406
|
-
}
|
|
3407
|
-
throw e;
|
|
3408
|
-
};
|
|
3409
|
-
|
|
3410
|
-
// src/resolver/filter-utils.ts
|
|
3411
|
-
var resolveReferences = async (filter, fields, resolver) => {
|
|
3412
|
-
for (const fieldKey of Object.keys(filter)) {
|
|
3413
|
-
const fieldDefinition = fields.find(
|
|
3414
|
-
(f) => f.name === fieldKey
|
|
3415
|
-
);
|
|
3416
|
-
if (fieldDefinition) {
|
|
3417
|
-
if (fieldDefinition.type === "reference") {
|
|
3418
|
-
const { edges, values } = await resolver(filter, fieldDefinition);
|
|
3419
|
-
if (edges.length === 1) {
|
|
3420
|
-
filter[fieldKey] = {
|
|
3421
|
-
eq: values[0]
|
|
3422
|
-
};
|
|
3423
|
-
} else if (edges.length > 1) {
|
|
3424
|
-
filter[fieldKey] = {
|
|
3425
|
-
in: values
|
|
3426
|
-
};
|
|
3427
|
-
} else {
|
|
3428
|
-
filter[fieldKey] = {
|
|
3429
|
-
eq: "___null___"
|
|
3430
|
-
};
|
|
3431
|
-
}
|
|
3432
|
-
} else if (fieldDefinition.type === "object") {
|
|
3433
|
-
if (fieldDefinition.templates) {
|
|
3434
|
-
for (const templateName of Object.keys(filter[fieldKey])) {
|
|
3435
|
-
const template = fieldDefinition.templates.find(
|
|
3436
|
-
(template2) => !(typeof template2 === "string") && template2.name === templateName
|
|
3437
|
-
);
|
|
3438
|
-
if (template) {
|
|
3439
|
-
await resolveReferences(
|
|
3440
|
-
filter[fieldKey][templateName],
|
|
3441
|
-
template.fields,
|
|
3442
|
-
resolver
|
|
3443
|
-
);
|
|
3444
|
-
} else {
|
|
3445
|
-
throw new Error(`Template ${templateName} not found`);
|
|
3446
|
-
}
|
|
3447
|
-
}
|
|
3448
|
-
} else {
|
|
3449
|
-
await resolveReferences(
|
|
3450
|
-
filter[fieldKey],
|
|
3451
|
-
fieldDefinition.fields,
|
|
3452
|
-
resolver
|
|
3453
|
-
);
|
|
3454
|
-
}
|
|
3455
|
-
}
|
|
3456
|
-
} else {
|
|
3457
|
-
throw new Error(`Unable to find field ${fieldKey}`);
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
};
|
|
3461
|
-
var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
|
|
3462
|
-
for (const childFieldName of Object.keys(filterNode)) {
|
|
3463
|
-
const childField = fields.find((field) => field.name === childFieldName);
|
|
3464
|
-
if (!childField) {
|
|
3465
|
-
throw new Error(`Unable to find type for field ${childFieldName}`);
|
|
3466
|
-
}
|
|
3467
|
-
collectConditionsForField(
|
|
3468
|
-
childFieldName,
|
|
3469
|
-
childField,
|
|
3470
|
-
filterNode[childFieldName],
|
|
3471
|
-
pathExpression,
|
|
3472
|
-
collectCondition
|
|
3473
|
-
);
|
|
3474
|
-
}
|
|
3475
|
-
};
|
|
3476
|
-
var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3477
|
-
if (field.list && field.templates) {
|
|
3478
|
-
for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
|
|
3479
|
-
const template = field.templates.find(
|
|
3480
|
-
(template2) => !(typeof template2 === "string") && template2.name === filterKey
|
|
3481
|
-
);
|
|
3482
|
-
const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
|
|
3483
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
|
|
3484
|
-
collectConditionsForChildFields(
|
|
3485
|
-
childFilterNode,
|
|
3486
|
-
template.fields,
|
|
3487
|
-
filterPath,
|
|
3488
|
-
collectCondition
|
|
3489
|
-
);
|
|
3490
|
-
}
|
|
3491
|
-
} else {
|
|
3492
|
-
const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
|
|
3493
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
|
|
3494
|
-
collectConditionsForChildFields(
|
|
3495
|
-
filterNode,
|
|
3496
|
-
field.fields,
|
|
3497
|
-
filterPath,
|
|
3498
|
-
collectCondition
|
|
3499
|
-
);
|
|
3500
|
-
}
|
|
3501
|
-
};
|
|
3502
|
-
var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3503
|
-
if (field.type === "object") {
|
|
3504
|
-
collectConditionsForObjectField(
|
|
3505
|
-
fieldName,
|
|
3506
|
-
field,
|
|
3507
|
-
filterNode,
|
|
3508
|
-
pathExpression,
|
|
3509
|
-
collectCondition
|
|
3510
|
-
);
|
|
3511
|
-
} else {
|
|
3512
|
-
collectCondition({
|
|
3513
|
-
filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
|
|
3514
|
-
filterExpression: {
|
|
3515
|
-
_type: field.type,
|
|
3516
|
-
_list: !!field.list,
|
|
3517
|
-
...filterNode
|
|
3518
|
-
}
|
|
3519
|
-
});
|
|
3520
|
-
}
|
|
3521
|
-
};
|
|
3522
|
-
|
|
3523
|
-
// src/resolver/media-utils.ts
|
|
3524
|
-
var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3525
|
-
if (config && value) {
|
|
3526
|
-
if (config.useRelativeMedia === true) {
|
|
3527
|
-
return value;
|
|
3528
|
-
}
|
|
3529
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3530
|
-
const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
|
|
3531
|
-
if (typeof value === "string" && value.includes(assetsURL)) {
|
|
3532
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3533
|
-
schema.config.media.tina.mediaRoot
|
|
3534
|
-
);
|
|
3535
|
-
const strippedURL = value.replace(assetsURL, "");
|
|
3536
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3537
|
-
}
|
|
3538
|
-
if (Array.isArray(value)) {
|
|
3539
|
-
return value.map((v) => {
|
|
3540
|
-
if (!v || typeof v !== "string") return v;
|
|
3541
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3542
|
-
schema.config.media.tina.mediaRoot
|
|
3543
|
-
);
|
|
3544
|
-
const strippedURL = v.replace(assetsURL, "");
|
|
3545
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3546
|
-
});
|
|
3547
|
-
}
|
|
3548
|
-
return value;
|
|
3549
|
-
}
|
|
3550
|
-
return value;
|
|
3551
|
-
} else {
|
|
3552
|
-
return value;
|
|
3553
|
-
}
|
|
3554
|
-
};
|
|
3555
|
-
var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3556
|
-
if (config && value) {
|
|
3557
|
-
if (config.useRelativeMedia === true) {
|
|
3558
|
-
return value;
|
|
3559
|
-
}
|
|
3560
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3561
|
-
const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
|
|
3562
|
-
if (typeof value === "string") {
|
|
3563
|
-
const strippedValue = value.replace(cleanMediaRoot, "");
|
|
3564
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3565
|
-
}
|
|
3566
|
-
if (Array.isArray(value)) {
|
|
3567
|
-
return value.map((v) => {
|
|
3568
|
-
if (!v || typeof v !== "string") return v;
|
|
3569
|
-
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
3570
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3571
|
-
});
|
|
3572
|
-
}
|
|
3573
|
-
}
|
|
3574
|
-
return value;
|
|
3575
|
-
} else {
|
|
3576
|
-
return value;
|
|
3577
|
-
}
|
|
3578
|
-
};
|
|
3579
|
-
var cleanUpSlashes = (path7) => {
|
|
3580
|
-
if (path7) {
|
|
3581
|
-
return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
|
|
3582
|
-
}
|
|
3583
|
-
return "";
|
|
3584
|
-
};
|
|
3585
|
-
var hasTinaMediaConfig = (schema) => {
|
|
3586
|
-
if (!schema.config?.media?.tina) return false;
|
|
3587
|
-
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
3588
|
-
return false;
|
|
3589
|
-
return true;
|
|
3590
|
-
};
|
|
3315
|
+
// src/mdx/index.ts
|
|
3316
|
+
import { parseMDX, serializeMDX } from "@tinacms/mdx";
|
|
3591
3317
|
|
|
3592
3318
|
// src/resolver/index.ts
|
|
3593
3319
|
import { GraphQLError as GraphQLError2 } from "graphql";
|
|
@@ -3610,7 +3336,9 @@ var LevelProxyHandler = {
|
|
|
3610
3336
|
throw new Error(`The property, ${property.toString()}, doesn't exist`);
|
|
3611
3337
|
}
|
|
3612
3338
|
if (typeof target[property] !== "function") {
|
|
3613
|
-
throw new Error(
|
|
3339
|
+
throw new Error(
|
|
3340
|
+
`The property, ${property.toString()}, is not a function`
|
|
3341
|
+
);
|
|
3614
3342
|
}
|
|
3615
3343
|
if (property === "get") {
|
|
3616
3344
|
return async (...args) => {
|
|
@@ -3648,13 +3376,13 @@ import path2 from "path";
|
|
|
3648
3376
|
|
|
3649
3377
|
// src/database/util.ts
|
|
3650
3378
|
import toml from "@iarna/toml";
|
|
3651
|
-
import yaml from "js-yaml";
|
|
3652
|
-
import matter from "gray-matter";
|
|
3653
3379
|
import {
|
|
3654
3380
|
normalizePath
|
|
3655
3381
|
} from "@tinacms/schema-tools";
|
|
3656
|
-
import
|
|
3382
|
+
import matter from "gray-matter";
|
|
3383
|
+
import yaml from "js-yaml";
|
|
3657
3384
|
import path from "path";
|
|
3385
|
+
import micromatch from "micromatch";
|
|
3658
3386
|
|
|
3659
3387
|
// src/database/alias-utils.ts
|
|
3660
3388
|
var replaceBlockAliases = (template, item) => {
|
|
@@ -3995,6 +3723,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
|
|
|
3995
3723
|
|
|
3996
3724
|
// src/database/datalayer.ts
|
|
3997
3725
|
var DEFAULT_COLLECTION_SORT_KEY = "__filepath__";
|
|
3726
|
+
var REFS_COLLECTIONS_SORT_KEY = "__refs__";
|
|
3727
|
+
var REFS_REFERENCE_FIELD = "__tina_ref__";
|
|
3728
|
+
var REFS_PATH_FIELD = "__tina_ref_path__";
|
|
3998
3729
|
var DEFAULT_NUMERIC_LPAD = 4;
|
|
3999
3730
|
var applyPadding = (input, pad) => {
|
|
4000
3731
|
if (pad) {
|
|
@@ -4568,6 +4299,57 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4568
4299
|
}
|
|
4569
4300
|
return result;
|
|
4570
4301
|
};
|
|
4302
|
+
var makeRefOpsForDocument = (filepath, collection, references, data, opType, level) => {
|
|
4303
|
+
const result = [];
|
|
4304
|
+
if (collection) {
|
|
4305
|
+
for (const [c, referencePaths] of Object.entries(references || {})) {
|
|
4306
|
+
if (!referencePaths.length) {
|
|
4307
|
+
continue;
|
|
4308
|
+
}
|
|
4309
|
+
const collectionSublevel = level.sublevel(c, SUBLEVEL_OPTIONS);
|
|
4310
|
+
const refSublevel = collectionSublevel.sublevel(
|
|
4311
|
+
REFS_COLLECTIONS_SORT_KEY,
|
|
4312
|
+
SUBLEVEL_OPTIONS
|
|
4313
|
+
);
|
|
4314
|
+
const references2 = {};
|
|
4315
|
+
for (const path7 of referencePaths) {
|
|
4316
|
+
const ref = JSONPath({ path: path7, json: data });
|
|
4317
|
+
if (!ref) {
|
|
4318
|
+
continue;
|
|
4319
|
+
}
|
|
4320
|
+
if (Array.isArray(ref)) {
|
|
4321
|
+
for (const r of ref) {
|
|
4322
|
+
if (!r) {
|
|
4323
|
+
continue;
|
|
4324
|
+
}
|
|
4325
|
+
if (references2[r]) {
|
|
4326
|
+
references2[r].push(path7);
|
|
4327
|
+
} else {
|
|
4328
|
+
references2[r] = [path7];
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
} else {
|
|
4332
|
+
if (references2[ref]) {
|
|
4333
|
+
references2[ref].push(path7);
|
|
4334
|
+
} else {
|
|
4335
|
+
references2[ref] = [path7];
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
}
|
|
4339
|
+
for (const ref of Object.keys(references2)) {
|
|
4340
|
+
for (const path7 of references2[ref]) {
|
|
4341
|
+
result.push({
|
|
4342
|
+
type: opType,
|
|
4343
|
+
key: `${ref}${INDEX_KEY_FIELD_SEPARATOR}${path7}${INDEX_KEY_FIELD_SEPARATOR}${filepath}`,
|
|
4344
|
+
sublevel: refSublevel,
|
|
4345
|
+
value: opType === "put" ? {} : void 0
|
|
4346
|
+
});
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
return result;
|
|
4352
|
+
};
|
|
4571
4353
|
var makeStringEscaper = (regex, replacement) => {
|
|
4572
4354
|
return (input) => {
|
|
4573
4355
|
if (Array.isArray(input)) {
|
|
@@ -4581,12 +4363,248 @@ var makeStringEscaper = (regex, replacement) => {
|
|
|
4581
4363
|
return input;
|
|
4582
4364
|
}
|
|
4583
4365
|
}
|
|
4584
|
-
};
|
|
4366
|
+
};
|
|
4367
|
+
};
|
|
4368
|
+
var stringEscaper = makeStringEscaper(
|
|
4369
|
+
new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
|
|
4370
|
+
encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
|
|
4371
|
+
);
|
|
4372
|
+
|
|
4373
|
+
// src/resolver/error.ts
|
|
4374
|
+
var TinaGraphQLError = class extends Error {
|
|
4375
|
+
constructor(message, extensions) {
|
|
4376
|
+
super(message);
|
|
4377
|
+
if (!this.name) {
|
|
4378
|
+
Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
|
|
4379
|
+
}
|
|
4380
|
+
this.extensions = { ...extensions };
|
|
4381
|
+
}
|
|
4382
|
+
};
|
|
4383
|
+
var TinaFetchError = class extends Error {
|
|
4384
|
+
constructor(message, args) {
|
|
4385
|
+
super(message);
|
|
4386
|
+
this.name = "TinaFetchError";
|
|
4387
|
+
this.collection = args.collection;
|
|
4388
|
+
this.file = args.file;
|
|
4389
|
+
this.originalError = args.originalError;
|
|
4390
|
+
}
|
|
4391
|
+
};
|
|
4392
|
+
var TinaQueryError = class extends TinaFetchError {
|
|
4393
|
+
constructor(args) {
|
|
4394
|
+
super(
|
|
4395
|
+
`Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
4396
|
+
args
|
|
4397
|
+
);
|
|
4398
|
+
}
|
|
4399
|
+
};
|
|
4400
|
+
var TinaParseDocumentError = class extends TinaFetchError {
|
|
4401
|
+
constructor(args) {
|
|
4402
|
+
super(
|
|
4403
|
+
`Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
4404
|
+
args
|
|
4405
|
+
);
|
|
4406
|
+
}
|
|
4407
|
+
toString() {
|
|
4408
|
+
return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
|
|
4409
|
+
}
|
|
4410
|
+
};
|
|
4411
|
+
var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
|
|
4412
|
+
var handleFetchErrorError = (e, verbose) => {
|
|
4413
|
+
if (e instanceof Error) {
|
|
4414
|
+
if (e instanceof TinaFetchError) {
|
|
4415
|
+
if (verbose) {
|
|
4416
|
+
console.log(e.toString());
|
|
4417
|
+
console.log(e);
|
|
4418
|
+
console.log(e.stack);
|
|
4419
|
+
}
|
|
4420
|
+
}
|
|
4421
|
+
} else {
|
|
4422
|
+
console.error(e);
|
|
4423
|
+
}
|
|
4424
|
+
throw e;
|
|
4425
|
+
};
|
|
4426
|
+
|
|
4427
|
+
// src/resolver/filter-utils.ts
|
|
4428
|
+
var resolveReferences = async (filter, fields, resolver) => {
|
|
4429
|
+
for (const fieldKey of Object.keys(filter)) {
|
|
4430
|
+
const fieldDefinition = fields.find(
|
|
4431
|
+
(f) => f.name === fieldKey
|
|
4432
|
+
);
|
|
4433
|
+
if (fieldDefinition) {
|
|
4434
|
+
if (fieldDefinition.type === "reference") {
|
|
4435
|
+
const { edges, values } = await resolver(filter, fieldDefinition);
|
|
4436
|
+
if (edges.length === 1) {
|
|
4437
|
+
filter[fieldKey] = {
|
|
4438
|
+
eq: values[0]
|
|
4439
|
+
};
|
|
4440
|
+
} else if (edges.length > 1) {
|
|
4441
|
+
filter[fieldKey] = {
|
|
4442
|
+
in: values
|
|
4443
|
+
};
|
|
4444
|
+
} else {
|
|
4445
|
+
filter[fieldKey] = {
|
|
4446
|
+
eq: "___null___"
|
|
4447
|
+
};
|
|
4448
|
+
}
|
|
4449
|
+
} else if (fieldDefinition.type === "object") {
|
|
4450
|
+
if (fieldDefinition.templates) {
|
|
4451
|
+
for (const templateName of Object.keys(filter[fieldKey])) {
|
|
4452
|
+
const template = fieldDefinition.templates.find(
|
|
4453
|
+
(template2) => !(typeof template2 === "string") && template2.name === templateName
|
|
4454
|
+
);
|
|
4455
|
+
if (template) {
|
|
4456
|
+
await resolveReferences(
|
|
4457
|
+
filter[fieldKey][templateName],
|
|
4458
|
+
template.fields,
|
|
4459
|
+
resolver
|
|
4460
|
+
);
|
|
4461
|
+
} else {
|
|
4462
|
+
throw new Error(`Template ${templateName} not found`);
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
} else {
|
|
4466
|
+
await resolveReferences(
|
|
4467
|
+
filter[fieldKey],
|
|
4468
|
+
fieldDefinition.fields,
|
|
4469
|
+
resolver
|
|
4470
|
+
);
|
|
4471
|
+
}
|
|
4472
|
+
}
|
|
4473
|
+
} else {
|
|
4474
|
+
throw new Error(`Unable to find field ${fieldKey}`);
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
};
|
|
4478
|
+
var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
|
|
4479
|
+
for (const childFieldName of Object.keys(filterNode)) {
|
|
4480
|
+
const childField = fields.find((field) => field.name === childFieldName);
|
|
4481
|
+
if (!childField) {
|
|
4482
|
+
throw new Error(`Unable to find type for field ${childFieldName}`);
|
|
4483
|
+
}
|
|
4484
|
+
collectConditionsForField(
|
|
4485
|
+
childFieldName,
|
|
4486
|
+
childField,
|
|
4487
|
+
filterNode[childFieldName],
|
|
4488
|
+
pathExpression,
|
|
4489
|
+
collectCondition
|
|
4490
|
+
);
|
|
4491
|
+
}
|
|
4492
|
+
};
|
|
4493
|
+
var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
4494
|
+
if (field.list && field.templates) {
|
|
4495
|
+
for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
|
|
4496
|
+
const template = field.templates.find(
|
|
4497
|
+
(template2) => !(typeof template2 === "string") && template2.name === filterKey
|
|
4498
|
+
);
|
|
4499
|
+
const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
|
|
4500
|
+
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
|
|
4501
|
+
collectConditionsForChildFields(
|
|
4502
|
+
childFilterNode,
|
|
4503
|
+
template.fields,
|
|
4504
|
+
filterPath,
|
|
4505
|
+
collectCondition
|
|
4506
|
+
);
|
|
4507
|
+
}
|
|
4508
|
+
} else {
|
|
4509
|
+
const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
|
|
4510
|
+
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
|
|
4511
|
+
collectConditionsForChildFields(
|
|
4512
|
+
filterNode,
|
|
4513
|
+
field.fields,
|
|
4514
|
+
filterPath,
|
|
4515
|
+
collectCondition
|
|
4516
|
+
);
|
|
4517
|
+
}
|
|
4518
|
+
};
|
|
4519
|
+
var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
4520
|
+
if (field.type === "object") {
|
|
4521
|
+
collectConditionsForObjectField(
|
|
4522
|
+
fieldName,
|
|
4523
|
+
field,
|
|
4524
|
+
filterNode,
|
|
4525
|
+
pathExpression,
|
|
4526
|
+
collectCondition
|
|
4527
|
+
);
|
|
4528
|
+
} else {
|
|
4529
|
+
collectCondition({
|
|
4530
|
+
filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
|
|
4531
|
+
filterExpression: {
|
|
4532
|
+
_type: field.type,
|
|
4533
|
+
_list: !!field.list,
|
|
4534
|
+
...filterNode
|
|
4535
|
+
}
|
|
4536
|
+
});
|
|
4537
|
+
}
|
|
4538
|
+
};
|
|
4539
|
+
|
|
4540
|
+
// src/resolver/media-utils.ts
|
|
4541
|
+
var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
|
|
4542
|
+
if (config && value) {
|
|
4543
|
+
if (config.useRelativeMedia === true) {
|
|
4544
|
+
return value;
|
|
4545
|
+
}
|
|
4546
|
+
if (hasTinaMediaConfig(schema) === true) {
|
|
4547
|
+
const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
|
|
4548
|
+
if (typeof value === "string" && value.includes(assetsURL)) {
|
|
4549
|
+
const cleanMediaRoot = cleanUpSlashes(
|
|
4550
|
+
schema.config.media.tina.mediaRoot
|
|
4551
|
+
);
|
|
4552
|
+
const strippedURL = value.replace(assetsURL, "");
|
|
4553
|
+
return `${cleanMediaRoot}${strippedURL}`;
|
|
4554
|
+
}
|
|
4555
|
+
if (Array.isArray(value)) {
|
|
4556
|
+
return value.map((v) => {
|
|
4557
|
+
if (!v || typeof v !== "string") return v;
|
|
4558
|
+
const cleanMediaRoot = cleanUpSlashes(
|
|
4559
|
+
schema.config.media.tina.mediaRoot
|
|
4560
|
+
);
|
|
4561
|
+
const strippedURL = v.replace(assetsURL, "");
|
|
4562
|
+
return `${cleanMediaRoot}${strippedURL}`;
|
|
4563
|
+
});
|
|
4564
|
+
}
|
|
4565
|
+
return value;
|
|
4566
|
+
}
|
|
4567
|
+
return value;
|
|
4568
|
+
} else {
|
|
4569
|
+
return value;
|
|
4570
|
+
}
|
|
4571
|
+
};
|
|
4572
|
+
var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
|
|
4573
|
+
if (config && value) {
|
|
4574
|
+
if (config.useRelativeMedia === true) {
|
|
4575
|
+
return value;
|
|
4576
|
+
}
|
|
4577
|
+
if (hasTinaMediaConfig(schema) === true) {
|
|
4578
|
+
const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
|
|
4579
|
+
if (typeof value === "string") {
|
|
4580
|
+
const strippedValue = value.replace(cleanMediaRoot, "");
|
|
4581
|
+
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
4582
|
+
}
|
|
4583
|
+
if (Array.isArray(value)) {
|
|
4584
|
+
return value.map((v) => {
|
|
4585
|
+
if (!v || typeof v !== "string") return v;
|
|
4586
|
+
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
4587
|
+
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
4588
|
+
});
|
|
4589
|
+
}
|
|
4590
|
+
}
|
|
4591
|
+
return value;
|
|
4592
|
+
} else {
|
|
4593
|
+
return value;
|
|
4594
|
+
}
|
|
4595
|
+
};
|
|
4596
|
+
var cleanUpSlashes = (path7) => {
|
|
4597
|
+
if (path7) {
|
|
4598
|
+
return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
|
|
4599
|
+
}
|
|
4600
|
+
return "";
|
|
4601
|
+
};
|
|
4602
|
+
var hasTinaMediaConfig = (schema) => {
|
|
4603
|
+
if (!schema.config?.media?.tina) return false;
|
|
4604
|
+
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
4605
|
+
return false;
|
|
4606
|
+
return true;
|
|
4585
4607
|
};
|
|
4586
|
-
var stringEscaper = makeStringEscaper(
|
|
4587
|
-
new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
|
|
4588
|
-
encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
|
|
4589
|
-
);
|
|
4590
4608
|
|
|
4591
4609
|
// src/resolver/index.ts
|
|
4592
4610
|
var createResolver = (args) => {
|
|
@@ -4748,8 +4766,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4748
4766
|
originalError: e,
|
|
4749
4767
|
collection: collection.name,
|
|
4750
4768
|
includeAuditMessage: !isAudit,
|
|
4751
|
-
file: relativePath
|
|
4752
|
-
stack: e.stack
|
|
4769
|
+
file: relativePath
|
|
4753
4770
|
});
|
|
4754
4771
|
}
|
|
4755
4772
|
const titleField = template.fields.find((x) => {
|
|
@@ -4788,24 +4805,33 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4788
4805
|
throw e;
|
|
4789
4806
|
}
|
|
4790
4807
|
};
|
|
4791
|
-
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4808
|
+
var updateObjectWithJsonPath = (obj, path7, oldValue, newValue) => {
|
|
4809
|
+
let updated = false;
|
|
4792
4810
|
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4793
|
-
if (path7 in obj) {
|
|
4811
|
+
if (path7 in obj && obj[path7] === oldValue) {
|
|
4794
4812
|
obj[path7] = newValue;
|
|
4813
|
+
updated = true;
|
|
4795
4814
|
}
|
|
4796
|
-
return obj;
|
|
4797
|
-
}
|
|
4798
|
-
const parentPath = path7.replace(/\.[
|
|
4799
|
-
const keyToUpdate = path7.match(/[
|
|
4800
|
-
const parents = JSONPath2({
|
|
4815
|
+
return { object: obj, updated };
|
|
4816
|
+
}
|
|
4817
|
+
const parentPath = path7.replace(/\.[^.\[\]]+$/, "");
|
|
4818
|
+
const keyToUpdate = path7.match(/[^.\[\]]+$/)[0];
|
|
4819
|
+
const parents = JSONPath2({
|
|
4820
|
+
path: parentPath,
|
|
4821
|
+
json: obj,
|
|
4822
|
+
resultType: "value"
|
|
4823
|
+
});
|
|
4801
4824
|
if (parents.length > 0) {
|
|
4802
4825
|
parents.forEach((parent) => {
|
|
4803
4826
|
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4804
|
-
parent[keyToUpdate]
|
|
4827
|
+
if (parent[keyToUpdate] === oldValue) {
|
|
4828
|
+
parent[keyToUpdate] = newValue;
|
|
4829
|
+
updated = true;
|
|
4830
|
+
}
|
|
4805
4831
|
}
|
|
4806
4832
|
});
|
|
4807
4833
|
}
|
|
4808
|
-
return obj;
|
|
4834
|
+
return { object: obj, updated };
|
|
4809
4835
|
};
|
|
4810
4836
|
var Resolver = class {
|
|
4811
4837
|
constructor(init) {
|
|
@@ -4822,7 +4848,9 @@ var Resolver = class {
|
|
|
4822
4848
|
};
|
|
4823
4849
|
this.getRaw = async (fullPath) => {
|
|
4824
4850
|
if (typeof fullPath !== "string") {
|
|
4825
|
-
throw new Error(
|
|
4851
|
+
throw new Error(
|
|
4852
|
+
`fullPath must be of type string for getDocument request`
|
|
4853
|
+
);
|
|
4826
4854
|
}
|
|
4827
4855
|
return this.database.get(fullPath);
|
|
4828
4856
|
};
|
|
@@ -4851,7 +4879,9 @@ var Resolver = class {
|
|
|
4851
4879
|
};
|
|
4852
4880
|
this.getDocument = async (fullPath, opts = {}) => {
|
|
4853
4881
|
if (typeof fullPath !== "string") {
|
|
4854
|
-
throw new Error(
|
|
4882
|
+
throw new Error(
|
|
4883
|
+
`fullPath must be of type string for getDocument request`
|
|
4884
|
+
);
|
|
4855
4885
|
}
|
|
4856
4886
|
const rawData = await this.getRaw(fullPath);
|
|
4857
4887
|
const hasReferences = opts?.checkReferences ? await this.hasReferences(fullPath, opts.collection) : void 0;
|
|
@@ -4866,7 +4896,9 @@ var Resolver = class {
|
|
|
4866
4896
|
};
|
|
4867
4897
|
this.deleteDocument = async (fullPath) => {
|
|
4868
4898
|
if (typeof fullPath !== "string") {
|
|
4869
|
-
throw new Error(
|
|
4899
|
+
throw new Error(
|
|
4900
|
+
`fullPath must be of type string for getDocument request`
|
|
4901
|
+
);
|
|
4870
4902
|
}
|
|
4871
4903
|
await this.database.delete(fullPath);
|
|
4872
4904
|
};
|
|
@@ -5070,7 +5102,11 @@ var Resolver = class {
|
|
|
5070
5102
|
collection,
|
|
5071
5103
|
doc?._rawData
|
|
5072
5104
|
);
|
|
5073
|
-
await this.database.put(
|
|
5105
|
+
await this.database.put(
|
|
5106
|
+
realPath,
|
|
5107
|
+
{ ...oldDoc, ...params },
|
|
5108
|
+
collection.name
|
|
5109
|
+
);
|
|
5074
5110
|
return this.getDocument(realPath);
|
|
5075
5111
|
};
|
|
5076
5112
|
/**
|
|
@@ -5183,17 +5219,35 @@ var Resolver = class {
|
|
|
5183
5219
|
await this.deleteDocument(realPath);
|
|
5184
5220
|
if (await this.hasReferences(realPath, collection)) {
|
|
5185
5221
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5186
|
-
for (const [collection2,
|
|
5187
|
-
for (const [
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5222
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5223
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5224
|
+
docsWithRefs
|
|
5225
|
+
)) {
|
|
5226
|
+
let refDoc = await this.getRaw(pathToDocWithRef);
|
|
5227
|
+
let hasUpdate = false;
|
|
5228
|
+
for (const path7 of referencePaths) {
|
|
5229
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5191
5230
|
refDoc,
|
|
5192
|
-
|
|
5231
|
+
path7,
|
|
5232
|
+
realPath,
|
|
5193
5233
|
null
|
|
5194
5234
|
);
|
|
5235
|
+
refDoc = object2;
|
|
5236
|
+
hasUpdate = updated || hasUpdate;
|
|
5237
|
+
}
|
|
5238
|
+
if (hasUpdate) {
|
|
5239
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5240
|
+
if (!collectionWithRef) {
|
|
5241
|
+
throw new Error(
|
|
5242
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5243
|
+
);
|
|
5244
|
+
}
|
|
5245
|
+
await this.database.put(
|
|
5246
|
+
pathToDocWithRef,
|
|
5247
|
+
refDoc,
|
|
5248
|
+
collectionWithRef.name
|
|
5249
|
+
);
|
|
5195
5250
|
}
|
|
5196
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5197
5251
|
}
|
|
5198
5252
|
}
|
|
5199
5253
|
}
|
|
@@ -5213,26 +5267,49 @@ var Resolver = class {
|
|
|
5213
5267
|
collection?.path,
|
|
5214
5268
|
args.params.relativePath
|
|
5215
5269
|
);
|
|
5270
|
+
if (newRealPath === realPath) {
|
|
5271
|
+
return doc;
|
|
5272
|
+
}
|
|
5216
5273
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
5217
5274
|
await this.deleteDocument(realPath);
|
|
5218
5275
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5219
|
-
for (const [collection2,
|
|
5220
|
-
for (const [
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5276
|
+
for (const [collection2, docsWithRefs] of Object.entries(collRefs)) {
|
|
5277
|
+
for (const [pathToDocWithRef, referencePaths] of Object.entries(
|
|
5278
|
+
docsWithRefs
|
|
5279
|
+
)) {
|
|
5280
|
+
let docWithRef = await this.getRaw(pathToDocWithRef);
|
|
5281
|
+
let hasUpdate = false;
|
|
5282
|
+
for (const path7 of referencePaths) {
|
|
5283
|
+
const { object: object2, updated } = updateObjectWithJsonPath(
|
|
5284
|
+
docWithRef,
|
|
5285
|
+
path7,
|
|
5286
|
+
realPath,
|
|
5226
5287
|
newRealPath
|
|
5227
5288
|
);
|
|
5289
|
+
docWithRef = object2;
|
|
5290
|
+
hasUpdate = updated || hasUpdate;
|
|
5291
|
+
}
|
|
5292
|
+
if (hasUpdate) {
|
|
5293
|
+
const collectionWithRef = this.tinaSchema.getCollectionByFullPath(pathToDocWithRef);
|
|
5294
|
+
if (!collectionWithRef) {
|
|
5295
|
+
throw new Error(
|
|
5296
|
+
`Unable to find collection for ${pathToDocWithRef}`
|
|
5297
|
+
);
|
|
5298
|
+
}
|
|
5299
|
+
await this.database.put(
|
|
5300
|
+
pathToDocWithRef,
|
|
5301
|
+
docWithRef,
|
|
5302
|
+
collectionWithRef.name
|
|
5303
|
+
);
|
|
5228
5304
|
}
|
|
5229
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5230
5305
|
}
|
|
5231
5306
|
}
|
|
5232
5307
|
return this.getDocument(newRealPath);
|
|
5233
5308
|
}
|
|
5234
5309
|
if (alreadyExists === false) {
|
|
5235
|
-
throw new Error(
|
|
5310
|
+
throw new Error(
|
|
5311
|
+
`Unable to update document, ${realPath} does not exist`
|
|
5312
|
+
);
|
|
5236
5313
|
}
|
|
5237
5314
|
return this.updateResolveDocument({
|
|
5238
5315
|
collection,
|
|
@@ -5358,35 +5435,30 @@ var Resolver = class {
|
|
|
5358
5435
|
*/
|
|
5359
5436
|
this.hasReferences = async (id, c) => {
|
|
5360
5437
|
let count = 0;
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
(refId) => {
|
|
5382
|
-
count++;
|
|
5383
|
-
return refId;
|
|
5384
|
-
}
|
|
5385
|
-
);
|
|
5386
|
-
if (count) {
|
|
5387
|
-
return true;
|
|
5388
|
-
}
|
|
5438
|
+
await this.database.query(
|
|
5439
|
+
{
|
|
5440
|
+
collection: c.name,
|
|
5441
|
+
filterChain: makeFilterChain({
|
|
5442
|
+
conditions: [
|
|
5443
|
+
{
|
|
5444
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5445
|
+
filterExpression: {
|
|
5446
|
+
_type: "string",
|
|
5447
|
+
_list: false,
|
|
5448
|
+
eq: id
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
]
|
|
5452
|
+
}),
|
|
5453
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5454
|
+
},
|
|
5455
|
+
(refId) => {
|
|
5456
|
+
count++;
|
|
5457
|
+
return refId;
|
|
5389
5458
|
}
|
|
5459
|
+
);
|
|
5460
|
+
if (count) {
|
|
5461
|
+
return true;
|
|
5390
5462
|
}
|
|
5391
5463
|
return false;
|
|
5392
5464
|
};
|
|
@@ -5394,46 +5466,41 @@ var Resolver = class {
|
|
|
5394
5466
|
* Finds references to a document
|
|
5395
5467
|
* @param id the id of the document to find references to
|
|
5396
5468
|
* @param c the collection to find references in
|
|
5397
|
-
* @returns
|
|
5469
|
+
* @returns a map of references to the document
|
|
5398
5470
|
*/
|
|
5399
5471
|
this.findReferences = async (id, c) => {
|
|
5400
5472
|
const references = {};
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
_list: false,
|
|
5414
|
-
eq: id
|
|
5415
|
-
}
|
|
5416
|
-
}
|
|
5417
|
-
]
|
|
5418
|
-
}),
|
|
5419
|
-
sort: ref.field.name
|
|
5420
|
-
},
|
|
5421
|
-
(refId) => {
|
|
5422
|
-
if (!references[collection]) {
|
|
5423
|
-
references[collection] = {};
|
|
5424
|
-
}
|
|
5425
|
-
if (!references[collection][refId]) {
|
|
5426
|
-
references[collection][refId] = [];
|
|
5473
|
+
await this.database.query(
|
|
5474
|
+
{
|
|
5475
|
+
collection: c.name,
|
|
5476
|
+
filterChain: makeFilterChain({
|
|
5477
|
+
conditions: [
|
|
5478
|
+
{
|
|
5479
|
+
filterPath: REFS_REFERENCE_FIELD,
|
|
5480
|
+
filterExpression: {
|
|
5481
|
+
_type: "string",
|
|
5482
|
+
_list: false,
|
|
5483
|
+
eq: id
|
|
5484
|
+
}
|
|
5427
5485
|
}
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5486
|
+
]
|
|
5487
|
+
}),
|
|
5488
|
+
sort: REFS_COLLECTIONS_SORT_KEY
|
|
5489
|
+
},
|
|
5490
|
+
(refId, rawItem) => {
|
|
5491
|
+
if (!references[c.name]) {
|
|
5492
|
+
references[c.name] = {};
|
|
5493
|
+
}
|
|
5494
|
+
if (!references[c.name][refId]) {
|
|
5495
|
+
references[c.name][refId] = [];
|
|
5496
|
+
}
|
|
5497
|
+
const referencePath = rawItem?.[REFS_PATH_FIELD];
|
|
5498
|
+
if (referencePath) {
|
|
5499
|
+
references[c.name][refId].push(referencePath);
|
|
5500
|
+
}
|
|
5501
|
+
return refId;
|
|
5435
5502
|
}
|
|
5436
|
-
|
|
5503
|
+
);
|
|
5437
5504
|
return references;
|
|
5438
5505
|
};
|
|
5439
5506
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
@@ -5503,7 +5570,7 @@ var Resolver = class {
|
|
|
5503
5570
|
}
|
|
5504
5571
|
break;
|
|
5505
5572
|
case "rich-text":
|
|
5506
|
-
accum[fieldName] =
|
|
5573
|
+
accum[fieldName] = serializeMDX(
|
|
5507
5574
|
fieldValue,
|
|
5508
5575
|
field,
|
|
5509
5576
|
(fieldValue2) => resolveMediaCloudToRelative(
|
|
@@ -5610,8 +5677,129 @@ var resolveDateInput = (value) => {
|
|
|
5610
5677
|
return date;
|
|
5611
5678
|
};
|
|
5612
5679
|
|
|
5613
|
-
// src/
|
|
5680
|
+
// src/resolver/auth-fields.ts
|
|
5614
5681
|
import set from "lodash.set";
|
|
5682
|
+
async function getUserDocumentContext(tinaSchema, resolver) {
|
|
5683
|
+
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5684
|
+
if (!collection) {
|
|
5685
|
+
throw new Error("Auth collection not found");
|
|
5686
|
+
}
|
|
5687
|
+
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5688
|
+
if (!userFields.length) {
|
|
5689
|
+
throw new Error(`No user field found in collection ${collection.name}`);
|
|
5690
|
+
}
|
|
5691
|
+
if (userFields.length > 1) {
|
|
5692
|
+
throw new Error(
|
|
5693
|
+
`Multiple user fields found in collection ${collection.name}`
|
|
5694
|
+
);
|
|
5695
|
+
}
|
|
5696
|
+
const userField = userFields[0];
|
|
5697
|
+
const realPath = `${collection.path}/index.json`;
|
|
5698
|
+
const userDoc = await resolver.getDocument(realPath);
|
|
5699
|
+
const users = get(userDoc, userField.path);
|
|
5700
|
+
if (!users) {
|
|
5701
|
+
throw new Error("No users found");
|
|
5702
|
+
}
|
|
5703
|
+
return { collection, userField, users, userDoc, realPath };
|
|
5704
|
+
}
|
|
5705
|
+
function findUserInCollection(users, userField, userSub) {
|
|
5706
|
+
const { idFieldName } = userField;
|
|
5707
|
+
if (!idFieldName) {
|
|
5708
|
+
throw new Error("No uid field found on user field");
|
|
5709
|
+
}
|
|
5710
|
+
return users.find((u) => u[idFieldName] === userSub) || null;
|
|
5711
|
+
}
|
|
5712
|
+
async function handleAuthenticate({
|
|
5713
|
+
tinaSchema,
|
|
5714
|
+
resolver,
|
|
5715
|
+
sub,
|
|
5716
|
+
password,
|
|
5717
|
+
ctxUser
|
|
5718
|
+
}) {
|
|
5719
|
+
const userSub = sub || ctxUser?.sub;
|
|
5720
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5721
|
+
tinaSchema,
|
|
5722
|
+
resolver
|
|
5723
|
+
);
|
|
5724
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5725
|
+
if (!user) {
|
|
5726
|
+
return null;
|
|
5727
|
+
}
|
|
5728
|
+
const { passwordFieldName } = userField;
|
|
5729
|
+
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5730
|
+
if (!saltedHash) {
|
|
5731
|
+
throw new Error("No password field found on user field");
|
|
5732
|
+
}
|
|
5733
|
+
const matches = await checkPasswordHash({
|
|
5734
|
+
saltedHash,
|
|
5735
|
+
password
|
|
5736
|
+
});
|
|
5737
|
+
return matches ? user : null;
|
|
5738
|
+
}
|
|
5739
|
+
async function handleAuthorize({
|
|
5740
|
+
tinaSchema,
|
|
5741
|
+
resolver,
|
|
5742
|
+
sub,
|
|
5743
|
+
ctxUser
|
|
5744
|
+
}) {
|
|
5745
|
+
const userSub = sub || ctxUser?.sub;
|
|
5746
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5747
|
+
tinaSchema,
|
|
5748
|
+
resolver
|
|
5749
|
+
);
|
|
5750
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5751
|
+
return user ? user : null;
|
|
5752
|
+
}
|
|
5753
|
+
async function handleUpdatePassword({
|
|
5754
|
+
tinaSchema,
|
|
5755
|
+
resolver,
|
|
5756
|
+
password,
|
|
5757
|
+
ctxUser
|
|
5758
|
+
}) {
|
|
5759
|
+
if (!ctxUser?.sub) {
|
|
5760
|
+
throw new Error("Not authorized");
|
|
5761
|
+
}
|
|
5762
|
+
if (!password) {
|
|
5763
|
+
throw new Error("No password provided");
|
|
5764
|
+
}
|
|
5765
|
+
const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
|
|
5766
|
+
const { idFieldName, passwordFieldName } = userField;
|
|
5767
|
+
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5768
|
+
if (!user) {
|
|
5769
|
+
throw new Error("Not authorized");
|
|
5770
|
+
}
|
|
5771
|
+
user[passwordFieldName] = {
|
|
5772
|
+
value: password,
|
|
5773
|
+
passwordChangeRequired: false
|
|
5774
|
+
};
|
|
5775
|
+
const params = {};
|
|
5776
|
+
set(
|
|
5777
|
+
params,
|
|
5778
|
+
userField.path.slice(1),
|
|
5779
|
+
// remove _rawData from users path
|
|
5780
|
+
users.map((u) => {
|
|
5781
|
+
if (user[idFieldName] === u[idFieldName]) {
|
|
5782
|
+
return user;
|
|
5783
|
+
}
|
|
5784
|
+
return {
|
|
5785
|
+
// don't overwrite other users' passwords
|
|
5786
|
+
...u,
|
|
5787
|
+
[passwordFieldName]: {
|
|
5788
|
+
...u[passwordFieldName],
|
|
5789
|
+
value: ""
|
|
5790
|
+
}
|
|
5791
|
+
};
|
|
5792
|
+
})
|
|
5793
|
+
);
|
|
5794
|
+
await resolver.updateResolveDocument({
|
|
5795
|
+
collection,
|
|
5796
|
+
args: { params },
|
|
5797
|
+
realPath,
|
|
5798
|
+
isCollectionSpecific: true,
|
|
5799
|
+
isAddPendingDocument: false
|
|
5800
|
+
});
|
|
5801
|
+
return true;
|
|
5802
|
+
}
|
|
5615
5803
|
|
|
5616
5804
|
// src/error.ts
|
|
5617
5805
|
import { GraphQLError as GraphQLError3 } from "graphql";
|
|
@@ -5721,119 +5909,33 @@ var resolve = async ({
|
|
|
5721
5909
|
);
|
|
5722
5910
|
}
|
|
5723
5911
|
}
|
|
5724
|
-
if (info.fieldName === "authenticate"
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
const realPath = `${collection.path}/index.json`;
|
|
5743
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5744
|
-
const users = get(userDoc, userField.path);
|
|
5745
|
-
if (!users) {
|
|
5746
|
-
throw new Error("No users found");
|
|
5747
|
-
}
|
|
5748
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5749
|
-
if (!idFieldName) {
|
|
5750
|
-
throw new Error("No uid field found on user field");
|
|
5751
|
-
}
|
|
5752
|
-
const user = users.find((u) => u[idFieldName] === sub);
|
|
5753
|
-
if (!user) {
|
|
5754
|
-
return null;
|
|
5755
|
-
}
|
|
5756
|
-
if (info.fieldName === "authenticate") {
|
|
5757
|
-
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5758
|
-
if (!saltedHash) {
|
|
5759
|
-
throw new Error("No password field found on user field");
|
|
5760
|
-
}
|
|
5761
|
-
const matches = await checkPasswordHash({
|
|
5762
|
-
saltedHash,
|
|
5763
|
-
password: args.password
|
|
5764
|
-
});
|
|
5765
|
-
if (matches) {
|
|
5766
|
-
return user;
|
|
5767
|
-
}
|
|
5768
|
-
return null;
|
|
5769
|
-
}
|
|
5770
|
-
return user;
|
|
5912
|
+
if (info.fieldName === "authenticate") {
|
|
5913
|
+
return handleAuthenticate({
|
|
5914
|
+
tinaSchema,
|
|
5915
|
+
resolver,
|
|
5916
|
+
sub: args.sub,
|
|
5917
|
+
password: args.password,
|
|
5918
|
+
info,
|
|
5919
|
+
ctxUser
|
|
5920
|
+
});
|
|
5921
|
+
}
|
|
5922
|
+
if (info.fieldName === "authorize") {
|
|
5923
|
+
return handleAuthorize({
|
|
5924
|
+
tinaSchema,
|
|
5925
|
+
resolver,
|
|
5926
|
+
sub: args.sub,
|
|
5927
|
+
info,
|
|
5928
|
+
ctxUser
|
|
5929
|
+
});
|
|
5771
5930
|
}
|
|
5772
5931
|
if (info.fieldName === "updatePassword") {
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5780
|
-
if (!collection) {
|
|
5781
|
-
throw new Error("Auth collection not found");
|
|
5782
|
-
}
|
|
5783
|
-
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5784
|
-
if (!userFields.length) {
|
|
5785
|
-
throw new Error(
|
|
5786
|
-
`No user field found in collection ${collection.name}`
|
|
5787
|
-
);
|
|
5788
|
-
}
|
|
5789
|
-
if (userFields.length > 1) {
|
|
5790
|
-
throw new Error(
|
|
5791
|
-
`Multiple user fields found in collection ${collection.name}`
|
|
5792
|
-
);
|
|
5793
|
-
}
|
|
5794
|
-
const userField = userFields[0];
|
|
5795
|
-
const realPath = `${collection.path}/index.json`;
|
|
5796
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5797
|
-
const users = get(userDoc, userField.path);
|
|
5798
|
-
if (!users) {
|
|
5799
|
-
throw new Error("No users found");
|
|
5800
|
-
}
|
|
5801
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5802
|
-
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5803
|
-
if (!user) {
|
|
5804
|
-
throw new Error("Not authorized");
|
|
5805
|
-
}
|
|
5806
|
-
user[passwordFieldName] = {
|
|
5807
|
-
value: args.password,
|
|
5808
|
-
passwordChangeRequired: false
|
|
5809
|
-
};
|
|
5810
|
-
const params = {};
|
|
5811
|
-
set(
|
|
5812
|
-
params,
|
|
5813
|
-
userField.path.slice(1),
|
|
5814
|
-
// remove _rawData from users path
|
|
5815
|
-
users.map((u) => {
|
|
5816
|
-
if (user[idFieldName] === u[idFieldName]) {
|
|
5817
|
-
return user;
|
|
5818
|
-
}
|
|
5819
|
-
return {
|
|
5820
|
-
// don't overwrite other users' passwords
|
|
5821
|
-
...u,
|
|
5822
|
-
[passwordFieldName]: {
|
|
5823
|
-
...u[passwordFieldName],
|
|
5824
|
-
value: ""
|
|
5825
|
-
}
|
|
5826
|
-
};
|
|
5827
|
-
})
|
|
5828
|
-
);
|
|
5829
|
-
await resolver.updateResolveDocument({
|
|
5830
|
-
collection,
|
|
5831
|
-
args: { params },
|
|
5832
|
-
realPath,
|
|
5833
|
-
isCollectionSpecific: true,
|
|
5834
|
-
isAddPendingDocument: false
|
|
5932
|
+
return handleUpdatePassword({
|
|
5933
|
+
tinaSchema,
|
|
5934
|
+
resolver,
|
|
5935
|
+
password: args.password,
|
|
5936
|
+
info,
|
|
5937
|
+
ctxUser
|
|
5835
5938
|
});
|
|
5836
|
-
return true;
|
|
5837
5939
|
}
|
|
5838
5940
|
if (!lookup) {
|
|
5839
5941
|
return value;
|
|
@@ -6177,6 +6279,7 @@ var Database = class {
|
|
|
6177
6279
|
);
|
|
6178
6280
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6179
6281
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6282
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6180
6283
|
const normalizedPath = normalizePath(filepath);
|
|
6181
6284
|
if (!collection?.isDetached) {
|
|
6182
6285
|
if (this.bridge) {
|
|
@@ -6205,6 +6308,14 @@ var Database = class {
|
|
|
6205
6308
|
let delOps = [];
|
|
6206
6309
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6207
6310
|
putOps = [
|
|
6311
|
+
...makeRefOpsForDocument(
|
|
6312
|
+
normalizedPath,
|
|
6313
|
+
collection?.name,
|
|
6314
|
+
collectionReferences,
|
|
6315
|
+
dataFields,
|
|
6316
|
+
"put",
|
|
6317
|
+
level
|
|
6318
|
+
),
|
|
6208
6319
|
...makeIndexOpsForDocument(
|
|
6209
6320
|
normalizedPath,
|
|
6210
6321
|
collection?.name,
|
|
@@ -6228,6 +6339,14 @@ var Database = class {
|
|
|
6228
6339
|
SUBLEVEL_OPTIONS
|
|
6229
6340
|
).get(normalizedPath);
|
|
6230
6341
|
delOps = existingItem ? [
|
|
6342
|
+
...makeRefOpsForDocument(
|
|
6343
|
+
normalizedPath,
|
|
6344
|
+
collection?.name,
|
|
6345
|
+
collectionReferences,
|
|
6346
|
+
existingItem,
|
|
6347
|
+
"del",
|
|
6348
|
+
level
|
|
6349
|
+
),
|
|
6231
6350
|
...makeIndexOpsForDocument(
|
|
6232
6351
|
normalizedPath,
|
|
6233
6352
|
collection?.name,
|
|
@@ -6275,6 +6394,7 @@ var Database = class {
|
|
|
6275
6394
|
);
|
|
6276
6395
|
collectionIndexDefinitions = indexDefinitions?.[collectionName];
|
|
6277
6396
|
}
|
|
6397
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collectionName];
|
|
6278
6398
|
const normalizedPath = normalizePath(filepath);
|
|
6279
6399
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
6280
6400
|
const collection = await this.collectionForPath(filepath);
|
|
@@ -6322,6 +6442,14 @@ var Database = class {
|
|
|
6322
6442
|
let delOps = [];
|
|
6323
6443
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6324
6444
|
putOps = [
|
|
6445
|
+
...makeRefOpsForDocument(
|
|
6446
|
+
normalizedPath,
|
|
6447
|
+
collectionName,
|
|
6448
|
+
collectionReferences,
|
|
6449
|
+
dataFields,
|
|
6450
|
+
"put",
|
|
6451
|
+
level
|
|
6452
|
+
),
|
|
6325
6453
|
...makeIndexOpsForDocument(
|
|
6326
6454
|
normalizedPath,
|
|
6327
6455
|
collectionName,
|
|
@@ -6345,6 +6473,14 @@ var Database = class {
|
|
|
6345
6473
|
SUBLEVEL_OPTIONS
|
|
6346
6474
|
).get(normalizedPath);
|
|
6347
6475
|
delOps = existingItem ? [
|
|
6476
|
+
...makeRefOpsForDocument(
|
|
6477
|
+
normalizedPath,
|
|
6478
|
+
collectionName,
|
|
6479
|
+
collectionReferences,
|
|
6480
|
+
existingItem,
|
|
6481
|
+
"del",
|
|
6482
|
+
level
|
|
6483
|
+
),
|
|
6348
6484
|
...makeIndexOpsForDocument(
|
|
6349
6485
|
normalizedPath,
|
|
6350
6486
|
collectionName,
|
|
@@ -6387,8 +6523,7 @@ var Database = class {
|
|
|
6387
6523
|
throw new TinaFetchError(`Error in PUT for ${filepath}`, {
|
|
6388
6524
|
originalError: error,
|
|
6389
6525
|
file: filepath,
|
|
6390
|
-
collection: collectionName
|
|
6391
|
-
stack: error.stack
|
|
6526
|
+
collection: collectionName
|
|
6392
6527
|
});
|
|
6393
6528
|
}
|
|
6394
6529
|
};
|
|
@@ -6507,6 +6642,22 @@ var Database = class {
|
|
|
6507
6642
|
this.tinaSchema = await createSchema({ schema });
|
|
6508
6643
|
return this.tinaSchema;
|
|
6509
6644
|
};
|
|
6645
|
+
this.getCollectionReferences = async (level) => {
|
|
6646
|
+
if (this.collectionReferences) {
|
|
6647
|
+
return this.collectionReferences;
|
|
6648
|
+
}
|
|
6649
|
+
const result = {};
|
|
6650
|
+
const schema = await this.getSchema(level || this.contentLevel);
|
|
6651
|
+
const collections = schema.getCollections();
|
|
6652
|
+
for (const collection of collections) {
|
|
6653
|
+
const collectionReferences = this.tinaSchema.findReferencesFromCollection(
|
|
6654
|
+
collection.name
|
|
6655
|
+
);
|
|
6656
|
+
result[collection.name] = collectionReferences;
|
|
6657
|
+
}
|
|
6658
|
+
this.collectionReferences = result;
|
|
6659
|
+
return result;
|
|
6660
|
+
};
|
|
6510
6661
|
this.getIndexDefinitions = async (level) => {
|
|
6511
6662
|
if (!this.collectionIndexDefinitions) {
|
|
6512
6663
|
await new Promise(async (resolve2, reject) => {
|
|
@@ -6516,11 +6667,53 @@ var Database = class {
|
|
|
6516
6667
|
const collections = schema.getCollections();
|
|
6517
6668
|
for (const collection of collections) {
|
|
6518
6669
|
const indexDefinitions = {
|
|
6519
|
-
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6670
|
+
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
|
|
6520
6671
|
// provide a default sort key which is the file sort
|
|
6672
|
+
// pseudo-index for the collection's references
|
|
6673
|
+
[REFS_COLLECTIONS_SORT_KEY]: {
|
|
6674
|
+
fields: [
|
|
6675
|
+
{
|
|
6676
|
+
name: REFS_REFERENCE_FIELD,
|
|
6677
|
+
type: "string",
|
|
6678
|
+
list: false
|
|
6679
|
+
},
|
|
6680
|
+
{
|
|
6681
|
+
name: REFS_PATH_FIELD,
|
|
6682
|
+
type: "string",
|
|
6683
|
+
list: false
|
|
6684
|
+
}
|
|
6685
|
+
]
|
|
6686
|
+
}
|
|
6521
6687
|
};
|
|
6522
|
-
|
|
6523
|
-
|
|
6688
|
+
let fields = [];
|
|
6689
|
+
if (collection.templates) {
|
|
6690
|
+
const templateFieldMap = {};
|
|
6691
|
+
const conflictedFields = /* @__PURE__ */ new Set();
|
|
6692
|
+
for (const template of collection.templates) {
|
|
6693
|
+
for (const field of template.fields) {
|
|
6694
|
+
if (!templateFieldMap[field.name]) {
|
|
6695
|
+
templateFieldMap[field.name] = field;
|
|
6696
|
+
} else {
|
|
6697
|
+
if (templateFieldMap[field.name].type !== field.type) {
|
|
6698
|
+
console.warn(
|
|
6699
|
+
`Field ${field.name} has conflicting types in templates - skipping index`
|
|
6700
|
+
);
|
|
6701
|
+
conflictedFields.add(field.name);
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
}
|
|
6706
|
+
for (const conflictedField in conflictedFields) {
|
|
6707
|
+
delete templateFieldMap[conflictedField];
|
|
6708
|
+
}
|
|
6709
|
+
for (const field of Object.values(templateFieldMap)) {
|
|
6710
|
+
fields.push(field);
|
|
6711
|
+
}
|
|
6712
|
+
} else if (collection.fields) {
|
|
6713
|
+
fields = collection.fields;
|
|
6714
|
+
}
|
|
6715
|
+
if (fields) {
|
|
6716
|
+
for (const field of fields) {
|
|
6524
6717
|
if (field.indexed !== void 0 && field.indexed === false || field.type === "object") {
|
|
6525
6718
|
continue;
|
|
6526
6719
|
}
|
|
@@ -6668,29 +6861,35 @@ var Database = class {
|
|
|
6668
6861
|
}
|
|
6669
6862
|
startKey = startKey || key || "";
|
|
6670
6863
|
endKey = key || "";
|
|
6671
|
-
edges = [...edges, { cursor: key, path: filepath }];
|
|
6864
|
+
edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
|
|
6672
6865
|
}
|
|
6673
6866
|
return {
|
|
6674
|
-
edges: await sequential(
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6867
|
+
edges: await sequential(
|
|
6868
|
+
edges,
|
|
6869
|
+
async ({
|
|
6870
|
+
cursor,
|
|
6871
|
+
path: path7,
|
|
6872
|
+
value
|
|
6873
|
+
}) => {
|
|
6874
|
+
try {
|
|
6875
|
+
const node = await hydrator(path7, value);
|
|
6876
|
+
return {
|
|
6877
|
+
node,
|
|
6878
|
+
cursor: btoa(cursor)
|
|
6879
|
+
};
|
|
6880
|
+
} catch (error) {
|
|
6881
|
+
console.log(error);
|
|
6882
|
+
if (error instanceof Error && (!path7.includes(".tina/__generated__/_graphql.json") || !path7.includes("tina/__generated__/_graphql.json"))) {
|
|
6883
|
+
throw new TinaQueryError({
|
|
6884
|
+
originalError: error,
|
|
6885
|
+
file: path7,
|
|
6886
|
+
collection: collection.name
|
|
6887
|
+
});
|
|
6888
|
+
}
|
|
6889
|
+
throw error;
|
|
6690
6890
|
}
|
|
6691
|
-
throw error;
|
|
6692
6891
|
}
|
|
6693
|
-
|
|
6892
|
+
),
|
|
6694
6893
|
pageInfo: {
|
|
6695
6894
|
hasPreviousPage,
|
|
6696
6895
|
hasNextPage,
|
|
@@ -6814,13 +7013,14 @@ var Database = class {
|
|
|
6814
7013
|
documentPaths,
|
|
6815
7014
|
async (collection, documentPaths2) => {
|
|
6816
7015
|
if (collection && !collection.isDetached) {
|
|
6817
|
-
await _indexContent(
|
|
6818
|
-
this,
|
|
6819
|
-
this.contentLevel,
|
|
6820
|
-
documentPaths2,
|
|
7016
|
+
await _indexContent({
|
|
7017
|
+
database: this,
|
|
7018
|
+
level: this.contentLevel,
|
|
7019
|
+
documentPaths: documentPaths2,
|
|
6821
7020
|
enqueueOps,
|
|
6822
|
-
collection
|
|
6823
|
-
|
|
7021
|
+
collection,
|
|
7022
|
+
isPartialReindex: true
|
|
7023
|
+
});
|
|
6824
7024
|
}
|
|
6825
7025
|
}
|
|
6826
7026
|
);
|
|
@@ -6836,6 +7036,7 @@ var Database = class {
|
|
|
6836
7036
|
throw new Error(`No collection found for path: ${filepath}`);
|
|
6837
7037
|
}
|
|
6838
7038
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
7039
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6839
7040
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6840
7041
|
let level = this.contentLevel;
|
|
6841
7042
|
if (collection?.isDetached) {
|
|
@@ -6854,6 +7055,14 @@ var Database = class {
|
|
|
6854
7055
|
collection.path || ""
|
|
6855
7056
|
);
|
|
6856
7057
|
await this.contentLevel.batch([
|
|
7058
|
+
...makeRefOpsForDocument(
|
|
7059
|
+
normalizedPath,
|
|
7060
|
+
collection.name,
|
|
7061
|
+
collectionReferences,
|
|
7062
|
+
item,
|
|
7063
|
+
"del",
|
|
7064
|
+
level
|
|
7065
|
+
),
|
|
6857
7066
|
...makeIndexOpsForDocument(
|
|
6858
7067
|
normalizedPath,
|
|
6859
7068
|
collection.name,
|
|
@@ -6918,20 +7127,26 @@ var Database = class {
|
|
|
6918
7127
|
);
|
|
6919
7128
|
const doc = await level2.keys({ limit: 1 }).next();
|
|
6920
7129
|
if (!doc) {
|
|
6921
|
-
await _indexContent(
|
|
6922
|
-
this,
|
|
6923
|
-
level2,
|
|
6924
|
-
contentPaths,
|
|
7130
|
+
await _indexContent({
|
|
7131
|
+
database: this,
|
|
7132
|
+
level: level2,
|
|
7133
|
+
documentPaths: contentPaths,
|
|
6925
7134
|
enqueueOps,
|
|
6926
7135
|
collection,
|
|
6927
|
-
userFields.map((field) => [
|
|
7136
|
+
passwordFields: userFields.map((field) => [
|
|
6928
7137
|
...field.path,
|
|
6929
7138
|
field.passwordFieldName
|
|
6930
7139
|
])
|
|
6931
|
-
);
|
|
7140
|
+
});
|
|
6932
7141
|
}
|
|
6933
7142
|
} else {
|
|
6934
|
-
await _indexContent(
|
|
7143
|
+
await _indexContent({
|
|
7144
|
+
database: this,
|
|
7145
|
+
level,
|
|
7146
|
+
documentPaths: contentPaths,
|
|
7147
|
+
enqueueOps,
|
|
7148
|
+
collection
|
|
7149
|
+
});
|
|
6935
7150
|
}
|
|
6936
7151
|
}
|
|
6937
7152
|
);
|
|
@@ -7070,7 +7285,15 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
|
|
|
7070
7285
|
)
|
|
7071
7286
|
);
|
|
7072
7287
|
var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${collection?.format || "md"}`);
|
|
7073
|
-
var _indexContent = async (
|
|
7288
|
+
var _indexContent = async ({
|
|
7289
|
+
database,
|
|
7290
|
+
level,
|
|
7291
|
+
documentPaths,
|
|
7292
|
+
enqueueOps,
|
|
7293
|
+
collection,
|
|
7294
|
+
passwordFields,
|
|
7295
|
+
isPartialReindex
|
|
7296
|
+
}) => {
|
|
7074
7297
|
let collectionIndexDefinitions;
|
|
7075
7298
|
let collectionPath;
|
|
7076
7299
|
if (collection) {
|
|
@@ -7081,6 +7304,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7081
7304
|
}
|
|
7082
7305
|
collectionPath = collection.path;
|
|
7083
7306
|
}
|
|
7307
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7084
7308
|
const tinaSchema = await database.getSchema();
|
|
7085
7309
|
let templateInfo = null;
|
|
7086
7310
|
if (collection) {
|
|
@@ -7102,12 +7326,61 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7102
7326
|
await hashPasswordValues(aliasedData, passwordFields);
|
|
7103
7327
|
}
|
|
7104
7328
|
const normalizedPath = normalizePath(filepath);
|
|
7329
|
+
const rootSublevel = level.sublevel(
|
|
7330
|
+
CONTENT_ROOT_PREFIX,
|
|
7331
|
+
SUBLEVEL_OPTIONS
|
|
7332
|
+
);
|
|
7105
7333
|
const folderKey = folderTreeBuilder.update(
|
|
7106
7334
|
normalizedPath,
|
|
7107
7335
|
collectionPath || ""
|
|
7108
7336
|
);
|
|
7337
|
+
if (isPartialReindex) {
|
|
7338
|
+
const item = await rootSublevel.get(normalizedPath);
|
|
7339
|
+
if (item) {
|
|
7340
|
+
await database.contentLevel.batch([
|
|
7341
|
+
...makeRefOpsForDocument(
|
|
7342
|
+
normalizedPath,
|
|
7343
|
+
collection?.name,
|
|
7344
|
+
collectionReferences,
|
|
7345
|
+
item,
|
|
7346
|
+
"del",
|
|
7347
|
+
level
|
|
7348
|
+
),
|
|
7349
|
+
...makeIndexOpsForDocument(
|
|
7350
|
+
normalizedPath,
|
|
7351
|
+
collection.name,
|
|
7352
|
+
collectionIndexDefinitions,
|
|
7353
|
+
item,
|
|
7354
|
+
"del",
|
|
7355
|
+
level
|
|
7356
|
+
),
|
|
7357
|
+
// folder indices
|
|
7358
|
+
...makeIndexOpsForDocument(
|
|
7359
|
+
normalizedPath,
|
|
7360
|
+
`${collection.name}_${folderKey}`,
|
|
7361
|
+
collectionIndexDefinitions,
|
|
7362
|
+
item,
|
|
7363
|
+
"del",
|
|
7364
|
+
level
|
|
7365
|
+
),
|
|
7366
|
+
{
|
|
7367
|
+
type: "del",
|
|
7368
|
+
key: normalizedPath,
|
|
7369
|
+
sublevel: rootSublevel
|
|
7370
|
+
}
|
|
7371
|
+
]);
|
|
7372
|
+
}
|
|
7373
|
+
}
|
|
7109
7374
|
if (!isGitKeep(filepath, collection)) {
|
|
7110
7375
|
await enqueueOps([
|
|
7376
|
+
...makeRefOpsForDocument(
|
|
7377
|
+
normalizedPath,
|
|
7378
|
+
collection?.name,
|
|
7379
|
+
collectionReferences,
|
|
7380
|
+
aliasedData,
|
|
7381
|
+
"put",
|
|
7382
|
+
level
|
|
7383
|
+
),
|
|
7111
7384
|
...makeIndexOpsForDocument(
|
|
7112
7385
|
normalizedPath,
|
|
7113
7386
|
collection?.name,
|
|
@@ -7140,8 +7413,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7140
7413
|
throw new TinaFetchError(`Unable to seed ${filepath}`, {
|
|
7141
7414
|
originalError: error,
|
|
7142
7415
|
file: filepath,
|
|
7143
|
-
collection: collection?.name
|
|
7144
|
-
stack: error.stack
|
|
7416
|
+
collection: collection?.name
|
|
7145
7417
|
});
|
|
7146
7418
|
}
|
|
7147
7419
|
});
|
|
@@ -7171,6 +7443,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7171
7443
|
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
7172
7444
|
}
|
|
7173
7445
|
}
|
|
7446
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7174
7447
|
const tinaSchema = await database.getSchema();
|
|
7175
7448
|
let templateInfo = null;
|
|
7176
7449
|
if (collection) {
|
|
@@ -7194,6 +7467,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7194
7467
|
item
|
|
7195
7468
|
) : item;
|
|
7196
7469
|
await enqueueOps([
|
|
7470
|
+
...makeRefOpsForDocument(
|
|
7471
|
+
itemKey,
|
|
7472
|
+
collection?.name,
|
|
7473
|
+
collectionReferences,
|
|
7474
|
+
aliasedData,
|
|
7475
|
+
"del",
|
|
7476
|
+
database.contentLevel
|
|
7477
|
+
),
|
|
7197
7478
|
...makeIndexOpsForDocument(
|
|
7198
7479
|
itemKey,
|
|
7199
7480
|
collection.name,
|
|
@@ -7323,8 +7604,8 @@ import path6 from "path";
|
|
|
7323
7604
|
import normalize from "normalize-path";
|
|
7324
7605
|
var FilesystemBridge = class {
|
|
7325
7606
|
constructor(rootPath, outputPath) {
|
|
7326
|
-
this.rootPath = rootPath
|
|
7327
|
-
this.outputPath = outputPath
|
|
7607
|
+
this.rootPath = path6.resolve(rootPath);
|
|
7608
|
+
this.outputPath = outputPath ? path6.resolve(outputPath) : this.rootPath;
|
|
7328
7609
|
}
|
|
7329
7610
|
async glob(pattern, extension) {
|
|
7330
7611
|
const basePath = path6.join(this.outputPath, ...pattern.split("/"));
|
|
@@ -7336,19 +7617,19 @@ var FilesystemBridge = class {
|
|
|
7336
7617
|
}
|
|
7337
7618
|
);
|
|
7338
7619
|
const posixRootPath = normalize(this.outputPath);
|
|
7339
|
-
return items.map(
|
|
7340
|
-
|
|
7341
|
-
|
|
7620
|
+
return items.map(
|
|
7621
|
+
(item) => item.substring(posixRootPath.length).replace(/^\/|\/$/g, "")
|
|
7622
|
+
);
|
|
7342
7623
|
}
|
|
7343
7624
|
async delete(filepath) {
|
|
7344
7625
|
await fs2.remove(path6.join(this.outputPath, filepath));
|
|
7345
7626
|
}
|
|
7346
7627
|
async get(filepath) {
|
|
7347
|
-
return fs2.
|
|
7628
|
+
return (await fs2.readFile(path6.join(this.outputPath, filepath))).toString();
|
|
7348
7629
|
}
|
|
7349
7630
|
async put(filepath, data, basePathOverride) {
|
|
7350
7631
|
const basePath = basePathOverride || this.outputPath;
|
|
7351
|
-
await fs2.
|
|
7632
|
+
await fs2.outputFile(path6.join(basePath, filepath), data);
|
|
7352
7633
|
}
|
|
7353
7634
|
};
|
|
7354
7635
|
var AuditFileSystemBridge = class extends FilesystemBridge {
|