@fluojs/runtime 1.0.0-beta.1 → 1.0.0-beta.11
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.ko.md +53 -11
- package/README.md +53 -11
- package/dist/adapters/request-response-factory.d.ts +9 -0
- package/dist/adapters/request-response-factory.d.ts.map +1 -1
- package/dist/adapters/request-response-factory.js +14 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +327 -60
- package/dist/health/diagnostics.d.ts +38 -0
- package/dist/health/diagnostics.d.ts.map +1 -1
- package/dist/health/diagnostics.js +48 -0
- package/dist/health/health.d.ts +34 -0
- package/dist/health/health.d.ts.map +1 -1
- package/dist/health/health.js +54 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/logging/json-logger.d.ts +5 -0
- package/dist/logging/json-logger.d.ts.map +1 -1
- package/dist/logging/json-logger.js +6 -0
- package/dist/logging/logger.d.ts +35 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +69 -5
- package/dist/module-graph.d.ts +16 -0
- package/dist/module-graph.d.ts.map +1 -1
- package/dist/module-graph.js +304 -8
- package/dist/node/internal-node-compression.d.ts +15 -0
- package/dist/node/internal-node-compression.d.ts.map +1 -1
- package/dist/node/internal-node-compression.js +16 -0
- package/dist/node/internal-node-request.d.ts +128 -0
- package/dist/node/internal-node-request.d.ts.map +1 -1
- package/dist/node/internal-node-request.js +321 -40
- package/dist/node/internal-node-response.d.ts +21 -1
- package/dist/node/internal-node-response.d.ts.map +1 -1
- package/dist/node/internal-node-response.js +42 -3
- package/dist/node/internal-node.d.ts +43 -6
- package/dist/node/internal-node.d.ts.map +1 -1
- package/dist/node/internal-node.js +65 -9
- package/dist/node/node-request.d.ts +1 -1
- package/dist/node/node-request.d.ts.map +1 -1
- package/dist/node/node-request.js +1 -1
- package/dist/platform-shell.d.ts +4 -0
- package/dist/platform-shell.d.ts.map +1 -1
- package/dist/platform-shell.js +72 -20
- package/dist/request-transaction.d.ts +28 -0
- package/dist/request-transaction.d.ts.map +1 -1
- package/dist/request-transaction.js +33 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web.d.ts +9 -1
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +207 -56
- package/package.json +6 -6
package/dist/web.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BadRequestException, createErrorResponse, HttpException, InternalServerErrorException, PayloadTooLargeException } from '@fluojs/http';
|
|
2
|
+
import { attachFrameworkRequestNativeRouteHandoff, consumeRawRequestNativeRouteHandoff } from '@fluojs/http/internal';
|
|
2
3
|
import { parseMultipart } from './multipart.js';
|
|
3
4
|
import { dispatchWithRequestResponseFactory } from './adapters/request-response-factory.js';
|
|
4
5
|
const DEFAULT_MAX_BODY_SIZE = 1 * 1024 * 1024;
|
|
@@ -93,12 +94,12 @@ class MutableWebFrameworkResponse {
|
|
|
93
94
|
statusCode;
|
|
94
95
|
statusSet;
|
|
95
96
|
finalizedResponse;
|
|
96
|
-
responseStream
|
|
97
|
-
this.streamActive = true;
|
|
98
|
-
});
|
|
97
|
+
responseStream;
|
|
99
98
|
responseBody;
|
|
100
99
|
streamActive = false;
|
|
101
|
-
stream
|
|
100
|
+
get stream() {
|
|
101
|
+
return this.getOrCreateResponseStream();
|
|
102
|
+
}
|
|
102
103
|
redirect(status, location) {
|
|
103
104
|
this.setStatus(status);
|
|
104
105
|
this.setHeader('Location', location);
|
|
@@ -116,6 +117,17 @@ class MutableWebFrameworkResponse {
|
|
|
116
117
|
this.responseBody = serialized.payload;
|
|
117
118
|
this.committed = true;
|
|
118
119
|
}
|
|
120
|
+
async sendSimpleJson(body) {
|
|
121
|
+
if (this.finalizedResponse) {
|
|
122
|
+
this.committed = true;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!hasHeader(this.headers, 'content-type')) {
|
|
126
|
+
this.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
127
|
+
}
|
|
128
|
+
this.responseBody = JSON.stringify(body);
|
|
129
|
+
this.committed = true;
|
|
130
|
+
}
|
|
119
131
|
setHeader(name, value) {
|
|
120
132
|
const existingHeaderName = findHeaderName(this.headers, name) ?? name;
|
|
121
133
|
if (name.toLowerCase() === 'set-cookie') {
|
|
@@ -134,13 +146,19 @@ class MutableWebFrameworkResponse {
|
|
|
134
146
|
headers: toResponseHeaders(this.headers),
|
|
135
147
|
status: this.statusCode ?? 200
|
|
136
148
|
};
|
|
137
|
-
const
|
|
138
|
-
this.finalizedResponse = this.streamActive ? new Response(this.
|
|
149
|
+
const nativeResponseBody = isResponseBodyForbidden(init.status) ? undefined : this.responseBody === undefined ? '' : this.responseBody;
|
|
150
|
+
this.finalizedResponse = this.streamActive ? new Response(this.getOrCreateResponseStream().readable, init) : new Response(nativeResponseBody, init);
|
|
139
151
|
this.raw = this.finalizedResponse;
|
|
140
152
|
this.committed = true;
|
|
141
153
|
}
|
|
142
154
|
return this.finalizedResponse;
|
|
143
155
|
}
|
|
156
|
+
getOrCreateResponseStream() {
|
|
157
|
+
this.responseStream ??= new WebResponseStream(() => {
|
|
158
|
+
this.streamActive = true;
|
|
159
|
+
});
|
|
160
|
+
return this.responseStream;
|
|
161
|
+
}
|
|
144
162
|
}
|
|
145
163
|
|
|
146
164
|
/**
|
|
@@ -152,7 +170,10 @@ class MutableWebFrameworkResponse {
|
|
|
152
170
|
export function createWebRequestResponseFactory(options = {}) {
|
|
153
171
|
return {
|
|
154
172
|
async createRequest(request, signal) {
|
|
155
|
-
return
|
|
173
|
+
return createDeferredWebFrameworkRequest(request, signal, options.multipart, options.maxBodySize ?? DEFAULT_MAX_BODY_SIZE, options.rawBody ?? false, options.preferNativeJsonBodyReader ?? false, options.consumeOriginalBody ?? false);
|
|
174
|
+
},
|
|
175
|
+
materializeRequest(request) {
|
|
176
|
+
return materializeWebFrameworkRequestBody(request);
|
|
156
177
|
},
|
|
157
178
|
createRequestSignal(signal) {
|
|
158
179
|
return signal ?? new AbortController().signal;
|
|
@@ -180,13 +201,14 @@ export function createWebRequestResponseFactory(options = {}) {
|
|
|
180
201
|
export async function dispatchWebRequest({
|
|
181
202
|
dispatcher,
|
|
182
203
|
dispatcherNotReadyMessage = 'Web adapter received a request before dispatcher binding completed.',
|
|
204
|
+
factory,
|
|
183
205
|
request,
|
|
184
206
|
...options
|
|
185
207
|
}) {
|
|
186
208
|
const frameworkResponse = await dispatchWithRequestResponseFactory({
|
|
187
209
|
dispatcher,
|
|
188
210
|
dispatcherNotReadyMessage,
|
|
189
|
-
factory: createWebRequestResponseFactory(options),
|
|
211
|
+
factory: factory ?? createWebRequestResponseFactory(options),
|
|
190
212
|
rawRequest: request,
|
|
191
213
|
rawResponse: request.signal
|
|
192
214
|
});
|
|
@@ -204,61 +226,176 @@ export async function dispatchWebRequest({
|
|
|
204
226
|
* @returns The normalized framework request used by the dispatcher.
|
|
205
227
|
*/
|
|
206
228
|
export async function createWebFrameworkRequest(request, signal, multipartOptions, maxBodySize = DEFAULT_MAX_BODY_SIZE, preserveRawBody = false) {
|
|
229
|
+
const frameworkRequest = createDeferredWebFrameworkRequest(request, signal, multipartOptions, maxBodySize, preserveRawBody);
|
|
230
|
+
await materializeWebFrameworkRequestBody(frameworkRequest);
|
|
231
|
+
return frameworkRequest;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Creates the cheap Web framework request shell before consuming the body stream.
|
|
236
|
+
*
|
|
237
|
+
* @param request - Native Web request to normalize.
|
|
238
|
+
* @param signal - Abort signal propagated to the framework request.
|
|
239
|
+
* @param multipartOptions - Multipart parser options applied when materializing multipart requests.
|
|
240
|
+
* @param maxBodySize - Maximum allowed non-multipart body size in bytes.
|
|
241
|
+
* @param preserveRawBody - Whether materialization should retain raw request body bytes.
|
|
242
|
+
* @returns The framework request shell with metadata snapshotted and body materialization deferred.
|
|
243
|
+
*/
|
|
244
|
+
function createDeferredWebFrameworkRequest(request, signal, multipartOptions, maxBodySize = DEFAULT_MAX_BODY_SIZE, preserveRawBody = false, preferNativeJsonBodyReader = false, consumeOriginalBody = false) {
|
|
207
245
|
const url = new URL(request.url);
|
|
208
|
-
const
|
|
209
|
-
const
|
|
246
|
+
const requestHeaders = new Headers(request.headers);
|
|
247
|
+
const method = request.method;
|
|
248
|
+
const headers = createMemoizedValue(() => cloneWebHeaders(requestHeaders));
|
|
249
|
+
const cookies = createMemoizedValue(() => parseCookieHeader(requestHeaders.get('cookie') ?? undefined));
|
|
250
|
+
const query = createMemoizedValue(() => parseQueryString(url.search));
|
|
251
|
+
const contentType = requestHeaders.get('content-type') ?? undefined;
|
|
210
252
|
const isMultipart = typeof contentType === 'string' && contentType.includes('multipart/form-data');
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
253
|
+
const hasRequestBody = request.body !== null;
|
|
254
|
+
const materializeBody = hasRequestBody ? createMemoizedAsyncValue(async () => {
|
|
255
|
+
if (isMultipart) {
|
|
256
|
+
const materializedRequest = request.clone();
|
|
257
|
+
const result = await parseMultipart(createRequestWithSnapshotMetadata(materializedRequest, request.url, method, requestHeaders), {
|
|
258
|
+
...multipartOptions,
|
|
259
|
+
maxTotalSize: multipartOptions?.maxTotalSize ?? maxBodySize
|
|
260
|
+
});
|
|
261
|
+
frameworkRequest.body = result.fields;
|
|
262
|
+
frameworkRequest.files = result.files;
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
validateWebRequestContentLength(request, maxBodySize);
|
|
266
|
+
if (!request.body) {
|
|
267
|
+
frameworkRequest.body = undefined;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const requestToRead = consumeOriginalBody ? request : request.clone();
|
|
271
|
+
const bodyResult = await readWebRequestBody(requestToRead, contentType, maxBodySize, preserveRawBody, preferNativeJsonBodyReader);
|
|
272
|
+
frameworkRequest.body = bodyResult.body;
|
|
273
|
+
if (bodyResult.rawBody) {
|
|
274
|
+
frameworkRequest.rawBody = bodyResult.rawBody;
|
|
275
|
+
}
|
|
276
|
+
}) : undefined;
|
|
226
277
|
const frameworkRequest = {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
278
|
+
get cookies() {
|
|
279
|
+
return cookies();
|
|
280
|
+
},
|
|
281
|
+
get headers() {
|
|
282
|
+
return headers();
|
|
283
|
+
},
|
|
284
|
+
method,
|
|
231
285
|
params: {},
|
|
232
286
|
path: url.pathname,
|
|
233
|
-
query
|
|
287
|
+
get query() {
|
|
288
|
+
return query();
|
|
289
|
+
},
|
|
234
290
|
raw: request,
|
|
291
|
+
requestId: requestHeaders.get('x-request-id') ?? undefined,
|
|
235
292
|
signal,
|
|
236
|
-
url: url.pathname + url.search
|
|
293
|
+
url: url.pathname + url.search,
|
|
294
|
+
materializeBody
|
|
237
295
|
};
|
|
238
|
-
if (
|
|
239
|
-
frameworkRequest.
|
|
296
|
+
if (!hasRequestBody) {
|
|
297
|
+
frameworkRequest.body = undefined;
|
|
240
298
|
}
|
|
241
|
-
|
|
242
|
-
|
|
299
|
+
const nativeRouteHandoff = consumeRawRequestNativeRouteHandoff(request);
|
|
300
|
+
return nativeRouteHandoff ? attachFrameworkRequestNativeRouteHandoff(frameworkRequest, nativeRouteHandoff) : frameworkRequest;
|
|
301
|
+
}
|
|
302
|
+
function createRequestWithSnapshotMetadata(request, url, method, headers) {
|
|
303
|
+
const init = {
|
|
304
|
+
headers: new Headers(headers),
|
|
305
|
+
method
|
|
306
|
+
};
|
|
307
|
+
if (request.body) {
|
|
308
|
+
init.body = request.body;
|
|
309
|
+
init.duplex = 'half';
|
|
243
310
|
}
|
|
244
|
-
return
|
|
311
|
+
return new Request(url, init);
|
|
245
312
|
}
|
|
246
|
-
function
|
|
313
|
+
function validateWebRequestContentLength(request, maxBodySize) {
|
|
314
|
+
const contentLength = request.headers.get('content-length');
|
|
315
|
+
if (contentLength === null) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const parsedContentLength = Number(contentLength);
|
|
319
|
+
if (Number.isFinite(parsedContentLength) && parsedContentLength > maxBodySize) {
|
|
320
|
+
throw new PayloadTooLargeException(REQUEST_BODY_LIMIT_MESSAGE);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Materializes a deferred Web framework request body exactly once.
|
|
326
|
+
*
|
|
327
|
+
* @param request - Framework request returned by {@link createDeferredWebFrameworkRequest}.
|
|
328
|
+
* @returns A promise that settles after body, rawBody, and files fields are populated when applicable.
|
|
329
|
+
*/
|
|
330
|
+
async function materializeWebFrameworkRequestBody(request) {
|
|
331
|
+
await request.materializeBody?.();
|
|
332
|
+
delete request.materializeBody;
|
|
333
|
+
}
|
|
334
|
+
function createMemoizedValue(factory) {
|
|
335
|
+
let initialized = false;
|
|
336
|
+
let value;
|
|
337
|
+
return () => {
|
|
338
|
+
if (!initialized) {
|
|
339
|
+
value = factory();
|
|
340
|
+
initialized = true;
|
|
341
|
+
}
|
|
342
|
+
return value;
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function createMemoizedAsyncValue(factory) {
|
|
346
|
+
let promise;
|
|
347
|
+
return () => {
|
|
348
|
+
promise ??= factory();
|
|
349
|
+
return promise;
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function parseQueryString(search) {
|
|
247
353
|
const query = {};
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
354
|
+
if (search.length <= 1) {
|
|
355
|
+
return query;
|
|
356
|
+
}
|
|
357
|
+
let index = search.charCodeAt(0) === 63 ? 1 : 0;
|
|
358
|
+
while (index <= search.length) {
|
|
359
|
+
let nextDelimiter = search.indexOf('&', index);
|
|
360
|
+
if (nextDelimiter === -1) {
|
|
361
|
+
nextDelimiter = search.length;
|
|
253
362
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
363
|
+
const entry = search.slice(index, nextDelimiter);
|
|
364
|
+
if (entry.length > 0) {
|
|
365
|
+
const separatorIndex = entry.indexOf('=');
|
|
366
|
+
const rawKey = separatorIndex === -1 ? entry : entry.slice(0, separatorIndex);
|
|
367
|
+
const rawValue = separatorIndex === -1 ? '' : entry.slice(separatorIndex + 1);
|
|
368
|
+
const key = decodeQueryComponent(rawKey, 'key');
|
|
369
|
+
const value = decodeQueryComponent(rawValue, 'value');
|
|
370
|
+
const current = query[key];
|
|
371
|
+
if (current === undefined) {
|
|
372
|
+
query[key] = value;
|
|
373
|
+
} else if (Array.isArray(current)) {
|
|
374
|
+
current.push(value);
|
|
375
|
+
} else {
|
|
376
|
+
query[key] = [current, value];
|
|
377
|
+
}
|
|
257
378
|
}
|
|
258
|
-
|
|
379
|
+
index = nextDelimiter + 1;
|
|
259
380
|
}
|
|
260
381
|
return query;
|
|
261
382
|
}
|
|
383
|
+
function decodeQueryComponent(value, kind) {
|
|
384
|
+
const normalizedValue = value.includes('+') ? value.replaceAll('+', ' ') : value;
|
|
385
|
+
try {
|
|
386
|
+
return decodeURIComponent(normalizedValue);
|
|
387
|
+
} catch {
|
|
388
|
+
return decodeQueryComponentLikeUrlSearchParams(value, kind);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function decodeQueryComponentLikeUrlSearchParams(value, kind) {
|
|
392
|
+
if (kind === 'key') {
|
|
393
|
+
const params = new URLSearchParams(`${value}=`);
|
|
394
|
+
return params.keys().next().value ?? '';
|
|
395
|
+
}
|
|
396
|
+
const params = new URLSearchParams(`x=${value}`);
|
|
397
|
+
return params.get('x') ?? '';
|
|
398
|
+
}
|
|
262
399
|
function cloneWebHeaders(headers) {
|
|
263
400
|
const clonedHeaders = {};
|
|
264
401
|
for (const [name, value] of headers.entries()) {
|
|
@@ -285,20 +422,23 @@ function parseCookieHeader(cookieHeader) {
|
|
|
285
422
|
return [pair.slice(0, index).trim(), decodeCookieValue(pair.slice(index + 1).trim())];
|
|
286
423
|
}));
|
|
287
424
|
}
|
|
288
|
-
async function readWebRequestBody(request, contentType, maxBodySize = DEFAULT_MAX_BODY_SIZE, preserveRawBody = false) {
|
|
289
|
-
|
|
290
|
-
if (contentLength !== null) {
|
|
291
|
-
const parsedContentLength = Number(contentLength);
|
|
292
|
-
if (Number.isFinite(parsedContentLength) && parsedContentLength > maxBodySize) {
|
|
293
|
-
throw new PayloadTooLargeException(REQUEST_BODY_LIMIT_MESSAGE);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
425
|
+
async function readWebRequestBody(request, contentType, maxBodySize = DEFAULT_MAX_BODY_SIZE, preserveRawBody = false, preferNativeJsonBodyReader = false) {
|
|
426
|
+
validateWebRequestContentLength(request, maxBodySize);
|
|
296
427
|
if (!request.body) {
|
|
297
428
|
return {
|
|
298
429
|
body: undefined
|
|
299
430
|
};
|
|
300
431
|
}
|
|
301
|
-
|
|
432
|
+
if (!preserveRawBody && isJsonContentType(contentType) && (preferNativeJsonBodyReader || isContentLengthWithinLimit(request, maxBodySize))) {
|
|
433
|
+
const rawBody = new Uint8Array(await request.arrayBuffer());
|
|
434
|
+
if (rawBody.byteLength > maxBodySize) {
|
|
435
|
+
throw new PayloadTooLargeException(REQUEST_BODY_LIMIT_MESSAGE);
|
|
436
|
+
}
|
|
437
|
+
return parseWebRequestRawBody(rawBody, contentType, preserveRawBody);
|
|
438
|
+
}
|
|
439
|
+
return parseWebRequestRawBody(await readByteLimitedStream(request.body, maxBodySize), contentType, preserveRawBody);
|
|
440
|
+
}
|
|
441
|
+
function parseWebRequestRawBody(rawBody, contentType, preserveRawBody) {
|
|
302
442
|
if (rawBody.byteLength === 0) {
|
|
303
443
|
return {
|
|
304
444
|
body: undefined
|
|
@@ -311,7 +451,7 @@ async function readWebRequestBody(request, contentType, maxBodySize = DEFAULT_MA
|
|
|
311
451
|
rawBody: preserveRawBody ? rawBody : undefined
|
|
312
452
|
};
|
|
313
453
|
}
|
|
314
|
-
if (
|
|
454
|
+
if (isJsonContentType(contentType)) {
|
|
315
455
|
try {
|
|
316
456
|
return {
|
|
317
457
|
body: JSON.parse(bodyText),
|
|
@@ -326,6 +466,14 @@ async function readWebRequestBody(request, contentType, maxBodySize = DEFAULT_MA
|
|
|
326
466
|
rawBody: preserveRawBody ? rawBody : undefined
|
|
327
467
|
};
|
|
328
468
|
}
|
|
469
|
+
function isContentLengthWithinLimit(request, maxBodySize) {
|
|
470
|
+
const contentLength = request.headers.get('content-length');
|
|
471
|
+
if (contentLength === null) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
const parsedContentLength = Number(contentLength);
|
|
475
|
+
return Number.isFinite(parsedContentLength) && parsedContentLength > 0 && parsedContentLength <= maxBodySize;
|
|
476
|
+
}
|
|
329
477
|
async function readByteLimitedStream(stream, maxBodySize) {
|
|
330
478
|
const reader = stream.getReader();
|
|
331
479
|
const chunks = [];
|
|
@@ -376,6 +524,9 @@ function findHeaderName(headers, name) {
|
|
|
376
524
|
function hasHeader(headers, name) {
|
|
377
525
|
return findHeaderName(headers, name) !== undefined;
|
|
378
526
|
}
|
|
527
|
+
function isResponseBodyForbidden(status) {
|
|
528
|
+
return status === 204 || status === 205 || status === 304;
|
|
529
|
+
}
|
|
379
530
|
function toResponseHeaders(headers) {
|
|
380
531
|
const responseHeaders = new Headers();
|
|
381
532
|
for (const [name, value] of Object.entries(headers)) {
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"module-graph",
|
|
10
10
|
"orchestration"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.0.0-beta.
|
|
12
|
+
"version": "1.0.0-beta.11",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"dist"
|
|
68
68
|
],
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@fluojs/
|
|
71
|
-
"@fluojs/
|
|
72
|
-
"@fluojs/di": "^1.0.0-beta.
|
|
73
|
-
"@fluojs/http": "^1.0.0-beta.
|
|
70
|
+
"@fluojs/config": "^1.0.0-beta.6",
|
|
71
|
+
"@fluojs/core": "^1.0.0-beta.4",
|
|
72
|
+
"@fluojs/di": "^1.0.0-beta.6",
|
|
73
|
+
"@fluojs/http": "^1.0.0-beta.10"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"vitest": "^3.2.4",
|
|
77
|
-
"@fluojs/serialization": "^1.0.0-beta.
|
|
77
|
+
"@fluojs/serialization": "^1.0.0-beta.5"
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
80
|
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|