@digitraffic/common 2026.5.27-1 → 2026.6.30-1
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.
- package/README.md +2 -0
- package/dist/__test__/utils/lead-time-logging.test.d.ts +1 -0
- package/dist/__test__/utils/lead-time-logging.test.js +153 -0
- package/dist/aws/infra/canaries/database-checker.js +2 -3
- package/dist/aws/runtime/secrets/proxy-holder.d.ts +6 -1
- package/dist/aws/runtime/secrets/proxy-holder.js +6 -4
- package/dist/aws/runtime/secrets/rds-holder.d.ts +4 -1
- package/dist/aws/runtime/secrets/rds-holder.js +6 -4
- package/dist/database/database.d.ts +1 -1
- package/dist/database/database.js +1 -1
- package/dist/utils/lead-time-logging.d.ts +10 -0
- package/dist/utils/lead-time-logging.js +33 -0
- package/package.json +36 -35
package/README.md
CHANGED
|
@@ -49,12 +49,14 @@ To update all dependencies to the latest versions:
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
pnpm up --latest
|
|
52
|
+
pnpm audit # -> fix high
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
To update both normal dependencies and `peerDependencies` in one command, use:
|
|
55
56
|
|
|
56
57
|
```bash
|
|
57
58
|
pnpm deps:update-all
|
|
59
|
+
pnpm audit # -> fix high
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
What `pnpm deps:update-all` does:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { logger } from "../../aws/runtime/dt-logger-default.js";
|
|
3
|
+
import { logLeadTime, logLeadTimes } from "../../utils/lead-time-logging.js";
|
|
4
|
+
describe("lead-time-logging", () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
vi.restoreAllMocks();
|
|
7
|
+
});
|
|
8
|
+
test("logLeadTime logs expected payload", () => {
|
|
9
|
+
const infoSpy = vi
|
|
10
|
+
.spyOn(logger, "info")
|
|
11
|
+
.mockImplementation(() => undefined);
|
|
12
|
+
const errorSpy = vi
|
|
13
|
+
.spyOn(logger, "error")
|
|
14
|
+
.mockImplementation(() => undefined);
|
|
15
|
+
logLeadTime("lead-time", "test-target", 123);
|
|
16
|
+
expect(infoSpy).toHaveBeenCalledTimes(1);
|
|
17
|
+
expect(infoSpy).toHaveBeenCalledWith({
|
|
18
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
19
|
+
customLeadTime: true,
|
|
20
|
+
customName: "lead-time",
|
|
21
|
+
customTarget: "test-target",
|
|
22
|
+
tookMs: 123,
|
|
23
|
+
});
|
|
24
|
+
expect(errorSpy).toHaveBeenCalledTimes(0);
|
|
25
|
+
});
|
|
26
|
+
test("logLeadTime merges extra fields", () => {
|
|
27
|
+
const infoSpy = vi
|
|
28
|
+
.spyOn(logger, "info")
|
|
29
|
+
.mockImplementation(() => undefined);
|
|
30
|
+
logLeadTime("mqtt-time", "mqtt", 88, {
|
|
31
|
+
customSource: "mqtt",
|
|
32
|
+
customRetriesCount: 2,
|
|
33
|
+
});
|
|
34
|
+
expect(infoSpy).toHaveBeenCalledTimes(1);
|
|
35
|
+
expect(infoSpy).toHaveBeenCalledWith({
|
|
36
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
37
|
+
customLeadTime: true,
|
|
38
|
+
customName: "mqtt-time",
|
|
39
|
+
customTarget: "mqtt",
|
|
40
|
+
tookMs: 88,
|
|
41
|
+
customSource: "mqtt",
|
|
42
|
+
customRetriesCount: 2,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
test("logLeadTime logs error if logger.info throws", () => {
|
|
46
|
+
const infoError = new Error("boom");
|
|
47
|
+
vi.spyOn(logger, "info").mockImplementation(() => {
|
|
48
|
+
throw infoError;
|
|
49
|
+
});
|
|
50
|
+
const errorSpy = vi
|
|
51
|
+
.spyOn(logger, "error")
|
|
52
|
+
.mockImplementation(() => undefined);
|
|
53
|
+
logLeadTime("process-time", "target", 10);
|
|
54
|
+
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(errorSpy).toHaveBeenCalledWith({
|
|
56
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
57
|
+
message: "Error logging lead time",
|
|
58
|
+
error: infoError,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
test("logLeadTimes logs only lead-time when only leadTimeMs is safe", () => {
|
|
62
|
+
const infoSpy = vi
|
|
63
|
+
.spyOn(logger, "info")
|
|
64
|
+
.mockImplementation(() => undefined);
|
|
65
|
+
logLeadTimes({ target: "x", leadTimeMs: 10 });
|
|
66
|
+
expect(infoSpy).toHaveBeenCalledTimes(1);
|
|
67
|
+
expect(infoSpy).toHaveBeenNthCalledWith(1, {
|
|
68
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
69
|
+
customLeadTime: true,
|
|
70
|
+
customName: "lead-time",
|
|
71
|
+
customTarget: "x",
|
|
72
|
+
tookMs: 10,
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
test("logLeadTimes logs only process-time when only processTimeMs is safe", () => {
|
|
76
|
+
const infoSpy = vi
|
|
77
|
+
.spyOn(logger, "info")
|
|
78
|
+
.mockImplementation(() => undefined);
|
|
79
|
+
logLeadTimes({ target: "x", processTimeMs: 20 });
|
|
80
|
+
expect(infoSpy).toHaveBeenCalledTimes(1);
|
|
81
|
+
expect(infoSpy).toHaveBeenNthCalledWith(1, {
|
|
82
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
83
|
+
customLeadTime: true,
|
|
84
|
+
customName: "process-time",
|
|
85
|
+
customTarget: "x",
|
|
86
|
+
tookMs: 20,
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
test("logLeadTimes logs both in order with extra fields", () => {
|
|
90
|
+
const infoSpy = vi
|
|
91
|
+
.spyOn(logger, "info")
|
|
92
|
+
.mockImplementation(() => undefined);
|
|
93
|
+
const input = {
|
|
94
|
+
target: "device",
|
|
95
|
+
leadTimeMs: 11,
|
|
96
|
+
processTimeMs: 22,
|
|
97
|
+
extraFields: { customSource: "mqtt", customPartition: 3 },
|
|
98
|
+
};
|
|
99
|
+
logLeadTimes(input);
|
|
100
|
+
expect(infoSpy).toHaveBeenCalledTimes(2);
|
|
101
|
+
expect(infoSpy).toHaveBeenNthCalledWith(1, {
|
|
102
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
103
|
+
customLeadTime: true,
|
|
104
|
+
customName: "lead-time",
|
|
105
|
+
customTarget: "device",
|
|
106
|
+
tookMs: 11,
|
|
107
|
+
customSource: "mqtt",
|
|
108
|
+
customPartition: 3,
|
|
109
|
+
});
|
|
110
|
+
expect(infoSpy).toHaveBeenNthCalledWith(2, {
|
|
111
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
112
|
+
customLeadTime: true,
|
|
113
|
+
customName: "process-time",
|
|
114
|
+
customTarget: "device",
|
|
115
|
+
tookMs: 22,
|
|
116
|
+
customSource: "mqtt",
|
|
117
|
+
customPartition: 3,
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
test("logLeadTimes ignores non-safe values", () => {
|
|
121
|
+
const infoSpy = vi
|
|
122
|
+
.spyOn(logger, "info")
|
|
123
|
+
.mockImplementation(() => undefined);
|
|
124
|
+
logLeadTimes({
|
|
125
|
+
target: "x",
|
|
126
|
+
leadTimeMs: 1.5,
|
|
127
|
+
processTimeMs: Number.MAX_SAFE_INTEGER + 1,
|
|
128
|
+
});
|
|
129
|
+
logLeadTimes({
|
|
130
|
+
target: "x",
|
|
131
|
+
leadTimeMs: Number.NaN,
|
|
132
|
+
processTimeMs: Infinity,
|
|
133
|
+
});
|
|
134
|
+
logLeadTimes({ target: "x" });
|
|
135
|
+
expect(infoSpy).toHaveBeenCalledTimes(0);
|
|
136
|
+
});
|
|
137
|
+
test("logLeadTimes logs negative safe integer values", () => {
|
|
138
|
+
const infoSpy = vi
|
|
139
|
+
.spyOn(logger, "info")
|
|
140
|
+
.mockImplementation(() => undefined);
|
|
141
|
+
logLeadTimes({ target: "x", leadTimeMs: -5 });
|
|
142
|
+
expect(infoSpy).toHaveBeenCalledTimes(1);
|
|
143
|
+
expect(infoSpy).toHaveBeenNthCalledWith(1, {
|
|
144
|
+
method: "LeadTimeLogging.logLeadTime",
|
|
145
|
+
customLeadTime: true,
|
|
146
|
+
customName: "lead-time",
|
|
147
|
+
customTarget: "x",
|
|
148
|
+
tookMs: -5,
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
// clean comment
|
|
153
|
+
//# sourceMappingURL=lead-time-logging.test.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import synthetics from "Synthetics";
|
|
2
2
|
import { inDatabaseReadonly } from "../../../database/database.js";
|
|
3
|
-
import { getEnvVariable } from "../../../utils/utils.js";
|
|
4
3
|
import { logger } from "../../runtime/dt-logger-default.js";
|
|
5
4
|
import { ProxyHolder } from "../../runtime/secrets/proxy-holder.js";
|
|
6
5
|
import { RdsHolder } from "../../runtime/secrets/rds-holder.js";
|
|
@@ -66,10 +65,10 @@ export class DatabaseCountChecker {
|
|
|
66
65
|
synthetics.getConfiguration().withFailedCanaryMetric(true);
|
|
67
66
|
}
|
|
68
67
|
static createForProxy() {
|
|
69
|
-
return new DatabaseCountChecker(() =>
|
|
68
|
+
return new DatabaseCountChecker(() => ProxyHolder.create().setCredentials());
|
|
70
69
|
}
|
|
71
70
|
static createForRds() {
|
|
72
|
-
return new DatabaseCountChecker(() =>
|
|
71
|
+
return new DatabaseCountChecker(() => RdsHolder.create().setCredentials());
|
|
73
72
|
}
|
|
74
73
|
/**
|
|
75
74
|
* Expect that the count is 1
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import type { RdsProxySecret } from "./dbsecret.js";
|
|
2
|
+
import { SecretHolder } from "./secret-holder.js";
|
|
1
3
|
/**
|
|
2
4
|
* Holds credentials for RDS Proxy access.
|
|
3
5
|
*/
|
|
4
6
|
export declare class ProxyHolder {
|
|
5
7
|
private readonly secretHolder;
|
|
6
|
-
constructor(
|
|
8
|
+
private constructor();
|
|
9
|
+
/** Creates a new instance of ProxyHolder from given SecretHolder. */
|
|
10
|
+
static create(secretHolder: SecretHolder<RdsProxySecret>): ProxyHolder;
|
|
11
|
+
/** Creates a new instance of ProxyHolder with a new default SecretHolder(using env variable SECRET_ID). */
|
|
7
12
|
static create(): ProxyHolder;
|
|
8
13
|
setCredentials(): Promise<void>;
|
|
9
14
|
}
|
|
@@ -8,11 +8,13 @@ const RDS_PROXY_SECRET_KEYS = Object.values(RdsProxySecretKey);
|
|
|
8
8
|
*/
|
|
9
9
|
export class ProxyHolder {
|
|
10
10
|
secretHolder;
|
|
11
|
-
constructor(
|
|
12
|
-
this.secretHolder =
|
|
11
|
+
constructor(secretHolder) {
|
|
12
|
+
this.secretHolder = secretHolder;
|
|
13
13
|
}
|
|
14
|
-
static create() {
|
|
15
|
-
|
|
14
|
+
static create(secretHolder) {
|
|
15
|
+
const holder = secretHolder ??
|
|
16
|
+
new SecretHolder(getEnvVariable("SECRET_ID"), "", RDS_PROXY_SECRET_KEYS);
|
|
17
|
+
return new ProxyHolder(holder);
|
|
16
18
|
}
|
|
17
19
|
async setCredentials() {
|
|
18
20
|
const secret = await this.secretHolder.get();
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type { RdsSecret } from "./dbsecret.js";
|
|
2
|
+
import { SecretHolder } from "./secret-holder.js";
|
|
1
3
|
/**
|
|
2
4
|
* Holds credentials for RDS access.
|
|
3
5
|
*/
|
|
4
6
|
export declare class RdsHolder {
|
|
5
7
|
private readonly secretHolder;
|
|
6
|
-
constructor(
|
|
8
|
+
private constructor();
|
|
9
|
+
static create(rdsHolder: SecretHolder<RdsSecret>): RdsHolder;
|
|
7
10
|
static create(): RdsHolder;
|
|
8
11
|
setCredentials(): Promise<void>;
|
|
9
12
|
}
|
|
@@ -8,11 +8,13 @@ const RDS_SECRET_KEYS = Object.values(RdsSecretKey);
|
|
|
8
8
|
*/
|
|
9
9
|
export class RdsHolder {
|
|
10
10
|
secretHolder;
|
|
11
|
-
constructor(
|
|
12
|
-
this.secretHolder =
|
|
11
|
+
constructor(secretHolder) {
|
|
12
|
+
this.secretHolder = secretHolder;
|
|
13
13
|
}
|
|
14
|
-
static create() {
|
|
15
|
-
|
|
14
|
+
static create(secretHolder) {
|
|
15
|
+
const holder = secretHolder ??
|
|
16
|
+
new SecretHolder(getEnvVariable("SECRET_ID"), "", RDS_SECRET_KEYS);
|
|
17
|
+
return new RdsHolder(holder);
|
|
16
18
|
}
|
|
17
19
|
async setCredentials() {
|
|
18
20
|
const secret = await this.secretHolder.get();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CustomParams } from "../aws/runtime/dt-logger.js";
|
|
2
|
+
export interface LeadTimeLogging {
|
|
3
|
+
readonly target: string;
|
|
4
|
+
readonly leadTimeMs?: number;
|
|
5
|
+
readonly processTimeMs?: number;
|
|
6
|
+
readonly extraFields?: CustomParams;
|
|
7
|
+
}
|
|
8
|
+
export type LeadTimeType = "lead-time" | "process-time" | "mqtt-time";
|
|
9
|
+
export declare function logLeadTime(name: LeadTimeType, target: string, tookMs: number, extraFields?: CustomParams): void;
|
|
10
|
+
export declare function logLeadTimes(ptl: LeadTimeLogging): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { logger } from "../aws/runtime/dt-logger-default.js";
|
|
2
|
+
export function logLeadTime(name, target, tookMs, extraFields) {
|
|
3
|
+
const method = "LeadTimeLogging.logLeadTime";
|
|
4
|
+
try {
|
|
5
|
+
logger.info({
|
|
6
|
+
...(extraFields ?? {}),
|
|
7
|
+
method,
|
|
8
|
+
customLeadTime: true,
|
|
9
|
+
customName: name,
|
|
10
|
+
customTarget: target,
|
|
11
|
+
tookMs,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
logger.error({
|
|
16
|
+
method,
|
|
17
|
+
message: "Error logging lead time",
|
|
18
|
+
error,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function isSafe(value) {
|
|
23
|
+
return Number.isSafeInteger(value);
|
|
24
|
+
}
|
|
25
|
+
export function logLeadTimes(ptl) {
|
|
26
|
+
if (isSafe(ptl.leadTimeMs)) {
|
|
27
|
+
logLeadTime("lead-time", ptl.target, ptl.leadTimeMs, ptl.extraFields);
|
|
28
|
+
}
|
|
29
|
+
if (isSafe(ptl.processTimeMs)) {
|
|
30
|
+
logLeadTime("process-time", ptl.target, ptl.processTimeMs, ptl.extraFields);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=lead-time-logging.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitraffic/common",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.6.30-1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"repository": {
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"./dist/marine/id_utils": "./dist/marine/id_utils.js",
|
|
37
37
|
"./dist/index": "./dist/index.js",
|
|
38
38
|
"./dist/utils/api-model": "./dist/utils/api-model.js",
|
|
39
|
+
"./dist/utils/lead-time-logging": "./dist/utils/lead-time-logging.js",
|
|
39
40
|
"./dist/utils/logging": "./dist/utils/logging.js",
|
|
40
41
|
"./dist/utils/base64": "./dist/utils/base64.js",
|
|
41
42
|
"./dist/utils/date-utils": "./dist/utils/date-utils.js",
|
|
@@ -108,62 +109,62 @@
|
|
|
108
109
|
"dist/**/*.d.ts"
|
|
109
110
|
],
|
|
110
111
|
"devDependencies": {
|
|
111
|
-
"@aws-sdk/client-api-gateway": "3.
|
|
112
|
-
"@aws-sdk/client-s3": "3.
|
|
113
|
-
"@aws-sdk/client-secrets-manager": "3.
|
|
114
|
-
"@aws-sdk/client-sns": "3.
|
|
115
|
-
"@aws-sdk/lib-storage": "3.
|
|
116
|
-
"@biomejs/biome": "2.
|
|
117
|
-
"@date-fns/tz": "1.
|
|
118
|
-
"@rushstack/heft": "1.2.
|
|
119
|
-
"@rushstack/heft-typescript-plugin": "1.3.
|
|
120
|
-
"@smithy/fetch-http-handler": "5.
|
|
121
|
-
"@smithy/node-http-handler": "4.
|
|
122
|
-
"@smithy/types": "4.
|
|
123
|
-
"@types/aws-lambda": "8.10.
|
|
112
|
+
"@aws-sdk/client-api-gateway": "3.1073.0",
|
|
113
|
+
"@aws-sdk/client-s3": "3.1073.0",
|
|
114
|
+
"@aws-sdk/client-secrets-manager": "3.1073.0",
|
|
115
|
+
"@aws-sdk/client-sns": "3.1073.0",
|
|
116
|
+
"@aws-sdk/lib-storage": "3.1073.0",
|
|
117
|
+
"@biomejs/biome": "2.5.0",
|
|
118
|
+
"@date-fns/tz": "1.5.0",
|
|
119
|
+
"@rushstack/heft": "1.2.19",
|
|
120
|
+
"@rushstack/heft-typescript-plugin": "1.3.14",
|
|
121
|
+
"@smithy/fetch-http-handler": "5.5.1",
|
|
122
|
+
"@smithy/node-http-handler": "4.8.1",
|
|
123
|
+
"@smithy/types": "4.15.0",
|
|
124
|
+
"@types/aws-lambda": "8.10.162",
|
|
124
125
|
"@types/etag": "1.8.4",
|
|
125
126
|
"@types/geojson": "7946.0.16",
|
|
126
127
|
"@types/geojson-validation": "1.0.3",
|
|
127
128
|
"@types/madge": "5.0.3",
|
|
128
129
|
"@types/node": "24.12.4",
|
|
129
|
-
"@vitest/coverage-v8": "4.1.
|
|
130
|
-
"aws-cdk-lib": "2.
|
|
130
|
+
"@vitest/coverage-v8": "4.1.9",
|
|
131
|
+
"aws-cdk-lib": "2.260.0",
|
|
131
132
|
"change-case": "5.4.4",
|
|
132
133
|
"constructs": "10.6.0",
|
|
133
|
-
"date-fns": "4.
|
|
134
|
-
"es-toolkit": "1.
|
|
134
|
+
"date-fns": "4.4.0",
|
|
135
|
+
"es-toolkit": "1.47.1",
|
|
135
136
|
"etag": "1.8.1",
|
|
136
137
|
"geojson-validation": "1.0.2",
|
|
137
138
|
"ky": "2.0.2",
|
|
138
|
-
"lefthook": "2.1.
|
|
139
|
+
"lefthook": "2.1.9",
|
|
139
140
|
"madge": "8.0.0",
|
|
140
|
-
"pg-native": "3.
|
|
141
|
+
"pg-native": "3.8.0",
|
|
141
142
|
"pg-promise": "12.6.2",
|
|
142
|
-
"pg-query-stream": "4.
|
|
143
|
+
"pg-query-stream": "4.16.0",
|
|
143
144
|
"rimraf": "6.1.3",
|
|
144
|
-
"sort-package-json": "
|
|
145
|
+
"sort-package-json": "4.0.0",
|
|
145
146
|
"typescript": "5.9.3",
|
|
146
147
|
"velocityjs": "2.1.6",
|
|
147
|
-
"vitest": "4.1.
|
|
148
|
+
"vitest": "4.1.9",
|
|
148
149
|
"zod": "4.4.3"
|
|
149
150
|
},
|
|
150
151
|
"peerDependencies": {
|
|
151
|
-
"@aws-sdk/client-api-gateway": "3.
|
|
152
|
-
"@aws-sdk/client-s3": "3.
|
|
153
|
-
"@aws-sdk/client-secrets-manager": "3.
|
|
154
|
-
"@aws-sdk/client-sns": "3.
|
|
155
|
-
"@aws-sdk/lib-storage": "3.
|
|
156
|
-
"@date-fns/tz": "1.
|
|
157
|
-
"@smithy/fetch-http-handler": "5.
|
|
158
|
-
"@smithy/node-http-handler": "4.
|
|
159
|
-
"aws-cdk-lib": "2.
|
|
152
|
+
"@aws-sdk/client-api-gateway": "3.1073.0",
|
|
153
|
+
"@aws-sdk/client-s3": "3.1073.0",
|
|
154
|
+
"@aws-sdk/client-secrets-manager": "3.1073.0",
|
|
155
|
+
"@aws-sdk/client-sns": "3.1073.0",
|
|
156
|
+
"@aws-sdk/lib-storage": "3.1073.0",
|
|
157
|
+
"@date-fns/tz": "1.5.0",
|
|
158
|
+
"@smithy/fetch-http-handler": "5.5.1",
|
|
159
|
+
"@smithy/node-http-handler": "4.8.1",
|
|
160
|
+
"aws-cdk-lib": "2.260.0",
|
|
160
161
|
"change-case": "5.4.4",
|
|
161
162
|
"constructs": "10.6.0",
|
|
162
|
-
"date-fns": "4.
|
|
163
|
-
"es-toolkit": "1.
|
|
163
|
+
"date-fns": "4.4.0",
|
|
164
|
+
"es-toolkit": "1.47.1",
|
|
164
165
|
"geojson-validation": "1.0.2",
|
|
165
166
|
"ky": "2.0.2",
|
|
166
|
-
"pg-native": "3.
|
|
167
|
+
"pg-native": "3.8.0",
|
|
167
168
|
"pg-promise": "12.6.2",
|
|
168
169
|
"zod": "4.4.3"
|
|
169
170
|
},
|