@wtfalch/foundry 0.42.1 → 0.43.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.
- package/dist/bootstrap/versions.d.ts +2 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -1
- package/dist/migrations/0055_release_requests.sql +20 -0
- package/dist/migrations/0056_platform_archon_blue_green.sql +7 -0
- package/dist/org.d.ts +13 -0
- package/dist/org.js +38 -1
- package/dist/plan/archon-blue-green.d.ts +54 -0
- package/dist/plan/archon-blue-green.js +72 -0
- package/dist/plan/blue-green-apply.d.ts +82 -0
- package/dist/plan/blue-green-apply.js +360 -0
- package/dist/plan/blue-green.d.ts +223 -0
- package/dist/plan/blue-green.js +444 -0
- package/dist/plan/cloudflared-connector.d.ts +26 -0
- package/dist/plan/cloudflared-connector.js +37 -0
- package/dist/plan/diff.d.ts +6 -0
- package/dist/plan/diff.js +31 -2
- package/dist/plan/executor.d.ts +34 -0
- package/dist/plan/executor.js +244 -9
- package/dist/plan/plan-apply.d.ts +51 -0
- package/dist/plan/plan-apply.js +222 -0
- package/dist/plan/platform-diff.d.ts +9 -0
- package/dist/plan/platform-diff.js +24 -1
- package/dist/plan/platform-providers.d.ts +15 -1
- package/dist/plan/platform-providers.js +90 -5
- package/dist/plan/proxy-labels.d.ts +2 -2
- package/dist/plan/proxy-labels.js +12 -4
- package/dist/plan/release-host.d.ts +59 -0
- package/dist/plan/release-host.js +239 -0
- package/dist/plan/remote-database.d.ts +124 -0
- package/dist/plan/remote-database.js +373 -0
- package/dist/platform.d.ts +11 -1
- package/dist/platform.js +4 -1
- package/dist/release/decide.d.ts +95 -0
- package/dist/release/decide.js +242 -0
- package/dist/release/health.d.ts +48 -0
- package/dist/release/health.js +61 -0
- package/dist/release/run.d.ts +40 -0
- package/dist/release/run.js +56 -0
- package/dist/release/state.d.ts +64 -0
- package/dist/release/state.js +126 -0
- package/dist/release/types.d.ts +54 -0
- package/dist/release/types.js +4 -0
- package/dist/store/postgres.d.ts +8 -0
- package/dist/store/postgres.js +56 -3
- package/dist/store/schema.d.ts +154 -0
- package/dist/store/schema.js +12 -0
- package/package.json +1 -1
- package/versions.digests.json +2 -1
- package/versions.json +2 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export type Color = 'blue' | 'green';
|
|
2
|
+
export type WindowState = {
|
|
3
|
+
kind: 'idle';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'step';
|
|
6
|
+
percent: number;
|
|
7
|
+
since: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'inconclusive';
|
|
10
|
+
percent: number;
|
|
11
|
+
since: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'window';
|
|
14
|
+
since: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'passed';
|
|
17
|
+
at: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'rolled_back';
|
|
20
|
+
at: string;
|
|
21
|
+
reason: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'cap';
|
|
24
|
+
since: string;
|
|
25
|
+
};
|
|
26
|
+
export interface ReleaseSignal {
|
|
27
|
+
requests: number;
|
|
28
|
+
errors: number;
|
|
29
|
+
baselineRate: number | null;
|
|
30
|
+
verdict: 'pass' | 'fail' | 'hard_fail' | 'inconclusive';
|
|
31
|
+
}
|
|
32
|
+
export interface ReleaseState {
|
|
33
|
+
entryKey: string;
|
|
34
|
+
live: Color;
|
|
35
|
+
weights: Record<Color, number>;
|
|
36
|
+
digests: Record<Color, string | null>;
|
|
37
|
+
stageDigest: string | null;
|
|
38
|
+
window: WindowState;
|
|
39
|
+
signal: ReleaseSignal | null;
|
|
40
|
+
held: string[];
|
|
41
|
+
}
|
|
42
|
+
export type ReleaseAction = {
|
|
43
|
+
kind: 'promote';
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'rollback';
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'clear_held';
|
|
48
|
+
digest: string;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'decide_at_cap';
|
|
51
|
+
decision: 'pass' | 'rollback';
|
|
52
|
+
};
|
|
53
|
+
export declare const COLORS: readonly Color[];
|
|
54
|
+
export declare function otherColor(color: Color): Color;
|
package/dist/store/postgres.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { type ReleaseStore } from '../release/state.js';
|
|
2
3
|
import { type AppliedVersionsStore, type DeclaredOrgStore, type PlatformStore, type RequestedChangeStore } from '../store.js';
|
|
3
4
|
/**
|
|
4
5
|
* The host's own drizzle handle or a transaction open on it, same shape
|
|
@@ -98,3 +99,10 @@ export declare function createPostgresRequestedChangeStore(db: FoundryStoreDb):
|
|
|
98
99
|
* lost the way `foundry_applied_state`'s one row per service would lose it.
|
|
99
100
|
*/
|
|
100
101
|
export declare function createPostgresAppliedVersionsStore(db: FoundryStoreDb): AppliedVersionsStore;
|
|
102
|
+
/**
|
|
103
|
+
* `ReleaseStore` (`../release/state.ts`) on Postgres: the recorded `bg.*`
|
|
104
|
+
* keys come from an org's applied state, or the platform's for the orgId
|
|
105
|
+
* `platform`; requests are rows in `foundry_release_requests`. Reading leaves
|
|
106
|
+
* the open rows consumed only when the caller says its run succeeded (`consumeRequests`).
|
|
107
|
+
*/
|
|
108
|
+
export declare function createPostgresReleaseStore(db: FoundryStoreDb): ReleaseStore;
|
package/dist/store/postgres.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { and, asc, desc, eq, ne, sql } from 'drizzle-orm';
|
|
2
|
-
import { APP_ENTRY_KEY, DEFAULT_MAIL_APPS, DEFAULT_NO_REPLY_LOCAL_PART, validateBuyerIdentity, validateCalls, validateDomain, validateDomainClaim, validateHosting, validateMail, validateOwners, validateServices, validateSignIn, validateSite, validateVersionPin, } from '../org.js';
|
|
1
|
+
import { and, asc, desc, eq, inArray, isNull, ne, sql } from 'drizzle-orm';
|
|
2
|
+
import { APP_ENTRY_KEY, DEFAULT_MAIL_APPS, DEFAULT_NO_REPLY_LOCAL_PART, validateBlueGreen, validateBuyerIdentity, validateCalls, validateDomain, validateDomainClaim, validateHosting, validateMail, validateOwners, validateServices, validateSignIn, validateSite, validateVersionPin, } from '../org.js';
|
|
3
3
|
import { lockedHostnames } from '../plan/locked-hostnames.js';
|
|
4
4
|
import { findNameClashes, nameClashMessage } from '../plan/org-names.js';
|
|
5
5
|
import { validatePlatform } from '../platform.js';
|
|
6
|
+
import { releaseActionSchema } from '../release/state.js';
|
|
6
7
|
import { RequestedChangeError, classifyChange } from '../requested-changes.js';
|
|
7
8
|
import { validateSlug } from '../slug.js';
|
|
8
9
|
import { StaleLeaseError, } from '../store.js';
|
|
9
|
-
import { declaredOrgs, foundryAppliedState, foundryAppliedVersions, foundryDeclaredPlatform, foundryMutationLeases, foundryRequestedChanges, } from './schema.js';
|
|
10
|
+
import { declaredOrgs, foundryAppliedState, foundryAppliedVersions, foundryDeclaredPlatform, foundryMutationLeases, foundryReleaseRequests, foundryRequestedChanges, } from './schema.js';
|
|
10
11
|
const UNIQUE_VIOLATION = '23505';
|
|
11
12
|
/**
|
|
12
13
|
* #441: runs `write`, and with a `fence` only if its token is still the
|
|
@@ -718,6 +719,10 @@ function rowToPlatform(row) {
|
|
|
718
719
|
enabled: row.archonEnabled,
|
|
719
720
|
hostname: row.archonHostname,
|
|
720
721
|
gitRef: row.archonGitRef,
|
|
722
|
+
// Omitted while off. Validated on read: a stored value is not trusted.
|
|
723
|
+
...(row.archonBlueGreen && validateBlueGreen(row.archonBlueGreen, 'archon') === null
|
|
724
|
+
? { blueGreen: row.archonBlueGreen }
|
|
725
|
+
: {}),
|
|
721
726
|
},
|
|
722
727
|
edge: {
|
|
723
728
|
enabled: row.edgeEnabled,
|
|
@@ -771,6 +776,7 @@ function platformToRow(platform) {
|
|
|
771
776
|
archonEnabled: platform.archon.enabled,
|
|
772
777
|
archonHostname: platform.archon.hostname,
|
|
773
778
|
archonGitRef: platform.archon.gitRef,
|
|
779
|
+
archonBlueGreen: platform.archon.blueGreen ?? null,
|
|
774
780
|
edgeEnabled: platform.edge.enabled,
|
|
775
781
|
edgeHostname: platform.edge.hostname,
|
|
776
782
|
edgeGitRef: platform.edge.gitRef,
|
|
@@ -923,3 +929,50 @@ export function createPostgresAppliedVersionsStore(db) {
|
|
|
923
929
|
},
|
|
924
930
|
};
|
|
925
931
|
}
|
|
932
|
+
/**
|
|
933
|
+
* `ReleaseStore` (`../release/state.ts`) on Postgres: the recorded `bg.*`
|
|
934
|
+
* keys come from an org's applied state, or the platform's for the orgId
|
|
935
|
+
* `platform`; requests are rows in `foundry_release_requests`. Reading leaves
|
|
936
|
+
* the open rows consumed only when the caller says its run succeeded (`consumeRequests`).
|
|
937
|
+
*/
|
|
938
|
+
export function createPostgresReleaseStore(db) {
|
|
939
|
+
return {
|
|
940
|
+
async getScopeIds(orgId) {
|
|
941
|
+
if (orgId === 'platform') {
|
|
942
|
+
const [row] = await db
|
|
943
|
+
.select({ ids: foundryDeclaredPlatform.serviceIds })
|
|
944
|
+
.from(foundryDeclaredPlatform)
|
|
945
|
+
.limit(1);
|
|
946
|
+
return row?.ids ?? {};
|
|
947
|
+
}
|
|
948
|
+
const [row] = await db
|
|
949
|
+
.select({ ids: foundryAppliedState.serviceIds })
|
|
950
|
+
.from(foundryAppliedState)
|
|
951
|
+
.where(eq(foundryAppliedState.orgId, orgId))
|
|
952
|
+
.limit(1);
|
|
953
|
+
return row?.ids ?? {};
|
|
954
|
+
},
|
|
955
|
+
async addRequest({ orgId, entryKey, action, actor }) {
|
|
956
|
+
await db.insert(foundryReleaseRequests).values({ orgId, entryKey, action, actor });
|
|
957
|
+
},
|
|
958
|
+
async openRequests({ orgId, entryKey }) {
|
|
959
|
+
const rows = await db
|
|
960
|
+
.select()
|
|
961
|
+
.from(foundryReleaseRequests)
|
|
962
|
+
.where(and(eq(foundryReleaseRequests.orgId, orgId), eq(foundryReleaseRequests.entryKey, entryKey), isNull(foundryReleaseRequests.consumedAt)))
|
|
963
|
+
.orderBy(asc(foundryReleaseRequests.id));
|
|
964
|
+
return rows.flatMap((row) => {
|
|
965
|
+
const action = releaseActionSchema.safeParse(row.action);
|
|
966
|
+
return action.success ? [{ id: row.id, action: action.data, actor: row.actor }] : [];
|
|
967
|
+
});
|
|
968
|
+
},
|
|
969
|
+
async consumeRequests(ids) {
|
|
970
|
+
if (ids.length === 0)
|
|
971
|
+
return;
|
|
972
|
+
await db
|
|
973
|
+
.update(foundryReleaseRequests)
|
|
974
|
+
.set({ consumedAt: sql `now()` })
|
|
975
|
+
.where(and(inArray(foundryReleaseRequests.id, [...ids]), isNull(foundryReleaseRequests.consumedAt)));
|
|
976
|
+
},
|
|
977
|
+
};
|
|
978
|
+
}
|
package/dist/store/schema.d.ts
CHANGED
|
@@ -2002,6 +2002,31 @@ export declare const foundryDeclaredPlatform: import("drizzle-orm/pg-core").PgTa
|
|
|
2002
2002
|
identity: undefined;
|
|
2003
2003
|
generated: undefined;
|
|
2004
2004
|
}, {}, {}>;
|
|
2005
|
+
archonBlueGreen: import("drizzle-orm/pg-core").PgColumn<{
|
|
2006
|
+
name: "archon_blue_green";
|
|
2007
|
+
tableName: "foundry_declared_platform";
|
|
2008
|
+
dataType: "json";
|
|
2009
|
+
columnType: "PgJsonb";
|
|
2010
|
+
data: {
|
|
2011
|
+
steps?: number[];
|
|
2012
|
+
stepHoldMinutes?: number;
|
|
2013
|
+
} | null;
|
|
2014
|
+
driverParam: unknown;
|
|
2015
|
+
notNull: false;
|
|
2016
|
+
hasDefault: false;
|
|
2017
|
+
isPrimaryKey: false;
|
|
2018
|
+
isAutoincrement: false;
|
|
2019
|
+
hasRuntimeDefault: false;
|
|
2020
|
+
enumValues: undefined;
|
|
2021
|
+
baseColumn: never;
|
|
2022
|
+
identity: undefined;
|
|
2023
|
+
generated: undefined;
|
|
2024
|
+
}, {}, {
|
|
2025
|
+
$type: {
|
|
2026
|
+
steps?: number[];
|
|
2027
|
+
stepHoldMinutes?: number;
|
|
2028
|
+
} | null;
|
|
2029
|
+
}>;
|
|
2005
2030
|
edgeEnabled: import("drizzle-orm/pg-core").PgColumn<{
|
|
2006
2031
|
name: "edge_enabled";
|
|
2007
2032
|
tableName: "foundry_declared_platform";
|
|
@@ -2414,6 +2439,135 @@ export declare const foundryRequestedChanges: import("drizzle-orm/pg-core").PgTa
|
|
|
2414
2439
|
};
|
|
2415
2440
|
dialect: "pg";
|
|
2416
2441
|
}>;
|
|
2442
|
+
/** Mirrors `migrations/0055_release_requests.sql`: an operator's release action, consumed once by the runner. */
|
|
2443
|
+
export declare const foundryReleaseRequests: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
2444
|
+
name: "foundry_release_requests";
|
|
2445
|
+
schema: undefined;
|
|
2446
|
+
columns: {
|
|
2447
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
2448
|
+
name: "id";
|
|
2449
|
+
tableName: "foundry_release_requests";
|
|
2450
|
+
dataType: "number";
|
|
2451
|
+
columnType: "PgBigSerial53";
|
|
2452
|
+
data: number;
|
|
2453
|
+
driverParam: number;
|
|
2454
|
+
notNull: true;
|
|
2455
|
+
hasDefault: true;
|
|
2456
|
+
isPrimaryKey: true;
|
|
2457
|
+
isAutoincrement: false;
|
|
2458
|
+
hasRuntimeDefault: false;
|
|
2459
|
+
enumValues: undefined;
|
|
2460
|
+
baseColumn: never;
|
|
2461
|
+
identity: undefined;
|
|
2462
|
+
generated: undefined;
|
|
2463
|
+
}, {}, {}>;
|
|
2464
|
+
orgId: import("drizzle-orm/pg-core").PgColumn<{
|
|
2465
|
+
name: "org_id";
|
|
2466
|
+
tableName: "foundry_release_requests";
|
|
2467
|
+
dataType: "string";
|
|
2468
|
+
columnType: "PgText";
|
|
2469
|
+
data: string;
|
|
2470
|
+
driverParam: string;
|
|
2471
|
+
notNull: true;
|
|
2472
|
+
hasDefault: false;
|
|
2473
|
+
isPrimaryKey: false;
|
|
2474
|
+
isAutoincrement: false;
|
|
2475
|
+
hasRuntimeDefault: false;
|
|
2476
|
+
enumValues: [string, ...string[]];
|
|
2477
|
+
baseColumn: never;
|
|
2478
|
+
identity: undefined;
|
|
2479
|
+
generated: undefined;
|
|
2480
|
+
}, {}, {}>;
|
|
2481
|
+
entryKey: import("drizzle-orm/pg-core").PgColumn<{
|
|
2482
|
+
name: "entry_key";
|
|
2483
|
+
tableName: "foundry_release_requests";
|
|
2484
|
+
dataType: "string";
|
|
2485
|
+
columnType: "PgText";
|
|
2486
|
+
data: string;
|
|
2487
|
+
driverParam: string;
|
|
2488
|
+
notNull: true;
|
|
2489
|
+
hasDefault: false;
|
|
2490
|
+
isPrimaryKey: false;
|
|
2491
|
+
isAutoincrement: false;
|
|
2492
|
+
hasRuntimeDefault: false;
|
|
2493
|
+
enumValues: [string, ...string[]];
|
|
2494
|
+
baseColumn: never;
|
|
2495
|
+
identity: undefined;
|
|
2496
|
+
generated: undefined;
|
|
2497
|
+
}, {}, {}>;
|
|
2498
|
+
action: import("drizzle-orm/pg-core").PgColumn<{
|
|
2499
|
+
name: "action";
|
|
2500
|
+
tableName: "foundry_release_requests";
|
|
2501
|
+
dataType: "json";
|
|
2502
|
+
columnType: "PgJsonb";
|
|
2503
|
+
data: Record<string, unknown>;
|
|
2504
|
+
driverParam: unknown;
|
|
2505
|
+
notNull: true;
|
|
2506
|
+
hasDefault: false;
|
|
2507
|
+
isPrimaryKey: false;
|
|
2508
|
+
isAutoincrement: false;
|
|
2509
|
+
hasRuntimeDefault: false;
|
|
2510
|
+
enumValues: undefined;
|
|
2511
|
+
baseColumn: never;
|
|
2512
|
+
identity: undefined;
|
|
2513
|
+
generated: undefined;
|
|
2514
|
+
}, {}, {
|
|
2515
|
+
$type: Record<string, unknown>;
|
|
2516
|
+
}>;
|
|
2517
|
+
actor: import("drizzle-orm/pg-core").PgColumn<{
|
|
2518
|
+
name: "actor";
|
|
2519
|
+
tableName: "foundry_release_requests";
|
|
2520
|
+
dataType: "string";
|
|
2521
|
+
columnType: "PgText";
|
|
2522
|
+
data: string;
|
|
2523
|
+
driverParam: string;
|
|
2524
|
+
notNull: true;
|
|
2525
|
+
hasDefault: false;
|
|
2526
|
+
isPrimaryKey: false;
|
|
2527
|
+
isAutoincrement: false;
|
|
2528
|
+
hasRuntimeDefault: false;
|
|
2529
|
+
enumValues: [string, ...string[]];
|
|
2530
|
+
baseColumn: never;
|
|
2531
|
+
identity: undefined;
|
|
2532
|
+
generated: undefined;
|
|
2533
|
+
}, {}, {}>;
|
|
2534
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
2535
|
+
name: "created_at";
|
|
2536
|
+
tableName: "foundry_release_requests";
|
|
2537
|
+
dataType: "date";
|
|
2538
|
+
columnType: "PgTimestamp";
|
|
2539
|
+
data: Date;
|
|
2540
|
+
driverParam: string;
|
|
2541
|
+
notNull: true;
|
|
2542
|
+
hasDefault: true;
|
|
2543
|
+
isPrimaryKey: false;
|
|
2544
|
+
isAutoincrement: false;
|
|
2545
|
+
hasRuntimeDefault: false;
|
|
2546
|
+
enumValues: undefined;
|
|
2547
|
+
baseColumn: never;
|
|
2548
|
+
identity: undefined;
|
|
2549
|
+
generated: undefined;
|
|
2550
|
+
}, {}, {}>;
|
|
2551
|
+
consumedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
2552
|
+
name: "consumed_at";
|
|
2553
|
+
tableName: "foundry_release_requests";
|
|
2554
|
+
dataType: "date";
|
|
2555
|
+
columnType: "PgTimestamp";
|
|
2556
|
+
data: Date;
|
|
2557
|
+
driverParam: string;
|
|
2558
|
+
notNull: false;
|
|
2559
|
+
hasDefault: false;
|
|
2560
|
+
isPrimaryKey: false;
|
|
2561
|
+
isAutoincrement: false;
|
|
2562
|
+
hasRuntimeDefault: false;
|
|
2563
|
+
enumValues: undefined;
|
|
2564
|
+
baseColumn: never;
|
|
2565
|
+
identity: undefined;
|
|
2566
|
+
generated: undefined;
|
|
2567
|
+
}, {}, {}>;
|
|
2568
|
+
};
|
|
2569
|
+
dialect: "pg";
|
|
2570
|
+
}>;
|
|
2417
2571
|
export type DeclaredOrgRow = typeof declaredOrgs.$inferSelect;
|
|
2418
2572
|
export type NewDeclaredOrgRow = typeof declaredOrgs.$inferInsert;
|
|
2419
2573
|
export type AppliedStateRow = typeof foundryAppliedState.$inferSelect;
|
package/dist/store/schema.js
CHANGED
|
@@ -191,6 +191,8 @@ export const foundryDeclaredPlatform = pgTable('foundry_declared_platform', {
|
|
|
191
191
|
archonEnabled: boolean('archon_enabled').notNull().default(false),
|
|
192
192
|
archonHostname: text('archon_hostname').notNull(),
|
|
193
193
|
archonGitRef: text('archon_git_ref').notNull().default(''),
|
|
194
|
+
/** `migrations/0056_platform_archon_blue_green.sql`: `platform.archon.blueGreen`; null keeps one app. */
|
|
195
|
+
archonBlueGreen: jsonb('archon_blue_green').$type(),
|
|
194
196
|
/** #317 (F7), `migrations/0043_platform_names.sql`, renamed from `names_*` by `0045_names_to_edge.sql`. */
|
|
195
197
|
edgeEnabled: boolean('edge_enabled').notNull().default(false),
|
|
196
198
|
edgeHostname: text('edge_hostname').notNull(),
|
|
@@ -230,3 +232,13 @@ export const foundryRequestedChanges = pgTable('foundry_requested_changes', {
|
|
|
230
232
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
231
233
|
state: text('state').notNull().default('needs_approval'),
|
|
232
234
|
});
|
|
235
|
+
/** Mirrors `migrations/0055_release_requests.sql`: an operator's release action, consumed once by the runner. */
|
|
236
|
+
export const foundryReleaseRequests = pgTable('foundry_release_requests', {
|
|
237
|
+
id: bigserial('id', { mode: 'number' }).primaryKey(),
|
|
238
|
+
orgId: text('org_id').notNull(),
|
|
239
|
+
entryKey: text('entry_key').notNull(),
|
|
240
|
+
action: jsonb('action').notNull().$type(),
|
|
241
|
+
actor: text('actor').notNull(),
|
|
242
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
243
|
+
consumedAt: timestamp('consumed_at', { withTimezone: true }),
|
|
244
|
+
});
|
package/package.json
CHANGED
package/versions.digests.json
CHANGED
|
@@ -8,5 +8,6 @@
|
|
|
8
8
|
"hc": "sha256:aa08a61b0dcfd83f1332eab195d5cec1b595ae076eb8388cadf8a3d597114f9b",
|
|
9
9
|
"alpine": "sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1",
|
|
10
10
|
"busybox": "sha256:5cec3fc171c87218698e85a52af7087de727372aae264a787b8112901a5b0092",
|
|
11
|
-
"postgres": "sha256:786dab398303b8ce7cb76b407bb21ef2e4dfbbbd4c6abcf3d29b3130467ffdbc"
|
|
11
|
+
"postgres": "sha256:786dab398303b8ce7cb76b407bb21ef2e4dfbbbd4c6abcf3d29b3130467ffdbc",
|
|
12
|
+
"traefik": "sha256:575fa15b135078fe5e50aa847987d96dbddd7b093c172429618404df73f3fa7c"
|
|
12
13
|
}
|