@kubun/graphql 0.9.0 → 0.10.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/context.d.ts +76 -5
- package/lib/context.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/schema.d.ts +98 -2
- package/lib/schema.js +1 -1
- package/package.json +15 -13
package/lib/context.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Tracer } from '@enkaku/otel';
|
|
2
2
|
import { DocumentID } from '@kubun/id';
|
|
3
|
-
import type { DocumentData, DocumentFilter, DocumentNode, DocumentOrderBy } from '@kubun/protocol';
|
|
3
|
+
import type { AggregateHaving, AggregateSpec, AggregateValues, DocumentData, DocumentFilter, DocumentNode, DocumentOrderBy, GroupedAggregateOrderTerm, GroupedAggregateValue } from '@kubun/protocol';
|
|
4
|
+
import type { ViewerReadAccess } from '@kubun/store-graph';
|
|
4
5
|
import type { GraphQLResolveInfo } from 'graphql';
|
|
5
6
|
import type { Connection, Edge } from 'graphql-relay';
|
|
6
7
|
import type { AllConnectionArguments, ModelAccessDefaults, UpdateMutationInput } from './types.js';
|
|
@@ -49,11 +50,30 @@ export type ReadContextDB = {
|
|
|
49
50
|
modelIDs: Array<string>;
|
|
50
51
|
docIDs: Array<string>;
|
|
51
52
|
}): Promise<Array<DocumentNode>>;
|
|
52
|
-
|
|
53
|
+
aggregateDocuments(params: {
|
|
53
54
|
modelIDs: Array<string>;
|
|
54
55
|
filter?: DocumentFilter;
|
|
56
|
+
owner?: string;
|
|
57
|
+
catalogID?: string;
|
|
58
|
+
count: boolean;
|
|
59
|
+
aggregates: Array<AggregateSpec>;
|
|
60
|
+
readAccess?: ViewerReadAccess;
|
|
61
|
+
}): Promise<AggregateValues>;
|
|
62
|
+
groupedAggregateDocuments(params: {
|
|
63
|
+
modelIDs: Array<string>;
|
|
64
|
+
filter?: DocumentFilter;
|
|
65
|
+
owner?: string;
|
|
55
66
|
catalogID?: string;
|
|
56
|
-
|
|
67
|
+
count: boolean;
|
|
68
|
+
aggregates: Array<AggregateSpec>;
|
|
69
|
+
groupBy: Array<{
|
|
70
|
+
keys: Array<string>;
|
|
71
|
+
}>;
|
|
72
|
+
having?: AggregateHaving;
|
|
73
|
+
orderBy?: Array<GroupedAggregateOrderTerm>;
|
|
74
|
+
limit?: number;
|
|
75
|
+
readAccess?: ViewerReadAccess;
|
|
76
|
+
}): Promise<Array<GroupedAggregateValue>>;
|
|
57
77
|
searchDocuments(params: {
|
|
58
78
|
query: string;
|
|
59
79
|
modelIDs: Array<string>;
|
|
@@ -64,15 +84,65 @@ export type ReadContextDB = {
|
|
|
64
84
|
rank: number;
|
|
65
85
|
}>>;
|
|
66
86
|
};
|
|
87
|
+
/**
|
|
88
|
+
* Query scope carried alongside a connection value so child resolvers (e.g.
|
|
89
|
+
* `aggregates`) can re-run against the exact same set of documents the page was
|
|
90
|
+
* built from. Shaped to feed the store aggregate query directly.
|
|
91
|
+
*/
|
|
92
|
+
export type AggregateScope = {
|
|
93
|
+
modelIDs: Array<string>;
|
|
94
|
+
filter?: DocumentFilter;
|
|
95
|
+
owner?: string;
|
|
96
|
+
catalogID?: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Connection value returned by {@link QueryContext.resolveConnection}. Extends
|
|
100
|
+
* the graphql-relay connection (edges/pageInfo are untouched) with the query
|
|
101
|
+
* scope so the `aggregates` field can resolve consistently with the page.
|
|
102
|
+
*/
|
|
103
|
+
export type ScopedConnection = Connection<DocumentNode> & {
|
|
104
|
+
aggregateScope: AggregateScope;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Aggregate request shaped by the connection's `aggregates` look-ahead: which
|
|
108
|
+
* ops over which fields were selected, plus whether a count was requested.
|
|
109
|
+
*/
|
|
110
|
+
export type ResolveAggregateParams = {
|
|
111
|
+
filter?: DocumentFilter;
|
|
112
|
+
owner?: string;
|
|
113
|
+
catalogID?: string;
|
|
114
|
+
count: boolean;
|
|
115
|
+
aggregates: Array<AggregateSpec>;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Grouped-aggregate request shaped by the connection's `groupedAggregates`
|
|
119
|
+
* look-ahead and field arguments: the aggregate ops/fields and count selected,
|
|
120
|
+
* plus the `groupBy` buckets, optional `having` predicate, group `orderBy` terms
|
|
121
|
+
* and `limit` translated from the field arguments.
|
|
122
|
+
*/
|
|
123
|
+
export type ResolveGroupedAggregateParams = {
|
|
124
|
+
filter?: DocumentFilter;
|
|
125
|
+
owner?: string;
|
|
126
|
+
catalogID?: string;
|
|
127
|
+
count: boolean;
|
|
128
|
+
aggregates: Array<AggregateSpec>;
|
|
129
|
+
groupBy: Array<{
|
|
130
|
+
keys: Array<string>;
|
|
131
|
+
}>;
|
|
132
|
+
having?: AggregateHaving;
|
|
133
|
+
orderBy?: Array<GroupedAggregateOrderTerm>;
|
|
134
|
+
limit?: number;
|
|
135
|
+
};
|
|
67
136
|
/**
|
|
68
137
|
* Query functions requiring server implementation
|
|
69
138
|
*/
|
|
70
139
|
export type QueryContext = {
|
|
71
140
|
getViewer(): string | null;
|
|
72
141
|
loadDocument(id: string): Promise<DocumentNode | null>;
|
|
73
|
-
resolveConnection(modelIDs: Array<string>, args: AllConnectionArguments): Promise<
|
|
142
|
+
resolveConnection(modelIDs: Array<string>, args: AllConnectionArguments): Promise<ScopedConnection>;
|
|
74
143
|
resolveList(modelIDs: Array<string>, ids: Array<string>): Promise<Array<DocumentNode>>;
|
|
75
|
-
|
|
144
|
+
resolveAggregate(modelIDs: Array<string>, params: ResolveAggregateParams): Promise<AggregateValues>;
|
|
145
|
+
resolveGroupedAggregate(modelIDs: Array<string>, params: ResolveGroupedAggregateParams): Promise<Array<GroupedAggregateValue>>;
|
|
76
146
|
searchDocuments(query: string, modelIDs: Array<string>, first?: number): Promise<Array<{
|
|
77
147
|
documentID: string;
|
|
78
148
|
modelID: string;
|
|
@@ -111,6 +181,7 @@ export type ReadContextParams = {
|
|
|
111
181
|
viewerDID: string;
|
|
112
182
|
catalogID?: string;
|
|
113
183
|
accessChecker?: AccessChecker;
|
|
184
|
+
viewerReadAccess?: ViewerReadAccess;
|
|
114
185
|
warnings?: Array<AccessWarning>;
|
|
115
186
|
complexity?: ComplexityStats;
|
|
116
187
|
tracer?: Tracer;
|
package/lib/context.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defer as e}from"@enkaku/async";import{withSpan as t}from"@enkaku/otel";import{DocumentID as o}from"@kubun/id";import{KubunAttributeKeys as
|
|
1
|
+
import{defer as e}from"@enkaku/async";import{withSpan as t}from"@enkaku/otel";import{DocumentID as o}from"@kubun/id";import{KubunAttributeKeys as r,KubunSpanNames as n}from"@kubun/protocol";export function createReadContext(l){let{store:a,viewerDID:i,accessChecker:s,viewerReadAccess:u}=l;function c(e,o,r){return null!=l.tracer?t(l.tracer,e,{attributes:o},async()=>r()):r()}function m(t,o){let r=!1,n=null,a=[];if(null==l.events)throw Error("Subscriptions require a document event emitter");let i=l.events.on("document:saved",e=>{if(t(e)){let t=o(e);null==n?a.push(t):(n.resolve(t),n=null)}}),s=()=>(i(),r=!0,Promise.resolve({done:!0,value:void 0}));return{[Symbol.asyncDispose]:()=>(i(),r=!0,Promise.resolve()),[Symbol.asyncIterator](){return this},next:()=>{if(r)return Promise.resolve({done:!0,value:void 0});let t=a.shift();return null!=t?Promise.resolve({value:t,done:!1}):(n=e()).promise.then(e=>({value:e,done:!1}))},return:s,throw:s}}return{getViewer:()=>i,async loadDocument(e){let t=`document:${e}`,i=l.complexity?.resolverTimings!=null?performance.now():0,u=await c(n.DATA_QUERY,{[r.DOCUMENT_ID]:e},async()=>{let t=await a.getDocument(o.fromString(e));return t&&null!=t.data?s&&!await s(t,"read")?(null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e}`,code:"KB07"}),null):(null!=l.complexity&&(l.complexity.resolverCount++,l.complexity.documentsScanned++),t):null});if(l.complexity?.resolverTimings!=null){let e=Math.round((performance.now()-i)*100)/100,o=l.complexity.resolverTimings.get(t)??0;l.complexity.resolverTimings.set(t,o+e)}return u},searchDocuments:async(e,t,o)=>await a.searchDocuments({query:e,modelIDs:t,first:o}),async resolveConnection(e,t){let o=`connection:${e.join(",")}`,i=l.complexity?.resolverTimings!=null?performance.now():0,u={modelIDs:e,filter:t.filter,owner:t.owner,catalogID:l.catalogID},m=await c(n.DATA_QUERY,{[r.MODEL_ID]:e.join(",")},async()=>{if(null!=t.search&&""!==t.search.trim()){let o=await a.searchDocuments({query:t.search,modelIDs:e,first:200});if(0===o.length){if(null!=l.complexity)for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);return{edges:[],pageInfo:{hasNextPage:!1,hasPreviousPage:!1,startCursor:null,endCursor:null}}}let r=o.map(e=>e.documentID),n=await a.listDocuments({modelIDs:e,docIDs:r}),i=n;if(s)for(let e of(i=[],n))await s(e,"read")?i.push(e):null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e.id}`,code:"KB07"});let u=new Map(o.map(e=>[e.documentID,e.rank]));i.sort((e,t)=>Math.abs(u.get(t.id)??0)-Math.abs(u.get(e.id)??0));let c=i.slice(0,t.first??50);if(null!=l.complexity){for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);l.complexity.documentsScanned+=c.length}return{edges:c.map((e,t)=>({cursor:String(t),node:e})),pageInfo:{hasNextPage:i.length>c.length,hasPreviousPage:!1,startCursor:c.length>0?"0":null,endCursor:c.length>0?String(c.length-1):null}}}if(null==s){let{entries:o,hasMore:r}=await a.queryDocuments({...t,modelIDs:e,catalogID:l.catalogID});if(null!=l.complexity){for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);l.complexity.documentsScanned+=o.length}return{edges:o.map(e=>({cursor:e.cursor,node:e.document})),pageInfo:{hasNextPage:!!t.first&&r,hasPreviousPage:!t.first&&r,endCursor:o.at(-1)?.cursor??null,startCursor:o.at(0)?.cursor??null}}}let o=[],r=0,n=0;if(null==t.first&&null==t.last){let{entries:n}=await a.queryDocuments({...t,modelIDs:e,catalogID:l.catalogID});for(let e of n)await s(e.document,"read")?o.push(e):null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e.document.id}`,code:"KB07"});r=o.length}else if(null!=t.first){let i=2*(r=t.first),u=t.after;for(;o.length<r&&n<10;){let{entries:c,hasMore:m}=await a.queryDocuments({...t,modelIDs:e,catalogID:l.catalogID,first:i,after:u});if(0===c.length&&!m)break;for(let e of c)if(await s(e.document,"read")){if(o.push(e),o.length>=r)break}else null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e.document.id}`,code:"KB07"});if(!m)break;u=c.at(-1)?.cursor??null,n++}}else if(null!=t.last){let i=2*(r=t.last),u=t.before;for(;o.length<r&&n<10;){let{entries:c,hasMore:m}=await a.queryDocuments({...t,modelIDs:e,catalogID:l.catalogID,last:i,before:u});if(0===c.length&&!m)break;for(let e of[...c].reverse())if(await s(e.document,"read")){if(o.unshift(e),o.length>=r)break}else null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e.document.id}`,code:"KB07"});if(!m)break;u=c.at(0)?.cursor??null,n++}}let i=o.slice(0,r),u=o.length>r;if(null!=l.complexity){for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);l.complexity.documentsScanned+=i.length}return{edges:i.map(e=>({cursor:e.cursor,node:e.document})),pageInfo:{hasNextPage:!!t.first&&u,hasPreviousPage:!t.first&&u,endCursor:i.at(-1)?.cursor??null,startCursor:i.at(0)?.cursor??null}}});if(l.complexity?.resolverTimings!=null){let e=Math.round((performance.now()-i)*100)/100,t=l.complexity.resolverTimings.get(o)??0;l.complexity.resolverTimings.set(o,t+e)}return{...m,aggregateScope:u}},async resolveList(e,t){let o=`list:${e.join(",")}`,i=l.complexity?.resolverTimings!=null?performance.now():0,u=await c(n.DATA_QUERY,{[r.MODEL_ID]:e.join(",")},async()=>{let o=await a.listDocuments({modelIDs:e,docIDs:t});if(!s){if(null!=l.complexity){for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);l.complexity.documentsScanned+=o.length}return o}let r=[];for(let e of o)await s(e,"read")?r.push(e):null!=l.warnings&&l.warnings.push({message:`Access denied for document ${e.id}`,code:"KB07"});if(null!=l.complexity){for(let t of(l.complexity.resolverCount++,e))l.complexity.modelsQueried.add(t);l.complexity.documentsScanned+=r.length}return r});if(l.complexity?.resolverTimings!=null){let e=Math.round((performance.now()-i)*100)/100,t=l.complexity.resolverTimings.get(o)??0;l.complexity.resolverTimings.set(o,t+e)}return u},async resolveAggregate(e,t){let o=`aggregate:${e.join(",")}`,i=l.complexity?.resolverTimings!=null?performance.now():0,s=await c(n.DATA_QUERY,{[r.MODEL_ID]:e.join(",")},async()=>(null!=l.complexity&&l.complexity.resolverCount++,await a.aggregateDocuments({modelIDs:e,filter:t.filter,owner:t.owner,catalogID:t.catalogID??l.catalogID,count:t.count,aggregates:t.aggregates,readAccess:u})));if(l.complexity?.resolverTimings!=null){let e=Math.round((performance.now()-i)*100)/100,t=l.complexity.resolverTimings.get(o)??0;l.complexity.resolverTimings.set(o,t+e)}return s},async resolveGroupedAggregate(e,t){let o=`grouped-aggregate:${e.join(",")}`,i=l.complexity?.resolverTimings!=null?performance.now():0,s=await c(n.DATA_QUERY,{[r.MODEL_ID]:e.join(",")},async()=>(null!=l.complexity&&l.complexity.resolverCount++,await a.groupedAggregateDocuments({modelIDs:e,filter:t.filter,owner:t.owner,catalogID:t.catalogID??l.catalogID,count:t.count,aggregates:t.aggregates,groupBy:t.groupBy,having:t.having,orderBy:t.orderBy,limit:t.limit,readAccess:u})));if(l.complexity?.resolverTimings!=null){let e=Math.round((performance.now()-i)*100)/100,t=l.complexity.resolverTimings.get(o)??0;l.complexity.resolverTimings.set(o,t+e)}return s},subscribeToDocumentCreated(e,t){let o=m(o=>"create"===o.type&&e.includes(o.document.model)&&(null==t||o.document.owner===t),e=>e.document);return s?async function*(){for await(let e of o)await s(e,"read")&&(yield e)}():o},subscribeToDocumentChanged(e){let t=m(t=>"update"===t.type&&t.document.id===e&&null!==t.document.data,e=>e.document);return s?async function*(){for await(let e of t)await s(e,"read")&&(yield e)}():t},subscribeToDocumentRemoved:()=>m(e=>"update"===e.type&&null===e.document.data,e=>e.document.id),subscribeToDocumentEdgeAdded(e,t){let o=m(o=>null!==o.document.data&&e.includes(o.document.model)&&t(o.document.data)&&("create"===o.type||null!==o.previous.data&&t(o.previous.data)),e=>({cursor:e.getCursor(),node:e.document}));return s?async function*(){for await(let e of o)await s(e.node,"read")&&(yield e)}():o},subscribeToDocumentEdgeRemoved:(e,t)=>m(o=>"update"===o.type&&e.includes(o.document.model)&&null!==o.previous.data&&t(o.previous.data)&&(null===o.document.data||!t(o.document.data)),e=>e.document.id)}}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { AccessWarning, ComplexityStats, Context, CreateMutationParams, DocumentEventEmitter, DocumentSavedEvent, MutationContext, PluginContextMap, QueryContext, ReadContextDB, ReadContextParams, ReadOnlyContext, RemoveMutationParams, SetDocumentAccessOverrideParams, SetModelAccessDefaultsParams, SetMutationParams, SubscriptionContext, UpdateMutationParams, } from './context.js';
|
|
1
|
+
export type { AccessWarning, AggregateScope, ComplexityStats, Context, CreateMutationParams, DocumentEventEmitter, DocumentSavedEvent, MutationContext, PluginContextMap, QueryContext, ReadContextDB, ReadContextParams, ReadOnlyContext, RemoveMutationParams, ScopedConnection, SetDocumentAccessOverrideParams, SetModelAccessDefaultsParams, SetMutationParams, SubscriptionContext, UpdateMutationParams, } from './context.js';
|
|
2
2
|
export { createReadContext } from './context.js';
|
|
3
3
|
export { GraphQLAttachmentID, GraphQLDocID } from './identifiers.js';
|
|
4
4
|
export type { ExtensionResolvers, SchemaBuilderParams, SharedDefinitions, } from './schema.js';
|
package/lib/schema.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AttachmentID, DocumentModelID } from '@kubun/id';
|
|
2
|
-
import type { ArrayModel, DocumentData, DocumentModel, DocumentModelSchema, DocumentModelsRecord, DocumentNode, ObjectModel, ReferencesRecordModel, ScalarModel, StringCustomModel, StringEnumModel, StringFormatModel, StringModel, TypeModel } from '@kubun/protocol';
|
|
3
|
-
import { GraphQLEnumType, type GraphQLFieldConfig, type GraphQLFieldConfigMap, type GraphQLFieldResolver, GraphQLInputObjectType, type GraphQLInputType, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, type GraphQLOutputType, type GraphQLScalarType, GraphQLSchema } from 'graphql';
|
|
2
|
+
import type { AggregateHaving, AggregateSpec, ArrayModel, DocumentData, DocumentModel, DocumentModelSchema, DocumentModelsRecord, DocumentNode, GroupedAggregateOrderTerm, ObjectModel, OrderByDirection as OrderByDirectionValue, ReferencesRecordModel, ScalarModel, StringCustomModel, StringEnumModel, StringFormatModel, StringModel, TypeModel } from '@kubun/protocol';
|
|
3
|
+
import { type FieldNode, GraphQLEnumType, type GraphQLFieldConfig, type GraphQLFieldConfigMap, type GraphQLFieldResolver, GraphQLInputObjectType, type GraphQLInputType, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, type GraphQLOutputType, type GraphQLResolveInfo, type GraphQLScalarType, GraphQLSchema, type SelectionNode } from 'graphql';
|
|
4
4
|
import type { Context } from './context.js';
|
|
5
5
|
export declare function toDocumentModelID(id: DocumentModelID | string): DocumentModelID;
|
|
6
6
|
export declare function getGlobalID(id: DocumentModelID | string, globalID: DocumentModelID | string): DocumentModelID;
|
|
@@ -48,10 +48,36 @@ export type SchemaBuilderParams = {
|
|
|
48
48
|
extensionResolvers?: ExtensionResolvers;
|
|
49
49
|
stubExtensionResolvers?: boolean;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* One `GroupOrderBy` argument entry. Each present leaf names a finalised-group
|
|
53
|
+
* value to order by, with its direction. The same shape covers the keys and each
|
|
54
|
+
* aggregate op; only the leaves the caller selected are present.
|
|
55
|
+
*/
|
|
56
|
+
export type GroupOrderBy = {
|
|
57
|
+
keys?: Record<string, OrderByDirectionValue>;
|
|
58
|
+
count?: OrderByDirectionValue;
|
|
59
|
+
sum?: Record<string, OrderByDirectionValue>;
|
|
60
|
+
average?: Record<string, OrderByDirectionValue>;
|
|
61
|
+
min?: Record<string, OrderByDirectionValue>;
|
|
62
|
+
max?: Record<string, OrderByDirectionValue>;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Resolved arguments of the `groupedAggregates` connection field. `groupBy` is a
|
|
66
|
+
* list of groupable field-key enum values; `having` mirrors {@link AggregateHaving}
|
|
67
|
+
* exactly (the value-filter operator names match), so it passes through untouched.
|
|
68
|
+
*/
|
|
69
|
+
export type GroupedAggregateArguments = {
|
|
70
|
+
groupBy?: Array<string>;
|
|
71
|
+
having?: AggregateHaving;
|
|
72
|
+
orderBy?: Array<GroupOrderBy>;
|
|
73
|
+
limit?: number | null;
|
|
74
|
+
};
|
|
51
75
|
export declare class SchemaBuilder {
|
|
52
76
|
#private;
|
|
53
77
|
_aliases: Record<string, string>;
|
|
54
78
|
_aliasToModelID: Record<string, string>;
|
|
79
|
+
_aggregateNumericByModel: Record<string, Map<string, boolean>>;
|
|
80
|
+
_groupKeyNumericByModel: Record<string, Map<string, boolean>>;
|
|
55
81
|
_definitions: SharedDefinitions | undefined;
|
|
56
82
|
_implemented: Record<string, Array<string>>;
|
|
57
83
|
_includedModelIDs: Set<string>;
|
|
@@ -85,6 +111,76 @@ export declare class SchemaBuilder {
|
|
|
85
111
|
_getReferenceInput(path: string, isPartial: boolean, parentName?: string): GraphQLInputType;
|
|
86
112
|
_buildSharedDefinitions(): SharedDefinitions;
|
|
87
113
|
_buildDocument(id: string): GraphQLObjectType<DocumentNode, Context> | GraphQLInterfaceType;
|
|
114
|
+
/**
|
|
115
|
+
* Build the `<Model>Aggregate` type attached to the connection, exposing `count`
|
|
116
|
+
* plus per-field `sum`/`average`/`min`/`max` selections gated by field type.
|
|
117
|
+
*
|
|
118
|
+
* Eligibility follows what SQL can faithfully compute over JSON-extracted values:
|
|
119
|
+
* - sum/average: numeric fields only (integer, number).
|
|
120
|
+
* - min/max: numeric fields plus string/date fields (lexical for strings).
|
|
121
|
+
* Field-selection subtypes are only emitted when at least one field qualifies,
|
|
122
|
+
* since an object type with no fields is invalid GraphQL. `count` is always present.
|
|
123
|
+
*/
|
|
124
|
+
_buildAggregate(id: string, model: DocumentModel, name: string): GraphQLObjectType;
|
|
125
|
+
/**
|
|
126
|
+
* Build the grouped-aggregate type surface for a model, reusing the v1
|
|
127
|
+
* `<Model>SumFields` / `AvgFields` / `MinMaxFields` types from
|
|
128
|
+
* `_buildAggregate` and the existing value-filter / `OrderByDirection` inputs.
|
|
129
|
+
*
|
|
130
|
+
* Groupable fields are every property resolving to a scalar (object/array fields
|
|
131
|
+
* excluded), which is broader than aggregate eligibility: boolean and enum fields
|
|
132
|
+
* can be grouped on but never summed. The sum/average and min/max sub-shapes are
|
|
133
|
+
* only emitted when the model actually has those eligible fields, matching the
|
|
134
|
+
* conditionals in `_buildAggregate`, since an object type with no fields is invalid.
|
|
135
|
+
*
|
|
136
|
+
* Produces, registered in `_types` / `_inputObjects`:
|
|
137
|
+
* `<Model>GroupBy` enum, `<Model>GroupKeys`, `<Model>GroupedAggregate`,
|
|
138
|
+
* `<Model>Having` (+ `HavingSum`/`HavingAverage`/`HavingMin`/`HavingMax`),
|
|
139
|
+
* `<Model>GroupOrderBy` (+ `GroupKeysOrderBy` and per-op `<Op>FieldsOrderBy`).
|
|
140
|
+
*/
|
|
141
|
+
_buildGroupedAggregate(id: string, model: DocumentModel, name: string): GraphQLObjectType | null;
|
|
142
|
+
/**
|
|
143
|
+
* Inspect the selection set under the `aggregates` field to determine exactly
|
|
144
|
+
* which aggregation work to ask the store for: whether a count was selected,
|
|
145
|
+
* and for each of sum/average/min/max, which field subselections were
|
|
146
|
+
* requested. Field aggregates not selected are never computed, so a
|
|
147
|
+
* `{ count }`-only query issues `aggregates: []`.
|
|
148
|
+
*
|
|
149
|
+
* Reads the resolved field nodes via `info.fieldNodes`. Selections reached
|
|
150
|
+
* through fragment spreads and inline fragments are expanded transparently, so
|
|
151
|
+
* `aggregates { ...AggFields }`, `aggregates { ... { count } }` and
|
|
152
|
+
* `sum { ...SumFields }` all request the same work as their inlined forms.
|
|
153
|
+
*/
|
|
154
|
+
_buildAggregateRequest(id: string, info: GraphQLResolveInfo): {
|
|
155
|
+
count: boolean;
|
|
156
|
+
aggregates: Array<AggregateSpec>;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Inspect the selection set under the `groupedAggregates` field to determine the
|
|
160
|
+
* aggregation work to ask the store for. The aggregate ops (`count`/`sum`/
|
|
161
|
+
* `average`/`min`/`max`) are nested directly under the field alongside `keys`,
|
|
162
|
+
* which is skipped here since it is shaped by the `groupBy` argument, not the
|
|
163
|
+
* selection. Fragment spreads and inline fragments are expanded transparently.
|
|
164
|
+
* Selecting only `keys` and `count` yields `aggregates: []`.
|
|
165
|
+
*/
|
|
166
|
+
_buildGroupedAggregateRequest(id: string, info: GraphQLResolveInfo): {
|
|
167
|
+
count: boolean;
|
|
168
|
+
aggregates: Array<AggregateSpec>;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Translate the `orderBy` argument entries into store ordering terms over each
|
|
172
|
+
* finalised group. Each entry's present leaves become a term whose `path`
|
|
173
|
+
* navigates the group object (`['count']`, `['keys', field]`, `['sum', field]`,
|
|
174
|
+
* etc.) and whose `numeric` flag drives arithmetic comparison. List order is
|
|
175
|
+
* preserved so earlier terms take precedence and later terms break ties.
|
|
176
|
+
*/
|
|
177
|
+
_buildGroupOrderBy(id: string, orderBy: Array<GroupOrderBy> | undefined): Array<GroupedAggregateOrderTerm>;
|
|
178
|
+
/**
|
|
179
|
+
* Walk a selection set and yield the underlying field nodes, expanding
|
|
180
|
+
* fragment spreads and inline fragments in place. The `visited` set tracks
|
|
181
|
+
* named fragments already entered so cyclic fragment references terminate.
|
|
182
|
+
*/
|
|
183
|
+
_expandFieldSelections(selections: ReadonlyArray<SelectionNode>, info: GraphQLResolveInfo, visited: Set<string>): Generator<FieldNode>;
|
|
88
184
|
_buildDocumentFields(id: string, model: DocumentModel, name: string): GraphQLFieldConfigMap<DocumentNode, Context>;
|
|
89
185
|
_buildDocumentDataObject(id: string, model: DocumentModel, name: string): GraphQLInterfaceType | GraphQLObjectType<DocumentData, Context>;
|
|
90
186
|
_buildDocumentInput(id: string, model: DocumentModel): void;
|
package/lib/schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AttachmentID as e,DocumentID as t,DocumentModelID as i,decodeID as n,PluginNodeID as s}from"@kubun/id";import{REFERENCE_PREFIX as l}from"@kubun/protocol";import{pascalCase as r}from"change-case";import{extendSchema as o,GraphQLBoolean as a,GraphQLEnumType as u,GraphQLFloat as c,GraphQLID as d,GraphQLInputObjectType as p,GraphQLInt as f,GraphQLInterfaceType as h,GraphQLList as y,GraphQLNonNull as m,GraphQLObjectType as _,GraphQLSchema as b,GraphQLString as w,isEnumType as D,isListType as g,isNonNullType as I,isObjectType as O,isScalarType as v,parse as $}from"graphql";import{connectionArgs as j,connectionDefinitions as S,mutationWithClientMutationId as F,nodeDefinitions as M}from"graphql-relay";import{GraphQLDateTimeISO as T,GraphQLDID as R,GraphQLDuration as L,GraphQLEmailAddress as E,GraphQLJSON as x,GraphQLJSONObject as A}from"graphql-scalars";import{GraphQLAttachmentID as q,GraphQLDocID as C}from"./identifiers.js";import{GraphQLURL as G}from"./scalars.js";import{getUniqueDocValue as P,validateAccessIdentifiers as N}from"./utils.js";function V(e){if(I(e))return V(e.ofType);if(g(e))return[];if(v(e))switch(e.name){case"String":case"ID":return"";case"Int":case"Float":return 0;case"Boolean":return!1;default:return null}if(D(e)){let t=e.getValues();return t[0]?.value??null}return{}}let k={date:w,time:w,"date-time":w,duration:L,email:E,uri:G},B={attachmentid:q,did:R,docid:C};function Q(e){return e.slice(l.length)}function U(e){return g(e)||I(e)&&g(e.ofType)}export function toDocumentModelID(e){return e instanceof i?e:i.fromString(e)}export function getGlobalID(e,t){let i=toDocumentModelID(e);return i.isLocal?i.toGlobal(toDocumentModelID(t)):i}export function toList(e){return new y(new m(e))}export function toOuputList(e){return new y(new m(e))}function W(e){return new p({name:`${e.name}ValueFilter`,isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:e},notEqualTo:{type:e},in:{type:toList(e)},notIn:{type:toList(e)},lessThan:{type:e},lessThanOrEqualTo:{type:e},greaterThan:{type:e},greaterThanOrEqualTo:{type:e}}})}let z={AccountValueFilter:new p({name:"AccountValueFilter",isOneOf:!0,fields:{equalTo:{type:R},notEqualTo:{type:R},in:{type:toList(R)},notIn:{type:toList(R)}}}),BooleanValueFilter:new p({name:"BooleanValueFilter",isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:a}}}),FloatValueFilter:W(c),IntValueFilter:W(f),StringValueFilter:W(w)},H={GraphQLBoolean:"BooleanValueFilter",GraphQLDID:"AccountValueFilter",GraphQLFloat:"FloatValueFilter",GraphQLInt:"IntValueFilter",GraphQLString:"StringValueFilter"},J=new p({name:"PatchSetOperation",fields:{path:{type:new m(w)},value:{type:x}}}),K=new p({name:"PatchRemoveOperation",fields:{path:{type:new m(w)}}}),X=new p({name:"PatchDestinationOperation",fields:{from:{type:new m(w)},path:{type:new m(w)}}});export const PatchOperation=new p({name:"PatchOperation",isOneOf:!0,fields:{add:{type:J},set:{type:J},remove:{type:K},replace:{type:J},copy:{type:X},move:{type:X}}});let Y=new u({name:"OrderByDirection",values:{ASC:{value:"asc"},DESC:{value:"desc"}}}),Z=new _({name:"AccessRule",fields:{level:{type:new m(w)},allowedDIDs:{type:new y(new m(w))},allowedCircles:{type:new y(new m(w))},allowedGroups:{type:new y(new m(w))}}}),ee=new _({name:"AccessPermissions",fields:{read:{type:Z},write:{type:Z}}}),et=new _({name:"ModelAccessDefaults",fields:()=>({ownerDID:{type:new m(w)},modelID:{type:new m(d)},permissions:{type:new m(ee)}})});export class SchemaBuilder{_aliases;_aliasToModelID;_definitions;_implemented={};_includedModelIDs;_includeInterfaceDependencies;_includeMutations;_includeRelationDependencies;_includeSubscriptions;_inputObjects={...z,PatchOperation};_mutations={};_nodeModelIDs;_onlyModels;_record;_references={};_relationsTo={};_extensionSDL;_extensionResolvers;_stubExtensionResolvers;_pluginNodeResolvers={};_subscriptions={};_types={OrderByDirection:Y};constructor(e){for(let[t,i]of(this._record=e.record,this._onlyModels=e.onlyModels??null,this._includeInterfaceDependencies=e.includeInterfaceDependencies??!0,this._includeRelationDependencies=e.includeRelationDependencies??!0,this._includeMutations=e.includeMutations??!0,this._includeSubscriptions=e.includeSubscriptions??!0,this._extensionSDL=e.extensionSDL,this._extensionResolvers=e.extensionResolvers,this._stubExtensionResolvers=e.stubExtensionResolvers??!1,this._aliasToModelID=e.aliases??{},this._aliases={},Object.entries(this._aliasToModelID)))this._aliases[i]=t;for(let[t,i]of Object.entries(e.record))if(null==this._aliases[t]){let e=r(i.name);this._aliases[t]=e,this._aliasToModelID[e]??=t}this._includedModelIDs=this._resolveModelIDsToInclude();let t={};for(let[n,s]of Object.entries(e.record)){let e=i.fromString(n);for(let i of(Object.assign(this._references,s.schema.$defs??{}),s.interfaces)){let s=getGlobalID(i,e).toString();t[s]??=new Set,t[s].add(n)}for(let[t,i]of Object.entries(s.fieldsMeta))if("document"===i.type&&null!=i.model){let l=Q(s.schema.properties[t]?.$ref),r="array"===this._getReferenceSchema(l).type,o=getGlobalID(i.model,e).toString();this._relationsTo[o]??={},this._relationsTo[o][t]??=[],this._relationsTo[o][t].push({model:n,isList:r})}}let n=new Set;for(let e of Object.keys(t)){let i=new Set;for(let s of(!function e(t,i,n){let s=i[n];if(null==s)throw Error(`Interface ${n} not found in record`);for(let n of s)null!=i[n]?e(t,i,n):t.add(n)}(i,t,e),0!==i.size&&(this._implemented[e]=Array.from(i)),i))n.add(s)}this._nodeModelIDs=Array.from(n)}_resolveModelIdentifier(e){if(null!=this._record[e])return e;let t=this._aliasToModelID[e];if(null!=t&&null!=this._record[t])return t;throw Error(`Model identifier "${e}" not found. Must be a valid model ID or alias.`)}_resolveModelIDsToInclude(){if(null==this._onlyModels||0===this._onlyModels.length)return new Set(Object.keys(this._record));let e=new Set;for(let t of this._onlyModels){let i=this._resolveModelIdentifier(t);e.add(i)}if(!this._includeInterfaceDependencies&&!this._includeRelationDependencies)return e;let t=Array.from(e),i=new Set;for(;t.length>0;){let n=t.pop();if(null==n||i.has(n))continue;i.add(n);let s=this._record[n];if(null!=s){if(this._includeInterfaceDependencies)for(let i of s.interfaces){let s=getGlobalID(i,n).toString();e.has(s)||(e.add(s),t.push(s))}if(this._includeRelationDependencies){for(let i of Object.values(s.fieldsMeta))if("document"===i.type&&null!=i.model&&null!==i.model){let s=getGlobalID(i.model,n).toString();e.has(s)||(e.add(s),t.push(s))}}}}return e}getModelIDs(e){return null===e?this._nodeModelIDs:this._implemented[e]??[e]}build(){let e=this._buildSharedDefinitions();this._definitions=e;let t={nodes:e.nodesField,...e.queryFields};for(let e of this._includedModelIDs){this._buildDocument(e);let i=this._aliases[e],n={type:this._inputObjects[`${e}-filter`]};t[`all${i}`]={type:this._types[`${e}-connection`],args:{...j,filter:n,orderBy:{type:toList(this._inputObjects[`${e}-order`])},search:{type:w}},resolve:async(t,i,n)=>await n.resolveConnection(this.getModelIDs(e),i)},t[`all${i}Count`]={type:new m(f),args:{filter:n},resolve:(t,i,n)=>n.resolveCount(this.getModelIDs(e),i.filter)}}let i=[...this._includedModelIDs][0];if(null!=i){let n=this._types[`${i}-connection`].getFields().pageInfo.type,s=new _({name:"SearchResultEdge",fields:()=>({cursor:{type:new m(w)},node:{type:new m(e.nodeInterface)},rank:{type:new m(c)}})}),l=new _({name:"SearchResultConnection",fields:()=>({edges:{type:new m(new y(new m(s)))},pageInfo:{type:n}})});t.search={type:new m(l),args:{query:{type:new m(w)},models:{type:new y(new m(w))},first:{type:f},after:{type:w}},resolve:async(e,t,i)=>{let{query:n,models:s,first:l}=t;if(""===n.trim())throw Error("Search query must not be empty");let r=s?s.map(e=>this._aliasToModelID[e]??e):[...this._includedModelIDs],o=await i.searchDocuments(n,r,l??20),a=o.map(e=>e.documentID),u=[...new Set(o.map(e=>e.modelID))],c=new Map((a.length>0?await i.resolveList(u,a):[]).map(e=>[e.id,e])),d=[];for(let e of o){let t=c.get(e.documentID);null!=t&&d.push({cursor:String(d.length),node:t,rank:Math.abs(e.rank)})}return{edges:d,pageInfo:{hasNextPage:!1,hasPreviousPage:!1,startCursor:d.length>0?d[0].cursor:null,endCursor:d.length>0?d[d.length-1].cursor:null}}}}}if(this._includeMutations){this._mutations.setModelAccessDefaults={type:et,args:{modelID:{type:new m(d)},permissionType:{type:new m(w)},accessLevel:{type:new m(w)},allowedDIDs:{type:toList(w)},allowedCircles:{type:toList(w)},allowedGroups:{type:toList(w)}},resolve:async(e,t,i)=>{let n=t.allowedDIDs??null,s=t.allowedCircles??null,l=t.allowedGroups??null;return N({allowedDIDs:n,allowedCircles:s,allowedGroups:l}),await i.executeSetModelAccessDefaults({modelID:t.modelID,permissionType:t.permissionType,accessLevel:t.accessLevel,allowedDIDs:n,allowedCircles:s,allowedGroups:l})}},this._mutations.removeModelAccessDefaults={type:a,args:{modelID:{type:new m(d)},permissionTypes:{type:new m(toList(w))}},resolve:async(e,t,i)=>(await i.executeRemoveModelAccessDefaults(t.modelID,t.permissionTypes),!0)},this._mutations.setDocumentAccessOverride={type:e.documentInterface,args:{documentID:{type:new m(d)},permissionType:{type:new m(w)},accessLevel:{type:new m(w)},allowedDIDs:{type:toList(w)},allowedCircles:{type:toList(w)},allowedGroups:{type:toList(w)}},resolve:async(e,t,i)=>{let n=t.allowedDIDs??null,s=t.allowedCircles??null,l=t.allowedGroups??null;return N({allowedDIDs:n,allowedCircles:s,allowedGroups:l}),await i.executeSetDocumentAccessOverride({documentID:t.documentID,permissionType:t.permissionType,accessLevel:t.accessLevel,allowedDIDs:n,allowedCircles:s,allowedGroups:l})}},this._mutations.removeDocumentAccessOverride={type:a,args:{documentID:{type:new m(d)},permissionTypes:{type:new m(toList(w))}},resolve:async(e,t,i)=>(await i.executeRemoveDocumentAccessOverride(t.documentID,t.permissionTypes),!0)};let t=new _({name:"BeginTransactionPayload",fields:{transactionID:{type:new m(d)}}}),i=new _({name:"CommitTransactionPayload",fields:{success:{type:new m(a)}}}),n=new _({name:"RollbackTransactionPayload",fields:{success:{type:new m(a)}}});this._mutations.beginTransaction={type:new m(t),args:{},resolve:(e,t,i)=>i.beginTransaction()},this._mutations.commitTransaction={type:new m(i),args:{transactionID:{type:new m(d)}},resolve:async(e,t,i)=>await i.commitTransaction(t.transactionID)},this._mutations.rollbackTransaction={type:new m(n),args:{transactionID:{type:new m(d)}},resolve:(e,t,i)=>i.rollbackTransaction(t.transactionID)}}let n={query:new _({name:"Query",fields:t}),types:[G,R,T]};this._includeMutations&&(n.mutation=new _({name:"Mutation",fields:this._mutations})),this._includeSubscriptions&&(n.subscription=new _({name:"Subscription",fields:()=>{let t={...this._subscriptions};if(this._includeSubscriptions)for(let[i,n]of(t.documentChanged={type:new m(e.documentInterface),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,i)=>i.subscribeToDocumentChanged(t.id)},t.documentRemoved={type:new m(d),resolve:e=>e,subscribe:(e,t,i)=>i.subscribeToDocumentRemoved()},Object.entries(this._record))){if(!this._includedModelIDs.has(i))continue;let e=this._aliases[i];for(let s of(t[`new${e}Created`]={type:new m(this._types[i]),args:{owner:{type:d}},resolve:e=>e,subscribe:(e,t,n)=>n.subscribeToDocumentCreated(this.getModelIDs(i),t.owner??void 0)},n.interfaces??[])){let e=getGlobalID(s,i).toString();for(let[i,n]of Object.entries(this._relationsTo[e]??{}))for(let s of n)this._buildRelationSubscriptions(t,e,i,s)}for(let[e,n]of Object.entries(this._relationsTo[i]??{}))for(let s of n)this._includedModelIDs.has(s.model)&&this._buildRelationSubscriptions(t,i,e,s)}return t}}));let s=new b(n);if(null!=this._extensionSDL){let e=new Set(Object.keys(s.getTypeMap()));s=o(s,$(this._extensionSDL)),this._stubExtensionResolvers&&this.#e(s,e)}return null!=this._extensionResolvers&&this.#t(s,this._extensionResolvers),s}#t(e,t){let i=e.getQueryType();if(null!=i&&null!=t.queryFields){let e=i.getFields();for(let[i,n]of Object.entries(t.queryFields)){if(null==e[i])throw Error(`Extension resolver for query field "${i}" has no matching field in SDL`);e[i].resolve=n}}let n=e.getMutationType();if(null!=n&&null!=t.mutationFields){let e=n.getFields();for(let[i,n]of Object.entries(t.mutationFields)){if(null==e[i])throw Error(`Extension resolver for mutation field "${i}" has no matching field in SDL`);e[i].resolve=n}}let s=e.getSubscriptionType();if(null!=s&&null!=t.subscriptionFields){let e=s.getFields();for(let[i,n]of Object.entries(t.subscriptionFields)){if(null==e[i])throw Error(`Extension resolver for subscription field "${i}" has no matching field in SDL`);e[i].resolve=n.resolve,e[i].subscribe=n.subscribe}}if(null!=t.typeFields)for(let[i,n]of Object.entries(t.typeFields)){let t=e.getType(i);if(null==t)throw Error(`Extension resolver references type "${i}" which does not exist in the schema`);if(!O(t))throw Error(`Extension resolver references type "${i}" which is not an object type`);let s=t.getFields();for(let[e,t]of Object.entries(n)){if(null==s[e])throw Error(`Extension resolver for field "${e}" on type "${i}" has no matching field in SDL`);s[e].resolve=t}}if(null!=t.nodeResolvers)for(let[e,i]of Object.entries(t.nodeResolvers))this._pluginNodeResolvers[e]=i}#e(e,t){for(let t of[e.getQueryType(),e.getMutationType()])if(null!=t)for(let e of Object.values(t.getFields()))null==e.resolve&&(e.resolve=()=>V(e.type));for(let[i,n]of Object.entries(e.getTypeMap()))if(!t.has(i)&&O(n)){for(let e of Object.values(n.getFields()))if(null==e.resolve){let t=e.type;e.resolve=i=>i[e.name]??V(t)}}}_getDefinitions(){if(null==this._definitions)throw Error("Definitions must be initialized");return this._definitions}_getReference(e,t){let i=Q(e),n=this._types[i];if(null!=n)return n;let s=this._getReferenceSchema(i);return this._buildReference(i,s,t)}_getReferenceSchema(e){let t=this._references[e];if(null==t)throw Error(`Could not find reference: ${e}`);return t}_getReferenceInput(e,t,i=""){let n=Q(e),s=this._getReferenceSchema(n);if("array"===s.type)return new y(new m(this._getReferenceInput(s.items.$ref,!1,s.title)));if("object"===s.type){if(s.additionalProperties)return A;let e=t?`${n}-partial`:n,l=this._inputObjects[e];if(null!=l)return l;let o={};for(let[e,i]of Object.entries(s.properties)){let n=this._getReferenceInput(i.$ref,t,s.title);o[e]={type:t||!s.required.includes(e)?n:new m(n)}}let a=this._aliases[n]??r(i+s.title),u=new p({name:t?`Partial${a}Input`:`${a}Input`,fields:o});return this._inputObjects[e]=u,u}return this._buildScalar(n,s,i)}_buildSharedDefinitions(){let i=M(async(i,l)=>{if(i.startsWith("did:"))return i;let r=n(i);if(r instanceof e)return r;if(r instanceof t)return await l.loadDocument(i);if(r instanceof s){let e=this._pluginNodeResolvers[r.typeName];if(null==e)throw Error(`No node resolver registered for plugin type "${r.typeName}"`);let t=await e.resolve(r.localID,l);if(null==t)throw Error(`Node resolver for "${r.typeName}" returned null for localID "${r.localID}"`);return{...t,__typename:r.typeName}}throw Error(`Unsupported node ID: ${i}`)},t=>{if("string"==typeof t)return"AccountNode";if(t instanceof e)return"AttachmentNode";if(null!=t&&"object"==typeof t&&"model"in t)return this._aliases[t.model];if(null!=t&&"object"==typeof t&&"__typename"in t)return t.__typename;throw Error("Unknown node type")}),l=new _({name:"AccountNode",interfaces:[i.nodeInterface],fields:()=>{let e={id:{type:new m(d),description:"Globally unique identifier of the account (DID string)",resolve:e=>e},isViewer:{type:new m(a),description:"Whether the authenticated request issuer is this account or not",resolve:(e,t,i)=>i.getViewer()===e}};for(let[i,n]of Object.entries(this._record))if(this._includedModelIDs.has(i))switch(n.behavior){case"interface":continue;case"default":{let t=this._aliases[i];e[`own${t}Connection`]={type:this._types[`${i}-connection`],args:{...j,filter:{type:this._inputObjects[`${i}-filter`]},orderBy:{type:toList(this._inputObjects[`${i}-order`])}},resolve:async(e,t,n)=>await n.resolveConnection(this.getModelIDs(i),{...t,owner:e})};break}case"unique":{let s=this._aliases[i];e[`own${s}`]={type:this._types[i],args:n.uniqueFields.length?{with:{type:new m(this._buildSetInputObjectType(i,n.uniqueFields))}}:{},resolve:async(e,s,l)=>{let r=P(n.uniqueFields,s.with),o=t.create(i,e,r);return await l.loadDocument(o.toString())}}}}return e}}),r=new _({name:"AttachmentNode",interfaces:[i.nodeInterface],fields:{id:{type:new m(d),resolve:e=>e.toString()},contentLength:{type:new m(f)},mimeType:{type:new m(w)}}}),o={id:{type:new m(d)},model:{type:new m(w)},owner:{type:new m(l)},createdAt:{type:new m(T)},updatedAt:{type:T},accessPermissions:{type:ee,resolve:e=>e.data?.accessPermissions??null}},u=new h({name:"DocumentNode",interfaces:[i.nodeInterface],fields:o,resolveType:e=>this._aliases[e.model]}),c={node:i.nodeField,viewer:{type:l,description:"Account issuing the request, if authenticated",resolve:(e,t,i)=>i.getViewer()}};return{...i,accountObject:l,attachmentObject:r,documentInterface:u,documentNodeFields:o,queryFields:c}}_buildDocument(e){if(null!=this._types[e])return this._types[e];let t=this._record[e];if(null==t)throw Error(`Could not find model id: ${e}`);let i=this._getDefinitions();this._aliases[e]??=r(t.name);let n=this._aliases[e],s={name:n,interfaces:()=>[i.documentInterface,i.nodeInterface].concat(t.interfaces.map(t=>this._types[getGlobalID(t,e).toString()]).filter(e=>null!=e)),fields:()=>this._buildDocumentFields(e,t,n)},l="interface"===t.behavior,o=l?new h({...s,resolveType:e=>this._aliases[e.model]}):new _(s),{connectionType:a,edgeType:u}=S({nodeType:o});return this._types[e]=o,this._types[`${e}-connection`]=a,this._types[`${e}-edge`]=u,this._buildDocumentDataObject(e,t,n),this._buildDocumentInput(e,t),this._buildObjectFilterInput(e,t.schema,n,!0),this._buildObjectOrderByInput(e,t.schema,n,!0),!l&&this._includeMutations&&("default"===t.behavior?this._mutations[`create${n}`]=F({name:`Create${n}`,inputFields:()=>({data:{type:new m(this._inputObjects[e])},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(t,i,n)=>({document:await i.executeCreateMutation({modelID:e,data:t.data,info:n,transactionID:t.transactionID})})}):"unique"===t.behavior&&(this._mutations[`set${n}`]=F({name:`Set${n}`,inputFields:()=>({data:{type:new m(this._inputObjects[e])},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(i,n,s)=>{let l=P(t.uniqueFields,i.data);return{document:await n.executeSetMutation({modelID:e,unique:l,data:i.data,info:s,transactionID:i.transactionID})}}})),this._mutations[`update${n}`]=F({name:`Update${n}`,inputFields:()=>({id:{type:new m(d)},patch:{type:new m(toList(PatchOperation))},from:{type:this._inputObjects[`${e}-update`]},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(e,t,i)=>({document:await t.executeUpdateMutation({input:e,info:i,transactionID:e.transactionID})})}),this._mutations[`remove${n}`]=F({name:`Remove${n}`,inputFields:()=>({id:{type:new m(d)},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,id:{type:new m(d)}}),mutateAndGetPayload:async(e,t,i)=>(await t.executeRemoveMutation({id:e.id,info:i,transactionID:e.transactionID}),{id:e.id})})),o}_buildDocumentFields(t,i,n){let s=this._buildDocumentDataObject(t,i,n),l=this._getDefinitions(),r={...l.documentNodeFields,data:{type:new m(s)}};for(let[n,o]of Object.entries(s.getFields())){let s=i.fieldsMeta[n];if(null!=s)switch(s.type){case"account":U(o.type)?r[`${n}Accounts`]={type:new m(toOuputList(l.accountObject)),resolve:e=>e.data?.[n]??[]}:r[`${n}Account`]={type:l.accountObject,resolve:e=>e.data?.[n]??null};break;case"attachment":U(o.type)?r[`${n}Attachments`]={type:new m(toOuputList(l.attachmentObject)),resolve:t=>(t.data?.[n]??[]).map(e.fromString)}:r[`${n}Attachment`]={type:l.attachmentObject,resolve:t=>{let i=t.data?.[n];return i?e.fromString(i):null}};break;case"document":{let e,i,a=s.model;if(void 0===a)continue;null===a?(e=null,i=l.documentInterface):(e=getGlobalID(a,t).toString(),this._includedModelIDs.has(e)?i=this._buildDocument(e):(i=l.documentInterface,e=null)),U(o.type)?r[`${n}Documents`]={type:new m(toOuputList(i)),resolve:async(t,i,s)=>{let l=t.data?.[n]??[];return l.length?await s.resolveList(this.getModelIDs(e),l):[]}}:r[`${n}Document`]={type:i,resolve:async(e,t,i)=>{let s=e.data?.[n];return s?await i.loadDocument(s):null}}}}}for(let e of i.interfaces??[]){let i=getGlobalID(e,t).toString();for(let[e,t]of Object.entries(this._relationsTo[i]??{}))for(let i of t)this._includedModelIDs.has(i.model)&&this._buildRelationFields(r,e,i)}for(let[e,i]of Object.entries(this._relationsTo[t]??{}))for(let t of i)this._includedModelIDs.has(t.model)&&this._buildRelationFields(r,e,t);return r}_buildDocumentDataObject(e,t,i){let n=`${e}-data`;if(null!=this._types[n])return this._types[n];let s=t.schema.required??[],l={};for(let[i,n]of Object.entries(t.schema.properties??{})){let t=n.$ref;if(null==t)throw Error(`Missing ref for field ${i} of object ${e}`);let r=this._getReference(t);l[i]={type:s.includes(i)?new m(r):r}}let r={name:`${i}Data`,interfaces:()=>t.interfaces.map(t=>{let i=`${getGlobalID(t,e).toString()}-data`;return this._types[i]}).filter(e=>null!=e),fields:l},o="interface"===t.behavior?new h(r):new _(r);return this._types[n]=o,o}_buildDocumentInput(e,t){if("interface"===t.behavior)return;let i={},n={};for(let[e,s]of Object.entries(t.schema.properties)){let l=s.$ref,r=this._getReferenceInput(l,!1);i[e]={type:t.schema.required.includes(e)?new m(r):r};let o=Q(l);null==this._getReferenceSchema(o).const&&(n[e]={type:this._getReferenceInput(l,!0)})}let s=this._aliases[e];this._inputObjects[e]=new p({name:`${s}Input`,fields:i}),this._inputObjects[`${e}-update`]=new p({name:`Partial${s}Input`,fields:n})}_buildReferenceFilterInput(e,t=""){let i=Q(e),n=this._getReferenceSchema(i),s=t;if("object"===n.type)return n.additionalProperties?null:this._buildObjectFilterInput(i,n,t);if("array"===n.type){let e=this._aliases[i]??r(t+n.title);return s=e,new p({name:`${e}Filter`,isOneOf:!0,fields:{isNull:{type:a}}})}let l=this._buildScalar(i,n,s),o=H[l.name];if(null!=o)return this._inputObjects[o];let u=D(l)?new p({name:`${l.name}ValueFilter`,isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:l},notEqualTo:{type:l},in:{type:toList(l)},notIn:{type:toList(l)}}}):W(l);return null==this._inputObjects[u.name]&&(this._inputObjects[u.name]=u),this._inputObjects[u.name]}_buildReferenceOrderByInput(e,t=""){let i=Q(e),n=this._getReferenceSchema(i);switch(n.type){case"array":return null;case"object":return n.additionalProperties?null:this._buildObjectOrderByInput(i,n,t);default:return Y}}_buildObjectFilterInput(e,t,i="",n=!1){let s=`${e}-filter`,l=this._inputObjects[s];if(null!=l)return l;let o=this._aliases[e]??r(i+(t.title??"")),a=n?{_owner:{type:this._inputObjects.AccountValueFilter}}:{};for(let[e,i]of Object.entries(t.properties)){let t=this._buildReferenceFilterInput(i.$ref,o);null!==t&&(a[e]={type:t})}let u=new p({name:`${o}ObjectFilter`,fields:a}),c=new p({name:`${o}Filter`,isOneOf:!0,fields:()=>({where:{type:u},and:{type:toList(this._inputObjects[s])},or:{type:toList(this._inputObjects[s])},not:{type:this._inputObjects[s]}})});return this._inputObjects[s]=c,c}_buildObjectOrderByInput(e,t,i="",n=!1){let s=`${e}-order`,l=this._inputObjects[s];if(null!=l)return l;let o=this._aliases[e]??r(i+(t.title??"")),a=n?{_docOwner:{type:Y},_createdAt:{type:Y}}:{};for(let[e,i]of Object.entries(t.properties)){let t=this._buildReferenceOrderByInput(i.$ref,o);null!=t&&(a[e]={type:t})}let u=new p({name:`${o}OrderBy`,isOneOf:!0,fields:a});return this._inputObjects[s]=u,u}_buildSetInputObjectType(e,t,i){let n=i?r(i):"",s=`${e}-with-${n}`,l=this._inputObjects[s];if(null!=l)return l;let o=this._record[e],a=this._aliases[e];return this._inputObjects[s]=new p({name:`With${n}${a}Input`,fields:()=>{let e={};for(let i of t){let t=o.schema.properties[i];if(null==t)throw Error(`Field ${i} not found on model ${a}`);let n=this._getReferenceInput(t.$ref,!1);e[i]={type:new m(n)}}return e}}),this._inputObjects[s]}_buildReference(e,t,i=""){if(null!=this._types[e])return this._types[e];switch(t.type){case"array":return this._types[e]=this._buildArray(t,i),this._types[e];case"object":return this._types[e]=t.additionalProperties?A:this._buildObject(e,t,i),this._types[e];default:return this._buildScalar(e,t,i)}}_buildScalar(e,t,i=""){if(null!=this._types[e])return this._types[e];switch(t.type){case"boolean":this._types[e]=a;break;case"integer":this._types[e]=f;break;case"number":this._types[e]=c;break;case"string":this._types[e]=this._buildString(t,i)}return this._types[e]}_buildArray(e,t=""){let i=e.items.$ref;return new y(new m(this._getReference(i,r(t+e.title))))}_buildObject(e,t,i=""){let n=r(i+t.title),s=this._buildObjectFields(e,t,n);return new _({name:n,fields:s})}_buildObjectFields(e,t,i=""){let n=t.required??[],s={};for(let[l,r]of Object.entries(t.properties??{})){let t=r.$ref;if(null==t)throw Error(`Missing ref for field ${l} of object ${e}`);let o=this._getReference(t,i);s[l]={type:n.includes(l)?new m(o):o}}return s}_buildRelationFields(e,t,i){if(i.isList)return;let n=i.model,s=`${r(t)}Of${this._aliases[n]}`;e[`in${s}`]={type:new m(this._types[`${n}-connection`]),args:{...j,filter:{type:this._inputObjects[`${n}-filter`]},orderBy:{type:toList(this._inputObjects[`${n}-order`])}},resolve:(e,i,s)=>{let l={where:{[t]:{equalTo:e.id}}},r=i.filter?{and:[i.filter,l]}:l;return s.resolveConnection(this.getModelIDs(n),{...i,filter:r})}},e[`in${s}Count`]={type:new m(f),args:{filter:{type:this._inputObjects[`${n}-filter`]}},resolve:(e,i,s)=>{let l={where:{[t]:{equalTo:e.id}}},r=i.filter?{and:[i.filter,l]}:l;return s.resolveCount(this.getModelIDs(n),r)}}}_buildRelationSubscriptions(e,t,i,n){if(n.isList)return;let s=r(i);e[`edge${this._aliases[n.model]}AddedAs${s}To${this._aliases[t]}`]={type:new m(this._types[`${n.model}-edge`]),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,s)=>s.subscribeToDocumentEdgeAdded(this.getModelIDs(n.model),e=>e[i]===t.id)},e[`edge${this._aliases[n.model]}RemovedAs${s}From${this._aliases[t]}`]={type:new m(d),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,s)=>s.subscribeToDocumentEdgeRemoved(this.getModelIDs(n.model),e=>e[i]===t.id)}}_buildString(e,t){return null!=e.const?w:null!=e.enum?this._buildEnumString(e,t):null!=e.format?this._buildFormatString(e):this._buildCustomString(e)}_buildCustomString(e){return null==e.title?w:B[e.title.toLowerCase()]??w}_buildEnumString(e,t=""){let i=r(t+e.title),n=`${i}-enum`;if(null==this._types[n]){let t={};for(let i of e.enum)t[i]={value:i};this._types[n]=new u({name:i,values:t})}return this._types[n]}_buildFormatString(e){let t=k[e.format];if(null==t)throw Error(`Unsupported string format: ${e.format}`);return t}}export function createSchema(e){return new SchemaBuilder(e).build()}
|
|
1
|
+
import{AttachmentID as e,DocumentID as t,DocumentModelID as i,decodeID as n,PluginNodeID as s}from"@kubun/id";import{REFERENCE_PREFIX as l}from"@kubun/protocol";import{pascalCase as r}from"change-case";import{extendSchema as o,GraphQLBoolean as a,GraphQLEnumType as u,GraphQLFloat as c,GraphQLID as d,GraphQLInputObjectType as p,GraphQLInt as f,GraphQLInterfaceType as h,GraphQLList as y,GraphQLNonNull as m,GraphQLObjectType as _,GraphQLSchema as g,GraphQLString as b,isEnumType as w,isListType as v,isNonNullType as D,isObjectType as O,isScalarType as I,Kind as $,parse as j}from"graphql";import{connectionArgs as S,connectionDefinitions as F,mutationWithClientMutationId as M,nodeDefinitions as R}from"graphql-relay";import{GraphQLDateTimeISO as T,GraphQLDID as x,GraphQLDuration as A,GraphQLEmailAddress as L,GraphQLJSON as E,GraphQLJSONObject as k}from"graphql-scalars";import{GraphQLAttachmentID as q,GraphQLDocID as B}from"./identifiers.js";import{GraphQLURL as G}from"./scalars.js";import{getUniqueDocValue as N,validateAccessIdentifiers as P}from"./utils.js";function C(e){if(D(e))return C(e.ofType);if(v(e))return[];if(I(e))switch(e.name){case"String":case"ID":return"";case"Int":case"Float":return 0;case"Boolean":return!1;default:return null}if(w(e)){let t=e.getValues();return t[0]?.value??null}return{}}let V={date:b,time:b,"date-time":b,duration:A,email:L,uri:G},Q={attachmentid:q,did:x,docid:B};function H(e){return e.slice(l.length)}function K(e){return v(e)||D(e)&&v(e.ofType)}export function toDocumentModelID(e){return e instanceof i?e:i.fromString(e)}export function getGlobalID(e,t){let i=toDocumentModelID(e);return i.isLocal?i.toGlobal(toDocumentModelID(t)):i}export function toList(e){return new y(new m(e))}export function toOuputList(e){return new y(new m(e))}function U(e){return new p({name:`${e.name}ValueFilter`,isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:e},notEqualTo:{type:e},in:{type:toList(e)},notIn:{type:toList(e)},lessThan:{type:e},lessThanOrEqualTo:{type:e},greaterThan:{type:e},greaterThanOrEqualTo:{type:e}}})}let z={AccountValueFilter:new p({name:"AccountValueFilter",isOneOf:!0,fields:{equalTo:{type:x},notEqualTo:{type:x},in:{type:toList(x)},notIn:{type:toList(x)}}}),BooleanValueFilter:new p({name:"BooleanValueFilter",isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:a}}}),FloatValueFilter:U(c),IntValueFilter:U(f),StringValueFilter:U(b)},W={GraphQLBoolean:"BooleanValueFilter",GraphQLDID:"AccountValueFilter",GraphQLFloat:"FloatValueFilter",GraphQLInt:"IntValueFilter",GraphQLString:"StringValueFilter"},J=new p({name:"PatchSetOperation",fields:{path:{type:new m(b)},value:{type:E}}}),X=new p({name:"PatchRemoveOperation",fields:{path:{type:new m(b)}}}),Y=new p({name:"PatchDestinationOperation",fields:{from:{type:new m(b)},path:{type:new m(b)}}});export const PatchOperation=new p({name:"PatchOperation",isOneOf:!0,fields:{add:{type:J},set:{type:J},remove:{type:X},replace:{type:J},copy:{type:Y},move:{type:Y}}});let Z=new u({name:"OrderByDirection",values:{ASC:{value:"asc"},DESC:{value:"desc"}}}),ee=new _({name:"AccessRule",fields:{level:{type:new m(b)},allowedDIDs:{type:new y(new m(b))},allowedCircles:{type:new y(new m(b))},allowedGroups:{type:new y(new m(b))}}}),et=new _({name:"AccessPermissions",fields:{read:{type:ee},write:{type:ee}}}),ei=new _({name:"ModelAccessDefaults",fields:()=>({ownerDID:{type:new m(b)},modelID:{type:new m(d)},permissions:{type:new m(et)}})});export class SchemaBuilder{_aliases;_aliasToModelID;_aggregateNumericByModel={};_groupKeyNumericByModel={};_definitions;_implemented={};_includedModelIDs;_includeInterfaceDependencies;_includeMutations;_includeRelationDependencies;_includeSubscriptions;_inputObjects={...z,PatchOperation};_mutations={};_nodeModelIDs;_onlyModels;_record;_references={};_relationsTo={};_extensionSDL;_extensionResolvers;_stubExtensionResolvers;_pluginNodeResolvers={};_subscriptions={};_types={OrderByDirection:Z};constructor(e){for(let[t,i]of(this._record=e.record,this._onlyModels=e.onlyModels??null,this._includeInterfaceDependencies=e.includeInterfaceDependencies??!0,this._includeRelationDependencies=e.includeRelationDependencies??!0,this._includeMutations=e.includeMutations??!0,this._includeSubscriptions=e.includeSubscriptions??!0,this._extensionSDL=e.extensionSDL,this._extensionResolvers=e.extensionResolvers,this._stubExtensionResolvers=e.stubExtensionResolvers??!1,this._aliasToModelID=e.aliases??{},this._aliases={},Object.entries(this._aliasToModelID)))this._aliases[i]=t;for(let[t,i]of Object.entries(e.record))if(null==this._aliases[t]){let e=r(i.name);this._aliases[t]=e,this._aliasToModelID[e]??=t}this._includedModelIDs=this._resolveModelIDsToInclude();let t={};for(let[n,s]of Object.entries(e.record)){let e=i.fromString(n);for(let i of(Object.assign(this._references,s.schema.$defs??{}),s.interfaces)){let s=getGlobalID(i,e).toString();t[s]??=new Set,t[s].add(n)}for(let[t,i]of Object.entries(s.fieldsMeta))if("document"===i.type&&null!=i.model){let l=H(s.schema.properties[t]?.$ref),r="array"===this._getReferenceSchema(l).type,o=getGlobalID(i.model,e).toString();this._relationsTo[o]??={},this._relationsTo[o][t]??=[],this._relationsTo[o][t].push({model:n,isList:r})}}let n=new Set;for(let e of Object.keys(t)){let i=new Set;for(let s of(!function e(t,i,n){let s=i[n];if(null==s)throw Error(`Interface ${n} not found in record`);for(let n of s)null!=i[n]?e(t,i,n):t.add(n)}(i,t,e),0!==i.size&&(this._implemented[e]=Array.from(i)),i))n.add(s)}this._nodeModelIDs=Array.from(n)}_resolveModelIdentifier(e){if(null!=this._record[e])return e;let t=this._aliasToModelID[e];if(null!=t&&null!=this._record[t])return t;throw Error(`Model identifier "${e}" not found. Must be a valid model ID or alias.`)}_resolveModelIDsToInclude(){if(null==this._onlyModels||0===this._onlyModels.length)return new Set(Object.keys(this._record));let e=new Set;for(let t of this._onlyModels){let i=this._resolveModelIdentifier(t);e.add(i)}if(!this._includeInterfaceDependencies&&!this._includeRelationDependencies)return e;let t=Array.from(e),i=new Set;for(;t.length>0;){let n=t.pop();if(null==n||i.has(n))continue;i.add(n);let s=this._record[n];if(null!=s){if(this._includeInterfaceDependencies)for(let i of s.interfaces){let s=getGlobalID(i,n).toString();e.has(s)||(e.add(s),t.push(s))}if(this._includeRelationDependencies){for(let i of Object.values(s.fieldsMeta))if("document"===i.type&&null!=i.model&&null!==i.model){let s=getGlobalID(i.model,n).toString();e.has(s)||(e.add(s),t.push(s))}}}}return e}getModelIDs(e){return null===e?this._nodeModelIDs:this._implemented[e]??[e]}build(){let e=this._buildSharedDefinitions();this._definitions=e;let t={nodes:e.nodesField,...e.queryFields};for(let e of this._includedModelIDs){this._buildDocument(e);let i=this._aliases[e],n={type:this._inputObjects[`${e}-filter`]};t[`all${i}`]={type:this._types[`${e}-connection`],args:{...S,filter:n,orderBy:{type:toList(this._inputObjects[`${e}-order`])},search:{type:b}},resolve:async(t,i,n)=>await n.resolveConnection(this.getModelIDs(e),i)}}let i=[...this._includedModelIDs][0];if(null!=i){let n=this._types[`${i}-connection`].getFields().pageInfo.type,s=new _({name:"SearchResultEdge",fields:()=>({cursor:{type:new m(b)},node:{type:new m(e.nodeInterface)},rank:{type:new m(c)}})}),l=new _({name:"SearchResultConnection",fields:()=>({edges:{type:new m(new y(new m(s)))},pageInfo:{type:n}})});t.search={type:new m(l),args:{query:{type:new m(b)},models:{type:new y(new m(b))},first:{type:f},after:{type:b}},resolve:async(e,t,i)=>{let{query:n,models:s,first:l}=t;if(""===n.trim())throw Error("Search query must not be empty");let r=s?s.map(e=>this._aliasToModelID[e]??e):[...this._includedModelIDs],o=await i.searchDocuments(n,r,l??20),a=o.map(e=>e.documentID),u=[...new Set(o.map(e=>e.modelID))],c=new Map((a.length>0?await i.resolveList(u,a):[]).map(e=>[e.id,e])),d=[];for(let e of o){let t=c.get(e.documentID);null!=t&&d.push({cursor:String(d.length),node:t,rank:Math.abs(e.rank)})}return{edges:d,pageInfo:{hasNextPage:!1,hasPreviousPage:!1,startCursor:d.length>0?d[0].cursor:null,endCursor:d.length>0?d[d.length-1].cursor:null}}}}}if(this._includeMutations){this._mutations.setModelAccessDefaults={type:ei,args:{modelID:{type:new m(d)},permissionType:{type:new m(b)},accessLevel:{type:new m(b)},allowedDIDs:{type:toList(b)},allowedCircles:{type:toList(b)},allowedGroups:{type:toList(b)}},resolve:async(e,t,i)=>{let n=t.allowedDIDs??null,s=t.allowedCircles??null,l=t.allowedGroups??null;return P({allowedDIDs:n,allowedCircles:s,allowedGroups:l}),await i.executeSetModelAccessDefaults({modelID:t.modelID,permissionType:t.permissionType,accessLevel:t.accessLevel,allowedDIDs:n,allowedCircles:s,allowedGroups:l})}},this._mutations.removeModelAccessDefaults={type:a,args:{modelID:{type:new m(d)},permissionTypes:{type:new m(toList(b))}},resolve:async(e,t,i)=>(await i.executeRemoveModelAccessDefaults(t.modelID,t.permissionTypes),!0)},this._mutations.setDocumentAccessOverride={type:e.documentInterface,args:{documentID:{type:new m(d)},permissionType:{type:new m(b)},accessLevel:{type:new m(b)},allowedDIDs:{type:toList(b)},allowedCircles:{type:toList(b)},allowedGroups:{type:toList(b)}},resolve:async(e,t,i)=>{let n=t.allowedDIDs??null,s=t.allowedCircles??null,l=t.allowedGroups??null;return P({allowedDIDs:n,allowedCircles:s,allowedGroups:l}),await i.executeSetDocumentAccessOverride({documentID:t.documentID,permissionType:t.permissionType,accessLevel:t.accessLevel,allowedDIDs:n,allowedCircles:s,allowedGroups:l})}},this._mutations.removeDocumentAccessOverride={type:a,args:{documentID:{type:new m(d)},permissionTypes:{type:new m(toList(b))}},resolve:async(e,t,i)=>(await i.executeRemoveDocumentAccessOverride(t.documentID,t.permissionTypes),!0)};let t=new _({name:"BeginTransactionPayload",fields:{transactionID:{type:new m(d)}}}),i=new _({name:"CommitTransactionPayload",fields:{success:{type:new m(a)}}}),n=new _({name:"RollbackTransactionPayload",fields:{success:{type:new m(a)}}});this._mutations.beginTransaction={type:new m(t),args:{},resolve:(e,t,i)=>i.beginTransaction()},this._mutations.commitTransaction={type:new m(i),args:{transactionID:{type:new m(d)}},resolve:async(e,t,i)=>await i.commitTransaction(t.transactionID)},this._mutations.rollbackTransaction={type:new m(n),args:{transactionID:{type:new m(d)}},resolve:(e,t,i)=>i.rollbackTransaction(t.transactionID)}}let n={query:new _({name:"Query",fields:t}),types:[G,x,T]};this._includeMutations&&(n.mutation=new _({name:"Mutation",fields:this._mutations})),this._includeSubscriptions&&(n.subscription=new _({name:"Subscription",fields:()=>{let t={...this._subscriptions};if(this._includeSubscriptions)for(let[i,n]of(t.documentChanged={type:new m(e.documentInterface),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,i)=>i.subscribeToDocumentChanged(t.id)},t.documentRemoved={type:new m(d),resolve:e=>e,subscribe:(e,t,i)=>i.subscribeToDocumentRemoved()},Object.entries(this._record))){if(!this._includedModelIDs.has(i))continue;let e=this._aliases[i];for(let s of(t[`new${e}Created`]={type:new m(this._types[i]),args:{owner:{type:d}},resolve:e=>e,subscribe:(e,t,n)=>n.subscribeToDocumentCreated(this.getModelIDs(i),t.owner??void 0)},n.interfaces??[])){let e=getGlobalID(s,i).toString();for(let[i,n]of Object.entries(this._relationsTo[e]??{}))for(let s of n)this._buildRelationSubscriptions(t,e,i,s)}for(let[e,n]of Object.entries(this._relationsTo[i]??{}))for(let s of n)this._includedModelIDs.has(s.model)&&this._buildRelationSubscriptions(t,i,e,s)}return t}}));let s=new g(n);if(null!=this._extensionSDL){let e=new Set(Object.keys(s.getTypeMap()));s=o(s,j(this._extensionSDL)),this._stubExtensionResolvers&&this.#e(s,e)}return null!=this._extensionResolvers&&this.#t(s,this._extensionResolvers),s}#t(e,t){let i=e.getQueryType();if(null!=i&&null!=t.queryFields){let e=i.getFields();for(let[i,n]of Object.entries(t.queryFields)){if(null==e[i])throw Error(`Extension resolver for query field "${i}" has no matching field in SDL`);e[i].resolve=n}}let n=e.getMutationType();if(null!=n&&null!=t.mutationFields){let e=n.getFields();for(let[i,n]of Object.entries(t.mutationFields)){if(null==e[i])throw Error(`Extension resolver for mutation field "${i}" has no matching field in SDL`);e[i].resolve=n}}let s=e.getSubscriptionType();if(null!=s&&null!=t.subscriptionFields){let e=s.getFields();for(let[i,n]of Object.entries(t.subscriptionFields)){if(null==e[i])throw Error(`Extension resolver for subscription field "${i}" has no matching field in SDL`);e[i].resolve=n.resolve,e[i].subscribe=n.subscribe}}if(null!=t.typeFields)for(let[i,n]of Object.entries(t.typeFields)){let t=e.getType(i);if(null==t)throw Error(`Extension resolver references type "${i}" which does not exist in the schema`);if(!O(t))throw Error(`Extension resolver references type "${i}" which is not an object type`);let s=t.getFields();for(let[e,t]of Object.entries(n)){if(null==s[e])throw Error(`Extension resolver for field "${e}" on type "${i}" has no matching field in SDL`);s[e].resolve=t}}if(null!=t.nodeResolvers)for(let[e,i]of Object.entries(t.nodeResolvers))this._pluginNodeResolvers[e]=i}#e(e,t){for(let t of[e.getQueryType(),e.getMutationType()])if(null!=t)for(let e of Object.values(t.getFields()))null==e.resolve&&(e.resolve=()=>C(e.type));for(let[i,n]of Object.entries(e.getTypeMap()))if(!t.has(i)&&O(n)){for(let e of Object.values(n.getFields()))if(null==e.resolve){let t=e.type;e.resolve=i=>i[e.name]??C(t)}}}_getDefinitions(){if(null==this._definitions)throw Error("Definitions must be initialized");return this._definitions}_getReference(e,t){let i=H(e),n=this._types[i];if(null!=n)return n;let s=this._getReferenceSchema(i);return this._buildReference(i,s,t)}_getReferenceSchema(e){let t=this._references[e];if(null==t)throw Error(`Could not find reference: ${e}`);return t}_getReferenceInput(e,t,i=""){let n=H(e),s=this._getReferenceSchema(n);if("array"===s.type)return new y(new m(this._getReferenceInput(s.items.$ref,!1,s.title)));if("object"===s.type){if(s.additionalProperties)return k;let e=t?`${n}-partial`:n,l=this._inputObjects[e];if(null!=l)return l;let o={};for(let[e,i]of Object.entries(s.properties)){let n=this._getReferenceInput(i.$ref,t,s.title);o[e]={type:t||!s.required.includes(e)?n:new m(n)}}let a=this._aliases[n]??r(i+s.title),u=new p({name:t?`Partial${a}Input`:`${a}Input`,fields:o});return this._inputObjects[e]=u,u}return this._buildScalar(n,s,i)}_buildSharedDefinitions(){let i=R(async(i,l)=>{if(i.startsWith("did:"))return i;let r=n(i);if(r instanceof e)return r;if(r instanceof t)return await l.loadDocument(i);if(r instanceof s){let e=this._pluginNodeResolvers[r.typeName];if(null==e)throw Error(`No node resolver registered for plugin type "${r.typeName}"`);let t=await e.resolve(r.localID,l);if(null==t)throw Error(`Node resolver for "${r.typeName}" returned null for localID "${r.localID}"`);return{...t,__typename:r.typeName}}throw Error(`Unsupported node ID: ${i}`)},t=>{if("string"==typeof t)return"AccountNode";if(t instanceof e)return"AttachmentNode";if(null!=t&&"object"==typeof t&&"model"in t)return this._aliases[t.model];if(null!=t&&"object"==typeof t&&"__typename"in t)return t.__typename;throw Error("Unknown node type")}),l=new _({name:"AccountNode",interfaces:[i.nodeInterface],fields:()=>{let e={id:{type:new m(d),description:"Globally unique identifier of the account (DID string)",resolve:e=>e},isViewer:{type:new m(a),description:"Whether the authenticated request issuer is this account or not",resolve:(e,t,i)=>i.getViewer()===e}};for(let[i,n]of Object.entries(this._record))if(this._includedModelIDs.has(i))switch(n.behavior){case"interface":continue;case"default":{let t=this._aliases[i];e[`own${t}Connection`]={type:this._types[`${i}-connection`],args:{...S,filter:{type:this._inputObjects[`${i}-filter`]},orderBy:{type:toList(this._inputObjects[`${i}-order`])}},resolve:async(e,t,n)=>await n.resolveConnection(this.getModelIDs(i),{...t,owner:e})};break}case"unique":{let s=this._aliases[i];e[`own${s}`]={type:this._types[i],args:n.uniqueFields.length?{with:{type:new m(this._buildSetInputObjectType(i,n.uniqueFields))}}:{},resolve:async(e,s,l)=>{let r=N(n.uniqueFields,s.with),o=t.create(i,e,r);return await l.loadDocument(o.toString())}}}}return e}}),r=new _({name:"AttachmentNode",interfaces:[i.nodeInterface],fields:{id:{type:new m(d),resolve:e=>e.toString()},contentLength:{type:new m(f)},mimeType:{type:new m(b)}}}),o={id:{type:new m(d)},model:{type:new m(b)},owner:{type:new m(l)},createdAt:{type:new m(T)},updatedAt:{type:T},accessPermissions:{type:et,resolve:e=>e.data?.accessPermissions??null}},u=new h({name:"DocumentNode",interfaces:[i.nodeInterface],fields:o,resolveType:e=>this._aliases[e.model]}),c={node:i.nodeField,viewer:{type:l,description:"Account issuing the request, if authenticated",resolve:(e,t,i)=>i.getViewer()}};return{...i,accountObject:l,attachmentObject:r,documentInterface:u,documentNodeFields:o,queryFields:c}}_buildDocument(e){if(null!=this._types[e])return this._types[e];let t=this._record[e];if(null==t)throw Error(`Could not find model id: ${e}`);let i=this._getDefinitions();this._aliases[e]??=r(t.name);let n=this._aliases[e],s={name:n,interfaces:()=>[i.documentInterface,i.nodeInterface].concat(t.interfaces.map(t=>this._types[getGlobalID(t,e).toString()]).filter(e=>null!=e)),fields:()=>this._buildDocumentFields(e,t,n)},l="interface"===t.behavior,o=l?new h({...s,resolveType:e=>this._aliases[e.model]}):new _(s),a=this._buildAggregate(e,t,n),u=this._buildGroupedAggregate(e,t,n),{connectionType:c,edgeType:p}=F({nodeType:o,connectionFields:()=>{let t={aggregates:{type:a,resolve:async(t,i,n,s)=>{let l=t.aggregateScope,{count:r,aggregates:o}=this._buildAggregateRequest(e,s);return await n.resolveAggregate(l.modelIDs,{filter:l.filter,owner:l.owner,catalogID:l.catalogID,count:r,aggregates:o})}}};return null!=u&&(t.groupedAggregates={type:new m(toOuputList(u)),args:{groupBy:{type:new m(toList(this._inputObjects[`${e}-group-by`]))},having:{type:this._inputObjects[`${e}-having`]},orderBy:{type:toList(this._inputObjects[`${e}-group-order`])},limit:{type:f}},resolve:async(t,i,n,s)=>{let l=t.aggregateScope,{count:r,aggregates:o}=this._buildGroupedAggregateRequest(e,s),a=(i.groupBy??[]).map(e=>({keys:[e]})),u=this._buildGroupOrderBy(e,i.orderBy);return await n.resolveGroupedAggregate(l.modelIDs,{filter:l.filter,owner:l.owner,catalogID:l.catalogID,count:r,aggregates:o,groupBy:a,having:i.having,orderBy:u.length>0?u:void 0,limit:i.limit??void 0})}}),t}});return this._types[e]=o,this._types[`${e}-connection`]=c,this._types[`${e}-edge`]=p,this._buildDocumentDataObject(e,t,n),this._buildDocumentInput(e,t),this._buildObjectFilterInput(e,t.schema,n,!0),this._buildObjectOrderByInput(e,t.schema,n,!0),!l&&this._includeMutations&&("default"===t.behavior?this._mutations[`create${n}`]=M({name:`Create${n}`,inputFields:()=>({data:{type:new m(this._inputObjects[e])},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(t,i,n)=>({document:await i.executeCreateMutation({modelID:e,data:t.data,info:n,transactionID:t.transactionID})})}):"unique"===t.behavior&&(this._mutations[`set${n}`]=M({name:`Set${n}`,inputFields:()=>({data:{type:new m(this._inputObjects[e])},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(i,n,s)=>{let l=N(t.uniqueFields,i.data);return{document:await n.executeSetMutation({modelID:e,unique:l,data:i.data,info:s,transactionID:i.transactionID})}}})),this._mutations[`update${n}`]=M({name:`Update${n}`,inputFields:()=>({id:{type:new m(d)},patch:{type:new m(toList(PatchOperation))},from:{type:this._inputObjects[`${e}-update`]},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,document:{type:this._types[e]}}),mutateAndGetPayload:async(e,t,i)=>({document:await t.executeUpdateMutation({input:e,info:i,transactionID:e.transactionID})})}),this._mutations[`remove${n}`]=M({name:`Remove${n}`,inputFields:()=>({id:{type:new m(d)},transactionID:{type:d}}),outputFields:()=>({...i.queryFields,id:{type:new m(d)}}),mutateAndGetPayload:async(e,t,i)=>(await t.executeRemoveMutation({id:e.id,info:i,transactionID:e.transactionID}),{id:e.id})})),o}_buildAggregate(e,t,i){let n=this._types[`${e}-aggregate`];if(null!=n)return n;let s={},l={},r=new Map;for(let[e,i]of Object.entries(t.schema.properties??{})){let t=i.$ref;if(null==t)continue;let n=H(t),o=this._getReferenceSchema(n);if("object"===o.type||"array"===o.type)continue;let a=this._buildScalar(n,o),u=a===f||a===c,d=a===b;u&&(s[e]={type:a}),(u||d)&&(l[e]={type:a},r.set(e,u))}this._aggregateNumericByModel[e]=r;let o=Object.keys(s),a={count:{type:new m(f),resolve:e=>e.count??0}};if(o.length>0){let t=new _({name:`${i}SumFields`,fields:s}),n={};for(let e of o)n[e]={type:c};let l=new _({name:`${i}AvgFields`,fields:n});this._types[`${e}-aggregate-sum`]=t,this._types[`${e}-aggregate-avg`]=l,a.sum={type:t,resolve:e=>e.sum??null},a.average={type:l,resolve:e=>e.average??null}}if(Object.keys(l).length>0){let t=new _({name:`${i}MinMaxFields`,fields:l});this._types[`${e}-aggregate-min-max`]=t,a.min={type:t,resolve:e=>e.min??null},a.max={type:t,resolve:e=>e.max??null}}let u=new _({name:`${i}Aggregate`,fields:a});return this._types[`${e}-aggregate`]=u,u}_buildGroupedAggregate(e,t,i){let n=this._types[`${e}-grouped-aggregate`];if(null!=n)return n;let s=new Map,l=new Map;for(let[e,i]of Object.entries(t.schema.properties??{})){let t=i.$ref;if(null==t)continue;let n=H(t),r=this._getReferenceSchema(n);if("object"===r.type||"array"===r.type)continue;let o=this._buildScalar(n,r);s.set(e,o),l.set(e,o===f||o===c)}if(this._groupKeyNumericByModel[e]=l,0===s.size)return null;let r=this._types[`${e}-aggregate-sum`],o=this._types[`${e}-aggregate-avg`],a=this._types[`${e}-aggregate-min-max`],d={};for(let e of s.keys())d[e]={value:e};let h=new u({name:`${i}GroupBy`,values:d});this._types[`${e}-group-by`]=h,this._inputObjects[`${e}-group-by`]=h;let y={};for(let[e,t]of s)y[e]={type:t};let g=new _({name:`${i}GroupKeys`,fields:y});this._types[`${e}-group-keys`]=g;let b={keys:{type:new m(g),resolve:e=>e.keys},count:{type:new m(f),resolve:e=>e.count??0}};null!=r&&null!=o&&(b.sum={type:r,resolve:e=>e.sum??null},b.average={type:o,resolve:e=>e.average??null}),null!=a&&(b.min={type:a,resolve:e=>e.min??null},b.max={type:a,resolve:e=>e.max??null});let w=new _({name:`${i}GroupedAggregate`,fields:b});this._types[`${e}-grouped-aggregate`]=w;let v=e=>this._inputObjects[`${e.name}ValueFilter`],D={count:{type:this._inputObjects.IntValueFilter}};if(null!=r&&null!=o){let t={},n={};for(let[e,i]of Object.entries(r.getFields()))t[e]={type:v(i.type)},n[e]={type:this._inputObjects.FloatValueFilter};let s=new p({name:`${i}HavingSum`,fields:t}),l=new p({name:`${i}HavingAverage`,fields:n});this._inputObjects[`${e}-having-sum`]=s,this._inputObjects[`${e}-having-average`]=l,D.sum={type:s},D.average={type:l}}if(null!=a){let t={},n={};for(let[e,i]of Object.entries(a.getFields()))t[e]={type:v(i.type)},n[e]={type:v(i.type)};let s=new p({name:`${i}HavingMin`,fields:t}),l=new p({name:`${i}HavingMax`,fields:n});this._inputObjects[`${e}-having-min`]=s,this._inputObjects[`${e}-having-max`]=l,D.min={type:s},D.max={type:l}}let O=new p({name:`${i}Having`,fields:D});this._inputObjects[`${e}-having`]=O;let I=(e,t)=>{let i={};for(let e of t)i[e]={type:Z};return new p({name:e,fields:i})},$=I(`${i}GroupKeysOrderBy`,s.keys());this._inputObjects[`${e}-group-keys-order`]=$;let j={keys:{type:$},count:{type:Z}};if(null!=r&&null!=o){let t=I(`${i}SumFieldsOrderBy`,Object.keys(r.getFields())),n=I(`${i}AvgFieldsOrderBy`,Object.keys(o.getFields()));this._inputObjects[`${e}-sum-order`]=t,this._inputObjects[`${e}-avg-order`]=n,j.sum={type:t},j.average={type:n}}if(null!=a){let t=I(`${i}MinFieldsOrderBy`,Object.keys(a.getFields())),n=I(`${i}MaxFieldsOrderBy`,Object.keys(a.getFields()));this._inputObjects[`${e}-min-order`]=t,this._inputObjects[`${e}-max-order`]=n,j.min={type:t},j.max={type:n}}let S=new p({name:`${i}GroupOrderBy`,fields:j});return this._inputObjects[`${e}-group-order`]=S,w}_buildAggregateRequest(e,t){let i=this._aggregateNumericByModel[e]??new Map,n=["sum","average","min","max"],s=!1,l=[];for(let e of t.fieldNodes){let r=e.selectionSet?.selections??[];for(let e of this._expandFieldSelections(r,t,new Set)){let r=e.name.value;if("count"===r){s=!0;continue}if(!n.includes(r))continue;let o=e.selectionSet?.selections??[];for(let e of this._expandFieldSelections(o,t,new Set)){let t=e.name.value;l.push({op:r,keys:[t],numeric:i.get(t)??!1})}}}return{count:s,aggregates:l}}_buildGroupedAggregateRequest(e,t){let i=this._aggregateNumericByModel[e]??new Map,n=["sum","average","min","max"],s=!1,l=[];for(let e of t.fieldNodes){let r=e.selectionSet?.selections??[];for(let e of this._expandFieldSelections(r,t,new Set)){let r=e.name.value;if("count"===r){s=!0;continue}if("keys"===r||!n.includes(r))continue;let o=e.selectionSet?.selections??[];for(let e of this._expandFieldSelections(o,t,new Set)){let t=e.name.value;l.push({op:r,keys:[t],numeric:i.get(t)??!1})}}}return{count:s,aggregates:l}}_buildGroupOrderBy(e,t){if(null==t)return[];let i=this._aggregateNumericByModel[e]??new Map,n=this._groupKeyNumericByModel[e]??new Map,s=[];for(let e of t){for(let[t,i]of(null!=e.count&&s.push({path:["count"],direction:e.count,numeric:!0}),Object.entries(e.keys??{})))s.push({path:["keys",t],direction:i,numeric:n.get(t)??!1});for(let[t,n]of Object.entries(e.sum??{}))s.push({path:["sum",t],direction:n,numeric:i.get(t)??!1});for(let[t,i]of Object.entries(e.average??{}))s.push({path:["average",t],direction:i,numeric:!0});for(let[t,n]of Object.entries(e.min??{}))s.push({path:["min",t],direction:n,numeric:i.get(t)??!1});for(let[t,n]of Object.entries(e.max??{}))s.push({path:["max",t],direction:n,numeric:i.get(t)??!1})}return s}*_expandFieldSelections(e,t,i){for(let n of e)switch(n.kind){case $.FIELD:yield n;break;case $.INLINE_FRAGMENT:yield*this._expandFieldSelections(n.selectionSet.selections,t,i);break;case $.FRAGMENT_SPREAD:{let e=n.name.value;if(i.has(e))break;let s=t.fragments[e];if(null==s)break;i.add(e),yield*this._expandFieldSelections(s.selectionSet.selections,t,i)}}}_buildDocumentFields(t,i,n){let s=this._buildDocumentDataObject(t,i,n),l=this._getDefinitions(),r={...l.documentNodeFields,data:{type:new m(s)}};for(let[n,o]of Object.entries(s.getFields())){let s=i.fieldsMeta[n];if(null!=s)switch(s.type){case"account":K(o.type)?r[`${n}Accounts`]={type:new m(toOuputList(l.accountObject)),resolve:e=>e.data?.[n]??[]}:r[`${n}Account`]={type:l.accountObject,resolve:e=>e.data?.[n]??null};break;case"attachment":K(o.type)?r[`${n}Attachments`]={type:new m(toOuputList(l.attachmentObject)),resolve:t=>(t.data?.[n]??[]).map(e.fromString)}:r[`${n}Attachment`]={type:l.attachmentObject,resolve:t=>{let i=t.data?.[n];return i?e.fromString(i):null}};break;case"document":{let e,i,a=s.model;if(void 0===a)continue;null===a?(e=null,i=l.documentInterface):(e=getGlobalID(a,t).toString(),this._includedModelIDs.has(e)?i=this._buildDocument(e):(i=l.documentInterface,e=null)),K(o.type)?r[`${n}Documents`]={type:new m(toOuputList(i)),resolve:async(t,i,s)=>{let l=t.data?.[n]??[];return l.length?await s.resolveList(this.getModelIDs(e),l):[]}}:r[`${n}Document`]={type:i,resolve:async(e,t,i)=>{let s=e.data?.[n];return s?await i.loadDocument(s):null}}}}}for(let e of i.interfaces??[]){let i=getGlobalID(e,t).toString();for(let[e,t]of Object.entries(this._relationsTo[i]??{}))for(let i of t)this._includedModelIDs.has(i.model)&&this._buildRelationFields(r,e,i)}for(let[e,i]of Object.entries(this._relationsTo[t]??{}))for(let t of i)this._includedModelIDs.has(t.model)&&this._buildRelationFields(r,e,t);return r}_buildDocumentDataObject(e,t,i){let n=`${e}-data`;if(null!=this._types[n])return this._types[n];let s=t.schema.required??[],l={};for(let[i,n]of Object.entries(t.schema.properties??{})){let t=n.$ref;if(null==t)throw Error(`Missing ref for field ${i} of object ${e}`);let r=this._getReference(t);l[i]={type:s.includes(i)?new m(r):r}}let r={name:`${i}Data`,interfaces:()=>t.interfaces.map(t=>{let i=`${getGlobalID(t,e).toString()}-data`;return this._types[i]}).filter(e=>null!=e),fields:l},o="interface"===t.behavior?new h(r):new _(r);return this._types[n]=o,o}_buildDocumentInput(e,t){if("interface"===t.behavior)return;let i={},n={};for(let[e,s]of Object.entries(t.schema.properties)){let l=s.$ref,r=this._getReferenceInput(l,!1);i[e]={type:t.schema.required.includes(e)?new m(r):r};let o=H(l);null==this._getReferenceSchema(o).const&&(n[e]={type:this._getReferenceInput(l,!0)})}let s=this._aliases[e];this._inputObjects[e]=new p({name:`${s}Input`,fields:i}),this._inputObjects[`${e}-update`]=new p({name:`Partial${s}Input`,fields:n})}_buildReferenceFilterInput(e,t=""){let i=H(e),n=this._getReferenceSchema(i),s=t;if("object"===n.type)return n.additionalProperties?null:this._buildObjectFilterInput(i,n,t);if("array"===n.type){let e=this._aliases[i]??r(t+n.title);return s=e,new p({name:`${e}Filter`,isOneOf:!0,fields:{isNull:{type:a}}})}let l=this._buildScalar(i,n,s),o=W[l.name];if(null!=o)return this._inputObjects[o];let u=w(l)?new p({name:`${l.name}ValueFilter`,isOneOf:!0,fields:{isNull:{type:a},equalTo:{type:l},notEqualTo:{type:l},in:{type:toList(l)},notIn:{type:toList(l)}}}):U(l);return null==this._inputObjects[u.name]&&(this._inputObjects[u.name]=u),this._inputObjects[u.name]}_buildReferenceOrderByInput(e,t=""){let i=H(e),n=this._getReferenceSchema(i);switch(n.type){case"array":return null;case"object":return n.additionalProperties?null:this._buildObjectOrderByInput(i,n,t);default:return Z}}_buildObjectFilterInput(e,t,i="",n=!1){let s=`${e}-filter`,l=this._inputObjects[s];if(null!=l)return l;let o=this._aliases[e]??r(i+(t.title??"")),a=n?{_owner:{type:this._inputObjects.AccountValueFilter}}:{};for(let[e,i]of Object.entries(t.properties)){let t=this._buildReferenceFilterInput(i.$ref,o);null!==t&&(a[e]={type:t})}let u=new p({name:`${o}ObjectFilter`,fields:a}),c=new p({name:`${o}Filter`,isOneOf:!0,fields:()=>({where:{type:u},and:{type:toList(this._inputObjects[s])},or:{type:toList(this._inputObjects[s])},not:{type:this._inputObjects[s]}})});return this._inputObjects[s]=c,c}_buildObjectOrderByInput(e,t,i="",n=!1){let s=`${e}-order`,l=this._inputObjects[s];if(null!=l)return l;let o=this._aliases[e]??r(i+(t.title??"")),a=n?{_docOwner:{type:Z},_createdAt:{type:Z}}:{};for(let[e,i]of Object.entries(t.properties)){let t=this._buildReferenceOrderByInput(i.$ref,o);null!=t&&(a[e]={type:t})}let u=new p({name:`${o}OrderBy`,isOneOf:!0,fields:a});return this._inputObjects[s]=u,u}_buildSetInputObjectType(e,t,i){let n=i?r(i):"",s=`${e}-with-${n}`,l=this._inputObjects[s];if(null!=l)return l;let o=this._record[e],a=this._aliases[e];return this._inputObjects[s]=new p({name:`With${n}${a}Input`,fields:()=>{let e={};for(let i of t){let t=o.schema.properties[i];if(null==t)throw Error(`Field ${i} not found on model ${a}`);let n=this._getReferenceInput(t.$ref,!1);e[i]={type:new m(n)}}return e}}),this._inputObjects[s]}_buildReference(e,t,i=""){if(null!=this._types[e])return this._types[e];switch(t.type){case"array":return this._types[e]=this._buildArray(t,i),this._types[e];case"object":return this._types[e]=t.additionalProperties?k:this._buildObject(e,t,i),this._types[e];default:return this._buildScalar(e,t,i)}}_buildScalar(e,t,i=""){if(null!=this._types[e])return this._types[e];switch(t.type){case"boolean":this._types[e]=a;break;case"integer":this._types[e]=f;break;case"number":this._types[e]=c;break;case"string":this._types[e]=this._buildString(t,i)}return this._types[e]}_buildArray(e,t=""){let i=e.items.$ref;return new y(new m(this._getReference(i,r(t+e.title))))}_buildObject(e,t,i=""){let n=r(i+t.title),s=this._buildObjectFields(e,t,n);return new _({name:n,fields:s})}_buildObjectFields(e,t,i=""){let n=t.required??[],s={};for(let[l,r]of Object.entries(t.properties??{})){let t=r.$ref;if(null==t)throw Error(`Missing ref for field ${l} of object ${e}`);let o=this._getReference(t,i);s[l]={type:n.includes(l)?new m(o):o}}return s}_buildRelationFields(e,t,i){if(i.isList)return;let n=i.model,s=`${r(t)}Of${this._aliases[n]}`;e[`in${s}`]={type:new m(this._types[`${n}-connection`]),args:{...S,filter:{type:this._inputObjects[`${n}-filter`]},orderBy:{type:toList(this._inputObjects[`${n}-order`])}},resolve:(e,i,s)=>{let l={where:{[t]:{equalTo:e.id}}},r=i.filter?{and:[i.filter,l]}:l;return s.resolveConnection(this.getModelIDs(n),{...i,filter:r})}}}_buildRelationSubscriptions(e,t,i,n){if(n.isList)return;let s=r(i);e[`edge${this._aliases[n.model]}AddedAs${s}To${this._aliases[t]}`]={type:new m(this._types[`${n.model}-edge`]),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,s)=>s.subscribeToDocumentEdgeAdded(this.getModelIDs(n.model),e=>e[i]===t.id)},e[`edge${this._aliases[n.model]}RemovedAs${s}From${this._aliases[t]}`]={type:new m(d),args:{id:{type:new m(d)}},resolve:e=>e,subscribe:(e,t,s)=>s.subscribeToDocumentEdgeRemoved(this.getModelIDs(n.model),e=>e[i]===t.id)}}_buildString(e,t){return null!=e.const?b:null!=e.enum?this._buildEnumString(e,t):null!=e.format?this._buildFormatString(e):this._buildCustomString(e)}_buildCustomString(e){return null==e.title?b:Q[e.title.toLowerCase()]??b}_buildEnumString(e,t=""){let i=r(t+e.title),n=`${i}-enum`;if(null==this._types[n]){let t={};for(let i of e.enum)t[i]={value:i};this._types[n]=new u({name:i,values:t})}return this._types[n]}_buildFormatString(e){let t=V[e.format];if(null==t)throw Error(`Unsupported string format: ${e.format}`);return t}}export function createSchema(e){return new SchemaBuilder(e).build()}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"license": "see LICENSE.md",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"type": "module",
|
|
@@ -15,24 +15,26 @@
|
|
|
15
15
|
],
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@enkaku/async": "^0.
|
|
19
|
-
"@enkaku/codec": "^0.
|
|
20
|
-
"@enkaku/event": "^0.
|
|
21
|
-
"@enkaku/otel": "^0.
|
|
18
|
+
"@enkaku/async": "^0.16.0",
|
|
19
|
+
"@enkaku/codec": "^0.16.0",
|
|
20
|
+
"@enkaku/event": "^0.16.0",
|
|
21
|
+
"@enkaku/otel": "^0.16.0",
|
|
22
22
|
"change-case": "^5.4.4",
|
|
23
|
-
"graphql": "^16.
|
|
23
|
+
"graphql": "^16.14.1",
|
|
24
24
|
"graphql-relay": "^0.10.2",
|
|
25
25
|
"graphql-scalars": "^1.25.0",
|
|
26
26
|
"multiformats": "^14.0.0",
|
|
27
|
-
"@kubun/
|
|
28
|
-
"@kubun/
|
|
29
|
-
"@kubun/
|
|
27
|
+
"@kubun/hlc": "^0.10.0",
|
|
28
|
+
"@kubun/protocol": "^0.10.0",
|
|
29
|
+
"@kubun/id": "^0.10.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@enkaku/capability": "^0.
|
|
33
|
-
"@enkaku/token": "^0.
|
|
34
|
-
"@kubun/db
|
|
35
|
-
"@kubun/test-utils": "^0.
|
|
32
|
+
"@enkaku/capability": "^0.16.0",
|
|
33
|
+
"@enkaku/token": "^0.16.0",
|
|
34
|
+
"@kubun/db": "^0.10.0",
|
|
35
|
+
"@kubun/test-utils": "^0.10.0",
|
|
36
|
+
"@kubun/store-graph": "^0.10.1",
|
|
37
|
+
"@kubun/db-better-sqlite": "^0.10.0"
|
|
36
38
|
},
|
|
37
39
|
"scripts": {
|
|
38
40
|
"build:clean": "del lib",
|