@carbonorm/carbonnode 5.0.0 → 6.0.0
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/convertForRequestBody.d.ts +1 -1
- package/dist/api/restOrm.d.ts +6 -6
- package/dist/api/restRequest.d.ts +2 -2
- package/dist/{api/executors → executors}/HttpExecutor.d.ts +2 -2
- package/dist/{api/handlers → handlers}/ExpressHandler.d.ts +3 -3
- package/dist/index.cjs.js +229 -160
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +30 -29
- package/dist/index.esm.js +225 -161
- package/dist/index.esm.js.map +1 -1
- package/dist/{api/types → types}/ormGenerics.d.ts +1 -1
- package/dist/{api/types → types}/ormInterfaces.d.ts +7 -6
- package/dist/{api/utils → utils}/apiHelpers.d.ts +2 -2
- package/dist/{api/utils → utils}/cacheManager.d.ts +2 -2
- package/dist/utils/sqlAllowList.d.ts +5 -0
- package/dist/utils/toastRuntime.d.ts +5 -0
- package/dist/variables/toastOptions.d.ts +10 -1
- package/package.json +2 -7
- package/scripts/assets/handlebars/C6.test.ts.handlebars +4 -8
- package/src/__tests__/binaryHex.e2e.test.ts +1 -1
- package/src/__tests__/cacheManager.test.ts +2 -3
- package/src/__tests__/expressServer.e2e.test.ts +1 -1
- package/src/__tests__/fixtures/c6.fixture.ts +1 -1
- package/src/__tests__/fixtures/createTestServer.ts +2 -2
- package/src/__tests__/fixtures/pu.fixture.ts +1 -2
- package/src/__tests__/httpExecutorSingular.e2e.test.ts +1 -1
- package/src/__tests__/normalizeSingularRequest.test.ts +3 -3
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
- package/src/__tests__/sakila-db/C6.test.ts +4 -8
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
- package/src/__tests__/sqlAllowList.test.ts +67 -74
- package/src/__tests__/sqlBuilders.complex.test.ts +3 -3
- package/src/__tests__/sqlBuilders.expressions.test.ts +2 -2
- package/src/__tests__/sqlBuilders.test.ts +5 -5
- package/src/__tests__/toastRuntime.test.ts +22 -0
- package/src/api/convertForRequestBody.ts +2 -2
- package/src/api/restOrm.ts +2 -2
- package/src/api/restRequest.ts +4 -5
- package/src/{api/executors → executors}/HttpExecutor.ts +21 -13
- package/src/{api/executors → executors}/SqlExecutor.ts +2 -2
- package/src/{api/handlers → handlers}/ExpressHandler.ts +5 -5
- package/src/index.ts +30 -29
- package/src/{api/orm → orm}/builders/AggregateBuilder.ts +1 -1
- package/src/{api/orm → orm}/builders/ConditionBuilder.ts +1 -1
- package/src/{api/orm → orm}/builders/JoinBuilder.ts +1 -1
- package/src/{api/orm → orm}/builders/PaginationBuilder.ts +1 -1
- package/src/{api/orm → orm}/queries/PostQueryBuilder.ts +1 -1
- package/src/{api/orm → orm}/queries/UpdateQueryBuilder.ts +1 -1
- package/src/{api/orm → orm}/queryHelpers.ts +1 -2
- package/src/{api/types → types}/ormGenerics.ts +1 -1
- package/src/{api/types → types}/ormInterfaces.ts +8 -6
- package/src/{api/utils → utils}/apiHelpers.ts +8 -8
- package/src/{api/utils → utils}/cacheManager.ts +2 -2
- package/src/{api/utils → utils}/normalizeSingularRequest.ts +1 -1
- package/src/utils/sqlAllowList.ts +120 -0
- package/src/{api/utils → utils}/testHelpers.ts +1 -1
- package/src/{api/utils → utils}/toastNotifier.ts +3 -3
- package/src/utils/toastRuntime.ts +22 -0
- package/src/variables/toastOptions.ts +10 -3
- package/dist/api/utils/sqlAllowList.d.ts +0 -2
- package/src/api/utils/sqlAllowList.ts +0 -54
- /package/dist/{api → constants}/C6Constants.d.ts +0 -0
- /package/dist/{api/executors → executors}/Executor.d.ts +0 -0
- /package/dist/{api/executors → executors}/SqlExecutor.d.ts +0 -0
- /package/dist/{api/orm → orm}/builders/AggregateBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/builders/ConditionBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/builders/JoinBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/builders/PaginationBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/queries/DeleteQueryBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/queries/PostQueryBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/queries/SelectQueryBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/queries/UpdateQueryBuilder.d.ts +0 -0
- /package/dist/{api/orm → orm}/queryHelpers.d.ts +0 -0
- /package/dist/{api/orm → orm}/utils/sqlUtils.d.ts +0 -0
- /package/dist/{api/types → types}/dynamicFetching.d.ts +0 -0
- /package/dist/{api/types → types}/modifyTypes.d.ts +0 -0
- /package/dist/{api/types → types}/mysqlTypes.d.ts +0 -0
- /package/dist/{api/utils → utils}/determineRuntimeJsType.d.ts +0 -0
- /package/dist/{api/utils → utils}/logger.d.ts +0 -0
- /package/dist/{api/utils → utils}/normalizeSingularRequest.d.ts +0 -0
- /package/dist/{api/utils → utils}/sortAndSerializeQueryObject.d.ts +0 -0
- /package/dist/{api/utils → utils}/testHelpers.d.ts +0 -0
- /package/dist/{api/utils → utils}/toastNotifier.d.ts +0 -0
- /package/src/{api → constants}/C6Constants.ts +0 -0
- /package/src/{api/executors → executors}/Executor.ts +0 -0
- /package/src/{api/orm → orm}/queries/DeleteQueryBuilder.ts +0 -0
- /package/src/{api/orm → orm}/queries/SelectQueryBuilder.ts +0 -0
- /package/src/{api/orm → orm}/utils/sqlUtils.ts +0 -0
- /package/src/{api/types → types}/dynamicFetching.ts +0 -0
- /package/src/{api/types → types}/modifyTypes.ts +0 -0
- /package/src/{api/types → types}/mysqlTypes.ts +0 -0
- /package/src/{api/utils → utils}/determineRuntimeJsType.ts +0 -0
- /package/src/{api/utils → utils}/logger.ts +0 -0
- /package/src/{api/utils → utils}/sortAndSerializeQueryObject.ts +0 -0
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"rest": [
|
|
3
3
|
{
|
|
4
4
|
"rental_id": 16050,
|
|
5
|
-
"rental_date": "2026-01-
|
|
5
|
+
"rental_date": "2026-01-24T05:49:17.000Z",
|
|
6
6
|
"inventory_id": 1,
|
|
7
7
|
"customer_id": 1,
|
|
8
|
-
"return_date": "2026-01-
|
|
8
|
+
"return_date": "2026-01-24T05:49:17.000Z",
|
|
9
9
|
"staff_id": 1,
|
|
10
|
-
"last_update": "2026-01-
|
|
10
|
+
"last_update": "2026-01-24T05:49:17.000Z"
|
|
11
11
|
}
|
|
12
12
|
],
|
|
13
13
|
"sql": {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {describe, expect, it, vi} from "vitest";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import {mkdir, readdir, readFile, writeFile} from "node:fs/promises";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {loadSqlAllowList, normalizeSql} from "../api/utils/sqlAllowList";
|
|
4
|
+
import {Actor, C6, GLOBAL_REST_PARAMETERS} from "./sakila-db/C6.js";
|
|
5
|
+
import {collectSqlAllowListEntries, compileSqlAllowList, extractSqlEntries, loadSqlAllowList, normalizeSql} from "../utils/sqlAllowList";
|
|
7
6
|
|
|
8
7
|
const fixturesDir = path.join(process.cwd(), "src/__tests__/fixtures/sqlResponses");
|
|
9
8
|
const fixturePath = path.join(fixturesDir, "actor.get.json");
|
|
@@ -20,31 +19,9 @@ const buildMockPool = (rows: Record<string, any>[]) => {
|
|
|
20
19
|
return {pool, connection};
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
const
|
|
24
|
-
if (Array.isArray(payload)) {
|
|
25
|
-
return payload.flatMap(extractSqlEntries);
|
|
26
|
-
}
|
|
27
|
-
if (!payload || typeof payload !== "object") {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const sqlValue = (payload as {sql?: unknown}).sql;
|
|
32
|
-
if (typeof sqlValue === "string") {
|
|
33
|
-
return [sqlValue];
|
|
34
|
-
}
|
|
35
|
-
if (sqlValue && typeof sqlValue === "object") {
|
|
36
|
-
const nested = (sqlValue as {sql?: unknown}).sql;
|
|
37
|
-
if (typeof nested === "string") {
|
|
38
|
-
return [nested];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return [];
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const compileSqlAllowList = async (): Promise<string[]> => {
|
|
22
|
+
const compileSqlAllowListFromFixtures = async (): Promise<string[]> => {
|
|
46
23
|
const entries = await readdir(fixturesDir);
|
|
47
|
-
const sqlEntries
|
|
24
|
+
const sqlEntries = new Set<string>();
|
|
48
25
|
|
|
49
26
|
for (const entry of entries) {
|
|
50
27
|
if (!entry.endsWith(".json") || entry.startsWith("sqlAllowList")) {
|
|
@@ -56,12 +33,28 @@ const compileSqlAllowList = async (): Promise<string[]> => {
|
|
|
56
33
|
if (extracted.length === 0) {
|
|
57
34
|
throw new Error(`No SQL found in fixture ${entry}`);
|
|
58
35
|
}
|
|
59
|
-
sqlEntries
|
|
36
|
+
collectSqlAllowListEntries(payload, sqlEntries);
|
|
60
37
|
}
|
|
61
38
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
return await compileSqlAllowList(compiledPath, sqlEntries);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const globalRestParameters = GLOBAL_REST_PARAMETERS as typeof GLOBAL_REST_PARAMETERS & {
|
|
43
|
+
mysqlPool?: unknown;
|
|
44
|
+
sqlAllowListPath?: string;
|
|
45
|
+
verbose?: boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const snapshotGlobals = () => ({
|
|
49
|
+
mysqlPool: globalRestParameters.mysqlPool,
|
|
50
|
+
sqlAllowListPath: globalRestParameters.sqlAllowListPath,
|
|
51
|
+
verbose: globalRestParameters.verbose,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const restoreGlobals = (snapshot: ReturnType<typeof snapshotGlobals>) => {
|
|
55
|
+
globalRestParameters.mysqlPool = snapshot.mysqlPool;
|
|
56
|
+
globalRestParameters.sqlAllowListPath = snapshot.sqlAllowListPath;
|
|
57
|
+
globalRestParameters.verbose = snapshot.verbose;
|
|
65
58
|
};
|
|
66
59
|
|
|
67
60
|
describe("SQL allowlist", () => {
|
|
@@ -72,37 +65,35 @@ describe("SQL allowlist", () => {
|
|
|
72
65
|
{actor_id: 1, first_name: "PENELOPE", last_name: "GUINESS"},
|
|
73
66
|
]);
|
|
74
67
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
mysqlPool
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
expect(allowedResponse.rest).toEqual(response.rest);
|
|
68
|
+
const originalGlobals = snapshotGlobals();
|
|
69
|
+
try {
|
|
70
|
+
globalRestParameters.mysqlPool = pool as any;
|
|
71
|
+
globalRestParameters.sqlAllowListPath = undefined;
|
|
72
|
+
globalRestParameters.verbose = false;
|
|
73
|
+
|
|
74
|
+
const response = await Actor.Get({
|
|
75
|
+
[C6.PAGINATION]: {[C6.LIMIT]: 1},
|
|
76
|
+
} as any);
|
|
77
|
+
|
|
78
|
+
await writeFile(fixturePath, JSON.stringify(response, null, 2));
|
|
79
|
+
|
|
80
|
+
const compiled = await compileSqlAllowListFromFixtures();
|
|
81
|
+
expect(compiled.length).toBeGreaterThan(0);
|
|
82
|
+
|
|
83
|
+
const allowList = await loadSqlAllowList(compiledPath);
|
|
84
|
+
const responseSql = normalizeSql((response as any).sql.sql as string);
|
|
85
|
+
expect(allowList.has(responseSql)).toBe(true);
|
|
86
|
+
|
|
87
|
+
globalRestParameters.sqlAllowListPath = compiledPath;
|
|
88
|
+
|
|
89
|
+
const allowedResponse = await Actor.Get({
|
|
90
|
+
[C6.PAGINATION]: {[C6.LIMIT]: 1},
|
|
91
|
+
} as any);
|
|
92
|
+
|
|
93
|
+
expect(allowedResponse.rest).toEqual(response.rest);
|
|
94
|
+
} finally {
|
|
95
|
+
restoreGlobals(originalGlobals);
|
|
96
|
+
}
|
|
106
97
|
});
|
|
107
98
|
|
|
108
99
|
it("throws when allowlist file is missing", async () => {
|
|
@@ -119,17 +110,19 @@ describe("SQL allowlist", () => {
|
|
|
119
110
|
{actor_id: 1, first_name: "PENELOPE", last_name: "GUINESS"},
|
|
120
111
|
]);
|
|
121
112
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
113
|
+
const originalGlobals = snapshotGlobals();
|
|
114
|
+
try {
|
|
115
|
+
globalRestParameters.mysqlPool = pool as any;
|
|
116
|
+
globalRestParameters.sqlAllowListPath = blockedPath;
|
|
117
|
+
globalRestParameters.verbose = false;
|
|
118
|
+
|
|
119
|
+
await expect(
|
|
120
|
+
Actor.Get({
|
|
121
|
+
[C6.PAGINATION]: {[C6.LIMIT]: 1},
|
|
122
|
+
} as any)
|
|
123
|
+
).rejects.toThrow("SQL statement is not permitted");
|
|
124
|
+
} finally {
|
|
125
|
+
restoreGlobals(originalGlobals);
|
|
126
|
+
}
|
|
134
127
|
});
|
|
135
128
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { C6C } from '../
|
|
3
|
-
import { SelectQueryBuilder } from '../
|
|
4
|
-
import { derivedTable, F } from '../
|
|
2
|
+
import { C6C } from '../constants/C6Constants';
|
|
3
|
+
import { SelectQueryBuilder } from '../orm/queries/SelectQueryBuilder';
|
|
4
|
+
import { derivedTable, F } from '../orm/queryHelpers';
|
|
5
5
|
import { buildParcelConfig, buildTestConfig } from './fixtures/c6.fixture';
|
|
6
6
|
|
|
7
7
|
const Property_Units = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { C6C } from '../
|
|
3
|
-
import { SelectQueryBuilder } from '../
|
|
2
|
+
import { C6C } from '../constants/C6Constants';
|
|
3
|
+
import { SelectQueryBuilder } from '../orm/queries/SelectQueryBuilder';
|
|
4
4
|
import { buildParcelConfig } from './fixtures/c6.fixture';
|
|
5
5
|
|
|
6
6
|
const Property_Units = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { C6C } from '../
|
|
3
|
-
import { SelectQueryBuilder } from '../
|
|
4
|
-
import { PostQueryBuilder } from '../
|
|
5
|
-
import { UpdateQueryBuilder } from '../
|
|
6
|
-
import { DeleteQueryBuilder } from '../
|
|
2
|
+
import { C6C } from '../constants/C6Constants';
|
|
3
|
+
import { SelectQueryBuilder } from '../orm/queries/SelectQueryBuilder';
|
|
4
|
+
import { PostQueryBuilder } from '../orm/queries/PostQueryBuilder';
|
|
5
|
+
import { UpdateQueryBuilder } from '../orm/queries/UpdateQueryBuilder';
|
|
6
|
+
import { DeleteQueryBuilder } from '../orm/queries/DeleteQueryBuilder';
|
|
7
7
|
import { buildTestConfig, buildBinaryTestConfig, buildBinaryTestConfigFqn } from './fixtures/c6.fixture';
|
|
8
8
|
|
|
9
9
|
describe('SQL Builders', () => {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {afterEach, describe, expect, it, vi} from "vitest";
|
|
2
|
+
|
|
3
|
+
import {notifyToast, setToastHandler} from "../utils/toastRuntime";
|
|
4
|
+
|
|
5
|
+
describe("toastRuntime", () => {
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
setToastHandler(null);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("no-ops when no handler is registered", () => {
|
|
11
|
+
expect(() => notifyToast("success", "hello")).not.toThrow();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("dispatches to the registered handler", () => {
|
|
15
|
+
const handler = vi.fn();
|
|
16
|
+
setToastHandler(handler);
|
|
17
|
+
|
|
18
|
+
notifyToast("error", "boom", {autoClose: 10});
|
|
19
|
+
|
|
20
|
+
expect(handler).toHaveBeenCalledWith("error", "boom", {autoClose: 10});
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C6Constants } from "
|
|
2
|
-
import {iC6Object, C6RestfulModel, iRestMethods, RequestQueryBody} from "
|
|
1
|
+
import { C6Constants } from "../constants/C6Constants";
|
|
2
|
+
import {iC6Object, C6RestfulModel, iRestMethods, RequestQueryBody} from "../types/ormInterfaces";
|
|
3
3
|
|
|
4
4
|
export default function <
|
|
5
5
|
RequestMethod extends iRestMethods,
|
package/src/api/restOrm.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import restRequest from "./restRequest";
|
|
2
|
-
import {OrmGenerics} from "
|
|
3
|
-
import {iRest, iRestMethods} from "
|
|
2
|
+
import {OrmGenerics} from "../types/ormGenerics";
|
|
3
|
+
import {iRest, iRestMethods} from "../types/ormInterfaces";
|
|
4
4
|
|
|
5
5
|
type WithMethod<G extends Omit<OrmGenerics, "RequestMethod">, M extends iRestMethods> =
|
|
6
6
|
Omit<G, "RequestMethod"> & { RequestMethod: M };
|
package/src/api/restRequest.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import isNode from '../variables/isNode';
|
|
2
|
-
import {OrmGenerics} from "
|
|
2
|
+
import {OrmGenerics} from "../types/ormGenerics";
|
|
3
3
|
import {
|
|
4
4
|
DetermineResponseDataType,
|
|
5
5
|
iRest, RequestQueryBody
|
|
6
|
-
} from "
|
|
6
|
+
} from "../types/ormInterfaces";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Facade: routes API calls to SQL or HTTP executors based on runtime context.
|
|
@@ -36,15 +36,14 @@ export default function restRequest<
|
|
|
36
36
|
|
|
37
37
|
// SQL path if on Node with a provided pool
|
|
38
38
|
if (isNode() && config.mysqlPool) {
|
|
39
|
-
const {SqlExecutor} = await import('
|
|
39
|
+
const {SqlExecutor} = await import('../executors/SqlExecutor');
|
|
40
40
|
const executor = new SqlExecutor<G>(config, request);
|
|
41
41
|
return executor.execute();
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// HTTP path fallback
|
|
45
|
-
const {HttpExecutor} = await import('
|
|
45
|
+
const {HttpExecutor} = await import('../executors/HttpExecutor');
|
|
46
46
|
const http = new HttpExecutor<G>(config, request);
|
|
47
47
|
return http.execute();
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {AxiosPromise, AxiosResponse} from "axios";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import convertForRequestBody from "../convertForRequestBody";
|
|
1
|
+
import type {AxiosPromise, AxiosResponse} from "axios";
|
|
2
|
+
import isLocal from "../variables/isLocal";
|
|
3
|
+
import isTest from "../variables/isTest";
|
|
4
|
+
import convertForRequestBody from "../api/convertForRequestBody";
|
|
6
5
|
import {eFetchDependencies} from "../types/dynamicFetching";
|
|
7
|
-
import {OrmGenerics} from "../types/ormGenerics";
|
|
6
|
+
import type {OrmGenerics} from "../types/ormGenerics";
|
|
8
7
|
import {
|
|
9
8
|
DELETE, DetermineResponseDataType,
|
|
10
9
|
GET,
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
import {removeInvalidKeys, removePrefixIfExists, TestRestfulResponse} from "../utils/apiHelpers";
|
|
17
16
|
import {checkCache, setCache, userCustomClearCache} from "../utils/cacheManager";
|
|
18
17
|
import {sortAndSerializeQueryObject} from "../utils/sortAndSerializeQueryObject";
|
|
18
|
+
import {notifyToast} from "../utils/toastRuntime";
|
|
19
19
|
import {Executor} from "./Executor";
|
|
20
20
|
import {toastOptions, toastOptionsDevs} from "variables/toastOptions";
|
|
21
21
|
|
|
@@ -260,11 +260,15 @@ export class HttpExecutor<
|
|
|
260
260
|
if (cacheResults) {
|
|
261
261
|
cachingConfirmed = true;
|
|
262
262
|
} else if (debug && isLocal()) {
|
|
263
|
-
|
|
263
|
+
notifyToast("info", "DEVS: Ignore cache was set to true.", toastOptionsDevs);
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
if (cacheResults && debug && isLocal()) {
|
|
267
|
-
|
|
267
|
+
notifyToast(
|
|
268
|
+
"success",
|
|
269
|
+
"DEVS: Request not in cache." + (requestMethod === C6.GET ? " Page (" + query[C6.PAGINATION][C6.PAGE] + ")" : ''),
|
|
270
|
+
toastOptionsDevs,
|
|
271
|
+
);
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
let apiResponse: G['RestTableInterface'][G['PrimaryKey']] | string | boolean | number | undefined;
|
|
@@ -308,7 +312,7 @@ export class HttpExecutor<
|
|
|
308
312
|
|
|
309
313
|
if (true === debug && isLocal()) {
|
|
310
314
|
|
|
311
|
-
|
|
315
|
+
notifyToast("error", `DEVS: The primary key (${primaryKey}) was not provided!!`);
|
|
312
316
|
|
|
313
317
|
}
|
|
314
318
|
|
|
@@ -319,7 +323,7 @@ export class HttpExecutor<
|
|
|
319
323
|
const providedPrimary = query?.[primaryKey!] ?? (primaryKeyFullyQualified ? query?.[primaryKeyFullyQualified] : undefined);
|
|
320
324
|
if (undefined === providedPrimary || null === providedPrimary) {
|
|
321
325
|
|
|
322
|
-
|
|
326
|
+
notifyToast("error", `The primary key (${primaryKey}) provided is undefined or null explicitly!!`);
|
|
323
327
|
|
|
324
328
|
throw Error('The primary key (' + primaryKey + ') provided in the request was exactly equal to undefined.');
|
|
325
329
|
|
|
@@ -390,7 +394,7 @@ export class HttpExecutor<
|
|
|
390
394
|
data,
|
|
391
395
|
fullTableList,
|
|
392
396
|
C6,
|
|
393
|
-
(message) =>
|
|
397
|
+
(message) => notifyToast("error", message, toastOptions)
|
|
394
398
|
);
|
|
395
399
|
|
|
396
400
|
const baseConfig = {
|
|
@@ -485,7 +489,7 @@ export class HttpExecutor<
|
|
|
485
489
|
|
|
486
490
|
if (false === apiResponse) {
|
|
487
491
|
if (debug && isLocal()) {
|
|
488
|
-
|
|
492
|
+
notifyToast("warning", "DEVS: TestRestfulResponse returned false.", toastOptionsDevs);
|
|
489
493
|
}
|
|
490
494
|
// Force a null payload so the final .then(response => response.data) yields null
|
|
491
495
|
return Promise.resolve({ ...response, data: null as unknown as ResponseDataType });
|
|
@@ -813,7 +817,11 @@ export class HttpExecutor<
|
|
|
813
817
|
|
|
814
818
|
if (debug && isLocal()) {
|
|
815
819
|
|
|
816
|
-
|
|
820
|
+
notifyToast(
|
|
821
|
+
"success",
|
|
822
|
+
`DEVS: (${requestMethod}) request complete.`,
|
|
823
|
+
toastOptionsDevs,
|
|
824
|
+
);
|
|
817
825
|
|
|
818
826
|
}
|
|
819
827
|
|
|
@@ -3,13 +3,13 @@ import {PostQueryBuilder} from "../orm/queries/PostQueryBuilder";
|
|
|
3
3
|
import {SelectQueryBuilder} from "../orm/queries/SelectQueryBuilder";
|
|
4
4
|
import {UpdateQueryBuilder} from "../orm/queries/UpdateQueryBuilder";
|
|
5
5
|
import {OrmGenerics} from "../types/ormGenerics";
|
|
6
|
-
import {C6Constants as C6C} from "../C6Constants";
|
|
6
|
+
import {C6Constants as C6C} from "../constants/C6Constants";
|
|
7
7
|
import {
|
|
8
8
|
DetermineResponseDataType,
|
|
9
9
|
iRestWebsocketPayload,
|
|
10
10
|
} from "../types/ormInterfaces";
|
|
11
11
|
import namedPlaceholders from 'named-placeholders';
|
|
12
|
-
import {PoolConnection} from 'mysql2/promise';
|
|
12
|
+
import type {PoolConnection} from 'mysql2/promise';
|
|
13
13
|
import {Buffer} from 'buffer';
|
|
14
14
|
import {Executor} from "./Executor";
|
|
15
15
|
import { normalizeSingularRequest } from "../utils/normalizeSingularRequest";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Request, Response, NextFunction} from "express";
|
|
2
|
-
import {Pool} from "mysql2/promise";
|
|
3
|
-
import {C6C} from "../C6Constants";
|
|
4
|
-
import restRequest from "../restRequest";
|
|
5
|
-
import {iC6Object, iRestMethods} from "../types/ormInterfaces";
|
|
1
|
+
import type {Request, Response, NextFunction} from "express";
|
|
2
|
+
import type {Pool} from "mysql2/promise";
|
|
3
|
+
import {C6C} from "../constants/C6Constants";
|
|
4
|
+
import restRequest from "../api/restRequest";
|
|
5
|
+
import type {iC6Object, iRestMethods} from "../types/ormInterfaces";
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
// TODO - WE MUST make this a generic - optional, but helpful
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* @file Automatically generated by barrelsby.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export * from "./api/C6Constants";
|
|
6
5
|
export { default as axiosInstance } from "./api/axiosInstance";
|
|
7
6
|
export * from "./api/axiosInstance";
|
|
8
7
|
export { default as convertForRequestBody } from "./api/convertForRequestBody";
|
|
@@ -12,34 +11,36 @@ export { default as restRequest } from "./api/restRequest";
|
|
|
12
11
|
export * from "./api/restRequest";
|
|
13
12
|
export { default as timeout } from "./api/timeout";
|
|
14
13
|
export * from "./api/timeout";
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./
|
|
18
|
-
export * from "./
|
|
19
|
-
export * from "./
|
|
20
|
-
export * from "./
|
|
21
|
-
export * from "./
|
|
22
|
-
export * from "./
|
|
23
|
-
export * from "./
|
|
24
|
-
export * from "./
|
|
25
|
-
export * from "./
|
|
26
|
-
export * from "./
|
|
27
|
-
export * from "./
|
|
28
|
-
export * from "./
|
|
29
|
-
export * from "./
|
|
30
|
-
export * from "./
|
|
31
|
-
export * from "./
|
|
32
|
-
export * from "./
|
|
33
|
-
export * from "./
|
|
34
|
-
export * from "./
|
|
35
|
-
export * from "./
|
|
36
|
-
export * from "./
|
|
37
|
-
export * from "./
|
|
38
|
-
export * from "./
|
|
39
|
-
export * from "./
|
|
40
|
-
export * from "./
|
|
41
|
-
export * from "./
|
|
42
|
-
export * from "./
|
|
14
|
+
export * from "./constants/C6Constants";
|
|
15
|
+
export * from "./executors/Executor";
|
|
16
|
+
export * from "./executors/HttpExecutor";
|
|
17
|
+
export * from "./executors/SqlExecutor";
|
|
18
|
+
export * from "./handlers/ExpressHandler";
|
|
19
|
+
export * from "./orm/queryHelpers";
|
|
20
|
+
export * from "./orm/builders/AggregateBuilder";
|
|
21
|
+
export * from "./orm/builders/ConditionBuilder";
|
|
22
|
+
export * from "./orm/builders/JoinBuilder";
|
|
23
|
+
export * from "./orm/builders/PaginationBuilder";
|
|
24
|
+
export * from "./orm/queries/DeleteQueryBuilder";
|
|
25
|
+
export * from "./orm/queries/PostQueryBuilder";
|
|
26
|
+
export * from "./orm/queries/SelectQueryBuilder";
|
|
27
|
+
export * from "./orm/queries/UpdateQueryBuilder";
|
|
28
|
+
export * from "./orm/utils/sqlUtils";
|
|
29
|
+
export * from "./types/dynamicFetching";
|
|
30
|
+
export * from "./types/modifyTypes";
|
|
31
|
+
export * from "./types/mysqlTypes";
|
|
32
|
+
export * from "./types/ormGenerics";
|
|
33
|
+
export * from "./types/ormInterfaces";
|
|
34
|
+
export * from "./utils/apiHelpers";
|
|
35
|
+
export * from "./utils/cacheManager";
|
|
36
|
+
export * from "./utils/determineRuntimeJsType";
|
|
37
|
+
export * from "./utils/logger";
|
|
38
|
+
export * from "./utils/normalizeSingularRequest";
|
|
39
|
+
export * from "./utils/sortAndSerializeQueryObject";
|
|
40
|
+
export * from "./utils/sqlAllowList";
|
|
41
|
+
export * from "./utils/testHelpers";
|
|
42
|
+
export * from "./utils/toastNotifier";
|
|
43
|
+
export * from "./utils/toastRuntime";
|
|
43
44
|
export * from "./variables/getEnvVar";
|
|
44
45
|
export { default as isLocal } from "./variables/isLocal";
|
|
45
46
|
export * from "./variables/isLocal";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Executor} from "../../executors/Executor";
|
|
2
2
|
import {OrmGenerics} from "../../types/ormGenerics";
|
|
3
|
-
import {C6C} from "../../C6Constants";
|
|
3
|
+
import {C6C} from "../../constants/C6Constants";
|
|
4
4
|
|
|
5
5
|
export abstract class AggregateBuilder<G extends OrmGenerics> extends Executor<G>{
|
|
6
6
|
protected selectAliases: Set<string> = new Set<string>();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {C6C} from "../../C6Constants";
|
|
1
|
+
import {C6C} from "../../constants/C6Constants";
|
|
2
2
|
import {OrmGenerics} from "../../types/ormGenerics";
|
|
3
3
|
import {DetermineResponseDataType} from "../../types/ormInterfaces";
|
|
4
4
|
import {convertHexIfBinary, SqlBuilderResult} from "../utils/sqlUtils";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {OrmGenerics} from "../../types/ormGenerics";
|
|
2
2
|
import {ConditionBuilder} from "./ConditionBuilder";
|
|
3
|
-
import {C6C} from "../../C6Constants";
|
|
3
|
+
import {C6C} from "../../constants/C6Constants";
|
|
4
4
|
import {resolveDerivedTable, isDerivedTableKey} from "../queryHelpers";
|
|
5
5
|
|
|
6
6
|
export abstract class JoinBuilder<G extends OrmGenerics> extends ConditionBuilder<G>{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Alias a table name with a given alias
|
|
2
|
-
import {C6C} from "../C6Constants";
|
|
2
|
+
import {C6C} from "../constants/C6Constants";
|
|
3
3
|
|
|
4
4
|
type DerivedTableSpec = Record<string, any> & {
|
|
5
5
|
[C6C.SUBSELECT]?: Record<string, any>;
|
|
@@ -90,4 +90,3 @@ export const bbox = (minLng: number, minLat: number, maxLng: number, maxLat: num
|
|
|
90
90
|
// ST_Contains for map envelope/shape queries
|
|
91
91
|
export const stContains = (envelope: string, shape: string): any[] =>
|
|
92
92
|
[C6C.ST_CONTAINS, envelope, shape];
|
|
93
|
-
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// Refined TypeScript types for CarbonORM
|
|
2
2
|
|
|
3
|
-
import {AxiosInstance, AxiosPromise, AxiosResponse} from "axios";
|
|
4
|
-
import {Pool} from "mysql2/promise";
|
|
3
|
+
import type {AxiosInstance, AxiosPromise, AxiosResponse} from "axios";
|
|
4
|
+
import type {Pool} from "mysql2/promise";
|
|
5
5
|
import {eFetchDependencies} from "./dynamicFetching";
|
|
6
6
|
import {Modify} from "./modifyTypes";
|
|
7
7
|
import {JoinType, OrderDirection, SQLComparisonOperator, SQLFunction} from "./mysqlTypes";
|
|
8
|
-
import {CarbonReact} from "@carbonorm/carbonreact";
|
|
9
|
-
import {OrmGenerics} from "./ormGenerics";
|
|
10
|
-
|
|
8
|
+
import type {CarbonReact} from "@carbonorm/carbonreact";
|
|
9
|
+
import type {OrmGenerics} from "./ormGenerics";
|
|
10
|
+
|
|
11
|
+
type RestOrmFactory = typeof import("../api/restOrm").restOrm;
|
|
12
|
+
type RestOrmReturn = ReturnType<RestOrmFactory<OrmGenerics<any>>>;
|
|
11
13
|
|
|
12
14
|
export type iRestMethods = 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
13
15
|
export const POST = 'POST';
|
|
@@ -288,7 +290,7 @@ export interface iC6Object<
|
|
|
288
290
|
ORM: {
|
|
289
291
|
[K in Extract<keyof RestTableInterfaces, string>]:
|
|
290
292
|
C6RestfulModel<K, RestTableInterfaces[K], keyof RestTableInterfaces[K] & string>
|
|
291
|
-
&
|
|
293
|
+
& RestOrmReturn
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
[key: string]: any;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// When we capture DropExceptions and display them as a custom page, this will change.
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import isTest from "../variables/isTest";
|
|
3
|
+
import type {AxiosResponse} from "axios";
|
|
4
|
+
import {toastOptions} from "../variables/toastOptions";
|
|
5
|
+
import type {C6RestfulModel} from "../types/ormInterfaces";
|
|
6
|
+
import {notifyToast} from "./toastRuntime";
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -21,7 +21,7 @@ export function TestRestfulResponse(response: AxiosResponse | any, success: ((r:
|
|
|
21
21
|
|
|
22
22
|
if (typeof successReturn === 'string') {
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
notifyToast("success", successReturn, toastOptions);
|
|
25
25
|
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -34,7 +34,7 @@ export function TestRestfulResponse(response: AxiosResponse | any, success: ((r:
|
|
|
34
34
|
|
|
35
35
|
if (typeof errorReturn === 'string') {
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
notifyToast("error", errorReturn, toastOptions);
|
|
38
38
|
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -83,4 +83,4 @@ export function removeInvalidKeys<iRestObject>(request: any, c6Tables: {
|
|
|
83
83
|
|
|
84
84
|
return intersection
|
|
85
85
|
|
|
86
|
-
}
|
|
86
|
+
}
|