@webiny/handler-graphql 6.3.0-beta.4 → 6.4.0-beta.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/ResolverDecoration.js +18 -14
- package/ResolverDecoration.js.map +1 -1
- package/builtInTypes/AnyScalar.js +7 -8
- package/builtInTypes/AnyScalar.js.map +1 -1
- package/builtInTypes/DateScalar.js +12 -18
- package/builtInTypes/DateScalar.js.map +1 -1
- package/builtInTypes/DateTimeScalar.js +12 -18
- package/builtInTypes/DateTimeScalar.js.map +1 -1
- package/builtInTypes/DateTimeZScalar.js +23 -35
- package/builtInTypes/DateTimeZScalar.js.map +1 -1
- package/builtInTypes/IconScalar.js +59 -87
- package/builtInTypes/IconScalar.js.map +1 -1
- package/builtInTypes/JsonScalar.js +2 -1
- package/builtInTypes/JsonScalar.js.map +1 -1
- package/builtInTypes/LongScalar.js +30 -39
- package/builtInTypes/LongScalar.js.map +1 -1
- package/builtInTypes/NumberScalar.js +31 -38
- package/builtInTypes/NumberScalar.js.map +1 -1
- package/builtInTypes/RefInputScalar.js +45 -68
- package/builtInTypes/RefInputScalar.js.map +1 -1
- package/builtInTypes/TimeScalar.js +28 -41
- package/builtInTypes/TimeScalar.js.map +1 -1
- package/builtInTypes/index.js +0 -2
- package/createGraphQLHandler.js +69 -80
- package/createGraphQLHandler.js.map +1 -1
- package/createGraphQLSchema.js +49 -66
- package/createGraphQLSchema.js.map +1 -1
- package/createRequestBody.js +20 -18
- package/createRequestBody.js.map +1 -1
- package/createResolverDecorator.js +2 -3
- package/createResolverDecorator.js.map +1 -1
- package/debugPlugins.js +24 -27
- package/debugPlugins.js.map +1 -1
- package/errors.js +6 -5
- package/errors.js.map +1 -1
- package/exports/api/graphql.js +1 -3
- package/features/GraphQLSchemaBuilder/GraphQLSchemaBuilder.js +52 -59
- package/features/GraphQLSchemaBuilder/GraphQLSchemaBuilder.js.map +1 -1
- package/features/GraphQLSchemaBuilder/GraphQLSchemaComposer.js +27 -21
- package/features/GraphQLSchemaBuilder/GraphQLSchemaComposer.js.map +1 -1
- package/features/GraphQLSchemaBuilder/abstractions.js +3 -2
- package/features/GraphQLSchemaBuilder/abstractions.js.map +1 -1
- package/features/GraphQLSchemaBuilder/feature.js +6 -5
- package/features/GraphQLSchemaBuilder/feature.js.map +1 -1
- package/graphql/abstractions.core.js +2 -7
- package/graphql/abstractions.core.js.map +1 -1
- package/graphql/abstractions.js +0 -2
- package/graphql/abstractions.public.js +2 -8
- package/graphql/abstractions.public.js.map +1 -1
- package/index.js +2 -3
- package/index.js.map +1 -1
- package/interceptConsole.js +30 -27
- package/interceptConsole.js.map +1 -1
- package/package.json +13 -13
- package/plugins/GraphQLSchemaPlugin.js +20 -21
- package/plugins/GraphQLSchemaPlugin.js.map +1 -1
- package/plugins/index.js +0 -2
- package/processRequestBody.js +33 -36
- package/processRequestBody.js.map +1 -1
- package/responses.js +48 -65
- package/responses.js.map +1 -1
- package/types.js +0 -3
- package/utils/index.js +0 -2
- package/utils/resolve.js +15 -14
- package/utils/resolve.js.map +1 -1
- package/builtInTypes/index.js.map +0 -1
- package/exports/api/graphql.js.map +0 -1
- package/graphql/abstractions.js.map +0 -1
- package/plugins/index.js.map +0 -1
- package/types.js.map +0 -1
- package/utils/index.js.map +0 -1
package/createGraphQLSchema.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import graphql_tag from "graphql-tag";
|
|
2
2
|
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
3
3
|
import { mergeResolvers } from "@graphql-tools/merge";
|
|
4
|
-
import {
|
|
4
|
+
import { AnyScalar, DateScalar, DateTimeScalar, IconScalar, JsonScalar, LongScalar, NumberScalar, RefInputScalar, TimeScalar } from "./builtInTypes/index.js";
|
|
5
5
|
import { ResolverDecoration } from "./ResolverDecoration.js";
|
|
6
6
|
import { GraphQLSchemaComposer } from "./features/GraphQLSchemaBuilder/abstractions.js";
|
|
7
7
|
import { GraphQLSchemaComposerFeature } from "./features/GraphQLSchemaBuilder/feature.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
GraphQLSchemaComposerFeature.register(context.container);
|
|
18
|
-
const scalars = context.plugins.byType("graphql-scalar").map(item => item.scalar);
|
|
19
|
-
const typeDefs = [gql`
|
|
8
|
+
const getSchemaPlugins = (context)=>context.plugins.byType("graphql-schema").filter((pl)=>{
|
|
9
|
+
if ("function" == typeof pl.isApplicable) return pl.isApplicable(context);
|
|
10
|
+
return true;
|
|
11
|
+
});
|
|
12
|
+
const createGraphQLSchema = async (context)=>{
|
|
13
|
+
GraphQLSchemaComposerFeature.register(context.container);
|
|
14
|
+
const scalars = context.plugins.byType("graphql-scalar").map((item)=>item.scalar);
|
|
15
|
+
const typeDefs = [
|
|
16
|
+
graphql_tag`
|
|
20
17
|
type Query
|
|
21
18
|
type Mutation
|
|
22
|
-
${scalars.map(scalar
|
|
19
|
+
${scalars.map((scalar)=>`scalar ${scalar.name}`).join(" ")}
|
|
23
20
|
scalar JSON
|
|
24
21
|
scalar Long
|
|
25
22
|
scalar Icon
|
|
@@ -41,58 +38,44 @@ export const createGraphQLSchema = async context => {
|
|
|
41
38
|
data: Boolean
|
|
42
39
|
error: Error
|
|
43
40
|
}
|
|
44
|
-
`
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
resolvers.push(schema.resolvers);
|
|
41
|
+
`
|
|
42
|
+
];
|
|
43
|
+
const resolvers = [
|
|
44
|
+
{
|
|
45
|
+
...scalars.reduce((acc, s)=>{
|
|
46
|
+
acc[s.name] = s;
|
|
47
|
+
return acc;
|
|
48
|
+
}, {}),
|
|
49
|
+
JSON: JsonScalar,
|
|
50
|
+
Long: LongScalar,
|
|
51
|
+
RefInput: RefInputScalar,
|
|
52
|
+
Number: NumberScalar,
|
|
53
|
+
Any: AnyScalar,
|
|
54
|
+
DateTime: DateTimeScalar,
|
|
55
|
+
Date: DateScalar,
|
|
56
|
+
Time: TimeScalar,
|
|
57
|
+
Icon: IconScalar
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
const resolverDecoration = new ResolverDecoration();
|
|
61
|
+
const plugins = getSchemaPlugins(context);
|
|
62
|
+
for (const plugin of plugins){
|
|
63
|
+
const schema = plugin.schema;
|
|
64
|
+
if (schema.typeDefs) typeDefs.push(schema.typeDefs);
|
|
65
|
+
if (schema.resolvers) resolvers.push(schema.resolvers);
|
|
66
|
+
if (schema.resolverDecorators) resolverDecoration.addDecorators(schema.resolverDecorators);
|
|
71
67
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
if (schema.resolvers) {
|
|
84
|
-
resolvers.push(schema.resolvers);
|
|
85
|
-
}
|
|
86
|
-
if (schema.resolverDecorators) {
|
|
87
|
-
resolverDecoration.addDecorators(schema.resolverDecorators);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Create executable schema
|
|
91
|
-
return makeExecutableSchema({
|
|
92
|
-
typeDefs,
|
|
93
|
-
resolvers: resolverDecoration.decorateResolvers(mergeResolvers(resolvers)),
|
|
94
|
-
inheritResolversFromInterfaces: true
|
|
95
|
-
});
|
|
68
|
+
const graphQLSchemaComposer = context.container.resolve(GraphQLSchemaComposer);
|
|
69
|
+
const schema = await graphQLSchemaComposer.build();
|
|
70
|
+
if (schema.typeDefs) typeDefs.push(schema.typeDefs);
|
|
71
|
+
if (schema.resolvers) resolvers.push(schema.resolvers);
|
|
72
|
+
if (schema.resolverDecorators) resolverDecoration.addDecorators(schema.resolverDecorators);
|
|
73
|
+
return makeExecutableSchema({
|
|
74
|
+
typeDefs,
|
|
75
|
+
resolvers: resolverDecoration.decorateResolvers(mergeResolvers(resolvers)),
|
|
76
|
+
inheritResolversFromInterfaces: true
|
|
77
|
+
});
|
|
96
78
|
};
|
|
79
|
+
export { createGraphQLSchema, getSchemaPlugins };
|
|
97
80
|
|
|
98
81
|
//# sourceMappingURL=createGraphQLSchema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"createGraphQLSchema.js","sources":["../src/createGraphQLSchema.ts"],"sourcesContent":["import gql from \"graphql-tag\";\nimport { makeExecutableSchema } from \"@graphql-tools/schema\";\nimport { mergeResolvers } from \"@graphql-tools/merge\";\nimport type { GraphQLScalarType } from \"graphql/type/definition.js\";\nimport type { GraphQLScalarPlugin, Resolvers, TypeDefs } from \"./types.js\";\nimport type { Context } from \"@webiny/api/types.js\";\nimport {\n RefInputScalar,\n NumberScalar,\n AnyScalar,\n DateScalar,\n DateTimeScalar,\n JsonScalar,\n TimeScalar,\n LongScalar,\n IconScalar\n} from \"./builtInTypes/index.js\";\nimport { ResolverDecoration } from \"./ResolverDecoration.js\";\nimport type { GraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport { GraphQLSchemaComposer } from \"~/features/GraphQLSchemaBuilder/abstractions.js\";\nimport { GraphQLSchemaComposerFeature } from \"~/features/GraphQLSchemaBuilder/feature.js\";\n\nexport const getSchemaPlugins = (context: Context) => {\n return context.plugins.byType<GraphQLSchemaPlugin>(\"graphql-schema\").filter(pl => {\n if (typeof pl.isApplicable === \"function\") {\n return pl.isApplicable(context);\n }\n return true;\n });\n};\n\nexport const createGraphQLSchema = async (context: Context) => {\n GraphQLSchemaComposerFeature.register(context.container);\n\n const scalars = context.plugins\n .byType<GraphQLScalarPlugin>(\"graphql-scalar\")\n .map(item => item.scalar);\n\n const typeDefs: TypeDefs[] = [\n gql`\n type Query\n type Mutation\n ${scalars.map(scalar => `scalar ${scalar.name}`).join(\" \")}\n scalar JSON\n scalar Long\n scalar Icon\n scalar RefInput\n scalar Number\n scalar Any\n scalar Date\n scalar DateTime\n scalar Time\n\n type Error {\n code: String\n message: String\n data: JSON\n stack: String\n }\n\n type BooleanResponse {\n data: Boolean\n error: Error\n }\n `\n ];\n\n const resolvers: Resolvers<any>[] = [\n {\n ...scalars.reduce<Record<string, GraphQLScalarType>>((acc, s) => {\n acc[s.name] = s;\n return acc;\n }, {}),\n JSON: JsonScalar,\n Long: LongScalar,\n RefInput: RefInputScalar,\n Number: NumberScalar,\n Any: AnyScalar,\n DateTime: DateTimeScalar,\n Date: DateScalar,\n Time: TimeScalar,\n Icon: IconScalar\n }\n ];\n\n const resolverDecoration = new ResolverDecoration();\n\n // Process legacy plugins\n const plugins = getSchemaPlugins(context);\n\n for (const plugin of plugins) {\n const schema = plugin.schema;\n if (schema.typeDefs) {\n typeDefs.push(schema.typeDefs);\n }\n if (schema.resolvers) {\n resolvers.push(schema.resolvers);\n }\n if (schema.resolverDecorators) {\n resolverDecoration.addDecorators(schema.resolverDecorators);\n }\n }\n\n // Process new DI implementations\n const graphQLSchemaComposer = context.container.resolve(GraphQLSchemaComposer);\n const schema = await graphQLSchemaComposer.build();\n\n if (schema.typeDefs) {\n typeDefs.push(schema.typeDefs);\n }\n if (schema.resolvers) {\n resolvers.push(schema.resolvers);\n }\n if (schema.resolverDecorators) {\n resolverDecoration.addDecorators(schema.resolverDecorators);\n }\n\n // Create executable schema\n return makeExecutableSchema({\n typeDefs,\n resolvers: resolverDecoration.decorateResolvers(mergeResolvers(resolvers)),\n inheritResolversFromInterfaces: true\n });\n};\n"],"names":["getSchemaPlugins","context","pl","createGraphQLSchema","GraphQLSchemaComposerFeature","scalars","item","typeDefs","gql","scalar","resolvers","acc","s","JsonScalar","LongScalar","RefInputScalar","NumberScalar","AnyScalar","DateTimeScalar","DateScalar","TimeScalar","IconScalar","resolverDecoration","ResolverDecoration","plugins","plugin","schema","graphQLSchemaComposer","GraphQLSchemaComposer","makeExecutableSchema","mergeResolvers"],"mappings":";;;;;;;AAsBO,MAAMA,mBAAmB,CAACC,UACtBA,QAAQ,OAAO,CAAC,MAAM,CAAsB,kBAAkB,MAAM,CAACC,CAAAA;QACxE,IAAI,AAA2B,cAA3B,OAAOA,GAAG,YAAY,EACtB,OAAOA,GAAG,YAAY,CAACD;QAE3B,OAAO;IACX;AAGG,MAAME,sBAAsB,OAAOF;IACtCG,6BAA6B,QAAQ,CAACH,QAAQ,SAAS;IAEvD,MAAMI,UAAUJ,QAAQ,OAAO,CAC1B,MAAM,CAAsB,kBAC5B,GAAG,CAACK,CAAAA,OAAQA,KAAK,MAAM;IAE5B,MAAMC,WAAuB;QACzBC,WAAG,CAAC;;;YAGA,EAAEH,QAAQ,GAAG,CAACI,CAAAA,SAAU,CAAC,OAAO,EAAEA,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;QAsB/D,CAAC;KACJ;IAED,MAAMC,YAA8B;QAChC;YACI,GAAGL,QAAQ,MAAM,CAAoC,CAACM,KAAKC;gBACvDD,GAAG,CAACC,EAAE,IAAI,CAAC,GAAGA;gBACd,OAAOD;YACX,GAAG,CAAC,EAAE;YACN,MAAME;YACN,MAAMC;YACN,UAAUC;YACV,QAAQC;YACR,KAAKC;YACL,UAAUC;YACV,MAAMC;YACN,MAAMC;YACN,MAAMC;QACV;KACH;IAED,MAAMC,qBAAqB,IAAIC;IAG/B,MAAMC,UAAUxB,iBAAiBC;IAEjC,KAAK,MAAMwB,UAAUD,QAAS;QAC1B,MAAME,SAASD,OAAO,MAAM;QAC5B,IAAIC,OAAO,QAAQ,EACfnB,SAAS,IAAI,CAACmB,OAAO,QAAQ;QAEjC,IAAIA,OAAO,SAAS,EAChBhB,UAAU,IAAI,CAACgB,OAAO,SAAS;QAEnC,IAAIA,OAAO,kBAAkB,EACzBJ,mBAAmB,aAAa,CAACI,OAAO,kBAAkB;IAElE;IAGA,MAAMC,wBAAwB1B,QAAQ,SAAS,CAAC,OAAO,CAAC2B;IACxD,MAAMF,SAAS,MAAMC,sBAAsB,KAAK;IAEhD,IAAID,OAAO,QAAQ,EACfnB,SAAS,IAAI,CAACmB,OAAO,QAAQ;IAEjC,IAAIA,OAAO,SAAS,EAChBhB,UAAU,IAAI,CAACgB,OAAO,SAAS;IAEnC,IAAIA,OAAO,kBAAkB,EACzBJ,mBAAmB,aAAa,CAACI,OAAO,kBAAkB;IAI9D,OAAOG,qBAAqB;QACxBtB;QACA,WAAWe,mBAAmB,iBAAiB,CAACQ,eAAepB;QAC/D,gCAAgC;IACpC;AACJ"}
|
package/createRequestBody.js
CHANGED
|
@@ -2,25 +2,27 @@ import zod from "zod";
|
|
|
2
2
|
import { WebinyError } from "@webiny/error";
|
|
3
3
|
import { createZodError } from "@webiny/utils/createZodError.js";
|
|
4
4
|
const requestBodySchema = zod.looseObject({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return value || undefined;
|
|
9
|
-
})
|
|
5
|
+
query: zod.string(),
|
|
6
|
+
variables: zod.record(zod.string(), zod.any()).nullish().optional(),
|
|
7
|
+
operationName: zod.string().nullish().optional().transform((value)=>value || void 0)
|
|
10
8
|
});
|
|
11
|
-
const schema = zod.union([
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
const schema = zod.union([
|
|
10
|
+
requestBodySchema,
|
|
11
|
+
zod.array(requestBodySchema)
|
|
12
|
+
]);
|
|
13
|
+
const createRequestBody = (input)=>{
|
|
14
|
+
const body = "string" == typeof input ? JSON.parse(input) : input;
|
|
15
|
+
const result = schema.safeParse(body);
|
|
16
|
+
if (!result.success) {
|
|
17
|
+
const error = createZodError(result.error);
|
|
18
|
+
throw new WebinyError({
|
|
19
|
+
message: "Invalid GraphQL request! Check your query and variables.",
|
|
20
|
+
code: "GRAPHQL_REQUEST_INVALID",
|
|
21
|
+
data: error.data
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return result.data;
|
|
24
25
|
};
|
|
26
|
+
export { createRequestBody };
|
|
25
27
|
|
|
26
28
|
//# sourceMappingURL=createRequestBody.js.map
|
package/createRequestBody.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"createRequestBody.js","sources":["../src/createRequestBody.ts"],"sourcesContent":["import zod from \"zod\";\nimport { WebinyError } from \"@webiny/error\";\nimport { createZodError } from \"@webiny/utils/createZodError.js\";\nimport type { GraphQLRequestBody } from \"~/types.js\";\n\nconst requestBodySchema = zod.looseObject({\n query: zod.string(),\n variables: zod.record(zod.string(), zod.any()).nullish().optional(),\n operationName: zod\n .string()\n .nullish()\n .optional()\n .transform(value => {\n return value || undefined;\n })\n});\n\nconst schema = zod.union([requestBodySchema, zod.array(requestBodySchema)]);\n\nexport const createRequestBody = (input: unknown): GraphQLRequestBody | GraphQLRequestBody[] => {\n const body = typeof input === \"string\" ? JSON.parse(input) : input;\n\n const result = schema.safeParse(body);\n if (!result.success) {\n const error = createZodError(result.error);\n throw new WebinyError({\n message: \"Invalid GraphQL request! Check your query and variables.\",\n code: \"GRAPHQL_REQUEST_INVALID\",\n data: error.data\n });\n }\n return result.data;\n};\n"],"names":["requestBodySchema","zod","value","undefined","schema","createRequestBody","input","body","JSON","result","error","createZodError","WebinyError"],"mappings":";;;AAKA,MAAMA,oBAAoBC,IAAI,WAAW,CAAC;IACtC,OAAOA,IAAI,MAAM;IACjB,WAAWA,IAAI,MAAM,CAACA,IAAI,MAAM,IAAIA,IAAI,GAAG,IAAI,OAAO,GAAG,QAAQ;IACjE,eAAeA,IAAAA,MACJ,GACN,OAAO,GACP,QAAQ,GACR,SAAS,CAACC,CAAAA,QACAA,SAASC;AAE5B;AAEA,MAAMC,SAASH,IAAI,KAAK,CAAC;IAACD;IAAmBC,IAAI,KAAK,CAACD;CAAmB;AAEnE,MAAMK,oBAAoB,CAACC;IAC9B,MAAMC,OAAO,AAAiB,YAAjB,OAAOD,QAAqBE,KAAK,KAAK,CAACF,SAASA;IAE7D,MAAMG,SAASL,OAAO,SAAS,CAACG;IAChC,IAAI,CAACE,OAAO,OAAO,EAAE;QACjB,MAAMC,QAAQC,eAAeF,OAAO,KAAK;QACzC,MAAM,IAAIG,YAAY;YAClB,SAAS;YACT,MAAM;YACN,MAAMF,MAAM,IAAI;QACpB;IACJ;IACA,OAAOD,OAAO,IAAI;AACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"createResolverDecorator.js","sources":["../src/createResolverDecorator.ts"],"sourcesContent":["import type { ResolverDecorator } from \"./types.js\";\n\nexport const createResolverDecorator = <TSource = any, TContext = any, TArgs = any>(\n decorator: ResolverDecorator<TSource, TContext, TArgs>\n) => {\n return decorator;\n};\n"],"names":["createResolverDecorator","decorator"],"mappings":"AAEO,MAAMA,0BAA0B,CACnCC,YAEOA"}
|
package/debugPlugins.js
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
import { interceptConsole } from "./interceptConsole.js";
|
|
2
2
|
import { ContextPlugin } from "@webiny/api";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}];
|
|
3
|
+
const debugPlugins = ()=>[
|
|
4
|
+
new ContextPlugin(async (context)=>{
|
|
5
|
+
if (!context.debug) context.debug = {};
|
|
6
|
+
if (!context.debug.logs) context.debug.logs = [];
|
|
7
|
+
interceptConsole((method, args)=>{
|
|
8
|
+
context.debug.logs.push({
|
|
9
|
+
method,
|
|
10
|
+
args
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}),
|
|
14
|
+
{
|
|
15
|
+
type: "graphql-after-query",
|
|
16
|
+
apply ({ result, context }) {
|
|
17
|
+
result["extensions"] = {
|
|
18
|
+
console: [
|
|
19
|
+
...context.debug.logs || []
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
if (context.debug.logs) context.debug.logs.length = 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
export default debugPlugins;
|
|
30
27
|
|
|
31
28
|
//# sourceMappingURL=debugPlugins.js.map
|
package/debugPlugins.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"debugPlugins.js","sources":["../src/debugPlugins.ts"],"sourcesContent":["import { interceptConsole } from \"./interceptConsole.js\";\nimport type { GraphQLAfterQueryPlugin } from \"./types.js\";\nimport type { Context } from \"@webiny/api/types.js\";\nimport { ContextPlugin } from \"@webiny/api\";\n\ninterface Log {\n method: string;\n args: any;\n}\ninterface DebugContext extends Context {\n debug: {\n logs?: Log[];\n };\n}\n\nexport default () => [\n new ContextPlugin<DebugContext>(async context => {\n if (!context.debug) {\n context.debug = {};\n }\n\n if (!context.debug.logs) {\n context.debug.logs = [];\n }\n\n interceptConsole((method, args) => {\n (context.debug.logs as Log[]).push({ method, args });\n });\n }),\n {\n type: \"graphql-after-query\",\n apply({ result, context }) {\n result[\"extensions\"] = { console: [...(context.debug.logs || [])] };\n if (context.debug.logs) {\n context.debug.logs.length = 0;\n }\n }\n } as GraphQLAfterQueryPlugin<DebugContext>\n];\n"],"names":["ContextPlugin","context","interceptConsole","method","args","result"],"mappings":";;AAeA,qBAAgB,IAAK;QACjB,IAAIA,cAA4B,OAAMC;YAClC,IAAI,CAACA,QAAQ,KAAK,EACdA,QAAQ,KAAK,GAAG,CAAC;YAGrB,IAAI,CAACA,QAAQ,KAAK,CAAC,IAAI,EACnBA,QAAQ,KAAK,CAAC,IAAI,GAAG,EAAE;YAG3BC,iBAAiB,CAACC,QAAQC;gBACrBH,QAAQ,KAAK,CAAC,IAAI,CAAW,IAAI,CAAC;oBAAEE;oBAAQC;gBAAK;YACtD;QACJ;QACA;YACI,MAAM;YACN,OAAM,EAAEC,MAAM,EAAEJ,OAAO,EAAE;gBACrBI,MAAM,CAAC,aAAa,GAAG;oBAAE,SAAS;2BAAKJ,QAAQ,KAAK,CAAC,IAAI,IAAI,EAAE;qBAAE;gBAAC;gBAClE,IAAIA,QAAQ,KAAK,CAAC,IAAI,EAClBA,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG;YAEpC;QACJ;KACJ"}
|
package/errors.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import error from "@webiny/error";
|
|
2
|
+
class NotFoundError extends error {
|
|
3
|
+
constructor(message = "Not found."){
|
|
4
|
+
super(message, "NOT_FOUND");
|
|
5
|
+
}
|
|
6
6
|
}
|
|
7
|
+
export { NotFoundError };
|
|
7
8
|
|
|
8
9
|
//# sourceMappingURL=errors.js.map
|
package/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\n\nexport class NotFoundError extends WebinyError {\n constructor(message = \"Not found.\") {\n super(message, \"NOT_FOUND\");\n }\n}\n"],"names":["NotFoundError","WebinyError","message"],"mappings":";AAEO,MAAMA,sBAAsBC;IAC/B,YAAYC,UAAU,YAAY,CAAE;QAChC,KAAK,CAACA,SAAS;IACnB;AACJ"}
|
package/exports/api/graphql.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export { GraphQLSchemaFactory } from "../../graphql/abstractions.js";
|
|
2
|
-
export { ErrorResponse,
|
|
3
|
-
|
|
4
|
-
//# sourceMappingURL=graphql.js.map
|
|
2
|
+
export { ErrorResponse, ListErrorResponse, ListResponse, NotFoundResponse, Response } from "../../responses.js";
|
|
@@ -1,64 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
1
|
+
class GraphQLSchemaBuilder {
|
|
2
|
+
addTypeDefs(typeDefs) {
|
|
3
|
+
this.typeDefsArray.push(typeDefs);
|
|
4
|
+
return this;
|
|
5
|
+
}
|
|
6
|
+
addResolver(config) {
|
|
7
|
+
const { path, dependencies = [], resolver } = config;
|
|
8
|
+
const pathParts = path.split(".");
|
|
9
|
+
const graphqlResolver = (parent, args, context, info)=>{
|
|
10
|
+
const resolvedDeps = dependencies.map((dep)=>{
|
|
11
|
+
const [abstraction] = Array.isArray(dep) ? dep : [
|
|
12
|
+
dep
|
|
13
|
+
];
|
|
14
|
+
return context.container.resolve(abstraction);
|
|
15
|
+
});
|
|
16
|
+
const actualResolver = resolver(...resolvedDeps);
|
|
17
|
+
return actualResolver({
|
|
18
|
+
parent,
|
|
19
|
+
args,
|
|
20
|
+
context,
|
|
21
|
+
info
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
this.setResolverAtPath(pathParts, graphqlResolver);
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
addResolverDecorator(path, decorator) {
|
|
28
|
+
if (!this.resolverDecorators[path]) this.resolverDecorators[path] = [];
|
|
29
|
+
this.resolverDecorators[path].push(decorator);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
build() {
|
|
33
|
+
return {
|
|
34
|
+
typeDefs: this.typeDefsArray.join("\n"),
|
|
35
|
+
resolvers: this.resolvers,
|
|
36
|
+
resolverDecorators: this.resolverDecorators
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
setResolverAtPath(pathParts, resolver) {
|
|
40
|
+
let current = this.resolvers;
|
|
41
|
+
for(let i = 0; i < pathParts.length - 1; i++){
|
|
42
|
+
const part = pathParts[i];
|
|
43
|
+
if (!current[part]) current[part] = {};
|
|
44
|
+
current = current[part];
|
|
45
|
+
}
|
|
46
|
+
const finalKey = pathParts[pathParts.length - 1];
|
|
47
|
+
current[finalKey] = resolver;
|
|
39
48
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
typeDefs: this.typeDefsArray.join("\n"),
|
|
46
|
-
resolvers: this.resolvers,
|
|
47
|
-
resolverDecorators: this.resolverDecorators
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
setResolverAtPath(pathParts, resolver) {
|
|
51
|
-
let current = this.resolvers;
|
|
52
|
-
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
53
|
-
const part = pathParts[i];
|
|
54
|
-
if (!current[part]) {
|
|
55
|
-
current[part] = {};
|
|
56
|
-
}
|
|
57
|
-
current = current[part];
|
|
49
|
+
constructor(){
|
|
50
|
+
this.typeDefsArray = [];
|
|
51
|
+
this.resolvers = {};
|
|
52
|
+
this.resolverDecorators = {};
|
|
58
53
|
}
|
|
59
|
-
const finalKey = pathParts[pathParts.length - 1];
|
|
60
|
-
current[finalKey] = resolver;
|
|
61
|
-
}
|
|
62
54
|
}
|
|
55
|
+
export { GraphQLSchemaBuilder };
|
|
63
56
|
|
|
64
57
|
//# sourceMappingURL=GraphQLSchemaBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/GraphQLSchemaBuilder/GraphQLSchemaBuilder.js","sources":["../../../src/features/GraphQLSchemaBuilder/GraphQLSchemaBuilder.ts"],"sourcesContent":["import type { GraphQLSchemaBuilder as Abstraction } from \"./abstractions.js\";\nimport type { IGraphQLSchema } from \"~/graphql/abstractions.public.js\";\nimport type { ResolverDecorator, ResolverDecorators, Resolvers } from \"~/types.js\";\nimport type { Dependency } from \"@webiny/di\";\n\nexport class GraphQLSchemaBuilder implements Abstraction.Interface {\n private readonly typeDefsArray: string[] = [];\n private readonly resolvers: Resolvers<any> = {};\n private readonly resolverDecorators: ResolverDecorators = {};\n\n addTypeDefs(typeDefs: string): this {\n this.typeDefsArray.push(typeDefs);\n return this;\n }\n\n addResolver<TArgs = any>(config: Abstraction.Config<TArgs>): this {\n const { path, dependencies = [], resolver } = config;\n\n const pathParts = path.split(\".\");\n\n const graphqlResolver = (parent: any, args: TArgs, context: any, info: any) => {\n const resolvedDeps = dependencies.map((dep: Dependency) => {\n const [abstraction] = Array.isArray(dep) ? dep : [dep];\n return context.container.resolve(abstraction);\n });\n\n const actualResolver = resolver(...resolvedDeps);\n\n return actualResolver({ parent, args, context, info });\n };\n\n this.setResolverAtPath(pathParts, graphqlResolver);\n\n return this;\n }\n\n /**\n * @internal This method needs revisiting, to align with DI concepts.\n */\n addResolverDecorator(path: string, decorator: ResolverDecorator): this {\n if (!this.resolverDecorators[path]) {\n this.resolverDecorators[path] = [];\n }\n this.resolverDecorators[path].push(decorator);\n return this;\n }\n\n build(): IGraphQLSchema {\n return {\n typeDefs: this.typeDefsArray.join(\"\\n\"),\n resolvers: this.resolvers,\n resolverDecorators: this.resolverDecorators\n };\n }\n\n private setResolverAtPath(pathParts: string[], resolver: any): void {\n let current: any = this.resolvers;\n\n for (let i = 0; i < pathParts.length - 1; i++) {\n const part = pathParts[i];\n if (!current[part]) {\n current[part] = {};\n }\n current = current[part];\n }\n\n const finalKey = pathParts[pathParts.length - 1];\n current[finalKey] = resolver;\n }\n}\n"],"names":["GraphQLSchemaBuilder","typeDefs","config","path","dependencies","resolver","pathParts","graphqlResolver","parent","args","context","info","resolvedDeps","dep","abstraction","Array","actualResolver","decorator","current","i","part","finalKey"],"mappings":"AAKO,MAAMA;IAKT,YAAYC,QAAgB,EAAQ;QAChC,IAAI,CAAC,aAAa,CAAC,IAAI,CAACA;QACxB,OAAO,IAAI;IACf;IAEA,YAAyBC,MAAiC,EAAQ;QAC9D,MAAM,EAAEC,IAAI,EAAEC,eAAe,EAAE,EAAEC,QAAQ,EAAE,GAAGH;QAE9C,MAAMI,YAAYH,KAAK,KAAK,CAAC;QAE7B,MAAMI,kBAAkB,CAACC,QAAaC,MAAaC,SAAcC;YAC7D,MAAMC,eAAeR,aAAa,GAAG,CAAC,CAACS;gBACnC,MAAM,CAACC,YAAY,GAAGC,MAAM,OAAO,CAACF,OAAOA,MAAM;oBAACA;iBAAI;gBACtD,OAAOH,QAAQ,SAAS,CAAC,OAAO,CAACI;YACrC;YAEA,MAAME,iBAAiBX,YAAYO;YAEnC,OAAOI,eAAe;gBAAER;gBAAQC;gBAAMC;gBAASC;YAAK;QACxD;QAEA,IAAI,CAAC,iBAAiB,CAACL,WAAWC;QAElC,OAAO,IAAI;IACf;IAKA,qBAAqBJ,IAAY,EAAEc,SAA4B,EAAQ;QACnE,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAACd,KAAK,EAC9B,IAAI,CAAC,kBAAkB,CAACA,KAAK,GAAG,EAAE;QAEtC,IAAI,CAAC,kBAAkB,CAACA,KAAK,CAAC,IAAI,CAACc;QACnC,OAAO,IAAI;IACf;IAEA,QAAwB;QACpB,OAAO;YACH,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAClC,WAAW,IAAI,CAAC,SAAS;YACzB,oBAAoB,IAAI,CAAC,kBAAkB;QAC/C;IACJ;IAEQ,kBAAkBX,SAAmB,EAAED,QAAa,EAAQ;QAChE,IAAIa,UAAe,IAAI,CAAC,SAAS;QAEjC,IAAK,IAAIC,IAAI,GAAGA,IAAIb,UAAU,MAAM,GAAG,GAAGa,IAAK;YAC3C,MAAMC,OAAOd,SAAS,CAACa,EAAE;YACzB,IAAI,CAACD,OAAO,CAACE,KAAK,EACdF,OAAO,CAACE,KAAK,GAAG,CAAC;YAErBF,UAAUA,OAAO,CAACE,KAAK;QAC3B;QAEA,MAAMC,WAAWf,SAAS,CAACA,UAAU,MAAM,GAAG,EAAE;QAChDY,OAAO,CAACG,SAAS,GAAGhB;IACxB;;aA9DiB,aAAa,GAAa,EAAE;aAC5B,SAAS,GAAmB,CAAC;aAC7B,kBAAkB,GAAuB,CAAC;;AA6D/D"}
|
|
@@ -1,29 +1,35 @@
|
|
|
1
|
-
import { GraphQLSchemaComposer
|
|
2
|
-
import {
|
|
1
|
+
import { GraphQLSchemaComposer } from "./abstractions.js";
|
|
2
|
+
import { CoreGraphQLSchemaFactory, GraphQLSchemaFactory } from "../../graphql/abstractions.js";
|
|
3
3
|
import { GraphQLSchemaBuilder } from "./GraphQLSchemaBuilder.js";
|
|
4
4
|
class GraphQLSchemaComposerImpl {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
async build() {
|
|
10
|
-
const builder = new GraphQLSchemaBuilder();
|
|
11
|
-
for (const factory of this.coreSchemas) {
|
|
12
|
-
await factory.execute(builder);
|
|
5
|
+
constructor(coreSchemas, userSchemas){
|
|
6
|
+
this.coreSchemas = coreSchemas;
|
|
7
|
+
this.userSchemas = userSchemas;
|
|
13
8
|
}
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
async build() {
|
|
10
|
+
const builder = new GraphQLSchemaBuilder();
|
|
11
|
+
for (const factory of this.coreSchemas)await factory.execute(builder);
|
|
12
|
+
for (const factory of this.userSchemas)await factory.execute(builder);
|
|
13
|
+
return builder.build();
|
|
16
14
|
}
|
|
17
|
-
return builder.build();
|
|
18
|
-
}
|
|
19
15
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
const GraphQLSchemaComposer_GraphQLSchemaComposer = GraphQLSchemaComposer.createImplementation({
|
|
17
|
+
implementation: GraphQLSchemaComposerImpl,
|
|
18
|
+
dependencies: [
|
|
19
|
+
[
|
|
20
|
+
CoreGraphQLSchemaFactory,
|
|
21
|
+
{
|
|
22
|
+
multiple: true
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
GraphQLSchemaFactory,
|
|
27
|
+
{
|
|
28
|
+
multiple: true
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
]
|
|
27
32
|
});
|
|
33
|
+
export { GraphQLSchemaComposer_GraphQLSchemaComposer as GraphQLSchemaComposer };
|
|
28
34
|
|
|
29
35
|
//# sourceMappingURL=GraphQLSchemaComposer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/GraphQLSchemaBuilder/GraphQLSchemaComposer.js","sources":["../../../src/features/GraphQLSchemaBuilder/GraphQLSchemaComposer.ts"],"sourcesContent":["import { GraphQLSchemaComposer as Abstraction } from \"./abstractions.js\";\nimport { GraphQLSchemaFactory, CoreGraphQLSchemaFactory } from \"~/graphql/abstractions.js\";\nimport { GraphQLSchemaBuilder } from \"./GraphQLSchemaBuilder.js\";\nimport type { IGraphQLSchema } from \"~/graphql/abstractions.public.js\";\n\nclass GraphQLSchemaComposerImpl implements Abstraction.Interface {\n constructor(\n private coreSchemas: CoreGraphQLSchemaFactory.Interface[],\n private userSchemas: GraphQLSchemaFactory.Interface[]\n ) {}\n\n async build(): Promise<IGraphQLSchema> {\n const builder = new GraphQLSchemaBuilder();\n\n for (const factory of this.coreSchemas) {\n await factory.execute(builder);\n }\n\n for (const factory of this.userSchemas) {\n await factory.execute(builder);\n }\n\n return builder.build();\n }\n}\n\nexport const GraphQLSchemaComposer = Abstraction.createImplementation({\n implementation: GraphQLSchemaComposerImpl,\n dependencies: [\n [CoreGraphQLSchemaFactory, { multiple: true }],\n [GraphQLSchemaFactory, { multiple: true }]\n ]\n});\n"],"names":["GraphQLSchemaComposerImpl","coreSchemas","userSchemas","builder","GraphQLSchemaBuilder","factory","GraphQLSchemaComposer","Abstraction","CoreGraphQLSchemaFactory","GraphQLSchemaFactory"],"mappings":";;;AAKA,MAAMA;IACF,YACYC,WAAiD,EACjDC,WAA6C,CACvD;aAFUD,WAAW,GAAXA;aACAC,WAAW,GAAXA;IACT;IAEH,MAAM,QAAiC;QACnC,MAAMC,UAAU,IAAIC;QAEpB,KAAK,MAAMC,WAAW,IAAI,CAAC,WAAW,CAClC,MAAMA,QAAQ,OAAO,CAACF;QAG1B,KAAK,MAAME,WAAW,IAAI,CAAC,WAAW,CAClC,MAAMA,QAAQ,OAAO,CAACF;QAG1B,OAAOA,QAAQ,KAAK;IACxB;AACJ;AAEO,MAAMG,8CAAwBC,sBAAAA,oBAAgC,CAAC;IAClE,gBAAgBP;IAChB,cAAc;QACV;YAACQ;YAA0B;gBAAE,UAAU;YAAK;SAAE;QAC9C;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAC7C;AACL"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createAbstraction } from "@webiny/feature/api";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
const GraphQLSchemaBuilder = createAbstraction("GraphQLSchemaBuilder");
|
|
3
|
+
const GraphQLSchemaComposer = createAbstraction("GraphQLSchemaComposer");
|
|
4
|
+
export { GraphQLSchemaBuilder, GraphQLSchemaComposer };
|
|
4
5
|
|
|
5
6
|
//# sourceMappingURL=abstractions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/GraphQLSchemaBuilder/abstractions.js","sources":["../../../src/features/GraphQLSchemaBuilder/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { ResolverDecorator, TypeDefs } from \"~/types.js\";\nimport type { Dependency } from \"@webiny/di\";\nimport type { IGraphQLSchema } from \"~/graphql/abstractions.public.js\";\n\nexport interface ResolverConfig<TArgs = any, TParent = any> {\n path: string;\n dependencies?: Dependency[];\n resolver: (\n ...resolvedDeps: any[]\n ) => (params: { parent: TParent; args: TArgs; context: any; info: any }) => any;\n}\n\nexport interface IGraphQLSchemaBuilder {\n addTypeDefs(typeDefs: TypeDefs): this;\n addResolver<TArgs = any, TParent = any>(config: ResolverConfig<TArgs, TParent>): this;\n /**\n * @internal This method needs revisiting, to align with DI concepts.\n */\n addResolverDecorator(path: string, decorator: ResolverDecorator): this;\n build(): IGraphQLSchema;\n}\n\nexport const GraphQLSchemaBuilder =\n createAbstraction<IGraphQLSchemaBuilder>(\"GraphQLSchemaBuilder\");\n\nexport namespace GraphQLSchemaBuilder {\n export type Interface = IGraphQLSchemaBuilder;\n export type Config<TArgs = any> = ResolverConfig<TArgs>;\n}\n\nexport interface IGraphQLSchemaComposer {\n build(): Promise<IGraphQLSchema>;\n}\n\nexport const GraphQLSchemaComposer =\n createAbstraction<IGraphQLSchemaComposer>(\"GraphQLSchemaComposer\");\n\nexport namespace GraphQLSchemaComposer {\n export type Interface = IGraphQLSchemaComposer;\n}\n"],"names":["GraphQLSchemaBuilder","createAbstraction","GraphQLSchemaComposer"],"mappings":";AAuBO,MAAMA,uBACTC,kBAAyC;AAWtC,MAAMC,wBACTD,kBAA0C"}
|