@baeta/extension-complexity 2.0.0-next.11 → 2.0.0-next.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.d.ts +14 -19
- package/dist/index.js +15 -26
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @baeta/extension-complexity
|
|
2
2
|
|
|
3
|
+
## 2.0.0-next.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`3e7a4d7`](https://github.com/andreisergiu98/baeta/commit/3e7a4d71a59543b8a506938f788aec8b5d907776)]:
|
|
8
|
+
- @baeta/core@2.0.0-next.13
|
|
9
|
+
|
|
10
|
+
## 2.0.0-next.12
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies []:
|
|
15
|
+
- @baeta/core@2.0.0-next.12
|
|
16
|
+
|
|
3
17
|
## 2.0.0-next.11
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as _baeta_core_sdk0 from "@baeta/core/sdk";
|
|
1
|
+
import * as _$_baeta_core_sdk0 from "@baeta/core/sdk";
|
|
2
2
|
import { Extension, FieldBuilder, ModuleCompiler, SubscriptionBuilder, TypeBuilder } from "@baeta/core/sdk";
|
|
3
3
|
import { GraphQLError, GraphQLErrorOptions } from "graphql";
|
|
4
4
|
|
|
@@ -14,9 +14,7 @@ type FieldSettings = {
|
|
|
14
14
|
* Arguments passed to field settings functions.
|
|
15
15
|
*/
|
|
16
16
|
type GetFieldSettingsArgs<Context, Args> = {
|
|
17
|
-
/** Arguments passed to the GraphQL field */
|
|
18
|
-
args: Args;
|
|
19
|
-
/** Request context */
|
|
17
|
+
/** Arguments passed to the GraphQL field */args: Args; /** Request context */
|
|
20
18
|
ctx: Context;
|
|
21
19
|
};
|
|
22
20
|
/**
|
|
@@ -31,7 +29,7 @@ type GetFieldSettings<Context, Args> = (params: GetFieldSettingsArgs<Context, Ar
|
|
|
31
29
|
//#region lib/global-types.d.ts
|
|
32
30
|
declare global {
|
|
33
31
|
export namespace BaetaExtensions {
|
|
34
|
-
interface FieldExtensions<Result, Source, Context, Args, Info
|
|
32
|
+
interface FieldExtensions<Result, Source, Context, Args, Info> {
|
|
35
33
|
/**
|
|
36
34
|
* Configures complexity calculation for a type field.
|
|
37
35
|
*
|
|
@@ -48,9 +46,9 @@ declare global {
|
|
|
48
46
|
* Query.simple.$complexity(() => false);
|
|
49
47
|
* ```
|
|
50
48
|
*/
|
|
51
|
-
$complexity: (fn: GetFieldSettings<Context, Args>) => ReturnType<
|
|
49
|
+
$complexity: (fn: GetFieldSettings<Context, Args>) => ReturnType<FieldBuilder<Result, Source, Context, Args, Info>['toMethods']>;
|
|
52
50
|
}
|
|
53
|
-
interface TypeExtensions<Source, Context, Info
|
|
51
|
+
interface TypeExtensions<Source, Context, Info> {
|
|
54
52
|
/**
|
|
55
53
|
* Configures complexity calculation for a type field.
|
|
56
54
|
*
|
|
@@ -67,9 +65,9 @@ declare global {
|
|
|
67
65
|
* Query.simple.$complexity(() => false);
|
|
68
66
|
* ```
|
|
69
67
|
*/
|
|
70
|
-
$complexity: (fn: GetFieldSettings<Context, unknown>) => ReturnType<
|
|
68
|
+
$complexity: (fn: GetFieldSettings<Context, unknown>) => ReturnType<TypeBuilder<Source, Context, Info>['toMethods']>;
|
|
71
69
|
}
|
|
72
|
-
interface SubscriptionExtensions<Result, Source, Context, Args, Info
|
|
70
|
+
interface SubscriptionExtensions<Result, Source, Context, Args, Info> {
|
|
73
71
|
/**
|
|
74
72
|
* Configures complexity calculation for a type field.
|
|
75
73
|
*
|
|
@@ -86,7 +84,7 @@ declare global {
|
|
|
86
84
|
* Query.simple.$complexity(() => false);
|
|
87
85
|
* ```
|
|
88
86
|
*/
|
|
89
|
-
$complexity: (fn: GetFieldSettings<Context, Args>) => ReturnType<
|
|
87
|
+
$complexity: (fn: GetFieldSettings<Context, Args>) => ReturnType<SubscriptionBuilder<Result, Source, Context, Args, Info>['toMethods']>;
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
90
|
}
|
|
@@ -104,11 +102,8 @@ declare class ComplexityError extends GraphQLError {
|
|
|
104
102
|
* Types of complexity validation errors that can occur during query analysis.
|
|
105
103
|
*/
|
|
106
104
|
declare const ComplexityErrorKind: {
|
|
107
|
-
/** Query exceeds maximum allowed depth */
|
|
108
|
-
|
|
109
|
-
/** Query exceeds maximum allowed breadth (fields per level) */
|
|
110
|
-
Breadth: string;
|
|
111
|
-
/** Query exceeds total complexity score limit */
|
|
105
|
+
/** Query exceeds maximum allowed depth */Depth: string; /** Query exceeds maximum allowed breadth (fields per level) */
|
|
106
|
+
Breadth: string; /** Query exceeds total complexity score limit */
|
|
112
107
|
Complexity: string;
|
|
113
108
|
};
|
|
114
109
|
type ComplexityErrorKind = (typeof ComplexityErrorKind)[keyof typeof ComplexityErrorKind];
|
|
@@ -175,11 +170,11 @@ declare class ComplexityExtension<Ctx> extends Extension<ComplexityState> {
|
|
|
175
170
|
readonly stateKey: symbol;
|
|
176
171
|
private readonly options;
|
|
177
172
|
constructor(options?: ComplexityExtensionOptions<Ctx>);
|
|
178
|
-
getTypeExtensions
|
|
179
|
-
getFieldExtensions
|
|
180
|
-
getSubscriptionExtensions
|
|
173
|
+
getTypeExtensions<Source, Context, Info>(builder: TypeBuilder<Source, Context, Info>): BaetaExtensions.TypeExtensions<Source, Context, Info>;
|
|
174
|
+
getFieldExtensions<Result, Source, Context, Args, Info>(builder: FieldBuilder<Result, Source, Context, Args, Info>): BaetaExtensions.FieldExtensions<Result, Source, Context, Args, Info>;
|
|
175
|
+
getSubscriptionExtensions<Result, Source, Context, Args, Info>(builder: SubscriptionBuilder<Result, Source, Context, Args, Info>): BaetaExtensions.SubscriptionExtensions<Result, Source, Context, Args, Info>;
|
|
181
176
|
mutate(compilers: ModuleCompiler[]): void;
|
|
182
|
-
protected iterateTypes(compilers: ModuleCompiler[]): Generator<_baeta_core_sdk0.TypeCompiler<unknown, unknown, unknown, _baeta_core_sdk0.FieldsResolversMap<unknown, unknown, unknown>>, void, unknown>;
|
|
177
|
+
protected iterateTypes(compilers: ModuleCompiler[]): Generator<_$_baeta_core_sdk0.TypeCompiler<unknown, unknown, unknown, _$_baeta_core_sdk0.FieldsResolversMap<unknown, unknown, unknown>>, void, unknown>;
|
|
183
178
|
}
|
|
184
179
|
//#endregion
|
|
185
180
|
//#region index.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { Extension } from "@baeta/core/sdk";
|
|
2
2
|
import { GraphQLError, GraphQLList, GraphQLNonNull, Kind, getArgumentValues, getNamedType, isInterfaceType, isObjectType, isOutputType } from "graphql";
|
|
3
3
|
import { createContextStore } from "@baeta/core";
|
|
4
|
-
|
|
5
4
|
//#region utils/graphlq.ts
|
|
6
5
|
function isListOrNullableList(type) {
|
|
7
6
|
if (type instanceof GraphQLList) return true;
|
|
8
7
|
if (type instanceof GraphQLNonNull) return isListOrNullableList(type.ofType);
|
|
9
8
|
return false;
|
|
10
9
|
}
|
|
11
|
-
|
|
12
10
|
//#endregion
|
|
13
11
|
//#region utils/string.ts
|
|
14
12
|
function capitalize(str) {
|
|
15
13
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
16
14
|
}
|
|
17
|
-
|
|
18
15
|
//#endregion
|
|
19
16
|
//#region lib/complexity-errors.ts
|
|
20
17
|
/** Complexity error code */
|
|
@@ -37,8 +34,11 @@ var ComplexityError = class extends GraphQLError {
|
|
|
37
34
|
* Types of complexity validation errors that can occur during query analysis.
|
|
38
35
|
*/
|
|
39
36
|
const ComplexityErrorKind = {
|
|
37
|
+
/** Query exceeds maximum allowed depth */
|
|
40
38
|
Depth: "DepthExceeded",
|
|
39
|
+
/** Query exceeds maximum allowed breadth (fields per level) */
|
|
41
40
|
Breadth: "BreadthExceeded",
|
|
41
|
+
/** Query exceeds total complexity score limit */
|
|
42
42
|
Complexity: "ComplexityExceeded"
|
|
43
43
|
};
|
|
44
44
|
function getDefaultComplexityError(kind, limit, result) {
|
|
@@ -59,7 +59,6 @@ function getDefaultComplexityError(kind, limit, result) {
|
|
|
59
59
|
} });
|
|
60
60
|
throw new Error("Unknown complexity error kind");
|
|
61
61
|
}
|
|
62
|
-
|
|
63
62
|
//#endregion
|
|
64
63
|
//#region lib/field-settings.ts
|
|
65
64
|
function getFieldComplexitySettings(ctx, info, type, field, selection, fieldName, fieldSettingsMap) {
|
|
@@ -79,7 +78,6 @@ function registerFieldSettingsSetter(type, field, fn, map) {
|
|
|
79
78
|
if (!map.has(type)) map.set(type, /* @__PURE__ */ new Map());
|
|
80
79
|
map.get(type)?.set(field, fn);
|
|
81
80
|
}
|
|
82
|
-
|
|
83
81
|
//#endregion
|
|
84
82
|
//#region lib/complexity-calculator.ts
|
|
85
83
|
/**
|
|
@@ -159,7 +157,6 @@ function complexityFromField(ctx, info, type, selection, fieldSettingsMap, defau
|
|
|
159
157
|
complexity
|
|
160
158
|
};
|
|
161
159
|
}
|
|
162
|
-
|
|
163
160
|
//#endregion
|
|
164
161
|
//#region lib/complexity-options.ts
|
|
165
162
|
const defaultLimits = {
|
|
@@ -175,15 +172,10 @@ function normalizeOptions(options) {
|
|
|
175
172
|
complexityError: options.complexityError ?? getDefaultComplexityError
|
|
176
173
|
};
|
|
177
174
|
}
|
|
178
|
-
|
|
179
|
-
//#endregion
|
|
180
|
-
//#region lib/store.ts
|
|
181
|
-
const complexityStoreKey = Symbol("complexity-extension");
|
|
182
|
-
const [getComplexityStore, setComplexityStoreLoader] = createContextStore(complexityStoreKey);
|
|
183
|
-
|
|
175
|
+
const [getComplexityStore, setComplexityStoreLoader] = createContextStore(Symbol("complexity-extension"));
|
|
184
176
|
//#endregion
|
|
185
177
|
//#region lib/store-loader.ts
|
|
186
|
-
function loadComplexityStore(ctx, getLimits, defaultLimits
|
|
178
|
+
function loadComplexityStore(ctx, getLimits, defaultLimits) {
|
|
187
179
|
setComplexityStoreLoader(ctx, async () => {
|
|
188
180
|
const limits = typeof getLimits === "function" ? await getLimits(ctx) : getLimits;
|
|
189
181
|
let cache;
|
|
@@ -194,15 +186,14 @@ function loadComplexityStore(ctx, getLimits, defaultLimits$1) {
|
|
|
194
186
|
};
|
|
195
187
|
return {
|
|
196
188
|
limits: {
|
|
197
|
-
depth: limits?.depth ?? defaultLimits
|
|
198
|
-
breadth: limits?.breadth ?? defaultLimits
|
|
199
|
-
complexity: limits?.complexity ?? defaultLimits
|
|
189
|
+
depth: limits?.depth ?? defaultLimits.depth,
|
|
190
|
+
breadth: limits?.breadth ?? defaultLimits.breadth,
|
|
191
|
+
complexity: limits?.complexity ?? defaultLimits.complexity
|
|
200
192
|
},
|
|
201
193
|
cacheComplexity
|
|
202
194
|
};
|
|
203
195
|
});
|
|
204
196
|
}
|
|
205
|
-
|
|
206
197
|
//#endregion
|
|
207
198
|
//#region lib/complexity-middleware.ts
|
|
208
199
|
function createComplexityMiddleware(options, fieldSettingsMap) {
|
|
@@ -222,7 +213,6 @@ function createComplexityMiddleware(options, fieldSettingsMap) {
|
|
|
222
213
|
return next();
|
|
223
214
|
};
|
|
224
215
|
}
|
|
225
|
-
|
|
226
216
|
//#endregion
|
|
227
217
|
//#region lib/complexity-extension.ts
|
|
228
218
|
var ComplexityExtension = class extends Extension {
|
|
@@ -232,27 +222,27 @@ var ComplexityExtension = class extends Extension {
|
|
|
232
222
|
super();
|
|
233
223
|
this.options = normalizeOptions(options);
|
|
234
224
|
}
|
|
235
|
-
getTypeExtensions
|
|
225
|
+
getTypeExtensions(builder) {
|
|
236
226
|
return { $complexity: (fn) => {
|
|
237
227
|
const editable = builder.edit();
|
|
238
228
|
this.setState(editable, { fieldSettings: fn });
|
|
239
229
|
return editable.commitToMethods();
|
|
240
230
|
} };
|
|
241
|
-
}
|
|
242
|
-
getFieldExtensions
|
|
231
|
+
}
|
|
232
|
+
getFieldExtensions(builder) {
|
|
243
233
|
return { $complexity: (fn) => {
|
|
244
234
|
const editable = builder.edit();
|
|
245
235
|
this.setState(editable, { fieldSettings: fn });
|
|
246
236
|
return editable.commitToMethods();
|
|
247
237
|
} };
|
|
248
|
-
}
|
|
249
|
-
getSubscriptionExtensions
|
|
238
|
+
}
|
|
239
|
+
getSubscriptionExtensions(builder) {
|
|
250
240
|
return { $complexity: (fn) => {
|
|
251
241
|
const editable = builder.edit();
|
|
252
242
|
this.setState(editable, { fieldSettings: fn });
|
|
253
243
|
return editable.commitToMethods();
|
|
254
244
|
} };
|
|
255
|
-
}
|
|
245
|
+
}
|
|
256
246
|
mutate(compilers) {
|
|
257
247
|
const fieldSettingsMap = /* @__PURE__ */ new Map();
|
|
258
248
|
for (const typeCompiler of this.iterateTypes(compilers)) {
|
|
@@ -278,7 +268,6 @@ var ComplexityExtension = class extends Extension {
|
|
|
278
268
|
for (const compiler of compilers) for (const typeCompiler of compiler.types) yield typeCompiler;
|
|
279
269
|
}
|
|
280
270
|
};
|
|
281
|
-
|
|
282
271
|
//#endregion
|
|
283
272
|
//#region index.ts
|
|
284
273
|
/**
|
|
@@ -303,7 +292,7 @@ var ComplexityExtension = class extends Extension {
|
|
|
303
292
|
function complexityExtension(options) {
|
|
304
293
|
return new ComplexityExtension(options);
|
|
305
294
|
}
|
|
306
|
-
|
|
307
295
|
//#endregion
|
|
308
296
|
export { ComplexityError, ComplexityErrorCode, ComplexityErrorKind, complexityExtension };
|
|
297
|
+
|
|
309
298
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["cache: Required<ComplexityLimit> | undefined","defaultLimits","fieldSettingsMap: FieldSettingsMap"],"sources":["../utils/graphlq.ts","../utils/string.ts","../lib/complexity-errors.ts","../lib/field-settings.ts","../lib/complexity-calculator.ts","../lib/complexity-options.ts","../lib/store.ts","../lib/store-loader.ts","../lib/complexity-middleware.ts","../lib/complexity-extension.ts","../index.ts"],"sourcesContent":["import { GraphQLList, GraphQLNonNull, type GraphQLOutputType } from 'graphql';\n\nexport function isListOrNullableList(type: GraphQLOutputType): boolean {\n\tif (type instanceof GraphQLList) {\n\t\treturn true;\n\t}\n\n\tif (type instanceof GraphQLNonNull) {\n\t\treturn isListOrNullableList(type.ofType);\n\t}\n\n\treturn false;\n}\n","export function capitalize(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { GraphQLError, type GraphQLErrorOptions } from 'graphql';\n\n/** Complexity error code */\nexport const ComplexityErrorCode = 'COMPLEXITY_ERROR';\n\n/**\n * Thrown when a query exceeds the complexity limits.\n */\nexport class ComplexityError extends GraphQLError {\n\tconstructor(\n\t\tmessage = \"Complexity limit exceeded! Please reduce the query's complexity.\",\n\t\toptions?: GraphQLErrorOptions,\n\t) {\n\t\tsuper(message, {\n\t\t\t...options,\n\t\t\textensions: {\n\t\t\t\tcode: ComplexityErrorCode,\n\t\t\t\t...options?.extensions,\n\t\t\t},\n\t\t});\n\t}\n}\n\n/**\n * Types of complexity validation errors that can occur during query analysis.\n */\nexport const ComplexityErrorKind = {\n\t/** Query exceeds maximum allowed depth */\n\tDepth: 'DepthExceeded',\n\t/** Query exceeds maximum allowed breadth (fields per level) */\n\tBreadth: 'BreadthExceeded',\n\t/** Query exceeds total complexity score limit */\n\tComplexity: 'ComplexityExceeded',\n};\n\ntype ComplexityErrorKind = (typeof ComplexityErrorKind)[keyof typeof ComplexityErrorKind];\n\n/**\n * Function type for creating custom complexity error messages.\n *\n * @param kind - The type of complexity limit that was exceeded\n * @param limits - The maximum allowed value\n * @param results - The actual value that exceeded the limit\n * @returns A GraphQL error with a custom message\n */\nexport type GetComplexityError = (\n\tkind: ComplexityErrorKind,\n\tlimits: number,\n\tresults: number,\n) => GraphQLError;\n\nexport function getDefaultComplexityError(\n\tkind: ComplexityErrorKind,\n\tlimit: number,\n\tresult: number,\n): GraphQLError {\n\tif (kind === ComplexityErrorKind.Depth) {\n\t\treturn new ComplexityError(`Depth limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Depth,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tif (kind === ComplexityErrorKind.Breadth) {\n\t\treturn new ComplexityError(`Breadth limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Breadth,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tif (kind === ComplexityErrorKind.Complexity) {\n\t\treturn new ComplexityError(`Complexity limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Complexity,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tthrow new Error('Unknown complexity error kind');\n}\n","import {\n\ttype FieldNode,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\tgetArgumentValues,\n} from 'graphql';\n\nexport type FieldSettingsMap = Map<string, Map<string, GetFieldSettings<unknown, unknown>>>;\n\n/**\n * Configuration for field complexity calculation.\n */\nexport type FieldSettings = {\n\tcomplexity?: number;\n\tmultiplier?: number;\n};\n\n/**\n * Arguments passed to field settings functions.\n */\nexport type GetFieldSettingsArgs<Context, Args> = {\n\t/** Arguments passed to the GraphQL field */\n\targs: Args;\n\t/** Request context */\n\tctx: Context;\n};\n\n/**\n * Function to determine complexity settings for a field.\n * Returns either field settings or false to disable complexity calculation.\n *\n * @param params - Object containing field arguments and context\n * @returns Field settings object or false\n */\nexport type GetFieldSettings<Context, Args> = (\n\tparams: GetFieldSettingsArgs<Context, Args>,\n) => FieldSettings | false;\n\nexport function getFieldComplexitySettings<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tfield: GraphQLField<unknown, unknown>,\n\tselection: FieldNode,\n\tfieldName: string,\n\tfieldSettingsMap: FieldSettingsMap,\n) {\n\tconst args = getArgumentValues(field, selection, info.variableValues);\n\tconst customComplexity = fieldSettingsMap.get(type.name)?.get(fieldName);\n\n\tif (customComplexity) {\n\t\treturn customComplexity({ args, ctx });\n\t}\n\n\tconst wildCardComplexity = fieldSettingsMap.get(type.name)?.get('*');\n\n\tif (wildCardComplexity) {\n\t\treturn wildCardComplexity({ args, ctx });\n\t}\n}\n\nexport function registerFieldSettingsSetter<Context, Args>(\n\ttype: string,\n\tfield: string,\n\tfn: GetFieldSettings<Context, Args>,\n\tmap: FieldSettingsMap,\n) {\n\tif (!map.has(type)) {\n\t\tmap.set(type, new Map());\n\t}\n\tmap.get(type)?.set(field, fn as GetFieldSettings<unknown, unknown>);\n}\n","/**\n * Originally based on plugin-complexity of Pothos\n * Source: https://github.com/hayes/pothos/blob/main/packages/plugin-complexity/src/calculate-complexity.ts\n * Copyright (c) 2021 Michael Hayes\n * Adapted by Baeta developers\n */\nimport {\n\ttype FieldNode,\n\ttype FragmentDefinitionNode,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\tgetNamedType,\n\ttype InlineFragmentNode,\n\tisInterfaceType,\n\tisObjectType,\n\tisOutputType,\n\tKind,\n\ttype SelectionNode,\n\ttype SelectionSetNode,\n} from 'graphql';\nimport { isListOrNullableList } from '../utils/graphlq.ts';\nimport { capitalize } from '../utils/string.ts';\nimport { ComplexityError } from './complexity-errors.ts';\nimport { type FieldSettingsMap, getFieldComplexitySettings } from './field-settings.ts';\n\ninterface ComplexityDefaults {\n\tcomplexity: number;\n\tmultiplier: number;\n}\n\nexport function calculateComplexity<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst operationName = capitalize(info.operation.operation);\n\tconst operationType = info.schema.getType(operationName);\n\n\tif (!operationType || !isOutputType(operationType)) {\n\t\tthrow new ComplexityError(`Unsupported operation ${operationName}`);\n\t}\n\n\treturn complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\toperationType,\n\t\tinfo.operation.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n}\n\nfunction complexityFromSelectionSet<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselectionSet: SelectionSetNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst result = {\n\t\tdepth: 0,\n\t\tbreadth: 0,\n\t\tcomplexity: 0,\n\t};\n\n\tfor (const selection of selectionSet.selections) {\n\t\tconst selectionResult = complexityFromSelection(\n\t\t\tctx,\n\t\t\tinfo,\n\t\t\ttype,\n\t\t\tselection,\n\t\t\tfieldSettingsMap,\n\t\t\tdefaults,\n\t\t);\n\t\tresult.complexity += selectionResult.complexity;\n\t\tresult.breadth += selectionResult.breadth;\n\t\tresult.depth = Math.max(result.depth, selectionResult.depth);\n\t}\n\n\treturn result;\n}\n\nfunction complexityFromSelection<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselection: SelectionNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tif (selection.kind === Kind.FIELD) {\n\t\treturn complexityFromField(ctx, info, type, selection, fieldSettingsMap, defaults);\n\t}\n\n\tif (selection.kind === Kind.FRAGMENT_SPREAD) {\n\t\tconst fragment = info.fragments[selection.name.value];\n\n\t\tif (!fragment) {\n\t\t\tthrow new ComplexityError(`Fragment ${selection.name.value} not found`);\n\t\t}\n\n\t\treturn complexityFromFragment(ctx, info, type, fragment, fieldSettingsMap, defaults);\n\t}\n\n\treturn complexityFromFragment(ctx, info, type, selection, fieldSettingsMap, defaults);\n}\n\nfunction complexityFromFragment<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tfragment: FragmentDefinitionNode | InlineFragmentNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst fragmentType = fragment.typeCondition\n\t\t? info.schema.getType(fragment.typeCondition.name.value)\n\t\t: type;\n\n\tif (!isOutputType(fragmentType)) {\n\t\tthrow new ComplexityError(`Unsupported fragment type ${fragmentType}`);\n\t}\n\n\tif (!fragmentType) {\n\t\tthrow new ComplexityError(`Fragment type ${fragmentType} not found`);\n\t}\n\n\treturn complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\tfragmentType,\n\t\tfragment.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n}\n\nfunction complexityFromField<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselection: FieldNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst fieldName = selection.name.value;\n\n\tconst field =\n\t\tisObjectType(type) || isInterfaceType(type) ? type.getFields()[fieldName] : undefined;\n\n\tif (!field && !fieldName.startsWith('__')) {\n\t\tthrow new ComplexityError(`Field ${fieldName} not found on type ${type.name}`);\n\t}\n\n\tif (!field) {\n\t\treturn {\n\t\t\tdepth: 1,\n\t\t\tbreadth: 1,\n\t\t\tcomplexity: 1,\n\t\t};\n\t}\n\n\tconst fieldComplexitySettings = getFieldComplexitySettings(\n\t\tctx,\n\t\tinfo,\n\t\ttype,\n\t\tfield,\n\t\tselection,\n\t\tfieldName,\n\t\tfieldSettingsMap,\n\t);\n\n\tif (fieldComplexitySettings === false) {\n\t\treturn {\n\t\t\tdepth: 0,\n\t\t\tbreadth: 0,\n\t\t\tcomplexity: 0,\n\t\t};\n\t}\n\n\tlet depth = 1;\n\tlet breadth = 1;\n\tlet complexity = 0;\n\n\tconst listMultiplier = fieldComplexitySettings?.multiplier ?? defaults.multiplier;\n\tconst multiplier = field && isListOrNullableList(field.type) ? listMultiplier : 1;\n\n\tcomplexity += (fieldComplexitySettings?.complexity ?? defaults.complexity) * multiplier;\n\n\tif (!field || !selection.selectionSet) {\n\t\treturn {\n\t\t\tdepth,\n\t\t\tbreadth,\n\t\t\tcomplexity,\n\t\t};\n\t}\n\n\tconst subSelection = complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\tgetNamedType(field.type),\n\t\tselection.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n\n\tdepth += subSelection.depth;\n\tbreadth += subSelection.breadth;\n\tcomplexity += subSelection.complexity * Math.max(multiplier, 1);\n\n\treturn {\n\t\tdepth,\n\t\tbreadth,\n\t\tcomplexity,\n\t};\n}\n","import { type GetComplexityError, getDefaultComplexityError } from './complexity-errors.ts';\nimport type { GetComplexityLimit } from './complexity-limits.ts';\n\n/**\n * Configuration options for the complexity extension.\n */\nexport interface ComplexityExtensionOptions<Context> {\n\t/** Static limits or function to determine limits based on context */\n\tlimit?: GetComplexityLimit<Context>;\n\t/**\n\t * Base complexity score for fields\n\t * @defaultValue 1\n\t */\n\tdefaultComplexity?: number;\n\t/**\n\t * Multiplier applied to list fields\n\t * @defaultValue 10\n\t */\n\tdefaultListMultiplier?: number;\n\t/** Custom error message generator */\n\tcomplexityError?: GetComplexityError;\n}\n\nexport const defaultLimits = {\n\tdepth: 10,\n\tbreadth: 50,\n\tcomplexity: 1000,\n};\n\nexport type NormalizedOptions = Required<ComplexityExtensionOptions<unknown>>;\n\nexport function normalizeOptions(options: ComplexityExtensionOptions<unknown>): NormalizedOptions {\n\treturn {\n\t\tlimit: options.limit ?? defaultLimits,\n\t\tdefaultComplexity: options.defaultComplexity ?? 1,\n\t\tdefaultListMultiplier: options.defaultListMultiplier ?? 10,\n\t\tcomplexityError: options.complexityError ?? getDefaultComplexityError,\n\t};\n}\n","import { createContextStore } from '@baeta/core';\nimport type { ComplexityLimit } from './complexity-limits.ts';\n\nexport interface ComplexityStore {\n\tlimits: Required<ComplexityLimit>;\n\tcacheComplexity: (fn: () => Required<ComplexityLimit>) => Required<ComplexityLimit>;\n}\n\nexport const complexityStoreKey = Symbol('complexity-extension');\n\nexport const [getComplexityStore, setComplexityStoreLoader] =\n\tcreateContextStore<ComplexityStore>(complexityStoreKey);\n","import type { ComplexityLimit } from './complexity-limits.ts';\nimport { setComplexityStoreLoader } from './store.ts';\n\nexport function loadComplexityStore<T>(\n\tctx: T,\n\tgetLimits:\n\t\t| ComplexityLimit\n\t\t| ((ctx: T) => ComplexityLimit | PromiseLike<ComplexityLimit>)\n\t\t| undefined,\n\tdefaultLimits: Required<ComplexityLimit>,\n) {\n\tsetComplexityStoreLoader(ctx, async () => {\n\t\tconst limits = typeof getLimits === 'function' ? await getLimits(ctx) : getLimits;\n\n\t\tlet cache: Required<ComplexityLimit> | undefined;\n\n\t\tconst cacheComplexity = (fn: () => Required<ComplexityLimit>) => {\n\t\t\tif (cache) {\n\t\t\t\treturn cache;\n\t\t\t}\n\n\t\t\tcache = fn();\n\t\t\treturn cache;\n\t\t};\n\n\t\treturn {\n\t\t\tlimits: {\n\t\t\t\tdepth: limits?.depth ?? defaultLimits.depth,\n\t\t\t\tbreadth: limits?.breadth ?? defaultLimits.breadth,\n\t\t\t\tcomplexity: limits?.complexity ?? defaultLimits.complexity,\n\t\t\t},\n\t\t\tcacheComplexity,\n\t\t};\n\t});\n}\n","import type { Middleware } from '@baeta/core';\nimport type { GraphQLResolveInfo } from 'graphql';\nimport { calculateComplexity } from './complexity-calculator.ts';\nimport { ComplexityErrorKind } from './complexity-errors.ts';\nimport { type ComplexityExtensionOptions, defaultLimits } from './complexity-options.ts';\nimport type { FieldSettingsMap } from './field-settings.ts';\nimport { getComplexityStore } from './store.ts';\nimport { loadComplexityStore } from './store-loader.ts';\n\nexport function createComplexityMiddleware<Result, Root, Context, Args, Info>(\n\toptions: Required<ComplexityExtensionOptions<Context>>,\n\tfieldSettingsMap: FieldSettingsMap,\n): Middleware<Result, Root, Context, Args, Info> {\n\treturn async (next, params) => {\n\t\tloadComplexityStore(params.ctx, options.limit, defaultLimits);\n\n\t\tconst store = await getComplexityStore(params.ctx);\n\n\t\tconst limits = store.limits;\n\n\t\tconst results = store.cacheComplexity(() => {\n\t\t\treturn calculateComplexity(params.ctx, params.info as GraphQLResolveInfo, fieldSettingsMap, {\n\t\t\t\tcomplexity: options.defaultComplexity,\n\t\t\t\tmultiplier: options.defaultListMultiplier,\n\t\t\t});\n\t\t});\n\n\t\tif (results.complexity > limits.complexity) {\n\t\t\tthrow options.complexityError(\n\t\t\t\tComplexityErrorKind.Complexity,\n\t\t\t\tlimits.complexity,\n\t\t\t\tresults.complexity,\n\t\t\t);\n\t\t}\n\n\t\tif (results.depth > limits.depth) {\n\t\t\tthrow options.complexityError(ComplexityErrorKind.Depth, limits.depth, results.depth);\n\t\t}\n\n\t\tif (results.breadth > limits.breadth) {\n\t\t\tthrow options.complexityError(ComplexityErrorKind.Breadth, limits.breadth, results.breadth);\n\t\t}\n\n\t\treturn next();\n\t};\n}\n","import {\n\tExtension,\n\ttype FieldBuilder,\n\ttype ModuleCompiler,\n\ttype SubscriptionBuilder,\n\ttype TypeBuilder,\n} from '@baeta/core/sdk';\nimport { createComplexityMiddleware } from './complexity-middleware.ts';\nimport { type ComplexityExtensionOptions, normalizeOptions } from './complexity-options.ts';\nimport {\n\ttype FieldSettingsMap,\n\ttype GetFieldSettings,\n\tregisterFieldSettingsSetter,\n} from './field-settings.ts';\n\ninterface ComplexityState {\n\tfieldSettings: GetFieldSettings<unknown, unknown>;\n}\n\ndeclare global {\n\texport namespace BaetaExtensions {\n\t\texport interface Extensions {\n\t\t\tcomplexityExtension: ComplexityExtension<unknown>;\n\t\t}\n\t}\n}\n\nexport class ComplexityExtension<Ctx> extends Extension<ComplexityState> {\n\treadonly stateKey = Symbol('complexity-settings');\n\tprivate readonly options: Required<ComplexityExtensionOptions<unknown>>;\n\n\tconstructor(options: ComplexityExtensionOptions<Ctx> = {}) {\n\t\tsuper();\n\t\tthis.options = normalizeOptions(options as ComplexityExtensionOptions<unknown>);\n\t}\n\n\tgetTypeExtensions = <Source, Context, Info>(\n\t\tbuilder: TypeBuilder<Source, Context, Info>,\n\t): BaetaExtensions.TypeExtensions<Source, Context, Info, TypeBuilder<Source, Context, Info>> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t};\n\n\tgetFieldExtensions = <Result, Source, Context, Args, Info>(\n\t\tbuilder: FieldBuilder<Result, Source, Context, Args, Info>,\n\t): BaetaExtensions.FieldExtensions<\n\t\tResult,\n\t\tSource,\n\t\tContext,\n\t\tArgs,\n\t\tInfo,\n\t\tFieldBuilder<Result, Source, Context, Args, Info>\n\t> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t};\n\n\tgetSubscriptionExtensions = <Result, Source, Context, Args, Info>(\n\t\tbuilder: SubscriptionBuilder<Result, Source, Context, Args, Info>,\n\t): BaetaExtensions.SubscriptionExtensions<\n\t\tResult,\n\t\tSource,\n\t\tContext,\n\t\tArgs,\n\t\tInfo,\n\t\tSubscriptionBuilder<Result, Source, Context, Args, Info>\n\t> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t};\n\n\tmutate(compilers: ModuleCompiler[]): void {\n\t\tconst fieldSettingsMap: FieldSettingsMap = new Map();\n\n\t\tfor (const typeCompiler of this.iterateTypes(compilers)) {\n\t\t\tconst typeState = this.getState(typeCompiler);\n\n\t\t\tif (typeState) {\n\t\t\t\tregisterFieldSettingsSetter(\n\t\t\t\t\ttypeCompiler.type,\n\t\t\t\t\t'*',\n\t\t\t\t\ttypeState.fieldSettings,\n\t\t\t\t\tfieldSettingsMap,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfor (const fieldCompiler of typeCompiler.fields) {\n\t\t\t\tconst fieldState = this.getState(fieldCompiler);\n\t\t\t\tif (!fieldState) continue;\n\n\t\t\t\tregisterFieldSettingsSetter(\n\t\t\t\t\ttypeCompiler.type,\n\t\t\t\t\tfieldCompiler.field,\n\t\t\t\t\tfieldState.fieldSettings,\n\t\t\t\t\tfieldSettingsMap,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst middleware = createComplexityMiddleware<any, unknown, unknown, unknown, unknown>(\n\t\t\tthis.options,\n\t\t\tfieldSettingsMap,\n\t\t);\n\n\t\tfor (const typeCompiler of this.iterateTypes(compilers)) {\n\t\t\tif (!['Query', 'Mutation', 'Subscription'].includes(typeCompiler.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const fieldCompiler of typeCompiler.fields) {\n\t\t\t\tfieldCompiler.addInitialMiddleware(middleware);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected *iterateTypes(compilers: ModuleCompiler[]) {\n\t\tfor (const compiler of compilers) {\n\t\t\tfor (const typeCompiler of compiler.types) {\n\t\t\t\tyield typeCompiler;\n\t\t\t}\n\t\t}\n\t}\n}\n","import './lib/global-types.ts';\n\nimport { ComplexityExtension } from './lib/complexity-extension.ts';\nimport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\n\nexport {\n\tComplexityError,\n\tComplexityErrorCode,\n\tComplexityErrorKind,\n\ttype GetComplexityError,\n} from './lib/complexity-errors.ts';\nexport type { ComplexityLimit, GetComplexityLimit } from './lib/complexity-limits.ts';\nexport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\nexport type {\n\tFieldSettings,\n\tGetFieldSettings,\n\tGetFieldSettingsArgs,\n} from './lib/field-settings.ts';\n\n/**\n * Creates a complexity analysis extension for GraphQL queries.\n *\n * @param options - Configuration options for complexity analysis\n * @returns Extension factory function\n *\n * @example\n * ```typescript\n * const complexity = complexityExtension<Context>({\n * defaultComplexity: 1,\n * defaultListMultiplier: 10,\n * limit: {\n * depth: 5,\n * breadth: 10,\n * complexity: 100\n * }\n * });\n * ```\n */\nexport function complexityExtension<Ctx>(options?: ComplexityExtensionOptions<Ctx>) {\n\treturn new ComplexityExtension(options);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../utils/graphlq.ts","../utils/string.ts","../lib/complexity-errors.ts","../lib/field-settings.ts","../lib/complexity-calculator.ts","../lib/complexity-options.ts","../lib/store.ts","../lib/store-loader.ts","../lib/complexity-middleware.ts","../lib/complexity-extension.ts","../index.ts"],"sourcesContent":["import { GraphQLList, GraphQLNonNull, type GraphQLOutputType } from 'graphql';\n\nexport function isListOrNullableList(type: GraphQLOutputType): boolean {\n\tif (type instanceof GraphQLList) {\n\t\treturn true;\n\t}\n\n\tif (type instanceof GraphQLNonNull) {\n\t\treturn isListOrNullableList(type.ofType);\n\t}\n\n\treturn false;\n}\n","export function capitalize(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { GraphQLError, type GraphQLErrorOptions } from 'graphql';\n\n/** Complexity error code */\nexport const ComplexityErrorCode = 'COMPLEXITY_ERROR';\n\n/**\n * Thrown when a query exceeds the complexity limits.\n */\nexport class ComplexityError extends GraphQLError {\n\tconstructor(\n\t\tmessage = \"Complexity limit exceeded! Please reduce the query's complexity.\",\n\t\toptions?: GraphQLErrorOptions,\n\t) {\n\t\tsuper(message, {\n\t\t\t...options,\n\t\t\textensions: {\n\t\t\t\tcode: ComplexityErrorCode,\n\t\t\t\t...options?.extensions,\n\t\t\t},\n\t\t});\n\t}\n}\n\n/**\n * Types of complexity validation errors that can occur during query analysis.\n */\nexport const ComplexityErrorKind = {\n\t/** Query exceeds maximum allowed depth */\n\tDepth: 'DepthExceeded',\n\t/** Query exceeds maximum allowed breadth (fields per level) */\n\tBreadth: 'BreadthExceeded',\n\t/** Query exceeds total complexity score limit */\n\tComplexity: 'ComplexityExceeded',\n};\n\ntype ComplexityErrorKind = (typeof ComplexityErrorKind)[keyof typeof ComplexityErrorKind];\n\n/**\n * Function type for creating custom complexity error messages.\n *\n * @param kind - The type of complexity limit that was exceeded\n * @param limits - The maximum allowed value\n * @param results - The actual value that exceeded the limit\n * @returns A GraphQL error with a custom message\n */\nexport type GetComplexityError = (\n\tkind: ComplexityErrorKind,\n\tlimits: number,\n\tresults: number,\n) => GraphQLError;\n\nexport function getDefaultComplexityError(\n\tkind: ComplexityErrorKind,\n\tlimit: number,\n\tresult: number,\n): GraphQLError {\n\tif (kind === ComplexityErrorKind.Depth) {\n\t\treturn new ComplexityError(`Depth limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Depth,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tif (kind === ComplexityErrorKind.Breadth) {\n\t\treturn new ComplexityError(`Breadth limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Breadth,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tif (kind === ComplexityErrorKind.Complexity) {\n\t\treturn new ComplexityError(`Complexity limit of ${limit} exceeded, got: ${result}`, {\n\t\t\textensions: {\n\t\t\t\tkind: ComplexityErrorKind.Complexity,\n\t\t\t\tlimit,\n\t\t\t\tgot: result,\n\t\t\t},\n\t\t});\n\t}\n\n\tthrow new Error('Unknown complexity error kind');\n}\n","import {\n\ttype FieldNode,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\tgetArgumentValues,\n} from 'graphql';\n\nexport type FieldSettingsMap = Map<string, Map<string, GetFieldSettings<unknown, unknown>>>;\n\n/**\n * Configuration for field complexity calculation.\n */\nexport type FieldSettings = {\n\tcomplexity?: number;\n\tmultiplier?: number;\n};\n\n/**\n * Arguments passed to field settings functions.\n */\nexport type GetFieldSettingsArgs<Context, Args> = {\n\t/** Arguments passed to the GraphQL field */\n\targs: Args;\n\t/** Request context */\n\tctx: Context;\n};\n\n/**\n * Function to determine complexity settings for a field.\n * Returns either field settings or false to disable complexity calculation.\n *\n * @param params - Object containing field arguments and context\n * @returns Field settings object or false\n */\nexport type GetFieldSettings<Context, Args> = (\n\tparams: GetFieldSettingsArgs<Context, Args>,\n) => FieldSettings | false;\n\nexport function getFieldComplexitySettings<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tfield: GraphQLField<unknown, unknown>,\n\tselection: FieldNode,\n\tfieldName: string,\n\tfieldSettingsMap: FieldSettingsMap,\n) {\n\tconst args = getArgumentValues(field, selection, info.variableValues);\n\tconst customComplexity = fieldSettingsMap.get(type.name)?.get(fieldName);\n\n\tif (customComplexity) {\n\t\treturn customComplexity({ args, ctx });\n\t}\n\n\tconst wildCardComplexity = fieldSettingsMap.get(type.name)?.get('*');\n\n\tif (wildCardComplexity) {\n\t\treturn wildCardComplexity({ args, ctx });\n\t}\n}\n\nexport function registerFieldSettingsSetter<Context, Args>(\n\ttype: string,\n\tfield: string,\n\tfn: GetFieldSettings<Context, Args>,\n\tmap: FieldSettingsMap,\n) {\n\tif (!map.has(type)) {\n\t\tmap.set(type, new Map());\n\t}\n\tmap.get(type)?.set(field, fn as GetFieldSettings<unknown, unknown>);\n}\n","/**\n * Originally based on plugin-complexity of Pothos\n * Source: https://github.com/hayes/pothos/blob/main/packages/plugin-complexity/src/calculate-complexity.ts\n * Copyright (c) 2021 Michael Hayes\n * Adapted by Baeta developers\n */\nimport {\n\ttype FieldNode,\n\ttype FragmentDefinitionNode,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\tgetNamedType,\n\ttype InlineFragmentNode,\n\tisInterfaceType,\n\tisObjectType,\n\tisOutputType,\n\tKind,\n\ttype SelectionNode,\n\ttype SelectionSetNode,\n} from 'graphql';\nimport { isListOrNullableList } from '../utils/graphlq.ts';\nimport { capitalize } from '../utils/string.ts';\nimport { ComplexityError } from './complexity-errors.ts';\nimport { type FieldSettingsMap, getFieldComplexitySettings } from './field-settings.ts';\n\ninterface ComplexityDefaults {\n\tcomplexity: number;\n\tmultiplier: number;\n}\n\nexport function calculateComplexity<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst operationName = capitalize(info.operation.operation);\n\tconst operationType = info.schema.getType(operationName);\n\n\tif (!operationType || !isOutputType(operationType)) {\n\t\tthrow new ComplexityError(`Unsupported operation ${operationName}`);\n\t}\n\n\treturn complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\toperationType,\n\t\tinfo.operation.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n}\n\nfunction complexityFromSelectionSet<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselectionSet: SelectionSetNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst result = {\n\t\tdepth: 0,\n\t\tbreadth: 0,\n\t\tcomplexity: 0,\n\t};\n\n\tfor (const selection of selectionSet.selections) {\n\t\tconst selectionResult = complexityFromSelection(\n\t\t\tctx,\n\t\t\tinfo,\n\t\t\ttype,\n\t\t\tselection,\n\t\t\tfieldSettingsMap,\n\t\t\tdefaults,\n\t\t);\n\t\tresult.complexity += selectionResult.complexity;\n\t\tresult.breadth += selectionResult.breadth;\n\t\tresult.depth = Math.max(result.depth, selectionResult.depth);\n\t}\n\n\treturn result;\n}\n\nfunction complexityFromSelection<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselection: SelectionNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tif (selection.kind === Kind.FIELD) {\n\t\treturn complexityFromField(ctx, info, type, selection, fieldSettingsMap, defaults);\n\t}\n\n\tif (selection.kind === Kind.FRAGMENT_SPREAD) {\n\t\tconst fragment = info.fragments[selection.name.value];\n\n\t\tif (!fragment) {\n\t\t\tthrow new ComplexityError(`Fragment ${selection.name.value} not found`);\n\t\t}\n\n\t\treturn complexityFromFragment(ctx, info, type, fragment, fieldSettingsMap, defaults);\n\t}\n\n\treturn complexityFromFragment(ctx, info, type, selection, fieldSettingsMap, defaults);\n}\n\nfunction complexityFromFragment<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tfragment: FragmentDefinitionNode | InlineFragmentNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst fragmentType = fragment.typeCondition\n\t\t? info.schema.getType(fragment.typeCondition.name.value)\n\t\t: type;\n\n\tif (!isOutputType(fragmentType)) {\n\t\tthrow new ComplexityError(`Unsupported fragment type ${fragmentType}`);\n\t}\n\n\tif (!fragmentType) {\n\t\tthrow new ComplexityError(`Fragment type ${fragmentType} not found`);\n\t}\n\n\treturn complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\tfragmentType,\n\t\tfragment.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n}\n\nfunction complexityFromField<Context>(\n\tctx: Context,\n\tinfo: GraphQLResolveInfo,\n\ttype: GraphQLNamedType,\n\tselection: FieldNode,\n\tfieldSettingsMap: FieldSettingsMap,\n\tdefaults: ComplexityDefaults,\n) {\n\tconst fieldName = selection.name.value;\n\n\tconst field =\n\t\tisObjectType(type) || isInterfaceType(type) ? type.getFields()[fieldName] : undefined;\n\n\tif (!field && !fieldName.startsWith('__')) {\n\t\tthrow new ComplexityError(`Field ${fieldName} not found on type ${type.name}`);\n\t}\n\n\tif (!field) {\n\t\treturn {\n\t\t\tdepth: 1,\n\t\t\tbreadth: 1,\n\t\t\tcomplexity: 1,\n\t\t};\n\t}\n\n\tconst fieldComplexitySettings = getFieldComplexitySettings(\n\t\tctx,\n\t\tinfo,\n\t\ttype,\n\t\tfield,\n\t\tselection,\n\t\tfieldName,\n\t\tfieldSettingsMap,\n\t);\n\n\tif (fieldComplexitySettings === false) {\n\t\treturn {\n\t\t\tdepth: 0,\n\t\t\tbreadth: 0,\n\t\t\tcomplexity: 0,\n\t\t};\n\t}\n\n\tlet depth = 1;\n\tlet breadth = 1;\n\tlet complexity = 0;\n\n\tconst listMultiplier = fieldComplexitySettings?.multiplier ?? defaults.multiplier;\n\tconst multiplier = field && isListOrNullableList(field.type) ? listMultiplier : 1;\n\n\tcomplexity += (fieldComplexitySettings?.complexity ?? defaults.complexity) * multiplier;\n\n\tif (!field || !selection.selectionSet) {\n\t\treturn {\n\t\t\tdepth,\n\t\t\tbreadth,\n\t\t\tcomplexity,\n\t\t};\n\t}\n\n\tconst subSelection = complexityFromSelectionSet(\n\t\tctx,\n\t\tinfo,\n\t\tgetNamedType(field.type),\n\t\tselection.selectionSet,\n\t\tfieldSettingsMap,\n\t\tdefaults,\n\t);\n\n\tdepth += subSelection.depth;\n\tbreadth += subSelection.breadth;\n\tcomplexity += subSelection.complexity * Math.max(multiplier, 1);\n\n\treturn {\n\t\tdepth,\n\t\tbreadth,\n\t\tcomplexity,\n\t};\n}\n","import { type GetComplexityError, getDefaultComplexityError } from './complexity-errors.ts';\nimport type { GetComplexityLimit } from './complexity-limits.ts';\n\n/**\n * Configuration options for the complexity extension.\n */\nexport interface ComplexityExtensionOptions<Context> {\n\t/** Static limits or function to determine limits based on context */\n\tlimit?: GetComplexityLimit<Context>;\n\t/**\n\t * Base complexity score for fields\n\t * @defaultValue 1\n\t */\n\tdefaultComplexity?: number;\n\t/**\n\t * Multiplier applied to list fields\n\t * @defaultValue 10\n\t */\n\tdefaultListMultiplier?: number;\n\t/** Custom error message generator */\n\tcomplexityError?: GetComplexityError;\n}\n\nexport const defaultLimits = {\n\tdepth: 10,\n\tbreadth: 50,\n\tcomplexity: 1000,\n};\n\nexport type NormalizedOptions = Required<ComplexityExtensionOptions<unknown>>;\n\nexport function normalizeOptions(options: ComplexityExtensionOptions<unknown>): NormalizedOptions {\n\treturn {\n\t\tlimit: options.limit ?? defaultLimits,\n\t\tdefaultComplexity: options.defaultComplexity ?? 1,\n\t\tdefaultListMultiplier: options.defaultListMultiplier ?? 10,\n\t\tcomplexityError: options.complexityError ?? getDefaultComplexityError,\n\t};\n}\n","import { createContextStore } from '@baeta/core';\nimport type { ComplexityLimit } from './complexity-limits.ts';\n\nexport interface ComplexityStore {\n\tlimits: Required<ComplexityLimit>;\n\tcacheComplexity: (fn: () => Required<ComplexityLimit>) => Required<ComplexityLimit>;\n}\n\nexport const complexityStoreKey = Symbol('complexity-extension');\n\nexport const [getComplexityStore, setComplexityStoreLoader] =\n\tcreateContextStore<ComplexityStore>(complexityStoreKey);\n","import type { ComplexityLimit } from './complexity-limits.ts';\nimport { setComplexityStoreLoader } from './store.ts';\n\nexport function loadComplexityStore<T>(\n\tctx: T,\n\tgetLimits:\n\t\t| ComplexityLimit\n\t\t| ((ctx: T) => ComplexityLimit | PromiseLike<ComplexityLimit>)\n\t\t| undefined,\n\tdefaultLimits: Required<ComplexityLimit>,\n) {\n\tsetComplexityStoreLoader(ctx, async () => {\n\t\tconst limits = typeof getLimits === 'function' ? await getLimits(ctx) : getLimits;\n\n\t\tlet cache: Required<ComplexityLimit> | undefined;\n\n\t\tconst cacheComplexity = (fn: () => Required<ComplexityLimit>) => {\n\t\t\tif (cache) {\n\t\t\t\treturn cache;\n\t\t\t}\n\n\t\t\tcache = fn();\n\t\t\treturn cache;\n\t\t};\n\n\t\treturn {\n\t\t\tlimits: {\n\t\t\t\tdepth: limits?.depth ?? defaultLimits.depth,\n\t\t\t\tbreadth: limits?.breadth ?? defaultLimits.breadth,\n\t\t\t\tcomplexity: limits?.complexity ?? defaultLimits.complexity,\n\t\t\t},\n\t\t\tcacheComplexity,\n\t\t};\n\t});\n}\n","import type { Middleware } from '@baeta/core';\nimport type { GraphQLResolveInfo } from 'graphql';\nimport { calculateComplexity } from './complexity-calculator.ts';\nimport { ComplexityErrorKind } from './complexity-errors.ts';\nimport { type ComplexityExtensionOptions, defaultLimits } from './complexity-options.ts';\nimport type { FieldSettingsMap } from './field-settings.ts';\nimport { getComplexityStore } from './store.ts';\nimport { loadComplexityStore } from './store-loader.ts';\n\nexport function createComplexityMiddleware<Result, Root, Context, Args, Info>(\n\toptions: Required<ComplexityExtensionOptions<Context>>,\n\tfieldSettingsMap: FieldSettingsMap,\n): Middleware<Result, Root, Context, Args, Info> {\n\treturn async (next, params) => {\n\t\tloadComplexityStore(params.ctx, options.limit, defaultLimits);\n\n\t\tconst store = await getComplexityStore(params.ctx);\n\n\t\tconst limits = store.limits;\n\n\t\tconst results = store.cacheComplexity(() => {\n\t\t\treturn calculateComplexity(params.ctx, params.info as GraphQLResolveInfo, fieldSettingsMap, {\n\t\t\t\tcomplexity: options.defaultComplexity,\n\t\t\t\tmultiplier: options.defaultListMultiplier,\n\t\t\t});\n\t\t});\n\n\t\tif (results.complexity > limits.complexity) {\n\t\t\tthrow options.complexityError(\n\t\t\t\tComplexityErrorKind.Complexity,\n\t\t\t\tlimits.complexity,\n\t\t\t\tresults.complexity,\n\t\t\t);\n\t\t}\n\n\t\tif (results.depth > limits.depth) {\n\t\t\tthrow options.complexityError(ComplexityErrorKind.Depth, limits.depth, results.depth);\n\t\t}\n\n\t\tif (results.breadth > limits.breadth) {\n\t\t\tthrow options.complexityError(ComplexityErrorKind.Breadth, limits.breadth, results.breadth);\n\t\t}\n\n\t\treturn next();\n\t};\n}\n","import {\n\tExtension,\n\ttype FieldBuilder,\n\ttype ModuleCompiler,\n\ttype SubscriptionBuilder,\n\ttype TypeBuilder,\n} from '@baeta/core/sdk';\nimport { createComplexityMiddleware } from './complexity-middleware.ts';\nimport { type ComplexityExtensionOptions, normalizeOptions } from './complexity-options.ts';\nimport {\n\ttype FieldSettingsMap,\n\ttype GetFieldSettings,\n\tregisterFieldSettingsSetter,\n} from './field-settings.ts';\n\ninterface ComplexityState {\n\tfieldSettings: GetFieldSettings<unknown, unknown>;\n}\n\ndeclare global {\n\texport namespace BaetaExtensions {\n\t\texport interface Extensions {\n\t\t\tcomplexityExtension: ComplexityExtension<unknown>;\n\t\t}\n\t}\n}\n\nexport class ComplexityExtension<Ctx> extends Extension<ComplexityState> {\n\treadonly stateKey = Symbol('complexity-settings');\n\tprivate readonly options: Required<ComplexityExtensionOptions<unknown>>;\n\n\tconstructor(options: ComplexityExtensionOptions<Ctx> = {}) {\n\t\tsuper();\n\t\tthis.options = normalizeOptions(options as ComplexityExtensionOptions<unknown>);\n\t}\n\n\tgetTypeExtensions<Source, Context, Info>(\n\t\tbuilder: TypeBuilder<Source, Context, Info>,\n\t): BaetaExtensions.TypeExtensions<Source, Context, Info> {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t}\n\n\tgetFieldExtensions<Result, Source, Context, Args, Info>(\n\t\tbuilder: FieldBuilder<Result, Source, Context, Args, Info>,\n\t): BaetaExtensions.FieldExtensions<Result, Source, Context, Args, Info> {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t}\n\n\tgetSubscriptionExtensions<Result, Source, Context, Args, Info>(\n\t\tbuilder: SubscriptionBuilder<Result, Source, Context, Args, Info>,\n\t): BaetaExtensions.SubscriptionExtensions<Result, Source, Context, Args, Info> {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tconst editable = builder.edit();\n\t\t\t\tthis.setState(editable, {\n\t\t\t\t\tfieldSettings: fn as GetFieldSettings<unknown, unknown>,\n\t\t\t\t});\n\t\t\t\treturn editable.commitToMethods();\n\t\t\t},\n\t\t};\n\t}\n\n\tmutate(compilers: ModuleCompiler[]): void {\n\t\tconst fieldSettingsMap: FieldSettingsMap = new Map();\n\n\t\tfor (const typeCompiler of this.iterateTypes(compilers)) {\n\t\t\tconst typeState = this.getState(typeCompiler);\n\n\t\t\tif (typeState) {\n\t\t\t\tregisterFieldSettingsSetter(\n\t\t\t\t\ttypeCompiler.type,\n\t\t\t\t\t'*',\n\t\t\t\t\ttypeState.fieldSettings,\n\t\t\t\t\tfieldSettingsMap,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfor (const fieldCompiler of typeCompiler.fields) {\n\t\t\t\tconst fieldState = this.getState(fieldCompiler);\n\t\t\t\tif (!fieldState) continue;\n\n\t\t\t\tregisterFieldSettingsSetter(\n\t\t\t\t\ttypeCompiler.type,\n\t\t\t\t\tfieldCompiler.field,\n\t\t\t\t\tfieldState.fieldSettings,\n\t\t\t\t\tfieldSettingsMap,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst middleware = createComplexityMiddleware<any, unknown, unknown, unknown, unknown>(\n\t\t\tthis.options,\n\t\t\tfieldSettingsMap,\n\t\t);\n\n\t\tfor (const typeCompiler of this.iterateTypes(compilers)) {\n\t\t\tif (!['Query', 'Mutation', 'Subscription'].includes(typeCompiler.type)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const fieldCompiler of typeCompiler.fields) {\n\t\t\t\tfieldCompiler.addInitialMiddleware(middleware);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected *iterateTypes(compilers: ModuleCompiler[]) {\n\t\tfor (const compiler of compilers) {\n\t\t\tfor (const typeCompiler of compiler.types) {\n\t\t\t\tyield typeCompiler;\n\t\t\t}\n\t\t}\n\t}\n}\n","import './lib/global-types.ts';\n\nimport { ComplexityExtension } from './lib/complexity-extension.ts';\nimport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\n\nexport {\n\tComplexityError,\n\tComplexityErrorCode,\n\tComplexityErrorKind,\n\ttype GetComplexityError,\n} from './lib/complexity-errors.ts';\nexport type { ComplexityLimit, GetComplexityLimit } from './lib/complexity-limits.ts';\nexport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\nexport type {\n\tFieldSettings,\n\tGetFieldSettings,\n\tGetFieldSettingsArgs,\n} from './lib/field-settings.ts';\n\n/**\n * Creates a complexity analysis extension for GraphQL queries.\n *\n * @param options - Configuration options for complexity analysis\n * @returns Extension factory function\n *\n * @example\n * ```typescript\n * const complexity = complexityExtension<Context>({\n * defaultComplexity: 1,\n * defaultListMultiplier: 10,\n * limit: {\n * depth: 5,\n * breadth: 10,\n * complexity: 100\n * }\n * });\n * ```\n */\nexport function complexityExtension<Ctx>(options?: ComplexityExtensionOptions<Ctx>) {\n\treturn new ComplexityExtension(options);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baeta/extension-complexity",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.13",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"baeta",
|
|
6
6
|
"graphql",
|
|
@@ -38,27 +38,27 @@
|
|
|
38
38
|
],
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "builder build",
|
|
41
|
+
"check:deps": "builder check-deps",
|
|
41
42
|
"prepack": "builder prepare",
|
|
42
|
-
"postpack": "builder prepare --
|
|
43
|
+
"postpack": "builder prepare --restore",
|
|
43
44
|
"test": "builder test",
|
|
44
|
-
"test:circular": "builder test-circular",
|
|
45
45
|
"types": "tsc --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"ava": {
|
|
48
|
-
"extensions":
|
|
49
|
-
"ts"
|
|
50
|
-
|
|
48
|
+
"extensions": [
|
|
49
|
+
"ts"
|
|
50
|
+
]
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@baeta/builder": "^0.0.0",
|
|
54
|
-
"@baeta/core": "^2.0.0-next.
|
|
54
|
+
"@baeta/core": "^2.0.0-next.13",
|
|
55
55
|
"@baeta/testing": "^0.0.0",
|
|
56
56
|
"@baeta/tsconfig": "^0.0.0",
|
|
57
|
-
"graphql": "^16.
|
|
58
|
-
"typescript": "^
|
|
57
|
+
"graphql": "^16.6.0",
|
|
58
|
+
"typescript": "^6.0.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@baeta/core": "^2.0.0-next.
|
|
61
|
+
"@baeta/core": "^2.0.0-next.13",
|
|
62
62
|
"graphql": "^16.6.0"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|