@baeta/extension-complexity 2.0.0-next.10 → 2.0.0-next.12
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 +12 -26
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @baeta/extension-complexity
|
|
2
2
|
|
|
3
|
+
## 2.0.0-next.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @baeta/core@2.0.0-next.12
|
|
9
|
+
|
|
10
|
+
## 2.0.0-next.11
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies []:
|
|
15
|
+
- @baeta/core@2.0.0-next.11
|
|
16
|
+
|
|
3
17
|
## 2.0.0-next.10
|
|
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 */
|
|
@@ -59,7 +56,6 @@ function getDefaultComplexityError(kind, limit, result) {
|
|
|
59
56
|
} });
|
|
60
57
|
throw new Error("Unknown complexity error kind");
|
|
61
58
|
}
|
|
62
|
-
|
|
63
59
|
//#endregion
|
|
64
60
|
//#region lib/field-settings.ts
|
|
65
61
|
function getFieldComplexitySettings(ctx, info, type, field, selection, fieldName, fieldSettingsMap) {
|
|
@@ -79,7 +75,6 @@ function registerFieldSettingsSetter(type, field, fn, map) {
|
|
|
79
75
|
if (!map.has(type)) map.set(type, /* @__PURE__ */ new Map());
|
|
80
76
|
map.get(type)?.set(field, fn);
|
|
81
77
|
}
|
|
82
|
-
|
|
83
78
|
//#endregion
|
|
84
79
|
//#region lib/complexity-calculator.ts
|
|
85
80
|
/**
|
|
@@ -159,7 +154,6 @@ function complexityFromField(ctx, info, type, selection, fieldSettingsMap, defau
|
|
|
159
154
|
complexity
|
|
160
155
|
};
|
|
161
156
|
}
|
|
162
|
-
|
|
163
157
|
//#endregion
|
|
164
158
|
//#region lib/complexity-options.ts
|
|
165
159
|
const defaultLimits = {
|
|
@@ -175,15 +169,10 @@ function normalizeOptions(options) {
|
|
|
175
169
|
complexityError: options.complexityError ?? getDefaultComplexityError
|
|
176
170
|
};
|
|
177
171
|
}
|
|
178
|
-
|
|
179
|
-
//#endregion
|
|
180
|
-
//#region lib/store.ts
|
|
181
|
-
const complexityStoreKey = Symbol("complexity-extension");
|
|
182
|
-
const [getComplexityStore, setComplexityStoreLoader] = createContextStore(complexityStoreKey);
|
|
183
|
-
|
|
172
|
+
const [getComplexityStore, setComplexityStoreLoader] = createContextStore(Symbol("complexity-extension"));
|
|
184
173
|
//#endregion
|
|
185
174
|
//#region lib/store-loader.ts
|
|
186
|
-
function loadComplexityStore(ctx, getLimits, defaultLimits
|
|
175
|
+
function loadComplexityStore(ctx, getLimits, defaultLimits) {
|
|
187
176
|
setComplexityStoreLoader(ctx, async () => {
|
|
188
177
|
const limits = typeof getLimits === "function" ? await getLimits(ctx) : getLimits;
|
|
189
178
|
let cache;
|
|
@@ -194,15 +183,14 @@ function loadComplexityStore(ctx, getLimits, defaultLimits$1) {
|
|
|
194
183
|
};
|
|
195
184
|
return {
|
|
196
185
|
limits: {
|
|
197
|
-
depth: limits?.depth ?? defaultLimits
|
|
198
|
-
breadth: limits?.breadth ?? defaultLimits
|
|
199
|
-
complexity: limits?.complexity ?? defaultLimits
|
|
186
|
+
depth: limits?.depth ?? defaultLimits.depth,
|
|
187
|
+
breadth: limits?.breadth ?? defaultLimits.breadth,
|
|
188
|
+
complexity: limits?.complexity ?? defaultLimits.complexity
|
|
200
189
|
},
|
|
201
190
|
cacheComplexity
|
|
202
191
|
};
|
|
203
192
|
});
|
|
204
193
|
}
|
|
205
|
-
|
|
206
194
|
//#endregion
|
|
207
195
|
//#region lib/complexity-middleware.ts
|
|
208
196
|
function createComplexityMiddleware(options, fieldSettingsMap) {
|
|
@@ -222,7 +210,6 @@ function createComplexityMiddleware(options, fieldSettingsMap) {
|
|
|
222
210
|
return next();
|
|
223
211
|
};
|
|
224
212
|
}
|
|
225
|
-
|
|
226
213
|
//#endregion
|
|
227
214
|
//#region lib/complexity-extension.ts
|
|
228
215
|
var ComplexityExtension = class extends Extension {
|
|
@@ -232,27 +219,27 @@ var ComplexityExtension = class extends Extension {
|
|
|
232
219
|
super();
|
|
233
220
|
this.options = normalizeOptions(options);
|
|
234
221
|
}
|
|
235
|
-
getTypeExtensions
|
|
222
|
+
getTypeExtensions(builder) {
|
|
236
223
|
return { $complexity: (fn) => {
|
|
237
224
|
const editable = builder.edit();
|
|
238
225
|
this.setState(editable, { fieldSettings: fn });
|
|
239
226
|
return editable.commitToMethods();
|
|
240
227
|
} };
|
|
241
|
-
}
|
|
242
|
-
getFieldExtensions
|
|
228
|
+
}
|
|
229
|
+
getFieldExtensions(builder) {
|
|
243
230
|
return { $complexity: (fn) => {
|
|
244
231
|
const editable = builder.edit();
|
|
245
232
|
this.setState(editable, { fieldSettings: fn });
|
|
246
233
|
return editable.commitToMethods();
|
|
247
234
|
} };
|
|
248
|
-
}
|
|
249
|
-
getSubscriptionExtensions
|
|
235
|
+
}
|
|
236
|
+
getSubscriptionExtensions(builder) {
|
|
250
237
|
return { $complexity: (fn) => {
|
|
251
238
|
const editable = builder.edit();
|
|
252
239
|
this.setState(editable, { fieldSettings: fn });
|
|
253
240
|
return editable.commitToMethods();
|
|
254
241
|
} };
|
|
255
|
-
}
|
|
242
|
+
}
|
|
256
243
|
mutate(compilers) {
|
|
257
244
|
const fieldSettingsMap = /* @__PURE__ */ new Map();
|
|
258
245
|
for (const typeCompiler of this.iterateTypes(compilers)) {
|
|
@@ -278,7 +265,6 @@ var ComplexityExtension = class extends Extension {
|
|
|
278
265
|
for (const compiler of compilers) for (const typeCompiler of compiler.types) yield typeCompiler;
|
|
279
266
|
}
|
|
280
267
|
};
|
|
281
|
-
|
|
282
268
|
//#endregion
|
|
283
269
|
//#region index.ts
|
|
284
270
|
/**
|
|
@@ -303,7 +289,7 @@ var ComplexityExtension = class extends Extension {
|
|
|
303
289
|
function complexityExtension(options) {
|
|
304
290
|
return new ComplexityExtension(options);
|
|
305
291
|
}
|
|
306
|
-
|
|
307
292
|
//#endregion
|
|
308
293
|
export { ComplexityError, ComplexityErrorCode, ComplexityErrorKind, complexityExtension };
|
|
294
|
+
|
|
309
295
|
//# 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":";;;;AAEA,SAAgB,qBAAqB,MAAkC;AACtE,KAAI,gBAAgB,YACnB,QAAO;AAGR,KAAI,gBAAgB,eACnB,QAAO,qBAAqB,KAAK,OAAO;AAGzC,QAAO;;;;ACXR,SAAgB,WAAW,KAAa;AACvC,QAAO,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE;;;;;ACElD,MAAa,sBAAsB;;;;AAKnC,IAAa,kBAAb,cAAqC,aAAa;CACjD,YACC,UAAU,oEACV,SACC;AACD,QAAM,SAAS;GACd,GAAG;GACH,YAAY;IACX,MAAM;IACN,GAAG,SAAS;IACZ;GACD,CAAC;;;;;;AAOJ,MAAa,sBAAsB;CAElC,OAAO;CAEP,SAAS;CAET,YAAY;CACZ;AAkBD,SAAgB,0BACf,MACA,OACA,QACe;AACf,KAAI,SAAS,oBAAoB,MAChC,QAAO,IAAI,gBAAgB,kBAAkB,MAAM,kBAAkB,UAAU,EAC9E,YAAY;EACX,MAAM,oBAAoB;EAC1B;EACA,KAAK;EACL,EACD,CAAC;AAGH,KAAI,SAAS,oBAAoB,QAChC,QAAO,IAAI,gBAAgB,oBAAoB,MAAM,kBAAkB,UAAU,EAChF,YAAY;EACX,MAAM,oBAAoB;EAC1B;EACA,KAAK;EACL,EACD,CAAC;AAGH,KAAI,SAAS,oBAAoB,WAChC,QAAO,IAAI,gBAAgB,uBAAuB,MAAM,kBAAkB,UAAU,EACnF,YAAY;EACX,MAAM,oBAAoB;EAC1B;EACA,KAAK;EACL,EACD,CAAC;AAGH,OAAM,IAAI,MAAM,gCAAgC;;;;AC/CjD,SAAgB,2BACf,KACA,MACA,MACA,OACA,WACA,WACA,kBACC;CACD,MAAM,OAAO,kBAAkB,OAAO,WAAW,KAAK,eAAe;CACrE,MAAM,mBAAmB,iBAAiB,IAAI,KAAK,KAAK,EAAE,IAAI,UAAU;AAExE,KAAI,iBACH,QAAO,iBAAiB;EAAE;EAAM;EAAK,CAAC;CAGvC,MAAM,qBAAqB,iBAAiB,IAAI,KAAK,KAAK,EAAE,IAAI,IAAI;AAEpE,KAAI,mBACH,QAAO,mBAAmB;EAAE;EAAM;EAAK,CAAC;;AAI1C,SAAgB,4BACf,MACA,OACA,IACA,KACC;AACD,KAAI,CAAC,IAAI,IAAI,KAAK,CACjB,KAAI,IAAI,sBAAM,IAAI,KAAK,CAAC;AAEzB,KAAI,IAAI,KAAK,EAAE,IAAI,OAAO,GAAyC;;;;;;;;;;ACzCpE,SAAgB,oBACf,KACA,MACA,kBACA,UACC;CACD,MAAM,gBAAgB,WAAW,KAAK,UAAU,UAAU;CAC1D,MAAM,gBAAgB,KAAK,OAAO,QAAQ,cAAc;AAExD,KAAI,CAAC,iBAAiB,CAAC,aAAa,cAAc,CACjD,OAAM,IAAI,gBAAgB,yBAAyB,gBAAgB;AAGpE,QAAO,2BACN,KACA,MACA,eACA,KAAK,UAAU,cACf,kBACA,SACA;;AAGF,SAAS,2BACR,KACA,MACA,MACA,cACA,kBACA,UACC;CACD,MAAM,SAAS;EACd,OAAO;EACP,SAAS;EACT,YAAY;EACZ;AAED,MAAK,MAAM,aAAa,aAAa,YAAY;EAChD,MAAM,kBAAkB,wBACvB,KACA,MACA,MACA,WACA,kBACA,SACA;AACD,SAAO,cAAc,gBAAgB;AACrC,SAAO,WAAW,gBAAgB;AAClC,SAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,gBAAgB,MAAM;;AAG7D,QAAO;;AAGR,SAAS,wBACR,KACA,MACA,MACA,WACA,kBACA,UACC;AACD,KAAI,UAAU,SAAS,KAAK,MAC3B,QAAO,oBAAoB,KAAK,MAAM,MAAM,WAAW,kBAAkB,SAAS;AAGnF,KAAI,UAAU,SAAS,KAAK,iBAAiB;EAC5C,MAAM,WAAW,KAAK,UAAU,UAAU,KAAK;AAE/C,MAAI,CAAC,SACJ,OAAM,IAAI,gBAAgB,YAAY,UAAU,KAAK,MAAM,YAAY;AAGxE,SAAO,uBAAuB,KAAK,MAAM,MAAM,UAAU,kBAAkB,SAAS;;AAGrF,QAAO,uBAAuB,KAAK,MAAM,MAAM,WAAW,kBAAkB,SAAS;;AAGtF,SAAS,uBACR,KACA,MACA,MACA,UACA,kBACA,UACC;CACD,MAAM,eAAe,SAAS,gBAC3B,KAAK,OAAO,QAAQ,SAAS,cAAc,KAAK,MAAM,GACtD;AAEH,KAAI,CAAC,aAAa,aAAa,CAC9B,OAAM,IAAI,gBAAgB,6BAA6B,eAAe;AAGvE,KAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,iBAAiB,aAAa,YAAY;AAGrE,QAAO,2BACN,KACA,MACA,cACA,SAAS,cACT,kBACA,SACA;;AAGF,SAAS,oBACR,KACA,MACA,MACA,WACA,kBACA,UACC;CACD,MAAM,YAAY,UAAU,KAAK;CAEjC,MAAM,QACL,aAAa,KAAK,IAAI,gBAAgB,KAAK,GAAG,KAAK,WAAW,CAAC,aAAa,KAAA;AAE7E,KAAI,CAAC,SAAS,CAAC,UAAU,WAAW,KAAK,CACxC,OAAM,IAAI,gBAAgB,SAAS,UAAU,qBAAqB,KAAK,OAAO;AAG/E,KAAI,CAAC,MACJ,QAAO;EACN,OAAO;EACP,SAAS;EACT,YAAY;EACZ;CAGF,MAAM,0BAA0B,2BAC/B,KACA,MACA,MACA,OACA,WACA,WACA,iBACA;AAED,KAAI,4BAA4B,MAC/B,QAAO;EACN,OAAO;EACP,SAAS;EACT,YAAY;EACZ;CAGF,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,IAAI,aAAa;CAEjB,MAAM,iBAAiB,yBAAyB,cAAc,SAAS;CACvE,MAAM,aAAa,SAAS,qBAAqB,MAAM,KAAK,GAAG,iBAAiB;AAEhF,gBAAe,yBAAyB,cAAc,SAAS,cAAc;AAE7E,KAAI,CAAC,SAAS,CAAC,UAAU,aACxB,QAAO;EACN;EACA;EACA;EACA;CAGF,MAAM,eAAe,2BACpB,KACA,MACA,aAAa,MAAM,KAAK,EACxB,UAAU,cACV,kBACA,SACA;AAED,UAAS,aAAa;AACtB,YAAW,aAAa;AACxB,eAAc,aAAa,aAAa,KAAK,IAAI,YAAY,EAAE;AAE/D,QAAO;EACN;EACA;EACA;EACA;;;;ACjMF,MAAa,gBAAgB;CAC5B,OAAO;CACP,SAAS;CACT,YAAY;CACZ;AAID,SAAgB,iBAAiB,SAAiE;AACjG,QAAO;EACN,OAAO,QAAQ,SAAS;EACxB,mBAAmB,QAAQ,qBAAqB;EAChD,uBAAuB,QAAQ,yBAAyB;EACxD,iBAAiB,QAAQ,mBAAmB;EAC5C;;AC3BF,MAAa,CAAC,oBAAoB,4BACjC,mBAHiC,OAAO,uBAAuB,CAGR;;;ACRxD,SAAgB,oBACf,KACA,WAIA,eACC;AACD,0BAAyB,KAAK,YAAY;EACzC,MAAM,SAAS,OAAO,cAAc,aAAa,MAAM,UAAU,IAAI,GAAG;EAExE,IAAI;EAEJ,MAAM,mBAAmB,OAAwC;AAChE,OAAI,MACH,QAAO;AAGR,WAAQ,IAAI;AACZ,UAAO;;AAGR,SAAO;GACN,QAAQ;IACP,OAAO,QAAQ,SAAS,cAAc;IACtC,SAAS,QAAQ,WAAW,cAAc;IAC1C,YAAY,QAAQ,cAAc,cAAc;IAChD;GACD;GACA;GACA;;;;ACxBH,SAAgB,2BACf,SACA,kBACgD;AAChD,QAAO,OAAO,MAAM,WAAW;AAC9B,sBAAoB,OAAO,KAAK,QAAQ,OAAO,cAAc;EAE7D,MAAM,QAAQ,MAAM,mBAAmB,OAAO,IAAI;EAElD,MAAM,SAAS,MAAM;EAErB,MAAM,UAAU,MAAM,sBAAsB;AAC3C,UAAO,oBAAoB,OAAO,KAAK,OAAO,MAA4B,kBAAkB;IAC3F,YAAY,QAAQ;IACpB,YAAY,QAAQ;IACpB,CAAC;IACD;AAEF,MAAI,QAAQ,aAAa,OAAO,WAC/B,OAAM,QAAQ,gBACb,oBAAoB,YACpB,OAAO,YACP,QAAQ,WACR;AAGF,MAAI,QAAQ,QAAQ,OAAO,MAC1B,OAAM,QAAQ,gBAAgB,oBAAoB,OAAO,OAAO,OAAO,QAAQ,MAAM;AAGtF,MAAI,QAAQ,UAAU,OAAO,QAC5B,OAAM,QAAQ,gBAAgB,oBAAoB,SAAS,OAAO,SAAS,QAAQ,QAAQ;AAG5F,SAAO,MAAM;;;;;AChBf,IAAa,sBAAb,cAA8C,UAA2B;CACxE,WAAoB,OAAO,sBAAsB;CACjD;CAEA,YAAY,UAA2C,EAAE,EAAE;AAC1D,SAAO;AACP,OAAK,UAAU,iBAAiB,QAA+C;;CAGhF,kBACC,SACwD;AACxD,SAAO,EACN,cAAc,OAAO;GACpB,MAAM,WAAW,QAAQ,MAAM;AAC/B,QAAK,SAAS,UAAU,EACvB,eAAe,IACf,CAAC;AACF,UAAO,SAAS,iBAAiB;KAElC;;CAGF,mBACC,SACuE;AACvE,SAAO,EACN,cAAc,OAAO;GACpB,MAAM,WAAW,QAAQ,MAAM;AAC/B,QAAK,SAAS,UAAU,EACvB,eAAe,IACf,CAAC;AACF,UAAO,SAAS,iBAAiB;KAElC;;CAGF,0BACC,SAC8E;AAC9E,SAAO,EACN,cAAc,OAAO;GACpB,MAAM,WAAW,QAAQ,MAAM;AAC/B,QAAK,SAAS,UAAU,EACvB,eAAe,IACf,CAAC;AACF,UAAO,SAAS,iBAAiB;KAElC;;CAGF,OAAO,WAAmC;EACzC,MAAM,mCAAqC,IAAI,KAAK;AAEpD,OAAK,MAAM,gBAAgB,KAAK,aAAa,UAAU,EAAE;GACxD,MAAM,YAAY,KAAK,SAAS,aAAa;AAE7C,OAAI,UACH,6BACC,aAAa,MACb,KACA,UAAU,eACV,iBACA;AAGF,QAAK,MAAM,iBAAiB,aAAa,QAAQ;IAChD,MAAM,aAAa,KAAK,SAAS,cAAc;AAC/C,QAAI,CAAC,WAAY;AAEjB,gCACC,aAAa,MACb,cAAc,OACd,WAAW,eACX,iBACA;;;EAIH,MAAM,aAAa,2BAClB,KAAK,SACL,iBACA;AAED,OAAK,MAAM,gBAAgB,KAAK,aAAa,UAAU,EAAE;AACxD,OAAI,CAAC;IAAC;IAAS;IAAY;IAAe,CAAC,SAAS,aAAa,KAAK,CACrE;AAED,QAAK,MAAM,iBAAiB,aAAa,OACxC,eAAc,qBAAqB,WAAW;;;CAKjD,CAAW,aAAa,WAA6B;AACpD,OAAK,MAAM,YAAY,UACtB,MAAK,MAAM,gBAAgB,SAAS,MACnC,OAAM;;;;;;;;;;;;;;;;;;;;;;;;ACtFV,SAAgB,oBAAyB,SAA2C;AACnF,QAAO,IAAI,oBAAoB,QAAQ"}
|
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.12",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"baeta",
|
|
6
6
|
"graphql",
|
|
@@ -38,8 +38,9 @@
|
|
|
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
45
|
"test:circular": "builder test-circular",
|
|
45
46
|
"types": "tsc --noEmit"
|
|
@@ -51,14 +52,14 @@
|
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@baeta/builder": "^0.0.0",
|
|
54
|
-
"@baeta/core": "^2.0.0-next.
|
|
55
|
+
"@baeta/core": "^2.0.0-next.12",
|
|
55
56
|
"@baeta/testing": "^0.0.0",
|
|
56
57
|
"@baeta/tsconfig": "^0.0.0",
|
|
57
|
-
"graphql": "^16.
|
|
58
|
+
"graphql": "^16.6.0",
|
|
58
59
|
"typescript": "^5.9.3"
|
|
59
60
|
},
|
|
60
61
|
"peerDependencies": {
|
|
61
|
-
"@baeta/core": "^2.0.0-next.
|
|
62
|
+
"@baeta/core": "^2.0.0-next.12",
|
|
62
63
|
"graphql": "^16.6.0"
|
|
63
64
|
},
|
|
64
65
|
"engines": {
|