@carbonorm/carbonnode 6.0.10 → 6.0.13

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.
Files changed (75) hide show
  1. package/dist/executors/SqlExecutor.d.ts +6 -0
  2. package/dist/handlers/ExpressHandler.d.ts +8 -9
  3. package/dist/index.cjs.js +324 -108
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.esm.js +324 -109
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/types/ormInterfaces.d.ts +25 -5
  8. package/dist/utils/cacheManager.d.ts +2 -3
  9. package/package.json +1 -1
  10. package/src/__tests__/convertForRequestBody.test.ts +58 -0
  11. package/src/__tests__/expressServer.e2e.test.ts +62 -38
  12. package/src/__tests__/fixtures/createTestServer.ts +7 -3
  13. package/src/__tests__/httpExecutorSingular.e2e.test.ts +97 -60
  14. package/src/__tests__/logSql.test.ts +13 -0
  15. package/src/__tests__/sakila-db/C6.js +1 -1
  16. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  17. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  18. package/src/__tests__/sakila-db/C6.sqlAllowList.json +11 -11
  19. package/src/__tests__/sakila-db/C6.ts +1 -1
  20. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +4 -4
  21. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  22. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  23. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  24. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +6 -6
  25. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  26. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  27. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  28. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +3 -3
  29. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  30. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  31. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +3 -3
  33. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  34. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  35. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +3 -3
  37. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  38. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  39. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  40. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +6 -6
  41. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  42. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  43. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  44. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +3 -3
  45. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  46. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  47. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  48. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +2 -2
  49. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  50. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  51. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  52. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +3 -3
  53. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  54. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  55. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  56. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +3 -3
  57. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  58. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  59. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +4 -4
  60. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  61. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  62. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  63. package/src/__tests__/sakila.generated.test.ts +11 -3
  64. package/src/__tests__/sqlBuilders.test.ts +46 -0
  65. package/src/__tests__/sqlExecutorLifecycleHooks.test.ts +122 -0
  66. package/src/api/convertForRequestBody.ts +9 -2
  67. package/src/api/restRequest.ts +1 -0
  68. package/src/executors/HttpExecutor.ts +1 -1
  69. package/src/executors/SqlExecutor.ts +252 -49
  70. package/src/handlers/ExpressHandler.ts +50 -24
  71. package/src/orm/builders/ConditionBuilder.ts +43 -1
  72. package/src/orm/queries/PostQueryBuilder.ts +24 -12
  73. package/src/types/ormInterfaces.ts +31 -5
  74. package/src/utils/cacheManager.ts +3 -4
  75. package/src/utils/colorSql.ts +18 -0
@@ -1,4 +1,4 @@
1
- import type {AxiosInstance, AxiosPromise, AxiosResponse} from "axios";
1
+ import type {AxiosInstance, AxiosResponse} from "axios";
2
2
  import type {Pool} from "mysql2/promise";
3
3
  import {eFetchDependencies} from "./dynamicFetching";
4
4
  import {Modify} from "./modifyTypes";
@@ -101,10 +101,22 @@ export type RequestQueryBody<
101
101
  ? iAPI<RequestGetPutDeleteBody<Modify<T, Overrides> & Custom>>
102
102
  : iAPI<RequestPostBody<Modify<T, Overrides> & Custom>>;
103
103
 
