@sprucelabs/postgres-data-store 6.0.69 → 6.1.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.
@@ -30,15 +30,13 @@ export default class PostgresDatabase implements Database {
30
30
  connect(): Promise<void>;
31
31
  getUniqueIndexes(collectionName: string): Promise<UniqueIndex[]>;
32
32
  private executeGetIndexes;
33
- dropIndex(collectionName: string, fields: UniqueIndex): Promise<void>;
33
+ dropIndex(collectionName: string, index: UniqueIndex): Promise<void>;
34
34
  syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
35
35
  syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
36
36
  private executeSyncIndexes;
37
37
  private areIndexesEqual;
38
38
  createUniqueIndex(collection: string, fields: UniqueIndex): Promise<void>;
39
39
  private executeCreateIndex;
40
- private generateKeyExpressions;
41
- private generateKeyExpression;
42
40
  private generateIndexName;
43
41
  close(): Promise<void>;
44
42
  isConnected(): boolean;
@@ -1,33 +1,14 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
4
  };
25
5
  Object.defineProperty(exports, "__esModule", { value: true });
26
6
  const crypto_1 = require("crypto");
27
7
  const data_stores_1 = require("@sprucelabs/data-stores");
28
8
  const schema_1 = require("@sprucelabs/schema");
29
9
  const pg_1 = require("pg");
30
- const QueryBuilder_1 = __importStar(require("./QueryBuilder"));
10
+ const indexUtils_1 = require("./indexUtils");
11
+ const QueryBuilder_1 = __importDefault(require("./QueryBuilder"));
31
12
  class PostgresDatabase {
32
13
  constructor(connectionString) {
33
14
  this.idCount = 1;
@@ -258,8 +239,8 @@ class PostgresDatabase {
258
239
  });
259
240
  return uniqueIndexes;
260
241
  }
