@tinacms/graphql 0.0.0-202222211116 → 0.0.0-2022222183246
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/CHANGELOG.md +10 -0
- package/dist/database/index.d.ts +27 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +313 -175
- package/dist/resolver/filter-utils.d.ts +22 -0
- package/dist/resolver/index.d.ts +16 -9
- package/dist/spec/setup.d.ts +1 -1
- package/dist/types.d.ts +9 -0
- package/package.json +5 -5
- package/dist/database/store/index.d.ts +0 -72
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# tina-graphql
|
|
2
2
|
|
|
3
|
+
## 0.0.0-2022222183246
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e7b27ba3b: Fix issue where un-normalized rich-text fields which send `null` values to the server on save would cause a parsing error
|
|
8
|
+
- 11d55f441: Add experimental useGraphQLForms hook
|
|
9
|
+
- e8043d510: Enable query filtering, pagination, sorting
|
|
10
|
+
- Updated dependencies [e8043d510]
|
|
11
|
+
- @tinacms/datalayer@0.0.0-2022222183246
|
|
12
|
+
|
|
3
13
|
## 0.59.7
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/database/index.d.ts
CHANGED
|
@@ -10,21 +10,32 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
10
10
|
See the License for the specific language governing permissions and
|
|
11
11
|
limitations under the License.
|
|
12
12
|
*/
|
|
13
|
+
import type { BinaryFilter, IndexDefinition, Store, TernaryFilter } from '@tinacms/datalayer';
|
|
13
14
|
import type { DocumentNode } from 'graphql';
|
|
14
15
|
import type { TinaSchema } from '../schema';
|
|
15
|
-
import type { TinaCloudSchemaBase } from '../types';
|
|
16
|
-
import type { Store } from './store';
|
|
16
|
+
import type { TinaCloudSchemaBase, CollectionFieldsWithNamespace, CollectionTemplatesWithNamespace } from '../types';
|
|
17
17
|
import type { Bridge } from './bridge';
|
|
18
18
|
declare type CreateDatabase = {
|
|
19
19
|
bridge: Bridge;
|
|
20
20
|
store: Store;
|
|
21
21
|
};
|
|
22
22
|
export declare const createDatabase: (config: CreateDatabase) => Promise<Database>;
|
|
23
|
+
/** Options for {@link Database.query} **/
|
|
24
|
+
export declare type QueryOptions = {
|
|
25
|
+
collection: string;
|
|
26
|
+
filterChain?: (BinaryFilter | TernaryFilter)[];
|
|
27
|
+
sort?: string;
|
|
28
|
+
first?: number;
|
|
29
|
+
last?: number;
|
|
30
|
+
after?: string;
|
|
31
|
+
before?: string;
|
|
32
|
+
};
|
|
23
33
|
export declare class Database {
|
|
24
34
|
config: CreateDatabase;
|
|
25
35
|
bridge: Bridge;
|
|
26
36
|
store: Store;
|
|
27
37
|
private tinaSchema;
|
|
38
|
+
private collectionIndexDefinitions;
|
|
28
39
|
private _lookup;
|
|
29
40
|
private _graphql;
|
|
30
41
|
private _tinaSchema;
|
|
@@ -51,8 +62,20 @@ export declare class Database {
|
|
|
51
62
|
getGraphQLSchemaFromBridge: () => Promise<DocumentNode>;
|
|
52
63
|
getTinaSchema: () => Promise<TinaCloudSchemaBase>;
|
|
53
64
|
getSchema: () => Promise<TinaSchema>;
|
|
65
|
+
getIndexDefinitions: () => Promise<Record<string, Record<string, IndexDefinition>>>;
|
|
54
66
|
documentExists: (fullpath: unknown) => Promise<boolean>;
|
|
55
|
-
query: (
|
|
67
|
+
query: (queryOptions: QueryOptions, hydrator: any) => Promise<{
|
|
68
|
+
edges: {
|
|
69
|
+
node: any;
|
|
70
|
+
cursor: string;
|
|
71
|
+
}[];
|
|
72
|
+
pageInfo: {
|
|
73
|
+
hasPreviousPage: boolean;
|
|
74
|
+
hasNextPage: boolean;
|
|
75
|
+
startCursor: string;
|
|
76
|
+
endCursor: string;
|
|
77
|
+
};
|
|
78
|
+
}>;
|
|
56
79
|
putConfigFiles: ({ graphQLSchema, tinaSchema, }: {
|
|
57
80
|
graphQLSchema: DocumentNode;
|
|
58
81
|
tinaSchema: TinaSchema;
|
|
@@ -61,7 +84,7 @@ export declare class Database {
|
|
|
61
84
|
graphQLSchema: DocumentNode;
|
|
62
85
|
tinaSchema: TinaSchema;
|
|
63
86
|
}) => Promise<void>;
|
|
64
|
-
indexContentByPaths: (documentPaths: string[]) => Promise<void>;
|
|
87
|
+
indexContentByPaths: (documentPaths: string[], collection: CollectionFieldsWithNamespace<true> | CollectionTemplatesWithNamespace<true>) => Promise<void>;
|
|
65
88
|
_indexAllContent: () => Promise<void>;
|
|
66
89
|
addToLookupMap: (lookup: LookupMapType) => Promise<void>;
|
|
67
90
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,9 +13,10 @@ limitations under the License.
|
|
|
13
13
|
export { indexDB } from './build';
|
|
14
14
|
export { resolve } from './resolve';
|
|
15
15
|
export { createDatabase } from './database';
|
|
16
|
+
export type { QueryOptions } from './database';
|
|
16
17
|
import type { Database } from './database';
|
|
17
18
|
export type { Database } from './database';
|
|
18
|
-
export type { Store } from '
|
|
19
|
+
export type { Store } from '@tinacms/datalayer';
|
|
19
20
|
export type { Bridge } from './database/bridge';
|
|
20
21
|
export { sequential, assertShape } from './util';
|
|
21
22
|
export { stringifyFile, parseFile } from './database/util';
|
package/dist/index.js
CHANGED
|
@@ -11902,6 +11902,11 @@ var Builder = class {
|
|
|
11902
11902
|
astBuilder.InputValueDefinition({
|
|
11903
11903
|
name: "exists",
|
|
11904
11904
|
type: astBuilder.TYPES.Boolean
|
|
11905
|
+
}),
|
|
11906
|
+
astBuilder.InputValueDefinition({
|
|
11907
|
+
name: "in",
|
|
11908
|
+
type: astBuilder.TYPES.Number,
|
|
11909
|
+
list: true
|
|
11905
11910
|
})
|
|
11906
11911
|
]
|
|
11907
11912
|
})
|
|
@@ -11927,6 +11932,11 @@ var Builder = class {
|
|
|
11927
11932
|
astBuilder.InputValueDefinition({
|
|
11928
11933
|
name: "exists",
|
|
11929
11934
|
type: astBuilder.TYPES.Boolean
|
|
11935
|
+
}),
|
|
11936
|
+
astBuilder.InputValueDefinition({
|
|
11937
|
+
name: "in",
|
|
11938
|
+
type: astBuilder.TYPES.String,
|
|
11939
|
+
list: true
|
|
11930
11940
|
})
|
|
11931
11941
|
]
|
|
11932
11942
|
})
|
|
@@ -11949,6 +11959,11 @@ var Builder = class {
|
|
|
11949
11959
|
astBuilder.InputValueDefinition({
|
|
11950
11960
|
name: "exists",
|
|
11951
11961
|
type: astBuilder.TYPES.Boolean
|
|
11962
|
+
}),
|
|
11963
|
+
astBuilder.InputValueDefinition({
|
|
11964
|
+
name: "in",
|
|
11965
|
+
type: astBuilder.TYPES.String,
|
|
11966
|
+
list: true
|
|
11952
11967
|
})
|
|
11953
11968
|
]
|
|
11954
11969
|
})
|
|
@@ -12256,6 +12271,10 @@ var listArgs = [
|
|
|
12256
12271
|
astBuilder.InputValueDefinition({
|
|
12257
12272
|
name: "last",
|
|
12258
12273
|
type: astBuilder.TYPES.Number
|
|
12274
|
+
}),
|
|
12275
|
+
astBuilder.InputValueDefinition({
|
|
12276
|
+
name: "sort",
|
|
12277
|
+
type: astBuilder.TYPES.String
|
|
12259
12278
|
})
|
|
12260
12279
|
];
|
|
12261
12280
|
var filterSelections = (arr) => {
|
|
@@ -12416,6 +12435,7 @@ var scripts = {
|
|
|
12416
12435
|
};
|
|
12417
12436
|
var dependencies = {
|
|
12418
12437
|
"@graphql-tools/relay-operation-optimizer": "^6.4.1",
|
|
12438
|
+
"@tinacms/datalayer": "workspace:*",
|
|
12419
12439
|
"body-parser": "^1.19.0",
|
|
12420
12440
|
cors: "^2.8.5",
|
|
12421
12441
|
dataloader: "^2.0.0",
|
|
@@ -12431,6 +12451,7 @@ var dependencies = {
|
|
|
12431
12451
|
"graphql-type-json": "^0.3.2",
|
|
12432
12452
|
"gray-matter": "^4.0.2",
|
|
12433
12453
|
"js-yaml": "^3.14.0",
|
|
12454
|
+
leveldown: "^6.1.0",
|
|
12434
12455
|
lodash: "^4.17.20",
|
|
12435
12456
|
mdast: "^3.0.0",
|
|
12436
12457
|
"mdast-util-from-markdown": "^1.0.0",
|
|
@@ -12438,7 +12459,6 @@ var dependencies = {
|
|
|
12438
12459
|
"mdast-util-mdx-expression": "^1.1.0",
|
|
12439
12460
|
"mdast-util-to-markdown": "^1.2.1",
|
|
12440
12461
|
"micromark-extension-mdxjs": "^1.0.0",
|
|
12441
|
-
mocha: "^9.1.1",
|
|
12442
12462
|
"normalize-path": "^3.0.0",
|
|
12443
12463
|
prettier: "^2.2.1",
|
|
12444
12464
|
"rehype-format": "^3.1.0",
|
|
@@ -12473,7 +12493,6 @@ var devDependencies = {
|
|
|
12473
12493
|
"@types/fs-extra": "^9.0.2",
|
|
12474
12494
|
"@types/jest": "^26.0.4",
|
|
12475
12495
|
"@types/js-yaml": "^3.12.5",
|
|
12476
|
-
"@types/level": "^6.0.0",
|
|
12477
12496
|
"@types/lodash": "^4.14.161",
|
|
12478
12497
|
"@types/lodash.camelcase": "^4.3.6",
|
|
12479
12498
|
"@types/lodash.upperfirst": "^4.3.6",
|
|
@@ -21895,6 +21914,9 @@ var allChildrenEmpty = (children) => {
|
|
|
21895
21914
|
return false;
|
|
21896
21915
|
};
|
|
21897
21916
|
var stringifyChildren = (children, field) => {
|
|
21917
|
+
if (!children) {
|
|
21918
|
+
return [];
|
|
21919
|
+
}
|
|
21898
21920
|
return children.map((child) => stringify(child, field)).filter(Boolean);
|
|
21899
21921
|
};
|
|
21900
21922
|
var stringify = (node, field) => {
|
|
@@ -22270,7 +22292,102 @@ ${out}
|
|
|
22270
22292
|
};
|
|
22271
22293
|
|
|
22272
22294
|
// pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/index.ts
|
|
22273
|
-
var
|
|
22295
|
+
var import_datalayer = __toModule(require("@tinacms/datalayer"));
|
|
22296
|
+
|
|
22297
|
+
// pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/filter-utils.ts
|
|
22298
|
+
var resolveReferences = async (filter, fields, resolver2) => {
|
|
22299
|
+
for (const fieldKey of Object.keys(filter)) {
|
|
22300
|
+
const fieldDefinition = fields.find((f) => f.name === fieldKey);
|
|
22301
|
+
if (fieldDefinition) {
|
|
22302
|
+
if (fieldDefinition.type === "reference") {
|
|
22303
|
+
const { edges, values } = await resolver2(filter, fieldDefinition);
|
|
22304
|
+
if (edges.length === 1) {
|
|
22305
|
+
filter[fieldKey] = {
|
|
22306
|
+
eq: values[0]
|
|
22307
|
+
};
|
|
22308
|
+
} else if (edges.length > 1) {
|
|
22309
|
+
filter[fieldKey] = {
|
|
22310
|
+
in: values
|
|
22311
|
+
};
|
|
22312
|
+
} else {
|
|
22313
|
+
filter[fieldKey] = {
|
|
22314
|
+
eq: "___null___"
|
|
22315
|
+
};
|
|
22316
|
+
}
|
|
22317
|
+
} else if (fieldDefinition.type === "object") {
|
|
22318
|
+
if (fieldDefinition.templates) {
|
|
22319
|
+
const globalTemplates = {};
|
|
22320
|
+
for (const template of fieldDefinition.templates) {
|
|
22321
|
+
if (typeof template === "string") {
|
|
22322
|
+
globalTemplates[template] = 1;
|
|
22323
|
+
}
|
|
22324
|
+
}
|
|
22325
|
+
for (const templateName of Object.keys(filter[fieldKey])) {
|
|
22326
|
+
if (templateName in globalTemplates) {
|
|
22327
|
+
throw new Error("Global templates not yet supported for queries");
|
|
22328
|
+
}
|
|
22329
|
+
const template = fieldDefinition.templates.find((template2) => !(typeof template2 === "string") && template2.name === templateName);
|
|
22330
|
+
if (template) {
|
|
22331
|
+
await resolveReferences(filter[fieldKey][templateName], template.fields, resolver2);
|
|
22332
|
+
} else {
|
|
22333
|
+
throw new Error(`Template ${templateName} not found`);
|
|
22334
|
+
}
|
|
22335
|
+
}
|
|
22336
|
+
} else {
|
|
22337
|
+
await resolveReferences(filter[fieldKey], fieldDefinition.fields, resolver2);
|
|
22338
|
+
}
|
|
22339
|
+
}
|
|
22340
|
+
} else {
|
|
22341
|
+
throw new Error(`Unable to find field ${fieldKey}`);
|
|
22342
|
+
}
|
|
22343
|
+
}
|
|
22344
|
+
};
|
|
22345
|
+
var collectConditionsForChildFields = (filterNode, fields, pathExpression, collectCondition) => {
|
|
22346
|
+
for (const childFieldName of Object.keys(filterNode)) {
|
|
22347
|
+
const childField = fields.find((field) => field.name === childFieldName);
|
|
22348
|
+
if (!childField) {
|
|
22349
|
+
throw new Error(`Unable to find type for field ${childFieldName}`);
|
|
22350
|
+
}
|
|
22351
|
+
collectConditionsForField(childFieldName, childField, filterNode[childFieldName], pathExpression, collectCondition);
|
|
22352
|
+
}
|
|
22353
|
+
};
|
|
22354
|
+
var collectConditionsForObjectField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
22355
|
+
if (field.list && field.templates) {
|
|
22356
|
+
const globalTemplates = {};
|
|
22357
|
+
for (const template of field.templates) {
|
|
22358
|
+
if (typeof template === "string") {
|
|
22359
|
+
globalTemplates[template] = 1;
|
|
22360
|
+
}
|
|
22361
|
+
}
|
|
22362
|
+
for (const [filterKey, childFilterNode] of Object.entries(filterNode)) {
|
|
22363
|
+
if (filterKey in globalTemplates) {
|
|
22364
|
+
throw new Error("Global templates not yet supported for queries");
|
|
22365
|
+
}
|
|
22366
|
+
const template = field.templates.find((template2) => !(typeof template2 === "string") && template2.name === filterKey);
|
|
22367
|
+
const jsonPath = `${fieldName}[?(@._template=="${filterKey}")]`;
|
|
22368
|
+
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : jsonPath;
|
|
22369
|
+
collectConditionsForChildFields(childFilterNode, template.fields, filterPath, collectCondition);
|
|
22370
|
+
}
|
|
22371
|
+
} else {
|
|
22372
|
+
const jsonPath = `${fieldName}${field.list ? "[*]" : ""}`;
|
|
22373
|
+
const filterPath = pathExpression ? `${pathExpression}.${jsonPath}` : `${jsonPath}`;
|
|
22374
|
+
collectConditionsForChildFields(filterNode, field.fields, filterPath, collectCondition);
|
|
22375
|
+
}
|
|
22376
|
+
};
|
|
22377
|
+
var collectConditionsForField = (fieldName, field, filterNode, pathExpression, collectCondition) => {
|
|
22378
|
+
if (field.type === "object") {
|
|
22379
|
+
collectConditionsForObjectField(fieldName, field, filterNode, pathExpression, collectCondition);
|
|
22380
|
+
} else {
|
|
22381
|
+
collectCondition({
|
|
22382
|
+
filterPath: pathExpression ? `${pathExpression}.${fieldName}` : fieldName,
|
|
22383
|
+
filterExpression: __spreadValues({
|
|
22384
|
+
_type: field.type
|
|
22385
|
+
}, filterNode)
|
|
22386
|
+
});
|
|
22387
|
+
}
|
|
22388
|
+
};
|
|
22389
|
+
|
|
22390
|
+
// pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/resolver/index.ts
|
|
22274
22391
|
var createResolver2 = (args) => {
|
|
22275
22392
|
return new Resolver(args);
|
|
22276
22393
|
};
|
|
@@ -22568,46 +22685,76 @@ var Resolver = class {
|
|
|
22568
22685
|
const collection = this.tinaSchema.getCollection(collectionName);
|
|
22569
22686
|
return this.database.store.glob(collection.path, this.getDocument);
|
|
22570
22687
|
};
|
|
22688
|
+
this.referenceResolver = async (filter, fieldDefinition) => {
|
|
22689
|
+
const referencedCollection = this.tinaSchema.getCollection(fieldDefinition.collections[0]);
|
|
22690
|
+
if (!referencedCollection) {
|
|
22691
|
+
throw new Error(`Unable to find collection for ${fieldDefinition.collections[0]} querying ${fieldDefinition.name}`);
|
|
22692
|
+
}
|
|
22693
|
+
const sortKeys = Object.keys(filter[fieldDefinition.name][referencedCollection.name]);
|
|
22694
|
+
const resolvedCollectionConnection = await this.resolveCollectionConnection({
|
|
22695
|
+
args: {
|
|
22696
|
+
sort: sortKeys.length === 1 ? sortKeys[0] : void 0,
|
|
22697
|
+
filter: __spreadValues({}, filter[fieldDefinition.name][referencedCollection.name]),
|
|
22698
|
+
first: -1
|
|
22699
|
+
},
|
|
22700
|
+
collection: referencedCollection,
|
|
22701
|
+
hydrator: (path6) => path6
|
|
22702
|
+
});
|
|
22703
|
+
const { edges } = resolvedCollectionConnection;
|
|
22704
|
+
const values = edges.map((edge) => edge.node);
|
|
22705
|
+
return { edges, values };
|
|
22706
|
+
};
|
|
22571
22707
|
this.resolveCollectionConnection = async ({
|
|
22572
22708
|
args,
|
|
22573
|
-
|
|
22709
|
+
collection,
|
|
22710
|
+
hydrator
|
|
22574
22711
|
}) => {
|
|
22575
|
-
let
|
|
22576
|
-
|
|
22577
|
-
|
|
22578
|
-
|
|
22579
|
-
|
|
22580
|
-
|
|
22581
|
-
|
|
22582
|
-
|
|
22583
|
-
|
|
22584
|
-
|
|
22585
|
-
|
|
22586
|
-
|
|
22587
|
-
|
|
22588
|
-
throw new Error(
|
|
22712
|
+
let edges;
|
|
22713
|
+
let pageInfo;
|
|
22714
|
+
if (args.filter || args.sort) {
|
|
22715
|
+
let conditions;
|
|
22716
|
+
if (args.filter) {
|
|
22717
|
+
if (collection.fields) {
|
|
22718
|
+
conditions = await this.resolveFilterConditions(args.filter, collection.fields, collection.name);
|
|
22719
|
+
} else if (collection.templates) {
|
|
22720
|
+
for (const templateName of Object.keys(args.filter)) {
|
|
22721
|
+
const template = collection.templates.find((template2) => template2.name === templateName);
|
|
22722
|
+
if (template) {
|
|
22723
|
+
conditions = await this.resolveFilterConditions(args.filter[templateName], template.fields, `${collection.name}.${templateName}`);
|
|
22724
|
+
} else {
|
|
22725
|
+
throw new Error(`Error template not found: ${templateName} in collection ${collection.name}`);
|
|
22589
22726
|
}
|
|
22590
|
-
return template2.name === maybeTemplateName;
|
|
22591
|
-
});
|
|
22592
|
-
if (typeof template === "string") {
|
|
22593
|
-
throw new Error("Global templates not yet supported for queries");
|
|
22594
|
-
}
|
|
22595
|
-
if (template) {
|
|
22596
|
-
templateName = template.name;
|
|
22597
22727
|
}
|
|
22598
22728
|
}
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22729
|
+
}
|
|
22730
|
+
const queryOptions = {
|
|
22731
|
+
filterChain: (0, import_datalayer.makeFilterChain)({
|
|
22732
|
+
conditions: conditions || []
|
|
22733
|
+
}),
|
|
22734
|
+
collection: collection.name,
|
|
22735
|
+
sort: args.sort,
|
|
22736
|
+
first: args.first,
|
|
22737
|
+
last: args.last,
|
|
22738
|
+
before: args.before,
|
|
22739
|
+
after: args.after
|
|
22740
|
+
};
|
|
22741
|
+
const result = await this.database.query(queryOptions, hydrator ? hydrator : this.getDocument);
|
|
22742
|
+
edges = result.edges;
|
|
22743
|
+
pageInfo = result.pageInfo;
|
|
22602
22744
|
} else {
|
|
22603
|
-
|
|
22604
|
-
|
|
22745
|
+
edges = (await this.database.store.glob(collection.path, this.getDocument)).map((document3) => ({
|
|
22746
|
+
node: document3
|
|
22747
|
+
}));
|
|
22605
22748
|
}
|
|
22606
22749
|
return {
|
|
22607
|
-
totalCount:
|
|
22608
|
-
edges
|
|
22609
|
-
|
|
22610
|
-
|
|
22750
|
+
totalCount: edges.length,
|
|
22751
|
+
edges,
|
|
22752
|
+
pageInfo: pageInfo || {
|
|
22753
|
+
hasPreviousPage: false,
|
|
22754
|
+
hasNextPage: false,
|
|
22755
|
+
startCursor: "",
|
|
22756
|
+
endCursor: ""
|
|
22757
|
+
}
|
|
22611
22758
|
};
|
|
22612
22759
|
};
|
|
22613
22760
|
this.buildFieldMutations = (fieldParams, template) => {
|
|
@@ -22868,6 +23015,27 @@ var Resolver = class {
|
|
|
22868
23015
|
this.database = init.database;
|
|
22869
23016
|
this.tinaSchema = init.tinaSchema;
|
|
22870
23017
|
}
|
|
23018
|
+
async resolveFilterConditions(filter, fields, collectionName) {
|
|
23019
|
+
const conditions = [];
|
|
23020
|
+
const conditionCollector = (condition) => {
|
|
23021
|
+
if (!condition.filterPath) {
|
|
23022
|
+
throw new Error("Error parsing filter - unable to generate filterPath");
|
|
23023
|
+
}
|
|
23024
|
+
if (!condition.filterExpression) {
|
|
23025
|
+
throw new Error(`Error parsing filter - missing expression for ${condition.filterPath}`);
|
|
23026
|
+
}
|
|
23027
|
+
conditions.push(condition);
|
|
23028
|
+
};
|
|
23029
|
+
await resolveReferences(filter, fields, this.referenceResolver);
|
|
23030
|
+
for (const fieldName of Object.keys(filter)) {
|
|
23031
|
+
const field = fields.find((field2) => field2.name === fieldName);
|
|
23032
|
+
if (!field) {
|
|
23033
|
+
throw new Error(`${fieldName} not found in collection ${collectionName}`);
|
|
23034
|
+
}
|
|
23035
|
+
collectConditionsForField(fieldName, field, filter[fieldName], "", conditionCollector);
|
|
23036
|
+
}
|
|
23037
|
+
return conditions;
|
|
23038
|
+
}
|
|
22871
23039
|
};
|
|
22872
23040
|
var resolveDateInput = (value) => {
|
|
22873
23041
|
const date = new Date(value);
|
|
@@ -23066,7 +23234,7 @@ var resolve = async ({
|
|
|
23066
23234
|
}
|
|
23067
23235
|
return result;
|
|
23068
23236
|
case "collectionDocumentList":
|
|
23069
|
-
return resolver2.resolveCollectionConnection({ args, lookup });
|
|
23237
|
+
return resolver2.resolveCollectionConnection({ args, collection: tinaSchema.getCollection(lookup.collection) });
|
|
23070
23238
|
case "unionData":
|
|
23071
23239
|
return value;
|
|
23072
23240
|
default:
|
|
@@ -23375,7 +23543,7 @@ var parseFile = (content3, format, yupSchema) => {
|
|
|
23375
23543
|
};
|
|
23376
23544
|
|
|
23377
23545
|
// pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/database/index.ts
|
|
23378
|
-
var
|
|
23546
|
+
var import_datalayer2 = __toModule(require("@tinacms/datalayer"));
|
|
23379
23547
|
var createDatabase = async (config) => {
|
|
23380
23548
|
return new Database(__spreadProps(__spreadValues({}, config), {
|
|
23381
23549
|
bridge: config.bridge,
|
|
@@ -23429,7 +23597,7 @@ var Database = class {
|
|
|
23429
23597
|
if (this.store.supportsSeeding()) {
|
|
23430
23598
|
await this.bridge.put(filepath, stringifiedFile);
|
|
23431
23599
|
}
|
|
23432
|
-
await this.store.put(filepath, payload, keepTemplateKey);
|
|
23600
|
+
await this.store.put(filepath, payload, { keepTemplateKey });
|
|
23433
23601
|
};
|
|
23434
23602
|
this.put = async (filepath, data) => {
|
|
23435
23603
|
if (SYSTEM_FILES.includes(filepath)) {
|
|
@@ -23439,14 +23607,7 @@ var Database = class {
|
|
|
23439
23607
|
if (this.store.supportsSeeding()) {
|
|
23440
23608
|
await this.bridge.put(filepath, stringifiedFile);
|
|
23441
23609
|
}
|
|
23442
|
-
|
|
23443
|
-
await indexDocument({
|
|
23444
|
-
filepath,
|
|
23445
|
-
data,
|
|
23446
|
-
database: this
|
|
23447
|
-
});
|
|
23448
|
-
}
|
|
23449
|
-
await this.store.put(filepath, payload, keepTemplateKey);
|
|
23610
|
+
await this.store.put(filepath, payload, { keepTemplateKey });
|
|
23450
23611
|
}
|
|
23451
23612
|
return true;
|
|
23452
23613
|
};
|
|
@@ -23533,6 +23694,55 @@ var Database = class {
|
|
|
23533
23694
|
this.tinaSchema = await createSchema({ schema });
|
|
23534
23695
|
return this.tinaSchema;
|
|
23535
23696
|
};
|
|
23697
|
+
this.getIndexDefinitions = async () => {
|
|
23698
|
+
if (!this.collectionIndexDefinitions) {
|
|
23699
|
+
await new Promise(async (resolve2, reject) => {
|
|
23700
|
+
try {
|
|
23701
|
+
const schema = await this.getSchema();
|
|
23702
|
+
const collections = schema.getCollections();
|
|
23703
|
+
for (const collection of collections) {
|
|
23704
|
+
const indexDefinitions = {
|
|
23705
|
+
[import_datalayer2.DEFAULT_COLLECTION_SORT_KEY]: { fields: [] }
|
|
23706
|
+
};
|
|
23707
|
+
if (collection.fields) {
|
|
23708
|
+
for (const field of collection.fields) {
|
|
23709
|
+
if (field.indexed !== void 0 && field.indexed === false || field.type === "object") {
|
|
23710
|
+
continue;
|
|
23711
|
+
}
|
|
23712
|
+
indexDefinitions[field.name] = {
|
|
23713
|
+
fields: [
|
|
23714
|
+
{
|
|
23715
|
+
name: field.name,
|
|
23716
|
+
type: field.type
|
|
23717
|
+
}
|
|
23718
|
+
]
|
|
23719
|
+
};
|
|
23720
|
+
}
|
|
23721
|
+
}
|
|
23722
|
+
if (collection.indexes) {
|
|
23723
|
+
for (const index2 of collection.indexes) {
|
|
23724
|
+
indexDefinitions[index2.name] = {
|
|
23725
|
+
fields: index2.fields.map((indexField) => {
|
|
23726
|
+
var _a;
|
|
23727
|
+
return {
|
|
23728
|
+
name: indexField.name,
|
|
23729
|
+
type: (_a = collection.fields.find((field) => indexField.name === field.name)) == null ? void 0 : _a.type
|
|
23730
|
+
};
|
|
23731
|
+
})
|
|
23732
|
+
};
|
|
23733
|
+
}
|
|
23734
|
+
}
|
|
23735
|
+
this.collectionIndexDefinitions = this.collectionIndexDefinitions || {};
|
|
23736
|
+
this.collectionIndexDefinitions[collection.name] = indexDefinitions;
|
|
23737
|
+
}
|
|
23738
|
+
resolve2();
|
|
23739
|
+
} catch (err) {
|
|
23740
|
+
reject(err);
|
|
23741
|
+
}
|
|
23742
|
+
});
|
|
23743
|
+
}
|
|
23744
|
+
return this.collectionIndexDefinitions;
|
|
23745
|
+
};
|
|
23536
23746
|
this.documentExists = async (fullpath) => {
|
|
23537
23747
|
try {
|
|
23538
23748
|
await this.get(fullpath);
|
|
@@ -23541,8 +23751,50 @@ var Database = class {
|
|
|
23541
23751
|
}
|
|
23542
23752
|
return true;
|
|
23543
23753
|
};
|
|
23544
|
-
this.query = async (
|
|
23545
|
-
|
|
23754
|
+
this.query = async (queryOptions, hydrator) => {
|
|
23755
|
+
const { first, after, last, before, sort, collection, filterChain } = queryOptions;
|
|
23756
|
+
const storeQueryOptions = { sort, collection, filterChain };
|
|
23757
|
+
if (first) {
|
|
23758
|
+
storeQueryOptions.limit = first;
|
|
23759
|
+
} else if (last) {
|
|
23760
|
+
storeQueryOptions.limit = last;
|
|
23761
|
+
} else {
|
|
23762
|
+
storeQueryOptions.limit = 10;
|
|
23763
|
+
}
|
|
23764
|
+
if (after) {
|
|
23765
|
+
storeQueryOptions.gt = (0, import_datalayer2.atob)(after);
|
|
23766
|
+
} else if (before) {
|
|
23767
|
+
storeQueryOptions.lt = (0, import_datalayer2.atob)(before);
|
|
23768
|
+
}
|
|
23769
|
+
if (last) {
|
|
23770
|
+
storeQueryOptions.reverse = true;
|
|
23771
|
+
}
|
|
23772
|
+
const indexDefinitions = await this.getIndexDefinitions();
|
|
23773
|
+
storeQueryOptions.indexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[queryOptions.collection];
|
|
23774
|
+
if (!storeQueryOptions.indexDefinitions) {
|
|
23775
|
+
throw new Error(`No indexDefinitions for collection ${queryOptions.collection}`);
|
|
23776
|
+
}
|
|
23777
|
+
const { edges, pageInfo: {
|
|
23778
|
+
hasPreviousPage,
|
|
23779
|
+
hasNextPage,
|
|
23780
|
+
startCursor,
|
|
23781
|
+
endCursor
|
|
23782
|
+
} } = await this.store.query(storeQueryOptions);
|
|
23783
|
+
return {
|
|
23784
|
+
edges: await sequential(edges, async (edge) => {
|
|
23785
|
+
const node = await hydrator(edge.path);
|
|
23786
|
+
return {
|
|
23787
|
+
node,
|
|
23788
|
+
cursor: (0, import_datalayer2.btoa)(edge.cursor)
|
|
23789
|
+
};
|
|
23790
|
+
}),
|
|
23791
|
+
pageInfo: {
|
|
23792
|
+
hasPreviousPage,
|
|
23793
|
+
hasNextPage,
|
|
23794
|
+
startCursor: (0, import_datalayer2.btoa)(startCursor),
|
|
23795
|
+
endCursor: (0, import_datalayer2.btoa)(endCursor)
|
|
23796
|
+
}
|
|
23797
|
+
};
|
|
23546
23798
|
};
|
|
23547
23799
|
this.putConfigFiles = async ({
|
|
23548
23800
|
graphQLSchema,
|
|
@@ -23570,14 +23822,14 @@ var Database = class {
|
|
|
23570
23822
|
}
|
|
23571
23823
|
}
|
|
23572
23824
|
};
|
|
23573
|
-
this.indexContentByPaths = async (documentPaths) => {
|
|
23574
|
-
await _indexContent(this, documentPaths);
|
|
23825
|
+
this.indexContentByPaths = async (documentPaths, collection) => {
|
|
23826
|
+
await _indexContent(this, documentPaths, collection);
|
|
23575
23827
|
};
|
|
23576
23828
|
this._indexAllContent = async () => {
|
|
23577
23829
|
const tinaSchema = await this.getSchema();
|
|
23578
23830
|
await sequential(tinaSchema.getCollections(), async (collection) => {
|
|
23579
23831
|
const documentPaths = await this.bridge.glob(collection.path);
|
|
23580
|
-
await _indexContent(this, documentPaths);
|
|
23832
|
+
await _indexContent(this, documentPaths, collection);
|
|
23581
23833
|
});
|
|
23582
23834
|
};
|
|
23583
23835
|
this.addToLookupMap = async (lookup) => {
|
|
@@ -23600,138 +23852,24 @@ var Database = class {
|
|
|
23600
23852
|
function hasOwnProperty2(obj, prop) {
|
|
23601
23853
|
return obj.hasOwnProperty(prop);
|
|
23602
23854
|
}
|
|
23603
|
-
var _indexContent = async (database, documentPaths) => {
|
|
23855
|
+
var _indexContent = async (database, documentPaths, collection) => {
|
|
23856
|
+
const indexDefinitions = await database.getIndexDefinitions();
|
|
23857
|
+
const collectionIndexDefinitions = indexDefinitions == null ? void 0 : indexDefinitions[collection.name];
|
|
23858
|
+
if (!collectionIndexDefinitions) {
|
|
23859
|
+
throw new Error(`No indexDefinitions for collection ${collection.name}`);
|
|
23860
|
+
}
|
|
23861
|
+
const numIndexes = Object.keys(collectionIndexDefinitions).length;
|
|
23862
|
+
if (numIndexes > 20) {
|
|
23863
|
+
throw new Error(`A maximum of 20 indexes are allowed per field. Currently collection ${collection.name} has ${numIndexes} indexes. Add 'indexed: false' to exclude a field from indexing.`);
|
|
23864
|
+
}
|
|
23604
23865
|
await sequential(documentPaths, async (filepath) => {
|
|
23605
23866
|
const dataString = await database.bridge.get(filepath);
|
|
23606
23867
|
const data = parseFile(dataString, import_path4.default.extname(filepath), (yup3) => yup3.object({}));
|
|
23607
23868
|
if (database.store.supportsSeeding()) {
|
|
23608
|
-
await database.store.seed(filepath, data);
|
|
23609
|
-
}
|
|
23610
|
-
if (database.store.supportsIndexing()) {
|
|
23611
|
-
return indexDocument({ filepath, data, database });
|
|
23612
|
-
}
|
|
23613
|
-
});
|
|
23614
|
-
};
|
|
23615
|
-
var indexDocument = async ({
|
|
23616
|
-
filepath,
|
|
23617
|
-
data,
|
|
23618
|
-
database
|
|
23619
|
-
}) => {
|
|
23620
|
-
var _a;
|
|
23621
|
-
const schema = await database.getSchema();
|
|
23622
|
-
const collection = await schema.getCollectionByFullPath(filepath);
|
|
23623
|
-
let existingData;
|
|
23624
|
-
try {
|
|
23625
|
-
existingData = await database.get(filepath);
|
|
23626
|
-
} catch (err) {
|
|
23627
|
-
if (((_a = err.extensions) == null ? void 0 : _a["status"]) !== 404) {
|
|
23628
|
-
throw err;
|
|
23629
|
-
}
|
|
23630
|
-
}
|
|
23631
|
-
if (existingData) {
|
|
23632
|
-
const attributesToFilterOut = await _indexCollectable({
|
|
23633
|
-
record: filepath,
|
|
23634
|
-
value: existingData,
|
|
23635
|
-
field: collection,
|
|
23636
|
-
prefix: collection.name,
|
|
23637
|
-
database
|
|
23638
|
-
});
|
|
23639
|
-
await sequential(attributesToFilterOut, async (attribute) => {
|
|
23640
|
-
const records = await database.store.get(attribute) || [];
|
|
23641
|
-
await database.store.put(attribute, records.filter((item) => item !== filepath));
|
|
23642
|
-
return true;
|
|
23643
|
-
});
|
|
23644
|
-
}
|
|
23645
|
-
const attributes = await _indexCollectable({
|
|
23646
|
-
record: filepath,
|
|
23647
|
-
field: collection,
|
|
23648
|
-
value: data,
|
|
23649
|
-
prefix: `${lastItem(collection.namespace)}`,
|
|
23650
|
-
database
|
|
23651
|
-
});
|
|
23652
|
-
await sequential(attributes, async (fieldName) => {
|
|
23653
|
-
const existingRecords = await database.store.get(fieldName) || [];
|
|
23654
|
-
const uniqueItems = [...new Set([...existingRecords, filepath])];
|
|
23655
|
-
await database.store.put(fieldName, uniqueItems);
|
|
23656
|
-
});
|
|
23657
|
-
};
|
|
23658
|
-
var _indexCollectable = async (_a) => {
|
|
23659
|
-
var _b = _a, {
|
|
23660
|
-
field,
|
|
23661
|
-
value
|
|
23662
|
-
} = _b, rest = __objRest(_b, [
|
|
23663
|
-
"field",
|
|
23664
|
-
"value"
|
|
23665
|
-
]);
|
|
23666
|
-
let template;
|
|
23667
|
-
let extra = "";
|
|
23668
|
-
if (field.templates) {
|
|
23669
|
-
template = field.templates.find((t) => {
|
|
23670
|
-
if (typeof t === "string") {
|
|
23671
|
-
throw new Error(`Global templates not yet supported`);
|
|
23672
|
-
}
|
|
23673
|
-
if (hasOwnProperty2(value, "_template")) {
|
|
23674
|
-
return t.name === value._template;
|
|
23675
|
-
} else {
|
|
23676
|
-
throw new Error(`Expected value for collectable with multiple templates to have property _template`);
|
|
23677
|
-
}
|
|
23678
|
-
});
|
|
23679
|
-
extra = `#${lastItem(template.namespace)}`;
|
|
23680
|
-
} else {
|
|
23681
|
-
template = field;
|
|
23682
|
-
}
|
|
23683
|
-
const atts = await _indexAttributes({
|
|
23684
|
-
record: rest.record,
|
|
23685
|
-
data: value,
|
|
23686
|
-
prefix: `${rest.prefix}${extra}#${template.name}`,
|
|
23687
|
-
fields: template.fields,
|
|
23688
|
-
database: rest.database
|
|
23689
|
-
});
|
|
23690
|
-
return (0, import_lodash7.flatten)(atts).filter((item) => !(0, import_lodash7.isBoolean)(item));
|
|
23691
|
-
};
|
|
23692
|
-
var _indexAttributes = async (_a) => {
|
|
23693
|
-
var _b = _a, {
|
|
23694
|
-
data,
|
|
23695
|
-
fields
|
|
23696
|
-
} = _b, rest = __objRest(_b, [
|
|
23697
|
-
"data",
|
|
23698
|
-
"fields"
|
|
23699
|
-
]);
|
|
23700
|
-
return sequential(fields, async (field) => {
|
|
23701
|
-
const value = data[field.name];
|
|
23702
|
-
if (!value) {
|
|
23703
|
-
return true;
|
|
23869
|
+
await database.store.seed(filepath, data, { collection: collection.name, indexDefinitions: collectionIndexDefinitions });
|
|
23704
23870
|
}
|
|
23705
|
-
switch (field.type) {
|
|
23706
|
-
case "boolean":
|
|
23707
|
-
case "string":
|
|
23708
|
-
case "number":
|
|
23709
|
-
case "datetime":
|
|
23710
|
-
return _indexAttribute(__spreadValues({ value, field }, rest));
|
|
23711
|
-
case "object":
|
|
23712
|
-
if (field.list) {
|
|
23713
|
-
await sequential(value, async (item) => {
|
|
23714
|
-
return _indexCollectable(__spreadValues({ field, value: item }, rest));
|
|
23715
|
-
});
|
|
23716
|
-
} else {
|
|
23717
|
-
return _indexCollectable(__spreadValues({ field, value }, rest));
|
|
23718
|
-
}
|
|
23719
|
-
return true;
|
|
23720
|
-
case "reference":
|
|
23721
|
-
return _indexAttribute(__spreadValues({ value, field }, rest));
|
|
23722
|
-
}
|
|
23723
|
-
return true;
|
|
23724
23871
|
});
|
|
23725
23872
|
};
|
|
23726
|
-
var _indexAttribute = async ({
|
|
23727
|
-
value,
|
|
23728
|
-
prefix,
|
|
23729
|
-
field
|
|
23730
|
-
}) => {
|
|
23731
|
-
const stringValue = value.toString().substr(0, 100);
|
|
23732
|
-
const fieldName = `__attribute__${prefix}#${field.name}#${stringValue}`;
|
|
23733
|
-
return fieldName;
|
|
23734
|
-
};
|
|
23735
23873
|
|
|
23736
23874
|
// pnp:/home/runner/work/tinacms/tinacms/packages/@tinacms/graphql/src/index.ts
|
|
23737
23875
|
var buildSchema = async (rootPath, database) => {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright 2021 Forestry.io Holdings, Inc.
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
See the License for the specific language governing permissions and
|
|
11
|
+
limitations under the License.
|
|
12
|
+
*/
|
|
13
|
+
import { ReferenceTypeInner, TinaFieldInner } from '../types';
|
|
14
|
+
import type { FilterCondition } from '@tinacms/datalayer';
|
|
15
|
+
export declare type ReferenceResolver = (filter: Record<string, object>, fieldDefinition: ReferenceTypeInner) => Promise<{
|
|
16
|
+
edges: {
|
|
17
|
+
node: any;
|
|
18
|
+
}[];
|
|
19
|
+
values: any[];
|
|
20
|
+
}>;
|
|
21
|
+
export declare const resolveReferences: (filter: any, fields: TinaFieldInner<false>[], resolver: ReferenceResolver) => Promise<void>;
|
|
22
|
+
export declare const collectConditionsForField: (fieldName: string, field: TinaFieldInner<false>, filterNode: Record<string, object>, pathExpression: string, collectCondition: (condition: FilterCondition) => void) => void;
|
package/dist/resolver/index.d.ts
CHANGED
|
@@ -11,8 +11,9 @@ See the License for the specific language governing permissions and
|
|
|
11
11
|
limitations under the License.
|
|
12
12
|
*/
|
|
13
13
|
import { TinaSchema } from '../schema';
|
|
14
|
-
import { Database
|
|
15
|
-
import type { Collectable, TinaCloudCollection } from '../types';
|
|
14
|
+
import { Database } from '../database';
|
|
15
|
+
import type { Collectable, ReferenceTypeWithNamespace, TinaCloudCollection } from '../types';
|
|
16
|
+
import { TinaFieldInner } from '../types';
|
|
16
17
|
interface ResolverConfig {
|
|
17
18
|
database: Database;
|
|
18
19
|
tinaSchema: TinaSchema;
|
|
@@ -28,32 +29,34 @@ export declare class Resolver {
|
|
|
28
29
|
tinaSchema: TinaSchema;
|
|
29
30
|
constructor(init: ResolverConfig);
|
|
30
31
|
resolveCollection: (collectionName: string, hasDocuments?: boolean) => Promise<{
|
|
31
|
-
fields: string |
|
|
32
|
+
fields: string | TinaFieldInner<true>[];
|
|
32
33
|
templates?: undefined;
|
|
33
|
-
references?:
|
|
34
|
+
references?: ReferenceTypeWithNamespace[];
|
|
34
35
|
namespace: string[];
|
|
35
36
|
label?: string;
|
|
36
37
|
name: string;
|
|
37
38
|
path: string;
|
|
38
39
|
format?: "json" | "md" | "markdown" | "mdx";
|
|
39
40
|
match?: string;
|
|
41
|
+
indexes?: import("../types").TinaIndex[];
|
|
40
42
|
documents: {};
|
|
41
43
|
} | {
|
|
42
44
|
templates: (string | {
|
|
43
45
|
label: string;
|
|
44
46
|
name: string;
|
|
45
|
-
fields:
|
|
47
|
+
fields: TinaFieldInner<true>[];
|
|
46
48
|
ui?: object;
|
|
47
49
|
namespace: string[];
|
|
48
50
|
})[];
|
|
49
51
|
fields?: undefined;
|
|
50
|
-
references?:
|
|
52
|
+
references?: ReferenceTypeWithNamespace[];
|
|
51
53
|
namespace: string[];
|
|
52
54
|
label?: string;
|
|
53
55
|
name: string;
|
|
54
56
|
path: string;
|
|
55
57
|
format?: "json" | "md" | "markdown" | "mdx";
|
|
56
58
|
match?: string;
|
|
59
|
+
indexes?: import("../types").TinaIndex[];
|
|
57
60
|
documents: {};
|
|
58
61
|
}>;
|
|
59
62
|
getDocument: (fullPath: unknown) => Promise<{
|
|
@@ -243,12 +246,16 @@ export declare class Resolver {
|
|
|
243
246
|
}[];
|
|
244
247
|
}>;
|
|
245
248
|
getDocumentsForCollection: (collectionName: string) => Promise<string[]>;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
private referenceResolver;
|
|
250
|
+
private resolveFilterConditions;
|
|
251
|
+
resolveCollectionConnection: ({ args, collection, hydrator, }: {
|
|
252
|
+
args: Record<string, Record<string, object> | string | number>;
|
|
253
|
+
collection: TinaCloudCollection<true>;
|
|
254
|
+
hydrator?: (string: any) => any;
|
|
249
255
|
}) => Promise<{
|
|
250
256
|
totalCount: any;
|
|
251
257
|
edges: any;
|
|
258
|
+
pageInfo: any;
|
|
252
259
|
}>;
|
|
253
260
|
private buildFieldMutations;
|
|
254
261
|
private resolveFieldData;
|
package/dist/spec/setup.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
|
|
|
11
11
|
limitations under the License.
|
|
12
12
|
*/
|
|
13
13
|
import { Database } from '../database';
|
|
14
|
-
import type { Store } from '
|
|
14
|
+
import type { Store } from '@tinacms/datalayer';
|
|
15
15
|
import type { TinaCloudSchema } from '../types';
|
|
16
16
|
export declare const setup: (rootPath: string, schema: TinaCloudSchema<false>, store: Store) => Promise<{
|
|
17
17
|
database: Database;
|
package/dist/types.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ interface BaseCollection {
|
|
|
36
36
|
path: string;
|
|
37
37
|
format?: FormatType;
|
|
38
38
|
match?: string;
|
|
39
|
+
indexes?: TinaIndex[];
|
|
39
40
|
}
|
|
40
41
|
declare type CollectionTemplates<WithNamespace extends boolean> = WithNamespace extends true ? CollectionTemplatesWithNamespace<WithNamespace> : CollectionTemplatesInner<WithNamespace>;
|
|
41
42
|
interface CollectionTemplatesInner<WithNamespace extends boolean> extends BaseCollection {
|
|
@@ -60,6 +61,13 @@ interface CollectionFieldsInner<WithNamespace extends boolean> extends BaseColle
|
|
|
60
61
|
templates?: undefined;
|
|
61
62
|
}
|
|
62
63
|
export declare type TinaFieldInner<WithNamespace extends boolean> = ScalarType<WithNamespace> | ObjectType<WithNamespace> | ReferenceType<WithNamespace> | RichType<WithNamespace>;
|
|
64
|
+
export declare type TinaIndex = {
|
|
65
|
+
name: string;
|
|
66
|
+
fields: {
|
|
67
|
+
name: string;
|
|
68
|
+
default?: string | number | boolean;
|
|
69
|
+
}[];
|
|
70
|
+
};
|
|
63
71
|
export declare type TinaFieldBase = TinaFieldInner<false>;
|
|
64
72
|
export declare type TinaFieldEnriched = TinaFieldInner<true>;
|
|
65
73
|
interface TinaField {
|
|
@@ -68,6 +76,7 @@ interface TinaField {
|
|
|
68
76
|
description?: string;
|
|
69
77
|
required?: boolean;
|
|
70
78
|
list?: boolean;
|
|
79
|
+
indexed?: boolean;
|
|
71
80
|
/**
|
|
72
81
|
* Any items passed to the UI field will be passed to the underlying field.
|
|
73
82
|
* NOTE: only serializable values are supported, so functions like `validate`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/graphql",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-2022222183246",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@graphql-tools/relay-operation-optimizer": "^6.4.1",
|
|
49
|
+
"@tinacms/datalayer": "0.0.0-2022222183246",
|
|
49
50
|
"body-parser": "^1.19.0",
|
|
50
51
|
"cors": "^2.8.5",
|
|
51
52
|
"dataloader": "^2.0.0",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"graphql-type-json": "^0.3.2",
|
|
62
63
|
"gray-matter": "^4.0.2",
|
|
63
64
|
"js-yaml": "^3.14.0",
|
|
65
|
+
"leveldown": "^6.1.0",
|
|
64
66
|
"lodash": "^4.17.20",
|
|
65
67
|
"mdast": "^3.0.0",
|
|
66
68
|
"mdast-util-from-markdown": "^1.0.0",
|
|
@@ -68,7 +70,6 @@
|
|
|
68
70
|
"mdast-util-mdx-expression": "^1.1.0",
|
|
69
71
|
"mdast-util-to-markdown": "^1.2.1",
|
|
70
72
|
"micromark-extension-mdxjs": "^1.0.0",
|
|
71
|
-
"mocha": "^9.1.1",
|
|
72
73
|
"normalize-path": "^3.0.0",
|
|
73
74
|
"prettier": "^2.2.1",
|
|
74
75
|
"rehype-format": "^3.1.0",
|
|
@@ -95,15 +96,14 @@
|
|
|
95
96
|
"directory": "packages/tina-graphql"
|
|
96
97
|
},
|
|
97
98
|
"devDependencies": {
|
|
98
|
-
"@tinacms/datalayer": "0.0.0-
|
|
99
|
-
"@tinacms/scripts": "0.
|
|
99
|
+
"@tinacms/datalayer": "0.0.0-2022222183246",
|
|
100
|
+
"@tinacms/scripts": "0.50.7",
|
|
100
101
|
"@types/cors": "^2.8.7",
|
|
101
102
|
"@types/estree": "^0.0.50",
|
|
102
103
|
"@types/express": "^4.17.8",
|
|
103
104
|
"@types/fs-extra": "^9.0.2",
|
|
104
105
|
"@types/jest": "^26.0.4",
|
|
105
106
|
"@types/js-yaml": "^3.12.5",
|
|
106
|
-
"@types/level": "^6.0.0",
|
|
107
107
|
"@types/lodash": "^4.14.161",
|
|
108
108
|
"@types/lodash.camelcase": "^4.3.6",
|
|
109
109
|
"@types/lodash.upperfirst": "^4.3.6",
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
Copyright 2021 Forestry.io Holdings, Inc.
|
|
3
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
you may not use this file except in compliance with the License.
|
|
5
|
-
You may obtain a copy of the License at
|
|
6
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
-
Unless required by applicable law or agreed to in writing, software
|
|
8
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
-
See the License for the specific language governing permissions and
|
|
11
|
-
limitations under the License.
|
|
12
|
-
*/
|
|
13
|
-
export interface Store {
|
|
14
|
-
glob(pattern: string, hydrator?: (fullPath: string) => Promise<object>): Promise<string[]>;
|
|
15
|
-
get<T extends object>(filepath: string): Promise<T>;
|
|
16
|
-
clear(): void;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @param queryStrings
|
|
20
|
-
* Queries are currently structured as prefixed keys where that last portion
|
|
21
|
-
* of the key is the value provided by the query
|
|
22
|
-
* ```graphql
|
|
23
|
-
* {
|
|
24
|
-
* getPostsList(filter: {
|
|
25
|
-
* title: {
|
|
26
|
-
* eq: "Hello, World"
|
|
27
|
-
* }
|
|
28
|
-
* }) {
|
|
29
|
-
* ...
|
|
30
|
-
* }
|
|
31
|
-
* }
|
|
32
|
-
* ```
|
|
33
|
-
* Would equate to a query string of:
|
|
34
|
-
* ```
|
|
35
|
-
* __attribute__#posts#posts#title#Hello, World
|
|
36
|
-
* ```
|
|
37
|
-
* This can be used by a data store as a secondary index of sorts
|
|
38
|
-
*
|
|
39
|
-
* It's important to note that for now each query string acts as an "AND" clause,
|
|
40
|
-
* meaning the resulting records need to be present in _each_ query string.
|
|
41
|
-
*
|
|
42
|
-
* @param hydrator
|
|
43
|
-
* hydrator is an optional callback, which may be useful depending on the storage mechanism.
|
|
44
|
-
* For example, the in-memory storage only stores the path to its records as its value,
|
|
45
|
-
* but in something like DynamoDB the query strings may be used to look up the full record,
|
|
46
|
-
* meaning there's no need to "hydrate" the return value
|
|
47
|
-
*/
|
|
48
|
-
query(queryStrings: string[], hydrator?: (fullPath: string) => Promise<object>): Promise<object[]>;
|
|
49
|
-
/**
|
|
50
|
-
* In this context, seeding is the act of putting records and indexing data into an ephemeral
|
|
51
|
-
* storage layer for use during the GraphQL runtime. What might seem suprising is that some stores
|
|
52
|
-
* don't support seeding, this is because they're behaving more like a "bridge" (GithubStore and FilesystemStore).
|
|
53
|
-
* Currently they're acting as a way to swap out true data-layer behavior with a backwards-compatible
|
|
54
|
-
* "store". In the future, all stores should be able to query and seed data.
|
|
55
|
-
*
|
|
56
|
-
* At this time it seems that it would never make sense to be able to "query" without "seed"-ing, and
|
|
57
|
-
* there'd be no value in "seeding" without "query"-ing.
|
|
58
|
-
*/
|
|
59
|
-
seed(filepath: string, data: object, options?: {
|
|
60
|
-
includeTemplate?: boolean;
|
|
61
|
-
}): Promise<void>;
|
|
62
|
-
supportsSeeding(): boolean;
|
|
63
|
-
/**
|
|
64
|
-
* Whether this store supports the ability to index data.
|
|
65
|
-
* Indexing data requires writing arbitrary keys/values to
|
|
66
|
-
* the external service, so is not advisable to use for
|
|
67
|
-
* something like Github, which would write commits to the
|
|
68
|
-
* user's repo.
|
|
69
|
-
*/
|
|
70
|
-
supportsIndexing(): boolean;
|
|
71
|
-
put(filepath: string, data: object, keepTemplateKey?: boolean): Promise<void>;
|
|
72
|
-
}
|