104
+ export interface iCacheRequestConfig {
105
+ method?: string;
106
+ url?: string;
107
+ headers?: any;
108
+ }
109
+
110
+ export interface iCacheResponse<ResponseDataType = any> {
111
+ data: ResponseDataType;
112
+ config?: iCacheRequestConfig;
113
+ [key: string]: any;
114
+ }
115
+
104
116
  export interface iCacheAPI<ResponseDataType = any> {
105
117
  requestArgumentsSerialized: string;
106
- request: AxiosPromise<ResponseDataType>;
107
- response?: AxiosResponse & {
118
+ request: Promise<iCacheResponse<ResponseDataType>>;
119
+ response?: iCacheResponse<ResponseDataType> & {
108
120
  __carbonTiming?: {
109
121
  start: number;
110
122
  end: number;
@@ -172,6 +184,19 @@ export type DetermineResponseDataType<
172
184
  ? iDeleteC6RestResponse<RestTableInterface>
173
185
  : never);
174
186
 
187
+ export type iRestSqlExecutionContext = {
188
+ sql: string;
189
+ values: any[];
190
+ };
191
+
192
+ export type iRestLifecycleResponse<G extends OrmGenerics> =
193
+ AxiosResponse<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>
194
+ | {
195
+ data: {
196
+ success: boolean;
197
+ } & DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>;
198
+ };
199
+
175
200
 
176
201
  export type iRestWebsocketPayload = {
177
202
  REST: {
@@ -254,20 +279,21 @@ export type iRestReactiveLifecycle<G extends OrmGenerics> = {
254
279
  [key: string]: (args: {
255
280
  config: iRest<G['RestShortTableName'], G['RestTableInterface'], G['PrimaryKey']>;
256
281
  request: RequestQueryBody<G['RequestMethod'], G['RestTableInterface'], G['CustomAndRequiredFields'], G['RequestTableOverrides']>;
282
+ sqlExecution?: iRestSqlExecutionContext;
257
283
  }) => void | Promise<void>;
258
284
  };
259
285
  afterExecution?: {
260
286
  [key: string]: (args: {
261
287
  config: iRest<G['RestShortTableName'], G['RestTableInterface'], G['PrimaryKey']>;
262
288
  request: RequestQueryBody<G['RequestMethod'], G['RestTableInterface'], G['CustomAndRequiredFields'], G['RequestTableOverrides']>;
263
- response: AxiosResponse<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>;
289
+ response: iRestLifecycleResponse<G>;
264
290
  }) => void | Promise<void>;
265
291
  };
266
292
  afterCommit?: {
267
293
  [key: string]: (args: {
268
294
  config: iRest<G['RestShortTableName'], G['RestTableInterface'], G['PrimaryKey']>;
269
295
  request: RequestQueryBody<G['RequestMethod'], G['RestTableInterface'], G['CustomAndRequiredFields'], G['RequestTableOverrides']>;
270
- response: AxiosResponse<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>;
296
+ response: iRestLifecycleResponse<G>;
271
297
  }) => void | Promise<void>;
272
298
  };
273
299
  };
@@ -1,5 +1,4 @@
1
- import type {AxiosPromise} from "axios";
2
- import type {iCacheAPI} from "../types/ormInterfaces";
1
+ import type {iCacheAPI, iCacheResponse} from "../types/ormInterfaces";
3
2
  import {LogLevel, logWithLevel, shouldLog} from "./logLevel";
4
3
 
5
4
  // -----------------------------------------------------------------------------
@@ -61,13 +60,13 @@ export function checkCache<ResponseDataType = any>(
61
60
  method: string,
62
61
  tableName: string | string[],
63
62
  requestData: any,
64
- ): AxiosPromise<ResponseDataType> | false {
63
+ ): Promise<iCacheResponse<ResponseDataType>> | false {
65
64
  const key = makeCacheKey(method, tableName, requestData);
66
65
  const cached = apiRequestCache.get(key);
67
66
 
68
67
  if (!cached) return false;
69
68
 
70
- if (shouldLog(LogLevel.DEBUG, undefined)) {
69
+ if (shouldLog(LogLevel.INFO, undefined)) {
71
70
  console.groupCollapsed(
72
71
  `%c API cache hit for ${method} ${tableName}`,
73
72
  "color:#0c0",
@@ -73,6 +73,23 @@ function collapseBinds(sql: string): string {
73
73
  );
74
74
  }
75
75
 
76
+ /**
77
+ * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
78
+ */
79
+ function collapseRepeatedValueRows(sql: string): string {
80
+ const repeatedRowPattern =
81
+ /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
82
+
83
+ return sql.replace(repeatedRowPattern, (match, row: string) => {
84
+ const rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
85
+ const count = rowMatches?.length ?? 1;
86
+ const normalizedRow = row.includes("×")
87
+ ? row
88
+ : `(${C.DIM}? ×${(row.match(/\?/g) ?? []).length}${RESET})`;
89
+ return `${normalizedRow} ${C.DIM}×${count}${RESET}`;
90
+ });
91
+ }
92
+
76
93
  /* ---------- main formatter ---------- */
77
94
 
78
95
  export default function colorSql(sql: string): string {
@@ -80,6 +97,7 @@ export default function colorSql(sql: string): string {
80
97
 
81
98
  /* 1️⃣ collapse bind noise */
82
99
  s = collapseBinds(s);
100
+ s = collapseRepeatedValueRows(s);
83
101
 
84
102
  /* 2️⃣ table.column coloring (core visual grouping) */
85
103
  s = s.replace(