@tinacms/graphql 0.0.0-d7c5ec1-20250219020924 → 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/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 +947 -687
- package/dist/index.mjs +849 -567
- 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 +5 -7
- package/readme.md +0 -194
package/dist/index.mjs
CHANGED
|
@@ -1847,7 +1847,7 @@ var Builder = class {
|
|
|
1847
1847
|
* ```
|
|
1848
1848
|
*
|
|
1849
1849
|
* @public
|
|
1850
|
-
* @param collection a
|
|
1850
|
+
* @param collection a TinaCloud collection
|
|
1851
1851
|
*/
|
|
1852
1852
|
this.collectionFragment = async (collection) => {
|
|
1853
1853
|
const name = NAMER.dataTypeName(collection.namespace);
|
|
@@ -2711,7 +2711,7 @@ var Builder = class {
|
|
|
2711
2711
|
this._buildDataField = async (field) => {
|
|
2712
2712
|
const listWarningMsg = `
|
|
2713
2713
|
WARNING: The user interface for ${field.type} does not support \`list: true\`
|
|
2714
|
-
Visit https://tina.io/docs/
|
|
2714
|
+
Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
|
|
2715
2715
|
|
|
2716
2716
|
`;
|
|
2717
2717
|
switch (field.type) {
|
|
@@ -3019,7 +3019,7 @@ var validateField = async (field) => {
|
|
|
3019
3019
|
// package.json
|
|
3020
3020
|
var package_default = {
|
|
3021
3021
|
name: "@tinacms/graphql",
|
|
3022
|
-
version: "1.
|
|
3022
|
+
version: "1.6.1",
|
|
3023
3023
|
main: "dist/index.js",
|
|
3024
3024
|
module: "dist/index.mjs",
|
|
3025
3025
|
typings: "dist/index.d.ts",
|
|
@@ -3045,33 +3045,32 @@ var package_default = {
|
|
|
3045
3045
|
types: "pnpm tsc",
|
|
3046
3046
|
build: "tinacms-scripts build",
|
|
3047
3047
|
docs: "pnpm typedoc",
|
|
3048
|
-
serve: "pnpm nodemon dist/server.js",
|
|
3049
3048
|
test: "vitest run",
|
|
3050
3049
|
"test-watch": "vitest"
|
|
3051
3050
|
},
|
|
3052
3051
|
dependencies: {
|
|
3053
|
-
"@iarna/toml": "
|
|
3052
|
+
"@iarna/toml": "catalog:",
|
|
3054
3053
|
"@tinacms/mdx": "workspace:*",
|
|
3055
3054
|
"@tinacms/schema-tools": "workspace:*",
|
|
3056
|
-
"abstract-level": "
|
|
3055
|
+
"abstract-level": "catalog:",
|
|
3057
3056
|
"date-fns": "^2.30.0",
|
|
3058
|
-
"fast-glob": "
|
|
3059
|
-
"fs-extra": "
|
|
3060
|
-
"glob-parent": "
|
|
3057
|
+
"fast-glob": "catalog:",
|
|
3058
|
+
"fs-extra": "catalog:",
|
|
3059
|
+
"glob-parent": "catalog:",
|
|
3061
3060
|
graphql: "15.8.0",
|
|
3062
|
-
"gray-matter": "
|
|
3063
|
-
"isomorphic-git": "
|
|
3064
|
-
"js-sha1": "
|
|
3061
|
+
"gray-matter": "catalog:",
|
|
3062
|
+
"isomorphic-git": "catalog:",
|
|
3063
|
+
"js-sha1": "catalog:",
|
|
3065
3064
|
"js-yaml": "^3.14.1",
|
|
3066
|
-
"jsonpath-plus": "
|
|
3067
|
-
"lodash.clonedeep": "
|
|
3068
|
-
"lodash.set": "
|
|
3069
|
-
"lodash.uniqby": "
|
|
3070
|
-
"many-level": "
|
|
3071
|
-
micromatch: "
|
|
3072
|
-
"normalize-path": "
|
|
3073
|
-
"readable-stream": "
|
|
3074
|
-
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:",
|
|
3075
3074
|
yup: "^0.32.11"
|
|
3076
3075
|
},
|
|
3077
3076
|
publishConfig: {
|
|
@@ -3086,25 +3085,24 @@ var package_default = {
|
|
|
3086
3085
|
"@tinacms/scripts": "workspace:*",
|
|
3087
3086
|
"@types/cors": "^2.8.17",
|
|
3088
3087
|
"@types/estree": "^0.0.50",
|
|
3089
|
-
"@types/express": "
|
|
3088
|
+
"@types/express": "catalog:",
|
|
3090
3089
|
"@types/fs-extra": "^9.0.13",
|
|
3091
3090
|
"@types/js-yaml": "^3.12.10",
|
|
3092
|
-
"@types/lodash.camelcase": "
|
|
3093
|
-
"@types/lodash.upperfirst": "
|
|
3094
|
-
"@types/lru-cache": "
|
|
3095
|
-
"@types/mdast": "
|
|
3096
|
-
"@types/micromatch": "
|
|
3091
|
+
"@types/lodash.camelcase": "catalog:",
|
|
3092
|
+
"@types/lodash.upperfirst": "catalog:",
|
|
3093
|
+
"@types/lru-cache": "catalog:",
|
|
3094
|
+
"@types/mdast": "catalog:",
|
|
3095
|
+
"@types/micromatch": "catalog:",
|
|
3097
3096
|
"@types/node": "^22.13.1",
|
|
3098
|
-
"@types/normalize-path": "
|
|
3099
|
-
"@types/ws": "
|
|
3097
|
+
"@types/normalize-path": "catalog:",
|
|
3098
|
+
"@types/ws": "catalog:",
|
|
3100
3099
|
"@types/yup": "^0.29.14",
|
|
3101
3100
|
"jest-file-snapshot": "^0.5.0",
|
|
3102
|
-
"memory-level": "
|
|
3103
|
-
nodemon: "3.1.4",
|
|
3101
|
+
"memory-level": "catalog:",
|
|
3104
3102
|
typescript: "^5.7.3",
|
|
3105
3103
|
vite: "^4.5.9",
|
|
3106
3104
|
vitest: "^0.32.4",
|
|
3107
|
-
zod: "
|
|
3105
|
+
zod: "catalog:"
|
|
3108
3106
|
}
|
|
3109
3107
|
};
|
|
3110
3108
|
|
|
@@ -3260,7 +3258,9 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3260
3258
|
await builder.buildCreateCollectionFolderMutation()
|
|
3261
3259
|
);
|
|
3262
3260
|
await sequential(collections, async (collection) => {
|
|
3263
|
-
queryTypeDefinitionFields.push(
|
|
3261
|
+
queryTypeDefinitionFields.push(
|
|
3262
|
+
await builder.collectionDocument(collection)
|
|
3263
|
+
);
|
|
3264
3264
|
if (collection.isAuthCollection) {
|
|
3265
3265
|
queryTypeDefinitionFields.push(
|
|
3266
3266
|
await builder.authenticationCollectionDocument(collection)
|
|
@@ -3310,249 +3310,10 @@ import { graphql, buildASTSchema, getNamedType, GraphQLError as GraphQLError4 }
|
|
|
3310
3310
|
// src/resolver/index.ts
|
|
3311
3311
|
import path3 from "path";
|
|
3312
3312
|
import isValid from "date-fns/isValid/index.js";
|
|
3313
|
-
|
|
3314
|
-
// src/mdx/index.ts
|
|
3315
|
-
import { parseMDX, stringifyMDX } from "@tinacms/mdx";
|
|
3316
|
-
|
|
3317
|
-
// src/resolver/index.ts
|
|
3318
3313
|
import { JSONPath as JSONPath2 } from "jsonpath-plus";
|
|
3319
3314
|
|
|
3320
|
-
// src/
|
|
3321
|
-
|
|
3322
|
-
constructor(message, extensions) {
|
|
3323
|
-
super(message);
|
|
3324
|
-
if (!this.name) {
|
|
3325
|
-
Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
|
|
3326
|
-
}
|
|
3327
|
-
this.extensions = { ...extensions };
|
|
3328
|
-
}
|
|
3329
|
-
};
|
|
3330
|
-
var TinaFetchError = class extends Error {
|
|
3331
|
-
constructor(message, args) {
|
|
3332
|
-
super(message);
|
|
3333
|
-
this.name = "TinaFetchError";
|
|
3334
|
-
this.collection = args.collection;
|
|
3335
|
-
this.stack = args.stack;
|
|
3336
|
-
this.file = args.file;
|
|
3337
|
-
this.originalError = args.originalError;
|
|
3338
|
-
}
|
|
3339
|
-
};
|
|
3340
|
-
var TinaQueryError = class extends TinaFetchError {
|
|
3341
|
-
constructor(args) {
|
|
3342
|
-
super(
|
|
3343
|
-
`Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3344
|
-
args
|
|
3345
|
-
);
|
|
3346
|
-
}
|
|
3347
|
-
};
|
|
3348
|
-
var TinaParseDocumentError = class extends TinaFetchError {
|
|
3349
|
-
constructor(args) {
|
|
3350
|
-
super(
|
|
3351
|
-
`Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3352
|
-
args
|
|
3353
|
-
);
|
|
3354
|
-
}
|
|
3355
|
-
toString() {
|
|
3356
|
-
return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
|
|
3357
|
-
}
|
|
3358
|
-
};
|
|
3359
|
-
var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
|
|
3360
|
-
var handleFetchErrorError = (e, verbose) => {
|
|
3361
|
-
if (e instanceof Error) {
|
|
3362
|
-
if (e instanceof TinaFetchError) {
|
|
3363
|
-
if (verbose) {
|
|
3364
|
-
console.log(e.toString());
|
|
3365
|
-
console.log(e);
|
|
3366
|
-
console.log(e.stack);
|
|
3367
|
-
}
|
|
3368
|
-
}
|
|
3369
|
-
} else {
|
|
3370
|
-
console.error(e);
|
|
3371
|
-
}
|
|
3372
|
-
throw e;
|
|
3373
|
-
};
|
|
3374
|
-
|
|
3375
|
-
// src/resolver/filter-utils.ts
|
|
3376
|
-
var resolveReferences = async (filter, fields, resolver) => {
|
|
3377
|
-
for (const fieldKey of Object.keys(filter)) {
|
|
3378
|
-
const fieldDefinition = fields.find(
|
|
3379
|
-
(f) => f.name === fieldKey
|
|
3380
|
-
);
|
|
3381
|
-
if (fieldDefinition) {
|
|
3382
|
-
if (fieldDefinition.type === "reference") {
|
|
3383
|
-
const { edges, values } = await resolver(filter, fieldDefinition);
|
|
3384
|
-
if (edges.length === 1) {
|
|
3385
|
-
filter[fieldKey] = {
|
|
3386
|
-
eq: values[0]
|
|
3387
|
-
};
|
|
3388
|
-
} else if (edges.length > 1) {
|
|
3389
|
-
filter[fieldKey] = {
|
|
3390
|
-
in: values
|
|
3391
|
-
};
|
|
3392
|
-
} else {
|
|
3393
|
-
filter[fieldKey] = {
|
|
3394
|
-
eq: "___null___"
|
|
3395
|
-
};
|
|
3396
|
-
}
|
|
3397
|
-
} else if (fieldDefinition.type === "object") {
|
|
3398
|
-
if (fieldDefinition.templates) {
|
|
3399
|
-
for (const templateName of Object.keys(filter[fieldKey])) {
|
|
3400
|
-
const template = fieldDefinition.templates.find(
|
|
3401
|
-
(template2) => !(typeof template2 === "string") && template2.name === templateName
|
|
3402
|
-
);
|
|
3403
|
-
if (template) {
|
|
3404
|
-
await resolveReferences(
|
|
3405
|
-
filter[fieldKey][templateName],
|
|
3406
|
-
template.fields,
|
|
3407
|
-
resolver
|
|
3408
|
-
);
|
|
3409
|
-
} else {
|
|
3410
|
-
throw new Error(`Template ${templateName} not found`);
|
|
3411
|
-
}
|
|
3412
|
-
}
|
|
3413
|
-
} else {
|
|
3414
|
-
await resolveReferences(
|
|
3415
|
-
filter[fieldKey],
|
|
3416
|
-
fieldDefinition.fields,
|
|
3417
|
-
resolver
|
|
3418
|
-
);
|
|
3419
|
-
}
|
|
3420
|
-
}
|
|
3421
|
-
} else {
|
|
3422
|
-
throw new Error(`Unable to find field ${fieldKey}`);
|
|
3423
|
-
}
|
|
3424
|
-
}
|
|
3425
|
-
};
|
|
3426
|
-
var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
|
|
3427
|
-
for (const childFieldName of Object.keys(filterNode)) {
|
|
3428
|
-
const childField = fields.find((field) => field.name === childFieldName);
|
|
3429
|
-
if (!childField) {
|
|
3430
|
-
throw new Error(`Unable to find type for field ${childFieldName}`);
|
|
3431
|
-
}
|
|
3432
|
-
collectConditionsForField(
|
|
3433
|
-
childFieldName,
|
|
3434
|
-
childField,
|
|
3435
|
-
filterNode[childFieldName],
|
|
3436
|
-
pathExpression,
|
|
3437
|
-
collectCondition
|
|
3438
|
-
);
|
|
3439
|
-
}
|
|
3440
|
-
};
|
|
3441
|
-
var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3442
|
-
if (field.list && field.templates) {
|
|
3443
|
-
for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
|
|
3444
|
-
const template = field.templates.find(
|
|
3445
|
-
(template2) => !(typeof template2 === "string") && template2.name === filterKey
|
|
3446
|
-
);
|
|
3447
|
-
const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
|
|
3448
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
|
|
3449
|
-
collectConditionsForChildFields(
|
|
3450
|
-
childFilterNode,
|
|
3451
|
-
template.fields,
|
|
3452
|
-
filterPath,
|
|
3453
|
-
collectCondition
|
|
3454
|
-
);
|
|
3455
|
-
}
|
|
3456
|
-
} else {
|
|
3457
|
-
const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
|
|
3458
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
|
|
3459
|
-
collectConditionsForChildFields(
|
|
3460
|
-
filterNode,
|
|
3461
|
-
field.fields,
|
|
3462
|
-
filterPath,
|
|
3463
|
-
collectCondition
|
|
3464
|
-
);
|
|
3465
|
-
}
|
|
3466
|
-
};
|
|
3467
|
-
var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3468
|
-
if (field.type === "object") {
|
|
3469
|
-
collectConditionsForObjectField(
|
|
3470
|
-
fieldName,
|
|
3471
|
-
field,
|
|
3472
|
-
filterNode,
|
|
3473
|
-
pathExpression,
|
|
3474
|
-
collectCondition
|
|
3475
|
-
);
|
|
3476
|
-
} else {
|
|
3477
|
-
collectCondition({
|
|
3478
|
-
filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
|
|
3479
|
-
filterExpression: {
|
|
3480
|
-
_type: field.type,
|
|
3481
|
-
_list: !!field.list,
|
|
3482
|
-
...filterNode
|
|
3483
|
-
}
|
|
3484
|
-
});
|
|
3485
|
-
}
|
|
3486
|
-
};
|
|
3487
|
-
|
|
3488
|
-
// src/resolver/media-utils.ts
|
|
3489
|
-
var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3490
|
-
if (config && value) {
|
|
3491
|
-
if (config.useRelativeMedia === true) {
|
|
3492
|
-
return value;
|
|
3493
|
-
}
|
|
3494
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3495
|
-
const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
|
|
3496
|
-
if (typeof value === "string" && value.includes(assetsURL)) {
|
|
3497
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3498
|
-
schema.config.media.tina.mediaRoot
|
|
3499
|
-
);
|
|
3500
|
-
const strippedURL = value.replace(assetsURL, "");
|
|
3501
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3502
|
-
}
|
|
3503
|
-
if (Array.isArray(value)) {
|
|
3504
|
-
return value.map((v) => {
|
|
3505
|
-
if (!v || typeof v !== "string") return v;
|
|
3506
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3507
|
-
schema.config.media.tina.mediaRoot
|
|
3508
|
-
);
|
|
3509
|
-
const strippedURL = v.replace(assetsURL, "");
|
|
3510
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3511
|
-
});
|
|
3512
|
-
}
|
|
3513
|
-
return value;
|
|
3514
|
-
}
|
|
3515
|
-
return value;
|
|
3516
|
-
} else {
|
|
3517
|
-
return value;
|
|
3518
|
-
}
|
|
3519
|
-
};
|
|
3520
|
-
var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3521
|
-
if (config && value) {
|
|
3522
|
-
if (config.useRelativeMedia === true) {
|
|
3523
|
-
return value;
|
|
3524
|
-
}
|
|
3525
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3526
|
-
const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
|
|
3527
|
-
if (typeof value === "string") {
|
|
3528
|
-
const strippedValue = value.replace(cleanMediaRoot, "");
|
|
3529
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3530
|
-
}
|
|
3531
|
-
if (Array.isArray(value)) {
|
|
3532
|
-
return value.map((v) => {
|
|
3533
|
-
if (!v || typeof v !== "string") return v;
|
|
3534
|
-
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
3535
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3536
|
-
});
|
|
3537
|
-
}
|
|
3538
|
-
}
|
|
3539
|
-
return value;
|
|
3540
|
-
} else {
|
|
3541
|
-
return value;
|
|
3542
|
-
}
|
|
3543
|
-
};
|
|
3544
|
-
var cleanUpSlashes = (path7) => {
|
|
3545
|
-
if (path7) {
|
|
3546
|
-
return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
|
|
3547
|
-
}
|
|
3548
|
-
return "";
|
|
3549
|
-
};
|
|
3550
|
-
var hasTinaMediaConfig = (schema) => {
|
|
3551
|
-
if (!schema.config?.media?.tina) return false;
|
|
3552
|
-
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
3553
|
-
return false;
|
|
3554
|
-
return true;
|
|
3555
|
-
};
|
|
3315
|
+
// src/mdx/index.ts
|
|
3316
|
+
import { parseMDX, serializeMDX } from "@tinacms/mdx";
|
|
3556
3317
|
|
|
3557
3318
|
// src/resolver/index.ts
|
|
3558
3319
|
import { GraphQLError as GraphQLError2 } from "graphql";
|
|
@@ -3575,7 +3336,9 @@ var LevelProxyHandler = {
|
|
|
3575
3336
|
throw new Error(`The property, ${property.toString()}, doesn't exist`);
|
|
3576
3337
|
}
|
|
3577
3338
|
if (typeof target[property] !== "function") {
|
|
3578
|
-
throw new Error(
|
|
3339
|
+
throw new Error(
|
|
3340
|
+
`The property, ${property.toString()}, is not a function`
|
|
3341
|
+
);
|
|
3579
3342
|
}
|
|
3580
3343
|
if (property === "get") {
|
|
3581
3344
|
return async (...args) => {
|
|
@@ -3613,13 +3376,13 @@ import path2 from "path";
|
|
|
3613
3376
|
|
|
3614
3377
|
// src/database/util.ts
|
|
3615
3378
|
import toml from "@iarna/toml";
|
|
3616
|
-
import yaml from "js-yaml";
|
|
3617
|
-
import matter from "gray-matter";
|
|
3618
3379
|
import {
|
|
3619
3380
|
normalizePath
|
|
3620
3381
|
} from "@tinacms/schema-tools";
|
|
3621
|
-
import
|
|
3382
|
+
import matter from "gray-matter";
|
|
3383
|
+
import yaml from "js-yaml";
|
|
3622
3384
|
import path from "path";
|
|
3385
|
+
import micromatch from "micromatch";
|
|
3623
3386
|
|
|
3624
3387
|
// src/database/alias-utils.ts
|
|
3625
3388
|
var replaceBlockAliases = (template, item) => {
|
|
@@ -3960,6 +3723,9 @@ var loadAndParseWithAliases = async (bridge, filepath, collection, templateInfo)
|
|
|
3960
3723
|
|
|
3961
3724
|
// src/database/datalayer.ts
|
|
3962
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__";
|
|
3963
3729
|
var DEFAULT_NUMERIC_LPAD = 4;
|
|
3964
3730
|
var applyPadding = (input, pad) => {
|
|
3965
3731
|
if (pad) {
|
|
@@ -4533,12 +4299,63 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4533
4299
|
}
|
|
4534
4300
|
return result;
|
|
4535
4301
|
};
|
|
4536
|
-
var
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
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
|
+
};
|
|
4353
|
+
var makeStringEscaper = (regex, replacement) => {
|
|
4354
|
+
return (input) => {
|
|
4355
|
+
if (Array.isArray(input)) {
|
|
4356
|
+
return input.map(
|
|
4357
|
+
(val) => val.replace(regex, replacement)
|
|
4358
|
+
);
|
|
4542
4359
|
} else {
|
|
4543
4360
|
if (typeof input === "string") {
|
|
4544
4361
|
return input.replace(regex, replacement);
|
|
@@ -4548,10 +4365,246 @@ var makeStringEscaper = (regex, replacement) => {
|
|
|
4548
4365
|
}
|
|
4549
4366
|
};
|
|
4550
4367
|
};
|
|
4551
|
-
var stringEscaper = makeStringEscaper(
|
|
4552
|
-
new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
|
|
4553
|
-
encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
|
|
4554
|
-
);
|
|
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;
|
|
4607
|
+
};
|
|
4555
4608
|
|
|
4556
4609
|
// src/resolver/index.ts
|
|
4557
4610
|
var createResolver = (args) => {
|
|
@@ -4713,8 +4766,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4713
4766
|
originalError: e,
|
|
4714
4767
|
collection: collection.name,
|
|
4715
4768
|
includeAuditMessage: !isAudit,
|
|
4716
|
-
file: relativePath
|
|
4717
|
-
stack: e.stack
|
|
4769
|
+
file: relativePath
|
|
4718
4770
|
});
|
|
4719
4771
|
}
|
|
4720
4772
|
const titleField = template.fields.find((x) => {
|
|
@@ -4753,24 +4805,33 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4753
4805
|
throw e;
|
|
4754
4806
|
}
|
|
4755
4807
|
};
|
|
4756
|
-
var updateObjectWithJsonPath = (obj, path7, newValue) => {
|
|
4808
|
+
var updateObjectWithJsonPath = (obj, path7, oldValue, newValue) => {
|
|
4809
|
+
let updated = false;
|
|
4757
4810
|
if (!path7.includes(".") && !path7.includes("[")) {
|
|
4758
|
-
if (path7 in obj) {
|
|
4811
|
+
if (path7 in obj && obj[path7] === oldValue) {
|
|
4759
4812
|
obj[path7] = newValue;
|
|
4813
|
+
updated = true;
|
|
4760
4814
|
}
|
|
4761
|
-
return obj;
|
|
4762
|
-
}
|
|
4763
|
-
const parentPath = path7.replace(/\.[
|
|
4764
|
-
const keyToUpdate = path7.match(/[
|
|
4765
|
-
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
|
+
});
|
|
4766
4824
|
if (parents.length > 0) {
|
|
4767
4825
|
parents.forEach((parent) => {
|
|
4768
4826
|
if (parent && typeof parent === "object" && keyToUpdate in parent) {
|
|
4769
|
-
parent[keyToUpdate]
|
|
4827
|
+
if (parent[keyToUpdate] === oldValue) {
|
|
4828
|
+
parent[keyToUpdate] = newValue;
|
|
4829
|
+
updated = true;
|
|
4830
|
+
}
|
|
4770
4831
|
}
|
|
4771
4832
|
});
|
|
4772
4833
|
}
|
|
4773
|
-
return obj;
|
|
4834
|
+
return { object: obj, updated };
|
|
4774
4835
|
};
|
|
4775
4836
|
var Resolver = class {
|
|
4776
4837
|
constructor(init) {
|
|
@@ -4787,7 +4848,9 @@ var Resolver = class {
|
|
|
4787
4848
|
};
|
|
4788
4849
|
this.getRaw = async (fullPath) => {
|
|
4789
4850
|
if (typeof fullPath !== "string") {
|
|
4790
|
-
throw new Error(
|
|
4851
|
+
throw new Error(
|
|
4852
|
+
`fullPath must be of type string for getDocument request`
|
|
4853
|
+
);
|
|
4791
4854
|
}
|
|
4792
4855
|
return this.database.get(fullPath);
|
|
4793
4856
|
};
|
|
@@ -4816,7 +4879,9 @@ var Resolver = class {
|
|
|
4816
4879
|
};
|
|
4817
4880
|
this.getDocument = async (fullPath, opts = {}) => {
|
|
4818
4881
|
if (typeof fullPath !== "string") {
|
|
4819
|
-
throw new Error(
|
|
4882
|
+
throw new Error(
|
|
4883
|
+
`fullPath must be of type string for getDocument request`
|
|
4884
|
+
);
|
|
4820
4885
|
}
|
|
4821
4886
|
const rawData = await this.getRaw(fullPath);
|
|
4822
4887
|
const hasReferences = opts?.checkReferences ? await this.hasReferences(fullPath, opts.collection) : void 0;
|
|
@@ -4831,7 +4896,9 @@ var Resolver = class {
|
|
|
4831
4896
|
};
|
|
4832
4897
|
this.deleteDocument = async (fullPath) => {
|
|
4833
4898
|
if (typeof fullPath !== "string") {
|
|
4834
|
-
throw new Error(
|
|
4899
|
+
throw new Error(
|
|
4900
|
+
`fullPath must be of type string for getDocument request`
|
|
4901
|
+
);
|
|
4835
4902
|
}
|
|
4836
4903
|
await this.database.delete(fullPath);
|
|
4837
4904
|
};
|
|
@@ -5035,7 +5102,11 @@ var Resolver = class {
|
|
|
5035
5102
|
collection,
|
|
5036
5103
|
doc?._rawData
|
|
5037
5104
|
);
|
|
5038
|
-
await this.database.put(
|
|
5105
|
+
await this.database.put(
|
|
5106
|
+
realPath,
|
|
5107
|
+
{ ...oldDoc, ...params },
|
|
5108
|
+
collection.name
|
|
5109
|
+
);
|
|
5039
5110
|
return this.getDocument(realPath);
|
|
5040
5111
|
};
|
|
5041
5112
|
/**
|
|
@@ -5148,17 +5219,35 @@ var Resolver = class {
|
|
|
5148
5219
|
await this.deleteDocument(realPath);
|
|
5149
5220
|
if (await this.hasReferences(realPath, collection)) {
|
|
5150
5221
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5151
|
-
for (const [collection2,
|
|
5152
|
-
for (const [
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
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(
|
|
5156
5230
|
refDoc,
|
|
5157
|
-
|
|
5231
|
+
path7,
|
|
5232
|
+
realPath,
|
|
5158
5233
|
null
|
|
5159
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
|
+
);
|
|
5160
5250
|
}
|
|
5161
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5162
5251
|
}
|
|
5163
5252
|
}
|
|
5164
5253
|
}
|
|
@@ -5184,23 +5273,43 @@ var Resolver = class {
|
|
|
5184
5273
|
await this.database.put(newRealPath, doc._rawData, collection.name);
|
|
5185
5274
|
await this.deleteDocument(realPath);
|
|
5186
5275
|
const collRefs = await this.findReferences(realPath, collection);
|
|
5187
|
-
for (const [collection2,
|
|
5188
|
-
for (const [
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
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,
|
|
5194
5287
|
newRealPath
|
|
5195
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
|
+
);
|
|
5196
5304
|
}
|
|
5197
|
-
await this.database.put(refPath, refDoc, collection2);
|
|
5198
5305
|
}
|
|
5199
5306
|
}
|
|
5200
5307
|
return this.getDocument(newRealPath);
|
|
5201
5308
|
}
|
|
5202
5309
|
if (alreadyExists === false) {
|
|
5203
|
-
throw new Error(
|
|
5310
|
+
throw new Error(
|
|
5311
|
+
`Unable to update document, ${realPath} does not exist`
|
|
5312
|
+
);
|
|
5204
5313
|
}
|
|
5205
5314
|
return this.updateResolveDocument({
|
|
5206
5315
|
collection,
|
|
@@ -5326,35 +5435,30 @@ var Resolver = class {
|
|
|
5326
5435
|
*/
|
|
5327
5436
|
this.hasReferences = async (id, c) => {
|
|
5328
5437
|
let count = 0;
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
(refId) => {
|
|
5350
|
-
count++;
|
|
5351
|
-
return refId;
|
|
5352
|
-
}
|
|
5353
|
-
);
|
|
5354
|
-
if (count) {
|
|
5355
|
-
return true;
|
|
5356
|
-
}
|
|
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;
|
|
5357
5458
|
}
|
|
5459
|
+
);
|
|
5460
|
+
if (count) {
|
|
5461
|
+
return true;
|
|
5358
5462
|
}
|
|
5359
5463
|
return false;
|
|
5360
5464
|
};
|
|
@@ -5362,46 +5466,41 @@ var Resolver = class {
|
|
|
5362
5466
|
* Finds references to a document
|
|
5363
5467
|
* @param id the id of the document to find references to
|
|
5364
5468
|
* @param c the collection to find references in
|
|
5365
|
-
* @returns
|
|
5469
|
+
* @returns a map of references to the document
|
|
5366
5470
|
*/
|
|
5367
5471
|
this.findReferences = async (id, c) => {
|
|
5368
5472
|
const references = {};
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
_list: false,
|
|
5382
|
-
eq: id
|
|
5383
|
-
}
|
|
5384
|
-
}
|
|
5385
|
-
]
|
|
5386
|
-
}),
|
|
5387
|
-
sort: ref.field.name
|
|
5388
|
-
},
|
|
5389
|
-
(refId) => {
|
|
5390
|
-
if (!references[collection]) {
|
|
5391
|
-
references[collection] = {};
|
|
5392
|
-
}
|
|
5393
|
-
if (!references[collection][refId]) {
|
|
5394
|
-
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
|
+
}
|
|
5395
5485
|
}
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
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;
|
|
5403
5502
|
}
|
|
5404
|
-
|
|
5503
|
+
);
|
|
5405
5504
|
return references;
|
|
5406
5505
|
};
|
|
5407
5506
|
this.buildFieldMutations = async (fieldParams, template, existingData) => {
|
|
@@ -5471,7 +5570,7 @@ var Resolver = class {
|
|
|
5471
5570
|
}
|
|
5472
5571
|
break;
|
|
5473
5572
|
case "rich-text":
|
|
5474
|
-
accum[fieldName] =
|
|
5573
|
+
accum[fieldName] = serializeMDX(
|
|
5475
5574
|
fieldValue,
|
|
5476
5575
|
field,
|
|
5477
5576
|
(fieldValue2) => resolveMediaCloudToRelative(
|
|
@@ -5578,8 +5677,129 @@ var resolveDateInput = (value) => {
|
|
|
5578
5677
|
return date;
|
|
5579
5678
|
};
|
|
5580
5679
|
|
|
5581
|
-
// src/
|
|
5680
|
+
// src/resolver/auth-fields.ts
|
|
5582
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
|
+
}
|
|
5583
5803
|
|
|
5584
5804
|
// src/error.ts
|
|
5585
5805
|
import { GraphQLError as GraphQLError3 } from "graphql";
|
|
@@ -5689,119 +5909,33 @@ var resolve = async ({
|
|
|
5689
5909
|
);
|
|
5690
5910
|
}
|
|
5691
5911
|
}
|
|
5692
|
-
if (info.fieldName === "authenticate"
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
const realPath = `${collection.path}/index.json`;
|
|
5711
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5712
|
-
const users = get(userDoc, userField.path);
|
|
5713
|
-
if (!users) {
|
|
5714
|
-
throw new Error("No users found");
|
|
5715
|
-
}
|
|
5716
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5717
|
-
if (!idFieldName) {
|
|
5718
|
-
throw new Error("No uid field found on user field");
|
|
5719
|
-
}
|
|
5720
|
-
const user = users.find((u) => u[idFieldName] === sub);
|
|
5721
|
-
if (!user) {
|
|
5722
|
-
return null;
|
|
5723
|
-
}
|
|
5724
|
-
if (info.fieldName === "authenticate") {
|
|
5725
|
-
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5726
|
-
if (!saltedHash) {
|
|
5727
|
-
throw new Error("No password field found on user field");
|
|
5728
|
-
}
|
|
5729
|
-
const matches = await checkPasswordHash({
|
|
5730
|
-
saltedHash,
|
|
5731
|
-
password: args.password
|
|
5732
|
-
});
|
|
5733
|
-
if (matches) {
|
|
5734
|
-
return user;
|
|
5735
|
-
}
|
|
5736
|
-
return null;
|
|
5737
|
-
}
|
|
5738
|
-
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
|
+
});
|
|
5739
5930
|
}
|
|
5740
5931
|
if (info.fieldName === "updatePassword") {
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5748
|
-
if (!collection) {
|
|
5749
|
-
throw new Error("Auth collection not found");
|
|
5750
|
-
}
|
|
5751
|
-
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5752
|
-
if (!userFields.length) {
|
|
5753
|
-
throw new Error(
|
|
5754
|
-
`No user field found in collection ${collection.name}`
|
|
5755
|
-
);
|
|
5756
|
-
}
|
|
5757
|
-
if (userFields.length > 1) {
|
|
5758
|
-
throw new Error(
|
|
5759
|
-
`Multiple user fields found in collection ${collection.name}`
|
|
5760
|
-
);
|
|
5761
|
-
}
|
|
5762
|
-
const userField = userFields[0];
|
|
5763
|
-
const realPath = `${collection.path}/index.json`;
|
|
5764
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5765
|
-
const users = get(userDoc, userField.path);
|
|
5766
|
-
if (!users) {
|
|
5767
|
-
throw new Error("No users found");
|
|
5768
|
-
}
|
|
5769
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5770
|
-
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5771
|
-
if (!user) {
|
|
5772
|
-
throw new Error("Not authorized");
|
|
5773
|
-
}
|
|
5774
|
-
user[passwordFieldName] = {
|
|
5775
|
-
value: args.password,
|
|
5776
|
-
passwordChangeRequired: false
|
|
5777
|
-
};
|
|
5778
|
-
const params = {};
|
|
5779
|
-
set(
|
|
5780
|
-
params,
|
|
5781
|
-
userField.path.slice(1),
|
|
5782
|
-
// remove _rawData from users path
|
|
5783
|
-
users.map((u) => {
|
|
5784
|
-
if (user[idFieldName] === u[idFieldName]) {
|
|
5785
|
-
return user;
|
|
5786
|
-
}
|
|
5787
|
-
return {
|
|
5788
|
-
// don't overwrite other users' passwords
|
|
5789
|
-
...u,
|
|
5790
|
-
[passwordFieldName]: {
|
|
5791
|
-
...u[passwordFieldName],
|
|
5792
|
-
value: ""
|
|
5793
|
-
}
|
|
5794
|
-
};
|
|
5795
|
-
})
|
|
5796
|
-
);
|
|
5797
|
-
await resolver.updateResolveDocument({
|
|
5798
|
-
collection,
|
|
5799
|
-
args: { params },
|
|
5800
|
-
realPath,
|
|
5801
|
-
isCollectionSpecific: true,
|
|
5802
|
-
isAddPendingDocument: false
|
|
5932
|
+
return handleUpdatePassword({
|
|
5933
|
+
tinaSchema,
|
|
5934
|
+
resolver,
|
|
5935
|
+
password: args.password,
|
|
5936
|
+
info,
|
|
5937
|
+
ctxUser
|
|
5803
5938
|
});
|
|
5804
|
-
return true;
|
|
5805
5939
|
}
|
|
5806
5940
|
if (!lookup) {
|
|
5807
5941
|
return value;
|
|
@@ -6145,6 +6279,7 @@ var Database = class {
|
|
|
6145
6279
|
);
|
|
6146
6280
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
6147
6281
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6282
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6148
6283
|
const normalizedPath = normalizePath(filepath);
|
|
6149
6284
|
if (!collection?.isDetached) {
|
|
6150
6285
|
if (this.bridge) {
|
|
@@ -6173,6 +6308,14 @@ var Database = class {
|
|
|
6173
6308
|
let delOps = [];
|
|
6174
6309
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6175
6310
|
putOps = [
|
|
6311
|
+
...makeRefOpsForDocument(
|
|
6312
|
+
normalizedPath,
|
|
6313
|
+
collection?.name,
|
|
6314
|
+
collectionReferences,
|
|
6315
|
+
dataFields,
|
|
6316
|
+
"put",
|
|
6317
|
+
level
|
|
6318
|
+
),
|
|
6176
6319
|
...makeIndexOpsForDocument(
|
|
6177
6320
|
normalizedPath,
|
|
6178
6321
|
collection?.name,
|
|
@@ -6196,6 +6339,14 @@ var Database = class {
|
|
|
6196
6339
|
SUBLEVEL_OPTIONS
|
|
6197
6340
|
).get(normalizedPath);
|
|
6198
6341
|
delOps = existingItem ? [
|
|
6342
|
+
...makeRefOpsForDocument(
|
|
6343
|
+
normalizedPath,
|
|
6344
|
+
collection?.name,
|
|
6345
|
+
collectionReferences,
|
|
6346
|
+
existingItem,
|
|
6347
|
+
"del",
|
|
6348
|
+
level
|
|
6349
|
+
),
|
|
6199
6350
|
...makeIndexOpsForDocument(
|
|
6200
6351
|
normalizedPath,
|
|
6201
6352
|
collection?.name,
|
|
@@ -6243,6 +6394,7 @@ var Database = class {
|
|
|
6243
6394
|
);
|
|
6244
6395
|
collectionIndexDefinitions = indexDefinitions?.[collectionName];
|
|
6245
6396
|
}
|
|
6397
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collectionName];
|
|
6246
6398
|
const normalizedPath = normalizePath(filepath);
|
|
6247
6399
|
const dataFields = await this.formatBodyOnPayload(filepath, data);
|
|
6248
6400
|
const collection = await this.collectionForPath(filepath);
|
|
@@ -6290,6 +6442,14 @@ var Database = class {
|
|
|
6290
6442
|
let delOps = [];
|
|
6291
6443
|
if (!isGitKeep(normalizedPath, collection)) {
|
|
6292
6444
|
putOps = [
|
|
6445
|
+
...makeRefOpsForDocument(
|
|
6446
|
+
normalizedPath,
|
|
6447
|
+
collectionName,
|
|
6448
|
+
collectionReferences,
|
|
6449
|
+
dataFields,
|
|
6450
|
+
"put",
|
|
6451
|
+
level
|
|
6452
|
+
),
|
|
6293
6453
|
...makeIndexOpsForDocument(
|
|
6294
6454
|
normalizedPath,
|
|
6295
6455
|
collectionName,
|
|
@@ -6313,6 +6473,14 @@ var Database = class {
|
|
|
6313
6473
|
SUBLEVEL_OPTIONS
|
|
6314
6474
|
).get(normalizedPath);
|
|
6315
6475
|
delOps = existingItem ? [
|
|
6476
|
+
...makeRefOpsForDocument(
|
|
6477
|
+
normalizedPath,
|
|
6478
|
+
collectionName,
|
|
6479
|
+
collectionReferences,
|
|
6480
|
+
existingItem,
|
|
6481
|
+
"del",
|
|
6482
|
+
level
|
|
6483
|
+
),
|
|
6316
6484
|
...makeIndexOpsForDocument(
|
|
6317
6485
|
normalizedPath,
|
|
6318
6486
|
collectionName,
|
|
@@ -6355,8 +6523,7 @@ var Database = class {
|
|
|
6355
6523
|
throw new TinaFetchError(`Error in PUT for ${filepath}`, {
|
|
6356
6524
|
originalError: error,
|
|
6357
6525
|
file: filepath,
|
|
6358
|
-
collection: collectionName
|
|
6359
|
-
stack: error.stack
|
|
6526
|
+
collection: collectionName
|
|
6360
6527
|
});
|
|
6361
6528
|
}
|
|
6362
6529
|
};
|
|
@@ -6475,6 +6642,22 @@ var Database = class {
|
|
|
6475
6642
|
this.tinaSchema = await createSchema({ schema });
|
|
6476
6643
|
return this.tinaSchema;
|
|
6477
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
|
+
};
|
|
6478
6661
|
this.getIndexDefinitions = async (level) => {
|
|
6479
6662
|
if (!this.collectionIndexDefinitions) {
|
|
6480
6663
|
await new Promise(async (resolve2, reject) => {
|
|
@@ -6484,11 +6667,53 @@ var Database = class {
|
|
|
6484
6667
|
const collections = schema.getCollections();
|
|
6485
6668
|
for (const collection of collections) {
|
|
6486
6669
|
const indexDefinitions = {
|
|
6487
|
-
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
6670
|
+
[DEFAULT_COLLECTION_SORT_KEY]: { fields: [] },
|
|
6488
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
|
+
}
|
|
6489
6687
|
};
|
|
6490
|
-
|
|
6491
|
-
|
|
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) {
|
|
6492
6717
|
if (field.indexed !== void 0 && field.indexed === false || field.type === "object") {
|
|
6493
6718
|
continue;
|
|
6494
6719
|
}
|
|
@@ -6636,29 +6861,35 @@ var Database = class {
|
|
|
6636
6861
|
}
|
|
6637
6862
|
startKey = startKey || key || "";
|
|
6638
6863
|
endKey = key || "";
|
|
6639
|
-
edges = [...edges, { cursor: key, path: filepath }];
|
|
6864
|
+
edges = [...edges, { cursor: key, path: filepath, value: itemRecord }];
|
|
6640
6865
|
}
|
|
6641
6866
|
return {
|
|
6642
|
-
edges: await sequential(
|
|
6643
|
-
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
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;
|
|
6658
6890
|
}
|
|
6659
|
-
throw error;
|
|
6660
6891
|
}
|
|
6661
|
-
|
|
6892
|
+
),
|
|
6662
6893
|
pageInfo: {
|
|
6663
6894
|
hasPreviousPage,
|
|
6664
6895
|
hasNextPage,
|
|
@@ -6782,13 +7013,14 @@ var Database = class {
|
|
|
6782
7013
|
documentPaths,
|
|
6783
7014
|
async (collection, documentPaths2) => {
|
|
6784
7015
|
if (collection && !collection.isDetached) {
|
|
6785
|
-
await _indexContent(
|
|
6786
|
-
this,
|
|
6787
|
-
this.contentLevel,
|
|
6788
|
-
documentPaths2,
|
|
7016
|
+
await _indexContent({
|
|
7017
|
+
database: this,
|
|
7018
|
+
level: this.contentLevel,
|
|
7019
|
+
documentPaths: documentPaths2,
|
|
6789
7020
|
enqueueOps,
|
|
6790
|
-
collection
|
|
6791
|
-
|
|
7021
|
+
collection,
|
|
7022
|
+
isPartialReindex: true
|
|
7023
|
+
});
|
|
6792
7024
|
}
|
|
6793
7025
|
}
|
|
6794
7026
|
);
|
|
@@ -6804,6 +7036,7 @@ var Database = class {
|
|
|
6804
7036
|
throw new Error(`No collection found for path: ${filepath}`);
|
|
6805
7037
|
}
|
|
6806
7038
|
const indexDefinitions = await this.getIndexDefinitions(this.contentLevel);
|
|
7039
|
+
const collectionReferences = (await this.getCollectionReferences())?.[collection.name];
|
|
6807
7040
|
const collectionIndexDefinitions = indexDefinitions?.[collection.name];
|
|
6808
7041
|
let level = this.contentLevel;
|
|
6809
7042
|
if (collection?.isDetached) {
|
|
@@ -6822,6 +7055,14 @@ var Database = class {
|
|
|
6822
7055
|
collection.path || ""
|
|
6823
7056
|
);
|
|
6824
7057
|
await this.contentLevel.batch([
|
|
7058
|
+
...makeRefOpsForDocument(
|
|
7059
|
+
normalizedPath,
|
|
7060
|
+
collection.name,
|
|
7061
|
+
collectionReferences,
|
|
7062
|
+
item,
|
|
7063
|
+
"del",
|
|
7064
|
+
level
|
|
7065
|
+
),
|
|
6825
7066
|
...makeIndexOpsForDocument(
|
|
6826
7067
|
normalizedPath,
|
|
6827
7068
|
collection.name,
|
|
@@ -6886,20 +7127,26 @@ var Database = class {
|
|
|
6886
7127
|
);
|
|
6887
7128
|
const doc = await level2.keys({ limit: 1 }).next();
|
|
6888
7129
|
if (!doc) {
|
|
6889
|
-
await _indexContent(
|
|
6890
|
-
this,
|
|
6891
|
-
level2,
|
|
6892
|
-
contentPaths,
|
|
7130
|
+
await _indexContent({
|
|
7131
|
+
database: this,
|
|
7132
|
+
level: level2,
|
|
7133
|
+
documentPaths: contentPaths,
|
|
6893
7134
|
enqueueOps,
|
|
6894
7135
|
collection,
|
|
6895
|
-
userFields.map((field) => [
|
|
7136
|
+
passwordFields: userFields.map((field) => [
|
|
6896
7137
|
...field.path,
|
|
6897
7138
|
field.passwordFieldName
|
|
6898
7139
|
])
|
|
6899
|
-
);
|
|
7140
|
+
});
|
|
6900
7141
|
}
|
|
6901
7142
|
} else {
|
|
6902
|
-
await _indexContent(
|
|
7143
|
+
await _indexContent({
|
|
7144
|
+
database: this,
|
|
7145
|
+
level,
|
|
7146
|
+
documentPaths: contentPaths,
|
|
7147
|
+
enqueueOps,
|
|
7148
|
+
collection
|
|
7149
|
+
});
|
|
6903
7150
|
}
|
|
6904
7151
|
}
|
|
6905
7152
|
);
|
|
@@ -7038,7 +7285,15 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
|
|
|
7038
7285
|
)
|
|
7039
7286
|
);
|
|
7040
7287
|
var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${collection?.format || "md"}`);
|
|
7041
|
-
var _indexContent = async (
|
|
7288
|
+
var _indexContent = async ({
|
|
7289
|
+
database,
|
|
7290
|
+
level,
|
|
7291
|
+
documentPaths,
|
|
7292
|
+
enqueueOps,
|
|
7293
|
+
collection,
|
|
7294
|
+
passwordFields,
|
|
7295
|
+
isPartialReindex
|
|
7296
|
+
}) => {
|
|
7042
7297
|
let collectionIndexDefinitions;
|
|
7043
7298
|
let collectionPath;
|
|
7044
7299
|
if (collection) {
|
|
@@ -7049,6 +7304,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7049
7304
|
}
|
|
7050
7305
|
collectionPath = collection.path;
|
|
7051
7306
|
}
|
|
7307
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7052
7308
|
const tinaSchema = await database.getSchema();
|
|
7053
7309
|
let templateInfo = null;
|
|
7054
7310
|
if (collection) {
|
|
@@ -7078,35 +7334,53 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7078
7334
|
normalizedPath,
|
|
7079
7335
|
collectionPath || ""
|
|
7080
7336
|
);
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
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
|
+
}
|
|
7107
7373
|
}
|
|
7108
7374
|
if (!isGitKeep(filepath, collection)) {
|
|
7109
7375
|
await enqueueOps([
|
|
7376
|
+
...makeRefOpsForDocument(
|
|
7377
|
+
normalizedPath,
|
|
7378
|
+
collection?.name,
|
|
7379
|
+
collectionReferences,
|
|
7380
|
+
aliasedData,
|
|
7381
|
+
"put",
|
|
7382
|
+
level
|
|
7383
|
+
),
|
|
7110
7384
|
...makeIndexOpsForDocument(
|
|
7111
7385
|
normalizedPath,
|
|
7112
7386
|
collection?.name,
|
|
@@ -7139,8 +7413,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7139
7413
|
throw new TinaFetchError(`Unable to seed ${filepath}`, {
|
|
7140
7414
|
originalError: error,
|
|
7141
7415
|
file: filepath,
|
|
7142
|
-
collection: collection?.name
|
|
7143
|
-
stack: error.stack
|
|
7416
|
+
collection: collection?.name
|
|
7144
7417
|
});
|
|
7145
7418
|
}
|
|
7146
7419
|
});
|
|
@@ -7170,6 +7443,7 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7170
7443
|
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
7171
7444
|
}
|
|
7172
7445
|
}
|
|
7446
|
+
const collectionReferences = (await database.getCollectionReferences())?.[collection?.name];
|
|
7173
7447
|
const tinaSchema = await database.getSchema();
|
|
7174
7448
|
let templateInfo = null;
|
|
7175
7449
|
if (collection) {
|
|
@@ -7193,6 +7467,14 @@ var _deleteIndexContent = async (database, documentPaths, enqueueOps, collection
|
|
|
7193
7467
|
item
|
|
7194
7468
|
) : item;
|
|
7195
7469
|
await enqueueOps([
|
|
7470
|
+
...makeRefOpsForDocument(
|
|
7471
|
+
itemKey,
|
|
7472
|
+
collection?.name,
|
|
7473
|
+
collectionReferences,
|
|
7474
|
+
aliasedData,
|
|
7475
|
+
"del",
|
|
7476
|
+
database.contentLevel
|
|
7477
|
+
),
|
|
7196
7478
|
...makeIndexOpsForDocument(
|
|
7197
7479
|
itemKey,
|
|
7198
7480
|
collection.name,
|
|
@@ -7322,8 +7604,8 @@ import path6 from "path";
|
|
|
7322
7604
|
import normalize from "normalize-path";
|
|
7323
7605
|
var FilesystemBridge = class {
|
|
7324
7606
|
constructor(rootPath, outputPath) {
|
|
7325
|
-
this.rootPath = rootPath
|
|
7326
|
-
this.outputPath = outputPath
|
|
7607
|
+
this.rootPath = path6.resolve(rootPath);
|
|
7608
|
+
this.outputPath = outputPath ? path6.resolve(outputPath) : this.rootPath;
|
|
7327
7609
|
}
|
|
7328
7610
|
async glob(pattern, extension) {
|
|
7329
7611
|
const basePath = path6.join(this.outputPath, ...pattern.split("/"));
|
|
@@ -7335,19 +7617,19 @@ var FilesystemBridge = class {
|
|
|
7335
7617
|
}
|
|
7336
7618
|
);
|
|
7337
7619
|
const posixRootPath = normalize(this.outputPath);
|
|
7338
|
-
return items.map(
|
|
7339
|
-
|
|
7340
|
-
|
|
7620
|
+
return items.map(
|
|
7621
|
+
(item) => item.substring(posixRootPath.length).replace(/^\/|\/$/g, "")
|
|
7622
|
+
);
|
|
7341
7623
|
}
|
|
7342
7624
|
async delete(filepath) {
|
|
7343
7625
|
await fs2.remove(path6.join(this.outputPath, filepath));
|
|
7344
7626
|
}
|
|
7345
7627
|
async get(filepath) {
|
|
7346
|
-
return fs2.
|
|
7628
|
+
return (await fs2.readFile(path6.join(this.outputPath, filepath))).toString();
|
|
7347
7629
|
}
|
|
7348
7630
|
async put(filepath, data, basePathOverride) {
|
|
7349
7631
|
const basePath = basePathOverride || this.outputPath;
|
|
7350
|
-
await fs2.
|
|
7632
|
+
await fs2.outputFile(path6.join(basePath, filepath), data);
|
|
7351
7633
|
}
|
|
7352
7634
|
};
|
|
7353
7635
|
var AuditFileSystemBridge = class extends FilesystemBridge {
|