json-rest-api 1.0.6 → 1.0.8
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/.claude/agents/library-guide-expert.md +29 -0
- package/.claude/agents/rest-api-internals-expert.md +53 -0
- package/CLAUDE.md +139 -1
- package/README.md +2 -5
- package/docTest.js +238 -0
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +955 -0
- package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +54 -0
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +750 -0
- package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +494 -0
- package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +398 -0
- package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +882 -0
- package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +709 -0
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +1233 -0
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +796 -0
- package/{README_X_Relationship_Plugin.md → docs/GUIDE/GUIDE_2_9_Relationships_Urls.md} +1 -4
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +66 -0
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +1246 -0
- package/docs/GUIDE/GUIDE_5_Non-Db_Stores.md +0 -0
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +1490 -0
- package/{README_X_SocketIO.md → docs/GUIDE/GUIDE_X_SocketIO.md} +17 -17
- package/docs/GUIDE/index.md +58 -0
- package/docs/GUIDE.md +61 -2238
- package/docs/ONBOARDING/Computed_Properties_And_Sparse_Fields.md +398 -0
- package/docs/README.md +57 -2239
- package/{README_2_Computed_and_hidden_fields.md → docs/README_VARIOUS/GUIDE_2_Computed_and_hidden_fields.md} +22 -17
- package/docs/README_VARIOUS/GUIDE_IN_DOCS.md +2277 -0
- package/{README.ORIG.md → docs/README_VARIOUS/README.ORIG.md} +8 -8
- package/{README_8_Polymorphic_Relationships.md → docs/README_VARIOUS/README_8_Polymorphic_Relationships.md} +1 -1
- package/docs/README_VARIOUS/README_IN_DOCS.ms +2277 -0
- package/{RELATIONSHIPS_ADVANCED.md → docs/README_VARIOUS/RELATIONSHIPS_ADVANCED.md} +3 -3
- package/{correct-schema-format.md → docs/README_VARIOUS/correct-schema-format.md} +13 -13
- package/{pagination.md → docs/README_VARIOUS/pagination.md} +11 -8
- package/docs/assets/css/style.scss +78 -5
- package/docs/index.md +2 -12
- package/helper-reorganization-plan.md +85 -0
- package/helper-usage-analysis.md +94 -0
- package/package.json +5 -4
- package/plugins/core/bulk-operations-plugin.js +2 -2
- package/plugins/core/connectors/express-plugin.js +99 -33
- package/plugins/core/lib/querying/knex-cross-table-search.js +609 -0
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +491 -0
- package/plugins/core/lib/querying/knex-pagination-helpers.js +544 -0
- package/plugins/core/lib/{knex-process-includes.js → querying/knex-process-includes.js} +65 -50
- package/plugins/core/lib/querying/knex-query-helpers-base.js +74 -0
- package/plugins/core/lib/{knex-query-helpers.js → querying/knex-query-helpers.js} +416 -180
- package/plugins/core/lib/{knex-relationship-includes.js → querying/knex-relationship-includes.js} +430 -114
- package/plugins/core/lib/querying/knex-window-queries.js +328 -0
- package/plugins/core/lib/querying-writing/compile-schemas.js +328 -0
- package/plugins/core/{utils → lib/querying-writing}/connectors-query-parser.js +62 -57
- package/plugins/core/lib/{database-capabilities.js → querying-writing/database-capabilities.js} +113 -7
- package/plugins/core/lib/querying-writing/database-value-normalizers.js +369 -0
- package/plugins/core/lib/querying-writing/default-data-helpers.js +72 -0
- package/plugins/core/{utils → lib/querying-writing}/field-utils.js +41 -31
- package/plugins/core/{utils → lib/querying-writing}/knex-constants.js +1 -0
- package/plugins/core/lib/{knex-field-helpers.js → querying-writing/knex-field-helpers.js} +190 -57
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +162 -0
- package/plugins/core/lib/{payload-validators.js → querying-writing/payload-validators.js} +297 -217
- package/plugins/core/lib/querying-writing/schema-helpers.js +497 -0
- package/plugins/core/lib/querying-writing/scope-validations.js +431 -0
- package/plugins/core/lib/{simplified-helpers.js → querying-writing/simplified-helpers.js} +216 -176
- package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +110 -0
- package/plugins/core/lib/writing/many-to-many-manipulations.js +300 -0
- package/plugins/core/lib/writing/relationship-processor.js +252 -0
- package/plugins/core/rest-api-knex-plugin.js +183 -62
- package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +7 -0
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +72 -0
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +102 -0
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +50 -0
- package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +39 -0
- package/plugins/core/rest-api-plugin-methods/add-route.js +23 -0
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +18 -0
- package/plugins/core/rest-api-plugin-methods/common.js +605 -0
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +115 -0
- package/plugins/core/rest-api-plugin-methods/delete.js +109 -0
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +186 -0
- package/plugins/core/rest-api-plugin-methods/get-related.js +295 -0
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +62 -0
- package/plugins/core/rest-api-plugin-methods/get.js +187 -0
- package/plugins/core/rest-api-plugin-methods/patch-relationship.js +56 -0
- package/plugins/core/rest-api-plugin-methods/patch.js +193 -0
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +104 -0
- package/plugins/core/rest-api-plugin-methods/post.js +157 -0
- package/plugins/core/rest-api-plugin-methods/put.js +257 -0
- package/plugins/core/rest-api-plugin-methods/query.js +208 -0
- package/plugins/core/rest-api-plugin.js +108 -2498
- package/plugins/core/socketio-plugin.js +28 -5
- package/plugins/storage/local-storage.js +2 -2
- package/tests/computed-fields.test.js +483 -0
- package/tests/cors.test.js +4 -4
- package/tests/curl.test.js +5 -4
- package/tests/custom-idproperty-relationships.test.js +891 -0
- package/tests/field-getters.test.js +353 -0
- package/tests/field-setters.test.js +310 -0
- package/tests/fixtures/api-configs.js +800 -28
- package/tests/jwt-auth.test.js +0 -2
- package/tests/nested-includes.test.js +1 -1
- package/tests/pagination-cursor-multifield.test.js +514 -0
- package/tests/pagination-enhanced.test.js +12 -9
- package/tests/polymorphic-relationships.test.js +10 -8
- package/tests/polymorphic-simple.test.js +6 -4
- package/tests/positioning-advanced.test.js +12 -12
- package/tests/positioning-extended.test.js +25 -25
- package/tests/positioning-multifilter.test.js +24 -24
- package/tests/positioning.test.js +3 -3
- package/tests/query-limits.test.js +24 -8
- package/tests/relationship-endpoints.test.js +4 -5
- package/tests/relationships.test.js +0 -1
- package/tests/socketio.test.js +12 -1
- package/tests/virtual-fields.test.js +13 -13
- package/PLAN_FOR_WEBSOCKETS.md +0 -398
- package/README_1_Initial_Setup.md +0 -393
- package/README_X_Hooks.md +0 -647
- package/TODO_rest-api-plugin-extras.todo +0 -23
- package/connectors_ideas/express-plugin.js +0 -120
- package/connectors_ideas/http-plugin.js +0 -138
- package/docs/examples/express-plugin.js +0 -366
- package/example.js +0 -301
- package/plugins/core/HELPER_MODULES.md +0 -285
- package/plugins/core/lib/compile-schemas.js +0 -245
- package/plugins/core/lib/database-value-normalizers.js +0 -192
- package/plugins/core/lib/default-data-helpers.js +0 -100
- package/plugins/core/lib/knex-cross-table-search.js +0 -442
- package/plugins/core/lib/knex-json-api-helpers.js +0 -84
- package/plugins/core/lib/knex-json-api-transformers.js +0 -449
- package/plugins/core/lib/knex-pagination-helpers.js +0 -193
- package/plugins/core/lib/knex-window-queries.js +0 -142
- package/plugins/core/lib/many-to-many-manipulations.js +0 -343
- package/plugins/core/lib/relationship-processor.js +0 -278
- package/plugins/core/lib/schema-helpers.js +0 -343
- package/plugins/core/lib/scope-validations.js +0 -252
- package/plugins/core/rest-api-relationships-plugin.js +0 -700
- package/plugins/core/utils/knex-query-helpers-base.js +0 -56
- /package/{README_X_Permissions.md → docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md} +0 -0
- /package/{README_X_Positioning.md → docs/GUIDE/GUIDE_6_Positioning.md} +0 -0
- /package/{README_X_Bulk_Operations.md → docs/GUIDE/GUIDE_X_Bulk_Operations.md} +0 -0
- /package/{README_X_Cors.md → docs/GUIDE/GUIDE_X_Cors.md} +0 -0
- /package/{README_X_Multihome.md → docs/GUIDE/GUIDE_X_Multihome.md} +0 -0
- /package/{README_X_Appendices.md → docs/GUIDE/GUIDE_Y_Appendices.md} +0 -0
- /package/{QUERY_DEPTH_PROTECTION.md → docs/README_VARIOUS/QUERY_DEPTH_PROTECTION.md} +0 -0
- /package/{RELATIONSHIPS.md → docs/README_VARIOUS/RELATIONSHIPS.md} +0 -0
- /package/{WEBSOCKET_IMPLEMENTATION_STATUS.md → docs/README_VARIOUS/WEBSOCKET_IMPLEMENTATION_STATUS.md} +0 -0
- /package/{helper-functions-chart.md → docs/README_VARIOUS/helper-functions-chart.md} +0 -0
- /package/docs/{implementation-hidden-computed-fields.md → README_VARIOUS/implementation-hidden-computed-fields.md} +0 -0
- /package/docs/{include-limits-migration-guide.md → README_VARIOUS/include-limits-migration-guide.md} +0 -0
- /package/{readmeSnippets → docs/README_VARIOUS}/test_put_behavior.js +0 -0
- /package/{readmeSnippets → docs/README_VARIOUS}/test_put_fields_without_defaults.js +0 -0
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* - File upload support with busboy or formidable
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import
|
|
18
|
-
import { parseJsonApiQuery } from '../
|
|
17
|
+
import { requirePackage } from 'hooked-api';
|
|
18
|
+
import { parseJsonApiQuery } from '../lib/querying-writing/connectors-query-parser.js';
|
|
19
19
|
import { createContext } from './lib/request-helpers.js';
|
|
20
20
|
import { createEnhancedLogger } from '../../../lib/enhanced-logger.js';
|
|
21
21
|
|
|
@@ -24,6 +24,14 @@ export const ExpressPlugin = {
|
|
|
24
24
|
dependencies: ['rest-api'],
|
|
25
25
|
|
|
26
26
|
async install({ on, vars, helpers, pluginOptions, log, scopes, api, runHooks, addHook }) {
|
|
27
|
+
// Dynamic import for Express
|
|
28
|
+
let express;
|
|
29
|
+
try {
|
|
30
|
+
express = (await import('express')).default;
|
|
31
|
+
} catch (e) {
|
|
32
|
+
requirePackage('express', 'express',
|
|
33
|
+
'Express.js is required for HTTP server functionality. This is a peer dependency.');
|
|
34
|
+
}
|
|
27
35
|
// Enhance the logger
|
|
28
36
|
const enhancedLog = createEnhancedLogger(log, {
|
|
29
37
|
logFullErrors: true,
|
|
@@ -38,14 +46,17 @@ export const ExpressPlugin = {
|
|
|
38
46
|
|
|
39
47
|
const expressOptions = pluginOptions || {};
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
// Get mountPath from options (this is now a transport concern)
|
|
50
|
+
const mountPath = expressOptions.mountPath || '';
|
|
51
|
+
const basePath = mountPath; // Keep basePath for internal use
|
|
42
52
|
const strictContentType = expressOptions.strictContentType !== false;
|
|
43
53
|
const requestSizeLimit = expressOptions.requestSizeLimit || '1mb';
|
|
44
54
|
|
|
45
55
|
// Set transport information for other plugins
|
|
46
56
|
vars.transport = {
|
|
47
57
|
type: 'express',
|
|
48
|
-
matchAll: '*' // Express wildcard pattern for matching all routes
|
|
58
|
+
matchAll: '*', // Express wildcard pattern for matching all routes
|
|
59
|
+
mountPath: mountPath // Transport-specific mount path
|
|
49
60
|
};
|
|
50
61
|
|
|
51
62
|
// Register file detector if enabled
|
|
@@ -102,6 +113,16 @@ export const ExpressPlugin = {
|
|
|
102
113
|
router.use(async (req, res, next) => {
|
|
103
114
|
const context = createContext(req, res, 'express');
|
|
104
115
|
|
|
116
|
+
// Auto-detect publicBaseUrl if not explicitly set
|
|
117
|
+
if (!vars.publicBaseUrl) {
|
|
118
|
+
// Use protocol from X-Forwarded-Proto if behind proxy, otherwise req.protocol
|
|
119
|
+
const protocol = req.get('x-forwarded-proto') || req.protocol || 'http';
|
|
120
|
+
const host = req.get('x-forwarded-host') || req.get('host');
|
|
121
|
+
if (host) {
|
|
122
|
+
vars.publicBaseUrl = `${protocol}://${host}${basePath}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
105
126
|
// Transport-specific data for hooks
|
|
106
127
|
const transportData = {
|
|
107
128
|
request: {
|
|
@@ -260,20 +281,9 @@ export const ExpressPlugin = {
|
|
|
260
281
|
// Apply any global before middleware
|
|
261
282
|
const beforeMiddleware = expressOptions.middleware?.beforeAll || [];
|
|
262
283
|
|
|
263
|
-
// Create the Express route
|
|
264
|
-
// Special handling for wildcard paths when basePath is set
|
|
265
|
-
let expressPath;
|
|
266
|
-
if (path === vars.transport.matchAll && basePath) {
|
|
267
|
-
// When we have a basePath and a wildcard, we need to use proper Express wildcard syntax
|
|
268
|
-
expressPath = basePath + '/*';
|
|
269
|
-
} else {
|
|
270
|
-
expressPath = basePath + path;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
274
284
|
try {
|
|
275
285
|
|
|
276
|
-
//
|
|
286
|
+
// Extract the handler logic into a shared function to keep it DRY (Don't Repeat Yourself).
|
|
277
287
|
const expressHandler = async (req, res) => {
|
|
278
288
|
try {
|
|
279
289
|
// Extract request data
|
|
@@ -293,10 +303,18 @@ export const ExpressPlugin = {
|
|
|
293
303
|
let responseStatus = 200;
|
|
294
304
|
if (result && typeof result.statusCode === 'number') {
|
|
295
305
|
responseStatus = result.statusCode;
|
|
296
|
-
} else if (req.method === '
|
|
297
|
-
|
|
298
|
-
} else if (req.method === 'POST') {
|
|
306
|
+
} else if (req.method === 'POST' && result) {
|
|
307
|
+
// POST with content returns 201 Created
|
|
299
308
|
responseStatus = 201;
|
|
309
|
+
} else if (req.method === 'POST' && !result) {
|
|
310
|
+
// POST without content returns 204 No Content
|
|
311
|
+
responseStatus = 204;
|
|
312
|
+
} else if (req.method === 'DELETE') {
|
|
313
|
+
// DELETE always returns 204 No Content
|
|
314
|
+
responseStatus = 204;
|
|
315
|
+
} else if ((req.method === 'PUT' || req.method === 'PATCH') && !result) {
|
|
316
|
+
// PUT/PATCH return 204 when no content is returned
|
|
317
|
+
responseStatus = 204;
|
|
300
318
|
}
|
|
301
319
|
|
|
302
320
|
// Apply headers from the handler result
|
|
@@ -318,6 +336,20 @@ export const ExpressPlugin = {
|
|
|
318
336
|
// Set content type
|
|
319
337
|
res.set('Content-Type', 'application/vnd.api+json');
|
|
320
338
|
|
|
339
|
+
// Set Location header for successful POST requests
|
|
340
|
+
if (req.method === 'POST' && context.id) {
|
|
341
|
+
// Extract scopeName from the path (e.g., /api/countries -> countries)
|
|
342
|
+
const pathParts = path.split('/');
|
|
343
|
+
const scopeName = pathParts[pathParts.length - 1];
|
|
344
|
+
|
|
345
|
+
// Set Location header for any successful POST (201 or 204)
|
|
346
|
+
if (helpers.getLocation) {
|
|
347
|
+
const location = helpers.getLocation({ scopeName, id: context.id });
|
|
348
|
+
const baseUrl = vars.publicBaseUrl || basePath;
|
|
349
|
+
res.set('Location', `${baseUrl}${location}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
321
353
|
// Handle response based on status
|
|
322
354
|
if (responseStatus === 204) {
|
|
323
355
|
res.sendStatus(204);
|
|
@@ -325,12 +357,6 @@ export const ExpressPlugin = {
|
|
|
325
357
|
// If result has a body property, that's what we should send
|
|
326
358
|
// This happens when handler returns { statusCode, body, headers }
|
|
327
359
|
const responseBody = result && result.body !== undefined ? result.body : result;
|
|
328
|
-
|
|
329
|
-
if (req.method === 'POST' && responseBody?.data?.id && helpers.getLocation) {
|
|
330
|
-
const scopeName = path.split('/')[2];
|
|
331
|
-
const location = helpers.getLocation({ scopeName, id: responseBody.data.id });
|
|
332
|
-
res.set('Location', `${basePath}/api${location}`);
|
|
333
|
-
}
|
|
334
360
|
res.status(responseStatus).json(responseBody);
|
|
335
361
|
}
|
|
336
362
|
} catch (error) {
|
|
@@ -338,35 +364,75 @@ export const ExpressPlugin = {
|
|
|
338
364
|
}
|
|
339
365
|
};
|
|
340
366
|
|
|
341
|
-
//
|
|
367
|
+
// CRITICAL: Express routing method selection - wildcard vs specific routes
|
|
368
|
+
//
|
|
369
|
+
// Express provides two different ways to register routes:
|
|
370
|
+
// 1. router.METHOD(path, handler) - e.g., router.get('/users', handler)
|
|
371
|
+
// - Only responds to the SPECIFIC HTTP method
|
|
372
|
+
// - Perfect for normal REST endpoints
|
|
373
|
+
//
|
|
374
|
+
// 2. router.use(path, handler)
|
|
375
|
+
// - Responds to ALL HTTP methods
|
|
376
|
+
// - Needed for wildcard paths that must handle any method
|
|
377
|
+
//
|
|
378
|
+
// The CORS plugin needs wildcard routes because it must handle OPTIONS
|
|
379
|
+
// requests for ANY path under the API prefix, even paths that don't exist
|
|
380
|
+
// as defined routes. For example:
|
|
381
|
+
// - Defined route: GET /api/users
|
|
382
|
+
// - Browser might send: OPTIONS /api/users/invalid/path
|
|
383
|
+
// - CORS must still respond with proper headers
|
|
384
|
+
//
|
|
342
385
|
if (path === vars.transport.matchAll) {
|
|
343
|
-
//
|
|
344
|
-
//
|
|
386
|
+
// This is a wildcard route (path = '*')
|
|
387
|
+
// We MUST use router.use() because:
|
|
388
|
+
// - We need to catch ALL paths (using '*' or '/api/*')
|
|
389
|
+
// - We need to handle a SPECIFIC method (e.g., OPTIONS)
|
|
390
|
+
// - router.options('*') would NOT work for paths like '/api/some/nested/path'
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
// Since router.use() responds to ALL methods, we need a wrapper
|
|
394
|
+
// that only handles our specific method (e.g., OPTIONS)
|
|
345
395
|
const methodSpecificMiddleware = (req, res, next) => {
|
|
346
396
|
if (req.method.toLowerCase() === method.toLowerCase()) {
|
|
347
397
|
expressHandler(req, res);
|
|
348
398
|
} else {
|
|
399
|
+
// Not our method, pass to next middleware
|
|
349
400
|
next();
|
|
350
401
|
}
|
|
351
402
|
};
|
|
403
|
+
// IMPORTANT: We do NOT need to pass a path to router.use() here!
|
|
404
|
+
// When no path is provided, router.use() matches ALL requests
|
|
405
|
+
// This is exactly what we want for wildcard routes
|
|
352
406
|
router.use(...beforeMiddleware, methodSpecificMiddleware);
|
|
353
407
|
} else {
|
|
354
|
-
//
|
|
355
|
-
router
|
|
408
|
+
// This is a normal route with a specific path (e.g., '/api/users')
|
|
409
|
+
// We use router.METHOD() because:
|
|
410
|
+
// - We want to respond to ONLY this specific HTTP method
|
|
411
|
+
// - The path is exact, not a wildcard
|
|
412
|
+
// - This is more efficient than router.use() with method checking
|
|
413
|
+
//
|
|
414
|
+
// Note: Routes from RestApiPlugin already include the full path with mountPath
|
|
415
|
+
// So we use them as-is without adding basePath to avoid double-prefixing
|
|
416
|
+
|
|
417
|
+
router[method.toLowerCase()](path, ...beforeMiddleware, expressHandler);
|
|
356
418
|
}
|
|
357
419
|
|
|
358
420
|
|
|
359
421
|
} catch (routeError) {
|
|
422
|
+
console.log('WWWWWWWWWWWWWWTTTTTTTTTTTTFFFFFFFFFFFFFFFFF', context)
|
|
360
423
|
console.log('[EXPRESS DEBUG] Error creating route:', {
|
|
361
424
|
error: routeError.message,
|
|
362
425
|
stack: routeError.stack,
|
|
363
|
-
path:
|
|
426
|
+
path: path,
|
|
364
427
|
method: method.toLowerCase()
|
|
365
428
|
});
|
|
366
429
|
throw routeError;
|
|
367
430
|
}
|
|
368
431
|
|
|
369
|
-
|
|
432
|
+
const logPath = path === vars.transport.matchAll
|
|
433
|
+
? '(all paths)' // router.use() with no path matches everything
|
|
434
|
+
: path;
|
|
435
|
+
log.trace(`Express route created: ${method} ${logPath}`);
|
|
370
436
|
});
|
|
371
437
|
|
|
372
438
|
// Apply global middleware if configured
|
|
@@ -381,7 +447,7 @@ export const ExpressPlugin = {
|
|
|
381
447
|
// Set up 404 handler in separate router (unless disabled)
|
|
382
448
|
if (expressOptions.handle404 !== false) {
|
|
383
449
|
notFoundRouter.use(async (req, res, next) => {
|
|
384
|
-
if (req.path.startsWith(
|
|
450
|
+
if (basePath && req.path.startsWith(basePath)) {
|
|
385
451
|
// Create minimal context for 404
|
|
386
452
|
const context = createContext(req, res, 'express');
|
|
387
453
|
const transportData = {
|