@wtfalch/foundry 0.17.0 → 0.17.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.
@@ -4,6 +4,7 @@ const PLATFORM_APP_SYSTEMS = {
4
4
  'platform:mail': 'stalwart',
5
5
  'platform:files': 'files',
6
6
  'platform:ai': 'ai',
7
+ 'platform:names': 'names',
7
8
  };
8
9
  /** The system `action` touches. The one place that decides it, so no planner sets it by hand. */
9
10
  export function stepSystemOf(action) {
@@ -12,8 +12,25 @@ export interface PlatformService {
12
12
  hostname: string;
13
13
  gitRef: string;
14
14
  }
15
- /** The eight shared services a declared platform names, decided in #165. */
16
- export type PlatformServiceKey = 'auth' | 'mail' | 'sfu' | 'files' | 'ai' | 'jobs' | 'integrations' | 'archon';
15
+ /**
16
+ * #491: `mail`'s own extra field, on top of every other service's shape.
17
+ * Company Included (or whichever org's mail domain is the platform's own
18
+ * apex) sends through the platform's existing Lettermint project rather than
19
+ * a second `<slug>-app` one of its own -- `undefined`/`null` until an
20
+ * operator declares which project that is. A ref only, never a value: the
21
+ * project's own sending token stays where it already lived, held under
22
+ * `PLATFORM_AUTH_BROKER_MAIL_KEY_REF` (`plan/platform-providers.ts`).
23
+ */
24
+ export interface PlatformMailService extends PlatformService {
25
+ lettermintProjectId?: string | null;
26
+ }
27
+ /**
28
+ * The shared services a declared platform names, decided in #165, plus
29
+ * `names` (#317, F7): the service that mints an entry's own names key and
30
+ * holds the Cloudflare token `<username>.<org domain>` claims use, so no
31
+ * hosting entry ever holds that credential itself.
32
+ */
33
+ export type PlatformServiceKey = 'auth' | 'mail' | 'sfu' | 'files' | 'ai' | 'jobs' | 'integrations' | 'archon' | 'names';
17
34
  export declare const PLATFORM_SERVICE_KEYS: readonly PlatformServiceKey[];
18
35
  /**
19
36
  * The one shared platform every org's services run on -- decided in #165 as
@@ -42,13 +59,15 @@ export interface DeclaredPlatform {
42
59
  */
43
60
  serverIpv4?: string | null;
44
61
  auth: PlatformService;
45
- mail: PlatformService;
62
+ mail: PlatformMailService;
46
63
  sfu: PlatformService;
47
64
  files: PlatformService;
48
65
  ai: PlatformService;
49
66
  jobs: PlatformService;
50
67
  integrations: PlatformService;
51
68
  archon: PlatformService;
69
+ /** #317 (F7). No deploy step reads this service's own `gitRef` yet -- `N1` is deployed by hand until it exists. */
70
+ names: PlatformService;
52
71
  }
53
72
  /** `<service>.<apex>` -- the default `hostname` for a platform service, before an operator overrides it. */
54
73
  export declare function defaultPlatformHostname(service: PlatformServiceKey, apex: string): string;
package/dist/platform.js CHANGED
@@ -9,6 +9,7 @@ export const PLATFORM_SERVICE_KEYS = [
9
9
  'jobs',
10
10
  'integrations',
11
11
  'archon',
12
+ 'names',
12
13
  ];
13
14
  /** `<service>.<apex>` -- the default `hostname` for a platform service, before an operator overrides it. */
14
15
  export function defaultPlatformHostname(service, apex) {
@@ -47,5 +48,10 @@ export function validatePlatform(platform) {
47
48
  return `${key}.gitRef must not be empty once ${key}.enabled is true`;
48
49
  }
49
50
  }
51
+ // #491: declared, never discovered -- a present-but-blank id is refused the
52
+ // same way `serverIpv4`'s blank string is, rather than being read as unset.
53
+ if (platform.mail.lettermintProjectId != null && !platform.mail.lettermintProjectId.trim()) {
54
+ return 'mail.lettermintProjectId must not be empty when set';
55
+ }
50
56
  return null;
51
57
  }
