@kubun/graphql 0.2.5 → 0.3.0
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 +56 -16
- package/lib/schema.d.ts.map +1 -1
- package/lib/schema.js +347 -134
- 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 { ContextType, DocumentType, ReadContextType, SchemaBuilderParams, SharedDefinitions, UpdateMutationInput, WriteContextType, } 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,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,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,53 +1,87 @@
|
|
|
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, 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;
|
|
11
|
+
type AllConnectionArguments = ConnectionArguments & {
|
|
12
|
+
filter?: DocumentFilter;
|
|
13
|
+
orderBy?: DocumentOrderBy;
|
|
14
|
+
};
|
|
10
15
|
export type DocumentType = {
|
|
11
16
|
id: string;
|
|
12
17
|
model: string;
|
|
13
18
|
owner: string;
|
|
14
19
|
data: DocumentData | null;
|
|
15
20
|
};
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Query and subscription functions requiring server implementation
|
|
23
|
+
*/
|
|
24
|
+
export type ReadContextType<Document extends DocumentType = DocumentType> = {
|
|
25
|
+
getViewer(): string | null;
|
|
26
|
+
loadDocument(id: string): Promise<Document | null>;
|
|
27
|
+
resolveConnection(modelIDs: Array<string>, args: AllConnectionArguments): Promise<Connection<Document>>;
|
|
28
|
+
resolveList(modelIDs: Array<string>, ids: Array<string>): Promise<Array<Document>>;
|
|
29
|
+
subscribeToDocumentCreated(modelIDs: Array<string>): AsyncGenerator<Document>;
|
|
30
|
+
subscribeToDocumentChanged(id: string): AsyncGenerator<Document>;
|
|
31
|
+
subscribeToDocumentRemoved(): AsyncGenerator<string>;
|
|
32
|
+
subscribeToDocumentEdgeAdded(modelIDs: Array<string>, hasRelation: (data: DocumentData) => boolean): AsyncGenerator<Edge<Document>>;
|
|
33
|
+
subscribeToDocumentEdgeRemoved(modelIDs: Array<string>, hasRelation: (data: DocumentData) => boolean): AsyncGenerator<string>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Mutation function requiring client implementation
|
|
37
|
+
*/
|
|
38
|
+
export type WriteContextType<Document extends DocumentType = DocumentType> = {
|
|
39
|
+
executeCreateMutation(modelID: string, data: DocumentData, info: GraphQLResolveInfo): Promise<Document>;
|
|
40
|
+
executeSetMutation(modelID: string, unique: Uint8Array, data: DocumentData, info: GraphQLResolveInfo): Promise<Document>;
|
|
41
|
+
executeUpdateMutation(input: UpdateMutationInput, info: GraphQLResolveInfo): Promise<Document>;
|
|
42
|
+
executeRemoveMutation(id: string, info: GraphQLResolveInfo): Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
export type ContextType<Document extends DocumentType = DocumentType> = ReadContextType<Document> & WriteContextType<Document>;
|
|
45
|
+
export type UpdateMutationInput = {
|
|
46
|
+
id: string;
|
|
47
|
+
patch: Array<PatchOperationType>;
|
|
48
|
+
from?: DocumentData;
|
|
49
|
+
};
|
|
50
|
+
export type GraphQLNodeDefinitions<Context> = {
|
|
18
51
|
nodeInterface: GraphQLInterfaceType;
|
|
19
52
|
nodeField: GraphQLFieldConfig<unknown, Context>;
|
|
20
53
|
nodesField: GraphQLFieldConfig<unknown, Context>;
|
|
21
54
|
};
|
|
22
|
-
export type SharedDefinitions<Document extends DocumentType = DocumentType, Context extends ContextType = ContextType
|
|
55
|
+
export type SharedDefinitions<Document extends DocumentType = DocumentType, Context extends ContextType<Document> = ContextType<Document>> = GraphQLNodeDefinitions<Context> & {
|
|
23
56
|
accountObject: GraphQLObjectType<string, Context>;
|
|
24
57
|
attachmentObject: GraphQLObjectType<AttachmentID, Context>;
|
|
25
58
|
documentInterface: GraphQLInterfaceType;
|
|
26
|
-
|
|
59
|
+
documentNodeFields: GraphQLFieldConfigMap<Document, Context>;
|
|
27
60
|
queryFields: GraphQLFieldConfigMap<unknown, Context>;
|
|
28
61
|
};
|
|
62
|
+
type RelationField = {
|
|
63
|
+
model: string;
|
|
64
|
+
isList: boolean;
|
|
65
|
+
};
|
|
66
|
+
type RelationFields = Record<string, RelationField>;
|
|
29
67
|
export type SchemaBuilderParams = {
|
|
30
68
|
aliases?: Record<string, string>;
|
|
31
69
|
record: DocumentModelsRecord;
|
|
32
70
|
};
|
|
33
|
-
export declare class SchemaBuilder<Document extends DocumentType = DocumentType, Context extends ContextType = ContextType
|
|
71
|
+
export declare class SchemaBuilder<Document extends DocumentType = DocumentType, Context extends ContextType<Document> = ContextType<Document>, Definitions extends SharedDefinitions<Document, Context> = SharedDefinitions<Document, Context>> {
|
|
34
72
|
_aliases: Record<string, string>;
|
|
35
73
|
_definitions: Definitions | undefined;
|
|
36
74
|
_implemented: Record<string, Array<string>>;
|
|
37
75
|
_inputObjects: Record<string, GraphQLInputObjectType>;
|
|
38
|
-
_mutations:
|
|
76
|
+
_mutations: GraphQLFieldConfigMap<unknown, Context>;
|
|
39
77
|
_nodeModelIDs: Array<string>;
|
|
40
78
|
_record: DocumentModelsRecord;
|
|
41
79
|
_references: ReferencesRecordModel;
|
|
42
|
-
_relationsTo: Record<string,
|
|
80
|
+
_relationsTo: Record<string, RelationFields>;
|
|
81
|
+
_subscriptions: GraphQLFieldConfigMap<unknown, Context>;
|
|
43
82
|
_types: Record<string, GraphQLOutputType>;
|
|
44
83
|
constructor(params: SchemaBuilderParams);
|
|
45
84
|
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
85
|
build(): GraphQLSchema;
|
|
52
86
|
_getDefinitions(): Definitions;
|
|
53
87
|
_getReference(path: string, parentName?: string): GraphQLOutputType;
|
|
@@ -55,6 +89,8 @@ export declare class SchemaBuilder<Document extends DocumentType = DocumentType,
|
|
|
55
89
|
_getReferenceInput(path: string, isPartial: boolean, parentName?: string): GraphQLInputType;
|
|
56
90
|
_buildSharedDefinitions(): Definitions;
|
|
57
91
|
_buildDocument(id: string): GraphQLObjectType<Document, Context> | GraphQLInterfaceType;
|
|
92
|
+
_buildDocumentFields(id: string, model: DocumentModel, name: string): GraphQLFieldConfigMap<Document, Context>;
|
|
93
|
+
_buildDocumentDataObject(id: string, model: DocumentModel, name: string): GraphQLInterfaceType | GraphQLObjectType<DocumentData, Context>;
|
|
58
94
|
_buildDocumentInput(id: string, model: DocumentModel): void;
|
|
59
95
|
_buildReferenceFilterInput(path: string, parentName?: string): GraphQLInputType;
|
|
60
96
|
_buildReferenceOrderByInput(path: string, parentName?: string): GraphQLInputType | null;
|
|
@@ -65,10 +101,14 @@ export declare class SchemaBuilder<Document extends DocumentType = DocumentType,
|
|
|
65
101
|
_buildScalar(id: string, schema: ScalarModel, asInput?: boolean): GraphQLScalarType;
|
|
66
102
|
_buildArray(schema: ArrayModel, parentName?: string): GraphQLList<GraphQLNonNull<GraphQLOutputType>>;
|
|
67
103
|
_buildObject(id: string, schema: ObjectModel, parentName?: string): GraphQLObjectType;
|
|
68
|
-
_buildObjectFields(id: string, schema: DocumentModelSchema | ObjectModel
|
|
104
|
+
_buildObjectFields(id: string, schema: DocumentModelSchema | ObjectModel): GraphQLFieldConfigMap<Record<string, unknown>, Context>;
|
|
105
|
+
_buildRelationFields(fields: GraphQLFieldConfigMap<Document, Context>, fieldName: string, relation: RelationField): void;
|
|
106
|
+
_buildRelationSubscriptions(fields: GraphQLFieldConfigMap<unknown, Context>, modelID: string, fieldName: string, relation: RelationField): void;
|
|
69
107
|
_buildString(schema: StringModel, asInput: boolean): GraphQLEnumType | GraphQLObjectType | GraphQLScalarType;
|
|
70
108
|
_buildCustomString(schema: StringCustomModel, asInput: boolean): GraphQLScalarType<unknown, unknown> | GraphQLObjectType<string, Context> | GraphQLObjectType<AttachmentID, Context>;
|
|
71
109
|
_buildEnumString(schema: StringEnumModel): GraphQLEnumType;
|
|
72
110
|
_buildFormatString(schema: StringFormatModel): GraphQLScalarType<unknown, unknown>;
|
|
73
111
|
}
|
|
112
|
+
export declare function createSchema(record: DocumentModelsRecord, aliases?: Record<string, string>): GraphQLSchema;
|
|
113
|
+
export {};
|
|
74
114
|
//# 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":"AAAA,OAAO,EAAE,YAAY,EAAc,eAAe,EAAY,MAAM,WAAW,CAAA;AAC/E,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,WAAW,EAEX,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,WAAW,EAEX,SAAS,EACV,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EAGL,eAAe,EAEf,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAI1B,sBAAsB,EACtB,KAAK,gBAAgB,EAErB,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,aAAa,EAKd,MAAM,SAAS,CAAA;AAChB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,IAAI,EAKV,MAAM,eAAe,CAAA;AAUtB,OAAO,KAAK,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,YAAY,CAAA;AA+CtE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,eAAe,GAAG,MAAM,GAAG,eAAe,CAE/E;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,eAAe,GAAG,MAAM,EAC5B,QAAQ,EAAE,eAAe,GAAG,MAAM,GACjC,eAAe,CAGjB;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,gBAAgB,iDAE5C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,kDAElD;AAyFD,eAAO,MAAM,cAAc,wBAUzB,CAAA;AAUF,KAAK,sBAAsB,GAAG,mBAAmB,GAAG;IAClD,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,EAAE,eAAe,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,YAAY,GAAG,IAAI,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,QAAQ,SAAS,YAAY,GAAG,YAAY,IAAI;IAC1E,SAAS,IAAI,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IAClD,iBAAiB,CACf,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EACvB,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAClF,0BAA0B,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC7E,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChE,0BAA0B,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;IACpD,4BAA4B,CAC1B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GAC3C,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IACjC,8BAA8B,CAC5B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EACvB,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GAC3C,cAAc,CAAC,MAAM,CAAC,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,QAAQ,SAAS,YAAY,GAAG,YAAY,IAAI;IAC3E,qBAAqB,CACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpB,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC9F,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3E,CAAA;AAED,MAAM,MAAM,WAAW,CAAC,QAAQ,SAAS,YAAY,GAAG,YAAY,IAAI,eAAe,CAAC,QAAQ,CAAC,GAC/F,gBAAgB,CAAC,QAAQ,CAAC,CAAA;AAE5B,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,YAAY,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,sBAAsB,CAAC,OAAO,IAAI;IAC5C,aAAa,EAAE,oBAAoB,CAAA;IACnC,SAAS,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC/C,UAAU,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,iBAAiB,CAC3B,QAAQ,SAAS,YAAY,GAAG,YAAY,EAC5C,OAAO,SAAS,WAAW,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,IAC3D,sBAAsB,CAAC,OAAO,CAAC,GAAG;IACpC,aAAa,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjD,gBAAgB,EAAE,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IAC1D,iBAAiB,EAAE,oBAAoB,CAAA;IACvC,kBAAkB,EAAE,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC5D,WAAW,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;CACrD,CAAA;AAED,KAAK,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAA;AACvD,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AAEnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,EAAE,oBAAoB,CAAA;CAC7B,CAAA;AAED,qBAAa,aAAa,CACxB,QAAQ,SAAS,YAAY,GAAG,YAAY,EAC5C,OAAO,SAAS,WAAW,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,EAC7D,WAAW,SAAS,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC;IAG/F,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,YAAY,EAAE,WAAW,GAAG,SAAS,CAAA;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAK;IAChD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAA6C;IAClG,UAAU,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAK;IACxD,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC5B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,WAAW,EAAE,qBAAqB,CAAK;IACvC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAK;IACjD,cAAc,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAK;IAC5D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAuB;gBAEpD,MAAM,EAAE,mBAAmB;IA0CvC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;IAI7C,KAAK,IAAI,aAAa;IA6EtB,eAAe,IAAI,WAAW;IAO9B,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAWnE,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;IAQ1C,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,SAAK,GAAG,gBAAgB;IAwCvF,uBAAuB,IAAI,WAAW;IA6HtC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,oBAAoB;IA+GvF,oBAAoB,CAClB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,GACX,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC;IAyD3C,wBAAwB,CACtB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,GACX,oBAAoB,GAAG,iBAAiB,CAAC,YAAY,EAAE,OAAO,CAAC;IAoClE,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAgC3D,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,gBAAgB;IAsC3E,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,gBAAgB,GAAG,IAAI;IAcnF,uBAAuB,CACrB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,mBAAmB,GAAG,WAAW,EACzC,UAAU,SAAK,EACf,UAAU,UAAQ;IAmCpB,wBAAwB,CACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,mBAAmB,GAAG,WAAW,EACzC,UAAU,SAAK,EACf,UAAU,UAAQ;IA4BpB,wBAAwB,CACtB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,EACzB,aAAa,CAAC,EAAE,MAAM,GACrB,sBAAsB;IA4BzB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,SAAK,GAAG,iBAAiB;IAiBlF,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,UAAQ,GAAG,iBAAiB;IAkBjF,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,SAAK,GAAG,WAAW,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAOhG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,SAAK,GAAG,iBAAiB;IAKjF,kBAAkB,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,mBAAmB,GAAG,WAAW,GACxC,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAiB1D,oBAAoB,CAClB,MAAM,EAAE,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAChD,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,aAAa,GACtB,IAAI;IA0BP,2BAA2B,CACzB,MAAM,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,EAC/C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,aAAa,GACtB,IAAI;IAkCP,YAAY,CACV,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,OAAO,GACf,eAAe,GAAG,iBAAiB,GAAG,iBAAiB;IAa1D,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO;IAqB9D,gBAAgB,CAAC,MAAM,EAAE,eAAe;IAQxC,kBAAkB,CAAC,MAAM,EAAE,iBAAiB;CAO7C;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,oBAAoB,EAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,aAAa,CAEf"}
|
package/lib/schema.js
CHANGED
|
@@ -2,7 +2,7 @@ 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';
|
|
5
|
+
import { connectionArgs, connectionDefinitions, mutationWithClientMutationId, nodeDefinitions } from 'graphql-relay';
|
|
6
6
|
import { GraphQLDID, GraphQLDuration, GraphQLJSON, GraphQLJSONObject, GraphQLURL } from 'graphql-scalars';
|
|
7
7
|
import { GraphQLAttachmentID, GraphQLDocID } from './identifiers.js';
|
|
8
8
|
import { getUniqueDocValue } from './utils.js';
|
|
@@ -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,32 @@ 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)
|
|
490
526
|
}
|
|
491
|
-
}
|
|
527
|
+
};
|
|
492
528
|
const documentInterface = new GraphQLInterfaceType({
|
|
493
529
|
name: 'DocumentNode',
|
|
494
530
|
interfaces: [
|
|
495
531
|
nodeDefs.nodeInterface
|
|
496
532
|
],
|
|
497
|
-
fields:
|
|
498
|
-
// Node interface
|
|
499
|
-
id: {
|
|
500
|
-
type: new GraphQLNonNull(GraphQLID)
|
|
501
|
-
},
|
|
502
|
-
_doc_metadata: {
|
|
503
|
-
type: new GraphQLNonNull(documentMetadata)
|
|
504
|
-
}
|
|
505
|
-
}
|
|
533
|
+
fields: documentNodeFields
|
|
506
534
|
});
|
|
507
535
|
const queryFields = {
|
|
508
536
|
node: nodeDefs.nodeField,
|
|
509
537
|
viewer: {
|
|
510
538
|
type: accountObject,
|
|
511
539
|
description: 'Account issuing the request, if authenticated',
|
|
512
|
-
resolve: (_self, _args, ctx)=>
|
|
540
|
+
resolve: (_self, _args, ctx)=>ctx.getViewer()
|
|
513
541
|
}
|
|
514
542
|
};
|
|
515
543
|
return {
|
|
@@ -517,7 +545,7 @@ export class SchemaBuilder {
|
|
|
517
545
|
accountObject,
|
|
518
546
|
attachmentObject,
|
|
519
547
|
documentInterface,
|
|
520
|
-
|
|
548
|
+
documentNodeFields,
|
|
521
549
|
queryFields
|
|
522
550
|
};
|
|
523
551
|
}
|
|
@@ -531,8 +559,9 @@ export class SchemaBuilder {
|
|
|
531
559
|
}
|
|
532
560
|
const definitions = this._getDefinitions();
|
|
533
561
|
this._aliases[id] ??= pascalCase(model.name);
|
|
562
|
+
const name = this._aliases[id];
|
|
534
563
|
const config = {
|
|
535
|
-
name
|
|
564
|
+
name,
|
|
536
565
|
interfaces: ()=>{
|
|
537
566
|
return [
|
|
538
567
|
definitions.documentInterface,
|
|
@@ -541,22 +570,194 @@ export class SchemaBuilder {
|
|
|
541
570
|
return this._types[getGlobalID(interfaceID, id).toString()];
|
|
542
571
|
}));
|
|
543
572
|
},
|
|
544
|
-
fields: ()=>this.
|
|
545
|
-
isTypeOf: (doc)=>DocumentID.fromString(doc.id).model.toString() === id
|
|
573
|
+
fields: ()=>this._buildDocumentFields(id, model, name)
|
|
546
574
|
};
|
|
547
575
|
const isInterface = model.behavior === 'interface';
|
|
548
|
-
const nodeType = isInterface ? new GraphQLInterfaceType(
|
|
576
|
+
const nodeType = isInterface ? new GraphQLInterfaceType({
|
|
577
|
+
...config,
|
|
578
|
+
resolveType: (doc)=>this._aliases[doc.model]
|
|
579
|
+
}) : new GraphQLObjectType(config);
|
|
549
580
|
const { connectionType, edgeType } = connectionDefinitions({
|
|
550
581
|
nodeType
|
|
551
582
|
});
|
|
552
583
|
this._types[id] = nodeType;
|
|
553
584
|
this._types[`${id}-connection`] = connectionType;
|
|
554
585
|
this._types[`${id}-edge`] = edgeType;
|
|
586
|
+
this._buildDocumentDataObject(id, model, name);
|
|
555
587
|
this._buildDocumentInput(id, model);
|
|
556
|
-
this._buildObjectFilterInput(id, model.schema,
|
|
557
|
-
this._buildObjectOrderByInput(id, model.schema,
|
|
588
|
+
this._buildObjectFilterInput(id, model.schema, name, true);
|
|
589
|
+
this._buildObjectOrderByInput(id, model.schema, name, true);
|
|
590
|
+
// TODO: move to dedicated method
|
|
591
|
+
if (!isInterface) {
|
|
592
|
+
if (model.behavior === 'default') {
|
|
593
|
+
this._mutations[`create${name}`] = mutationWithClientMutationId({
|
|
594
|
+
name: `Create${name}`,
|
|
595
|
+
inputFields: ()=>({
|
|
596
|
+
data: {
|
|
597
|
+
type: new GraphQLNonNull(this._inputObjects[id])
|
|
598
|
+
}
|
|
599
|
+
}),
|
|
600
|
+
outputFields: ()=>({
|
|
601
|
+
...definitions.queryFields,
|
|
602
|
+
document: {
|
|
603
|
+
type: this._types[id]
|
|
604
|
+
}
|
|
605
|
+
}),
|
|
606
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
607
|
+
const document = await ctx.executeCreateMutation(id, input.data, info);
|
|
608
|
+
return {
|
|
609
|
+
document
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
} else if (model.behavior === 'unique') {
|
|
614
|
+
this._mutations[`set${name}`] = mutationWithClientMutationId({
|
|
615
|
+
name: `Set${name}`,
|
|
616
|
+
inputFields: ()=>({
|
|
617
|
+
data: {
|
|
618
|
+
type: new GraphQLNonNull(this._inputObjects[id])
|
|
619
|
+
}
|
|
620
|
+
}),
|
|
621
|
+
outputFields: ()=>({
|
|
622
|
+
...definitions.queryFields,
|
|
623
|
+
document: {
|
|
624
|
+
type: this._types[id]
|
|
625
|
+
}
|
|
626
|
+
}),
|
|
627
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
628
|
+
const unique = getUniqueDocValue(model.uniqueFields, input.data);
|
|
629
|
+
const document = await ctx.executeSetMutation(id, unique, input.data, info);
|
|
630
|
+
return {
|
|
631
|
+
document
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
this._mutations[`update${name}`] = mutationWithClientMutationId({
|
|
637
|
+
name: `Update${name}`,
|
|
638
|
+
inputFields: ()=>({
|
|
639
|
+
id: {
|
|
640
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
641
|
+
},
|
|
642
|
+
patch: {
|
|
643
|
+
type: new GraphQLNonNull(toList(PatchOperation))
|
|
644
|
+
},
|
|
645
|
+
from: {
|
|
646
|
+
type: this._inputObjects[`${id}-update`]
|
|
647
|
+
}
|
|
648
|
+
}),
|
|
649
|
+
outputFields: ()=>({
|
|
650
|
+
...definitions.queryFields,
|
|
651
|
+
document: {
|
|
652
|
+
type: this._types[id]
|
|
653
|
+
}
|
|
654
|
+
}),
|
|
655
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
656
|
+
const document = await ctx.executeUpdateMutation(input, info);
|
|
657
|
+
return {
|
|
658
|
+
document
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
this._mutations[`remove${name}`] = mutationWithClientMutationId({
|
|
663
|
+
name: `Remove${name}`,
|
|
664
|
+
inputFields: ()=>({
|
|
665
|
+
id: {
|
|
666
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
667
|
+
}
|
|
668
|
+
}),
|
|
669
|
+
outputFields: ()=>definitions.queryFields,
|
|
670
|
+
mutateAndGetPayload: async (input, ctx, info)=>{
|
|
671
|
+
await ctx.executeRemoveMutation(input.id, info);
|
|
672
|
+
return {};
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
558
676
|
return nodeType;
|
|
559
677
|
}
|
|
678
|
+
_buildDocumentFields(id, model, name) {
|
|
679
|
+
const dataObject = this._buildDocumentDataObject(id, model, name);
|
|
680
|
+
const definitions = this._getDefinitions();
|
|
681
|
+
const fields = {
|
|
682
|
+
...definitions.documentNodeFields,
|
|
683
|
+
data: {
|
|
684
|
+
type: new GraphQLNonNull(dataObject)
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
for (const [key, field] of Object.entries(dataObject.getFields())){
|
|
688
|
+
const relationModel = model.fieldsMeta[key]?.relationModel;
|
|
689
|
+
if (typeof relationModel !== 'undefined') {
|
|
690
|
+
let relationModelID;
|
|
691
|
+
let relationType;
|
|
692
|
+
if (relationModel === null) {
|
|
693
|
+
relationModelID = null;
|
|
694
|
+
relationType = definitions.documentInterface;
|
|
695
|
+
} else {
|
|
696
|
+
relationModelID = getGlobalID(relationModel, id).toString();
|
|
697
|
+
relationType = this._buildDocument(relationModelID);
|
|
698
|
+
}
|
|
699
|
+
if (isList(field.type)) {
|
|
700
|
+
// TODO: add suport for filters?
|
|
701
|
+
fields[`${key}Documents`] = {
|
|
702
|
+
type: new GraphQLNonNull(toOuputList(relationType)),
|
|
703
|
+
resolve: async (doc, _args, ctx)=>{
|
|
704
|
+
const relationIDs = doc.data?.[key] ?? [];
|
|
705
|
+
return relationIDs.length ? await ctx.resolveList(this.getModelIDs(relationModelID), relationIDs) : [];
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
} else {
|
|
709
|
+
fields[`${key}Document`] = {
|
|
710
|
+
type: relationType,
|
|
711
|
+
resolve: async (doc, _args, ctx)=>{
|
|
712
|
+
const relationID = doc.data?.[key];
|
|
713
|
+
return relationID ? await ctx.loadDocument(relationID) : null;
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
for (const iid of model.interfaces ?? []){
|
|
719
|
+
const interfaceID = getGlobalID(iid, id).toString();
|
|
720
|
+
for (const [fieldName, relation] of Object.entries(this._relationsTo[interfaceID] ?? {})){
|
|
721
|
+
this._buildRelationFields(fields, fieldName, relation);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
for (const [fieldName, relation] of Object.entries(this._relationsTo[id] ?? {})){
|
|
725
|
+
this._buildRelationFields(fields, fieldName, relation);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return fields;
|
|
729
|
+
}
|
|
730
|
+
_buildDocumentDataObject(id, model, name) {
|
|
731
|
+
const typeID = `${id}-data`;
|
|
732
|
+
if (this._types[typeID] != null) {
|
|
733
|
+
return this._types[typeID];
|
|
734
|
+
}
|
|
735
|
+
const required = model.schema.required ?? [];
|
|
736
|
+
const fields = {};
|
|
737
|
+
for (const [key, value] of Object.entries(model.schema.properties ?? {})){
|
|
738
|
+
const fieldRef = value.$ref;
|
|
739
|
+
if (fieldRef == null) {
|
|
740
|
+
throw new Error(`Missing ref for field ${key} of object ${id}`);
|
|
741
|
+
}
|
|
742
|
+
const type = this._getReference(fieldRef);
|
|
743
|
+
fields[key] = {
|
|
744
|
+
type: required.includes(key) ? new GraphQLNonNull(type) : type
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
const config = {
|
|
748
|
+
name: `${name}Data`,
|
|
749
|
+
interfaces: ()=>{
|
|
750
|
+
return model.interfaces.map((interfaceID)=>{
|
|
751
|
+
const typeID = `${getGlobalID(interfaceID, id).toString()}-data`;
|
|
752
|
+
return this._types[typeID];
|
|
753
|
+
});
|
|
754
|
+
},
|
|
755
|
+
fields
|
|
756
|
+
};
|
|
757
|
+
const object = model.behavior === 'interface' ? new GraphQLInterfaceType(config) : new GraphQLObjectType(config);
|
|
758
|
+
this._types[typeID] = object;
|
|
759
|
+
return object;
|
|
760
|
+
}
|
|
560
761
|
_buildDocumentInput(id, model) {
|
|
561
762
|
if (model.behavior === 'interface') {
|
|
562
763
|
// No mutations for interfaces
|
|
@@ -580,11 +781,11 @@ export class SchemaBuilder {
|
|
|
580
781
|
}
|
|
581
782
|
const name = this._aliases[id];
|
|
582
783
|
this._inputObjects[id] = new GraphQLInputObjectType({
|
|
583
|
-
name:
|
|
784
|
+
name: `${name}Input`,
|
|
584
785
|
fields: setFields
|
|
585
786
|
});
|
|
586
787
|
this._inputObjects[`${id}-update`] = new GraphQLInputObjectType({
|
|
587
|
-
name: `
|
|
788
|
+
name: `Partial${name}Input`,
|
|
588
789
|
fields: updateFields
|
|
589
790
|
});
|
|
590
791
|
}
|
|
@@ -596,17 +797,14 @@ export class SchemaBuilder {
|
|
|
596
797
|
}
|
|
597
798
|
if (schema.type === 'array') {
|
|
598
799
|
const name = this._aliases[id] ?? pascalCase(parentName + schema.title);
|
|
599
|
-
const itemType = this._buildReferenceFilterInput(schema.items.$ref, schema.title)
|
|
800
|
+
// const itemType = this._buildReferenceFilterInput(schema.items.$ref, schema.title)
|
|
600
801
|
return new GraphQLInputObjectType({
|
|
601
802
|
name: `${name}Filter`,
|
|
602
803
|
isOneOf: true,
|
|
603
804
|
fields: {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
},
|
|
607
|
-
isEmpty: {
|
|
608
|
-
type: GraphQLBoolean
|
|
609
|
-
},
|
|
805
|
+
// DB does not support filtering on array values
|
|
806
|
+
// contains: { type: toList(itemType) },
|
|
807
|
+
// isEmpty: { type: GraphQLBoolean },
|
|
610
808
|
isNull: {
|
|
611
809
|
type: GraphQLBoolean
|
|
612
810
|
}
|
|
@@ -644,7 +842,7 @@ export class SchemaBuilder {
|
|
|
644
842
|
}
|
|
645
843
|
const name = this._aliases[id] ?? pascalCase(parentName + (schema.title ?? ''));
|
|
646
844
|
const fields = isDocument ? {
|
|
647
|
-
|
|
845
|
+
_owner: {
|
|
648
846
|
type: this._inputObjects.AccountValueFilter
|
|
649
847
|
}
|
|
650
848
|
} : {};
|
|
@@ -687,10 +885,10 @@ export class SchemaBuilder {
|
|
|
687
885
|
}
|
|
688
886
|
const name = this._aliases[id] ?? pascalCase(parentName + (schema.title ?? ''));
|
|
689
887
|
const fields = isDocument ? {
|
|
690
|
-
|
|
888
|
+
_docOwner: {
|
|
691
889
|
type: OrderByDirection
|
|
692
890
|
},
|
|
693
|
-
|
|
891
|
+
_createdAt: {
|
|
694
892
|
type: OrderByDirection
|
|
695
893
|
}
|
|
696
894
|
} : {};
|
|
@@ -781,19 +979,9 @@ export class SchemaBuilder {
|
|
|
781
979
|
fields
|
|
782
980
|
});
|
|
783
981
|
}
|
|
784
|
-
_buildObjectFields(id, schema
|
|
785
|
-
const definitions = this._getDefinitions();
|
|
982
|
+
_buildObjectFields(id, schema) {
|
|
786
983
|
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
|
-
} : {};
|
|
984
|
+
const fields = {};
|
|
797
985
|
for (const [key, value] of Object.entries(schema.properties ?? {})){
|
|
798
986
|
const fieldRef = value.$ref;
|
|
799
987
|
if (fieldRef == null) {
|
|
@@ -803,63 +991,82 @@ export class SchemaBuilder {
|
|
|
803
991
|
fields[key] = {
|
|
804
992
|
type: required.includes(key) ? new GraphQLNonNull(type) : type
|
|
805
993
|
};
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
994
|
+
}
|
|
995
|
+
return fields;
|
|
996
|
+
}
|
|
997
|
+
_buildRelationFields(fields, fieldName, relation) {
|
|
998
|
+
if (relation.isList) {
|
|
999
|
+
// DB does not support matches for array containing values
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
const relationID = relation.model;
|
|
1003
|
+
const relationName = `${pascalCase(fieldName)}Of${this._aliases[relationID]}`;
|
|
1004
|
+
fields[`in${relationName}`] = {
|
|
1005
|
+
type: new GraphQLNonNull(this._types[`${relationID}-connection`]),
|
|
1006
|
+
args: {
|
|
1007
|
+
...connectionArgs,
|
|
1008
|
+
filter: {
|
|
1009
|
+
type: this._inputObjects[`${relationID}-filter`]
|
|
1010
|
+
},
|
|
1011
|
+
orderBy: {
|
|
1012
|
+
type: toList(this._inputObjects[`${relationID}-order`])
|
|
820
1013
|
}
|
|
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;
|
|
1014
|
+
},
|
|
1015
|
+
resolve: (doc, args, ctx)=>{
|
|
1016
|
+
const docFilter = {
|
|
1017
|
+
where: {
|
|
1018
|
+
[fieldName]: {
|
|
1019
|
+
equalTo: doc.id
|
|
836
1020
|
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
const filter = args.filter ? {
|
|
1024
|
+
and: [
|
|
1025
|
+
args.filter,
|
|
1026
|
+
docFilter
|
|
1027
|
+
]
|
|
1028
|
+
} : docFilter;
|
|
1029
|
+
return ctx.resolveConnection(this.getModelIDs(relationID), {
|
|
1030
|
+
...args,
|
|
1031
|
+
filter
|
|
1032
|
+
});
|
|
839
1033
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1034
|
+
};
|
|
1035
|
+
// TODO: add support for count relation
|
|
1036
|
+
// fields[`_${fieldName}_of_${relationName}_count`] = {
|
|
1037
|
+
// type: new GraphQLNonNull(GraphQLInt),
|
|
1038
|
+
// }
|
|
1039
|
+
}
|
|
1040
|
+
_buildRelationSubscriptions(fields, modelID, fieldName, relation) {
|
|
1041
|
+
if (relation.isList) {
|
|
1042
|
+
// Inverse relations to list fields are not supported in connections so we skip them for subscriptions as well
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
const relationName = `${pascalCase(fieldName)}Of${this._aliases[relation.model]}`;
|
|
1046
|
+
fields[`edgeAddedTo${relationName}`] = {
|
|
1047
|
+
type: new GraphQLNonNull(this._types[`${modelID}-edge`]),
|
|
1048
|
+
args: {
|
|
1049
|
+
id: {
|
|
1050
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
850
1051
|
}
|
|
1052
|
+
},
|
|
1053
|
+
resolve: (edge)=>edge,
|
|
1054
|
+
subscribe: (_src, args, ctx)=>{
|
|
1055
|
+
return ctx.subscribeToDocumentEdgeAdded(this.getModelIDs(modelID), (data)=>data[fieldName] === args.id);
|
|
851
1056
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1057
|
+
};
|
|
1058
|
+
fields[`edgeRemovedFrom${relationName}`] = {
|
|
1059
|
+
type: new GraphQLNonNull(GraphQLID),
|
|
1060
|
+
args: {
|
|
1061
|
+
id: {
|
|
1062
|
+
type: new GraphQLNonNull(GraphQLID)
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
resolve: (id)=>id,
|
|
1066
|
+
subscribe: (_src, args, ctx)=>{
|
|
1067
|
+
return ctx.subscribeToDocumentEdgeRemoved(this.getModelIDs(modelID), (data)=>data[fieldName] === args.id);
|
|
860
1068
|
}
|
|
861
|
-
}
|
|
862
|
-
return fields;
|
|
1069
|
+
};
|
|
863
1070
|
}
|
|
864
1071
|
_buildString(schema, asInput) {
|
|
865
1072
|
if (schema.const != null) {
|
|
@@ -912,3 +1119,9 @@ export class SchemaBuilder {
|
|
|
912
1119
|
return scalar;
|
|
913
1120
|
}
|
|
914
1121
|
}
|
|
1122
|
+
export function createSchema(record, aliases) {
|
|
1123
|
+
return new SchemaBuilder({
|
|
1124
|
+
record,
|
|
1125
|
+
aliases
|
|
1126
|
+
}).build();
|
|
1127
|
+
}
|
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.0",
|
|
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/
|
|
25
|
-
"@kubun/
|
|
24
|
+
"@kubun/protocol": "^0.3.0",
|
|
25
|
+
"@kubun/id": "^0.3.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"json-schema-typed": "^8.0.1"
|