@wtfalch/foundry 0.28.0 → 0.30.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/calls-sfu-ssh-client.d.ts +11 -0
- package/dist/calls-sfu-ssh-client.js +65 -11
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -3
- package/dist/org.d.ts +88 -0
- package/dist/org.js +68 -0
- package/dist/plan/agora.d.ts +13 -0
- package/dist/plan/agora.js +15 -0
- package/dist/plan/boule.d.ts +27 -3
- package/dist/plan/boule.js +39 -1
- package/dist/plan/chat-matrix.d.ts +31 -2
- package/dist/plan/chat-matrix.js +40 -6
- package/dist/plan/diff.d.ts +45 -2
- package/dist/plan/diff.js +211 -16
- package/dist/plan/executor.d.ts +132 -0
- package/dist/plan/executor.js +510 -31
- package/dist/plan/index.d.ts +5 -2
- package/dist/plan/index.js +3 -1
- package/dist/plan/plan-apply.js +1 -0
- package/dist/plan/platform-diff.d.ts +9 -0
- package/dist/plan/platform-diff.js +15 -3
- package/dist/plan/platform-org.d.ts +2 -0
- package/dist/plan/platform-org.js +4 -1
- package/dist/plan/platform-providers.d.ts +1 -1
- package/dist/plan/platform-providers.js +79 -22
- package/dist/plan/providers-readers.d.ts +15 -2
- package/dist/plan/providers-readers.js +44 -6
- package/dist/plan/step-system.js +1 -0
- package/dist/plan/version-status.d.ts +200 -0
- package/dist/plan/version-status.js +213 -0
- package/dist/plan/zitadel-login-policy.d.ts +23 -0
- package/dist/plan/zitadel-login-policy.js +103 -0
- package/dist/plan/zitadel-machine-user.d.ts +1 -1
- package/dist/plan/zitadel-machine-user.js +34 -0
- package/dist/platform.d.ts +1 -1
- package/package.json +3 -2
package/dist/plan/executor.d.ts
CHANGED
|
@@ -712,6 +712,39 @@ export interface CallsSfuPort {
|
|
|
712
712
|
apiSecret: string;
|
|
713
713
|
} | null>;
|
|
714
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* #463: the cross-homeserver copy chat's forward re-key needs (design note,
|
|
717
|
+
* `docs/chat-rekey-design.md`, Option 1) -- copies every room, member and
|
|
718
|
+
* message from the org's platform-named homeserver onto its newly
|
|
719
|
+
* provisioned, domain-named one, inviting members under their new ids, so
|
|
720
|
+
* history reads continuous once the chat service is repointed
|
|
721
|
+
* (`coolifyChatRekey`).
|
|
722
|
+
*
|
|
723
|
+
* Optional on {@link FoundryStepExecutorPorts}, the same shape as
|
|
724
|
+
* `jobsScheduler`/`edge`/`mailCopy`: nothing in the estate has proven this
|
|
725
|
+
* mechanism against a real Synapse and MAS pair yet (issue #463's own Human
|
|
726
|
+
* step), so a host without one builds the executor without it and
|
|
727
|
+
* `coolify:chat`'s forward re-key throws `NotBuiltError` naming the gap,
|
|
728
|
+
* rather than running a copy nobody has watched work.
|
|
729
|
+
*
|
|
730
|
+
* Idempotent by `fromServerName`/`toServerName`: a room or message the
|
|
731
|
+
* implementation already copied for this pair is skipped, so a retried or
|
|
732
|
+
* resumed copy never duplicates history. Never returns or throws a secret,
|
|
733
|
+
* token or credential -- same rule as every other port here.
|
|
734
|
+
*/
|
|
735
|
+
export interface ChatRekeyPort {
|
|
736
|
+
copyHomeserver(input: {
|
|
737
|
+
orgSlug: string;
|
|
738
|
+
fromServerName: string;
|
|
739
|
+
fromInternalHost: string;
|
|
740
|
+
toServerName: string;
|
|
741
|
+
toInternalHost: string;
|
|
742
|
+
/** Aborted when foundry stops waiting for the copy. */
|
|
743
|
+
signal: AbortSignal;
|
|
744
|
+
}): Promise<{
|
|
745
|
+
roomsCopied: number;
|
|
746
|
+
}>;
|
|
747
|
+
}
|
|
715
748
|
/**
|
|
716
749
|
* The ZITADEL calls this executor makes. `findOrCreateOrg`/`findOrCreateProject`
|
|
717
750
|
* already exist on `@wtfalch/providers/zitadel`'s `ZitadelClient` (returning
|
|
@@ -871,6 +904,16 @@ export interface ZitadelPort {
|
|
|
871
904
|
allowSelfRegistration(orgId: string): Promise<{
|
|
872
905
|
changed: boolean;
|
|
873
906
|
}>;
|
|
907
|
+
/**
|
|
908
|
+
* Forces the org's login policy to `allowRegister: false`, writing the org
|
|
909
|
+
* its own policy even when it only inherits the instance default.
|
|
910
|
+
* Idempotent: a custom policy that already forbids registration is no
|
|
911
|
+
* write. `@wtfalch/providers` can only turn registration on, so
|
|
912
|
+
* `zitadel-login-policy.ts` is the real implementation.
|
|
913
|
+
*/
|
|
914
|
+
closeSelfRegistration(orgId: string): Promise<{
|
|
915
|
+
changed: boolean;
|
|
916
|
+
}>;
|
|
874
917
|
/** Grants another ZITADEL org access to a project (plan gap A9). Idempotent. */
|
|
875
918
|
findOrCreateProjectGrant(orgId: string, projectId: string, grantedOrgId: string): Promise<{
|
|
876
919
|
created: boolean;
|
|
@@ -1010,6 +1053,14 @@ export interface ZitadelPort {
|
|
|
1010
1053
|
* the binding holds; `zitadelApp` never sets it at creation.
|
|
1011
1054
|
*/
|
|
1012
1055
|
updateOidcAppLoginBaseUri(orgId: string, projectId: string, appId: string, loginBaseUri: string): Promise<void>;
|
|
1056
|
+
/**
|
|
1057
|
+
* Occupies `userName` in `orgId` with a machine user that has no role and
|
|
1058
|
+
* no token, so nobody can register under that name. Idempotent: a user
|
|
1059
|
+
* already holding the name, however it was made, is returned unchanged.
|
|
1060
|
+
*/
|
|
1061
|
+
reserveUserName(orgId: string, userName: string): Promise<{
|
|
1062
|
+
userId: string;
|
|
1063
|
+
}>;
|
|
1013
1064
|
/**
|
|
1014
1065
|
* Switches on "user info inside the ID token" for an already-created app,
|
|
1015
1066
|
* read-modify-write (`@wtfalch/providers`' `ZitadelClient.
|
|
@@ -1405,6 +1456,13 @@ export interface FoundryStepExecutorPorts {
|
|
|
1405
1456
|
* compilation over one dependency nothing else needs.
|
|
1406
1457
|
*/
|
|
1407
1458
|
mailCopy?: MailCopyPort;
|
|
1459
|
+
/**
|
|
1460
|
+
* #463: the cross-homeserver copy chat's forward re-key needs -- see
|
|
1461
|
+
* {@link ChatRekeyPort}'s own doc comment. Optional the same way
|
|
1462
|
+
* `mailCopy` is: without it `coolify:chat`'s forward re-key throws
|
|
1463
|
+
* `NotBuiltError` naming the gap instead of running an unproven copy.
|
|
1464
|
+
*/
|
|
1465
|
+
chatRekey?: ChatRekeyPort;
|
|
1408
1466
|
/** Flat, not a factory: `organisationId` is an explicit argument on every method of both ports (see each port's own doc comment; #177 dropped the `filesLimitsFor`/`aiLimitsFor` factories this used to need). */
|
|
1409
1467
|
filesOrganisation?: FilesOrganisationPort;
|
|
1410
1468
|
aiOrganisation?: AiOrganisationPort;
|
|
@@ -1957,6 +2015,10 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
|
|
|
1957
2015
|
* domain restricted to them before any old project is deleted, so the
|
|
1958
2016
|
* restriction list never becomes empty.
|
|
1959
2017
|
*
|
|
2018
|
+
* #654: the non-platform-apex part now lives in {@link ensureOrgAppMailToken},
|
|
2019
|
+
* shared with Boule, which holds the same token; the rule below is its rule
|
|
2020
|
+
* with the consumers read from the hosted app and Boule.
|
|
2021
|
+
*
|
|
1960
2022
|
* Mint rule ("Credential model"): the project is healthy when the app env
|
|
1961
2023
|
* holds `LETTERMINT_API_TOKEN` and Lettermint lists exactly one project
|
|
1962
2024
|
* named `<slug>-app` -- unlike the earlier provider's key, a Lettermint project's name
|
|
@@ -2003,6 +2065,31 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
|
|
|
2003
2065
|
* this field existed (review round 2, finding 3).
|
|
2004
2066
|
*/
|
|
2005
2067
|
private ensureAppLettermintMail;
|
|
2068
|
+
/**
|
|
2069
|
+
* The one mint rule for the org's `<slug>-app` Lettermint token, shared by
|
|
2070
|
+
* the hosted app (`ensureAppLettermintMail`) and Boule
|
|
2071
|
+
* (`ensureBouleMail`), which hold the same token. Lettermint shows a
|
|
2072
|
+
* token once, so the token lives only in those apps' envs: the rule reads
|
|
2073
|
+
* every consumer that is recorded (the hosted app first, Boule second).
|
|
2074
|
+
* The project is healthy when Lettermint lists exactly one `<slug>-app`
|
|
2075
|
+
* project and some consumer holds a token. A healthy rule gives `self` that
|
|
2076
|
+
* token (the app's wins) when it lacks it or holds another; a peer gets it
|
|
2077
|
+
* in its own step. An
|
|
2078
|
+
* unhealthy one mints a fresh project and writes its token to every
|
|
2079
|
+
* consumer, restarting those that run, before any other `<slug>-app`
|
|
2080
|
+
* project is deleted. Either role may run first: an app added after Boule
|
|
2081
|
+
* adopts Boule's token instead of deleting its project.
|
|
2082
|
+
*
|
|
2083
|
+
* The token goes straight to `bulkUpsertEnvs` and nowhere else: never
|
|
2084
|
+
* returned, recorded, logged or interpolated into an error. Returns
|
|
2085
|
+
* whether `self`'s own token changed and whether it was restarted here.
|
|
2086
|
+
*
|
|
2087
|
+
* A peer recorded but gone from Coolify (404) is no consumer. A healthy
|
|
2088
|
+
* company's step writes only its own env; a re-mint writes every live
|
|
2089
|
+
* consumer, restarts the running ones, restricts the domain, then deletes
|
|
2090
|
+
* the old projects.
|
|
2091
|
+
*/
|
|
2092
|
+
private ensureOrgAppMailToken;
|
|
2006
2093
|
/**
|
|
2007
2094
|
* #149: mints this org's own Lettermint relay credential and writes it to
|
|
2008
2095
|
* Stalwart via `MailPort.applyOrgRelay`, the same mint rule
|
|
@@ -2309,6 +2396,26 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
|
|
|
2309
2396
|
* No secret reaches an error: errors name the org and the missing input only.
|
|
2310
2397
|
*/
|
|
2311
2398
|
private coolifyChat;
|
|
2399
|
+
/**
|
|
2400
|
+
* `coolifyChat`'s forward re-key (#463, design note
|
|
2401
|
+
* `docs/chat-rekey-design.md` Option 1): a live chat recorded, and
|
|
2402
|
+
* `org.chat.usesDomain` flipped on. Provisions a second Synapse+MAS pair
|
|
2403
|
+
* named for the org's own domain (`chatRekeyedInternalNames`), copies
|
|
2404
|
+
* every room, member and message across through
|
|
2405
|
+
* {@link FoundryStepExecutorPorts.chatRekey}, repoints the existing chat
|
|
2406
|
+
* service at the new pair, and parks -- never deletes, so a stalled
|
|
2407
|
+
* migration can be rolled back by simply restarting them -- the original
|
|
2408
|
+
* Synapse and MAS apps. The chat service and its own database are never
|
|
2409
|
+
* re-created; only the Matrix half of the stack moves.
|
|
2410
|
+
*
|
|
2411
|
+
* Idempotent on recorded ids: new resources are found by name before they
|
|
2412
|
+
* are created, the new MAS's secrets are read back from its own envs, and
|
|
2413
|
+
* the copy, the repoint and the park each run once
|
|
2414
|
+
* ({@link CHAT_REKEY_COPIED_SCOPE_KEY}, {@link CHAT_REKEY_REPOINTED_SCOPE_KEY}).
|
|
2415
|
+
* The original pair keeps serving until the chat service is healthy on the
|
|
2416
|
+
* new one; a failure before that leaves it running.
|
|
2417
|
+
*/
|
|
2418
|
+
private coolifyChatRekey;
|
|
2312
2419
|
/**
|
|
2313
2420
|
* `plan/diff.ts`'s `planCallsService`: the org's own calls service --
|
|
2314
2421
|
* `wtfalch/calls`'s `packages/service`, wired to the calls Matrix stack
|
|
@@ -2323,6 +2430,21 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
|
|
|
2323
2430
|
* 1); its own database is never touched from that branch.
|
|
2324
2431
|
*/
|
|
2325
2432
|
private coolifyCallsService;
|
|
2433
|
+
/**
|
|
2434
|
+
* `plan/diff.ts`'s `planCallsChat`: the one internal token that lets the
|
|
2435
|
+
* calls service ask chat who is in a room, and the chat address. The token
|
|
2436
|
+
* is `CHAT_INTERNAL_TOKEN` on chat-service and `CALLS_CHAT_TOKEN` on the
|
|
2437
|
+
* calls service, which gets `CALLS_CHAT_URL` in the same write: it refuses
|
|
2438
|
+
* to boot on one without the other. Chat-service's env is the only memory
|
|
2439
|
+
* of the token across a run, the way {@link ensureCallsMatrixSecrets} keeps
|
|
2440
|
+
* the MAS secrets on the MAS app, so it is generated only when that env has
|
|
2441
|
+
* none. Its id is recorded and persisted before either app holds it, and the
|
|
2442
|
+
* guard after both do (platform rule 1). Both apps are redeployed last; the
|
|
2443
|
+
* applied marker is recorded after that, so a run that fails in between is
|
|
2444
|
+
* planned and finished again. `remove` (chat is off) deletes both vars from
|
|
2445
|
+
* the calls service and restarts it.
|
|
2446
|
+
*/
|
|
2447
|
+
private coolifyCallsChat;
|
|
2326
2448
|
/**
|
|
2327
2449
|
* The seven ZITADEL token env vars the calls service needs to accept
|
|
2328
2450
|
* Agora's sign-in token (`calls/docs/member-auth.md`). Only called with all
|
|
@@ -2443,6 +2565,16 @@ export declare class FoundryStepExecutor implements StepExecutor, StepDestroyer
|
|
|
2443
2565
|
* shape {@link coolifyAgora}'s own doc comment explains.
|
|
2444
2566
|
*/
|
|
2445
2567
|
private coolifyBoule;
|
|
2568
|
+
/**
|
|
2569
|
+
* Gives Boule `LETTERMINT_API_TOKEN`: the platform's held key for an org on
|
|
2570
|
+
* the platform's own apex, else the org's `<slug>-app` token through the
|
|
2571
|
+
* shared mint rule ({@link ensureOrgAppMailToken}), which mints that project
|
|
2572
|
+
* when no hosted app made it yet. `MAIL_FROM` is written with the rest of
|
|
2573
|
+
* Boule's env. Returns whether Boule's token changed, so the caller
|
|
2574
|
+
* restarts a running Boule, unless `restarted`: the shared rule then already
|
|
2575
|
+
* restarted it (`running`), before it deleted the old project.
|
|
2576
|
+
*/
|
|
2577
|
+
private ensureBouleMail;
|
|
2446
2578
|
/**
|
|
2447
2579
|
* `plan/diff.ts`'s `planJobsRegistration`: registers the org's own app with
|
|
2448
2580
|
* the platform's jobs scheduler (`JobsSchedulerPort.registerProject`, the
|