@bleedingdev/modern-js-plugin-bff 3.4.0-ultramodern.1 → 3.4.0-ultramodern.3

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.
@@ -64,6 +64,11 @@ const JS_OR_TS_EXTS = [
64
64
  '.cjs',
65
65
  '.cts'
66
66
  ];
67
+ function resolveJsOrTsEntry(entryWithoutOrWithExt) {
68
+ const extension = external_path_default().extname(entryWithoutOrWithExt);
69
+ if (JS_OR_TS_EXTS.includes(extension)) return utils_namespaceObject.fs.existsSync(entryWithoutOrWithExt) ? entryWithoutOrWithExt : void 0;
70
+ return (0, utils_namespaceObject.findExists)(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutOrWithExt}${ext}`));
71
+ }
67
72
  function normalizePrefix(prefix) {
68
73
  if ('/' === prefix) return '';
69
74
  return prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
@@ -91,7 +96,7 @@ class EffectAdapter {
91
96
  const configuredEntry = bffConfig?.effect?.entry;
92
97
  const defaultEntry = external_path_default().resolve(appDirectory || process.cwd(), apiDirectory || utils_namespaceObject.API_DIR, 'effect', 'index');
93
98
  const entryWithoutExt = configuredEntry ? external_path_default().isAbsolute(configuredEntry) ? configuredEntry : external_path_default().resolve(appDirectory || process.cwd(), configuredEntry) : defaultEntry;
94
- return (0, utils_namespaceObject.findExists)(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
99
+ return resolveJsOrTsEntry(entryWithoutExt);
95
100
  }
96
101
  isApiRequestPath(requestPath, prefix, enableHandleWeb) {
97
102
  if (!enableHandleWeb) return true;
@@ -202,6 +202,41 @@ var __webpack_exports__ = {};
202
202
  }
203
203
  });
204
204
  }
205
+ function createJsonValidationResponse(message, status = 400) {
206
+ return new Response(JSON.stringify({
207
+ message
208
+ }), {
209
+ status,
210
+ headers: {
211
+ 'content-type': 'application/json; charset=utf-8'
212
+ }
213
+ });
214
+ }
215
+ function cloneWithoutJsonBodyHeaders(request) {
216
+ const headers = new Headers(request.headers);
217
+ headers.delete('content-type');
218
+ headers.delete('content-length');
219
+ return new Request(request.url, {
220
+ method: request.method,
221
+ headers,
222
+ signal: request.signal
223
+ });
224
+ }
225
+ async function prepareJsonRequestBody(request) {
226
+ const method = normalizeItemMethod(request.method);
227
+ if ('GET' === method || 'HEAD' === method) return request;
228
+ const contentType = (request.headers.get('content-type') || '').toLowerCase();
229
+ if (!contentType.includes('application/json')) return request;
230
+ if (null === request.body) return cloneWithoutJsonBodyHeaders(request);
231
+ try {
232
+ const bodyText = await request.clone().text();
233
+ if ('' === bodyText) return cloneWithoutJsonBodyHeaders(request);
234
+ JSON.parse(bodyText);
235
+ } catch {
236
+ return createJsonValidationResponse('Invalid JSON request body');
237
+ }
238
+ return request;
239
+ }
205
240
  function toBatchItemError(id, status, message) {
206
241
  return {
207
242
  id,
@@ -459,9 +494,11 @@ var __webpack_exports__ = {};
459
494
  const withDataPlatformValidation = async (request, context)=>{
460
495
  const policyDenial = options.validateRequest?.(request);
461
496
  if (policyDenial) return policyDenial;
462
- const validationError = validateDataPlatformRequestEnvelope(request, options.dataPlatform);
497
+ const preparedRequest = await prepareJsonRequestBody(request);
498
+ if (preparedRequest instanceof Response) return preparedRequest;
499
+ const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
463
500
  if (validationError) return validationError;
464
- return httpApiHandler.handler(request, context ?? emptyEffectServiceContext);
501
+ return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
465
502
  };
466
503
  const handleBatchRequest = async (request, context)=>{
467
504
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -22,6 +22,11 @@ const JS_OR_TS_EXTS = [
22
22
  '.cjs',
23
23
  '.cts'
24
24
  ];
25
+ function resolveJsOrTsEntry(entryWithoutOrWithExt) {
26
+ const extension = path.extname(entryWithoutOrWithExt);
27
+ if (JS_OR_TS_EXTS.includes(extension)) return fs.existsSync(entryWithoutOrWithExt) ? entryWithoutOrWithExt : void 0;
28
+ return findExists(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutOrWithExt}${ext}`));
29
+ }
25
30
  function normalizePrefix(prefix) {
26
31
  if ('/' === prefix) return '';
27
32
  return prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
@@ -49,7 +54,7 @@ class EffectAdapter {
49
54
  const configuredEntry = bffConfig?.effect?.entry;
50
55
  const defaultEntry = path.resolve(appDirectory || process.cwd(), apiDirectory || API_DIR, 'effect', 'index');
51
56
  const entryWithoutExt = configuredEntry ? path.isAbsolute(configuredEntry) ? configuredEntry : path.resolve(appDirectory || process.cwd(), configuredEntry) : defaultEntry;
52
- return findExists(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
57
+ return resolveJsOrTsEntry(entryWithoutExt);
53
58
  }
54
59
  isApiRequestPath(requestPath, prefix, enableHandleWeb) {
55
60
  if (!enableHandleWeb) return true;
@@ -74,6 +74,41 @@ function createBatchValidationResponse(message, status = 400) {
74
74
  }
75
75
  });
76
76
  }
