prostgles-server 4.2.612 → 4.2.613

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 (49) hide show
  1. package/dist/DboBuilder/DboBuilder.d.ts +1 -1
  2. package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
  3. package/dist/DboBuilder/DboBuilder.js +1 -1
  4. package/dist/DboBuilder/DboBuilder.js.map +1 -1
  5. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -1
  6. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  7. package/dist/DboBuilder/joins/getInferredJoins.d.ts +4 -0
  8. package/dist/DboBuilder/joins/getInferredJoins.d.ts.map +1 -0
  9. package/dist/DboBuilder/joins/getInferredJoins.js +55 -0
  10. package/dist/DboBuilder/joins/getInferredJoins.js.map +1 -0
  11. package/dist/DboBuilder/joins/prepareShortestJoinPaths.d.ts +12 -0
  12. package/dist/DboBuilder/joins/prepareShortestJoinPaths.d.ts.map +1 -0
  13. package/dist/DboBuilder/joins/prepareShortestJoinPaths.js +165 -0
  14. package/dist/DboBuilder/joins/prepareShortestJoinPaths.js.map +1 -0
  15. package/dist/DboBuilder/joins/prepareShortestJoinPaths.spec.d.ts.map +1 -0
  16. package/dist/DboBuilder/joins/prepareShortestJoinPaths.spec.js +67 -0
  17. package/dist/DboBuilder/joins/prepareShortestJoinPaths.spec.js.map +1 -0
  18. package/dist/DboBuilder/joins/shortestPath.d.ts.map +1 -0
  19. package/dist/{shortestPath.js → DboBuilder/joins/shortestPath.js} +11 -11
  20. package/dist/DboBuilder/joins/shortestPath.js.map +1 -0
  21. package/dist/ProstglesTypes.d.ts +4 -3
  22. package/dist/ProstglesTypes.d.ts.map +1 -1
  23. package/dist/utils/utils.d.ts +1 -0
  24. package/dist/utils/utils.d.ts.map +1 -1
  25. package/dist/utils/utils.js +8 -3
  26. package/dist/utils/utils.js.map +1 -1
  27. package/lib/DboBuilder/DboBuilder.ts +13 -10
  28. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +1 -1
  29. package/lib/DboBuilder/joins/getInferredJoins.ts +59 -0
  30. package/lib/DboBuilder/joins/prepareShortestJoinPaths.spec.ts +72 -0
  31. package/lib/DboBuilder/joins/prepareShortestJoinPaths.ts +205 -0
  32. package/lib/{shortestPath.ts → DboBuilder/joins/shortestPath.ts} +14 -13
  33. package/lib/ProstglesTypes.ts +4 -3
  34. package/lib/utils/utils.ts +6 -0
  35. package/package.json +1 -1
  36. package/tsconfig.json +1 -1
  37. package/dist/DboBuilder/prepareShortestJoinPaths.d.ts +0 -12
  38. package/dist/DboBuilder/prepareShortestJoinPaths.d.ts.map +0 -1
  39. package/dist/DboBuilder/prepareShortestJoinPaths.js +0 -186
  40. package/dist/DboBuilder/prepareShortestJoinPaths.js.map +0 -1
  41. package/dist/DboBuilder/prepareShortestJoinPaths.spec.d.ts.map +0 -1
  42. package/dist/DboBuilder/prepareShortestJoinPaths.spec.js +0 -30
  43. package/dist/DboBuilder/prepareShortestJoinPaths.spec.js.map +0 -1
  44. package/dist/shortestPath.d.ts.map +0 -1
  45. package/dist/shortestPath.js.map +0 -1
  46. package/lib/DboBuilder/prepareShortestJoinPaths.spec.ts +0 -29
  47. package/lib/DboBuilder/prepareShortestJoinPaths.ts +0 -225
  48. /package/dist/DboBuilder/{prepareShortestJoinPaths.spec.d.ts → joins/prepareShortestJoinPaths.spec.d.ts} +0 -0
  49. /package/dist/{shortestPath.d.ts → DboBuilder/joins/shortestPath.d.ts} +0 -0
