@middy/util 7.1.2 → 7.1.4
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/README.md +18 -5
- package/index.d.ts +20 -19
- package/index.js +54 -24
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -30,10 +30,23 @@
|
|
|
30
30
|
<p>You can read the documentation at: <a href="https://middy.js.org/docs/intro/utilities">https://middy.js.org/docs/intro/utilities</a></p>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install --save @middy/util
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Documentation and examples
|
|
41
|
+
|
|
42
|
+
For documentation and examples, refer to the main [Middy monorepo on GitHub](https://github.com/middyjs/middy) or [Middy official website](https://middy.js.org/docs/intro/utilities).
|
|
34
43
|
|
|
35
|
-
Licensed under [MIT License](LICENSE). Copyright (c) 2017-2026 [will Farrell](https://github.com/willfarrell), [Luciano Mammino](https://github.com/lmammino), and [Middy contributors](https://github.com/middyjs/middy/graphs/contributors).
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
## Contributing
|
|
46
|
+
|
|
47
|
+
Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/middyjs/middy/issues) or to [submit Pull Requests](https://github.com/middyjs/middy/pulls).
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
Licensed under [MIT License](LICENSE). Copyright (c) 2017-2026 [will Farrell](https://github.com/willfarrell), [Luciano Mammino](https://github.com/lmammino), and [Middy contributors](https://github.com/middyjs/middy/graphs/contributors).
|
package/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
} from "./type-utils.d.ts";
|
|
13
13
|
|
|
14
14
|
export interface Options<Client, ClientOptions> {
|
|
15
|
-
AwsClient?: new (
|
|
15
|
+
AwsClient?: new (config: ClientOptions) => Client;
|
|
16
16
|
awsClientOptions?: Partial<ClientOptions>;
|
|
17
17
|
awsClientAssumeRole?: string;
|
|
18
18
|
awsClientCapture?: (service: Client) => Client;
|
|
@@ -20,6 +20,7 @@ export interface Options<Client, ClientOptions> {
|
|
|
20
20
|
disablePrefetch?: boolean;
|
|
21
21
|
cacheKey?: string;
|
|
22
22
|
cacheExpiry?: number;
|
|
23
|
+
cacheKeyExpiry?: Record<string, number>;
|
|
23
24
|
setToContext?: boolean;
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -27,8 +28,8 @@ export declare class HttpError extends Error {
|
|
|
27
28
|
status: number;
|
|
28
29
|
statusCode: number;
|
|
29
30
|
expose: boolean;
|
|
30
|
-
[key: string]:
|
|
31
|
-
[key: number]:
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
[key: number]: unknown;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
declare function createPrefetchClient<Client, ClientOptions>(
|
|
@@ -118,43 +119,43 @@ declare function sanitizeKey<T extends string>(key: T): SanitizeKey<T>;
|
|
|
118
119
|
|
|
119
120
|
declare function processCache<Client, ClientOptions>(
|
|
120
121
|
options: Options<Client, ClientOptions>,
|
|
121
|
-
fetch: (request: middy.Request, cachedValues:
|
|
122
|
+
fetch: (request: middy.Request, cachedValues: unknown) => unknown,
|
|
122
123
|
request?: middy.Request,
|
|
123
|
-
): { value:
|
|
124
|
+
): { value: unknown; expiry: number };
|
|
124
125
|
|
|
125
|
-
declare function getCache(keys: string):
|
|
126
|
+
declare function getCache(keys: string): unknown;
|
|
126
127
|
|
|
127
128
|
declare function clearCache(keys?: string | string[] | null): void;
|
|
128
129
|
|
|
129
130
|
declare function jsonSafeParse(
|
|
130
131
|
string: string,
|
|
131
|
-
reviver?: (key: string, value:
|
|
132
|
-
):
|
|
132
|
+
reviver?: (key: string, value: unknown) => unknown,
|
|
133
|
+
): unknown;
|
|
133
134
|
|
|
134
135
|
declare function normalizeHttpResponse(
|
|
135
|
-
request:
|
|
136
|
-
fallbackResponse?:
|
|
137
|
-
):
|
|
136
|
+
request: middy.Request,
|
|
137
|
+
fallbackResponse?: Record<string, unknown>,
|
|
138
|
+
): Record<string, unknown>;
|
|
138
139
|
|
|
139
140
|
declare function createError(
|
|
140
141
|
code: number,
|
|
141
142
|
message: string,
|
|
142
|
-
properties?: Record<string,
|
|
143
|
+
properties?: Record<string, unknown>,
|
|
143
144
|
): HttpError;
|
|
144
145
|
|
|
145
|
-
declare function modifyCache(cacheKey: string, value:
|
|
146
|
+
declare function modifyCache(cacheKey: string, value: unknown): void;
|
|
146
147
|
|
|
147
148
|
declare function catchInvalidSignatureException<Client, Command>(
|
|
148
149
|
e: Error & { __type?: string },
|
|
149
150
|
client: Client,
|
|
150
151
|
command: Command,
|
|
151
|
-
): Promise<
|
|
152
|
+
): Promise<unknown>;
|
|
152
153
|
|
|
153
154
|
declare function jsonSafeStringify(
|
|
154
|
-
value:
|
|
155
|
-
replacer?: (key: string, value:
|
|
155
|
+
value: unknown,
|
|
156
|
+
replacer?: (key: string, value: unknown) => unknown,
|
|
156
157
|
space?: string | number,
|
|
157
|
-
): string |
|
|
158
|
+
): string | unknown;
|
|
158
159
|
|
|
159
160
|
declare function decodeBody(event: {
|
|
160
161
|
body?: string | null;
|
|
@@ -171,12 +172,12 @@ declare function executionContext(
|
|
|
171
172
|
request: middy.Request,
|
|
172
173
|
key: string,
|
|
173
174
|
context: LambdaContext,
|
|
174
|
-
):
|
|
175
|
+
): unknown;
|
|
175
176
|
|
|
176
177
|
declare function lambdaContext(
|
|
177
178
|
request: middy.Request,
|
|
178
179
|
key: string,
|
|
179
180
|
context: LambdaContext,
|
|
180
|
-
):
|
|
181
|
+
): unknown;
|
|
181
182
|
|
|
182
183
|
declare const httpErrorCodes: Record<number, string>;
|
package/index.js
CHANGED
|
@@ -46,6 +46,9 @@ export const canPrefetch = (options = {}) => {
|
|
|
46
46
|
return !options.awsClientAssumeRole && !options.disablePrefetch;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
const safeGet = (obj, key) =>
|
|
50
|
+
obj != null && Object.hasOwn(obj, key) ? obj[key] : undefined;
|
|
51
|
+
|
|
49
52
|
// Internal Context
|
|
50
53
|
export const getInternal = async (variables, request) => {
|
|
51
54
|
if (!variables || !request) return {};
|
|
@@ -61,6 +64,36 @@ export const getInternal = async (variables, request) => {
|
|
|
61
64
|
keys = Object.keys(variables);
|
|
62
65
|
values = Object.values(variables);
|
|
63
66
|
}
|
|
67
|
+
// Fast synchronous path: when all internal values are already resolved
|
|
68
|
+
// (warm/cached invocations), skip all Promise machinery entirely
|
|
69
|
+
let allSync = true;
|
|
70
|
+
const syncResults = new Array(values.length);
|
|
71
|
+
for (let i = 0; i < values.length; i++) {
|
|
72
|
+
const internalKey = values[i];
|
|
73
|
+
const dotIndex = internalKey.indexOf(".");
|
|
74
|
+
const rootKey =
|
|
75
|
+
dotIndex === -1 ? internalKey : internalKey.substring(0, dotIndex);
|
|
76
|
+
let value = request.internal[rootKey];
|
|
77
|
+
if (isPromise(value)) {
|
|
78
|
+
allSync = false;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (dotIndex !== -1) {
|
|
82
|
+
for (const part of internalKey.substring(dotIndex + 1).split(".")) {
|
|
83
|
+
value = safeGet(value, part);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
syncResults[i] = value;
|
|
87
|
+
}
|
|
88
|
+
if (allSync) {
|
|
89
|
+
const obj = {};
|
|
90
|
+
for (let i = 0; i < keys.length; i++) {
|
|
91
|
+
obj[sanitizeKey(keys[i])] = syncResults[i];
|
|
92
|
+
}
|
|
93
|
+
return obj;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Async fallback: for cold/first invocations with pending promises
|
|
64
97
|
const promises = [];
|
|
65
98
|
for (const internalKey of values) {
|
|
66
99
|
// 'internal.key.sub_value' -> { [key]: internal.key.sub_value }
|
|
@@ -71,26 +104,27 @@ export const getInternal = async (variables, request) => {
|
|
|
71
104
|
valuePromise = Promise.resolve(valuePromise);
|
|
72
105
|
}
|
|
73
106
|
promises.push(
|
|
74
|
-
valuePromise.then((value) =>
|
|
75
|
-
pathOptionKey.reduce((p, c) => p?.[c], value),
|
|
76
|
-
),
|
|
107
|
+
valuePromise.then((value) => pathOptionKey.reduce(safeGet, value)),
|
|
77
108
|
);
|
|
78
109
|
}
|
|
79
110
|
// ensure promise has resolved by the time it's needed
|
|
80
111
|
// If one of the promises throws it will bubble up to @middy/core
|
|
81
112
|
values = await Promise.allSettled(promises);
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
113
|
+
const obj = {};
|
|
114
|
+
let errors;
|
|
115
|
+
for (let i = 0; i < keys.length; i++) {
|
|
116
|
+
if (values[i].status === "rejected") {
|
|
117
|
+
errors ??= [];
|
|
118
|
+
errors.push(values[i].reason);
|
|
119
|
+
} else {
|
|
120
|
+
obj[sanitizeKey(keys[i])] = values[i].value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (errors) {
|
|
86
124
|
throw new Error("Failed to resolve internal values", {
|
|
87
125
|
cause: { package: "@middy/util", data: errors },
|
|
88
126
|
});
|
|
89
127
|
}
|
|
90
|
-
const obj = {};
|
|
91
|
-
for (let i = keys.length; i--; ) {
|
|
92
|
-
obj[sanitizeKey(keys[i])] = values[i].value;
|
|
93
|
-
}
|
|
94
128
|
return obj;
|
|
95
129
|
};
|
|
96
130
|
|
|
@@ -125,7 +159,8 @@ export const processCache = (
|
|
|
125
159
|
cache[cacheKey] = { value: cached.value, expiry: cached.expiry };
|
|
126
160
|
return cache[cacheKey];
|
|
127
161
|
}
|
|
128
|
-
|
|
162
|
+
cached.cache = true;
|
|
163
|
+
return cached;
|
|
129
164
|
}
|
|
130
165
|
}
|
|
131
166
|
const value = middlewareFetch(middlewareFetchRequest);
|
|
@@ -161,8 +196,9 @@ export const getCache = (key) => {
|
|
|
161
196
|
// Used to remove parts of a cache
|
|
162
197
|
export const modifyCache = (cacheKey, value) => {
|
|
163
198
|
if (!cache[cacheKey]) return;
|
|
164
|
-
clearTimeout(cache[cacheKey]
|
|
165
|
-
cache[cacheKey] =
|
|
199
|
+
clearTimeout(cache[cacheKey].refresh);
|
|
200
|
+
cache[cacheKey].value = value;
|
|
201
|
+
cache[cacheKey].modified = true;
|
|
166
202
|
};
|
|
167
203
|
|
|
168
204
|
export const clearCache = (inputKeys = null) => {
|
|
@@ -192,18 +228,12 @@ export const lambdaContextKeys = [
|
|
|
192
228
|
"callbackWaitsForEmptyEventLoop",
|
|
193
229
|
];
|
|
194
230
|
|
|
195
|
-
export const executionContextKeys = [
|
|
196
|
-
//'requestId',
|
|
197
|
-
"tenantId",
|
|
198
|
-
];
|
|
231
|
+
export const executionContextKeys = ["tenantId"];
|
|
199
232
|
|
|
200
233
|
export const isExecutionModeDurable = (context) => {
|
|
201
234
|
// using `context instanceof DurableContextImpl` would be better
|
|
202
235
|
// but would require an extra dependency
|
|
203
|
-
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
return false;
|
|
236
|
+
return context.constructor.name === "DurableContextImpl";
|
|
207
237
|
};
|
|
208
238
|
|
|
209
239
|
export const executionContext = (request, key, context) => {
|
|
@@ -241,7 +271,7 @@ export const jsonSafeStringify = (value, replacer, space) => {
|
|
|
241
271
|
|
|
242
272
|
export const decodeBody = (event) => {
|
|
243
273
|
const { body, isBase64Encoded } = event;
|
|
244
|
-
if (body === undefined || body === null) return body;
|
|
274
|
+
if (typeof body === "undefined" || body === null) return body;
|
|
245
275
|
return isBase64Encoded ? Buffer.from(body, "base64").toString() : body;
|
|
246
276
|
};
|
|
247
277
|
|
|
@@ -286,7 +316,7 @@ export const createError = (code, message, properties = {}) => {
|
|
|
286
316
|
return new HttpError(code, message, properties);
|
|
287
317
|
};
|
|
288
318
|
|
|
289
|
-
const httpErrorCodes = {
|
|
319
|
+
export const httpErrorCodes = {
|
|
290
320
|
100: "Continue",
|
|
291
321
|
101: "Switching Protocols",
|
|
292
322
|
102: "Processing",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@middy/util",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.4",
|
|
4
4
|
"description": "🛵 The stylish Node.js middleware engine for AWS Lambda (util package)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@aws-sdk/client-ssm": "^3.0.0",
|
|
63
|
-
"@middy/core": "7.1.
|
|
63
|
+
"@middy/core": "7.1.4",
|
|
64
64
|
"@types/aws-lambda": "^8.0.0",
|
|
65
65
|
"@types/node": "^22.0.0",
|
|
66
66
|
"aws-xray-sdk": "^3.3.3"
|
|
@@ -69,6 +69,5 @@
|
|
|
69
69
|
"funding": {
|
|
70
70
|
"type": "github",
|
|
71
71
|
"url": "https://github.com/sponsors/willfarrell"
|
|
72
|
-
}
|
|
73
|
-
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
|
|
72
|
+
}
|
|
74
73
|
}
|