77
+ function createJsonValidationResponse(message, status = 400) {
78
+ return new Response(JSON.stringify({
79
+ message
80
+ }), {
81
+ status,
82
+ headers: {
83
+ 'content-type': 'application/json; charset=utf-8'
84
+ }
85
+ });
86
+ }
87
+ function cloneWithoutJsonBodyHeaders(request) {
88
+ const headers = new Headers(request.headers);
89
+ headers.delete('content-type');
90
+ headers.delete('content-length');
91
+ return new Request(request.url, {
92
+ method: request.method,
93
+ headers,
94
+ signal: request.signal
95
+ });
96
+ }
97
+ async function prepareJsonRequestBody(request) {
98
+ const method = normalizeItemMethod(request.method);
99
+ if ('GET' === method || 'HEAD' === method) return request;
100
+ const contentType = (request.headers.get('content-type') || '').toLowerCase();
101
+ if (!contentType.includes('application/json')) return request;
102
+ if (null === request.body) return cloneWithoutJsonBodyHeaders(request);
103
+ try {
104
+ const bodyText = await request.clone().text();
105
+ if ('' === bodyText) return cloneWithoutJsonBodyHeaders(request);
106
+ JSON.parse(bodyText);
107
+ } catch {
108
+ return createJsonValidationResponse('Invalid JSON request body');
109
+ }
110
+ return request;
111
+ }
77
112
  function toBatchItemError(id, status, message) {
78
113
  return {
79
114
  id,
@@ -331,9 +366,11 @@ function createHttpApiHandler(options) {
331
366
  const withDataPlatformValidation = async (request, context)=>{
332
367
  const policyDenial = options.validateRequest?.(request);
333
368
  if (policyDenial) return policyDenial;
334
- const validationError = validateDataPlatformRequestEnvelope(request, options.dataPlatform);
369
+ const preparedRequest = await prepareJsonRequestBody(request);
370
+ if (preparedRequest instanceof Response) return preparedRequest;
371
+ const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
335
372
  if (validationError) return validationError;
336
- return httpApiHandler.handler(request, context ?? emptyEffectServiceContext);
373
+ return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
337
374
  };
338
375
  const handleBatchRequest = async (request, context)=>{
339
376
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -24,6 +24,11 @@ const JS_OR_TS_EXTS = [
24
24
  '.cjs',
25
25
  '.cts'
26
26
  ];
27
+ function resolveJsOrTsEntry(entryWithoutOrWithExt) {
28
+ const extension = path.extname(entryWithoutOrWithExt);
29
+ if (JS_OR_TS_EXTS.includes(extension)) return fs.existsSync(entryWithoutOrWithExt) ? entryWithoutOrWithExt : void 0;
30
+ return findExists(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutOrWithExt}${ext}`));
31
+ }
27
32
  function normalizePrefix(prefix) {
28
33
  if ('/' === prefix) return '';
29
34
  return prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
@@ -51,7 +56,7 @@ class EffectAdapter {
51
56
  const configuredEntry = bffConfig?.effect?.entry;
52
57
  const defaultEntry = path.resolve(appDirectory || process.cwd(), apiDirectory || API_DIR, 'effect', 'index');
53
58
  const entryWithoutExt = configuredEntry ? path.isAbsolute(configuredEntry) ? configuredEntry : path.resolve(appDirectory || process.cwd(), configuredEntry) : defaultEntry;
54
- return findExists(JS_OR_TS_EXTS.map((ext)=>`${entryWithoutExt}${ext}`));
59
+ return resolveJsOrTsEntry(entryWithoutExt);
55
60
  }
56
61
  isApiRequestPath(requestPath, prefix, enableHandleWeb) {
57
62
  if (!enableHandleWeb) return true;
@@ -75,6 +75,41 @@ function createBatchValidationResponse(message, status = 400) {
75
75
  }
76
76
  });
77
77
  }
78
+ function createJsonValidationResponse(message, status = 400) {
79
+ return new Response(JSON.stringify({
80
+ message
81
+ }), {
82
+ status,
83
+ headers: {
84
+ 'content-type': 'application/json; charset=utf-8'
85
+ }
86
+ });
87
+ }
88
+ function cloneWithoutJsonBodyHeaders(request) {
89
+ const headers = new Headers(request.headers);
90
+ headers.delete('content-type');
91
+ headers.delete('content-length');
92
+ return new Request(request.url, {
93
+ method: request.method,
94
+ headers,
95
+ signal: request.signal
96
+ });
97
+ }
98
+ async function prepareJsonRequestBody(request) {
99
+ const method = normalizeItemMethod(request.method);
100
+ if ('GET' === method || 'HEAD' === method) return request;
101
+ const contentType = (request.headers.get('content-type') || '').toLowerCase();
102
+ if (!contentType.includes('application/json')) return request;
103
+ if (null === request.body) return cloneWithoutJsonBodyHeaders(request);
104
+ try {
105
+ const bodyText = await request.clone().text();
106
+ if ('' === bodyText) return cloneWithoutJsonBodyHeaders(request);
107
+ JSON.parse(bodyText);
108
+ } catch {
109
+ return createJsonValidationResponse('Invalid JSON request body');
110
+ }
111
+ return request;
112
+ }
78
113
  function toBatchItemError(id, status, message) {
79
114
  return {
80
115
  id,
@@ -332,9 +367,11 @@ function createHttpApiHandler(options) {
332
367
  const withDataPlatformValidation = async (request, context)=>{
333
368
  const policyDenial = options.validateRequest?.(request);
334
369
  if (policyDenial) return policyDenial;
335
- const validationError = validateDataPlatformRequestEnvelope(request, options.dataPlatform);
370
+ const preparedRequest = await prepareJsonRequestBody(request);
371
+ if (preparedRequest instanceof Response) return preparedRequest;
372
+ const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
336
373
  if (validationError) return validationError;
337
- return httpApiHandler.handler(request, context ?? emptyEffectServiceContext);
374
+ return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
338
375
  };
339
376
  const handleBatchRequest = async (request, context)=>{
340
377
  const mountedPrefix = getMountedPrefixFromContext(request, context);
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.4.0-ultramodern.1",
20
+ "version": "3.4.0-ultramodern.3",
21
21
  "types": "./dist/types/cli.d.ts",
22
22
  "main": "./dist/cjs/cli.js",
23
23
  "exports": {
@@ -142,7 +142,7 @@
142
142
  }
143
143
  },
144
144
  "dependencies": {
145
- "@effect/opentelemetry": "4.0.0-beta.84",
145
+ "@effect/opentelemetry": "4.0.0-beta.89",
146
146
  "@opentelemetry/api": "1.9.1",
147
147
  "@opentelemetry/api-logs": "0.219.0",
148
148
  "@opentelemetry/resources": "2.8.0",
@@ -154,32 +154,32 @@
154
154
  "@opentelemetry/semantic-conventions": "1.41.1",
155
155
  "@swc/core": "1.15.43",
156
156
  "@swc/helpers": "^0.5.23",
157
- "effect": "4.0.0-beta.84",
158
- "qs": "^6.15.2",
157
+ "effect": "4.0.0-beta.89",
158
+ "qs": "^6.15.3",
159
159
  "type-is": "^2.1.0",
160
- "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.4.0-ultramodern.1",
161
- "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.4.0-ultramodern.1",
162
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.4.0-ultramodern.1",
163
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.4.0-ultramodern.1",
164
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.1",
165
- "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.4.0-ultramodern.1"
160
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.4.0-ultramodern.3",
161
+ "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.4.0-ultramodern.3",
162
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.4.0-ultramodern.3",
163
+ "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.4.0-ultramodern.3",
164
+ "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.4.0-ultramodern.3",
165
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.3"
166
166
  },
167
167
  "devDependencies": {
168
- "@rsbuild/core": "2.0.15",
168
+ "@rsbuild/core": "2.1.0",
169
169
  "@rslib/core": "0.23.0",
170
- "@types/node": "^26.0.0",
170
+ "@types/node": "^26.0.1",
171
171
  "@types/qs": "^6.15.1",
172
172
  "@types/type-is": "^1.6.7",
173
173
  "@typescript/native-preview": "7.0.0-dev.20260624.1",
174
174
  "memfs": "^4.57.8",
175
175
  "typescript": "^6.0.3",
176
176
  "zod": "^4.4.3",
177
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.4.0-ultramodern.1",
178
- "@modern-js/bff-runtime": "npm:@bleedingdev/modern-js-bff-runtime@3.4.0-ultramodern.1",
179
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.4.0-ultramodern.1",
180
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.1",
181
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.1",
182
- "@scripts/rstest-config": "2.66.0"
177
+ "@modern-js/bff-runtime": "npm:@bleedingdev/modern-js-bff-runtime@3.4.0-ultramodern.3",
178
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.4.0-ultramodern.3",
179
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.3",
180
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.4.0-ultramodern.3",
181
+ "@scripts/rstest-config": "2.66.0",
182
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.3"
183
183
  },
184
184
  "sideEffects": false,
185
185
  "publishConfig": {