Skip to content

Commit 5b6a166

Browse files
Use Promise helpers (#2455)
* Use Promise helpers * chore(dependencies): updated changesets for modified dependencies * Lockfile --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent ce23388 commit 5b6a166

13 files changed

+117
-152
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@envelop/core": patch
3+
---
4+
dependencies updates:
5+
- Added dependency [`@whatwg-node/promise-helpers@^1.0.0` ↗︎](https://www.npmjs.com/package/@whatwg-node/promise-helpers/v/1.0.0) (to `dependencies`)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@envelop/on-resolve": patch
3+
---
4+
dependencies updates:
5+
- Added dependency [`@whatwg-node/promise-helpers@^1.0.0` ↗︎](https://www.npmjs.com/package/@whatwg-node/promise-helpers/v/1.0.0) (to `dependencies`)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@envelop/rate-limiter": patch
3+
---
4+
dependencies updates:
5+
- Added dependency [`@whatwg-node/promise-helpers@^1.0.0` ↗︎](https://www.npmjs.com/package/@whatwg-node/promise-helpers/v/1.0.0) (to `dependencies`)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@envelop/types": patch
3+
---
4+
dependencies updates:
5+
- Added dependency [`@whatwg-node/promise-helpers@^1.0.0` ↗︎](https://www.npmjs.com/package/@whatwg-node/promise-helpers/v/1.0.0) (to `dependencies`)

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
],
5858
"dependencies": {
5959
"@envelop/types": "workspace:^",
60+
"@whatwg-node/promise-helpers": "^1.0.0",
6061
"tslib": "^2.5.0"
6162
},
6263
"devDependencies": {

packages/core/src/utils.ts

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -40,53 +40,7 @@ export const makeSubscribe = (subscribeFn: (args: ExecutionArgs) => any): Subscr
4040
((...polyArgs: PolymorphicSubscribeArguments): PromiseOrValue<AsyncIterableIterator<any>> =>
4141
subscribeFn(getSubscribeArgs(polyArgs))) as SubscribeFunction;
4242

43-
export function mapAsyncIterator<T, O>(
44-
source: AsyncIterable<T>,
45-
mapper: (input: T) => Promise<O> | O,
46-
): AsyncGenerator<O> {
47-
const iterator = source[Symbol.asyncIterator]();
48-
49-
async function mapResult(result: IteratorResult<T, O>): Promise<IteratorResult<O>> {
50-
if (result.done) {
51-
return result;
52-
}
53-
try {
54-
return { value: await mapper(result.value), done: false };
55-
} catch (error) {
56-
try {
57-
await iterator.return?.();
58-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
59-
} catch (_error) {
60-
/* ignore error */
61-
}
62-
throw error;
63-
}
64-
}
65-
66-
const stream: AsyncGenerator<O> = {
67-
[Symbol.asyncIterator]() {
68-
return stream;
69-
},
70-
async next() {
71-
return await mapResult(await iterator.next());
72-
},
73-
async return() {
74-
const promise = iterator.return?.();
75-
return promise ? await mapResult(await promise) : { value: undefined as any, done: true };
76-
},
77-
async throw(error: unknown) {
78-
const promise = iterator.throw?.();
79-
if (promise) {
80-
return await mapResult(await promise);
81-
}
82-
// if the source has no throw method we just re-throw error
83-
// usually throw is not called anyways
84-
throw error;
85-
},
86-
};
87-
88-
return stream;
89-
}
43+
export { mapAsyncIterator } from '@whatwg-node/promise-helpers';
9044

9145
function getExecuteArgs(args: PolymorphicExecuteArguments): ExecutionArgs {
9246
return args.length === 1
@@ -226,31 +180,4 @@ export function errorAsyncIterator<TInput>(
226180
return stream;
227181
}
228182

229-
export function isPromise<T>(value: any): value is Promise<T> {
230-
return value?.then !== undefined;
231-
}
232-
233-
export function mapMaybePromise<T, R>(
234-
value: PromiseOrValue<T>,
235-
mapper: (v: T) => PromiseOrValue<R>,
236-
errorMapper?: (e: any) => PromiseOrValue<R>,
237-
): PromiseOrValue<R> {
238-
if (isPromise(value)) {
239-
if (errorMapper) {
240-
try {
241-
return value.then(mapper, errorMapper);
242-
} catch (e) {
243-
return errorMapper(e);
244-
}
245-
}
246-
return value.then(mapper);
247-
}
248-
if (errorMapper) {
249-
try {
250-
return mapper(value);
251-
} catch (e) {
252-
return errorMapper(e);
253-
}
254-
}
255-
return mapper(value);
256-
}
183+
export { mapMaybePromise, isPromise } from '@whatwg-node/promise-helpers';

packages/plugins/on-resolve/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@
5050
"@envelop/core": "workspace:^",
5151
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
5252
},
53-
"dependencies": {},
53+
"dependencies": {
54+
"@whatwg-node/promise-helpers": "^1.0.0"
55+
},
5456
"devDependencies": {
5557
"@envelop/core": "workspace:^",
5658
"@graphql-tools/schema": "10.0.19",

packages/plugins/on-resolve/src/index.ts

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@ import {
55
isIntrospectionType,
66
isObjectType,
77
} from 'graphql';
8-
import { mapMaybePromise, Plugin, PromiseOrValue } from '@envelop/core';
8+
import type { Plugin } from '@envelop/core';
9+
import { handleMaybePromise, mapMaybePromise, MaybePromise } from '@whatwg-node/promise-helpers';
910

1011
export type Resolver<Context = unknown> = (
1112
root: unknown,
1213
args: Record<string, unknown>,
1314
context: Context,
1415
info: GraphQLResolveInfo,
15-
) => PromiseOrValue<unknown>;
16+
) => MaybePromise<unknown>;
1617

1718
export type AfterResolver = (options: {
1819
result: unknown;
1920
setResult: (newResult: unknown) => void;
20-
}) => PromiseOrValue<void>;
21+
}) => MaybePromise<void>;
2122

2223
export interface OnResolveOptions<PluginContext extends Record<string, any> = {}> {
2324
context: PluginContext;
@@ -30,7 +31,7 @@ export interface OnResolveOptions<PluginContext extends Record<string, any> = {}
3031

3132
export type OnResolve<PluginContext extends Record<string, any> = {}> = (
3233
options: OnResolveOptions<PluginContext>,
33-
) => PromiseOrValue<AfterResolver | void>;
34+
) => MaybePromise<AfterResolver | void>;
3435

3536
export type UseOnResolveOptions = {
3637
/**
@@ -64,57 +65,46 @@ export function useOnResolve<PluginContext extends Record<string, any> = {}>(
6465
let resolver = (field.resolve || defaultFieldResolver) as Resolver<PluginContext>;
6566

6667
field.resolve = (root, args, context, info) =>
67-
mapMaybePromise(
68-
onResolve({
69-
root,
70-
args,
71-
context,
72-
info,
73-
resolver,
74-
replaceResolver: newResolver => {
75-
resolver = newResolver;
76-
},
77-
}),
68+
handleMaybePromise(
69+
() =>
70+
onResolve({
71+
root,
72+
args,
73+
context,
74+
info,
75+
resolver,
76+
replaceResolver: newResolver => {
77+
resolver = newResolver;
78+
},
79+
}),
7880
afterResolve => {
7981
if (typeof afterResolve === 'function') {
80-
try {
81-
return mapMaybePromise(
82-
resolver(root, args, context, info),
83-
result =>
84-
mapMaybePromise(
85-
afterResolve({
86-
result,
87-
setResult: newResult => {
88-
result = newResult;
89-
},
90-
}),
91-
() => result,
92-
),
93-
errorResult =>
94-
mapMaybePromise(
82+
return handleMaybePromise(
83+
() => resolver(root, args, context, info),
84+
result =>
85+
mapMaybePromise(
86+
afterResolve({
87+
result,
88+
setResult: newResult => {
89+
result = newResult;
90+
},
91+
}),
92+
() => result,
93+
),
94+
errorResult =>
95+
handleMaybePromise(
96+
() =>
9597
afterResolve({
9698
result: errorResult,
9799
setResult: newResult => {
98100
errorResult = newResult;
99101
},
100102
}),
101-
() => {
102-
throw errorResult;
103-
},
104-
),
105-
);
106-
} catch (err) {
107-
let errorResult = err;
108-
return mapMaybePromise(
109-
afterResolve({
110-
result: errorResult,
111-
setResult: newResult => {
112-
errorResult = newResult;
103+
() => {
104+
throw errorResult;
113105
},
114-
}),
115-
() => errorResult,
116-
);
117-
}
106+
),
107+
);
118108
}
119109
return resolver(root, args, context, info);
120110
},

packages/plugins/rate-limiter/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"dependencies": {
5454
"@envelop/on-resolve": "workspace:^",
5555
"@graphql-tools/utils": "^10.5.4",
56+
"@whatwg-node/promise-helpers": "^1.0.0",
5657
"lodash.get": "^4.4.2",
5758
"minimatch": "^10.0.1",
5859
"ms": "^2.1.3",

packages/plugins/rate-limiter/src/index.ts

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { GraphQLResolveInfo, responsePathAsArray } from 'graphql';
22
import { minimatch } from 'minimatch';
3-
import { mapMaybePromise, Plugin } from '@envelop/core';
3+
import type { Plugin } from '@envelop/core';
44
import { useOnResolve } from '@envelop/on-resolve';
55
import { createGraphQLError, getDirectiveExtensions } from '@graphql-tools/utils';
6+
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
67
import { getGraphQLRateLimiter } from './get-graphql-rate-limiter.js';
78
import { InMemoryStore } from './in-memory-store.js';
89
import { RateLimitError } from './rate-limit-error.js';
@@ -133,34 +134,35 @@ export const useRateLimiter = (options: RateLimiterPluginOptions): Plugin<RateLi
133134
const window = rateLimitDef.window;
134135
const identifier = identifyFn(context);
135136

136-
return mapMaybePromise(
137-
rateLimiterFn(
138-
{
139-
parent: root,
140-
args: fieldIdentity ? { ...args, identifier } : args,
141-
context,
142-
info,
143-
},
144-
{
145-
max,
146-
window,
147-
identityArgs: fieldIdentity
148-
? ['identifier', ...(rateLimitDef.identityArgs || [])]
149-
: rateLimitDef.identityArgs,
150-
arrayLengthField: rateLimitDef.arrayLengthField,
151-
uncountRejected: rateLimitDef.uncountRejected,
152-
readOnly: rateLimitDef.readOnly,
153-
message:
154-
message && identifier
155-
? interpolateMessage(message, identifier, {
156-
root,
157-
args,
158-
context,
159-
info,
160-
})
161-
: undefined,
162-
},
163-
),
137+
return handleMaybePromise(
138+
() =>
139+
rateLimiterFn(
140+
{
141+
parent: root,
142+
args: fieldIdentity ? { ...args, identifier } : args,
143+
context,
144+
info,
145+
},
146+
{
147+
max,
148+
window,
149+
identityArgs: fieldIdentity
150+
? ['identifier', ...(rateLimitDef.identityArgs || [])]
151+
: rateLimitDef.identityArgs,
152+
arrayLengthField: rateLimitDef.arrayLengthField,
153+
uncountRejected: rateLimitDef.uncountRejected,
154+
readOnly: rateLimitDef.readOnly,
155+
message:
156+
message && identifier
157+
? interpolateMessage(message, identifier, {
158+
root,
159+
args,
160+
context,
161+
info,
162+
})
163+
: undefined,
164+
},
165+
),
164166
errorMessage => {
165167
if (errorMessage) {
166168
if (options.onRateLimitError) {

0 commit comments

Comments
 (0)