@baeta/extension-complexity 0.0.4 → 1.0.9

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @baeta/extension-complexity
2
2
 
3
+ ## 1.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [`583014f`](https://github.com/andreisergiu98/baeta/commit/583014f0bac810b25d9a8226bda2df4c9039f5e3) Thanks [@andreisergiu98](https://github.com/andreisergiu98)! - Update dependencies
8
+
9
+ - Updated dependencies [[`583014f`](https://github.com/andreisergiu98/baeta/commit/583014f0bac810b25d9a8226bda2df4c9039f5e3)]:
10
+ - @baeta/core@1.0.9
11
+
12
+ ## 0.0.5
13
+
14
+ ### Patch Changes
15
+
16
+ - [#189](https://github.com/andreisergiu98/baeta/pull/189) [`d500378`](https://github.com/andreisergiu98/baeta/commit/d500378198e0a9c48298c4242913bca8ad348228) Thanks [@andreisergiu98](https://github.com/andreisergiu98)! - add jsdocs
17
+
18
+ - Updated dependencies [[`d500378`](https://github.com/andreisergiu98/baeta/commit/d500378198e0a9c48298c4242913bca8ad348228), [`1334c2a`](https://github.com/andreisergiu98/baeta/commit/1334c2a866676c88f0f3d380b22133d81c4e98bc)]:
19
+ - @baeta/core@1.0.8
20
+
3
21
  ## 0.0.4
4
22
 
5
23
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,62 +1,171 @@
1
- import { Extension, ModuleBuilder, NativeMiddleware, ResolverMapper } from '@baeta/core/sdk';
2
- import { GraphQLError } from 'graphql';
1
+ import { Extension } from '@baeta/core/sdk';
2
+ import { GraphQLError, GraphQLErrorOptions } from 'graphql';
3
3
 
4
+ /**
5
+ * Configuration for field complexity calculation.
6
+ */
4
7
  type FieldSettings = {
5
8
  complexity?: number;
6
9
  multiplier?: number;
7
10
  };
11
+ /**
12
+ * Arguments passed to field settings functions.
13
+ */
8
14
  type GetFieldSettingsArgs<Context, Args> = {
15
+ /** Arguments passed to the GraphQL field */
9
16
  args: Args;
17
+ /** Request context */
10
18
  ctx: Context;
11
19
  };
20
+ /**
21
+ * Function to determine complexity settings for a field.
22
+ * Returns either field settings or false to disable complexity calculation.
23
+ *
24
+ * @param params - Object containing field arguments and context
25
+ * @returns Field settings object or false
26
+ */
12
27
  type GetFieldSettings<Context, Args> = (params: GetFieldSettingsArgs<Context, Args>) => FieldSettings | false;
13
28
 
14
29
  declare global {
15
30
  export namespace BaetaExtensions {
16
31
  interface ResolverExtensions<Result, Root, Context, Args> {
32
+ /**
33
+ * Configures complexity calculation for a type field.
34
+ *
35
+ * @param fn - Function to determine complexity settings
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * Query.users.$complexity(({ args }) => ({
40
+ * complexity: 1,
41
+ * multiplier: args.limit || 10
42
+ * }));
43
+ *
44
+ * // Disable complexity calculation
45
+ * Query.simple.$complexity(() => false);
46
+ * ```
47
+ */
17
48
  $complexity: (fn: GetFieldSettings<Context, Args>) => void;
18
49
  }
19
50
  interface TypeExtensions<Root, Context> {
51
+ /**
52
+ * Configures complexity calculation for all fields of a type.
53
+ *
54
+ * @param fn - Function to determine complexity settings
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * User.$complexity(() => ({
59
+ * complexity: 2, // Higher base complexity for all User fields
60
+ * multiplier: 5
61
+ * }));
62
+ * ```
63
+ */
20
64
  $complexity: (fn: GetFieldSettings<Context, unknown>) => void;
21
65
  }
22
66
  interface SubscriptionExtensions<Root, Context, Args> {
67
+ /**
68
+ * Configures complexity calculation for subscription fields.
69
+ *
70
+ * @param fn - Function to determine complexity settings
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * Subscription.userUpdates.$complexity(({ args }) => ({
75
+ * complexity: 5,
76
+ * multiplier: args.batchSize || 1
77
+ * }));
78
+ * ```
79
+ */
23
80
  $complexity: (fn: GetFieldSettings<Context, Args>) => void;
24
81
  }
25
82
  }
26
83
  }
27
84
 
85
+ /** Complexity error code */
86
+ declare const ComplexityErrorCode = "COMPLEXITY_ERROR";
87
+ /**
88
+ * Thrown when a query exceeds the complexity limits.
89
+ */
90
+ declare class ComplexityError extends GraphQLError {
91
+ constructor(message?: string, options?: GraphQLErrorOptions);
92
+ }
93
+ /**
94
+ * Types of complexity validation errors that can occur during query analysis.
95
+ */
28
96
  declare enum ComplexityErrorKind {
97
+ /** Query exceeds maximum allowed depth */
29
98
  Depth = "DepthExceeded",
99
+ /** Query exceeds maximum allowed breadth (fields per level) */
30
100
  Breadth = "BreadthExceeded",
101
+ /** Query exceeds total complexity score limit */
31
102
  Complexity = "ComplexityExceeded"
32
103
  }
104
+ /**
105
+ * Function type for creating custom complexity error messages.
106
+ *
107
+ * @param kind - The type of complexity limit that was exceeded
108
+ * @param limits - The maximum allowed value
109
+ * @param results - The actual value that exceeded the limit
110
+ * @returns A GraphQL error with a custom message
111
+ */
33
112
  type GetComplexityError = (kind: ComplexityErrorKind, limits: number, results: number) => GraphQLError;
34
113
 
114
+ /**
115
+ * Configuration for query complexity limits.
116
+ */
35
117
  interface ComplexityLimit {
118
+ /** Maximum allowed query depth */
36
119
  depth?: number;
120
+ /** Maximum allowed fields per level */
37
121
  breadth?: number;
122
+ /** Maximum allowed total complexity score */
38
123
  complexity?: number;
39
124
  }
125
+ /**
126
+ * Function to determine complexity limits, can be static or context-based.
127
+ */
40
128
  type GetComplexityLimit<Context> = ComplexityLimit | ((ctx: Context) => ComplexityLimit | Promise<ComplexityLimit>);
41
129
 
130
+ /**
131
+ * Configuration options for the complexity extension.
132
+ */
42
133
  interface ComplexityExtensionOptions<Context> {
134
+ /** Static limits or function to determine limits based on context */
43
135
  limit?: GetComplexityLimit<Context>;
136
+ /**
137
+ * Base complexity score for fields
138
+ * @defaultValue 1
139
+ */
44
140
  defaultComplexity?: number;
141
+ /**
142
+ * Multiplier applied to list fields
143
+ * @defaultValue 10
144
+ */
45
145
  defaultListMultiplier?: number;
146
+ /** Custom error message generator */
46
147
  complexityError?: GetComplexityError;
47
148
  }
48
149
 
49
- declare class ComplexityExtension<Ctx> extends Extension {
50
- private readonly options;
51
- constructor(options?: ComplexityExtensionOptions<Ctx>);
52
- private fieldSettingsMap;
53
- getTypeExtensions: <Root, Context>(_module: ModuleBuilder, type: string) => BaetaExtensions.TypeExtensions<Root, Context>;
54
- getResolverExtensions: <Result, Root, Context, Args>(_module: ModuleBuilder, type: string, field: string) => BaetaExtensions.ResolverExtensions<Result, Root, Context, Args>;
55
- getSubscriptionExtensions: <Root, Context, Args>(_module: ModuleBuilder, field: string) => BaetaExtensions.SubscriptionExtensions<Root, Context, Args>;
56
- createComplexityMiddleware<Result, Root, Context, Args>(): NativeMiddleware<Result, Root, Context, Args>;
57
- build: (_module: ModuleBuilder, mapper: ResolverMapper) => void;
58
- }
59
-
60
- declare function complexityExtension<Ctx>(options?: ComplexityExtensionOptions<Ctx>): () => ComplexityExtension<Ctx>;
150
+ /**
151
+ * Creates a complexity analysis extension for GraphQL queries.
152
+ *
153
+ * @param options - Configuration options for complexity analysis
154
+ * @returns Extension factory function
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const complexity = complexityExtension<Context>({
159
+ * defaultComplexity: 1,
160
+ * defaultListMultiplier: 10,
161
+ * limit: {
162
+ * depth: 5,
163
+ * breadth: 10,
164
+ * complexity: 100
165
+ * }
166
+ * });
167
+ * ```
168
+ */
169
+ declare function complexityExtension<Ctx>(options?: ComplexityExtensionOptions<Ctx>): () => Extension;
61
170
 
62
- export { ComplexityErrorKind, type ComplexityExtensionOptions, type ComplexityLimit, type GetComplexityError, type GetComplexityLimit, complexityExtension };
171
+ export { ComplexityError, ComplexityErrorCode, ComplexityErrorKind, type ComplexityExtensionOptions, type ComplexityLimit, type FieldSettings, type GetComplexityError, type GetComplexityLimit, type GetFieldSettings, type GetFieldSettingsArgs, complexityExtension };
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@ import {
4
4
  } from "@baeta/core/sdk";
5
5
 
6
6
  // lib/complexity-calculator.ts
7
- import { ValidationError } from "@baeta/errors";
8
7
  import {
9
8
  Kind,
10
9
  getNamedType,
@@ -30,6 +29,57 @@ function capitalize(str) {
30
29
  return str.charAt(0).toUpperCase() + str.slice(1);
31
30
  }
32
31
 
32
+ // lib/complexity-errors.ts
33
+ import { GraphQLError } from "graphql";
34
+ var ComplexityErrorCode = "COMPLEXITY_ERROR";
35
+ var ComplexityError = class extends GraphQLError {
36
+ constructor(message = "Complexity limit exceeded! Please reduce the query's complexity.", options) {
37
+ super(message, {
38
+ ...options,
39
+ extensions: {
40
+ code: ComplexityErrorCode,
41
+ ...options?.extensions
42
+ }
43
+ });
44
+ }
45
+ };
46
+ var ComplexityErrorKind = /* @__PURE__ */ ((ComplexityErrorKind2) => {
47
+ ComplexityErrorKind2["Depth"] = "DepthExceeded";
48
+ ComplexityErrorKind2["Breadth"] = "BreadthExceeded";
49
+ ComplexityErrorKind2["Complexity"] = "ComplexityExceeded";
50
+ return ComplexityErrorKind2;
51
+ })(ComplexityErrorKind || {});
52
+ function getDefaultComplexityError(kind, limit, result) {
53
+ if (kind === "DepthExceeded" /* Depth */) {
54
+ return new ComplexityError(`Depth limit of ${limit} exceeded, got: ${result}`, {
55
+ extensions: {
56
+ kind: "DepthExceeded" /* Depth */,
57
+ limit,
58
+ got: result
59
+ }
60
+ });
61
+ }
62
+ if (kind === "BreadthExceeded" /* Breadth */) {
63
+ return new ComplexityError(`Breadth limit of ${limit} exceeded, got: ${result}`, {
64
+ extensions: {
65
+ kind: "BreadthExceeded" /* Breadth */,
66
+ limit,
67
+ got: result
68
+ }
69
+ });
70
+ }
71
+ if (kind === "ComplexityExceeded" /* Complexity */) {
72
+ return new ComplexityError(`Complexity limit of ${limit} exceeded, got: ${result}`, {
73
+ extensions: {
74
+ kind: "ComplexityExceeded" /* Complexity */,
75
+ limit,
76
+ got: result
77
+ }
78
+ });
79
+ }
80
+ throw new Error("Unknown complexity error kind");
81
+ }
82
+
33
83
  // lib/field-settings.ts
34
84
  import {
35
85
  getArgumentValues
@@ -55,7 +105,7 @@ function calculateComplexity(ctx, info, fieldSettingsMap, defaults) {
55
105
  const operationName = capitalize(info.operation.operation);
56
106
  const operationType = info.schema.getType(operationName);
57
107
  if (!operationType || !isOutputType(operationType)) {
58
- throw new ValidationError(`Unsupported operation ${operationName}`);
108
+ throw new ComplexityError(`Unsupported operation ${operationName}`);
59
109
  }
60
110
  return complexityFromSelectionSet(
61
111
  ctx,
@@ -94,7 +144,7 @@ function complexityFromSelection(ctx, info, type, selection, fieldSettingsMap, d
94
144
  if (selection.kind === Kind.FRAGMENT_SPREAD) {
95
145
  const fragment = info.fragments[selection.name.value];
96
146
  if (!fragment) {
97
- throw new ValidationError(`Fragment ${selection.name.value} not found`);
147
+ throw new ComplexityError(`Fragment ${selection.name.value} not found`);
98
148
  }
99
149
  return complexityFromFragment(ctx, info, type, fragment, fieldSettingsMap, defaults);
100
150
  }
@@ -103,10 +153,10 @@ function complexityFromSelection(ctx, info, type, selection, fieldSettingsMap, d
103
153
  function complexityFromFragment(ctx, info, type, fragment, fieldSettingsMap, defaults) {
104
154
  const fragmentType = fragment.typeCondition ? info.schema.getType(fragment.typeCondition.name.value) : type;
105
155
  if (!isOutputType(fragmentType)) {
106
- throw new ValidationError(`Unsupported fragment type ${fragmentType}`);
156
+ throw new ComplexityError(`Unsupported fragment type ${fragmentType}`);
107
157
  }
108
158
  if (!fragmentType) {
109
- throw new ValidationError(`Fragment type ${fragmentType} not found`);
159
+ throw new ComplexityError(`Fragment type ${fragmentType} not found`);
110
160
  }
111
161
  return complexityFromSelectionSet(
112
162
  ctx,
@@ -121,7 +171,7 @@ function complexityFromField(ctx, info, type, selection, fieldSettingsMap, defau
121
171
  const fieldName = selection.name.value;
122
172
  const field = isObjectType(type) || isInterfaceType(type) ? type.getFields()[fieldName] : void 0;
123
173
  if (!field && !fieldName.startsWith("__")) {
124
- throw new ValidationError(`Field ${fieldName} not found on type ${type.name}`);
174
+ throw new ComplexityError(`Field ${fieldName} not found on type ${type.name}`);
125
175
  }
126
176
  if (!field) {
127
177
  return {
@@ -177,27 +227,6 @@ function complexityFromField(ctx, info, type, selection, fieldSettingsMap, defau
177
227
  };
178
228
  }
179
229
 
180
- // lib/complexity-errors.ts
181
- import { ValidationError as ValidationError2 } from "@baeta/errors";
182
- var ComplexityErrorKind = /* @__PURE__ */ ((ComplexityErrorKind2) => {
183
- ComplexityErrorKind2["Depth"] = "DepthExceeded";
184
- ComplexityErrorKind2["Breadth"] = "BreadthExceeded";
185
- ComplexityErrorKind2["Complexity"] = "ComplexityExceeded";
186
- return ComplexityErrorKind2;
187
- })(ComplexityErrorKind || {});
188
- function getDefaultComplexityError(kind, limit, result) {
189
- if (kind === "DepthExceeded" /* Depth */) {
190
- return new ValidationError2(`Depth limit of ${limit} exceeded, got: ${result}`);
191
- }
192
- if (kind === "BreadthExceeded" /* Breadth */) {
193
- return new ValidationError2(`Breadth limit of ${limit} exceeded, got: ${result}`);
194
- }
195
- if (kind === "ComplexityExceeded" /* Complexity */) {
196
- return new ValidationError2(`Complexity limit of ${limit} exceeded, got: ${result}`);
197
- }
198
- throw new Error("Unknown complexity error kind");
199
- }
200
-
201
230
  // lib/complexity-options.ts
202
231
  var defaultLimits = {
203
232
  depth: 10,
@@ -241,6 +270,35 @@ function loadComplexityStore(ctx, getLimits, defaultLimits2) {
241
270
  });
242
271
  }
243
272
 
273
+ // lib/complexity-middleware.ts
274
+ function createComplexityMiddleware(options, fieldSettingsMap) {
275
+ return (next) => async (root, args, ctx, info) => {
276
+ loadComplexityStore(ctx, options.limit, defaultLimits);
277
+ const store = await getComplexityStore(ctx);
278
+ const limits = store.limits;
279
+ const results = store.cacheComplexity(() => {
280
+ return calculateComplexity(ctx, info, fieldSettingsMap, {
281
+ complexity: options.defaultComplexity,
282
+ multiplier: options.defaultListMultiplier
283
+ });
284
+ });
285
+ if (results.complexity > limits.complexity) {
286
+ throw options.complexityError(
287
+ "ComplexityExceeded" /* Complexity */,
288
+ limits.complexity,
289
+ results.complexity
290
+ );
291
+ }
292
+ if (results.depth > limits.depth) {
293
+ throw options.complexityError("DepthExceeded" /* Depth */, limits.depth, results.depth);
294
+ }
295
+ if (results.breadth > limits.breadth) {
296
+ throw options.complexityError("BreadthExceeded" /* Breadth */, limits.breadth, results.breadth);
297
+ }
298
+ return next(root, args, ctx, info);
299
+ };
300
+ }
301
+
244
302
  // lib/complexity-extension.ts
245
303
  var ComplexityExtension = class extends Extension {
246
304
  options;
@@ -271,35 +329,10 @@ var ComplexityExtension = class extends Extension {
271
329
  };
272
330
  };
273
331
  createComplexityMiddleware() {
274
- return (next) => async (root, args, ctx, info) => {
275
- loadComplexityStore(ctx, this.options.limit, defaultLimits);
276
- const store = await getComplexityStore(ctx);
277
- const limits = store.limits;
278
- const results = store.cacheComplexity(() => {
279
- return calculateComplexity(ctx, info, this.fieldSettingsMap, {
280
- complexity: this.options.defaultComplexity,
281
- multiplier: this.options.defaultListMultiplier
282
- });
283
- });
284
- if (results.depth > limits.depth) {
285
- throw this.options.complexityError("DepthExceeded" /* Depth */, limits.depth, results.depth);
286
- }
287
- if (results.breadth > limits.breadth) {
288
- throw this.options.complexityError(
289
- "BreadthExceeded" /* Breadth */,
290
- limits.breadth,
291
- results.breadth
292
- );
293
- }
294
- if (results.complexity > limits.complexity) {
295
- throw this.options.complexityError(
296
- "ComplexityExceeded" /* Complexity */,
297
- limits.complexity,
298
- results.complexity
299
- );
300
- }
301
- return next(root, args, ctx, info);
302
- };
332
+ return createComplexityMiddleware(
333
+ this.options,
334
+ this.fieldSettingsMap
335
+ );
303
336
  }
304
337
  build = (_module, mapper) => {
305
338
  for (const type of mapper.getTypes()) {
@@ -324,6 +357,8 @@ function complexityExtension(options) {
324
357
  return () => new ComplexityExtension(options);
325
358
  }
326
359
  export {
360
+ ComplexityError,
361
+ ComplexityErrorCode,
327
362
  ComplexityErrorKind,
328
363
  complexityExtension
329
364
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/complexity-extension.ts","../lib/complexity-calculator.ts","../utils/graphlq.ts","../utils/string.ts","../lib/field-settings.ts","../lib/complexity-errors.ts","../lib/complexity-options.ts","../lib/store.ts","../lib/store-loader.ts","../index.ts"],"sourcesContent":["import {\n\tExtension,\n\ttype ModuleBuilder,\n\ttype NativeMiddleware,\n\ttype ResolverMapper,\n} from '@baeta/core/sdk';\nimport { calculateComplexity } from './complexity-calculator.ts';\nimport { ComplexityErrorKind } from './complexity-errors.ts';\nimport {\n\ttype ComplexityExtensionOptions,\n\tdefaultLimits,\n\tnormalizeOptions,\n} from './complexity-options.ts';\nimport { type FieldSettingsMap, registerFieldSettingsSetter } from './field-settings.ts';\nimport { loadComplexityStore } from './store-loader.ts';\nimport { getComplexityStore } from './store.ts';\n\nexport class ComplexityExtension<Ctx> extends Extension {\n\tprivate readonly options: Required<ComplexityExtensionOptions<Ctx>>;\n\n\tconstructor(options: ComplexityExtensionOptions<Ctx> = {}) {\n\t\tsuper();\n\t\tthis.options = normalizeOptions(options);\n\t}\n\n\tprivate fieldSettingsMap: FieldSettingsMap = {};\n\n\tgetTypeExtensions = <Root, Context>(\n\t\t_module: ModuleBuilder,\n\t\ttype: string,\n\t): BaetaExtensions.TypeExtensions<Root, Context> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter(type, '*', fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tgetResolverExtensions = <Result, Root, Context, Args>(\n\t\t_module: ModuleBuilder,\n\t\ttype: string,\n\t\tfield: string,\n\t): BaetaExtensions.ResolverExtensions<Result, Root, Context, Args> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter(type, field, fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tgetSubscriptionExtensions = <Root, Context, Args>(\n\t\t_module: ModuleBuilder,\n\t\tfield: string,\n\t): BaetaExtensions.SubscriptionExtensions<Root, Context, Args> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter('Subscription', field, fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tcreateComplexityMiddleware<Result, Root, Context, Args>(): NativeMiddleware<\n\t\tResult,\n\t\tRoot,\n\t\tContext,\n\t\tArgs\n\t> {\n\t\treturn (next) => async (root, args, ctx, info) => {\n\t\t\tloadComplexityStore(ctx as unknown as Ctx, this.options.limit, defaultLimits);\n\n\t\t\tconst store = await getComplexityStore(ctx);\n\n\t\t\tconst limits = store.limits;\n\n\t\t\tconst results = store.cacheComplexity(() => {\n\t\t\t\treturn calculateComplexity(ctx as unknown as Ctx, info, this.fieldSettingsMap, {\n\t\t\t\t\tcomplexity: this.options.defaultComplexity,\n\t\t\t\t\tmultiplier: this.options.defaultListMultiplier,\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (results.depth > limits.depth) {\n\t\t\t\tthrow this.options.complexityError(ComplexityErrorKind.Depth, limits.depth, results.depth);\n\t\t\t}\n\n\t\t\tif (results.breadth > limits.breadth) {\n\t\t\t\tthrow this.options.complexityError(\n\t\t\t\t\tComplexityErrorKind.Breadth,\n\t\t\t\t\tlimits.breadth,\n\t\t\t\t\tresults.breadth,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (results.complexity > limits.complexity) {\n\t\t\t\tthrow this.options.complexityError(\n\t\t\t\t\tComplexityErrorKind.Complexity,\n\t\t\t\t\tlimits.complexity,\n\t\t\t\t\tresults.complexity,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn next(root, args, ctx, info);\n\t\t};\n\t}\n\n\tbuild = (_module: ModuleBuilder, mapper: ResolverMapper) => {\n\t\tfor (const type of mapper.getTypes()) {\n\t\t\tif (type !== 'Query' && type !== 'Mutation' && type !== 'Subscription') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (type !== 'Subscription') {\n\t\t\t\tfor (const field of mapper.getTypeFields(type)) {\n\t\t\t\t\tmapper.prependMiddleware(type, field, this.createComplexityMiddleware());\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const field of mapper.getTypeFields(type)) {\n\t\t\t\tmapper.prependMiddleware(type, `${field}.subscribe`, this.createComplexityMiddleware());\n\t\t\t}\n\t\t}\n\t};\n}\n","import { ValidationError } from '@baeta/errors';\nimport {\n\ttype FieldNode,\n\ttype FragmentDefinitionNode,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\ttype InlineFragmentNode,\n\tKind,\n\ttype SelectionNode,\n\ttype SelectionSetNode,\n\tgetNamedType,\n\tisInterfaceType,\n\tisObjectType,\n\tisOutputType,\n} from 'graphql';\nimport { isListOrNullableList } from '../utils/graphlq.ts';\nimport { capitalize } from '../utils/string.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 ValidationError(`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 ValidationError(`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 ValidationError(`Unsupported fragment type ${fragmentType}`);\n\t}\n\n\tif (!fragmentType) {\n\t\tthrow new ValidationError(`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 ValidationError(`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 { 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 {\n\ttype FieldNode,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLResolveInfo,\n\tgetArgumentValues,\n} from 'graphql';\n\nexport type FieldSettingsMap = Record<\n\tstring,\n\t// biome-ignore lint/suspicious/noExplicitAny: Match any type from the original code\n\tRecord<string, GetFieldSettings<any, any> | undefined> | undefined\n>;\n\nexport type FieldSettings = {\n\tcomplexity?: number;\n\tmultiplier?: number;\n};\n\nexport type GetFieldSettingsArgs<Context, Args> = {\n\targs: Args;\n\tctx: Context;\n};\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[type.name]?.[fieldName];\n\n\tif (customComplexity) {\n\t\treturn customComplexity({ args, ctx });\n\t}\n\n\tconst wildCardComplexity = fieldSettingsMap[type.name]?.['*'];\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\tmap[type] ??= {};\n\tmap[type][field] = fn;\n}\n","import { ValidationError } from '@baeta/errors';\nimport type { GraphQLError } from 'graphql';\n\nexport enum ComplexityErrorKind {\n\tDepth = 'DepthExceeded',\n\tBreadth = 'BreadthExceeded',\n\tComplexity = 'ComplexityExceeded',\n}\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 ValidationError(`Depth limit of ${limit} exceeded, got: ${result}`);\n\t}\n\n\tif (kind === ComplexityErrorKind.Breadth) {\n\t\treturn new ValidationError(`Breadth limit of ${limit} exceeded, got: ${result}`);\n\t}\n\n\tif (kind === ComplexityErrorKind.Complexity) {\n\t\treturn new ValidationError(`Complexity limit of ${limit} exceeded, got: ${result}`);\n\t}\n\n\tthrow new Error('Unknown complexity error kind');\n}\n","import { type GetComplexityError, getDefaultComplexityError } from './complexity-errors.ts';\nimport type { GetComplexityLimit } from './complexity-limits.ts';\n\nexport interface ComplexityExtensionOptions<Context> {\n\tlimit?: GetComplexityLimit<Context>;\n\tdefaultComplexity?: number;\n\tdefaultListMultiplier?: number;\n\tcomplexityError?: GetComplexityError;\n}\n\nexport const defaultLimits = {\n\tdepth: 10,\n\tbreadth: 50,\n\tcomplexity: 1000,\n};\n\nexport type NormalizedOptions<Context> = Required<ComplexityExtensionOptions<Context>>;\n\nexport function normalizeOptions<Context>(\n\toptions: ComplexityExtensionOptions<Context>,\n): NormalizedOptions<Context> {\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: ComplexityLimit | ((ctx: T) => ComplexityLimit | Promise<ComplexityLimit>) | 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 = 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 './lib/global-types.ts';\n\nimport { ComplexityExtension } from './lib/complexity-extension.ts';\nimport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\n\nexport { ComplexityErrorKind, type GetComplexityError } from './lib/complexity-errors.ts';\nexport type { ComplexityLimit, GetComplexityLimit } from './lib/complexity-limits.ts';\nexport type { ComplexityExtensionOptions } from './lib/complexity-options.ts';\n\nexport function complexityExtension<Ctx>(options?: ComplexityExtensionOptions<Ctx>) {\n\treturn () => new ComplexityExtension(options);\n}\n"],"mappings":"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","names":["ValidationError","ComplexityErrorKind","defaultLimits"]}
1
+ {"version":3,"sources":["../lib/complexity-extension.ts","../lib/complexity-calculator.ts","../utils/graphlq.ts","../utils/string.ts","../lib/complexity-errors.ts","../lib/field-settings.ts","../lib/complexity-options.ts","../lib/store.ts","../lib/store-loader.ts","../lib/complexity-middleware.ts","../index.ts"],"sourcesContent":["import {\n\tExtension,\n\ttype ModuleBuilder,\n\ttype NativeMiddleware,\n\ttype ResolverMapper,\n} from '@baeta/core/sdk';\nimport { createComplexityMiddleware } from './complexity-middleware.ts';\nimport { type ComplexityExtensionOptions, normalizeOptions } from './complexity-options.ts';\nimport { type FieldSettingsMap, registerFieldSettingsSetter } from './field-settings.ts';\n\nexport class ComplexityExtension<Ctx> extends Extension {\n\tprivate readonly options: Required<ComplexityExtensionOptions<Ctx>>;\n\n\tconstructor(options: ComplexityExtensionOptions<Ctx> = {}) {\n\t\tsuper();\n\t\tthis.options = normalizeOptions(options);\n\t}\n\n\tprivate fieldSettingsMap: FieldSettingsMap = {};\n\n\tgetTypeExtensions = <Root, Context>(\n\t\t_module: ModuleBuilder,\n\t\ttype: string,\n\t): BaetaExtensions.TypeExtensions<Root, Context> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter(type, '*', fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tgetResolverExtensions = <Result, Root, Context, Args>(\n\t\t_module: ModuleBuilder,\n\t\ttype: string,\n\t\tfield: string,\n\t): BaetaExtensions.ResolverExtensions<Result, Root, Context, Args> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter(type, field, fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tgetSubscriptionExtensions = <Root, Context, Args>(\n\t\t_module: ModuleBuilder,\n\t\tfield: string,\n\t): BaetaExtensions.SubscriptionExtensions<Root, Context, Args> => {\n\t\treturn {\n\t\t\t$complexity: (fn) => {\n\t\t\t\tregisterFieldSettingsSetter('Subscription', field, fn, this.fieldSettingsMap);\n\t\t\t},\n\t\t};\n\t};\n\n\tcreateComplexityMiddleware<Result, Root, Context, Args>(): NativeMiddleware<\n\t\tResult,\n\t\tRoot,\n\t\tContext,\n\t\tArgs\n\t> {\n\t\treturn createComplexityMiddleware<Result, Root, Context, Args>(\n\t\t\tthis.options as Required<ComplexityExtensionOptions<Context>>,\n\t\t\tthis.fieldSettingsMap,\n\t\t);\n\t}\n\n\tbuild = (_module: ModuleBuilder, mapper: ResolverMapper) => {\n\t\tfor (const type of mapper.getTypes()) {\n\t\t\tif (type !== 'Query' && type !== 'Mutation' && type !== 'Subscription') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (type !== 'Subscription') {\n\t\t\t\tfor (const field of mapper.getTypeFields(type)) {\n\t\t\t\t\tmapper.prependMiddleware(type, field, this.createComplexityMiddleware());\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const field of mapper.getTypeFields(type)) {\n\t\t\t\tmapper.prependMiddleware(type, `${field}.subscribe`, this.createComplexityMiddleware());\n\t\t\t}\n\t\t}\n\t};\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\ttype InlineFragmentNode,\n\tKind,\n\ttype SelectionNode,\n\ttype SelectionSetNode,\n\tgetNamedType,\n\tisInterfaceType,\n\tisObjectType,\n\tisOutputType,\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 { 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 enum 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\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 = Record<\n\tstring,\n\t// biome-ignore lint/suspicious/noExplicitAny: Match any type from the original code\n\tRecord<string, GetFieldSettings<any, any> | undefined> | undefined\n>;\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[type.name]?.[fieldName];\n\n\tif (customComplexity) {\n\t\treturn customComplexity({ args, ctx });\n\t}\n\n\tconst wildCardComplexity = fieldSettingsMap[type.name]?.['*'];\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\tmap[type] ??= {};\n\tmap[type][field] = fn;\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<Context> = Required<ComplexityExtensionOptions<Context>>;\n\nexport function normalizeOptions<Context>(\n\toptions: ComplexityExtensionOptions<Context>,\n): NormalizedOptions<Context> {\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: ComplexityLimit | ((ctx: T) => ComplexityLimit | Promise<ComplexityLimit>) | 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 = 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 { NativeMiddleware } from '@baeta/core/sdk';\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 { loadComplexityStore } from './store-loader.ts';\nimport { getComplexityStore } from './store.ts';\n\nexport function createComplexityMiddleware<Result, Root, Context, Args>(\n\toptions: Required<ComplexityExtensionOptions<Context>>,\n\tfieldSettingsMap: FieldSettingsMap,\n): NativeMiddleware<Result, Root, Context, Args> {\n\treturn (next) => async (root, args, ctx, info) => {\n\t\tloadComplexityStore(ctx, options.limit, defaultLimits);\n\n\t\tconst store = await getComplexityStore(ctx);\n\n\t\tconst limits = store.limits;\n\n\t\tconst results = store.cacheComplexity(() => {\n\t\t\treturn calculateComplexity(ctx, info, 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(root, args, ctx, info);\n\t};\n}\n","import './lib/global-types.ts';\n\nimport type { Extension } from '@baeta/core/sdk';\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 (): Extension => new ComplexityExtension(options);\n}\n"],"mappings":"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","names":["ComplexityErrorKind","defaultLimits"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baeta/extension-complexity",
3
- "version": "0.0.4",
3
+ "version": "1.0.9",
4
4
  "keywords": [
5
5
  "baeta",
6
6
  "graphql",
@@ -40,17 +40,19 @@
40
40
  "build": "tsup",
41
41
  "prepack": "prep",
42
42
  "postpack": "prep --clean",
43
+ "test": "ava",
43
44
  "types": "tsc --noEmit"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@baeta/builder": "^0.0.0",
47
- "@baeta/core": "^0.1.5",
48
+ "@baeta/core": "^1.0.9",
49
+ "@baeta/testing": "^0.0.0",
48
50
  "@baeta/tsconfig": "^0.0.0",
49
- "graphql": "^16.9.0",
50
- "typescript": "^5.7.2"
51
+ "graphql": "^16.10.0",
52
+ "typescript": "^5.8.2"
51
53
  },
52
54
  "peerDependencies": {
53
- "@baeta/core": "^0.1.5",
55
+ "@baeta/core": "^1.0.9",
54
56
  "graphql": "^16.6.0"
55
57
  },
56
58
  "engines": {
@@ -74,14 +76,17 @@
74
76
  "--experimental-transform-types"
75
77
  ]
76
78
  },
77
- "dependencies": {
78
- "@baeta/errors": "^0.1.4"
79
- },
80
79
  "typedocOptions": {
81
80
  "entryPoints": [
82
81
  "./index.ts"
83
82
  ],
84
83
  "readme": "none",
85
- "tsconfig": "./tsconfig.json"
84
+ "tsconfig": "./tsconfig.json",
85
+ "sort": [
86
+ "kind",
87
+ "instance-first",
88
+ "required-first",
89
+ "alphabetical-ignoring-documents"
90
+ ]
86
91
  }
87
92
  }