@agent-native/core 0.209.2 → 0.209.3-nightly-20261016212700
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/a2a-claims.js +5 -5
- package/dist/agent/context-xray/plugin.js +2 -6
- package/dist/agent/context-xray/schema-store.d.ts +1 -0
- package/dist/agent/context-xray/schema-store.js +7 -0
- package/dist/agent/harness/store.js +3 -0
- package/dist/agent/observational-memory/plugin.js +2 -6
- package/dist/agent/observational-memory/store.js +3 -0
- package/dist/agent/run-store.js +3 -0
- package/dist/agent/tool-approval-store.js +4 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/chat-threads/store.js +3 -0
- package/dist/client/action-query-cache-context.d.ts +1 -0
- package/dist/client/action-query-cache-context.js +2 -0
- package/dist/client/action-query-cache.d.ts +1 -1
- package/dist/client/action-query-cache.js +34 -15
- package/dist/client/motion-text.css +8 -0
- package/dist/client/motion-text.d.ts +6 -0
- package/dist/client/motion-text.js +154 -29
- package/dist/client/use-action.js +18 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/migrations.d.ts +1 -0
- package/dist/db/migrations.js +1 -1
- package/dist/db/runtime-facts.d.ts +7 -0
- package/dist/db/runtime-facts.js +18 -0
- package/dist/db/schema-catalog.js +4 -1
- package/dist/db/store-ledger.test-helpers.d.ts +5 -0
- package/dist/db/store-ledger.test-helpers.js +19 -0
- package/dist/db/store-registry.d.ts +34 -0
- package/dist/db/store-registry.generated.js +13 -0
- package/dist/db/store-registry.js +288 -46
- package/dist/db/versioned-store-migrations.d.ts +14 -0
- package/dist/db/versioned-store-migrations.js +37 -0
- package/dist/db/widen-columns.js +5 -2
- package/dist/extensions/html-shell.js +67 -0
- package/dist/integrations/remote-devices-store.js +3 -0
- package/dist/jobs/run-history.d.ts +3 -2
- package/dist/jobs/run-history.js +5 -5
- package/dist/jobs/scheduler-health.d.ts +3 -2
- package/dist/jobs/scheduler-health.js +5 -5
- package/dist/mcp/build-server.d.ts +3 -0
- package/dist/mcp/build-server.js +24 -7
- package/dist/mcp/server.js +40 -9
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/oauth-tokens/store.js +3 -0
- package/dist/observability/routes.d.ts +4 -4
- package/dist/observability/store.js +4 -0
- package/dist/org/auto-join-domain.js +23 -15
- package/dist/org/context.d.ts +12 -0
- package/dist/org/context.js +27 -19
- package/dist/org/handlers.js +31 -13
- package/dist/org/index.d.ts +2 -1
- package/dist/org/index.js +1 -0
- package/dist/org/plugin.js +2 -4
- package/dist/org/schema-store.d.ts +1 -0
- package/dist/org/schema-store.js +13 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +9 -9
- package/dist/resources/store.js +5 -2
- package/dist/server/agent-access.js +2 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/auth-plugin.js +2 -6
- package/dist/server/auth.js +22 -2
- package/dist/server/better-auth-migrations.d.ts +4 -2
- package/dist/server/better-auth-migrations.js +18 -6
- package/dist/server/identity-sso-store.js +3 -0
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/release-migrations.d.ts +1 -1
- package/dist/server/release-migrations.js +3 -65
- package/dist/server/release-schema.js +10 -2
- package/dist/server/short-lived-token.d.ts +3 -2
- package/dist/server/short-lived-token.js +3 -2
- package/dist/triggers/actions/manage-automation.d.ts +3 -3
- package/dist/triggers/event-queue.d.ts +4 -2
- package/dist/triggers/event-queue.js +38 -38
- package/dist/usage/alerts-store.js +3 -0
- package/dist/workspace-connections/groups.js +4 -0
- package/dist/workspace-connections/store.js +3 -0
- package/package.json +3 -3
|
@@ -316,6 +316,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
316
316
|
notes?: string | undefined;
|
|
317
317
|
scope?: "org" | "user" | undefined;
|
|
318
318
|
}, {
|
|
319
|
+
id?: undefined;
|
|
320
|
+
deleted?: undefined;
|
|
319
321
|
message?: undefined;
|
|
320
322
|
providers: {
|
|
321
323
|
id: string;
|
|
@@ -329,33 +331,31 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
329
331
|
count: number;
|
|
330
332
|
provider?: undefined;
|
|
331
333
|
found?: undefined;
|
|
332
|
-
deleted?: undefined;
|
|
333
334
|
registered?: undefined;
|
|
334
|
-
id?: undefined;
|
|
335
335
|
label?: undefined;
|
|
336
336
|
} | {
|
|
337
|
-
|
|
337
|
+
id?: undefined;
|
|
338
|
+
deleted?: undefined;
|
|
338
339
|
count?: undefined;
|
|
340
|
+
message?: undefined;
|
|
339
341
|
providers?: undefined;
|
|
340
342
|
found: boolean;
|
|
341
343
|
provider: import("../custom-registry.js").CustomProviderConfig;
|
|
342
|
-
deleted?: undefined;
|
|
343
344
|
registered?: undefined;
|
|
344
|
-
id?: undefined;
|
|
345
345
|
label?: undefined;
|
|
346
346
|
} | {
|
|
347
|
-
|
|
347
|
+
deleted?: undefined;
|
|
348
348
|
count?: undefined;
|
|
349
|
+
message?: undefined;
|
|
349
350
|
providers?: undefined;
|
|
350
351
|
provider?: undefined;
|
|
351
352
|
found: boolean;
|
|
352
353
|
id: string;
|
|
353
|
-
deleted?: undefined;
|
|
354
354
|
registered?: undefined;
|
|
355
355
|
label?: undefined;
|
|
356
356
|
} | {
|
|
357
|
-
message?: undefined;
|
|
358
357
|
count?: undefined;
|
|
358
|
+
message?: undefined;
|
|
359
359
|
providers?: undefined;
|
|
360
360
|
provider?: undefined;
|
|
361
361
|
found?: undefined;
|
|
@@ -364,11 +364,11 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
|
|
|
364
364
|
registered?: undefined;
|
|
365
365
|
label?: undefined;
|
|
366
366
|
} | {
|
|
367
|
+
deleted?: undefined;
|
|
367
368
|
count?: undefined;
|
|
368
369
|
providers?: undefined;
|
|
369
370
|
provider?: undefined;
|
|
370
371
|
found?: undefined;
|
|
371
|
-
deleted?: undefined;
|
|
372
372
|
registered: boolean;
|
|
373
373
|
id: string;
|
|
374
374
|
label: string;
|
package/dist/resources/store.js
CHANGED
|
@@ -3,6 +3,7 @@ import { getDbExec } from "../db/client.js";
|
|
|
3
3
|
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
4
4
|
import { isMigrationAuthorizedRuntime } from "../db/migration-runtime.js";
|
|
5
5
|
import { retainRequestDbPoolScope } from "../db/request-pool-context.js";
|
|
6
|
+
import { isRecordingStoreMigration } from "../db/runtime-facts.js";
|
|
6
7
|
import { defineStore } from "../db/store-registry.js";
|
|
7
8
|
import { widenIntColumnsToBigInt } from "../db/widen-columns.js";
|
|
8
9
|
import { noteJobFrontmatterWrite } from "../jobs/frontmatter-loss.js";
|
|
@@ -866,8 +867,9 @@ export const resourcesStore = defineStore({
|
|
|
866
867
|
run: async () => {
|
|
867
868
|
await ensureIndexExists("resources_visibility_expires_idx", `CREATE INDEX IF NOT EXISTS resources_visibility_expires_idx ON resources (visibility, expires_at)`).catch((err) => {
|
|
868
869
|
// At release, fail so the ledger never records an index that was not built.
|
|
869
|
-
if (isMigrationAuthorizedRuntime())
|
|
870
|
+
if (isMigrationAuthorizedRuntime() || isRecordingStoreMigration()) {
|
|
870
871
|
throw err;
|
|
872
|
+
}
|
|
871
873
|
// An index is an optimization, not a correctness requirement: a
|
|
872
874
|
// concurrent creator or a permissions edge must not fail table init and
|
|
873
875
|
// take the app down with it. The scan it avoids is slow, not wrong — but
|
|
@@ -889,8 +891,9 @@ export const resourcesStore = defineStore({
|
|
|
889
891
|
// `CREATE INDEX CONCURRENTLY` without creating anything (see the matching
|
|
890
892
|
// note in chat-threads/store.ts). A plain build is the form that lands.
|
|
891
893
|
await ensureIndexExists("resources_path_pattern_idx", `CREATE INDEX IF NOT EXISTS resources_path_pattern_idx ON resources (path text_pattern_ops)`).catch((err) => {
|
|
892
|
-
if (isMigrationAuthorizedRuntime())
|
|
894
|
+
if (isMigrationAuthorizedRuntime() || isRecordingStoreMigration()) {
|
|
893
895
|
throw err;
|
|
896
|
+
}
|
|
894
897
|
// coercion-ok: absence of an index degrades latency, never correctness
|
|
895
898
|
console.warn("[resources] could not ensure resources_path_pattern_idx; prefix reads such as the jobs/ fingerprint will full-scan:", err?.message ?? err);
|
|
896
899
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_AGENT_ACCESS_TTL_SECONDS, scopedAgentAccessResourceId, } from "../shared/agent-access.js";
|
|
2
|
-
import { signCompactShortLivedToken, verifyCompactShortLivedToken,
|
|
2
|
+
import { signCompactShortLivedToken, verifyCompactShortLivedToken, } from "./short-lived-token.js";
|
|
3
3
|
export { AGENT_ACCESS_PARAM, DEFAULT_AGENT_ACCESS_TTL_SECONDS, appendAgentAccessParam, buildAgentAccessApiUrl, buildAgentAccessUrl, normalizeAgentAccessBasePath, normalizeAgentAccessOrigin, scopedAgentAccessResourceId, toAgentAccessUrl, } from "../shared/agent-access.js";
|
|
4
4
|
export function signScopedAgentAccessToken({ resourceKind, resourceId, viewerEmail, agentLabel, ttlSeconds = DEFAULT_AGENT_ACCESS_TTL_SECONDS, }) {
|
|
5
5
|
return signCompactShortLivedToken({
|
|
@@ -12,11 +12,7 @@ export function signScopedAgentAccessToken({ resourceKind, resourceId, viewerEma
|
|
|
12
12
|
export function verifyScopedAgentAccessToken(token, scope) {
|
|
13
13
|
if (!token)
|
|
14
14
|
return { ok: false, reason: "missing" };
|
|
15
|
-
|
|
16
|
-
const compact = verifyCompactShortLivedToken(token, resourceId);
|
|
17
|
-
if (compact.ok || compact.reason !== "bad_signature")
|
|
18
|
-
return compact;
|
|
19
|
-
return verifyShortLivedToken(token, resourceId);
|
|
15
|
+
return verifyCompactShortLivedToken(token, scopedAgentAccessResourceId(scope.resourceKind, scope.resourceId));
|
|
20
16
|
}
|
|
21
17
|
export function createScopedAgentAccessGrant(options) {
|
|
22
18
|
const ttlSeconds = options.ttlSeconds ?? DEFAULT_AGENT_ACCESS_TTL_SECONDS;
|
|
@@ -67,12 +67,12 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
67
67
|
code: any;
|
|
68
68
|
} | {
|
|
69
69
|
errorCode?: undefined;
|
|
70
|
-
error?: undefined;
|
|
71
70
|
code?: undefined;
|
|
72
71
|
ok: boolean;
|
|
73
72
|
key: string;
|
|
74
73
|
baseUrlKey?: string;
|
|
75
74
|
scope: AgentEngineApiKeyScope;
|
|
76
75
|
defaultModel?: import("./agent-engine-default-model-route.js").SavedKeyDefaultModelOutcome;
|
|
76
|
+
error?: undefined;
|
|
77
77
|
}>>;
|
|
78
78
|
export {};
|
|
@@ -8,8 +8,8 @@ export declare const AGENT_ENGINE_API_KEY_ACTION_NAME = "agent-engine-api-key";
|
|
|
8
8
|
* resolveEngine's credential detection.
|
|
9
9
|
*/
|
|
10
10
|
export declare function createAgentEngineDisconnectHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
11
|
-
ok?: undefined;
|
|
12
11
|
error: string;
|
|
12
|
+
ok?: undefined;
|
|
13
13
|
scope?: undefined;
|
|
14
14
|
} | {
|
|
15
15
|
ok: boolean;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ORG_MIGRATIONS } from "../org/migrations.js";
|
|
1
|
+
import { orgStore } from "../org/schema-store.js";
|
|
3
2
|
import { authSessionHandler, autoMountAuth } from "./auth.js";
|
|
4
3
|
import { runBetterAuthMigrations } from "./better-auth-migrations.js";
|
|
5
4
|
import { FRAMEWORK_AUTH_EARLY_PATHS, getH3App, markDefaultPluginProvided, markFrameworkRoutesReadyBeforeBootstrap, trackPluginInit, } from "./framework-request-handler.js";
|
|
6
5
|
export function createAuthPlugin(options) {
|
|
7
|
-
const migrateOrgSchema = runMigrations(ORG_MIGRATIONS, {
|
|
8
|
-
table: "_org_migrations",
|
|
9
|
-
});
|
|
10
6
|
return (nitroApp) => {
|
|
11
7
|
markDefaultPluginProvided(nitroApp, "auth");
|
|
12
8
|
const isByoa = Boolean(options?.getSession);
|
|
@@ -38,7 +34,7 @@ export function createAuthPlugin(options) {
|
|
|
38
34
|
// transaction, where a missing table aborts the sign-up. The org
|
|
39
35
|
// plugin migrates only after the whole bootstrap, too late for that.
|
|
40
36
|
const mountPromise = runBetterAuthMigrations(nitroApp)
|
|
41
|
-
.then(() =>
|
|
37
|
+
.then(() => orgStore.ready())
|
|
42
38
|
.then(() => autoMountAuth(app, options));
|
|
43
39
|
markFrameworkRoutesReadyBeforeBootstrap(nitroApp, FRAMEWORK_AUTH_EARLY_PATHS);
|
|
44
40
|
await mountPromise;
|
package/dist/server/auth.js
CHANGED
|
@@ -802,11 +802,21 @@ export async function getMcpOAuthBearerSession(event) {
|
|
|
802
802
|
const bearerToken = getBearerSessionToken(event);
|
|
803
803
|
if (!bearerToken)
|
|
804
804
|
return null;
|
|
805
|
+
let identityVerificationUnavailableErrorClass;
|
|
806
|
+
let identityVerificationRefusedErrorClass;
|
|
807
|
+
let connectUrl;
|
|
805
808
|
try {
|
|
806
|
-
const [
|
|
809
|
+
const [oauthRoute, mcp] = await Promise.all([
|
|
807
810
|
import("../mcp/oauth-route.js"),
|
|
808
811
|
import("../mcp/build-server.js"),
|
|
809
812
|
]);
|
|
813
|
+
connectUrl = oauthRoute.getMcpConnectUrl(event);
|
|
814
|
+
identityVerificationUnavailableErrorClass =
|
|
815
|
+
mcp.McpIdentityVerificationUnavailableError;
|
|
816
|
+
identityVerificationRefusedErrorClass =
|
|
817
|
+
mcp.McpIdentityVerificationRefusedError;
|
|
818
|
+
const { getMcpOAuthAudiences } = oauthRoute;
|
|
819
|
+
const { verifyAuth, resolveMcpIdentityOrgId } = mcp;
|
|
810
820
|
const result = await verifyAuth(authHeader, undefined, {
|
|
811
821
|
resourceUrl: getMcpOAuthAudiences(event),
|
|
812
822
|
allowDevOpen: false,
|
|
@@ -818,7 +828,7 @@ export async function getMcpOAuthBearerSession(event) {
|
|
|
818
828
|
}
|
|
819
829
|
if (!result.authed) {
|
|
820
830
|
if (result.refusal) {
|
|
821
|
-
markBearerCredentialRefused(event, result.refusal,
|
|
831
|
+
markBearerCredentialRefused(event, result.refusal, connectUrl);
|
|
822
832
|
}
|
|
823
833
|
return null;
|
|
824
834
|
}
|
|
@@ -843,6 +853,16 @@ export async function getMcpOAuthBearerSession(event) {
|
|
|
843
853
|
};
|
|
844
854
|
}
|
|
845
855
|
catch (e) {
|
|
856
|
+
if (identityVerificationRefusedErrorClass &&
|
|
857
|
+
e instanceof identityVerificationRefusedErrorClass) {
|
|
858
|
+
markBearerCredentialRefused(event, "invalid", connectUrl);
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
if (identityVerificationUnavailableErrorClass &&
|
|
862
|
+
e instanceof identityVerificationUnavailableErrorClass) {
|
|
863
|
+
markCredentialMembershipUnavailable(event);
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
846
866
|
console.error("[auth] MCP OAuth bearer verification error:", e);
|
|
847
867
|
return null;
|
|
848
868
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { MigrationEntry } from "../db/migrations.js";
|
|
2
2
|
/**
|
|
3
3
|
* Better Auth encrypts persisted JWT private keys with the current auth
|
|
4
4
|
* secret. If that secret is rotated, the old row remains the newest key and
|
|
@@ -19,4 +19,6 @@ export declare function expireJwksKeysAfterAuthSecretRotation(): Promise<void>;
|
|
|
19
19
|
* be able to construct the auth adapter without probing or creating tables.
|
|
20
20
|
*/
|
|
21
21
|
export declare const BETTER_AUTH_MIGRATIONS: MigrationEntry[];
|
|
22
|
-
export declare
|
|
22
|
+
export declare const betterAuthStore: import("../db/store-registry.js").Store;
|
|
23
|
+
/** Kept for callers of the public export; the store owns these migrations. */
|
|
24
|
+
export declare function runBetterAuthMigrations(_nitroApp?: unknown): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineStore } from "../db/store-registry.js";
|
|
2
|
+
import { fromMigrationEntries } from "../db/versioned-store-migrations.js";
|
|
2
3
|
async function assertBetterAuthUserIdentityColumns() {
|
|
3
4
|
const { getDbExec } = await import("../db/client.js");
|
|
4
5
|
const { rows } = await getDbExec().execute(`SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = 'user' AND column_name IN ('id', 'email')`);
|
|
@@ -170,7 +171,9 @@ export const BETTER_AUTH_MIGRATIONS = [
|
|
|
170
171
|
},
|
|
171
172
|
},
|
|
172
173
|
{
|
|
173
|
-
|
|
174
|
+
// Shipped as a second v5. Named entries are gated by name, so the new
|
|
175
|
+
// number changes nothing for databases that already applied it.
|
|
176
|
+
version: 11,
|
|
174
177
|
name: "better-auth-user-lower-email-index",
|
|
175
178
|
sql: {
|
|
176
179
|
postgres: 'CREATE INDEX IF NOT EXISTS better_auth_user_lower_email_idx ON "user" (LOWER(email))',
|
|
@@ -447,8 +450,17 @@ export const BETTER_AUTH_MIGRATIONS = [
|
|
|
447
450
|
},
|
|
448
451
|
},
|
|
449
452
|
];
|
|
450
|
-
export
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
453
|
+
export const betterAuthStore = defineStore({
|
|
454
|
+
id: "better_auth",
|
|
455
|
+
// v3 creates the legacy `sessions` table the auth-sessions store owns; on
|
|
456
|
+
// main every store ran before this list.
|
|
457
|
+
after: ["auth_sessions"],
|
|
458
|
+
migrations: fromMigrationEntries("_better_auth_migrations", BETTER_AUTH_MIGRATIONS,
|
|
459
|
+
// v4 expires every active signing key: it must run at most once per
|
|
460
|
+
// database, which the ledger (or the imported old bookkeeping) guarantees.
|
|
461
|
+
{ ranAtBoot: true, data: [4] }),
|
|
462
|
+
});
|
|
463
|
+
/** Kept for callers of the public export; the store owns these migrations. */
|
|
464
|
+
export async function runBetterAuthMigrations(_nitroApp) {
|
|
465
|
+
await betterAuthStore.ready();
|
|
454
466
|
}
|
|
@@ -2,6 +2,8 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { getDbExec, isConnectionError } from "../db/client.js";
|
|
3
3
|
import { ensureTableExists } from "../db/ddl-guard.js";
|
|
4
4
|
import { defineStore } from "../db/store-registry.js";
|
|
5
|
+
import { fromMigrationEntries } from "../db/versioned-store-migrations.js";
|
|
6
|
+
import { IDENTITY_SSO_MIGRATIONS } from "./identity-sso-migrations.js";
|
|
5
7
|
const DESKTOP_SSO_USER_AGENT = /AgentNativeDesktop(?:SsoCanary)?\//i;
|
|
6
8
|
const DESKTOP_SSO_CANARY_USER_AGENT = /AgentNativeDesktopSsoCanary\//i;
|
|
7
9
|
export const CANONICAL_IDENTITY_SSO_HUB_URL = "https://dispatch.agent-native.com";
|
|
@@ -223,6 +225,7 @@ export const identitySsoStore = defineStore({
|
|
|
223
225
|
await ensureTableExists("identity_sso_jti", buildIdentitySsoJtiCreateSql());
|
|
224
226
|
},
|
|
225
227
|
},
|
|
228
|
+
...fromMigrationEntries("_identity_sso_migrations", IDENTITY_SSO_MIGRATIONS),
|
|
226
229
|
],
|
|
227
230
|
});
|
|
228
231
|
export function ensureTable() {
|
|
@@ -54,8 +54,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
54
54
|
expiresAt?: undefined;
|
|
55
55
|
ttlSeconds?: undefined;
|
|
56
56
|
} | {
|
|
57
|
-
error?: undefined;
|
|
58
57
|
token: string;
|
|
59
58
|
expiresAt: string;
|
|
60
59
|
ttlSeconds: number;
|
|
60
|
+
error?: undefined;
|
|
61
61
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function runFrameworkReleaseMigrations(
|
|
1
|
+
export declare function runFrameworkReleaseMigrations(_nitroApp?: unknown): Promise<void>;
|
|
@@ -1,26 +1,8 @@
|
|
|
1
|
-
import { CONTEXT_XRAY_MIGRATIONS } from "../agent/context-xray/migrations.js";
|
|
2
|
-
import { AGENT_HARNESS_SESSION_MIGRATIONS, AGENT_HARNESS_SESSION_MIGRATIONS_TABLE, } from "../agent/harness/migrations.js";
|
|
3
|
-
import { OBSERVATIONAL_MEMORY_MIGRATIONS } from "../agent/observational-memory/migrations.js";
|
|
4
|
-
import { AGENT_RUN_MIGRATIONS, AGENT_RUN_MIGRATIONS_TABLE, } from "../agent/run-migrations.js";
|
|
5
|
-
import { AGENT_TOOL_APPROVAL_MIGRATIONS, AGENT_TOOL_APPROVAL_MIGRATIONS_TABLE, } from "../agent/tool-approval-migrations.js";
|
|
6
1
|
import { getAppConfig } from "../app-config/index.js";
|
|
7
|
-
import { CHAT_THREAD_SCHEMA_MIGRATIONS, CHAT_THREAD_SCHEMA_MIGRATIONS_TABLE, } from "../chat-threads/schema-migrations.js";
|
|
8
2
|
import { getDatabaseUrl } from "../db/client.js";
|
|
9
|
-
import { runMigrations } from "../db/migrations.js";
|
|
10
3
|
import { withStoreMigrationLock } from "../db/store-registry.js";
|
|
11
|
-
import { REMOTE_DEVICE_MIGRATIONS, REMOTE_DEVICE_MIGRATIONS_TABLE, } from "../integrations/remote-device-migrations.js";
|
|
12
|
-
import { runAutomationRunMigrations } from "../jobs/run-history.js";
|
|
13
|
-
import { runAutomationSchedulerHealthMigrations } from "../jobs/scheduler-health.js";
|
|
14
|
-
import { OAUTH_TOKEN_MIGRATIONS, OAUTH_TOKEN_MIGRATIONS_TABLE, } from "../oauth-tokens/migrations.js";
|
|
15
|
-
import { OBSERVABILITY_MIGRATIONS, OBSERVABILITY_MIGRATIONS_TABLE, } from "../observability/migrations.js";
|
|
16
|
-
import { ORG_MIGRATIONS } from "../org/migrations.js";
|
|
17
4
|
import { ensureSharingAccessIndexes } from "../sharing/indexes.js";
|
|
18
|
-
import { runAutomationTriggerEventMigrations } from "../triggers/event-queue.js";
|
|
19
|
-
import { USAGE_ALERT_MIGRATIONS, USAGE_ALERT_MIGRATIONS_TABLE, } from "../usage/migrations.js";
|
|
20
|
-
import { WORKSPACE_CONNECTIONS_MIGRATIONS, WORKSPACE_CONNECTIONS_MIGRATIONS_TABLE, } from "../workspace-connections/migrations.js";
|
|
21
|
-
import { runBetterAuthMigrations } from "./better-auth-migrations.js";
|
|
22
5
|
import { recordDatabaseIdentity } from "./database-identity.js";
|
|
23
|
-
import { IDENTITY_SSO_MIGRATIONS } from "./identity-sso-migrations.js";
|
|
24
6
|
import { runFrameworkSchemaEnsures } from "./release-schema.js";
|
|
25
7
|
/**
|
|
26
8
|
* A release deploy whose `DATABASE_URL` resolves to a local development
|
|
@@ -62,57 +44,13 @@ function describeReleaseMigrationUrl(url) {
|
|
|
62
44
|
const scheme = url.includes("://") ? url.split("://")[0] : undefined;
|
|
63
45
|
return scheme ? `${scheme} url` : "no scheme — likely a masked secret";
|
|
64
46
|
}
|
|
65
|
-
export async function runFrameworkReleaseMigrations(
|
|
47
|
+
export async function runFrameworkReleaseMigrations(_nitroApp) {
|
|
66
48
|
assertReleaseMigrationTargetsRemoteDatabase();
|
|
67
|
-
// One lease for the whole release
|
|
68
|
-
//
|
|
49
|
+
// One lease for the whole release, so two deploys against one database
|
|
50
|
+
// never interleave.
|
|
69
51
|
await withStoreMigrationLock(async () => {
|
|
70
|
-
// First: the versioned migration lists below only cover the tables that have
|
|
71
|
-
// one. Most framework tables are defined by their store's `ensureTable()`,
|
|
72
|
-
// which production serverless can never run — see `./release-schema.ts`.
|
|
73
52
|
await runFrameworkSchemaEnsures();
|
|
74
53
|
await recordDatabaseIdentity();
|
|
75
|
-
await runBetterAuthMigrations(nitroApp);
|
|
76
|
-
await runMigrations(AGENT_TOOL_APPROVAL_MIGRATIONS, {
|
|
77
|
-
table: AGENT_TOOL_APPROVAL_MIGRATIONS_TABLE,
|
|
78
|
-
})(nitroApp);
|
|
79
|
-
await runMigrations(OAUTH_TOKEN_MIGRATIONS, {
|
|
80
|
-
table: OAUTH_TOKEN_MIGRATIONS_TABLE,
|
|
81
|
-
})(nitroApp);
|
|
82
|
-
await runMigrations(CHAT_THREAD_SCHEMA_MIGRATIONS, {
|
|
83
|
-
table: CHAT_THREAD_SCHEMA_MIGRATIONS_TABLE,
|
|
84
|
-
})(nitroApp);
|
|
85
|
-
await runMigrations(OBSERVABILITY_MIGRATIONS, {
|
|
86
|
-
table: OBSERVABILITY_MIGRATIONS_TABLE,
|
|
87
|
-
})(nitroApp);
|
|
88
|
-
await runMigrations(AGENT_RUN_MIGRATIONS, {
|
|
89
|
-
table: AGENT_RUN_MIGRATIONS_TABLE,
|
|
90
|
-
})(nitroApp);
|
|
91
|
-
await runMigrations(AGENT_HARNESS_SESSION_MIGRATIONS, {
|
|
92
|
-
table: AGENT_HARNESS_SESSION_MIGRATIONS_TABLE,
|
|
93
|
-
})(nitroApp);
|
|
94
|
-
await runMigrations(USAGE_ALERT_MIGRATIONS, {
|
|
95
|
-
table: USAGE_ALERT_MIGRATIONS_TABLE,
|
|
96
|
-
})(nitroApp);
|
|
97
|
-
await runMigrations(ORG_MIGRATIONS, { table: "_org_migrations" })(nitroApp);
|
|
98
|
-
await runMigrations(REMOTE_DEVICE_MIGRATIONS, {
|
|
99
|
-
table: REMOTE_DEVICE_MIGRATIONS_TABLE,
|
|
100
|
-
})(nitroApp);
|
|
101
|
-
await runMigrations(IDENTITY_SSO_MIGRATIONS, {
|
|
102
|
-
table: "_identity_sso_migrations",
|
|
103
|
-
})(nitroApp);
|
|
104
|
-
await runMigrations(CONTEXT_XRAY_MIGRATIONS, {
|
|
105
|
-
table: "_context_xray_migrations",
|
|
106
|
-
})(nitroApp);
|
|
107
|
-
await runMigrations(OBSERVATIONAL_MEMORY_MIGRATIONS, {
|
|
108
|
-
table: "_observational_memory_migrations",
|
|
109
|
-
})(nitroApp);
|
|
110
|
-
await runMigrations(WORKSPACE_CONNECTIONS_MIGRATIONS, {
|
|
111
|
-
table: WORKSPACE_CONNECTIONS_MIGRATIONS_TABLE,
|
|
112
|
-
})(nitroApp);
|
|
113
|
-
await runAutomationRunMigrations(nitroApp);
|
|
114
|
-
await runAutomationTriggerEventMigrations(nitroApp);
|
|
115
|
-
await runAutomationSchedulerHealthMigrations(nitroApp);
|
|
116
54
|
// Last, so the framework's own share and owner tables exist. An app's tables
|
|
117
55
|
// are indexed by the release after the one that creates them.
|
|
118
56
|
await ensureSharingAccessIndexes();
|
|
@@ -9,11 +9,16 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { isMigrationAuthorizedRuntime } from "../db/migration-runtime.js";
|
|
11
11
|
import { FRAMEWORK_STORES } from "../db/store-registry.generated.js";
|
|
12
|
-
import { SchemaNotMigratedError, findUnappliedStoreMigrations, withStoreMigrationLock, } from "../db/store-registry.js";
|
|
12
|
+
import { SchemaNotMigratedError, findUnappliedStoreMigrations, orderStoresForRelease, withStoreMigrationLock, } from "../db/store-registry.js";
|
|
13
13
|
const FRAMEWORK_SCHEMA_ENSURES = FRAMEWORK_STORES.map(([id, load]) => [id, () => load().then((store) => store.ready())]);
|
|
14
14
|
export function frameworkSchemaEnsureNames() {
|
|
15
15
|
return FRAMEWORK_SCHEMA_ENSURES.map(([name]) => name);
|
|
16
16
|
}
|
|
17
|
+
/** Every registered store, loaded and ordered by its `after` dependencies. */
|
|
18
|
+
async function orderedFrameworkEnsures() {
|
|
19
|
+
const stores = await Promise.all(FRAMEWORK_STORES.map(([, load]) => load()));
|
|
20
|
+
return orderStoresForRelease(stores).map((store) => [store.id, () => store.ready()]);
|
|
21
|
+
}
|
|
17
22
|
/**
|
|
18
23
|
* Create every framework-owned table, in one pass, before the app serves
|
|
19
24
|
* traffic. Callers must hold migration duty via `withMigrationRuntime`; without
|
|
@@ -31,8 +36,11 @@ export async function runFrameworkSchemaEnsures(ensures = FRAMEWORK_SCHEMA_ENSUR
|
|
|
31
36
|
if (!isMigrationAuthorizedRuntime()) {
|
|
32
37
|
throw new Error("runFrameworkSchemaEnsures must run inside withMigrationRuntime(); outside it no store is migrated.");
|
|
33
38
|
}
|
|
39
|
+
const pass = ensures === FRAMEWORK_SCHEMA_ENSURES
|
|
40
|
+
? await orderedFrameworkEnsures()
|
|
41
|
+
: ensures;
|
|
34
42
|
await withStoreMigrationLock(async () => {
|
|
35
|
-
for (const [name, run] of
|
|
43
|
+
for (const [name, run] of pass) {
|
|
36
44
|
try {
|
|
37
45
|
await run();
|
|
38
46
|
}
|
|
@@ -34,8 +34,9 @@ export declare function verifyShortLivedToken(token: string, expectedResourceId:
|
|
|
34
34
|
export declare function signCompactShortLivedToken(claims: ShortLivedTokenClaims): string;
|
|
35
35
|
/**
|
|
36
36
|
* Verify a token produced by {@link signCompactShortLivedToken}. A token for a
|
|
37
|
-
* different resource, and any
|
|
38
|
-
* is not in the payload, so a mismatch is
|
|
37
|
+
* different resource, and any `signShortLivedToken` token, fails as
|
|
38
|
+
* `bad_signature` — the id is not in the payload, so a mismatch is
|
|
39
|
+
* indistinguishable from tampering.
|
|
39
40
|
*/
|
|
40
41
|
export declare function verifyCompactShortLivedToken(token: string, expectedResourceId: string): VerifyResult;
|
|
41
42
|
/** Payload `typ` discriminator for realtime subscribe tokens. */
|
|
@@ -123,8 +123,9 @@ export function signCompactShortLivedToken(claims) {
|
|
|
123
123
|
}
|
|
124
124
|
/**
|
|
125
125
|
* Verify a token produced by {@link signCompactShortLivedToken}. A token for a
|
|
126
|
-
* different resource, and any
|
|
127
|
-
* is not in the payload, so a mismatch is
|
|
126
|
+
* different resource, and any `signShortLivedToken` token, fails as
|
|
127
|
+
* `bad_signature` — the id is not in the payload, so a mismatch is
|
|
128
|
+
* indistinguishable from tampering.
|
|
128
129
|
*/
|
|
129
130
|
export function verifyCompactShortLivedToken(token, expectedResourceId) {
|
|
130
131
|
if (typeof token !== "string" || !token.includes(".")) {
|
|
@@ -14,6 +14,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
14
14
|
executionCwd?: string;
|
|
15
15
|
}, {
|
|
16
16
|
deleted?: undefined;
|
|
17
|
+
enabled?: undefined;
|
|
17
18
|
created: boolean;
|
|
18
19
|
name: string;
|
|
19
20
|
scope: "organization" | "personal";
|
|
@@ -24,25 +25,24 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
24
25
|
reasoningEffort: "auto" | "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh";
|
|
25
26
|
webhookPath: string;
|
|
26
27
|
nextRun: string;
|
|
27
|
-
enabled?: undefined;
|
|
28
28
|
executionHostId?: undefined;
|
|
29
29
|
executionEngine?: undefined;
|
|
30
30
|
executionCwd?: undefined;
|
|
31
31
|
} | {
|
|
32
|
+
enabled?: undefined;
|
|
33
|
+
nextRun?: undefined;
|
|
32
34
|
created?: undefined;
|
|
33
35
|
scope?: undefined;
|
|
34
36
|
triggerType?: undefined;
|
|
35
37
|
event?: undefined;
|
|
36
38
|
deleted: boolean;
|
|
37
39
|
name: string;
|
|
38
|
-
enabled?: undefined;
|
|
39
40
|
schedule?: undefined;
|
|
40
41
|
timezone?: undefined;
|
|
41
42
|
reasoningEffort?: undefined;
|
|
42
43
|
executionHostId?: undefined;
|
|
43
44
|
executionEngine?: undefined;
|
|
44
45
|
executionCwd?: undefined;
|
|
45
|
-
nextRun?: undefined;
|
|
46
46
|
webhookPath?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
deleted?: undefined;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { MigrationEntry } from "../db/migrations.js";
|
|
2
2
|
export declare const AUTOMATION_TRIGGER_EVENT_DEDUPE_RETENTION_MS: number;
|
|
3
3
|
export declare const AUTOMATION_TRIGGER_EVENT_PURGE_BATCH_SIZE = 1000;
|
|
4
4
|
export declare const AUTOMATION_TRIGGER_EVENT_EXPIRY_BATCH_SIZE = 1000;
|
|
5
5
|
export declare const MAX_AUTOMATION_TRIGGER_EVENT_FAILURES = 8;
|
|
6
6
|
declare const CLAIM_LEASE_MS: () => number;
|
|
7
7
|
export declare const AUTOMATION_TRIGGER_EVENT_MIGRATIONS: MigrationEntry[];
|
|
8
|
-
export declare
|
|
8
|
+
export declare const automationTriggerEventsStore: import("../db/store-registry.js").Store;
|
|
9
|
+
/** Kept for callers of the export; the store owns these migrations. */
|
|
10
|
+
export declare function runAutomationTriggerEventMigrations(_nitroApp?: unknown): Promise<void>;
|
|
9
11
|
export declare function ensureAutomationTriggerEventQueue(): Promise<void>;
|
|
10
12
|
export interface EnqueueAutomationTriggerEventInput {
|
|
11
13
|
triggerId: string;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
// guard:allow-unreleased-schema — owned by the versioned AUTOMATION_TRIGGER_EVENT_MIGRATIONS list in release-migrations.ts until Phase 2 folds versioned lists into stores
|
|
2
1
|
import { randomUUID } from "node:crypto";
|
|
3
2
|
import { resolveBackgroundRunHardTimeoutMs } from "../agent/run-manager.js";
|
|
4
3
|
import { getDbExec } from "../db/client.js";
|
|
5
4
|
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { defineStore } from "../db/store-registry.js";
|
|
6
|
+
import { fromMigrationEntries } from "../db/versioned-store-migrations.js";
|
|
8
7
|
const TABLE = "automation_trigger_event_queue";
|
|
9
8
|
const SWEEP_STATE_TABLE = "automation_trigger_event_queue_sweep_state";
|
|
10
9
|
const COMPLETED_PAYLOAD = '{"kind":"completed"}';
|
|
@@ -91,42 +90,43 @@ export const AUTOMATION_TRIGGER_EVENT_MIGRATIONS = [
|
|
|
91
90
|
WHERE status IN ('pending', 'processing')`,
|
|
92
91
|
},
|
|
93
92
|
];
|
|
94
|
-
export
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
export const automationTriggerEventsStore = defineStore({
|
|
94
|
+
id: "automation_trigger_events",
|
|
95
|
+
migrations: [
|
|
96
|
+
{
|
|
97
|
+
name: "baseline",
|
|
98
|
+
run: async () => {
|
|
99
|
+
await ensureTableExists(TABLE, CREATE_TABLE_SQL);
|
|
100
|
+
await ensureTableExists(SWEEP_STATE_TABLE, CREATE_SWEEP_STATE_TABLE_SQL);
|
|
101
|
+
await ensureColumnExists(TABLE, "failure_attempts", `ALTER TABLE ${TABLE}
|
|
102
|
+
ADD COLUMN IF NOT EXISTS failure_attempts BIGINT NOT NULL DEFAULT 0`);
|
|
103
|
+
await ensureIndexExists(UNIQUE_INDEX, `CREATE UNIQUE INDEX IF NOT EXISTS ${UNIQUE_INDEX}
|
|
104
|
+
ON ${TABLE} (trigger_id, event_id)`);
|
|
105
|
+
await ensureIndexExists(ORDER_INDEX, `CREATE INDEX IF NOT EXISTS ${ORDER_INDEX}
|
|
106
|
+
ON ${TABLE} (trigger_id, sequence_id, status)`);
|
|
107
|
+
await ensureIndexExists(READY_INDEX, `CREATE INDEX IF NOT EXISTS ${READY_INDEX}
|
|
108
|
+
ON ${TABLE} (app_id, status, available_at, claimed_at)`);
|
|
109
|
+
await ensureIndexExists(ACTIVE_HEAD_INDEX, `CREATE INDEX IF NOT EXISTS ${ACTIVE_HEAD_INDEX}
|
|
110
|
+
ON ${TABLE} (app_id, trigger_id, sequence_id)
|
|
111
|
+
WHERE status IN ('pending', 'processing')`);
|
|
112
|
+
await ensureIndexExists(FAILED_INDEX, `CREATE INDEX IF NOT EXISTS ${FAILED_INDEX}
|
|
113
|
+
ON ${TABLE} (completed_at) WHERE status = 'failed'`);
|
|
114
|
+
await ensureIndexExists(STALE_EVENT_INDEX, `CREATE INDEX IF NOT EXISTS ${STALE_EVENT_INDEX}
|
|
115
|
+
ON ${TABLE} (app_id, event_name, emitted_at)
|
|
116
|
+
WHERE status = 'pending'`);
|
|
117
|
+
await ensureIndexExists(COMPLETED_INDEX, `CREATE INDEX IF NOT EXISTS ${COMPLETED_INDEX}
|
|
118
|
+
ON ${TABLE} (completed_at) WHERE status = 'completed'`);
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
...fromMigrationEntries("_automation_trigger_event_migrations", AUTOMATION_TRIGGER_EVENT_MIGRATIONS),
|
|
122
|
+
],
|
|
123
|
+
});
|
|
124
|
+
/** Kept for callers of the export; the store owns these migrations. */
|
|
125
|
+
export async function runAutomationTriggerEventMigrations(_nitroApp) {
|
|
126
|
+
await automationTriggerEventsStore.ready();
|
|
98
127
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!_initPromise) {
|
|
102
|
-
const _initPromiseWithRequestDbPoolScope = (async () => {
|
|
103
|
-
await ensureTableExists(TABLE, CREATE_TABLE_SQL);
|
|
104
|
-
await ensureTableExists(SWEEP_STATE_TABLE, CREATE_SWEEP_STATE_TABLE_SQL);
|
|
105
|
-
await ensureColumnExists(TABLE, "failure_attempts", `ALTER TABLE ${TABLE}
|
|
106
|
-
ADD COLUMN IF NOT EXISTS failure_attempts BIGINT NOT NULL DEFAULT 0`);
|
|
107
|
-
await ensureIndexExists(UNIQUE_INDEX, `CREATE UNIQUE INDEX IF NOT EXISTS ${UNIQUE_INDEX}
|
|
108
|
-
ON ${TABLE} (trigger_id, event_id)`);
|
|
109
|
-
await ensureIndexExists(ORDER_INDEX, `CREATE INDEX IF NOT EXISTS ${ORDER_INDEX}
|
|
110
|
-
ON ${TABLE} (trigger_id, sequence_id, status)`);
|
|
111
|
-
await ensureIndexExists(READY_INDEX, `CREATE INDEX IF NOT EXISTS ${READY_INDEX}
|
|
112
|
-
ON ${TABLE} (app_id, status, available_at, claimed_at)`);
|
|
113
|
-
await ensureIndexExists(ACTIVE_HEAD_INDEX, `CREATE INDEX IF NOT EXISTS ${ACTIVE_HEAD_INDEX}
|
|
114
|
-
ON ${TABLE} (app_id, trigger_id, sequence_id)
|
|
115
|
-
WHERE status IN ('pending', 'processing')`);
|
|
116
|
-
await ensureIndexExists(FAILED_INDEX, `CREATE INDEX IF NOT EXISTS ${FAILED_INDEX}
|
|
117
|
-
ON ${TABLE} (completed_at) WHERE status = 'failed'`);
|
|
118
|
-
await ensureIndexExists(STALE_EVENT_INDEX, `CREATE INDEX IF NOT EXISTS ${STALE_EVENT_INDEX}
|
|
119
|
-
ON ${TABLE} (app_id, event_name, emitted_at)
|
|
120
|
-
WHERE status = 'pending'`);
|
|
121
|
-
await ensureIndexExists(COMPLETED_INDEX, `CREATE INDEX IF NOT EXISTS ${COMPLETED_INDEX}
|
|
122
|
-
ON ${TABLE} (completed_at) WHERE status = 'completed'`);
|
|
123
|
-
})().catch((error) => {
|
|
124
|
-
_initPromise = undefined;
|
|
125
|
-
throw error;
|
|
126
|
-
});
|
|
127
|
-
_initPromise = retainRequestDbPoolScope(_initPromiseWithRequestDbPoolScope);
|
|
128
|
-
}
|
|
129
|
-
return _initPromise;
|
|
128
|
+
export function ensureAutomationTriggerEventQueue() {
|
|
129
|
+
return automationTriggerEventsStore.ready();
|
|
130
130
|
}
|
|
131
131
|
function rowToEvent(row) {
|
|
132
132
|
if (row.claimed_at == null || !Number.isFinite(Number(row.claimed_at))) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { getDbExec } from "../db/client.js";
|
|
2
2
|
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
3
3
|
import { defineStore } from "../db/store-registry.js";
|
|
4
|
+
import { fromMigrationEntries } from "../db/versioned-store-migrations.js";
|
|
4
5
|
import { deleteNotification, notifyWithDelivery, } from "../notifications/index.js";
|
|
5
6
|
import { ForbiddenError } from "../sharing/access.js";
|
|
7
|
+
import { USAGE_ALERT_MIGRATIONS, USAGE_ALERT_MIGRATIONS_TABLE, } from "./migrations.js";
|
|
6
8
|
import { builderCreditsFromCostCents } from "./store.js";
|
|
7
9
|
const DAY_MS = 86_400_000;
|
|
8
10
|
const DEFAULT_DAILY_USD = 100;
|
|
@@ -128,6 +130,7 @@ export const usageAlertsStore = defineStore({
|
|
|
128
130
|
}
|
|
129
131
|
},
|
|
130
132
|
},
|
|
133
|
+
...fromMigrationEntries(USAGE_ALERT_MIGRATIONS_TABLE, USAGE_ALERT_MIGRATIONS),
|
|
131
134
|
],
|
|
132
135
|
});
|
|
133
136
|
export function ensureTables() {
|
|
@@ -2,8 +2,10 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { getDbExec, isUniqueViolation, retryOnDdlRace, safeJsonParse, } from "../db/client.js";
|
|
3
3
|
import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
|
|
4
4
|
import { defineStore } from "../db/store-registry.js";
|
|
5
|
+
import { fromMigrationEntries } from "../db/versioned-store-migrations.js";
|
|
5
6
|
import { isOrgMember } from "../org/membership.js";
|
|
6
7
|
import { getRequestOrgId, getRequestUserEmail, } from "../server/request-context.js";
|
|
8
|
+
import { WORKSPACE_CONNECTIONS_MIGRATIONS, WORKSPACE_CONNECTIONS_MIGRATIONS_TABLE, } from "./migrations.js";
|
|
7
9
|
export function workspaceUserGroupsTable() {
|
|
8
10
|
return "public.workspace_user_groups";
|
|
9
11
|
}
|
|
@@ -124,6 +126,7 @@ async function ensureWorkspaceUserGroupNameTrigger(client) {
|
|
|
124
126
|
}
|
|
125
127
|
export const workspaceUserGroupsStore = defineStore({
|
|
126
128
|
id: "workspace_user_groups",
|
|
129
|
+
after: ["workspace_connections"],
|
|
127
130
|
// Hosted requests never created these tables on main, release-owned or not.
|
|
128
131
|
releaseOnly: true,
|
|
129
132
|
migrations: [
|
|
@@ -153,6 +156,7 @@ export const workspaceUserGroupsStore = defineStore({
|
|
|
153
156
|
WHERE normalized_name IS NOT NULL`);
|
|
154
157
|
},
|
|
155
158
|
},
|
|
159
|
+
...fromMigrationEntries(WORKSPACE_CONNECTIONS_MIGRATIONS_TABLE, WORKSPACE_CONNECTIONS_MIGRATIONS.filter((entry) => entry.version >= 8)),
|
|
156
160
|
],
|
|
157
161
|
});
|
|
158
162
|
export function ensureWorkspaceUserGroupsTable() {
|