261
- async dropIndex(collectionName, fields) {
262
- const indexName = this.generateIndexName(collectionName, fields);
242
+ async dropIndex(collectionName, index) {
243
+ const indexName = this.generateIndexName(collectionName, index);
263
244
  const query = `DROP INDEX ${indexName}`;
264
245
  try {
265
246
  await this.client.query({
@@ -269,7 +250,7 @@ class PostgresDatabase {
269
250
  catch (err) {
270
251
  throw new data_stores_1.DataStoresError({
271
252
  code: 'INDEX_NOT_FOUND',
272
- missingIndex: fields,
253
+ missingIndex: (0, data_stores_1.normalizeIndex)(index).fields,
273
254
  collectionName,
274
255
  });
275
256
  }
@@ -311,11 +292,9 @@ class PostgresDatabase {
311
292
  const isUnique = true;
312
293
  await this.executeCreateIndex(collection, fields, isUnique);
313
294
  }
314
- async executeCreateIndex(collection, fields, isUnique) {
295
+ async executeCreateIndex(collection, index, isUnique) {
315
296
  var _a, _b;
316
- const indexName = this.generateIndexName(collection, fields);
317
- const keys = this.generateKeyExpressions(fields);
318
- const query = `CREATE ${isUnique ? `UNIQUE` : ''} INDEX ${indexName} ON "${collection}" (${keys})`;
297
+ const { sql: query } = this.queries.createIndex(collection, index, isUnique);
319
298
  try {
320
299
  await this.client.query({
321
300
  text: query,
@@ -332,20 +311,8 @@ class PostgresDatabase {
332
311
  throw err;
333
312
  }
334
313
  }
335
- generateKeyExpressions(fields) {
336
- return fields.map((f) => this.generateKeyExpression(f)).join(', ');
337
- }
338
- generateKeyExpression(field) {
339
- if (field.includes('.')) {
340
- const parts = field.split('.');
341
- return `(${parts[0]}->>'${parts[1]}')`;
342
- }
343
- return (0, QueryBuilder_1.quote)(field);
344
- }
345
- generateIndexName(collection, fields) {
346
- return `${collection}_${fields
347
- .map((f) => f.toLowerCase())
348
- .join('_')}${'_index'}`.replace(/\./g, '_');
314
+ generateIndexName(collection, index) {
315
+ return (0, indexUtils_1.generateIndexName)(collection, index);
349
316
  }
350
317
  async close() {
351
318
  await this.client.end();
@@ -1,14 +1,15 @@
1
- import { QueryOptions } from '@sprucelabs/data-stores';
1
+ import { QueryOptions, UniqueIndex } from '@sprucelabs/data-stores';
2
2
  import { Query } from './postgres.types';
3
3
  export default class QueryBuilder {
4
4
  private constructor();
5
5
  static Builder(): QueryBuilder;
6
+ createIndex(tableName: string, index: UniqueIndex, isUnique?: boolean): BuiltQuery;
6
7
  find(tableName: string, query: Query, options?: QueryOptions): BuiltQuery;
7
8
  buildTableName(tableName: string): string;
8
9
  private conditionalQuote;
9
10
  private get shouldQuote();
10
11
  private optionallyBuildWhere;
11
- private buildSetClause;
12
+ private buildEqualityClause;
12
13
  private buildSetClausFor$Or;
13
14
  create(tableName: string, records: Record<string, any>[]): BuiltQuery;
14
15
  private log;
@@ -1,11 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.quote = void 0;
4
+ const data_stores_1 = require("@sprucelabs/data-stores");
5
+ const indexUtils_1 = require("./indexUtils");
4
6
  class QueryBuilder {
5
7
  constructor() { }
6
8
  static Builder() {
7
9
  return new this();
8
10
  }
11
+ createIndex(tableName, index, isUnique = false) {
12
+ const { fields, filter } = (0, data_stores_1.normalizeIndex)(index);
13
+ const indexName = (0, indexUtils_1.generateIndexName)(tableName, index);
14
+ const keys = (0, indexUtils_1.generateKeyExpressions)(fields);
15
+ let query = `CREATE ${isUnique ? `UNIQUE` : ''} INDEX ${indexName} ON "${tableName}" (${keys})`;
16
+ if (filter) {
17
+ const { sql: where } = this.optionallyBuildWhere(filter);
18
+ debugger;
19
+ query += where;
20
+ }
21
+ return { sql: query, values: [] };
22
+ }
9
23
  find(tableName, query, options) {
10
24
  const { includeFields, limit, skip, sort } = options !== null && options !== void 0 ? options : {};
11
25
  const fields = this.buildColumnListFromIncludeFields(includeFields);
@@ -32,7 +46,7 @@ class QueryBuilder {
32
46
  const values = [];
33
47
  const queryKeys = Object.keys(query);
34
48
  if ((queryKeys !== null && queryKeys !== void 0 ? queryKeys : []).length > 0) {
35
- const { set: columnSpecs, values: whereValues } = this.buildSetClause({
49
+ const { set: columnSpecs, values: whereValues } = this.buildEqualityClause({
36
50
  query,
37
51
  startingCount: startingPlaceholderCount,
38
52
  isBuildingWhere: true,
@@ -42,7 +56,7 @@ class QueryBuilder {
42
56
  }
43
57
  return { values, sql };
44
58
  }
45
- buildSetClause(options) {
59
+ buildEqualityClause(options) {
46
60
  const { query, startingCount = 0, placeholderTemplate = '${{count}}', isBuildingWhere = false, useIsNull = true, } = options;
47
61
  let placeholderCount = startingCount;
48
62
  const queryKeys = Object.keys(query);
@@ -58,6 +72,9 @@ class QueryBuilder {
58
72
  .map(() => `$${++placeholderCount}`)
59
73
  .join(', ')})`);
60
74
  }
75
+ else if (value === null || value === void 0 ? void 0 : value.$exists) {
76
+ set.push(`${formattedK} IS NOT NULL`);
77
+ }
61
78
  else if (value === null || value === void 0 ? void 0 : value.$regex) {
62
79
  values.push(this.normalizeValue(value.$regex));
63
80
  set.push(`${formattedK} ~* $${++placeholderCount}`);
@@ -89,7 +106,7 @@ class QueryBuilder {
89
106
  values.push(...orValues);
90
107
  }
91
108
  else if (k === '$push') {
92
- const sub = this.buildSetClause({
109
+ const sub = this.buildEqualityClause({
93
110
  query: value,
94
111
  startingCount: placeholderCount++,
95
112
  placeholderTemplate: '"{{fieldName}}" || ARRAY[${{count}}]',
@@ -127,7 +144,7 @@ class QueryBuilder {
127
144
  const ors = [];
128
145
  const orValues = [];
129
146
  value.forEach((q) => {
130
- const { set: where, values } = this.buildSetClause({
147
+ const { set: where, values } = this.buildEqualityClause({
131
148
  query: q,
132
149
  startingCount: placeholderCount++,
133
150
  });
@@ -232,7 +249,7 @@ class QueryBuilder {
232
249
  : includeFields.map((f) => quote(f)).join(', ');
233
250
  }
234
251
  update(tableName, query, updates, shouldReturnUpdatedRecords = true) {
235
- const { set: set, values } = this.buildSetClause({
252
+ const { set: set, values } = this.buildEqualityClause({
236
253
  query: updates,
237
254
  startingCount: 0,
238
255
  useIsNull: false,
@@ -30,15 +30,13 @@ export default class PostgresDatabase implements Database {
30
30
  connect(): Promise<void>;
31
31
  getUniqueIndexes(collectionName: string): Promise<UniqueIndex[]>;
32
32
  private executeGetIndexes;
33
- dropIndex(collectionName: string, fields: UniqueIndex): Promise<void>;
33
+ dropIndex(collectionName: string, index: UniqueIndex): Promise<void>;
34
34
  syncIndexes(collectionName: string, indexes: Index[]): Promise<void>;
35
35
  syncUniqueIndexes(collectionName: string, indexes: UniqueIndex[]): Promise<void>;
36
36
  private executeSyncIndexes;
37
37
  private areIndexesEqual;
38
38
  createUniqueIndex(collection: string, fields: UniqueIndex): Promise<void>;
39
39
  private executeCreateIndex;
40
- private generateKeyExpressions;
41
- private generateKeyExpression;
42
40
  private generateIndexName;
43
41
  close(): Promise<void>;
44
42
  isConnected(): boolean;
@@ -8,10 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { randomUUID } from 'crypto';
11
- import { DataStoresError, } from '@sprucelabs/data-stores';
11
+ import { DataStoresError, normalizeIndex, } from '@sprucelabs/data-stores';
12
12
  import { assertOptions } from '@sprucelabs/schema';
13
13
  import { Client } from 'pg';
14
- import QueryBuilder, { quote } from './QueryBuilder.js';
14
+ import { generateIndexName } from './indexUtils.js';
15
+ import QueryBuilder from './QueryBuilder.js';
15
16
  export default class PostgresDatabase {
16
17
  constructor(connectionString) {
17
18
  this.idCount = 1;
@@ -283,9 +284,9 @@ export default class PostgresDatabase {
283
284
  return uniqueIndexes;
284
285
  });
285
286
  }
286
- dropIndex(collectionName, fields) {
287
+ dropIndex(collectionName, index) {
287
288
  return __awaiter(this, void 0, void 0, function* () {
288
- const indexName = this.generateIndexName(collectionName, fields);
289
+ const indexName = this.generateIndexName(collectionName, index);
289
290
  const query = `DROP INDEX ${indexName}`;
290
291
  try {
291
292
  yield this.client.query({
@@ -295,7 +296,7 @@ export default class PostgresDatabase {
295
296
  catch (err) {
296
297
  throw new DataStoresError({
297
298
  code: 'INDEX_NOT_FOUND',
298
- missingIndex: fields,
299
+ missingIndex: normalizeIndex(index).fields,
299
300
  collectionName,
300
301
  });
301
302
  }
@@ -346,12 +347,10 @@ export default class PostgresDatabase {
346
347
  yield this.executeCreateIndex(collection, fields, isUnique);
347
348
  });
348
349
  }
349
- executeCreateIndex(collection, fields, isUnique) {
350
+ executeCreateIndex(collection, index, isUnique) {
350
351
  return __awaiter(this, void 0, void 0, function* () {
351
352
  var _a, _b;
352
- const indexName = this.generateIndexName(collection, fields);
353
- const keys = this.generateKeyExpressions(fields);
354
- const query = `CREATE ${isUnique ? `UNIQUE` : ''} INDEX ${indexName} ON "${collection}" (${keys})`;
353
+ const { sql: query } = this.queries.createIndex(collection, index, isUnique);
355
354
  try {
356
355
  yield this.client.query({
357
356
  text: query,
@@ -369,20 +368,8 @@ export default class PostgresDatabase {
369
368
  }
370
369
  });
371
370
  }
372
- generateKeyExpressions(fields) {
373
- return fields.map((f) => this.generateKeyExpression(f)).join(', ');
374
- }
375
- generateKeyExpression(field) {
376
- if (field.includes('.')) {
377
- const parts = field.split('.');
378
- return `(${parts[0]}->>'${parts[1]}')`;
379
- }
380
- return quote(field);
381
- }
382
- generateIndexName(collection, fields) {
383
- return `${collection}_${fields
384
- .map((f) => f.toLowerCase())
385
- .join('_')}${'_index'}`.replace(/\./g, '_');
371
+ generateIndexName(collection, index) {
372
+ return generateIndexName(collection, index);
386
373
  }
387
374
  close() {
388
375
  return __awaiter(this, void 0, void 0, function* () {
@@ -1,14 +1,15 @@
1
- import { QueryOptions } from '@sprucelabs/data-stores';
1
+ import { QueryOptions, UniqueIndex } from '@sprucelabs/data-stores';
2
2
  import { Query } from './postgres.types';
3
3
  export default class QueryBuilder {
4
4
  private constructor();
5
5
  static Builder(): QueryBuilder;
6
+ createIndex(tableName: string, index: UniqueIndex, isUnique?: boolean): BuiltQuery;
6
7
  find(tableName: string, query: Query, options?: QueryOptions): BuiltQuery;
7
8
  buildTableName(tableName: string): string;
8
9
  private conditionalQuote;
9
10
  private get shouldQuote();
10
11
  private optionallyBuildWhere;
11
- private buildSetClause;
12
+ private buildEqualityClause;
12
13
  private buildSetClausFor$Or;
13
14
  create(tableName: string, records: Record<string, any>[]): BuiltQuery;
14
15
  private log;
@@ -1,8 +1,22 @@
1
+ import { normalizeIndex, } from '@sprucelabs/data-stores';
2
+ import { generateIndexName, generateKeyExpressions } from './indexUtils.js';
1
3
  export default class QueryBuilder {
2
4
  constructor() { }
3
5
  static Builder() {
4
6
  return new this();
5
7
  }
8
+ createIndex(tableName, index, isUnique = false) {
9
+ const { fields, filter } = normalizeIndex(index);
10
+ const indexName = generateIndexName(tableName, index);
11
+ const keys = generateKeyExpressions(fields);
12
+ let query = `CREATE ${isUnique ? `UNIQUE` : ''} INDEX ${indexName} ON "${tableName}" (${keys})`;
13
+ if (filter) {
14
+ const { sql: where } = this.optionallyBuildWhere(filter);
15
+ debugger;
16
+ query += where;
17
+ }
18
+ return { sql: query, values: [] };
19
+ }
6
20
  find(tableName, query, options) {
7
21
  const { includeFields, limit, skip, sort } = options !== null && options !== void 0 ? options : {};
8
22
  const fields = this.buildColumnListFromIncludeFields(includeFields);
@@ -29,7 +43,7 @@ export default class QueryBuilder {
29
43
  const values = [];
30
44
  const queryKeys = Object.keys(query);
31
45
  if ((queryKeys !== null && queryKeys !== void 0 ? queryKeys : []).length > 0) {
32
- const { set: columnSpecs, values: whereValues } = this.buildSetClause({
46
+ const { set: columnSpecs, values: whereValues } = this.buildEqualityClause({
33
47
  query,
34
48
  startingCount: startingPlaceholderCount,
35
49
  isBuildingWhere: true,
@@ -39,7 +53,7 @@ export default class QueryBuilder {
39
53
  }
40
54
  return { values, sql };
41
55
  }
42
- buildSetClause(options) {
56
+ buildEqualityClause(options) {
43
57
  const { query, startingCount = 0, placeholderTemplate = '${{count}}', isBuildingWhere = false, useIsNull = true, } = options;
44
58
  let placeholderCount = startingCount;
45
59
  const queryKeys = Object.keys(query);
@@ -55,6 +69,9 @@ export default class QueryBuilder {
55
69
  .map(() => `$${++placeholderCount}`)
56
70
  .join(', ')})`);
57
71
  }
72
+ else if (value === null || value === void 0 ? void 0 : value.$exists) {
73
+ set.push(`${formattedK} IS NOT NULL`);
74
+ }
58
75
  else if (value === null || value === void 0 ? void 0 : value.$regex) {
59
76
  values.push(this.normalizeValue(value.$regex));
60
77
  set.push(`${formattedK} ~* $${++placeholderCount}`);
@@ -86,7 +103,7 @@ export default class QueryBuilder {
86
103
  values.push(...orValues);
87
104
  }
88
105
  else if (k === '$push') {
89
- const sub = this.buildSetClause({
106
+ const sub = this.buildEqualityClause({
90
107
  query: value,
91
108
  startingCount: placeholderCount++,
92
109
  placeholderTemplate: '"{{fieldName}}" || ARRAY[${{count}}]',
@@ -124,7 +141,7 @@ export default class QueryBuilder {
124
141
  const ors = [];
125
142
  const orValues = [];
126
143
  value.forEach((q) => {
127
- const { set: where, values } = this.buildSetClause({
144
+ const { set: where, values } = this.buildEqualityClause({
128
145
  query: q,
129
146
  startingCount: placeholderCount++,
130
147
  });
@@ -229,7 +246,7 @@ export default class QueryBuilder {
229
246
  : includeFields.map((f) => quote(f)).join(', ');
230
247
  }
231
248
  update(tableName, query, updates, shouldReturnUpdatedRecords = true) {
232
- const { set: set, values } = this.buildSetClause({
249
+ const { set: set, values } = this.buildEqualityClause({
233
250
  query: updates,
234
251
  startingCount: 0,
235
252
  useIsNull: false,
@@ -0,0 +1,4 @@
1
+ import { UniqueIndex } from '@sprucelabs/data-stores';
2
+ export declare function generateKeyExpression(field: string): string;
3
+ export declare function generateKeyExpressions(fields: string[]): string;
4
+ export declare function generateIndexName(collection: string, index: UniqueIndex): string;
@@ -0,0 +1,21 @@
1
+ import { normalizeIndex } from '@sprucelabs/data-stores';
2
+ import { quote } from './QueryBuilder.js';
3
+ export function generateKeyExpression(field) {
4
+ let result;
5
+ if (field.includes('.')) {
6
+ const parts = field.split('.');
7
+ result = `(${parts[0]}->>'${parts[1]}')`;
8
+ }
9
+ else {
10
+ result = quote(field);
11
+ }
12
+ return result;
13
+ }
14
+ export function generateKeyExpressions(fields) {
15
+ return fields.map((f) => generateKeyExpression(f)).join(', ');
16
+ }
17
+ export function generateIndexName(collection, index) {
18
+ return `${collection}_${normalizeIndex(index)
19
+ .fields.map((f) => f.toLowerCase())
20
+ .join('_')}${'_index'}`.replace(/\./g, '_');
21
+ }
@@ -0,0 +1,4 @@
1
+ import { UniqueIndex } from '@sprucelabs/data-stores';
2
+ export declare function generateKeyExpression(field: string): string;
3
+ export declare function generateKeyExpressions(fields: string[]): string;
4
+ export declare function generateIndexName(collection: string, index: UniqueIndex): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateIndexName = exports.generateKeyExpressions = exports.generateKeyExpression = void 0;
4
+ const data_stores_1 = require("@sprucelabs/data-stores");
5
+ const QueryBuilder_1 = require("./QueryBuilder");
6
+ function generateKeyExpression(field) {
7
+ let result;
8
+ if (field.includes('.')) {
9
+ const parts = field.split('.');
10
+ result = `(${parts[0]}->>'${parts[1]}')`;
11
+ }
12
+ else {
13
+ result = (0, QueryBuilder_1.quote)(field);
14
+ }
15
+ return result;
16
+ }
17
+ exports.generateKeyExpression = generateKeyExpression;
18
+ function generateKeyExpressions(fields) {
19
+ return fields.map((f) => generateKeyExpression(f)).join(', ');
20
+ }
21
+ exports.generateKeyExpressions = generateKeyExpressions;
22
+ function generateIndexName(collection, index) {
23
+ return `${collection}_${(0, data_stores_1.normalizeIndex)(index)
24
+ .fields.map((f) => f.toLowerCase())
25
+ .join('_')}${'_index'}`.replace(/\./g, '_');
26
+ }
27
+ exports.generateIndexName = generateIndexName;
package/package.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "@sprucelabs/postgres-data-store",
3
+ "version": "6.1.0",
3
4
  "description": "Postgres production and test adapters for @sprucelabs/data-stores",
4
5
  "skill": {
5
6
  "namespace": "postgres-data-store",
@@ -21,7 +22,6 @@
21
22
  "sprucebot",
22
23
  "sprucelabs"
23
24
  ],
24
- "version": "6.0.69",
25
25
  "scripts": {
26
26
  "build.ci": "yarn run build.tsc && yarn run build.resolve-paths && yarn run lint",
27
27
  "build.dev": "yarn run build.tsc --sourceMap ; yarn run resolve-paths.lint",
@@ -49,22 +49,22 @@
49
49
  "watch.tsc": "tsc -w"
50
50
  },
51
51
  "dependencies": {
52
- "@sprucelabs/data-stores": "^28.0.26",
53
- "@sprucelabs/schema": "^30.0.61",
52
+ "@sprucelabs/data-stores": "^28.1.11",
53
+ "@sprucelabs/schema": "^30.0.66",
54
54
  "pg": "^8.11.5"
55
55
  },
56
56
  "devDependencies": {
57
- "@sprucelabs/esm-postbuild": "^6.0.26",
58
- "@sprucelabs/jest-json-reporter": "^8.0.37",
59
- "@sprucelabs/resolve-path-aliases": "^2.0.27",
57
+ "@sprucelabs/esm-postbuild": "^6.0.28",
58
+ "@sprucelabs/jest-json-reporter": "^8.0.41",
59
+ "@sprucelabs/resolve-path-aliases": "^2.0.29",
60
60
  "@sprucelabs/semantic-release": "^5.0.1",
61
- "@sprucelabs/test": "^9.0.18",
62
- "@sprucelabs/test-utils": "^5.0.50",
63
- "@types/node": "^20.12.12",
61
+ "@sprucelabs/test": "^9.0.19",
62
+ "@sprucelabs/test-utils": "^5.0.55",
63
+ "@types/node": "^20.13.0",
64
64
  "@types/pg": "^8.11.6",
65
65
  "chokidar-cli": "^3.0.0",
66
66
  "eslint": "^9.3.0",
67
- "eslint-config-spruce": "^11.2.19",
67
+ "eslint-config-spruce": "^11.2.20",
68
68
  "jest": "^29.7.0",
69
69
  "jest-circus": "^29.7.0",
70
70
  "prettier": "^3.2.5",