@wtfalch/foundry 0.10.0 → 0.11.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.
@@ -482,6 +482,33 @@ export declare const declaredOrgs: import("drizzle-orm/pg-core").PgTableWithColu
482
482
  }, {}, {
483
483
  $type: HostingEntry[];
484
484
  }>;
485
+ hostingAdopt: import("drizzle-orm/pg-core").PgColumn<{
486
+ name: "hosting_adopt";
487
+ tableName: "foundry_declared_orgs";
488
+ dataType: "json";
489
+ columnType: "PgJsonb";
490
+ data: {
491
+ database?: string;
492
+ tunnel?: string;
493
+ connectorApp?: string;
494
+ };
495
+ driverParam: unknown;
496
+ notNull: false;
497
+ hasDefault: false;
498
+ isPrimaryKey: false;
499
+ isAutoincrement: false;
500
+ hasRuntimeDefault: false;
501
+ enumValues: undefined;
502
+ baseColumn: never;
503
+ identity: undefined;
504
+ generated: undefined;
505
+ }, {}, {
506
+ $type: {
507
+ database?: string;
508
+ tunnel?: string;
509
+ connectorApp?: string;
510
+ };
511
+ }>;
485
512
  ssoEnabled: import("drizzle-orm/pg-core").PgColumn<{
486
513
  name: "sso_enabled";
487
514
  tableName: "foundry_declared_orgs";
@@ -1809,6 +1836,140 @@ export declare const foundryRequestedChanges: import("drizzle-orm/pg-core").PgTa
1809
1836
  };
1810
1837
  dialect: "pg";
1811
1838
  }>;