@@ -578,7 +578,12 @@ function rowToPlatform(row) {
578
578
  apex: row.apex,
579
579
  ...(row.serverIpv4 ? { serverIpv4: row.serverIpv4 } : {}),
580
580
  auth: { enabled: row.authEnabled, hostname: row.authHostname, gitRef: row.authGitRef },
581
- mail: { enabled: row.mailEnabled, hostname: row.mailHostname, gitRef: row.mailGitRef },
581
+ mail: {
582
+ enabled: row.mailEnabled,
583
+ hostname: row.mailHostname,
584
+ gitRef: row.mailGitRef,
585
+ ...(row.mailLettermintProjectId ? { lettermintProjectId: row.mailLettermintProjectId } : {}),
586
+ },
582
587
  sfu: { enabled: row.sfuEnabled, hostname: row.sfuHostname, gitRef: row.sfuGitRef },
583
588
  files: { enabled: row.filesEnabled, hostname: row.filesHostname, gitRef: row.filesGitRef },
584
589
  ai: { enabled: row.aiEnabled, hostname: row.aiHostname, gitRef: row.aiGitRef },
@@ -593,6 +598,11 @@ function rowToPlatform(row) {
593
598
  hostname: row.archonHostname,
594
599
  gitRef: row.archonGitRef,
595
600
  },
601
+ names: {
602
+ enabled: row.namesEnabled,
603
+ hostname: row.namesHostname,
604
+ gitRef: row.namesGitRef,
605
+ },
596
606
  };
597
607
  }
