@carbonorm/carbonnode 3.8.0 → 3.8.2
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/dist/api/axiosInstance.d.ts +3 -2
- package/dist/index.cjs.js +50 -12
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +50 -13
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/expressServer.e2e.test.ts +29 -0
- package/src/__tests__/sakila-db/C6.js +7 -4
- package/src/__tests__/sakila-db/C6.ts +11 -6
- package/src/api/axiosInstance.ts +28 -2
- package/src/api/handlers/ExpressHandler.ts +19 -2
- package/dist/api/handlers/createTestServer.d.ts +0 -8
|
@@ -59,7 +59,7 @@ CREATE TABLE `actor` (
|
|
|
59
59
|
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
60
60
|
PRIMARY KEY (`actor_id`),
|
|
61
61
|
KEY `idx_actor_last_name` (`last_name`)
|
|
62
|
-
) ENGINE=InnoDB AUTO_INCREMENT=
|
|
62
|
+
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
63
63
|
**/
|
|
64
64
|
|
|
65
65
|
export interface iActor {
|
|
@@ -2009,7 +2009,7 @@ export type RestTableInterfaces = iActor
|
|
|
2009
2009
|
|
|
2010
2010
|
export const C6 : iC6Object<RestTableInterfaces> = {
|
|
2011
2011
|
...C6Constants,
|
|
2012
|
-
C6VERSION: '3.
|
|
2012
|
+
C6VERSION: '3.8.2',
|
|
2013
2013
|
IMPORT: async (tableName: string) : Promise<iDynamicApiImport> => {
|
|
2014
2014
|
|
|
2015
2015
|
tableName = tableName.toLowerCase();
|
|
@@ -2028,10 +2028,15 @@ export const C6 : iC6Object<RestTableInterfaces> = {
|
|
|
2028
2028
|
}
|
|
2029
2029
|
}
|
|
2030
2030
|
// This will rightfully throw a dynamic import warning in the console, but it is necessary to use dynamic imports
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2031
|
+
const toPascalUnderscore = (name: string) =>
|
|
2032
|
+
name
|
|
2033
|
+
.split("_")
|
|
2034
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
2035
|
+
.join("_");
|
|
2036
|
+
|
|
2037
|
+
return import(
|
|
2038
|
+
/* @vite-ignore */ `./${toPascalUnderscore(tableName)}.ts`
|
|
2039
|
+
);
|
|
2035
2040
|
},
|
|
2036
2041
|
PREFIX: RestTablePrefix,
|
|
2037
2042
|
TABLES: TABLES,
|
package/src/api/axiosInstance.ts
CHANGED
|
@@ -3,6 +3,15 @@ import axios from "axios";
|
|
|
3
3
|
import Qs from "qs";
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
export const carbonNodeQsStringify = (params: any): string =>
|
|
7
|
+
Qs.stringify(params, {
|
|
8
|
+
arrayFormat: "indices",
|
|
9
|
+
indices: true,
|
|
10
|
+
skipNulls: false,
|
|
11
|
+
strictNullHandling: true,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
|
|
6
15
|
// updating these values
|
|
7
16
|
// @link https://github.com/axios/axios/issues/209
|
|
8
17
|
//
|
|
@@ -11,7 +20,8 @@ import Qs from "qs";
|
|
|
11
20
|
//
|
|
12
21
|
// immediately affects this instance
|
|
13
22
|
// axiosInstance.defaults.headers['Auth-Token'] = 'foo bar';
|
|
14
|
-
|
|
23
|
+
|
|
24
|
+
const axiosInstance = (axios.create({
|
|
15
25
|
|
|
16
26
|
// `baseURL` will be prepended to `url` unless `url` is absolute.
|
|
17
27
|
// It can be convenient to set `baseURL` for an instance of axios to pass relative URLs
|
|
@@ -37,7 +47,7 @@ export default (axios.create({
|
|
|
37
47
|
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
|
|
38
48
|
paramsSerializer: function (params) {
|
|
39
49
|
// Nested get params [][][,,,] do not serialize correctly without Qs
|
|
40
|
-
return
|
|
50
|
+
return carbonNodeQsStringify(params)
|
|
41
51
|
},
|
|
42
52
|
|
|
43
53
|
|
|
@@ -128,4 +138,20 @@ export default (axios.create({
|
|
|
128
138
|
}));
|
|
129
139
|
|
|
130
140
|
|
|
141
|
+
axiosInstance.interceptors.request.use((config) => {
|
|
142
|
+
if (config.params) {
|
|
143
|
+
const serialized = carbonNodeQsStringify(config.params);
|
|
144
|
+
if (serialized.length > 2000) {
|
|
145
|
+
// Move params into body but keep track of intended method
|
|
146
|
+
config.method = "post";
|
|
147
|
+
config.data = config.params;
|
|
148
|
+
config.params = {
|
|
149
|
+
METHOD: "GET", // 👈 explicit signal for your REST parser
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return config;
|
|
155
|
+
});
|
|
131
156
|
|
|
157
|
+
export default axiosInstance
|
|
@@ -11,10 +11,27 @@ export function ExpressHandler({C6, mysqlPool}: { C6: iC6Object, mysqlPool: Pool
|
|
|
11
11
|
|
|
12
12
|
return async (req: Request, res: Response, next: NextFunction) => {
|
|
13
13
|
try {
|
|
14
|
-
const
|
|
14
|
+
const incomingMethod = req.method.toUpperCase() as iRestMethods;
|
|
15
15
|
const table = req.params.table;
|
|
16
16
|
const primary = req.params.primary;
|
|
17
|
-
|
|
17
|
+
// Support Axios interceptor promoting large GETs to POST with ?METHOD=GET
|
|
18
|
+
const methodOverrideRaw = (req.query?.METHOD ?? req.query?.method) as unknown;
|
|
19
|
+
const methodOverride = typeof methodOverrideRaw === 'string' ? methodOverrideRaw.toUpperCase() : undefined;
|
|
20
|
+
|
|
21
|
+
const treatAsGet = incomingMethod === 'POST' && methodOverride === 'GET';
|
|
22
|
+
|
|
23
|
+
const method: iRestMethods = treatAsGet ? 'GET' : incomingMethod;
|
|
24
|
+
const payload: any = treatAsGet ? { ...(req.body as any) } : (method === 'GET' ? req.query : req.body);
|
|
25
|
+
|
|
26
|
+
// Remove transport-only METHOD flag so it never leaks into ORM parsing
|
|
27
|
+
if (treatAsGet && 'METHOD' in payload) {
|
|
28
|
+
try { delete (payload as any).METHOD } catch { /* noop */ }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Warn for unsupported overrides but continue normally
|
|
32
|
+
if (incomingMethod !== 'GET' && methodOverride && methodOverride !== 'GET') {
|
|
33
|
+
console.warn(`Ignoring unsupported METHOD override: ${methodOverride}`);
|
|
34
|
+
}
|
|
18
35
|
|
|
19
36
|
if (!(table in C6.TABLES)) {
|
|
20
37
|
res.status(400).json({error: `Invalid table: ${table}`});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Express } from "express";
|
|
2
|
-
import { Pool } from "mysql2/promise";
|
|
3
|
-
import { iC6Object } from "api/types/ormInterfaces";
|
|
4
|
-
export declare function createTestServer({ C6, mysqlPool }: {
|
|
5
|
-
C6: iC6Object;
|
|
6
|
-
mysqlPool: Pool;
|
|
7
|
-
}): Express;
|
|
8
|
-
export default createTestServer;
|