1839
+ /**
1840
+ * Mirrors `migrations/0031_adoptions.sql`, which is the source of truth (the
1841
+ * CHECKs live there). One row per live resource foundry took over (#311).
1842
+ * `settings` holds non-secret settings only; secrets go to the vault under
1843
+ * `vaultRef`.
1844
+ */
1845
+ export declare const foundryAdoptions: import("drizzle-orm/pg-core").PgTableWithColumns<{
1846
+ name: "foundry_adoptions";
1847
+ schema: undefined;
1848
+ columns: {
1849
+ orgId: import("drizzle-orm/pg-core").PgColumn<{
1850
+ name: "org_id";
1851
+ tableName: "foundry_adoptions";
1852
+ dataType: "string";
1853
+ columnType: "PgText";
1854
+ data: string;
1855
+ driverParam: string;
1856
+ notNull: true;
1857
+ hasDefault: false;
1858
+ isPrimaryKey: false;
1859
+ isAutoincrement: false;
1860
+ hasRuntimeDefault: false;
1861
+ enumValues: [string, ...string[]];
1862
+ baseColumn: never;
1863
+ identity: undefined;
1864
+ generated: undefined;
1865
+ }, {}, {}>;
1866
+ resourceKey: import("drizzle-orm/pg-core").PgColumn<{
1867
+ name: "resource_key";
1868
+ tableName: "foundry_adoptions";
1869
+ dataType: "string";
1870
+ columnType: "PgText";
1871
+ data: string;
1872
+ driverParam: string;
1873
+ notNull: true;
1874
+ hasDefault: false;
1875
+ isPrimaryKey: false;
1876
+ isAutoincrement: false;
1877
+ hasRuntimeDefault: false;
1878
+ enumValues: [string, ...string[]];
1879
+ baseColumn: never;
1880
+ identity: undefined;
1881
+ generated: undefined;
1882
+ }, {}, {}>;
1883
+ kind: import("drizzle-orm/pg-core").PgColumn<{
1884
+ name: "kind";
1885
+ tableName: "foundry_adoptions";
1886
+ dataType: "string";
1887
+ columnType: "PgText";
1888
+ data: string;
1889
+ driverParam: string;
1890
+ notNull: true;
1891
+ hasDefault: false;
1892
+ isPrimaryKey: false;
1893
+ isAutoincrement: false;
1894
+ hasRuntimeDefault: false;
1895
+ enumValues: [string, ...string[]];
1896
+ baseColumn: never;
1897
+ identity: undefined;
1898
+ generated: undefined;
1899
+ }, {}, {}>;
1900
+ takenAt: import("drizzle-orm/pg-core").PgColumn<{
1901
+ name: "taken_at";
1902
+ tableName: "foundry_adoptions";
1903
+ dataType: "date";
1904
+ columnType: "PgTimestamp";
1905
+ data: Date;
1906
+ driverParam: string;
1907
+ notNull: true;
1908
+ hasDefault: false;
1909
+ isPrimaryKey: false;
1910
+ isAutoincrement: false;
1911
+ hasRuntimeDefault: false;
1912
+ enumValues: undefined;
1913
+ baseColumn: never;
1914
+ identity: undefined;
1915
+ generated: undefined;
1916
+ }, {}, {}>;
1917
+ settings: import("drizzle-orm/pg-core").PgColumn<{
1918
+ name: "settings";
1919
+ tableName: "foundry_adoptions";
1920
+ dataType: "json";
1921
+ columnType: "PgJsonb";
1922
+ data: Record<string, unknown>;
1923
+ driverParam: unknown;
1924
+ notNull: true;
1925
+ hasDefault: false;
1926
+ isPrimaryKey: false;
1927
+ isAutoincrement: false;
1928
+ hasRuntimeDefault: false;
1929
+ enumValues: undefined;
1930
+ baseColumn: never;
1931
+ identity: undefined;
1932
+ generated: undefined;
1933
+ }, {}, {
1934
+ $type: Record<string, unknown>;
1935
+ }>;
1936
+ vaultRef: import("drizzle-orm/pg-core").PgColumn<{
1937
+ name: "vault_ref";
1938
+ tableName: "foundry_adoptions";
1939
+ dataType: "string";
1940
+ columnType: "PgText";
1941
+ data: string;
1942
+ driverParam: string;
1943
+ notNull: false;
1944
+ hasDefault: false;
1945
+ isPrimaryKey: false;
1946
+ isAutoincrement: false;
1947
+ hasRuntimeDefault: false;
1948
+ enumValues: [string, ...string[]];
1949
+ baseColumn: never;
1950
+ identity: undefined;
1951
+ generated: undefined;
1952
+ }, {}, {}>;
1953
+ state: import("drizzle-orm/pg-core").PgColumn<{
1954
+ name: "state";
1955
+ tableName: "foundry_adoptions";
1956
+ dataType: "string";
1957
+ columnType: "PgText";
1958
+ data: string;
1959
+ driverParam: string;
1960
+ notNull: true;
1961
+ hasDefault: true;
1962
+ isPrimaryKey: false;
1963
+ isAutoincrement: false;
1964
+ hasRuntimeDefault: false;
1965
+ enumValues: [string, ...string[]];
1966
+ baseColumn: never;
1967
+ identity: undefined;
1968
+ generated: undefined;
1969
+ }, {}, {}>;
1970
+ };
1971
+ dialect: "pg";
1972
+ }>;
1812
1973
  export type DeclaredOrgRow = typeof declaredOrgs.$inferSelect;
1813
1974
  export type NewDeclaredOrgRow = typeof declaredOrgs.$inferInsert;
1814
1975
  export type AppliedStateRow = typeof foundryAppliedState.$inferSelect;
@@ -1818,3 +1979,4 @@ export type DeclaredPlatformRow = typeof foundryDeclaredPlatform.$inferSelect;
1818
1979
  export type NewDeclaredPlatformRow = typeof foundryDeclaredPlatform.$inferInsert;
1819
1980
  export type RequestedChangeRow = typeof foundryRequestedChanges.$inferSelect;
1820
1981
  export type NewRequestedChangeRow = typeof foundryRequestedChanges.$inferInsert;