@@ -11,7 +11,7 @@ import type { PublishParser } from "../PublishParser/PublishParser";
11
11
  import type { OnCommitCallback } from "../PublishParser/publishTypesAndUtils";
12
12
  import type { ServerFunctionDefinition } from "../PublishParser/defineServerFunction";
13
13
  import { getQueryErrorPositionInfo } from "../TableConfig/runSQLFile";
14
- import type { Graph } from "../shortestPath";
14
+ import type { Graph } from "./joins/shortestPath";
15
15
  import { clone } from "../utils/utils";
16
16
  import type {
17
17
  DBHandlerServer,
@@ -31,7 +31,7 @@ import {
31
31
  getConstraints,
32
32
  getSerializedClientErrorFromPGError,
33
33
  } from "./dboBuilderUtils";
34
- import { prepareShortestJoinPaths } from "./prepareShortestJoinPaths";
34
+ import { prepareShortestJoinPaths } from "./joins/prepareShortestJoinPaths";
35
35
  import { cacheDBTypes, runSQL } from "./runSql/runSQL";
36
36
  import { getDetailedFieldInfo, type getDbTypes } from "./runSql/runSqlUtils";
37
37
  import { getTablesForSchemaPostgresSQL } from "./schema/getTablesForSchemaPostgresSQL";
@@ -140,10 +140,7 @@ export class DboBuilder {
140
140
 
141
141
  onSchemaChange?: (event: { command: string; query: string }) => void;
142
142
 
143
- private readonly onCommitCallbacksByTransaction = new WeakMap<
144
- object,
145
- OnCommitCallback[]
146
- >();
143
+ private readonly onCommitCallbacksByTransaction = new WeakMap<object, OnCommitCallback[]>();
147
144
 
148
145
  registerOnCommitCallback = (transaction: object, callback: OnCommitCallback) => {
149
146
  const callbacks = this.onCommitCallbacksByTransaction.get(transaction);
@@ -250,9 +247,12 @@ export class DboBuilder {
250
247
  this.checkingCanSubscribe = false;
251
248
  }
252
249
  const start = Date.now();
253
- const tablesOrViewsReq = await getTablesForSchemaPostgresSQL({ db: this.prostgles.dbForSchema! }, {
254
- schemaFilter: this.prostgles.opts.schemaFilter,
255
- });
250
+ const tablesOrViewsReq = await getTablesForSchemaPostgresSQL(
251
+ { db: this.prostgles.dbForSchema! },
252
+ {
253
+ schemaFilter: this.prostgles.opts.schemaFilter,
254
+ },
255
+ );
256
256
  await this.prostgles.opts.onLog?.({
257
257
  type: "debug",
258
258
  command: "DboBuilder.getTablesForSchemaPostgresSQL",
@@ -262,7 +262,10 @@ export class DboBuilder {
262
262
  const tablesOrViews = tablesOrViewsReq.result;
263
263
  this.tablesOrViews = tablesOrViews;
264
264
 
265
- this.constraints = await getConstraints(this.prostgles.dbForSchema!, this.prostgles.opts.schemaFilter);
265
+ this.constraints = await getConstraints(
266
+ this.prostgles.dbForSchema!,
267
+ this.prostgles.opts.schemaFilter,
268
+ );
266
269
  await this.prepareShortestJoinPaths();
267
270
 
268
271
  this.dbo = {};
@@ -13,7 +13,7 @@ import type { TableEvent } from "../../Logging";
13
13
  import type { DB } from "../../Prostgles";
14
14
  import type { Join } from "../../ProstglesTypes";
15
15
  import type { ParsedTableRule } from "../../PublishParser/PublishParser";
16
- import type { Graph } from "../../shortestPath";
16
+ import type { Graph } from "../joins/shortestPath";
17
17
  import type { DboBuilder, Filter, LocalParams, TableHandlers } from "../DboBuilder";
18
18
  import { getSerializedClientErrorFromPGError } from "../DboBuilder";
19
19
  import type { TableSchema } from "../DboBuilderTypes";
@@ -0,0 +1,59 @@
1
+ import type { TableSchema } from "../DboBuilderTypes";
2
+ import type { Join } from "../../ProstglesTypes";
3
+ import { sortedArraysMatch } from "../../utils/utils";
4
+ import { isEqual } from "prostgles-types";
5
+
6
+ export const getInferredJoins = (schema: TableSchema[]): Join[] => {
7
+ const joins: Join[] = [];
8
+ const upsertJoin = (
9
+ t1: string,
10
+ t2: string,
11
+ cols: { col1: string; col2: string }[],
12
+ type: Join["type"],
13
+ ) => {
14
+ const existingIdx = joins.findIndex((j) => sortedArraysMatch(j.tables, [t1, t2]));
15
+ const existing = joins[existingIdx];
16
+ const normalCond = cols.reduce((a, v) => ({ ...a, [v.col1]: v.col2 }), {});
17
+ const revertedCond = cols.reduce((a, v) => ({ ...a, [v.col2]: v.col1 }), {});
18
+ if (existing) {
19
+ const isLTR = existing.tables[0] === t1;
20
+ const cond = isLTR ? normalCond : revertedCond;
21
+
22
+ /** At some point we should add relationship type to EACH JOIN CONDITION GROUP */
23
+ // const fixedType = isLTR? type : type.split("").reverse().join("") as Join["type"];
24
+
25
+ /** Avoid duplicates */
26
+ if (!existing.on.some((existingOnCondition) => isEqual(existingOnCondition, cond))) {
27
+ existing.on.push(cond);
28
+ joins[existingIdx] = existing;
29
+ }
30
+ } else {
31
+ joins.push({
32
+ tables: [t1, t2],
33
+ on: [normalCond],
34
+ type,
35
+ });
36
+ }
37
+ };
38
+ schema.map((tov) => {
39
+ tov.columns.map((col) => {
40
+ if (col.references) {
41
+ col.references.forEach((r) => {
42
+ const joinCols = r.cols.map((c, i) => ({
43
+ col1: c,
44
+ col2: r.fcols[i]!,
45
+ }));
46
+ let type: Join["type"] = "one-many";
47
+ const ftablePKeys = schema
48
+ .find(({ name }) => name === r.ftable)
49
+ ?.columns.filter((fcol) => fcol.is_pkey);
50
+ if (ftablePKeys?.length && ftablePKeys.every((fkey) => r.fcols.includes(fkey.name))) {
51
+ type = "one-one";
52
+ }
53
+ upsertJoin(tov.name, r.ftable, joinCols, type);
54
+ });
55
+ }
56
+ });
57
+ });
58
+ return joins;
59
+ };
@@ -0,0 +1,72 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import type { DboBuilder } from "../DboBuilder";
4
+ import { prepareShortestJoinPaths } from "./prepareShortestJoinPaths";
5
+ import type { Join } from "../../ProstglesTypes";
6
+
7
+ void test("duplicate configured table pairs are rejected even during table configuration", () => {
8
+ const join: Join = {
9
+ tables: ["conditions", "members"],
10
+ on: [{ project_id: "project_id" }],
11
+ type: "many-many",
12
+ };
13
+ for (const preparingTableConfig of [false, true]) {
14
+ for (const override of [false, true]) {
15
+ for (const tables of [join.tables, [...join.tables].reverse() as Join["tables"]]) {
16
+ const builder = {
17
+ prostgles: {
18
+ preparingTableConfig,
19
+ opts: { joins: [join, { ...join, tables, override }] },
20
+ },
21
+ tablesOrViews: [],
22
+ } as unknown as DboBuilder;
23
+ assert.throws(
24
+ () => prepareShortestJoinPaths(builder),
25
+ /Duplicate configured join for table pair/,
26
+ );
27
+ }
28
+ }
29
+ }
30
+ });
31
+
32
+ void test("configured joins are deferred only during table configuration", () => {
33
+ const builder = {
34
+ prostgles: {
35
+ preparingTableConfig: true,
36
+ opts: {
37
+ joins: [
38
+ {
39
+ tables: ["conditions", "members"],
40
+ on: [{ project_id: "project_id" }],
41
+ type: "many-many",
42
+ },
43
+ ],
44
+ },
45
+ },
46
+ tablesOrViews: [],
47
+ } as unknown as DboBuilder;
48
+ assert.deepEqual(prepareShortestJoinPaths(builder).joins, []);
49
+ builder.prostgles.preparingTableConfig = false;
50
+ assert.throws(
51
+ () => prepareShortestJoinPaths(builder),
52
+ (error: unknown) => typeof error === "string" && error.includes("Table not found: conditions"),
53
+ );
54
+ });
55
+
56
+ void test("existing configured joins remain available during table configuration", () => {
57
+ const join = {
58
+ tables: ["conditions", "members"],
59
+ on: [{ project_id: "project_id" }],
60
+ type: "many-many",
61
+ };
62
+ const builder = {
63
+ prostgles: { preparingTableConfig: true, opts: { joins: [join] } },
64
+ tablesOrViews: ["conditions", "members"].map((name) => ({
65
+ name,
66
+ columns: [{ name: "project_id" }],
67
+ })),
68
+ } as unknown as DboBuilder;
69
+ assert.deepEqual(prepareShortestJoinPaths(builder).joins, [join]);
70
+ builder.prostgles.preparingTableConfig = false;
71
+ assert.deepEqual(prepareShortestJoinPaths(builder).joins, [join]);
72
+ });
@@ -0,0 +1,205 @@
1
+ import { isEqual, reverseJoinOn } from "prostgles-types";
2
+ import type { DboBuilder } from "../DboBuilder";
3
+ import type { Join } from "../../ProstglesTypes";
4
+ import { JOIN_TYPES } from "../../ProstglesTypes";
5
+ import type { Graph } from "./shortestPath";
6
+ import { findShortestPath } from "./shortestPath";
7
+ import type { JoinPaths } from "../ViewHandler/ViewHandler";
8
+ import { getInferredJoins } from "./getInferredJoins";
9
+ import { sortedArraysMatch } from "../../utils/utils";
10
+
11
+ type Result = {
12
+ joinGraph?: Graph | undefined;
13
+ joins: Join[];
14
+ shortestJoinPaths: JoinPaths;
15
+ };
16
+
17
+ export const prepareShortestJoinPaths = (dboBuilder: DboBuilder): Result => {
18
+ if (!dboBuilder.prostgles.opts.joins) {
19
+ return {
20
+ joins: [],
21
+ shortestJoinPaths: [],
22
+ };
23
+ }
24
+
25
+ let joinConfig = dboBuilder.prostgles.opts.joins;
26
+ if (Array.isArray(joinConfig)) {
27
+ joinConfig.forEach((join, index, configured) => {
28
+ const duplicate = configured
29
+ .slice(0, index)
30
+ .some((existing) => isEqual(existing.tables.toSorted(), join.tables.toSorted()));
31
+ if (duplicate) {
32
+ throw new Error(
33
+ `Duplicate configured join for table pair ${JSON.stringify(join.tables)}. Combine conditions in a single Join.on.`,
34
+ );
35
+ }
36
+ });
37
+ }
38
+ if (!dboBuilder.tablesOrViews) {
39
+ throw new Error("Could not create join config. this.tablesOrViews missing");
40
+ }
41
+
42
+ // The initial DBO is needed by tableConfig before its tables/columns exist.
43
+ // Defer only joins that cannot be resolved yet; the final rebuild validates all.
44
+ if (Array.isArray(joinConfig) && dboBuilder.prostgles.preparingTableConfig) {
45
+ const tables = dboBuilder.tablesOrViews;
46
+ joinConfig = joinConfig.filter((join) =>
47
+ join.tables.every((name, index) => {
48
+ const table = tables.find((candidate) => candidate.name === name);
49
+ return (
50
+ table &&
51
+ join.on.every((on) =>
52
+ (index === 0 ? Object.keys(on) : Object.values(on)).every((column) =>
53
+ table.columns.some((candidate) => candidate.name === column),
54
+ ),
55
+ )
56
+ );
57
+ }),
58
+ );
59
+ }
60
+ const inferredJoins = getInferredJoins(dboBuilder.tablesOrViews);
61
+ if (joinConfig === "inferred") {
62
+ joinConfig = inferredJoins;
63
+ } else if (Array.isArray(joinConfig)) {
64
+ joinConfig = mergeJoins(inferredJoins, joinConfig);
65
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
66
+ } else if (joinConfig) {
67
+ throw new Error(
68
+ "Unexpected joins init param. Expecting 'inferred' OR joinConfig but got: " +
69
+ JSON.stringify(joinConfig),
70
+ );
71
+ }
72
+ const joins = JSON.parse(JSON.stringify(joinConfig)) as Join[];
73
+
74
+ // Validate joins
75
+ try {
76
+ const tovNames = dboBuilder.tablesOrViews.map((t) => t.name);
77
+
78
+ // 2 find incorrect tables
79
+ const missing = joins.flatMap((j) => j.tables).find((t) => !tovNames.includes(t));
80
+ if (missing) {
81
+ throw "Table not found: " + missing;
82
+ }
83
+
84
+ // 3 find incorrect fields
85
+ joins.map(({ tables, on }) => {
86
+ const t1 = tables[0],
87
+ t2 = tables[1];
88
+ on.map((cond) => {
89
+ const f1s = Object.keys(cond),
90
+ f2s = Object.values(cond);
91
+ [
92
+ [t1, f1s],
93
+ [t2, f2s],
94
+ ].map((v) => {
95
+ const t = <string>v[0],
96
+ f = <string[]>v[1];
97
+
98
+ const tov = dboBuilder.tablesOrViews!.find((_t) => _t.name === t);
99
+ if (!tov) throw "Table not found: " + t;
100
+ const m1 = f.filter((k) => !tov.columns.map((c) => c.name).includes(k));
101
+ if (m1.length) {
102
+ throw `Table ${t}(${tov.columns.map((c) => c.name).join()}) has no fields named: ${m1.join()}`;
103
+ }
104
+ });
105
+ });
106
+ });
107
+
108
+ // 4 find incorrect/missing join types
109
+ const expected_types =
110
+ " \n\n-> Expecting: " + JOIN_TYPES.map((t) => JSON.stringify(t)).join(` | `);
111
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
112
+ const mt = joins.find((j) => !j.type);
113
+ if (mt) throw "Join type missing for: " + JSON.stringify(mt, null, 2) + expected_types;
114
+
115
+ const it = joins.find((j) => !JOIN_TYPES.includes(j.type));
116
+ if (it) throw "Incorrect join type for: " + JSON.stringify(it, null, 2) + expected_types;
117
+ } catch (e: any) {
118
+ const errMsg =
119
+ ((joinConfig as any) === "inferred" ? "INFERRED " : "") + "JOINS VALIDATION ERROR \n-> " + e;
120
+ throw errMsg;
121
+ }
122
+
123
+ // Make joins graph
124
+ const joinGraph: Graph = {};
125
+ joins.forEach(({ tables }) => {
126
+ const _t = tables.slice().sort(),
127
+ t1 = _t[0]!,
128
+ t2 = _t[1]!;
129
+
130
+ if (t1 === t2) return;
131
+
132
+ joinGraph[t1] ??= {};
133
+ joinGraph[t1][t2] = 1;
134
+
135
+ joinGraph[t2] ??= {};
136
+ joinGraph[t2][t1] = 1;
137
+ });
138
+ const tables = Array.from(new Set(joins.flatMap((t) => t.tables)));
139
+ const shortestJoinPaths: JoinPaths = [];
140
+ tables.forEach((t1) => {
141
+ tables.forEach((t2) => {
142
+ /** Prevent recursion */
143
+ if (
144
+ t1 === t2 ||
145
+ shortestJoinPaths.some((jp) => {
146
+ if (sortedArraysMatch([jp.t1, jp.t2], [t1, t2])) {
147
+ const shortestPath = findShortestPath(joinGraph, t1, t2);
148
+ if (sortedArraysMatch(shortestPath.path, jp.path)) {
149
+ return true;
150
+ }
151
+ }
152
+ })
153
+ ) {
154
+ return;
155
+ }
156
+
157
+ const calculatedPath = findShortestPath(joinGraph, t1, t2);
158
+ if (!(calculatedPath.distance < Infinity)) return;
159
+
160
+ const existing1 = shortestJoinPaths.find((j) => j.t1 === t1 && j.t2 === t2);
161
+ if (!existing1) {
162
+ shortestJoinPaths.push({ t1, t2, path: calculatedPath.path.slice() });
163
+ }
164
+
165
+ const existing2 = shortestJoinPaths.find((j) => j.t2 === t1 && j.t1 === t2);
166
+ if (!existing2) {
167
+ shortestJoinPaths.push({
168
+ t1: t2,
169
+ t2: t1,
170
+ path: calculatedPath.path.slice().reverse(),
171
+ });
172
+ }
173
+ });
174
+ });
175
+ return {
176
+ joins,
177
+ shortestJoinPaths,
178
+ joinGraph,
179
+ };
180
+ };
181
+
182
+ const mergeJoins = (inferred: Join[], configured: Join[]): Join[] => {
183
+ const joins = [...inferred];
184
+ configured.forEach((join) => {
185
+ const index = joins.findIndex((existing) =>
186
+ isEqual(existing.tables.toSorted(), join.tables.toSorted()),
187
+ );
188
+ const existing = joins[index];
189
+ const previousOn =
190
+ !existing || join.override ? []
191
+ : existing.tables[0] === join.tables[0] ? existing.on
192
+ : reverseJoinOn(existing.on);
193
+ const on = [...previousOn, ...join.on].filter(
194
+ (condition, index, conditions) =>
195
+ conditions.findIndex((candidate) => isEqual(candidate, condition)) === index,
196
+ );
197
+ const merged = { ...join, on };
198
+ if (existing) {
199
+ joins[index] = merged;
200
+ } else {
201
+ joins.push(merged);
202
+ }
203
+ });
204
+ return joins;
205
+ };
@@ -2,17 +2,6 @@
2
2
  /* eslint-disable */
3
3
  import { AnyObject } from "prostgles-types";
4
4
 
5
- const shortestDistanceNode = (distances: Graph, visited: Graph) => {
6
- let shortest = null;
7
-
8
- for (const node in distances) {
9
- const currentIsShortest = shortest === null || distances[node] < distances[shortest];
10
- if (currentIsShortest && !visited.includes(node)) {
11
- shortest = node;
12
- }
13
- }
14
- return shortest;
15
- };
16
5
  export type Graph = {
17
6
  [key: string]: { [key: string]: number };
18
7
  };
@@ -20,7 +9,7 @@ export type Graph = {
20
9
  export const findShortestPath = (
21
10
  graph: Graph,
22
11
  startNode: string,
23
- endNode: string
12
+ endNode: string,
24
13
  ): { distance: number; path: string[] } => {
25
14
  // establish object for recording distances from the start node
26
15
  let distances: AnyObject = {};
@@ -87,7 +76,19 @@ export const findShortestPath = (
87
76
  return results;
88
77
  };
89
78
 
90
- /* Usage:
79
+ const shortestDistanceNode = (distances: Graph, visited: Graph) => {
80
+ let shortest = null;
81
+
82
+ for (const node in distances) {
83
+ const currentIsShortest = shortest === null || distances[node] < distances[shortest];
84
+ if (currentIsShortest && !visited.includes(node)) {
85
+ shortest = node;
86
+ }
87
+ }
88
+ return shortest;
89
+ };
90
+
91
+ /* Example:
91
92
 
92
93
  const graph = {
93
94
  start: { A: 5, B: 2 },
@@ -94,6 +94,8 @@ export type Join = {
94
94
  tables: [string, string];
95
95
  on: { [key: string]: string }[]; // Allow multi references to table
96
96
  type: (typeof JOIN_TYPES)[number];
97
+ /** Replace inferred joins for this table pair. Defaults to false. */
98
+ override?: boolean;
97
99
  };
98
100
  type Joins = Join[] | "inferred";
99
101
 
@@ -203,9 +205,8 @@ export type ProstglesInitOptions<
203
205
  testRulesOnConnect?: boolean;
204
206
 
205
207
  /**
206
- * Allows defining table relationships that can then be used in filters and data inserts:
207
- * - `inferred` - uses the foreign keys to infer the joins
208
- * - `Join[]` - specifies the joins manually
208
+ * Allows defining custom table relationships that can then be used in filters and data inserts.
209
+ * By default FKs are used to infer the joins.
209
210
  */
210
211
  joins?: Joins;
211
212
 
@@ -1,3 +1,5 @@
1
+ import { isEqual } from "prostgles-types";
2
+
1
3
  export { get } from "prostgles-types";
2
4
  export const clone = <T extends any[] | Record<string, any>>(obj: T): T => {
3
5
  if (typeof structuredClone !== "undefined") {
@@ -27,3 +29,7 @@ const canBeUsedAsIsInTypescript = (str: string): boolean => {
27
29
  };
28
30
 
29
31
  export const isArray = <T>(data: T): data is Extract<T, readonly unknown[]> => Array.isArray(data);
32
+
33
+ export const sortedArraysMatch = (a: string[], b: string[]): boolean => {
34
+ return isEqual(a.toSorted(), b.toSorted());
35
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "4.2.612",
3
+ "version": "4.2.613",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/tsconfig.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "compilerOptions": {
4
4
  "target": "es2022",
5
5
  "lib": [
6
- "es2022"
6
+ "ES2023"
7
7
  ],
8
8
  "strict": true,
9
9
  "module": "node16",
@@ -1,12 +0,0 @@
1
- import type { DboBuilder } from "../DboBuilder/DboBuilder";
2
- import type { Join } from "../ProstglesTypes";
3
- import type { Graph } from "../shortestPath";
4
- import type { JoinPaths } from "./ViewHandler/ViewHandler";
5
- type Result = {
6
- joinGraph?: Graph | undefined;
7
- joins: Join[];
8
- shortestJoinPaths: JoinPaths;
9
- };
10
- export declare function prepareShortestJoinPaths(dboBuilder: DboBuilder): Promise<Result>;
11
- export {};
12
- //# sourceMappingURL=prepareShortestJoinPaths.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prepareShortestJoinPaths.d.ts","sourceRoot":"","sources":["../../lib/DboBuilder/prepareShortestJoinPaths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAG5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,KAAK,MAAM,GAAG;IACZ,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,iBAAiB,EAAE,SAAS,CAAC;CAC9B,CAAC;AACF,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAwJtF"}