@kubun/graphql 0.2.5 → 0.3.1
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/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -2
- package/lib/schema.d.ts +58 -24
- package/lib/schema.d.ts.map +1 -1
- package/lib/schema.js +354 -135
- package/lib/types.d.ts +26 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +1 -0
- package/package.json +4 -4
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { GraphQLAttachmentID, GraphQLDocID } from './identifiers.js';
|
|
2
2
|
export * as scalars from './scalars.js';
|
|
3
|
-
export
|
|
4
|
-
export {
|
|
3
|
+
export type { Context, ReadContext, SchemaBuilderParams, SharedDefinitions, UpdateMutationInput, WriteContext, } from './schema.js';
|
|
4
|
+
export { SchemaBuilder, createSchema } from './schema.js';
|
|
5
|
+
export type * from './types.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpE,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpE,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,YAAY,EACV,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACzD,mBAAmB,YAAY,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { GraphQLAttachmentID, GraphQLDocID } from './identifiers.js';
|
|
2
2
|
export * as scalars from './scalars.js';
|
|
3
|
-
export {
|
|
4
|
-
export { getUniqueDocValue } from './utils.js';
|
|
3
|
+
export { SchemaBuilder, createSchema } from './schema.js';
|
package/lib/schema.d.ts
CHANGED
|
@@ -1,60 +1,90 @@
|
|
|
1
1
|
import { AttachmentID, DocumentModelID } from '@kubun/id';
|
|
2
|
-
import {
|
|
3
|
-
import { GraphQLEnumType, type GraphQLFieldConfig, type GraphQLFieldConfigMap, GraphQLInputObjectType, type GraphQLInputType, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, type GraphQLOutputType, type GraphQLScalarType, GraphQLSchema } from 'graphql';
|
|
4
|
-
import { type Connection, type ConnectionArguments } from 'graphql-relay';
|
|
2
|
+
import type { ArrayModel, DocumentData, DocumentFilter, DocumentModel, DocumentModelSchema, DocumentModelsRecord, DocumentNode, DocumentOrderBy, ObjectModel, ReferencesRecordModel, ScalarModel, StringCustomModel, StringEnumModel, StringFormatModel, StringModel, TypeModel } from '@kubun/protocol';
|
|
3
|
+
import { GraphQLEnumType, type GraphQLFieldConfig, type GraphQLFieldConfigMap, GraphQLInputObjectType, type GraphQLInputType, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, type GraphQLOutputType, type GraphQLResolveInfo, type GraphQLScalarType, GraphQLSchema } from 'graphql';
|
|
4
|
+
import { type Connection, type ConnectionArguments, type Edge } from 'graphql-relay';
|
|
5
|
+
import type { PatchOperation as PatchOperationType } from './types.js';
|
|
5
6
|
export declare function toDocumentModelID(id: DocumentModelID | string): DocumentModelID;
|
|
6
7
|
export declare function getGlobalID(id: DocumentModelID | string, globalID: DocumentModelID | string): DocumentModelID;
|
|
7
8
|
export declare function toList(type: GraphQLInputType): GraphQLList<GraphQLNonNull<GraphQLInputType>>;
|
|
8
9
|
export declare function toOuputList(type: GraphQLOutputType): GraphQLList<GraphQLNonNull<GraphQLOutputType>>;
|
|
9
10
|
export declare const PatchOperation: GraphQLInputObjectType;
|
|
10
|
-
|
|
11
|
+
type AllConnectionArguments = ConnectionArguments & {
|
|
12
|
+
filter?: DocumentFilter;
|
|
13
|
+
orderBy?: DocumentOrderBy;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Query and subscription functions requiring server implementation
|
|
17
|
+
*/
|
|
18
|
+
export type ReadContext = {
|
|
19
|
+
getViewer(): string | null;
|
|
20
|
+
loadDocument(id: string): Promise<DocumentNode | null>;
|
|
21
|
+
resolveConnection(modelIDs: Array<string>, args: AllConnectionArguments): Promise<Connection<DocumentNode>>;
|
|
22
|
+
resolveList(modelIDs: Array<string>, ids: Array<string>): Promise<Array<DocumentNode>>;
|
|
23
|
+
subscribeToDocumentCreated(modelIDs: Array<string>): AsyncGenerator<DocumentNode>;
|
|
24
|
+
subscribeToDocumentChanged(id: string): AsyncGenerator<DocumentNode>;
|
|
25
|
+
subscribeToDocumentRemoved(): AsyncGenerator<string>;
|
|
26
|
+
subscribeToDocumentEdgeAdded(modelIDs: Array<string>, hasRelation: (data: DocumentData) => boolean): AsyncGenerator<Edge<DocumentNode>>;
|
|
27
|
+
subscribeToDocumentEdgeRemoved(modelIDs: Array<string>, hasRelation: (data: DocumentData) => boolean): AsyncGenerator<string>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Mutation function requiring client implementation
|
|
31
|
+
*/
|
|
32
|
+
export type WriteContext = {
|
|
33
|
+
executeCreateMutation(modelID: string, data: DocumentData, info: GraphQLResolveInfo): Promise<DocumentNode>;
|
|
34
|
+
executeSetMutation(modelID: string, unique: Uint8Array, data: DocumentData, info: GraphQLResolveInfo): Promise<DocumentNode>;
|
|
35
|
+
executeUpdateMutation(input: UpdateMutationInput, info: GraphQLResolveInfo): Promise<DocumentNode>;
|
|
36
|
+
executeRemoveMutation(id: string, info: GraphQLResolveInfo): Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
export type Context = ReadContext & WriteContext;
|
|
39
|
+
export type UpdateMutationInput = {
|
|
11
40
|
id: string;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
data: DocumentData | null;
|
|
41
|
+
patch: Array<PatchOperationType>;
|
|
42
|
+
from?: DocumentData;
|
|
15
43
|
};
|
|
16
|
-
export type
|
|
17
|
-
export type GraphQLNodeDefinitions<Context extends ContextType = ContextType> = {
|
|
44
|
+
export type GraphQLNodeDefinitions = {
|
|
18
45
|
nodeInterface: GraphQLInterfaceType;
|
|
19
46
|
nodeField: GraphQLFieldConfig<unknown, Context>;
|
|
20
47
|
nodesField: GraphQLFieldConfig<unknown, Context>;
|
|
21
48
|
};
|
|
22
|
-
export type SharedDefinitions
|
|
49
|
+
export type SharedDefinitions = GraphQLNodeDefinitions & {
|
|
23
50
|
accountObject: GraphQLObjectType<string, Context>;
|
|
24
51
|
attachmentObject: GraphQLObjectType<AttachmentID, Context>;
|
|
25
52
|
documentInterface: GraphQLInterfaceType;
|
|
26
|
-
|
|
53
|
+
documentNodeFields: GraphQLFieldConfigMap<DocumentNode, Context>;
|
|
27
54
|
queryFields: GraphQLFieldConfigMap<unknown, Context>;
|
|
28
55
|
};
|
|
56
|
+
type RelationField = {
|
|
57
|
+
model: string;
|
|
58
|
+
isList: boolean;
|
|
59
|
+
};
|
|
60
|
+
type RelationFields = Record<string, RelationField>;
|
|
29
61
|
export type SchemaBuilderParams = {
|
|
30
62
|
aliases?: Record<string, string>;
|
|
31
63
|
record: DocumentModelsRecord;
|
|
32
64
|
};
|
|
33
|
-
export declare class SchemaBuilder
|
|
65
|
+
export declare class SchemaBuilder {
|
|
34
66
|
_aliases: Record<string, string>;
|
|
35
|
-
_definitions:
|
|
67
|
+
_definitions: SharedDefinitions | undefined;
|
|
36
68
|
_implemented: Record<string, Array<string>>;
|
|
37
69
|
_inputObjects: Record<string, GraphQLInputObjectType>;
|
|
38
|
-
_mutations:
|
|
70
|
+
_mutations: GraphQLFieldConfigMap<unknown, Context>;
|
|
39
71
|
_nodeModelIDs: Array<string>;
|
|
40
72
|
_record: DocumentModelsRecord;
|
|
41
73
|
_references: ReferencesRecordModel;
|
|
42
|
-
_relationsTo: Record<string,
|
|
74
|
+
_relationsTo: Record<string, RelationFields>;
|
|
75
|
+
_subscriptions: GraphQLFieldConfigMap<unknown, Context>;
|
|
43
76
|
_types: Record<string, GraphQLOutputType>;
|
|
44
77
|
constructor(params: SchemaBuilderParams);
|
|
45
78
|
getModelIDs(id: string | null): Array<string>;
|
|
46
|
-
getViewer(ctx: Context): string | null;
|
|
47
|
-
loadDocument(id: string, ctx: Context): Promise<Document | null>;
|
|
48
|
-
resolveConnection(model: string | null, args: ConnectionArguments, ctx: Context): Promise<Connection<Document>>;
|
|
49
|
-
resolveList(model: string | null, ids: Array<string>, ctx: Context): Promise<Array<Document>>;
|
|
50
|
-
buildMutations(id: string, definitions: Definitions): void;
|
|
51
79
|
build(): GraphQLSchema;
|
|
52
|
-
_getDefinitions():
|
|
80
|
+
_getDefinitions(): SharedDefinitions;
|
|
53
81
|
_getReference(path: string, parentName?: string): GraphQLOutputType;
|
|
54
82
|
_getReferenceSchema(id: string): TypeModel;
|
|
55
83
|
_getReferenceInput(path: string, isPartial: boolean, parentName?: string): GraphQLInputType;
|
|
56
|
-
_buildSharedDefinitions():
|
|
57
|
-
_buildDocument(id: string): GraphQLObjectType<
|
|
84
|
+
_buildSharedDefinitions(): SharedDefinitions;
|
|
85
|
+
_buildDocument(id: string): GraphQLObjectType<DocumentNode, Context> | GraphQLInterfaceType;
|
|
86
|
+
_buildDocumentFields(id: string, model: DocumentModel, name: string): GraphQLFieldConfigMap<DocumentNode, Context>;
|
|
87
|
+
_buildDocumentDataObject(id: string, model: DocumentModel, name: string): GraphQLInterfaceType | GraphQLObjectType<DocumentData, Context>;
|
|
58
88
|
_buildDocumentInput(id: string, model: DocumentModel): void;
|
|
59
89
|
_buildReferenceFilterInput(path: string, parentName?: string): GraphQLInputType;
|
|
60
90
|
_buildReferenceOrderByInput(path: string, parentName?: string): GraphQLInputType | null;
|
|
@@ -65,10 +95,14 @@ export declare class SchemaBuilder<Document extends DocumentType = DocumentType,
|
|
|
65
95
|
_buildScalar(id: string, schema: ScalarModel, asInput?: boolean): GraphQLScalarType;
|
|
66
96
|
_buildArray(schema: ArrayModel, parentName?: string): GraphQLList<GraphQLNonNull<GraphQLOutputType>>;
|
|
67
97
|
_buildObject(id: string, schema: ObjectModel, parentName?: string): GraphQLObjectType;
|
|
68
|
-
_buildObjectFields(id: string, schema: DocumentModelSchema | ObjectModel
|
|
98
|
+
_buildObjectFields(id: string, schema: DocumentModelSchema | ObjectModel): GraphQLFieldConfigMap<Record<string, unknown>, Context>;
|
|
99
|
+
_buildRelationFields(fields: GraphQLFieldConfigMap<DocumentNode, Context>, fieldName: string, relation: RelationField): void;
|
|
100
|
+
_buildRelationSubscriptions(fields: GraphQLFieldConfigMap<unknown, Context>, modelID: string, fieldName: string, relation: RelationField): void;
|
|
69
101
|
_buildString(schema: StringModel, asInput: boolean): GraphQLEnumType | GraphQLObjectType | GraphQLScalarType;
|
|
70
102
|
_buildCustomString(schema: StringCustomModel, asInput: boolean): GraphQLScalarType<unknown, unknown> | GraphQLObjectType<string, Context> | GraphQLObjectType<AttachmentID, Context>;
|
|
71
103
|
_buildEnumString(schema: StringEnumModel): GraphQLEnumType;
|
|
72
104
|
_buildFormatString(schema: StringFormatModel): GraphQLScalarType<unknown, unknown>;
|
|
73
105
|
}
|
|
106
|
+
export declare function createSchema(record: DocumentModelsRecord, aliases?: Record<string, string>): GraphQLSchema;
|
|
107
|
+
export {};
|
|
74
108
|
//# sourceMappingURL=schema.d.ts.map
|
package/lib/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,eAAe,EAAY,MAAM,WAAW,CAAA;AAC/E,OAAO,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/lib/schema.js
CHANGED
|
@@ -2,8 +2,8 @@ import { AttachmentID, DocumentID, DocumentModelID, decodeID } from '@kubun/id';
|
|
|
2
2
|
import { REFERENCE_PREFIX } from '@kubun/protocol';
|
|
3
3
|
import { pascalCase } from 'change-case';
|
|
4
4
|
import { GraphQLBoolean, GraphQLEnumType, GraphQLFloat, GraphQLID, GraphQLInputObjectType, GraphQLInt, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema, GraphQLString, isEnumType, isListType, isNonNullType } from 'graphql';
|
|
5
|
-
import { connectionArgs, connectionDefinitions, nodeDefinitions } from 'graphql-relay';
|
|
6
|
-
import { GraphQLDID, GraphQLDuration, GraphQLJSON, GraphQLJSONObject, GraphQLURL } from 'graphql-scalars';
|
|
5
|
+
import { connectionArgs, connectionDefinitions, mutationWithClientMutationId, nodeDefinitions } from 'graphql-relay';
|
|
6
|
+
import { GraphQLDID, GraphQLDateTimeISO, GraphQLDuration, GraphQLJSON, GraphQLJSONObject, GraphQLURL } from 'graphql-scalars';
|
|
7
7
|
import { GraphQLAttachmentID, GraphQLDocID } from './identifiers.js';
|
|
8
8
|
import { getUniqueDocValue } from './utils.js';
|
|
9
9
|
const STRING_FORMATS = {
|
|
@@ -224,6 +224,7 @@ export class SchemaBuilder {
|
|
|
224
224
|
_record;
|
|
225
225
|
_references = {};
|
|
226
226
|
_relationsTo = {};
|
|
227
|
+
_subscriptions = {};
|
|
227
228
|
_types = {
|
|
228
229
|
OrderByDirection
|
|
229
230
|
};
|
|
@@ -246,9 +247,14 @@ export class SchemaBuilder {
|
|
|
246
247
|
// Extract inverse relations
|
|
247
248
|
for (const [fieldName, meta] of Object.entries(model.fieldsMeta)){
|
|
248
249
|
if (meta.relationModel != null) {
|
|
250
|
+
const relationRefID = getReferenceID(model.schema.properties[fieldName]?.$ref);
|
|
251
|
+
const isList = this._getReferenceSchema(relationRefID).type === 'array';
|
|
249
252
|
const relationID = getGlobalID(meta.relationModel, modelID).toString();
|
|
250
253
|
this._relationsTo[relationID] ??= {};
|
|
251
|
-
this._relationsTo[relationID][fieldName] =
|
|
254
|
+
this._relationsTo[relationID][fieldName] = {
|
|
255
|
+
model: modelIDstring,
|
|
256
|
+
isList
|
|
257
|
+
};
|
|
252
258
|
}
|
|
253
259
|
}
|
|
254
260
|
}
|
|
@@ -269,21 +275,6 @@ export class SchemaBuilder {
|
|
|
269
275
|
id
|
|
270
276
|
];
|
|
271
277
|
}
|
|
272
|
-
getViewer(ctx) {
|
|
273
|
-
throw new Error('Must be implemented');
|
|
274
|
-
}
|
|
275
|
-
async loadDocument(id, ctx) {
|
|
276
|
-
throw new Error('Must be implemented');
|
|
277
|
-
}
|
|
278
|
-
async resolveConnection(model, args, ctx) {
|
|
279
|
-
throw new Error('Must be implemented');
|
|
280
|
-
}
|
|
281
|
-
async resolveList(model, ids, ctx) {
|
|
282
|
-
throw new Error('Must be implemented');
|
|
283
|
-
}
|
|
284
|
-
buildMutations(id, definitions) {
|
|
285
|
-
throw new Error('Must be implemented');
|
|
286
|
-
}
|
|
287
278
|
build() {
|
|
288
279
|
const definitions = this._buildSharedDefinitions();
|
|
289
280
|
this._definitions = definitions;
|
|
@@ -293,25 +284,25 @@ export class SchemaBuilder {
|
|
|
293
284
|
};
|
|
294
285
|
for (const id of Object.keys(this._record)){
|
|
295
286
|
this._buildDocument(id);
|
|
296
|
-
this.buildMutations(id, definitions);
|
|
297
287
|
const name = this._aliases[id];
|
|
288
|
+
const filterArg = {
|
|
289
|
+
type: this._inputObjects[`${id}-filter`]
|
|
290
|
+
};
|
|
298
291
|
queryFields[`all${name}`] = {
|
|
299
292
|
type: this._types[`${id}-connection`],
|
|
300
293
|
args: {
|
|
301
294
|
...connectionArgs,
|
|
302
|
-
filter:
|
|
303
|
-
type: this._inputObjects[`${id}-filter`]
|
|
304
|
-
},
|
|
295
|
+
filter: filterArg,
|
|
305
296
|
orderBy: {
|
|
306
297
|
type: toList(this._inputObjects[`${id}-order`])
|
|
307
298
|
}
|
|
308
299
|
},
|
|
309
300
|
resolve: async (_, args, ctx)=>{
|
|
310
|
-
return await
|
|
301
|
+
return await ctx.resolveConnection(this.getModelIDs(id), args);
|
|
311
302
|
}
|
|
312
303
|
};
|
|
313
304
|
}
|
|
314
|
-
|
|
305
|
+
return new GraphQLSchema({
|
|
315
306
|
query: new GraphQLObjectType({
|
|
316
307
|
name: 'Query',
|
|
317
308
|
fields: queryFields
|
|
@@ -319,9 +310,54 @@ export class SchemaBuilder {
|
|
|
319
310
|
mutation: new GraphQLObjectType({
|
|
320
311
|
name: 'Mutation',
|
|
321
312
|
fields: this._mutations
|
|
313
|
+
}),
|
|
314
|
+
subscription: new GraphQLObjectType({
|
|
315
|
+
name: 'Subscription',
|
|
316
|
+
fields: ()=>{
|
|
317
|
+
const fields = {
|
|
318
|
+
documentChanged: {
|
|
319
|
+
type: new GraphQLNonNull(definitions.documentInterface),
|
|
320
|
+
args: {
|
|
321
|
+
id: {
|
|
322
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
resolve: (doc)=>doc,
|
|
326
|
+
subscribe: (_, args, ctx)=>{
|
|
327
|
+
return ctx.subscribeToDocumentChanged(args.id);
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
documentRemoved: {
|
|
331
|
+
type: new GraphQLNonNull(GraphQLID),
|
|
332
|
+
resolve: (id)=>id,
|
|
333
|
+
subscribe: (_src, _args, ctx)=>{
|
|
334
|
+
return ctx.subscribeToDocumentRemoved();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
for (const [id, model] of Object.entries(this._record)){
|
|
339
|
+
const name = this._aliases[id];
|
|
340
|
+
fields[`new${name}Created`] = {
|
|
341
|
+
type: new GraphQLNonNull(this._types[id]),
|
|
342
|
+
resolve: (doc)=>doc,
|
|
343
|
+
subscribe: (_src, _args, ctx)=>{
|
|
344
|
+
return ctx.subscribeToDocumentCreated(this.getModelIDs(id));
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
for (const iid of model.interfaces ?? []){
|
|
348
|
+
const interfaceID = getGlobalID(iid, id).toString();
|
|
349
|
+
for (const [fieldName, relationID] of Object.entries(this._relationsTo[interfaceID] ?? {})){
|
|
350
|
+
this._buildRelationSubscriptions(fields, interfaceID, fieldName, relationID);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
for (const [fieldName, relationID] of Object.entries(this._relationsTo[id] ?? {})){
|
|
354
|
+
this._buildRelationSubscriptions(fields, id, fieldName, relationID);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return fields;
|
|
358
|
+
}
|
|
322
359
|
})
|
|
323
|
-
};
|
|
324
|
-
return new GraphQLSchema(schemaFields);
|
|
360
|
+
});
|
|
325
361
|
}
|
|
326
362
|
_getDefinitions() {
|
|
327
363
|
if (this._definitions == null) {
|
|
@@ -385,7 +421,7 @@ export class SchemaBuilder {
|
|
|
385
421
|
return decoded;
|
|
386
422
|
}
|
|
387
423
|
if (decoded instanceof DocumentID) {
|
|
388
|
-
return await
|
|
424
|
+
return await ctx.loadDocument(id);
|
|
389
425
|
}
|
|
390
426
|
throw new Error(`Unsupported node ID: ${id}`);
|
|
391
427
|
}, (node)=>{
|
|
@@ -406,7 +442,7 @@ export class SchemaBuilder {
|
|
|
406
442
|
isViewer: {
|
|
407
443
|
type: new GraphQLNonNull(GraphQLBoolean),
|
|
408
444
|
description: 'Whether the authenticated request issuer is this account or not',
|
|
409
|
-
resolve: (did, _, ctx)=>
|
|
445
|
+
resolve: (did, _, ctx)=>ctx.getViewer() === did
|
|
410
446
|
}
|
|
411
447
|
};
|
|
412
448
|
for (const [id, model] of Object.entries(this._record)){
|
|
@@ -428,10 +464,10 @@ export class SchemaBuilder {
|
|
|
428
464
|
}
|
|
429
465
|
},
|
|
430
466
|
resolve: async (owner, args, ctx)=>{
|
|
431
|
-
return await
|
|
467
|
+
return await ctx.resolveConnection(this.getModelIDs(id), {
|
|
432
468
|
...args,
|
|
433
469
|
owner
|
|
434
|
-
}
|
|
470
|
+
});
|
|
435
471
|
}
|
|
436
472
|
};
|
|
437
473
|
break;
|
|
@@ -449,7 +485,7 @@ export class SchemaBuilder {
|
|
|
449
485
|
resolve: async (owner, args, ctx)=>{
|
|
450
486
|
const unique = getUniqueDocValue(model.uniqueFields, args.with);
|
|
451
487
|
const docID = await DocumentID.create(id, owner, unique);
|
|
452
|
-
return await
|
|
488
|
+
return await ctx.loadDocument(docID.toString());
|
|
453
489
|
}
|
|
454
490
|
};
|
|
455
491
|
}
|
|
@@ -476,40 +512,38 @@ export class SchemaBuilder {
|
|
|
476
512
|
}
|
|
477
513
|
}
|
|
478
514
|
});
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
515
|
+
const documentNodeFields = {
|
|
516
|
+
// Node interface
|
|
517
|
+
id: {
|
|
518
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
519
|
+
},
|
|
520
|
+
// Metadata
|
|
521
|
+
model: {
|
|
522
|
+
type: new GraphQLNonNull(GraphQLString)
|
|
523
|
+
},
|
|
524
|
+
owner: {
|
|
525
|
+
type: new GraphQLNonNull(accountObject)
|
|
526
|
+
},
|
|
527
|
+
createdAt: {
|
|
528
|
+
type: new GraphQLNonNull(GraphQLDateTimeISO)
|
|
529
|
+
},
|
|
530
|
+
updatedAt: {
|
|
531
|
+
type: GraphQLDateTimeISO
|
|
490
532
|
}
|
|
491
|
-
}
|
|
533
|
+
};
|
|
492
534
|
const documentInterface = new GraphQLInterfaceType({
|
|
493
535
|
name: 'DocumentNode',
|
|
494
536
|
interfaces: [
|
|
495
537
|
nodeDefs.nodeInterface
|
|
496
538
|
],
|
|
497
|
-
fields:
|
|
498
|
-
// Node interface
|
|
499
|
-
id: {
|
|
500
|
-
type: new GraphQLNonNull(GraphQLID)
|
|
501
|
-
},
|
|
502
|
-
_doc_metadata: {
|
|
503
|
-
type: new GraphQLNonNull(documentMetadata)
|
|
504
|
-
}
|
|
505
|
-
}
|
|
539
|
+
fields: documentNodeFields
|
|
506
540
|
});
|
|
507
541
|
const queryFields = {
|
|
508
542
|
node: nodeDefs.nodeField,
|
|
509
543
|
viewer: {
|
|
510
544
|
type: accountObject,
|
|
511
545
|
description: 'Account issuing the request, if authenticated',
|
|
512
|
-
resolve: (_self, _args, ctx)=>
|
|
546
|
+
resolve: (_self, _args, ctx)=>ctx.getViewer()
|
|
513
547
|
}
|
|
514
548
|
};
|
|
515
549
|
return {
|
|
@@ -517,7 +551,7 @@ export class SchemaBuilder {
|
|
|
517
551
|
accountObject,
|
|
518
552
|
attachmentObject,
|
|
519
553
|
documentInterface,
|
|
520
|
-
|
|
554
|
+
documentNodeFields,
|
|
521
555
|
queryFields
|
|
522
556
|
};
|
|
523
557
|
}
|
|
@@ -531,8 +565,9 @@ export class SchemaBuilder {
|
|
|
531
565
|
}
|
|
532
566
|
const definitions = this._getDefinitions();
|
|
533
567
|
this._aliases[id] ??= pascalCase(model.name);
|
|
568
|
+
const name = this._aliases[id];
|
|
534
569
|
const config = {
|
|
535
|
-
name
|
|
570
|
+
name,
|
|
536
571
|
interfaces: ()=>{
|
|
537
572
|
return [
|
|
538
573
|
definitions.documentInterface,
|
|
@@ -541,22 +576,194 @@ export class SchemaBuilder {
|
|
|
541
576
|
return this._types[getGlobalID(interfaceID, id).toString()];
|
|
542
577
|
}));
|
|
543
578
|
},
|
|
544
|
-
fields: ()=>this.
|
|
545
|
-
isTypeOf: (doc)=>DocumentID.fromString(doc.id).model.toString() === id
|
|
579
|
+
fields: ()=>this._buildDocumentFields(id, model, name)
|
|
546
580
|
};
|
|
547
581
|
const isInterface = model.behavior === 'interface';
|
|
548
|
-
const nodeType = isInterface ? new GraphQLInterfaceType(
|
|
582
|
+
const nodeType = isInterface ? new GraphQLInterfaceType({
|
|
583
|
+
...config,
|
|
584
|
+
resolveType: (doc)=>this._aliases[doc.model]
|
|
585
|
+
}) : new GraphQLObjectType(config);
|
|
549
586
|
const { connectionType, edgeType } = connectionDefinitions({
|
|
550
587
|
nodeType
|
|
551
588
|
});
|
|
552
589
|
this._types[id] = nodeType;
|
|
553
590
|
this._types[`${id}-connection`] = connectionType;
|
|
554
591
|
this._types[`${id}-edge`] = edgeType;
|
|
592
|
+
this._buildDocumentDataObject(id, model, name);
|
|
555
593
|
this._buildDocumentInput(id, model);
|
|
556
|
-
this._buildObjectFilterInput(id, model.schema,
|
|
557
|
-
this._buildObjectOrderByInput(id, model.schema,
|
|
594
|
+
this._buildObjectFilterInput(id, model.schema, name, true);
|
|
595
|
+
this._buildObjectOrderByInput(id, model.schema, name, true);
|
|
596
|
+
// TODO: move to dedicated method
|
|
597
|
+
if (!isInterface) {
|
|
598
|
+
if (model.behavior === 'default') {
|
|
599
|
+
this._mutations[`create${name}`] = mutationWithClientMutationId({
|
|
600
|
+
name: `Create${name}`,
|
|
601
|
+
inputFields: ()=>({
|
|
602
|
+
data: {
|
|
603
|
+
type: new GraphQLNonNull(this._inputObjects[id])
|
|
604
|
+
}
|
|
605
|
+
}),
|
|
606
|
+
outputFields: ()=>({
|
|
607
|
+
...definitions.queryFields,
|
|
608
|
+
document: {
|
|
609
|
+
type: this._types[id]
|
|
610
|
+
}
|
|
611
|
+
}),
|
|
612
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
613
|
+
const document = await ctx.executeCreateMutation(id, input.data, info);
|
|
614
|
+
return {
|
|
615
|
+
document
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
} else if (model.behavior === 'unique') {
|
|
620
|
+
this._mutations[`set${name}`] = mutationWithClientMutationId({
|
|
621
|
+
name: `Set${name}`,
|
|
622
|
+
inputFields: ()=>({
|
|
623
|
+
data: {
|
|
624
|
+
type: new GraphQLNonNull(this._inputObjects[id])
|
|
625
|
+
}
|
|
626
|
+
}),
|
|
627
|
+
outputFields: ()=>({
|
|
628
|
+
...definitions.queryFields,
|
|
629
|
+
document: {
|
|
630
|
+
type: this._types[id]
|
|
631
|
+
}
|
|
632
|
+
}),
|
|
633
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
634
|
+
const unique = getUniqueDocValue(model.uniqueFields, input.data);
|
|
635
|
+
const document = await ctx.executeSetMutation(id, unique, input.data, info);
|
|
636
|
+
return {
|
|
637
|
+
document
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
this._mutations[`update${name}`] = mutationWithClientMutationId({
|
|
643
|
+
name: `Update${name}`,
|
|
644
|
+
inputFields: ()=>({
|
|
645
|
+
id: {
|
|
646
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
647
|
+
},
|
|
648
|
+
patch: {
|
|
649
|
+
type: new GraphQLNonNull(toList(PatchOperation))
|
|
650
|
+
},
|
|
651
|
+
from: {
|
|
652
|
+
type: this._inputObjects[`${id}-update`]
|
|
653
|
+
}
|
|
654
|
+
}),
|
|
655
|
+
outputFields: ()=>({
|
|
656
|
+
...definitions.queryFields,
|
|
657
|
+
document: {
|
|
658
|
+
type: this._types[id]
|
|
659
|
+
}
|
|
660
|
+
}),
|
|
661
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
662
|
+
const document = await ctx.executeUpdateMutation(input, info);
|
|
663
|
+
return {
|
|
664
|
+
document
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
this._mutations[`remove${name}`] = mutationWithClientMutationId({
|
|
669
|
+
name: `Remove${name}`,
|
|
670
|
+
inputFields: ()=>({
|
|
671
|
+
id: {
|
|
672
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
673
|
+
}
|
|
674
|
+
}),
|
|
675
|
+
outputFields: ()=>definitions.queryFields,
|
|
676
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
677
|
+
await ctx.executeRemoveMutation(input.id, info);
|
|
678
|
+
return {};
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
}
|
|
558
682
|
return nodeType;
|
|
559
683
|
}
|
|
684
|
+
_buildDocumentFields(id, model, name) {
|
|
685
|
+
const dataObject = this._buildDocumentDataObject(id, model, name);
|
|
686
|
+
const definitions = this._getDefinitions();
|
|
687
|
+
const fields = {
|
|
688
|
+
...definitions.documentNodeFields,
|
|
689
|
+
data: {
|
|
690
|
+
type: new GraphQLNonNull(dataObject)
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
for (const [key, field] of Object.entries(dataObject.getFields())){
|
|
694
|
+
const relationModel = model.fieldsMeta[key]?.relationModel;
|
|
695
|
+
if (typeof relationModel !== 'undefined') {
|
|
696
|
+
let relationModelID;
|
|
697
|
+
let relationType;
|
|
698
|
+
if (relationModel === null) {
|
|
699
|
+
relationModelID = null;
|
|
700
|
+
relationType = definitions.documentInterface;
|
|
701
|
+
} else {
|
|
702
|
+
relationModelID = getGlobalID(relationModel, id).toString();
|
|
703
|
+
relationType = this._buildDocument(relationModelID);
|
|
704
|
+
}
|
|
705
|
+
if (isList(field.type)) {
|
|
706
|
+
// TODO: add suport for filters?
|
|
707
|
+
fields[`${key}Documents`] = {
|
|
708
|
+
type: new GraphQLNonNull(toOuputList(relationType)),
|
|
709
|
+
resolve: async (doc, _args, ctx)=>{
|
|
710
|
+
const relationIDs = doc.data?.[key] ?? [];
|
|
711
|
+
return relationIDs.length ? await ctx.resolveList(this.getModelIDs(relationModelID), relationIDs) : [];
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
} else {
|
|
715
|
+
fields[`${key}Document`] = {
|
|
716
|
+
type: relationType,
|
|
717
|
+
resolve: async (doc, _args, ctx)=>{
|
|
718
|
+
const relationID = doc.data?.[key];
|
|
719
|
+
return relationID ? await ctx.loadDocument(relationID) : null;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
for (const iid of model.interfaces ?? []){
|
|
725
|
+
const interfaceID = getGlobalID(iid, id).toString();
|
|
726
|
+
for (const [fieldName, relation] of Object.entries(this._relationsTo[interfaceID] ?? {})){
|
|
727
|
+
this._buildRelationFields(fields, fieldName, relation);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
for (const [fieldName, relation] of Object.entries(this._relationsTo[id] ?? {})){
|
|
731
|
+
this._buildRelationFields(fields, fieldName, relation);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
return fields;
|
|
735
|
+
}
|
|
736
|
+
_buildDocumentDataObject(id, model, name) {
|
|
737
|
+
const typeID = `${id}-data`;
|
|
738
|
+
if (this._types[typeID] != null) {
|
|
739
|
+
return this._types[typeID];
|
|
740
|
+
}
|
|
741
|
+
const required = model.schema.required ?? [];
|
|
742
|
+
const fields = {};
|
|
743
|
+
for (const [key, value] of Object.entries(model.schema.properties ?? {})){
|
|
744
|
+
const fieldRef = value.$ref;
|
|
745
|
+
if (fieldRef == null) {
|
|
746
|
+
throw new Error(`Missing ref for field ${key} of object ${id}`);
|
|
747
|
+
}
|
|
748
|
+
const type = this._getReference(fieldRef);
|
|
749
|
+
fields[key] = {
|
|
750
|
+
type: required.includes(key) ? new GraphQLNonNull(type) : type
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
const config = {
|
|
754
|
+
name: `${name}Data`,
|
|
755
|
+
interfaces: ()=>{
|
|
756
|
+
return model.interfaces.map((interfaceID)=>{
|
|
757
|
+
const typeID = `${getGlobalID(interfaceID, id).toString()}-data`;
|
|
758
|
+
return this._types[typeID];
|
|
759
|
+
});
|
|
760
|
+
},
|
|
761
|
+
fields
|
|
762
|
+
};
|
|
763
|
+
const object = model.behavior === 'interface' ? new GraphQLInterfaceType(config) : new GraphQLObjectType(config);
|
|
764
|
+
this._types[typeID] = object;
|
|
765
|
+
return object;
|
|
766
|
+
}
|
|
560
767
|
_buildDocumentInput(id, model) {
|
|
561
768
|
if (model.behavior === 'interface') {
|
|
562
769
|
// No mutations for interfaces
|
|
@@ -580,11 +787,11 @@ export class SchemaBuilder {
|
|
|
580
787
|
}
|
|
581
788
|
const name = this._aliases[id];
|
|
582
789
|
this._inputObjects[id] = new GraphQLInputObjectType({
|
|
583
|
-
name:
|
|
790
|
+
name: `${name}Input`,
|
|
584
791
|
fields: setFields
|
|
585
792
|
});
|
|
586
793
|
this._inputObjects[`${id}-update`] = new GraphQLInputObjectType({
|
|
587
|
-
name: `
|
|
794
|
+
name: `Partial${name}Input`,
|
|
588
795
|
fields: updateFields
|
|
589
796
|
});
|
|
590
797
|
}
|
|
@@ -596,17 +803,14 @@ export class SchemaBuilder {
|
|
|
596
803
|
}
|
|
597
804
|
if (schema.type === 'array') {
|
|
598
805
|
const name = this._aliases[id] ?? pascalCase(parentName + schema.title);
|
|
599
|
-
const itemType = this._buildReferenceFilterInput(schema.items.$ref, schema.title)
|
|
806
|
+
// const itemType = this._buildReferenceFilterInput(schema.items.$ref, schema.title)
|
|
600
807
|
return new GraphQLInputObjectType({
|
|
601
808
|
name: `${name}Filter`,
|
|
602
809
|
isOneOf: true,
|
|
603
810
|
fields: {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
},
|
|
607
|
-
isEmpty: {
|
|
608
|
-
type: GraphQLBoolean
|
|
609
|
-
},
|
|
811
|
+
// DB does not support filtering on array values
|
|
812
|
+
// contains: { type: toList(itemType) },
|
|
813
|
+
// isEmpty: { type: GraphQLBoolean },
|
|
610
814
|
isNull: {
|
|
611
815
|
type: GraphQLBoolean
|
|
612
816
|
}
|
|
@@ -644,7 +848,7 @@ export class SchemaBuilder {
|
|
|
644
848
|
}
|
|
645
849
|
const name = this._aliases[id] ?? pascalCase(parentName + (schema.title ?? ''));
|
|
646
850
|
const fields = isDocument ? {
|
|
647
|
-
|
|
851
|
+
_owner: {
|
|
648
852
|
type: this._inputObjects.AccountValueFilter
|
|
649
853
|
}
|
|
650
854
|
} : {};
|
|
@@ -687,10 +891,10 @@ export class SchemaBuilder {
|
|
|
687
891
|
}
|
|
688
892
|
const name = this._aliases[id] ?? pascalCase(parentName + (schema.title ?? ''));
|
|
689
893
|
const fields = isDocument ? {
|
|
690
|
-
|
|
894
|
+
_docOwner: {
|
|
691
895
|
type: OrderByDirection
|
|
692
896
|
},
|
|
693
|
-
|
|
897
|
+
_createdAt: {
|
|
694
898
|
type: OrderByDirection
|
|
695
899
|
}
|
|
696
900
|
} : {};
|
|
@@ -781,19 +985,9 @@ export class SchemaBuilder {
|
|
|
781
985
|
fields
|
|
782
986
|
});
|
|
783
987
|
}
|
|
784
|
-
_buildObjectFields(id, schema
|
|
785
|
-
const definitions = this._getDefinitions();
|
|
988
|
+
_buildObjectFields(id, schema) {
|
|
786
989
|
const required = schema.required ?? [];
|
|
787
|
-
const fields =
|
|
788
|
-
id: {
|
|
789
|
-
type: new GraphQLNonNull(GraphQLID),
|
|
790
|
-
resolve: (doc)=>doc.id
|
|
791
|
-
},
|
|
792
|
-
_doc_metadata: {
|
|
793
|
-
type: new GraphQLNonNull(definitions.documentMetadata),
|
|
794
|
-
resolve: (doc)=>doc
|
|
795
|
-
}
|
|
796
|
-
} : {};
|
|
990
|
+
const fields = {};
|
|
797
991
|
for (const [key, value] of Object.entries(schema.properties ?? {})){
|
|
798
992
|
const fieldRef = value.$ref;
|
|
799
993
|
if (fieldRef == null) {
|
|
@@ -803,63 +997,82 @@ export class SchemaBuilder {
|
|
|
803
997
|
fields[key] = {
|
|
804
998
|
type: required.includes(key) ? new GraphQLNonNull(type) : type
|
|
805
999
|
};
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1000
|
+
}
|
|
1001
|
+
return fields;
|
|
1002
|
+
}
|
|
1003
|
+
_buildRelationFields(fields, fieldName, relation) {
|
|
1004
|
+
if (relation.isList) {
|
|
1005
|
+
// DB does not support matches for array containing values
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const relationID = relation.model;
|
|
1009
|
+
const relationName = `${pascalCase(fieldName)}Of${this._aliases[relationID]}`;
|
|
1010
|
+
fields[`in${relationName}`] = {
|
|
1011
|
+
type: new GraphQLNonNull(this._types[`${relationID}-connection`]),
|
|
1012
|
+
args: {
|
|
1013
|
+
...connectionArgs,
|
|
1014
|
+
filter: {
|
|
1015
|
+
type: this._inputObjects[`${relationID}-filter`]
|
|
1016
|
+
},
|
|
1017
|
+
orderBy: {
|
|
1018
|
+
type: toList(this._inputObjects[`${relationID}-order`])
|
|
820
1019
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
return relationIDs.length ? await this.resolveList(relationModelID, relationIDs, ctx) : [];
|
|
828
|
-
}
|
|
829
|
-
};
|
|
830
|
-
} else {
|
|
831
|
-
fields[`_${key}_document`] = {
|
|
832
|
-
type: relationType,
|
|
833
|
-
resolve: async (doc, _args, ctx)=>{
|
|
834
|
-
const relationID = doc.data?.[key];
|
|
835
|
-
return relationID ? await this.loadDocument(relationID, ctx) : null;
|
|
1020
|
+
},
|
|
1021
|
+
resolve: (doc, args, ctx)=>{
|
|
1022
|
+
const docFilter = {
|
|
1023
|
+
where: {
|
|
1024
|
+
[fieldName]: {
|
|
1025
|
+
equalTo: doc.id
|
|
836
1026
|
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
const filter = args.filter ? {
|
|
1030
|
+
and: [
|
|
1031
|
+
args.filter,
|
|
1032
|
+
docFilter
|
|
1033
|
+
]
|
|
1034
|
+
} : docFilter;
|
|
1035
|
+
return ctx.resolveConnection(this.getModelIDs(relationID), {
|
|
1036
|
+
...args,
|
|
1037
|
+
filter
|
|
1038
|
+
});
|
|
839
1039
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1040
|
+
};
|
|
1041
|
+
// TODO: add support for count relation
|
|
1042
|
+
// fields[`_${fieldName}_of_${relationName}_count`] = {
|
|
1043
|
+
// type: new GraphQLNonNull(GraphQLInt),
|
|
1044
|
+
// }
|
|
1045
|
+
}
|
|
1046
|
+
_buildRelationSubscriptions(fields, modelID, fieldName, relation) {
|
|
1047
|
+
if (relation.isList) {
|
|
1048
|
+
// Inverse relations to list fields are not supported in connections so we skip them for subscriptions as well
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
const relationName = `${pascalCase(fieldName)}Of${this._aliases[relation.model]}`;
|
|
1052
|
+
fields[`edgeAddedTo${relationName}`] = {
|
|
1053
|
+
type: new GraphQLNonNull(this._types[`${modelID}-edge`]),
|
|
1054
|
+
args: {
|
|
1055
|
+
id: {
|
|
1056
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
850
1057
|
}
|
|
1058
|
+
},
|
|
1059
|
+
resolve: (edge)=>edge,
|
|
1060
|
+
subscribe: (_src, args, ctx)=>{
|
|
1061
|
+
return ctx.subscribeToDocumentEdgeAdded(this.getModelIDs(modelID), (data)=>data[fieldName] === args.id);
|
|
851
1062
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1063
|
+
};
|
|
1064
|
+
fields[`edgeRemovedFrom${relationName}`] = {
|
|
1065
|
+
type: new GraphQLNonNull(GraphQLID),
|
|
1066
|
+
args: {
|
|
1067
|
+
id: {
|
|
1068
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
resolve: (id)=>id,
|
|
1072
|
+
subscribe: (_src, args, ctx)=>{
|
|
1073
|
+
return ctx.subscribeToDocumentEdgeRemoved(this.getModelIDs(modelID), (data)=>data[fieldName] === args.id);
|
|
860
1074
|
}
|
|
861
|
-
}
|
|
862
|
-
return fields;
|
|
1075
|
+
};
|
|
863
1076
|
}
|
|
864
1077
|
_buildString(schema, asInput) {
|
|
865
1078
|
if (schema.const != null) {
|
|
@@ -912,3 +1125,9 @@ export class SchemaBuilder {
|
|
|
912
1125
|
return scalar;
|
|
913
1126
|
}
|
|
914
1127
|
}
|
|
1128
|
+
export function createSchema(record, aliases) {
|
|
1129
|
+
return new SchemaBuilder({
|
|
1130
|
+
record,
|
|
1131
|
+
aliases
|
|
1132
|
+
}).build();
|
|
1133
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type PatchAddOperation = {
|
|
2
|
+
op: 'add';
|
|
3
|
+
path: string;
|
|
4
|
+
value: unknown;
|
|
5
|
+
};
|
|
6
|
+
export type PatchRemoveOperation = {
|
|
7
|
+
op: 'remove';
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
export type PatchReplaceOperation = {
|
|
11
|
+
op: 'replace';
|
|
12
|
+
path: string;
|
|
13
|
+
value: unknown;
|
|
14
|
+
};
|
|
15
|
+
export type PatchMoveOperation = {
|
|
16
|
+
op: 'move';
|
|
17
|
+
from: string;
|
|
18
|
+
path: string;
|
|
19
|
+
};
|
|
20
|
+
export type PatchCopyOperation = {
|
|
21
|
+
op: 'copy';
|
|
22
|
+
from: string;
|
|
23
|
+
path: string;
|
|
24
|
+
};
|
|
25
|
+
export type PatchOperation = PatchAddOperation | PatchCopyOperation | PatchMoveOperation | PatchRemoveOperation | PatchReplaceOperation;
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAC3E,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AACjE,MAAM,MAAM,qBAAqB,GAAG;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AACnF,MAAM,MAAM,kBAAkB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAC3E,MAAM,MAAM,kBAAkB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAC3E,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,kBAAkB,GAClB,kBAAkB,GAClB,oBAAoB,GACpB,qBAAqB,CAAA"}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"license": "see LICENSE.md",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"type": "module",
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
],
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@enkaku/codec": "^0.
|
|
18
|
+
"@enkaku/codec": "^0.12.0",
|
|
19
19
|
"change-case": "^5.4.4",
|
|
20
20
|
"graphql": "^16.9.0",
|
|
21
21
|
"graphql-relay": "^0.10.2",
|
|
22
22
|
"graphql-scalars": "^1.24.2",
|
|
23
23
|
"multiformats": "^13.3.2",
|
|
24
|
-
"@kubun/id": "^0.
|
|
25
|
-
"@kubun/protocol": "^0.
|
|
24
|
+
"@kubun/id": "^0.3.0",
|
|
25
|
+
"@kubun/protocol": "^0.3.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"json-schema-typed": "^8.0.1"
|