ugly-app 0.1.162 → 0.1.164

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.
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.1.162";
1
+ export declare const CLI_VERSION = "0.1.164";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.162";
2
+ export const CLI_VERSION = "0.1.164";
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PostgresFilter.d.ts","sourceRoot":"","sources":["../../src/server/PostgresFilter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAmBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAkFjF;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAOlE"}
1
+ {"version":3,"file":"PostgresFilter.d.ts","sourceRoot":"","sources":["../../src/server/PostgresFilter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAiCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAmGjF;AAED,iDAAiD;AACjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAOlE"}
@@ -5,10 +5,21 @@
5
5
  * Fields are accessed via JSONB operators (data->>'field' for text, casts for numbers/booleans).
6
6
  * Dot-notation paths (e.g. 'user.profile.name') are translated to -> chains.
7
7
  */
8
+ /** Fields stored as top-level columns rather than inside the JSONB data column. */
9
+ const TOP_LEVEL_COLUMNS = new Set(['_id', 'created', 'updated', 'version']);
10
+ /** Top-level columns that store timestamps (TIMESTAMPTZ). Numeric values must be converted to Date. */
11
+ const TIMESTAMP_COLUMNS = new Set(['created', 'updated']);
12
+ /** Convert a value to a Date if it's a numeric epoch for a timestamp column. */
13
+ function coerceTimestamp(field, value) {
14
+ if (TIMESTAMP_COLUMNS.has(field) && typeof value === 'number') {
15
+ return new Date(value);
16
+ }
17
+ return value;
18
+ }
8
19
  /** Build the JSONB accessor for a field path. Last segment uses ->> (text extraction). */
9
20
  function jsonbPath(field, asText = true) {
10
- if (field === '_id')
11
- return '_id';
21
+ if (TOP_LEVEL_COLUMNS.has(field))
22
+ return `"${field}"`;
12
23
  const parts = field.split('.');
13
24
  if (parts.length === 1) {
14
25
  return asText ? `data->>'${parts[0]}'` : `data->'${parts[0]}'`;
@@ -44,29 +55,41 @@ export function translateFilter(filter) {
44
55
  values.push(operand);
45
56
  paramIdx++;
46
57
  break;
47
- case '$gt':
48
- clauses.push(`(${jsonbPath(field)})::numeric > $${paramIdx}`);
49
- values.push(operand);
58
+ case '$gt': {
59
+ const acc = jsonbPath(field);
60
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
61
+ clauses.push(`${cast} > $${paramIdx}`);
62
+ values.push(coerceTimestamp(field, operand));
50
63
  paramIdx++;
51
64
  break;
52
- case '$gte':
53
- clauses.push(`(${jsonbPath(field)})::numeric >= $${paramIdx}`);
54
- values.push(operand);
65
+ }
66
+ case '$gte': {
67
+ const acc = jsonbPath(field);
68
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
69
+ clauses.push(`${cast} >= $${paramIdx}`);
70
+ values.push(coerceTimestamp(field, operand));
55
71
  paramIdx++;
56
72
  break;
57
- case '$lt':
58
- clauses.push(`(${jsonbPath(field)})::numeric < $${paramIdx}`);
59
- values.push(operand);
73
+ }
74
+ case '$lt': {
75
+ const acc = jsonbPath(field);
76
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
77
+ clauses.push(`${cast} < $${paramIdx}`);
78
+ values.push(coerceTimestamp(field, operand));
60
79
  paramIdx++;
61
80
  break;
62
- case '$lte':
63
- clauses.push(`(${jsonbPath(field)})::numeric <= $${paramIdx}`);
64
- values.push(operand);
81
+ }
82
+ case '$lte': {
83
+ const acc = jsonbPath(field);
84
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
85
+ clauses.push(`${cast} <= $${paramIdx}`);
86
+ values.push(coerceTimestamp(field, operand));
65
87
  paramIdx++;
66
88
  break;
89
+ }
67
90
  case '$ne':
68
91
  clauses.push(`${jsonbPath(field)} != $${paramIdx}`);
69
- values.push(operand);
92
+ values.push(coerceTimestamp(field, operand));
70
93
  paramIdx++;
71
94
  break;
72
95
  case '$exists':
@@ -86,8 +109,14 @@ export function translateFilter(filter) {
86
109
  clauses.push(`${jsonbPath(field, false)} IS NULL OR ${jsonbPath(field)} = 'null'`);
87
110
  }
88
111
  else if (typeof value === 'number') {
89
- clauses.push(`(${jsonbPath(field)})::numeric = $${paramIdx}`);
90
- values.push(value);
112
+ if (TIMESTAMP_COLUMNS.has(field)) {
113
+ clauses.push(`${jsonbPath(field)} = $${paramIdx}`);
114
+ values.push(new Date(value));
115
+ }
116
+ else {
117
+ clauses.push(`(${jsonbPath(field)})::numeric = $${paramIdx}`);
118
+ values.push(value);
119
+ }
91
120
  paramIdx++;
92
121
  }
93
122
  else if (typeof value === 'boolean') {
@@ -112,7 +141,7 @@ export function translateFilter(filter) {
112
141
  export function translateSort(sort) {
113
142
  return Object.entries(sort)
114
143
  .map(([field, dir]) => {
115
- const accessor = field === '_id' ? '_id' : jsonbPath(field);
144
+ const accessor = TOP_LEVEL_COLUMNS.has(field) ? `"${field}"` : jsonbPath(field);
116
145
  return `${accessor} ${dir === 1 ? 'ASC' : 'DESC'}`;
117
146
  })
118
147
  .join(', ');
@@ -1 +1 @@
1
- {"version":3,"file":"PostgresFilter.js","sourceRoot":"","sources":["../../src/server/PostgresFilter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostgresFilter.js","sourceRoot":"","sources":["../../src/server/PostgresFilter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-app",
3
- "version": "0.1.162",
3
+ "version": "0.1.164",
4
4
  "type": "module",
5
5
  "main": "./dist/server/index.js",
6
6
  "exports": {
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.162";
2
+ export const CLI_VERSION = "0.1.164";
@@ -11,9 +11,23 @@ export interface TranslatedFilter {
11
11
  values: unknown[];
12
12
  }
13
13
 
14
+ /** Fields stored as top-level columns rather than inside the JSONB data column. */
15
+ const TOP_LEVEL_COLUMNS = new Set(['_id', 'created', 'updated', 'version']);
16
+
17
+ /** Top-level columns that store timestamps (TIMESTAMPTZ). Numeric values must be converted to Date. */
18
+ const TIMESTAMP_COLUMNS = new Set(['created', 'updated']);
19
+
20
+ /** Convert a value to a Date if it's a numeric epoch for a timestamp column. */
21
+ function coerceTimestamp(field: string, value: unknown): unknown {
22
+ if (TIMESTAMP_COLUMNS.has(field) && typeof value === 'number') {
23
+ return new Date(value);
24
+ }
25
+ return value;
26
+ }
27
+
14
28
  /** Build the JSONB accessor for a field path. Last segment uses ->> (text extraction). */
15
29
  function jsonbPath(field: string, asText = true): string {
16
- if (field === '_id') return '_id';
30
+ if (TOP_LEVEL_COLUMNS.has(field)) return `"${field}"`;
17
31
  const parts = field.split('.');
18
32
  if (parts.length === 1) {
19
33
  return asText ? `data->>'${parts[0]}'` : `data->'${parts[0]}'`;
@@ -51,29 +65,41 @@ export function translateFilter(filter: Record<string, unknown>): TranslatedFilt
51
65
  values.push(operand);
52
66
  paramIdx++;
53
67
  break;
54
- case '$gt':
55
- clauses.push(`(${jsonbPath(field)})::numeric > $${paramIdx}`);
56
- values.push(operand);
68
+ case '$gt': {
69
+ const acc = jsonbPath(field);
70
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
71
+ clauses.push(`${cast} > $${paramIdx}`);
72
+ values.push(coerceTimestamp(field, operand));
57
73
  paramIdx++;
58
74
  break;
59
- case '$gte':
60
- clauses.push(`(${jsonbPath(field)})::numeric >= $${paramIdx}`);
61
- values.push(operand);
75
+ }
76
+ case '$gte': {
77
+ const acc = jsonbPath(field);
78
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
79
+ clauses.push(`${cast} >= $${paramIdx}`);
80
+ values.push(coerceTimestamp(field, operand));
62
81
  paramIdx++;
63
82
  break;
64
- case '$lt':
65
- clauses.push(`(${jsonbPath(field)})::numeric < $${paramIdx}`);
66
- values.push(operand);
83
+ }
84
+ case '$lt': {
85
+ const acc = jsonbPath(field);
86
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
87
+ clauses.push(`${cast} < $${paramIdx}`);
88
+ values.push(coerceTimestamp(field, operand));
67
89
  paramIdx++;
68
90
  break;
69
- case '$lte':
70
- clauses.push(`(${jsonbPath(field)})::numeric <= $${paramIdx}`);
71
- values.push(operand);
91
+ }
92
+ case '$lte': {
93
+ const acc = jsonbPath(field);
94
+ const cast = TOP_LEVEL_COLUMNS.has(field) ? acc : `(${acc})::numeric`;
95
+ clauses.push(`${cast} <= $${paramIdx}`);
96
+ values.push(coerceTimestamp(field, operand));
72
97
  paramIdx++;
73
98
  break;
99
+ }
74
100
  case '$ne':
75
101
  clauses.push(`${jsonbPath(field)} != $${paramIdx}`);
76
- values.push(operand);
102
+ values.push(coerceTimestamp(field, operand));
77
103
  paramIdx++;
78
104
  break;
79
105
  case '$exists':
@@ -90,8 +116,13 @@ export function translateFilter(filter: Record<string, unknown>): TranslatedFilt
90
116
  } else if (value === null) {
91
117
  clauses.push(`${jsonbPath(field, false)} IS NULL OR ${jsonbPath(field)} = 'null'`);
92
118
  } else if (typeof value === 'number') {
93
- clauses.push(`(${jsonbPath(field)})::numeric = $${paramIdx}`);
94
- values.push(value);
119
+ if (TIMESTAMP_COLUMNS.has(field)) {
120
+ clauses.push(`${jsonbPath(field)} = $${paramIdx}`);
121
+ values.push(new Date(value));
122
+ } else {
123
+ clauses.push(`(${jsonbPath(field)})::numeric = $${paramIdx}`);
124
+ values.push(value);
125
+ }
95
126
  paramIdx++;
96
127
  } else if (typeof value === 'boolean') {
97
128
  clauses.push(`(${jsonbPath(field)})::boolean = $${paramIdx}`);
@@ -116,7 +147,7 @@ export function translateFilter(filter: Record<string, unknown>): TranslatedFilt
116
147
  export function translateSort(sort: Record<string, 1 | -1>): string {
117
148
  return Object.entries(sort)
118
149
  .map(([field, dir]) => {
119
- const accessor = field === '_id' ? '_id' : jsonbPath(field);
150
+ const accessor = TOP_LEVEL_COLUMNS.has(field) ? `"${field}"` : jsonbPath(field);
120
151
  return `${accessor} ${dir === 1 ? 'ASC' : 'DESC'}`;
121
152
  })
122
153
  .join(', ');