@carbonorm/carbonnode 6.0.6 → 6.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.
Files changed (97) hide show
  1. package/dist/index.cjs.js +537 -130
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +8 -1
  4. package/dist/index.esm.js +525 -130
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/types/ormInterfaces.d.ts +1 -0
  7. package/dist/utils/colorSql.d.ts +1 -0
  8. package/dist/utils/logLevel.d.ts +32 -0
  9. package/dist/utils/logSql.d.ts +2 -0
  10. package/dist/utils/logger.d.ts +0 -3
  11. package/dist/utils/versionColor.d.ts +6 -0
  12. package/dist/variables/getEnv.d.ts +10 -0
  13. package/dist/variables/isTest.d.ts +1 -1
  14. package/dist/variables/isVerbose.d.ts +1 -1
  15. package/package.json +3 -1
  16. package/src/__tests__/fixtures/c6.fixture.ts +5 -0
  17. package/src/__tests__/logLevel.test.ts +54 -0
  18. package/src/__tests__/logSql.test.ts +70 -0
  19. package/src/__tests__/sakila-db/C6.js +1 -1
  20. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  21. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  22. package/src/__tests__/sakila-db/C6.ts +1 -1
  23. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +3 -3
  24. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  25. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  26. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  27. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +5 -5
  28. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  29. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  30. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  31. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  33. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  34. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  35. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  37. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  38. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  39. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +2 -2
  40. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  41. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  42. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  43. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +5 -5
  44. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  45. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  46. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  47. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +2 -2
  48. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  49. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  50. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  51. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +1 -1
  52. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  53. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  54. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  55. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +2 -2
  56. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  57. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  58. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  59. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +2 -2
  60. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  61. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  62. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +3 -3
  63. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  64. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  65. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  66. package/src/__tests__/sqlBuilders.test.ts +21 -1
  67. package/src/__tests__/versionColor.test.ts +42 -0
  68. package/src/api/convertForRequestBody.ts +8 -1
  69. package/src/api/restRequest.ts +12 -12
  70. package/src/executors/Executor.ts +11 -2
  71. package/src/executors/HttpExecutor.ts +92 -54
  72. package/src/executors/SqlExecutor.ts +151 -40
  73. package/src/handlers/ExpressHandler.ts +7 -1
  74. package/src/index.ts +8 -1
  75. package/src/orm/builders/AggregateBuilder.ts +13 -2
  76. package/src/orm/builders/ConditionBuilder.ts +13 -2
  77. package/src/orm/builders/JoinBuilder.ts +7 -1
  78. package/src/orm/builders/PaginationBuilder.ts +7 -1
  79. package/src/orm/queries/DeleteQueryBuilder.ts +4 -0
  80. package/src/orm/queries/PostQueryBuilder.ts +4 -0
  81. package/src/orm/queries/SelectQueryBuilder.ts +3 -1
  82. package/src/orm/queries/UpdateQueryBuilder.ts +4 -0
  83. package/src/types/ormInterfaces.ts +1 -0
  84. package/src/utils/apiHelpers.ts +4 -1
  85. package/src/utils/cacheManager.ts +13 -7
  86. package/src/utils/colorSql.ts +112 -0
  87. package/src/utils/logLevel.ts +157 -0
  88. package/src/utils/logSql.ts +59 -0
  89. package/src/utils/logger.ts +7 -1
  90. package/src/utils/testHelpers.ts +2 -1
  91. package/src/utils/versionColor.ts +54 -0
  92. package/src/variables/getEnv.ts +73 -0
  93. package/src/variables/isLocal.ts +2 -2
  94. package/src/variables/isTest.ts +4 -4
  95. package/src/variables/isVerbose.ts +4 -5
  96. package/dist/variables/getEnvVar.d.ts +0 -1
  97. package/src/variables/getEnvVar.ts +0 -15
@@ -171,6 +171,7 @@ export interface iRest<RestShortTableName extends string = any, RestTableInterfa
171
171
  clearCache?: () => void;
172
172
  skipPrimaryCheck?: boolean;