598
608
  function platformToRow(platform) {
@@ -607,6 +617,7 @@ function platformToRow(platform) {
607
617
  mailEnabled: platform.mail.enabled,
608
618
  mailHostname: platform.mail.hostname,
609
619
  mailGitRef: platform.mail.gitRef,
620
+ mailLettermintProjectId: platform.mail.lettermintProjectId ?? null,
610
621
  sfuEnabled: platform.sfu.enabled,
611
622
  sfuHostname: platform.sfu.hostname,
612
623
  sfuGitRef: platform.sfu.gitRef,
@@ -625,6 +636,9 @@ function platformToRow(platform) {
625
636
  archonEnabled: platform.archon.enabled,
626
637
  archonHostname: platform.archon.hostname,
627
638
  archonGitRef: platform.archon.gitRef,
639
+ namesEnabled: platform.names.enabled,
640
+ namesHostname: platform.names.hostname,
641
+ namesGitRef: platform.names.gitRef,
628
642
  };
629
643
  }
630
644
  /**
@@ -1236,7 +1236,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
1236
1236
  tableName: "foundry_audit_events";
1237
1237
  dataType: "string";
1238
1238
  columnType: "PgText";
1239
- data: "plan" | "destroy" | "apply";
1239
+ data: "apply" | "plan" | "destroy";
1240
1240
  driverParam: string;
1241
1241
  notNull: true;
1242
1242
  hasDefault: false;
@@ -1248,7 +1248,7 @@ export declare const foundryAuditEvents: import("drizzle-orm/pg-core").PgTableWi
1248
1248
  identity: undefined;
1249
1249
  generated: undefined;
1250
1250
  }, {}, {
1251
- $type: "plan" | "destroy" | "apply";
1251
+ $type: "apply" | "plan" | "destroy";
1252
1252
  }>;
1253
1253
  actorId: import("drizzle-orm/pg-core").PgColumn<{
1254
1254
  name: "actor_id";
@@ -1558,6 +1558,23 @@ export declare const foundryDeclaredPlatform: import("drizzle-orm/pg-core").PgTa
1558
1558
  identity: undefined;
1559
1559
  generated: undefined;
1560
1560
  }, {}, {}>;
1561
+ mailLettermintProjectId: import("drizzle-orm/pg-core").PgColumn<{
1562
+ name: "mail_lettermint_project_id";
1563
+ tableName: "foundry_declared_platform";
1564
+ dataType: "string";
1565
+ columnType: "PgText";
1566
+ data: string;
1567
+ driverParam: string;
1568
+ notNull: false;
1569
+ hasDefault: false;
1570
+ isPrimaryKey: false;
1571
+ isAutoincrement: false;
1572
+ hasRuntimeDefault: false;
1573
+ enumValues: [string, ...string[]];
1574
+ baseColumn: never;
1575
+ identity: undefined;
1576
+ generated: undefined;
1577
+ }, {}, {}>;
1561
1578
  sfuEnabled: import("drizzle-orm/pg-core").PgColumn<{
1562
1579
  name: "sfu_enabled";
1563
1580
  tableName: "foundry_declared_platform";
@@ -1864,6 +1881,57 @@ export declare const foundryDeclaredPlatform: import("drizzle-orm/pg-core").PgTa
1864
1881
  identity: undefined;
1865
1882
  generated: undefined;
1866
1883
  }, {}, {}>;
1884
+ namesEnabled: import("drizzle-orm/pg-core").PgColumn<{
1885
+ name: "names_enabled";
1886
+ tableName: "foundry_declared_platform";
1887
+ dataType: "boolean";
1888
+ columnType: "PgBoolean";
1889
+ data: boolean;
1890
+ driverParam: boolean;
1891
+ notNull: true;
1892
+ hasDefault: true;
1893
+ isPrimaryKey: false;
1894
+ isAutoincrement: false;
1895
+ hasRuntimeDefault: false;
1896
+ enumValues: undefined;
1897
+ baseColumn: never;
1898
+ identity: undefined;
1899
+ generated: undefined;
1900
+ }, {}, {}>;
1901
+ namesHostname: import("drizzle-orm/pg-core").PgColumn<{
1902
+ name: "names_hostname";
1903
+ tableName: "foundry_declared_platform";
1904
+ dataType: "string";
1905
+ columnType: "PgText";
1906
+ data: string;
1907
+ driverParam: string;
1908
+ notNull: true;
1909
+ hasDefault: false;
1910
+ isPrimaryKey: false;
1911
+ isAutoincrement: false;
1912
+ hasRuntimeDefault: false;
1913
+ enumValues: [string, ...string[]];
1914
+ baseColumn: never;
1915
+ identity: undefined;
1916
+ generated: undefined;
1917
+ }, {}, {}>;
1918
+ namesGitRef: import("drizzle-orm/pg-core").PgColumn<{
1919
+ name: "names_git_ref";
1920
+ tableName: "foundry_declared_platform";
1921
+ dataType: "string";
1922
+ columnType: "PgText";
1923
+ data: string;
1924
+ driverParam: string;
1925
+ notNull: true;
1926
+ hasDefault: true;
1927
+ isPrimaryKey: false;
1928
+ isAutoincrement: false;
1929
+ hasRuntimeDefault: false;
1930
+ enumValues: [string, ...string[]];
1931
+ baseColumn: never;
1932
+ identity: undefined;
1933
+ generated: undefined;
1934
+ }, {}, {}>;
1867
1935
  serviceIds: import("drizzle-orm/pg-core").PgColumn<{
1868
1936
  name: "service_ids";
1869
1937
  tableName: "foundry_declared_platform";
@@ -158,6 +158,8 @@ export const foundryDeclaredPlatform = pgTable('foundry_declared_platform', {
158
158
  mailEnabled: boolean('mail_enabled').notNull().default(false),
159
159
  mailHostname: text('mail_hostname').notNull(),
160
160
  mailGitRef: text('mail_git_ref').notNull().default(''),
161
+ /** #491, `migrations/0044_platform_mail_lettermint_project.sql`. Declared, never discovered. */
162
+ mailLettermintProjectId: text('mail_lettermint_project_id'),
161
163
  sfuEnabled: boolean('sfu_enabled').notNull().default(false),
162
164
  sfuHostname: text('sfu_hostname').notNull(),
163
165
  sfuGitRef: text('sfu_git_ref').notNull().default(''),
@@ -176,6 +178,10 @@ export const foundryDeclaredPlatform = pgTable('foundry_declared_platform', {
176
178
  archonEnabled: boolean('archon_enabled').notNull().default(false),
177
179
  archonHostname: text('archon_hostname').notNull(),
178
180
  archonGitRef: text('archon_git_ref').notNull().default(''),
181
+ /** #317 (F7), `migrations/0038_platform_names.sql`. */
182
+ namesEnabled: boolean('names_enabled').notNull().default(false),
183
+ namesHostname: text('names_hostname').notNull(),
184
+ namesGitRef: text('names_git_ref').notNull().default(''),
179
185
  /** `migrations/0018_platform_apply.sql`: the platform's applied state, `system:kind:key` to provider id. */
180
186
  serviceIds: jsonb('service_ids').$type().notNull().default({}),
181
187
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtfalch/foundry",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Foundry's SDK: the declared org's types, the plan and apply contracts, and the state store's interface.",
5
5
  "repository": {
6
6
  "type": "git",