@tinacms/graphql 0.0.0-d20d4ee-20250329210608 → 0.0.0-d4c653b-20251027224657
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/util.d.ts +6 -9
- package/dist/index.js +669 -658
- package/dist/index.mjs +555 -518
- 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 +5 -5
- 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
|
|
|
@@ -3312,249 +3310,10 @@ import { graphql, buildASTSchema, getNamedType, GraphQLError as GraphQLError4 }
|
|
|
3312
3310
|
// src/resolver/index.ts
|
|
3313
3311
|
import path3 from "path";
|
|
3314
3312
|
import isValid from "date-fns/isValid/index.js";
|
|
3315
|
-
|
|
3316
|
-
// src/mdx/index.ts
|
|
3317
|
-
import { parseMDX, stringifyMDX } from "@tinacms/mdx";
|
|
3318
|
-
|
|
3319
|
-
// src/resolver/index.ts
|
|
3320
3313
|
import { JSONPath as JSONPath2 } from "jsonpath-plus";
|
|
3321
3314
|
|
|
3322
|
-
// src/
|
|
3323
|
-
|
|
3324
|
-
constructor(message, extensions) {
|
|
3325
|
-
super(message);
|
|
3326
|
-
if (!this.name) {
|
|
3327
|
-
Object.defineProperty(this, "name", { value: "TinaGraphQLError" });
|
|
3328
|
-
}
|
|
3329
|
-
this.extensions = { ...extensions };
|
|
3330
|
-
}
|
|
3331
|
-
};
|
|
3332
|
-
var TinaFetchError = class extends Error {
|
|
3333
|
-
constructor(message, args) {
|
|
3334
|
-
super(message);
|
|
3335
|
-
this.name = "TinaFetchError";
|
|
3336
|
-
this.collection = args.collection;
|
|
3337
|
-
this.stack = args.stack;
|
|
3338
|
-
this.file = args.file;
|
|
3339
|
-
this.originalError = args.originalError;
|
|
3340
|
-
}
|
|
3341
|
-
};
|
|
3342
|
-
var TinaQueryError = class extends TinaFetchError {
|
|
3343
|
-
constructor(args) {
|
|
3344
|
-
super(
|
|
3345
|
-
`Error querying file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3346
|
-
args
|
|
3347
|
-
);
|
|
3348
|
-
}
|
|
3349
|
-
};
|
|
3350
|
-
var TinaParseDocumentError = class extends TinaFetchError {
|
|
3351
|
-
constructor(args) {
|
|
3352
|
-
super(
|
|
3353
|
-
`Error parsing file ${args.file} from collection ${args.collection}. ${auditMessage(args.includeAuditMessage)}`,
|
|
3354
|
-
args
|
|
3355
|
-
);
|
|
3356
|
-
}
|
|
3357
|
-
toString() {
|
|
3358
|
-
return super.toString() + "\n OriginalError: \n" + this.originalError.toString();
|
|
3359
|
-
}
|
|
3360
|
-
};
|
|
3361
|
-
var auditMessage = (includeAuditMessage = true) => includeAuditMessage ? `Please run "tinacms audit" or add the --verbose option for more info` : "";
|
|
3362
|
-
var handleFetchErrorError = (e, verbose) => {
|
|
3363
|
-
if (e instanceof Error) {
|
|
3364
|
-
if (e instanceof TinaFetchError) {
|
|
3365
|
-
if (verbose) {
|
|
3366
|
-
console.log(e.toString());
|
|
3367
|
-
console.log(e);
|
|
3368
|
-
console.log(e.stack);
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
} else {
|
|
3372
|
-
console.error(e);
|
|
3373
|
-
}
|
|
3374
|
-
throw e;
|
|
3375
|
-
};
|
|
3376
|
-
|
|
3377
|
-
// src/resolver/filter-utils.ts
|
|
3378
|
-
var resolveReferences = async (filter, fields, resolver) => {
|
|
3379
|
-
for (const fieldKey of Object.keys(filter)) {
|
|
3380
|
-
const fieldDefinition = fields.find(
|
|
3381
|
-
(f) => f.name === fieldKey
|
|
3382
|
-
);
|
|
3383
|
-
if (fieldDefinition) {
|
|
3384
|
-
if (fieldDefinition.type === "reference") {
|
|
3385
|
-
const { edges, values } = await resolver(filter, fieldDefinition);
|
|
3386
|
-
if (edges.length === 1) {
|
|
3387
|
-
filter[fieldKey] = {
|
|
3388
|
-
eq: values[0]
|
|
3389
|
-
};
|
|
3390
|
-
} else if (edges.length > 1) {
|
|
3391
|
-
filter[fieldKey] = {
|
|
3392
|
-
in: values
|
|
3393
|
-
};
|
|
3394
|
-
} else {
|
|
3395
|
-
filter[fieldKey] = {
|
|
3396
|
-
eq: "___null___"
|
|
3397
|
-
};
|
|
3398
|
-
}
|
|
3399
|
-
} else if (fieldDefinition.type === "object") {
|
|
3400
|
-
if (fieldDefinition.templates) {
|
|
3401
|
-
for (const templateName of Object.keys(filter[fieldKey])) {
|
|
3402
|
-
const template = fieldDefinition.templates.find(
|
|
3403
|
-
(template2) => !(typeof template2 === "string") && template2.name === templateName
|
|
3404
|
-
);
|
|
3405
|
-
if (template) {
|
|
3406
|
-
await resolveReferences(
|
|
3407
|
-
filter[fieldKey][templateName],
|
|
3408
|
-
template.fields,
|
|
3409
|
-
resolver
|
|
3410
|
-
);
|
|
3411
|
-
} else {
|
|
3412
|
-
throw new Error(`Template ${templateName} not found`);
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3415
|
-
} else {
|
|
3416
|
-
await resolveReferences(
|
|
3417
|
-
filter[fieldKey],
|
|
3418
|
-
fieldDefinition.fields,
|
|
3419
|
-
resolver
|
|
3420
|
-
);
|
|
3421
|
-
}
|
|
3422
|
-
}
|
|
3423
|
-
} else {
|
|
3424
|
-
throw new Error(`Unable to find field ${fieldKey}`);
|
|
3425
|
-
}
|
|
3426
|
-
}
|
|
3427
|
-
};
|
|
3428
|
-
var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
|
|
3429
|
-
for (const childFieldName of Object.keys(filterNode)) {
|
|
3430
|
-
const childField = fields.find((field) => field.name === childFieldName);
|
|
3431
|
-
if (!childField) {
|
|
3432
|
-
throw new Error(`Unable to find type for field ${childFieldName}`);
|
|
3433
|
-
}
|
|
3434
|
-
collectConditionsForField(
|
|
3435
|
-
childFieldName,
|
|
3436
|
-
childField,
|
|
3437
|
-
filterNode[childFieldName],
|
|
3438
|
-
pathExpression,
|
|
3439
|
-
collectCondition
|
|
3440
|
-
);
|
|
3441
|
-
}
|
|
3442
|
-
};
|
|
3443
|
-
var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3444
|
-
if (field.list && field.templates) {
|
|
3445
|
-
for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
|
|
3446
|
-
const template = field.templates.find(
|
|
3447
|
-
(template2) => !(typeof template2 === "string") && template2.name === filterKey
|
|
3448
|
-
);
|
|
3449
|
-
const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
|
|
3450
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
|
|
3451
|
-
collectConditionsForChildFields(
|
|
3452
|
-
childFilterNode,
|
|
3453
|
-
template.fields,
|
|
3454
|
-
filterPath,
|
|
3455
|
-
collectCondition
|
|
3456
|
-
);
|
|
3457
|
-
}
|
|
3458
|
-
} else {
|
|
3459
|
-
const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
|
|
3460
|
-
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
|
|
3461
|
-
collectConditionsForChildFields(
|
|
3462
|
-
filterNode,
|
|
3463
|
-
field.fields,
|
|
3464
|
-
filterPath,
|
|
3465
|
-
collectCondition
|
|
3466
|
-
);
|
|
3467
|
-
}
|
|
3468
|
-
};
|
|
3469
|
-
var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
3470
|
-
if (field.type === "object") {
|
|
3471
|
-
collectConditionsForObjectField(
|
|
3472
|
-
fieldName,
|
|
3473
|
-
field,
|
|
3474
|
-
filterNode,
|
|
3475
|
-
pathExpression,
|
|
3476
|
-
collectCondition
|
|
3477
|
-
);
|
|
3478
|
-
} else {
|
|
3479
|
-
collectCondition({
|
|
3480
|
-
filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
|
|
3481
|
-
filterExpression: {
|
|
3482
|
-
_type: field.type,
|
|
3483
|
-
_list: !!field.list,
|
|
3484
|
-
...filterNode
|
|
3485
|
-
}
|
|
3486
|
-
});
|
|
3487
|
-
}
|
|
3488
|
-
};
|
|
3489
|
-
|
|
3490
|
-
// src/resolver/media-utils.ts
|
|
3491
|
-
var resolveMediaCloudToRelative = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3492
|
-
if (config && value) {
|
|
3493
|
-
if (config.useRelativeMedia === true) {
|
|
3494
|
-
return value;
|
|
3495
|
-
}
|
|
3496
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3497
|
-
const assetsURL = `https://${config.assetsHost}/${config.clientId}`;
|
|
3498
|
-
if (typeof value === "string" && value.includes(assetsURL)) {
|
|
3499
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3500
|
-
schema.config.media.tina.mediaRoot
|
|
3501
|
-
);
|
|
3502
|
-
const strippedURL = value.replace(assetsURL, "");
|
|
3503
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3504
|
-
}
|
|
3505
|
-
if (Array.isArray(value)) {
|
|
3506
|
-
return value.map((v) => {
|
|
3507
|
-
if (!v || typeof v !== "string") return v;
|
|
3508
|
-
const cleanMediaRoot = cleanUpSlashes(
|
|
3509
|
-
schema.config.media.tina.mediaRoot
|
|
3510
|
-
);
|
|
3511
|
-
const strippedURL = v.replace(assetsURL, "");
|
|
3512
|
-
return `${cleanMediaRoot}${strippedURL}`;
|
|
3513
|
-
});
|
|
3514
|
-
}
|
|
3515
|
-
return value;
|
|
3516
|
-
}
|
|
3517
|
-
return value;
|
|
3518
|
-
} else {
|
|
3519
|
-
return value;
|
|
3520
|
-
}
|
|
3521
|
-
};
|
|
3522
|
-
var resolveMediaRelativeToCloud = (value, config = { useRelativeMedia: true }, schema) => {
|
|
3523
|
-
if (config && value) {
|
|
3524
|
-
if (config.useRelativeMedia === true) {
|
|
3525
|
-
return value;
|
|
3526
|
-
}
|
|
3527
|
-
if (hasTinaMediaConfig(schema) === true) {
|
|
3528
|
-
const cleanMediaRoot = cleanUpSlashes(schema.config.media.tina.mediaRoot);
|
|
3529
|
-
if (typeof value === "string") {
|
|
3530
|
-
const strippedValue = value.replace(cleanMediaRoot, "");
|
|
3531
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3532
|
-
}
|
|
3533
|
-
if (Array.isArray(value)) {
|
|
3534
|
-
return value.map((v) => {
|
|
3535
|
-
if (!v || typeof v !== "string") return v;
|
|
3536
|
-
const strippedValue = v.replace(cleanMediaRoot, "");
|
|
3537
|
-
return `https://${config.assetsHost}/${config.clientId}${strippedValue}`;
|
|
3538
|
-
});
|
|
3539
|
-
}
|
|
3540
|
-
}
|
|
3541
|
-
return value;
|
|
3542
|
-
} else {
|
|
3543
|
-
return value;
|
|
3544
|
-
}
|
|
3545
|
-
};
|
|
3546
|
-
var cleanUpSlashes = (path7) => {
|
|
3547
|
-
if (path7) {
|
|
3548
|
-
return `/${path7.replace(/^\/+|\/+$/gm, "")}`;
|
|
3549
|
-
}
|
|
3550
|
-
return "";
|
|
3551
|
-
};
|
|
3552
|
-
var hasTinaMediaConfig = (schema) => {
|
|
3553
|
-
if (!schema.config?.media?.tina) return false;
|
|
3554
|
-
if (typeof schema.config?.media?.tina?.publicFolder !== "string" && typeof schema.config?.media?.tina?.mediaRoot !== "string")
|
|
3555
|
-
return false;
|
|
3556
|
-
return true;
|
|
3557
|
-
};
|
|
3315
|
+
// src/mdx/index.ts
|
|
3316
|
+
import { parseMDX, serializeMDX } from "@tinacms/mdx";
|
|
3558
3317
|
|
|
3559
3318
|
// src/resolver/index.ts
|
|
3560
3319
|
import { GraphQLError as GraphQLError2 } from "graphql";
|
|
@@ -3617,13 +3376,13 @@ import path2 from "path";
|
|
|
3617
3376
|
|
|
3618
3377
|
// src/database/util.ts
|
|
3619
3378
|
import toml from "@iarna/toml";
|
|
3620
|
-
import yaml from "js-yaml";
|
|
3621
|
-
import matter from "gray-matter";
|
|
3622
3379
|
import {
|
|
3623
3380
|
normalizePath
|
|
3624
3381
|
} from "@tinacms/schema-tools";
|
|
3625
|
-
import
|
|
3382
|
+
import matter from "gray-matter";
|
|
3383
|
+
import yaml from "js-yaml";
|
|
3626
3384
|
import path from "path";
|
|
3385
|
+
import micromatch from "micromatch";
|
|
3627
3386
|
|
|
3628
3387
|
// src/database/alias-utils.ts
|
|
3629
3388
|
var replaceBlockAliases = (template, item) => {
|
|
@@ -4536,80 +4295,316 @@ var makeIndexOpsForDocument = (filepath, collection, indexDefinitions, data, opT
|
|
|
4536
4295
|
});
|
|
4537
4296
|
}
|
|
4538
4297
|
}
|
|
4539
|
-
}
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
return result;
|
|
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
|
+
};
|
|
4353
|
+
var makeStringEscaper = (regex, replacement) => {
|
|
4354
|
+
return (input) => {
|
|
4355
|
+
if (Array.isArray(input)) {
|
|
4356
|
+
return input.map(
|
|
4357
|
+
(val) => val.replace(regex, replacement)
|
|
4358
|
+
);
|
|
4359
|
+
} else {
|
|
4360
|
+
if (typeof input === "string") {
|
|
4361
|
+
return input.replace(regex, replacement);
|
|
4362
|
+
} else {
|
|
4363
|
+
return input;
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
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
|
+
});
|
|
4540
4537
|
}
|
|
4541
|
-
return result;
|
|
4542
4538
|
};
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
const
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
if (!ref) {
|
|
4559
|
-
continue;
|
|
4560
|
-
}
|
|
4561
|
-
if (Array.isArray(ref)) {
|
|
4562
|
-
for (const r of ref) {
|
|
4563
|
-
if (!r) {
|
|
4564
|
-
continue;
|
|
4565
|
-
}
|
|
4566
|
-
if (references2[r]) {
|
|
4567
|
-
references2[r].push(path7);
|
|
4568
|
-
} else {
|
|
4569
|
-
references2[r] = [path7];
|
|
4570
|
-
}
|
|
4571
|
-
}
|
|
4572
|
-
} else {
|
|
4573
|
-
if (references2[ref]) {
|
|
4574
|
-
references2[ref].push(path7);
|
|
4575
|
-
} else {
|
|
4576
|
-
references2[ref] = [path7];
|
|
4577
|
-
}
|
|
4578
|
-
}
|
|
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}`;
|
|
4579
4554
|
}
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
}
|
|
4588
|
-
}
|
|
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
|
+
});
|
|
4589
4564
|
}
|
|
4565
|
+
return value;
|
|
4590
4566
|
}
|
|
4567
|
+
return value;
|
|
4568
|
+
} else {
|
|
4569
|
+
return value;
|
|
4591
4570
|
}
|
|
4592
|
-
return result;
|
|
4593
4571
|
};
|
|
4594
|
-
var
|
|
4595
|
-
|
|
4596
|
-
if (
|
|
4597
|
-
return
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
if (typeof
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
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
|
+
});
|
|
4605
4589
|
}
|
|
4606
4590
|
}
|
|
4607
|
-
|
|
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;
|
|
4608
4607
|
};
|
|
4609
|
-
var stringEscaper = makeStringEscaper(
|
|
4610
|
-
new RegExp(INDEX_KEY_FIELD_SEPARATOR, "gm"),
|
|
4611
|
-
encodeURIComponent(INDEX_KEY_FIELD_SEPARATOR)
|
|
4612
|
-
);
|
|
4613
4608
|
|
|
4614
4609
|
// src/resolver/index.ts
|
|
4615
4610
|
var createResolver = (args) => {
|
|
@@ -4771,8 +4766,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4771
4766
|
originalError: e,
|
|
4772
4767
|
collection: collection.name,
|
|
4773
4768
|
includeAuditMessage: !isAudit,
|
|
4774
|
-
file: relativePath
|
|
4775
|
-
stack: e.stack
|
|
4769
|
+
file: relativePath
|
|
4776
4770
|
});
|
|
4777
4771
|
}
|
|
4778
4772
|
const titleField = template.fields.find((x) => {
|
|
@@ -5576,7 +5570,7 @@ var Resolver = class {
|
|
|
5576
5570
|
}
|
|
5577
5571
|
break;
|
|
5578
5572
|
case "rich-text":
|
|
5579
|
-
accum[fieldName] =
|
|
5573
|
+
accum[fieldName] = serializeMDX(
|
|
5580
5574
|
fieldValue,
|
|
5581
5575
|
field,
|
|
5582
5576
|
(fieldValue2) => resolveMediaCloudToRelative(
|
|
@@ -5683,8 +5677,129 @@ var resolveDateInput = (value) => {
|
|
|
5683
5677
|
return date;
|
|
5684
5678
|
};
|
|
5685
5679
|
|
|
5686
|
-
// src/
|
|
5680
|
+
// src/resolver/auth-fields.ts
|
|
5687
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
|
+
}
|
|
5688
5803
|
|
|
5689
5804
|
// src/error.ts
|
|
5690
5805
|
import { GraphQLError as GraphQLError3 } from "graphql";
|
|
@@ -5794,119 +5909,33 @@ var resolve = async ({
|
|
|
5794
5909
|
);
|
|
5795
5910
|
}
|
|
5796
5911
|
}
|
|
5797
|
-
if (info.fieldName === "authenticate"
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
const realPath = `${collection.path}/index.json`;
|
|
5816
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5817
|
-
const users = get(userDoc, userField.path);
|
|
5818
|
-
if (!users) {
|
|
5819
|
-
throw new Error("No users found");
|
|
5820
|
-
}
|
|
5821
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5822
|
-
if (!idFieldName) {
|
|
5823
|
-
throw new Error("No uid field found on user field");
|
|
5824
|
-
}
|
|
5825
|
-
const user = users.find((u) => u[idFieldName] === sub);
|
|
5826
|
-
if (!user) {
|
|
5827
|
-
return null;
|
|
5828
|
-
}
|
|
5829
|
-
if (info.fieldName === "authenticate") {
|
|
5830
|
-
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5831
|
-
if (!saltedHash) {
|
|
5832
|
-
throw new Error("No password field found on user field");
|
|
5833
|
-
}
|
|
5834
|
-
const matches = await checkPasswordHash({
|
|
5835
|
-
saltedHash,
|
|
5836
|
-
password: args.password
|
|
5837
|
-
});
|
|
5838
|
-
if (matches) {
|
|
5839
|
-
return user;
|
|
5840
|
-
}
|
|
5841
|
-
return null;
|
|
5842
|
-
}
|
|
5843
|
-
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
|
+
});
|
|
5844
5930
|
}
|
|
5845
5931
|
if (info.fieldName === "updatePassword") {
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5853
|
-
if (!collection) {
|
|
5854
|
-
throw new Error("Auth collection not found");
|
|
5855
|
-
}
|
|
5856
|
-
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5857
|
-
if (!userFields.length) {
|
|
5858
|
-
throw new Error(
|
|
5859
|
-
`No user field found in collection ${collection.name}`
|
|
5860
|
-
);
|
|
5861
|
-
}
|
|
5862
|
-
if (userFields.length > 1) {
|
|
5863
|
-
throw new Error(
|
|
5864
|
-
`Multiple user fields found in collection ${collection.name}`
|
|
5865
|
-
);
|
|
5866
|
-
}
|
|
5867
|
-
const userField = userFields[0];
|
|
5868
|
-
const realPath = `${collection.path}/index.json`;
|
|
5869
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5870
|
-
const users = get(userDoc, userField.path);
|
|
5871
|
-
if (!users) {
|
|
5872
|
-
throw new Error("No users found");
|
|
5873
|
-
}
|
|
5874
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5875
|
-
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5876
|
-
if (!user) {
|
|
5877
|
-
throw new Error("Not authorized");
|
|
5878
|
-
}
|
|
5879
|
-
user[passwordFieldName] = {
|
|
5880
|
-
value: args.password,
|
|
5881
|
-
passwordChangeRequired: false
|
|
5882
|
-
};
|
|
5883
|
-
const params = {};
|
|
5884
|
-
set(
|
|
5885
|
-
params,
|
|
5886
|
-
userField.path.slice(1),
|
|
5887
|
-
// remove _rawData from users path
|
|
5888
|
-
users.map((u) => {
|
|
5889
|
-
if (user[idFieldName] === u[idFieldName]) {
|
|
5890
|
-
return user;
|
|
5891
|
-
}
|
|
5892
|
-
return {
|
|
5893
|
-
// don't overwrite other users' passwords
|
|
5894
|
-
...u,
|
|
5895
|
-
[passwordFieldName]: {
|
|
5896
|
-
...u[passwordFieldName],
|
|
5897
|
-
value: ""
|
|
5898
|
-
}
|
|
5899
|
-
};
|
|
5900
|
-
})
|
|
5901
|
-
);
|
|
5902
|
-
await resolver.updateResolveDocument({
|
|
5903
|
-
collection,
|
|
5904
|
-
args: { params },
|
|
5905
|
-
realPath,
|
|
5906
|
-
isCollectionSpecific: true,
|
|
5907
|
-
isAddPendingDocument: false
|
|
5932
|
+
return handleUpdatePassword({
|
|
5933
|
+
tinaSchema,
|
|
5934
|
+
resolver,
|
|
5935
|
+
password: args.password,
|
|
5936
|
+
info,
|
|
5937
|
+
ctxUser
|
|
5908
5938
|
});
|
|
5909
|
-
return true;
|
|
5910
5939
|
}
|
|
5911
5940
|
if (!lookup) {
|
|
5912
5941
|
return value;
|
|
@@ -6494,8 +6523,7 @@ var Database = class {
|
|
|
6494
6523
|
throw new TinaFetchError(`Error in PUT for ${filepath}`, {
|
|
6495
6524
|
originalError: error,
|
|
6496
6525
|
file: filepath,
|
|
6497
|
-
collection: collectionName
|
|
6498
|
-
stack: error.stack
|
|
6526
|
+
collection: collectionName
|
|
6499
6527
|
});
|
|
6500
6528
|
}
|
|
6501
6529
|
};
|
|
@@ -6855,8 +6883,7 @@ var Database = class {
|
|
|
6855
6883
|
throw new TinaQueryError({
|
|
6856
6884
|
originalError: error,
|
|
6857
6885
|
file: path7,
|
|
6858
|
-
collection: collection.name
|
|
6859
|
-
stack: error.stack
|
|
6886
|
+
collection: collection.name
|
|
6860
6887
|
});
|
|
6861
6888
|
}
|
|
6862
6889
|
throw error;
|
|
@@ -6986,13 +7013,14 @@ var Database = class {
|
|
|
6986
7013
|
documentPaths,
|
|
6987
7014
|
async (collection, documentPaths2) => {
|
|
6988
7015
|
if (collection && !collection.isDetached) {
|
|
6989
|
-
await _indexContent(
|
|
6990
|
-
this,
|
|
6991
|
-
this.contentLevel,
|
|
6992
|
-
documentPaths2,
|
|
7016
|
+
await _indexContent({
|
|
7017
|
+
database: this,
|
|
7018
|
+
level: this.contentLevel,
|
|
7019
|
+
documentPaths: documentPaths2,
|
|
6993
7020
|
enqueueOps,
|
|
6994
|
-
collection
|
|
6995
|
-
|
|
7021
|
+
collection,
|
|
7022
|
+
isPartialReindex: true
|
|
7023
|
+
});
|
|
6996
7024
|
}
|
|
6997
7025
|
}
|
|
6998
7026
|
);
|
|
@@ -7099,26 +7127,26 @@ var Database = class {
|
|
|
7099
7127
|
);
|
|
7100
7128
|
const doc = await level2.keys({ limit: 1 }).next();
|
|
7101
7129
|
if (!doc) {
|
|
7102
|
-
await _indexContent(
|
|
7103
|
-
this,
|
|
7104
|
-
level2,
|
|
7105
|
-
contentPaths,
|
|
7130
|
+
await _indexContent({
|
|
7131
|
+
database: this,
|
|
7132
|
+
level: level2,
|
|
7133
|
+
documentPaths: contentPaths,
|
|
7106
7134
|
enqueueOps,
|
|
7107
7135
|
collection,
|
|
7108
|
-
userFields.map((field) => [
|
|
7136
|
+
passwordFields: userFields.map((field) => [
|
|
7109
7137
|
...field.path,
|
|
7110
7138
|
field.passwordFieldName
|
|
7111
7139
|
])
|
|
7112
|
-
);
|
|
7140
|
+
});
|
|
7113
7141
|
}
|
|
7114
7142
|
} else {
|
|
7115
|
-
await _indexContent(
|
|
7116
|
-
this,
|
|
7143
|
+
await _indexContent({
|
|
7144
|
+
database: this,
|
|
7117
7145
|
level,
|
|
7118
|
-
contentPaths,
|
|
7146
|
+
documentPaths: contentPaths,
|
|
7119
7147
|
enqueueOps,
|
|
7120
7148
|
collection
|
|
7121
|
-
);
|
|
7149
|
+
});
|
|
7122
7150
|
}
|
|
7123
7151
|
}
|
|
7124
7152
|
);
|
|
@@ -7257,7 +7285,15 @@ var hashPasswordValues = async (data, passwordFields) => Promise.all(
|
|
|
7257
7285
|
)
|
|
7258
7286
|
);
|
|
7259
7287
|
var isGitKeep = (filepath, collection) => filepath.endsWith(`.gitkeep.${collection?.format || "md"}`);
|
|
7260
|
-
var _indexContent = async (
|
|
7288
|
+
var _indexContent = async ({
|
|
7289
|
+
database,
|
|
7290
|
+
level,
|
|
7291
|
+
documentPaths,
|
|
7292
|
+
enqueueOps,
|
|
7293
|
+
collection,
|
|
7294
|
+
passwordFields,
|
|
7295
|
+
isPartialReindex
|
|
7296
|
+
}) => {
|
|
7261
7297
|
let collectionIndexDefinitions;
|
|
7262
7298
|
let collectionPath;
|
|
7263
7299
|
if (collection) {
|
|
@@ -7298,40 +7334,42 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7298
7334
|
normalizedPath,
|
|
7299
7335
|
collectionPath || ""
|
|
7300
7336
|
);
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
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
|
+
}
|
|
7335
7373
|
}
|
|
7336
7374
|
if (!isGitKeep(filepath, collection)) {
|
|
7337
7375
|
await enqueueOps([
|
|
@@ -7375,8 +7413,7 @@ var _indexContent = async (database, level, documentPaths, enqueueOps, collectio
|
|
|
7375
7413
|
throw new TinaFetchError(`Unable to seed ${filepath}`, {
|
|
7376
7414
|
originalError: error,
|
|
7377
7415
|
file: filepath,
|
|
7378
|
-
collection: collection?.name
|
|
7379
|
-
stack: error.stack
|
|
7416
|
+
collection: collection?.name
|
|
7380
7417
|
});
|
|
7381
7418
|
}
|
|
7382
7419
|
});
|
|
@@ -7567,8 +7604,8 @@ import path6 from "path";
|
|
|
7567
7604
|
import normalize from "normalize-path";
|
|
7568
7605
|
var FilesystemBridge = class {
|
|
7569
7606
|
constructor(rootPath, outputPath) {
|
|
7570
|
-
this.rootPath = rootPath
|
|
7571
|
-
this.outputPath = outputPath
|
|
7607
|
+
this.rootPath = path6.resolve(rootPath);
|
|
7608
|
+
this.outputPath = outputPath ? path6.resolve(outputPath) : this.rootPath;
|
|
7572
7609
|
}
|
|
7573
7610
|
async glob(pattern, extension) {
|
|
7574
7611
|
const basePath = path6.join(this.outputPath, ...pattern.split("/"));
|
|
@@ -7580,19 +7617,19 @@ var FilesystemBridge = class {
|
|
|
7580
7617
|
}
|
|
7581
7618
|
);
|
|
7582
7619
|
const posixRootPath = normalize(this.outputPath);
|
|
7583
|
-
return items.map(
|
|
7584
|
-
|
|
7585
|
-
|
|
7620
|
+
return items.map(
|
|
7621
|
+
(item) => item.substring(posixRootPath.length).replace(/^\/|\/$/g, "")
|
|
7622
|
+
);
|
|
7586
7623
|
}
|
|
7587
7624
|
async delete(filepath) {
|
|
7588
7625
|
await fs2.remove(path6.join(this.outputPath, filepath));
|
|
7589
7626
|
}
|
|
7590
7627
|
async get(filepath) {
|
|
7591
|
-
return fs2.
|
|
7628
|
+
return (await fs2.readFile(path6.join(this.outputPath, filepath))).toString();
|
|
7592
7629
|
}
|
|
7593
7630
|
async put(filepath, data, basePathOverride) {
|
|
7594
7631
|
const basePath = basePathOverride || this.outputPath;
|
|
7595
|
-
await fs2.
|
|
7632
|
+
await fs2.outputFile(path6.join(basePath, filepath), data);
|
|
7596
7633
|
}
|
|
7597
7634
|
};
|
|
7598
7635
|
var AuditFileSystemBridge = class extends FilesystemBridge {
|