173
173
  websocketBroadcast?: tWebsocketBroadcast;
174
+ logLevel?: number;
174
175
  verbose?: boolean;
175
176
  sqlAllowListPath?: string;
176
177
  }
@@ -0,0 +1 @@
1
+ export default function colorSql(sql: string): string;
@@ -0,0 +1,32 @@
1
+ export declare enum LogLevel {
2
+ NONE = 0,
3
+ ERROR = 1,
4
+ WARN = 2,
5
+ INFO = 3,
6
+ DEBUG = 4,
7
+ TRACE = 5
8
+ }
9
+ export type LogContext = {
10
+ logLevel?: number | null;
11
+ verbose?: boolean | null;
12
+ request?: {
13
+ debug?: boolean;
14
+ } | null;
15
+ };
16
+ export declare const parseLogLevel: (value: unknown) => LogLevel | undefined;
17
+ export declare const getEnvLogLevel: () => LogLevel | undefined;
18
+ export declare const resolveLogLevel: (context?: LogContext) => LogLevel;
19
+ export declare const shouldLog: (requiredLevel: LogLevel, context?: LogContext) => boolean;
20
+ export declare const applyLogLevelDefaults: (config: {
21
+ logLevel?: number | null;
22
+ verbose?: boolean | null;
23
+ }, request?: {
24
+ debug?: boolean;
25
+ } | null) => LogLevel;
26
+ export declare const getLogContext: (config?: {
27
+ logLevel?: number | null;
28
+ verbose?: boolean | null;
29
+ }, request?: {
30
+ debug?: boolean;
31
+ } | null) => LogContext | undefined;
32
+ export declare const logWithLevel: (requiredLevel: LogLevel, context: LogContext | undefined, logger: (...args: any[]) => void, ...args: any[]) => void;
@@ -0,0 +1,2 @@
1
+ import type { LogContext } from "./logLevel";
2
+ export default function logSql(method: string, sql: string, context?: LogContext): void;
@@ -1,6 +1,3 @@
1
- /**
2
- * Conditionally group a log if verbose.
3
- */
4
1
  export declare function group(title: string, data?: any): void;
5
2
  export declare function info(message: string, ...optional: any[]): void;
6
3
  export declare function warn(message: string, ...optional: any[]): void;
@@ -0,0 +1,6 @@
1
+ export interface RgbColor {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ }
6
+ export default function versionToRgb(version: string, step?: number): RgbColor;
@@ -0,0 +1,10 @@
1
+ export declare function getEnv(key: string, fallback?: string): string;
2
+ export declare function getEnv<T>(key: string, fallback: T): T;
3
+ export declare function getEnvBool(key: string, fallback?: boolean): boolean;
4
+ type EnvSource = "vite" | "runtime" | "process" | "fallback" | "missing";
5
+ export declare function getEnvDebug<T = string>(key: string, fallback?: T): {
6
+ key: string;
7
+ value: T;
8
+ source: EnvSource;
9
+ };
10
+ export {};
@@ -1 +1 @@
1
- export default function (): string | boolean;
1
+ export default function (): boolean;
@@ -1 +1 @@
1
- export default function (): boolean;
1
+ export default function isVerbose(): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbonorm/carbonnode",
3
- "version": "6.0.6",
3
+ "version": "6.0.8",
4
4
  "browser": "dist/index.umd.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "exports": {
10
10
  ".": {
11
+ "types": "./dist/index.d.ts",
11
12
  "import": "./dist/index.esm.js",
12
13
  "require": "./dist/index.cjs.js"
13
14
  }
@@ -54,6 +55,7 @@
54
55
  "@drop-in-gaming/barrelsby": "^0.0.2",
55
56
  "@jest/globals": "^29.7.0",
56
57
  "@rollup/plugin-commonjs": "^28",
58
+ "@rollup/plugin-json": "^6.1.0",
57
59
  "@rollup/plugin-node-resolve": "^16",
58
60
  "@rollup/plugin-typescript": "^12",
59
61
  "@types/geojson": "^7946.0.16",
@@ -1,4 +1,5 @@
1
1
  import type { iRest, C6RestfulModel } from "../../types/ormInterfaces";