1982
+ export type AdoptionRow = typeof foundryAdoptions.$inferSelect;
@@ -1,4 +1,4 @@
1
- import { bigserial, boolean, jsonb, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
1
+ import { bigserial, boolean, jsonb, pgTable, primaryKey, text, timestamp, } from 'drizzle-orm/pg-core';
2
2
  /**
3
3
  * Mirrors `migrations/0001_declared_org.sql`, which is the source of truth:
4
4
  * the SQL carries the CHECKs drizzle-kit does not generate here (this
@@ -54,6 +54,9 @@ export const declaredOrgs = pgTable('foundry_declared_orgs', {
54
54
  // hosting_access_emails and hosting_app_env columns, which stay for an older
55
55
  // reader and are no longer written.
56
56
  hostingEntries: jsonb('hosting_entries').notNull().default([]).$type(),
57
+ // HostingConfig.adopt (org.ts): the live resources the org takes over by
58
+ // uuid. null when it adopts none. An entry's own `adopt` lives in `hostingEntries`.
59
+ hostingAdopt: jsonb('hosting_adopt').$type(),
57
60
  ssoEnabled: boolean('sso_enabled').notNull().default(false),
58
61
  guestsEnabled: boolean('guests_enabled').notNull().default(false),
59
62
  soloEnabled: boolean('solo_enabled').notNull().default(false),
@@ -172,3 +175,18 @@ export const foundryRequestedChanges = pgTable('foundry_requested_changes', {
172
175
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
173
176
  state: text('state').notNull().default('needs_approval'),
174
177
  });
178
+ /**
179
+ * Mirrors `migrations/0031_adoptions.sql`, which is the source of truth (the
180
+ * CHECKs live there). One row per live resource foundry took over (#311).
181
+ * `settings` holds non-secret settings only; secrets go to the vault under
182
+ * `vaultRef`.
183
+ */
184
+ export const foundryAdoptions = pgTable('foundry_adoptions', {
185
+ orgId: text('org_id').notNull(),
186
+ resourceKey: text('resource_key').notNull(),
187
+ kind: text('kind').notNull(),
188
+ takenAt: timestamp('taken_at', { withTimezone: true }).notNull(),
189
+ settings: jsonb('settings').notNull().$type(),
190
+ vaultRef: text('vault_ref'),
191
+ state: text('state').notNull().default('adopted'),
192
+ }, (table) => [primaryKey({ columns: [table.orgId, table.resourceKey] })]);
package/dist/store.d.ts CHANGED
@@ -96,3 +96,40 @@ export interface RequestedChangeStore {
96
96
  /** Every request an org has made, oldest first. */
97
97
  listForOrg(orgId: OrgId): Promise<RequestedChange[]>;
98
98
  }
99
+ export type AdoptionKind = 'app' | 'database' | 'tunnel' | 'connector' | 'access';
100
+ export type AdoptionState = 'adopted' | 'confirmed' | 'restored' | 'released';
101
+ /**
102
+ * What foundry recorded before it first changed a live resource it took over
103
+ * (#311). `settings` holds non-secret settings only; secrets live in the
104
+ * `AdoptionVault` (`plan/adoption-vault.ts`) under `vaultRef`.
105
+ */
106
+ export interface Adoption {
107
+ orgId: OrgId;
108
+ /** The scope key of the resource, for example `coolify:app:<orgId>:<entryKey>`. */
109
+ resourceKey: string;
110
+ kind: AdoptionKind;
111
+ /** ISO time the snapshot was taken. */
112
+ takenAt: string;
113
+ settings: Record<string, unknown>;
114
+ /** The vault ref of the secret part of the snapshot, or `null` when it has none. */
115
+ vaultRef: string | null;
116
+ state: AdoptionState;
117
+ }
118
+ /** The persistence seam for #311's {@link Adoption} rows, beside {@link DeclaredOrgStore}. */
119
+ export interface AdoptionStore {
120
+ /**
121
+ * Inserts the row, or replaces it in any state; the row is stored as
122
+ * `adopted`. A new snapshot after a restore or a release replaces the old one.
123
+ */
124
+ put(adoption: Omit<Adoption, 'state'>): Promise<void>;
125
+ get(orgId: OrgId, resourceKey: string): Promise<Adoption | null>;
126
+ /** Every row of an org, ordered by resource key. */
127
+ list(orgId: OrgId): Promise<Adoption[]>;
128
+ /** Moves a row to `state`. A no-op for a row that does not exist. */
129
+ setState(orgId: OrgId, resourceKey: string, state: AdoptionState): Promise<void>;
130
+ /**
131
+ * Replaces a row's `settings` and nothing else: its state, `takenAt` and
132
+ * `vaultRef` stay (#312). A no-op for a row that does not exist.
133
+ */
134
+ setSettings(orgId: OrgId, resourceKey: string, settings: Record<string, unknown>): Promise<void>;
135
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtfalch/foundry",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
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",