2
+ import { LogLevel } from "../../utils/logLevel";
2
3
 
3
4
  // Minimal C6 table descriptor for tests
4
5
  function tableModel<T extends Record<string, any>>(name: string, columns: Record<string, keyof T>): C6RestfulModel<string, T, keyof T & string> {
@@ -70,6 +71,7 @@ export function buildTestConfig() {
70
71
  restModel: C6.TABLES.actor,
71
72
  requestMethod: 'GET',
72
73
  verbose: false,
74
+ logLevel: LogLevel.DEBUG,
73
75
  } as any;
74
76
 
75
77
  return baseConfig;
@@ -97,6 +99,7 @@ export function buildBinaryTestConfig() {
97
99
  restModel: C6.TABLES.binary_test,
98
100
  requestMethod: 'POST',
99
101
  verbose: false,
102
+ logLevel: LogLevel.DEBUG,
100
103
  } as any;
101
104
 
102
105
  return baseConfig;
@@ -127,6 +130,7 @@ export function buildBinaryTestConfigFqn() {
127
130
  restModel: C6.TABLES.binary_test,
128
131
  requestMethod: 'POST',
129
132
  verbose: false,
133
+ logLevel: LogLevel.DEBUG,
130
134
  } as any;
131
135
 
132
136
  return baseConfig;
@@ -169,6 +173,7 @@ export function buildParcelConfig() {
169
173
  restModel: C6.TABLES.property_units,
170
174
  requestMethod: 'GET',
171
175
  verbose: false,
176
+ logLevel: LogLevel.DEBUG,
172
177
  } as any;
173
178
 
174
179
  return baseConfig;
@@ -0,0 +1,54 @@
1
+ import {afterEach, describe, expect, it} from "vitest";
2
+ import {LogLevel, resolveLogLevel} from "../utils/logLevel";
3
+
4
+ const LOG_LEVEL_KEY = "LOG_LEVEL";
5
+ const VERBOSE_KEY = "VERBOSE";
6
+
7
+ const originalLogLevel = process.env[LOG_LEVEL_KEY];
8
+ const originalVerbose = process.env[VERBOSE_KEY];
9
+
10
+ const resetEnv = () => {
11
+ if (originalLogLevel === undefined) {
12
+ delete process.env[LOG_LEVEL_KEY];
13
+ } else {
14
+ process.env[LOG_LEVEL_KEY] = originalLogLevel;
15
+ }
16
+
17
+ if (originalVerbose === undefined) {
18
+ delete process.env[VERBOSE_KEY];
19
+ } else {
20
+ process.env[VERBOSE_KEY] = originalVerbose;
21
+ }
22
+ };
23
+
24
+ afterEach(() => {
25
+ resetEnv();
26
+ });
27
+
28
+ describe("log level resolution", () => {
29
+ it("uses LOG_LEVEL env when set", () => {
30
+ process.env[LOG_LEVEL_KEY] = "1";
31
+ delete process.env[VERBOSE_KEY];
32
+
33
+ expect(resolveLogLevel()).toBe(LogLevel.ERROR);
34
+ });
35
+
36
+ it("maps VERBOSE env to DEBUG when log level env is unset", () => {
37
+ delete process.env[LOG_LEVEL_KEY];
38
+ process.env[VERBOSE_KEY] = "true";
39
+
40
+ expect(resolveLogLevel()).toBe(LogLevel.DEBUG);
41
+ });
42
+
43
+ it("maps verbose config to DEBUG/WARN and respects logLevel override", () => {
44
+ expect(resolveLogLevel({verbose: true})).toBe(LogLevel.DEBUG);
45
+ expect(resolveLogLevel({verbose: false})).toBe(LogLevel.WARN);
46
+ expect(resolveLogLevel({logLevel: LogLevel.ERROR, verbose: true})).toBe(LogLevel.ERROR);
47
+ expect(resolveLogLevel({logLevel: "TRACE" as any})).toBe(LogLevel.TRACE);
48
+ });
49
+
50
+ it("bumps request debug to DEBUG when base level is lower", () => {
51
+ expect(resolveLogLevel({logLevel: LogLevel.ERROR, request: {debug: true}})).toBe(LogLevel.DEBUG);
52
+ expect(resolveLogLevel({logLevel: LogLevel.TRACE, request: {debug: true}})).toBe(LogLevel.TRACE);
53
+ });
54
+ });
@@ -0,0 +1,70 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import logSql from "../utils/logSql";
3
+ import colorSql from "../utils/colorSql";
4
+ import { version } from "../../package.json";
5
+
6
+ const stripAnsi = (value: string) => value.replace(/\x1b\[[0-9;]*m/g, "");
7
+
8
+ const SSR_ENV_KEY = "SSR";
9
+ const originalSsr = process.env[SSR_ENV_KEY];
10
+ const LOG_LEVEL_KEY = "LOG_LEVEL";
11
+ const originalLogLevel = process.env[LOG_LEVEL_KEY];
12
+
13
+ const restoreEnv = () => {
14
+ if (originalSsr === undefined) {
15
+ delete process.env[SSR_ENV_KEY];
16
+ } else {
17
+ process.env[SSR_ENV_KEY] = originalSsr;
18
+ }
19
+
20
+ if (originalLogLevel === undefined) {
21
+ delete process.env[LOG_LEVEL_KEY];
22
+ } else {
23
+ process.env[LOG_LEVEL_KEY] = originalLogLevel;
24
+ }
25
+ };
26
+
27
+ afterEach(() => {
28
+ restoreEnv();
29
+ vi.restoreAllMocks();
30
+ });
31
+
32
+ describe("logSql", () => {
33
+ it("logs API prefix when SSR is disabled", () => {
34
+ process.env[SSR_ENV_KEY] = "false";
35
+ process.env[LOG_LEVEL_KEY] = "DEBUG";
36
+ const spy = vi.spyOn(console, "log").mockImplementation(() => {});
37
+
38
+ logSql("SELECT", "SELECT * FROM `users`");
39
+
40
+ expect(spy).toHaveBeenCalledTimes(1);
41
+ const message = stripAnsi(String(spy.mock.calls[0][0]));
42
+ expect(message).toContain(`[${version}]`);
43
+ expect(message).toContain("[API]");
44
+ expect(message).toContain("[SELECT]");
45
+ expect(message).toContain("SELECT * FROM `users`");
46
+ });
47
+
48
+ it("logs SSR prefix when SSR is enabled", () => {
49
+ process.env[SSR_ENV_KEY] = "true";
50
+ process.env[LOG_LEVEL_KEY] = "DEBUG";
51
+ const spy = vi.spyOn(console, "log").mockImplementation(() => {});
52
+
53
+ logSql("DELETE", "DELETE `users` FROM `users`");
54
+
55
+ const message = stripAnsi(String(spy.mock.calls[0][0]));
56
+ expect(message).toContain("[SSR]");
57
+ expect(message).toContain("[DELETE]");
58
+ });
59
+ });
60
+
61
+ describe("colorSql", () => {
62
+ it("highlights INSERT and UPDATE keywords", () => {
63
+ const sql = "INSERT INTO `users` (id) VALUES (1) ON DUPLICATE KEY UPDATE id = VALUES(id)";
64
+ const colored = colorSql(sql);
65
+
66
+ expect(colored).toContain("\x1b[94mINSERT\x1b[0m");
67
+ expect(colored).toContain("\x1b[94mUPDATE\x1b[0m");
68
+ expect(colored).toContain("\x1b[94mDUPLICATE\x1b[0m");
69
+ });
70
+ });
@@ -1342,7 +1342,7 @@ export const TABLES = {
1342
1342
  };
1343
1343
  export const C6 = {
1344
1344
  ...C6Constants,
1345
- C6VERSION: '6.0.6',
1345
+ C6VERSION: '6.0.8',
1346
1346
  IMPORT: async (tableName) => {
1347
1347
  tableName = tableName.toLowerCase();
1348
1348
  // if tableName is not a key in the TABLES object then throw an error