@opengeni/db 0.31.1 → 0.36.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.
- package/dist/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/chunk-FPVAD4CO.js +117 -0
- package/dist/chunk-FPVAD4CO.js.map +1 -0
- package/dist/chunk-GYO7ED2Q.js +259 -0
- package/dist/chunk-GYO7ED2Q.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-HSOWSYOX.js} +2 -2
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-VTPRIXKG.js} +49 -9
- package/dist/chunk-VTPRIXKG.js.map +1 -0
- package/dist/{chunk-ISI2TIUG.js → chunk-Z7VYMNPZ.js} +76 -4
- package/dist/chunk-Z7VYMNPZ.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +467 -29
- package/dist/index.js +23247 -16232
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/persistence-errors.d.ts +8 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_recover_unclaimed_session_turns.sql +307 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4625 -411
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/persistence-errors.ts +60 -1
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-HSOWSYOX.js.map} +0 -0
package/src/pack-components.ts
CHANGED
|
@@ -17,9 +17,9 @@ import {
|
|
|
17
17
|
} from "./capability-integrations";
|
|
18
18
|
import { withRlsContext, withWorkspaceRls, type Database } from "./database";
|
|
19
19
|
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
addIntegrationFacetBindingOwner,
|
|
21
|
+
removeIntegrationFacetBindingOwner,
|
|
22
|
+
removeIntegrationFacetBindingOwnersForOwner,
|
|
23
23
|
} from "./integration-bindings";
|
|
24
24
|
import * as schema from "./schema";
|
|
25
25
|
|
|
@@ -224,7 +224,7 @@ export async function adoptPackComponentReferences(
|
|
|
224
224
|
retainedFacetInstallationIds.push(facetInstallationId);
|
|
225
225
|
}
|
|
226
226
|
for (const bindingId of target.bindingIds) {
|
|
227
|
-
await
|
|
227
|
+
await addIntegrationFacetBindingOwner(tx, bindingId, {
|
|
228
228
|
accountId: input.accountId,
|
|
229
229
|
workspaceId: input.workspaceId,
|
|
230
230
|
owner: { kind: "pack", id: input.packInstallationId, removable: true },
|
|
@@ -402,13 +402,13 @@ export async function finalizePackComponentOwnership(
|
|
|
402
402
|
}
|
|
403
403
|
const retainedBindings = new Set(input.retainedBindingIds);
|
|
404
404
|
const ownedBindings = await tx
|
|
405
|
-
.select({ bindingId: schema.
|
|
406
|
-
.from(schema.
|
|
405
|
+
.select({ bindingId: schema.integrationFacetBindingOwners.bindingId })
|
|
406
|
+
.from(schema.integrationFacetBindingOwners)
|
|
407
407
|
.where(
|
|
408
408
|
and(
|
|
409
|
-
eq(schema.
|
|
410
|
-
eq(schema.
|
|
411
|
-
eq(schema.
|
|
409
|
+
eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
|
|
410
|
+
eq(schema.integrationFacetBindingOwners.ownerKind, "pack"),
|
|
411
|
+
eq(schema.integrationFacetBindingOwners.ownerId, input.packInstallationId),
|
|
412
412
|
),
|
|
413
413
|
);
|
|
414
414
|
for (const bindingId of [
|
|
@@ -418,7 +418,7 @@ export async function finalizePackComponentOwnership(
|
|
|
418
418
|
.filter((ownedBindingId) => !retainedBindings.has(ownedBindingId)),
|
|
419
419
|
),
|
|
420
420
|
]) {
|
|
421
|
-
await
|
|
421
|
+
await removeIntegrationFacetBindingOwner(tx, {
|
|
422
422
|
workspaceId: input.workspaceId,
|
|
423
423
|
bindingId,
|
|
424
424
|
owner: { kind: "pack", id: input.packInstallationId },
|
|
@@ -505,18 +505,18 @@ async function previewPackComponentReleaseInRlsContext(
|
|
|
505
505
|
bindingIds.length === 0
|
|
506
506
|
? []
|
|
507
507
|
: await scopedDb
|
|
508
|
-
.select({ id: schema.
|
|
509
|
-
.from(schema.
|
|
508
|
+
.select({ id: schema.integrationFacetBindingOwners.id })
|
|
509
|
+
.from(schema.integrationFacetBindingOwners)
|
|
510
510
|
.where(
|
|
511
511
|
and(
|
|
512
|
-
inArray(schema.
|
|
512
|
+
inArray(schema.integrationFacetBindingOwners.bindingId, bindingIds),
|
|
513
513
|
effectiveCapabilityOwnerSql(
|
|
514
|
-
schema.
|
|
515
|
-
schema.
|
|
514
|
+
schema.integrationFacetBindingOwners.ownerKind,
|
|
515
|
+
schema.integrationFacetBindingOwners.ownerId,
|
|
516
516
|
),
|
|
517
517
|
or(
|
|
518
|
-
ne(schema.
|
|
519
|
-
ne(schema.
|
|
518
|
+
ne(schema.integrationFacetBindingOwners.ownerKind, "pack"),
|
|
519
|
+
ne(schema.integrationFacetBindingOwners.ownerId, packInstallationId),
|
|
520
520
|
),
|
|
521
521
|
),
|
|
522
522
|
)
|
|
@@ -546,7 +546,7 @@ export async function releasePackComponents(
|
|
|
546
546
|
input.workspaceId,
|
|
547
547
|
input.packInstallationId,
|
|
548
548
|
);
|
|
549
|
-
await
|
|
549
|
+
await removeIntegrationFacetBindingOwnersForOwner(tx, {
|
|
550
550
|
workspaceId: input.workspaceId,
|
|
551
551
|
owner: { kind: "pack", id: input.packInstallationId },
|
|
552
552
|
});
|
|
@@ -597,7 +597,7 @@ async function resolvePackComponentTargets(
|
|
|
597
597
|
} else if (reference.kind === "integration") {
|
|
598
598
|
targets.push(await resolveIntegrationReference(db, workspaceId, reference, integrations));
|
|
599
599
|
} else {
|
|
600
|
-
targets.push(await
|
|
600
|
+
targets.push(await resolveFacetReference(db, workspaceId, reference, integrations));
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
return targets;
|
|
@@ -655,13 +655,13 @@ async function resolvePluginReference(
|
|
|
655
655
|
? []
|
|
656
656
|
: (
|
|
657
657
|
await db
|
|
658
|
-
.select({ id: schema.
|
|
659
|
-
.from(schema.
|
|
658
|
+
.select({ id: schema.integrationFacetBindingOwners.bindingId })
|
|
659
|
+
.from(schema.integrationFacetBindingOwners)
|
|
660
660
|
.where(
|
|
661
661
|
and(
|
|
662
|
-
eq(schema.
|
|
663
|
-
eq(schema.
|
|
664
|
-
eq(schema.
|
|
662
|
+
eq(schema.integrationFacetBindingOwners.workspaceId, workspaceId),
|
|
663
|
+
eq(schema.integrationFacetBindingOwners.ownerKind, "plugin"),
|
|
664
|
+
eq(schema.integrationFacetBindingOwners.ownerId, row.pluginInstallationId),
|
|
665
665
|
),
|
|
666
666
|
)
|
|
667
667
|
).map((entry) => entry.id);
|
|
@@ -781,10 +781,10 @@ async function resolveIntegrationReference(
|
|
|
781
781
|
};
|
|
782
782
|
}
|
|
783
783
|
|
|
784
|
-
async function
|
|
784
|
+
async function resolveFacetReference(
|
|
785
785
|
db: Database,
|
|
786
786
|
workspaceId: string,
|
|
787
|
-
reference: Extract<CapabilityPackComponentReference, { kind: "
|
|
787
|
+
reference: Extract<CapabilityPackComponentReference, { kind: "facet" }>,
|
|
788
788
|
integrations: readonly ApiIntegrationRuntime[],
|
|
789
789
|
): Promise<ResolvedPackComponentTarget> {
|
|
790
790
|
const integration = integrations.find(
|
|
@@ -793,7 +793,7 @@ async function resolveFeatureReference(
|
|
|
793
793
|
candidate.instanceKey === reference.instanceKey,
|
|
794
794
|
);
|
|
795
795
|
if (!integration) {
|
|
796
|
-
return missingTarget(reference, "
|
|
796
|
+
return missingTarget(reference, "facet", reference.capabilityId, reference.configDigest);
|
|
797
797
|
}
|
|
798
798
|
const [integrationFacetInstallationId] = await integrationFacetInstallationIds(
|
|
799
799
|
db,
|
|
@@ -801,29 +801,29 @@ async function resolveFeatureReference(
|
|
|
801
801
|
"integration",
|
|
802
802
|
);
|
|
803
803
|
if (!integrationFacetInstallationId) {
|
|
804
|
-
return missingTarget(reference, "
|
|
804
|
+
return missingTarget(reference, "facet", reference.capabilityId, reference.configDigest);
|
|
805
805
|
}
|
|
806
806
|
const [binding] = await db
|
|
807
807
|
.select({
|
|
808
|
-
id: schema.
|
|
809
|
-
config: schema.
|
|
810
|
-
status: schema.
|
|
811
|
-
displayName: schema.
|
|
808
|
+
id: schema.integrationFacetBindings.id,
|
|
809
|
+
config: schema.integrationFacetBindings.config,
|
|
810
|
+
status: schema.integrationFacetBindings.status,
|
|
811
|
+
displayName: schema.integrationFacetBindings.displayName,
|
|
812
812
|
})
|
|
813
|
-
.from(schema.
|
|
813
|
+
.from(schema.integrationFacetBindings)
|
|
814
814
|
.innerJoin(
|
|
815
|
-
schema.
|
|
816
|
-
eq(schema.
|
|
815
|
+
schema.integrationFacetDefinitions,
|
|
816
|
+
eq(schema.integrationFacetDefinitions.id, schema.integrationFacetBindings.facetDefinitionId),
|
|
817
817
|
)
|
|
818
818
|
.where(
|
|
819
819
|
and(
|
|
820
|
-
eq(schema.
|
|
820
|
+
eq(schema.integrationFacetBindings.workspaceId, workspaceId),
|
|
821
821
|
eq(
|
|
822
|
-
schema.
|
|
822
|
+
schema.integrationFacetBindings.integrationFacetInstallationId,
|
|
823
823
|
integrationFacetInstallationId,
|
|
824
824
|
),
|
|
825
|
-
eq(schema.
|
|
826
|
-
eq(schema.
|
|
825
|
+
eq(schema.integrationFacetDefinitions.facetKey, reference.facetKey),
|
|
826
|
+
eq(schema.integrationFacetBindings.bindingKey, reference.bindingKey),
|
|
827
827
|
),
|
|
828
828
|
)
|
|
829
829
|
.limit(1);
|
|
@@ -835,20 +835,20 @@ async function resolveFeatureReference(
|
|
|
835
835
|
return {
|
|
836
836
|
resolution: {
|
|
837
837
|
key: reference.key,
|
|
838
|
-
kind: "
|
|
838
|
+
kind: "facet",
|
|
839
839
|
capabilityId: reference.capabilityId,
|
|
840
840
|
required: reference.required,
|
|
841
841
|
status: !binding ? "missing" : exact ? "ready" : "mismatch",
|
|
842
842
|
expectedDigest: reference.configDigest,
|
|
843
843
|
actualDigest,
|
|
844
844
|
resolvedId: exact ? binding.id : null,
|
|
845
|
-
label: binding?.displayName ?? reference.
|
|
845
|
+
label: binding?.displayName ?? reference.facetKey,
|
|
846
846
|
},
|
|
847
847
|
facetInstallationIds: exact ? [integrationFacetInstallationId] : [],
|
|
848
848
|
bindingIds: exact ? [binding.id] : [],
|
|
849
849
|
metadata: {
|
|
850
850
|
instanceKey: reference.instanceKey,
|
|
851
|
-
|
|
851
|
+
facetKey: reference.facetKey,
|
|
852
852
|
bindingKey: reference.bindingKey,
|
|
853
853
|
},
|
|
854
854
|
};
|
|
@@ -926,7 +926,7 @@ function mapStoredPackComponent(
|
|
|
926
926
|
row.kind !== "plugin" &&
|
|
927
927
|
row.kind !== "skill" &&
|
|
928
928
|
row.kind !== "integration" &&
|
|
929
|
-
row.kind !== "
|
|
929
|
+
row.kind !== "facet" &&
|
|
930
930
|
row.kind !== "inline_skill"
|
|
931
931
|
) {
|
|
932
932
|
throw new Error(`Unknown Pack component kind: ${row.kind}`);
|
|
@@ -272,40 +272,6 @@ export async function finalizePackInstallationOperation(
|
|
|
272
272
|
)
|
|
273
273
|
.returning();
|
|
274
274
|
if (!installation) throw new Error("Pack installation was not found during finalize");
|
|
275
|
-
await tx
|
|
276
|
-
.insert(schema.capabilityInstallations)
|
|
277
|
-
.values({
|
|
278
|
-
accountId: input.accountId,
|
|
279
|
-
workspaceId: input.workspaceId,
|
|
280
|
-
capabilityId: `pack:${input.packId}`,
|
|
281
|
-
kind: "pack",
|
|
282
|
-
status: "active",
|
|
283
|
-
config: {},
|
|
284
|
-
metadata: {
|
|
285
|
-
platformVersion: 2,
|
|
286
|
-
packInstallationId: input.packInstallationId,
|
|
287
|
-
manifestDigest: installation.manifestDigest,
|
|
288
|
-
},
|
|
289
|
-
enabledAt: now,
|
|
290
|
-
updatedAt: now,
|
|
291
|
-
})
|
|
292
|
-
.onConflictDoUpdate({
|
|
293
|
-
target: [
|
|
294
|
-
schema.capabilityInstallations.workspaceId,
|
|
295
|
-
schema.capabilityInstallations.capabilityId,
|
|
296
|
-
],
|
|
297
|
-
set: {
|
|
298
|
-
status: "active",
|
|
299
|
-
config: {},
|
|
300
|
-
metadata: {
|
|
301
|
-
platformVersion: 2,
|
|
302
|
-
packInstallationId: input.packInstallationId,
|
|
303
|
-
manifestDigest: installation.manifestDigest,
|
|
304
|
-
},
|
|
305
|
-
enabledAt: now,
|
|
306
|
-
updatedAt: now,
|
|
307
|
-
},
|
|
308
|
-
});
|
|
309
275
|
const [completed] = await tx
|
|
310
276
|
.update(schema.capabilityOperations)
|
|
311
277
|
.set({
|
|
@@ -617,15 +583,6 @@ export async function finalizePackUninstallOperation(
|
|
|
617
583
|
eq(schema.packInstallations.packId, input.packId),
|
|
618
584
|
),
|
|
619
585
|
);
|
|
620
|
-
await tx
|
|
621
|
-
.update(schema.capabilityInstallations)
|
|
622
|
-
.set({ status: "disabled", updatedAt: now })
|
|
623
|
-
.where(
|
|
624
|
-
and(
|
|
625
|
-
eq(schema.capabilityInstallations.workspaceId, input.workspaceId),
|
|
626
|
-
eq(schema.capabilityInstallations.capabilityId, `pack:${input.packId}`),
|
|
627
|
-
),
|
|
628
|
-
);
|
|
629
586
|
const [completed] = await tx
|
|
630
587
|
.update(schema.capabilityOperations)
|
|
631
588
|
.set({
|
|
@@ -25,6 +25,26 @@ export type PersistenceFailureDetails = {
|
|
|
25
25
|
|
|
26
26
|
const SQLSTATE_KEYS = ["sqlState", "sqlstate", "code"] as const;
|
|
27
27
|
const NESTED_ERROR_KEYS = ["cause", "original", "driverError", "error", "errors"] as const;
|
|
28
|
+
const RETRYABLE_DATABASE_TRANSPORT_CODES = new Set([
|
|
29
|
+
// postgres.js connection lifecycle failures.
|
|
30
|
+
"CONNECTION_CLOSED",
|
|
31
|
+
"CONNECTION_DESTROYED",
|
|
32
|
+
"CONNECTION_ENDED",
|
|
33
|
+
"CONNECT_TIMEOUT",
|
|
34
|
+
// Node socket/DNS failures surfaced unchanged by postgres.js.
|
|
35
|
+
"EAI_AGAIN",
|
|
36
|
+
"ECONNABORTED",
|
|
37
|
+
"ECONNREFUSED",
|
|
38
|
+
"ECONNRESET",
|
|
39
|
+
"EHOSTDOWN",
|
|
40
|
+
"EHOSTUNREACH",
|
|
41
|
+
"ENETDOWN",
|
|
42
|
+
"ENETRESET",
|
|
43
|
+
"ENETUNREACH",
|
|
44
|
+
"ENOTFOUND",
|
|
45
|
+
"EPIPE",
|
|
46
|
+
"ETIMEDOUT",
|
|
47
|
+
]);
|
|
28
48
|
const DATABASE_ERROR_NAMES = new Set(["DatabaseError", "DrizzleQueryError", "PostgresError"]);
|
|
29
49
|
const DATABASE_DIAGNOSTIC_KEYS = [
|
|
30
50
|
"severity",
|
|
@@ -72,6 +92,9 @@ export function nestedPostgresSqlState(error: unknown): string | null {
|
|
|
72
92
|
const value = current[key];
|
|
73
93
|
if (typeof value !== "string" || !/^[0-9A-Z]{5}$/i.test(value)) continue;
|
|
74
94
|
const normalized = value.toUpperCase();
|
|
95
|
+
// Node transport codes such as EPIPE happen to be five characters but
|
|
96
|
+
// are not PostgreSQL SQLSTATEs.
|
|
97
|
+
if (RETRYABLE_DATABASE_TRANSPORT_CODES.has(normalized)) continue;
|
|
75
98
|
if (normalized === "40P01" || normalized === "40001") return normalized;
|
|
76
99
|
fallback ??= normalized;
|
|
77
100
|
}
|
|
@@ -94,13 +117,49 @@ export function isRetryablePersistenceSqlState(sqlState: string | null): boolean
|
|
|
94
117
|
return sqlState === "40P01" || sqlState === "40001";
|
|
95
118
|
}
|
|
96
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Recognize only explicit postgres.js/Node transport codes, including nested
|
|
122
|
+
* driver causes. These failures can arrive as plain Errors with no SQLSTATE or
|
|
123
|
+
* database diagnostic fields when the connection dies before PostgreSQL can
|
|
124
|
+
* answer. Messages are intentionally ignored: they are unstable and may
|
|
125
|
+
* contain connection detail.
|
|
126
|
+
*/
|
|
127
|
+
export function isRetryableDatabaseTransportFailure(error: unknown): boolean {
|
|
128
|
+
const queue: unknown[] = [error];
|
|
129
|
+
const seen = new Set<unknown>();
|
|
130
|
+
while (queue.length > 0 && seen.size < 64) {
|
|
131
|
+
const current = queue.shift();
|
|
132
|
+
if (!isRecord(current) || seen.has(current)) continue;
|
|
133
|
+
seen.add(current);
|
|
134
|
+
|
|
135
|
+
for (const key of ["code", "errno"] as const) {
|
|
136
|
+
const value = current[key];
|
|
137
|
+
if (
|
|
138
|
+
typeof value === "string" &&
|
|
139
|
+
RETRYABLE_DATABASE_TRANSPORT_CODES.has(value.toUpperCase())
|
|
140
|
+
) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for (const key of NESTED_ERROR_KEYS) {
|
|
146
|
+
const nested = current[key];
|
|
147
|
+
if (Array.isArray(nested)) queue.push(...nested);
|
|
148
|
+
else if (nested !== undefined) queue.push(nested);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
97
154
|
/**
|
|
98
155
|
* Distinguish database/ORM failures from expected domain exceptions when a
|
|
99
156
|
* driver omitted SQLSTATE. This checks shape only; callers retain the original
|
|
100
157
|
* failure independently as canonical error evidence.
|
|
101
158
|
*/
|
|
102
159
|
export function isDatabasePersistenceFailure(error: unknown): boolean {
|
|
103
|
-
if (nestedPostgresSqlState(error) !== null)
|
|
160
|
+
if (isRetryableDatabaseTransportFailure(error) || nestedPostgresSqlState(error) !== null) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
104
163
|
|
|
105
164
|
const queue: unknown[] = [error];
|
|
106
165
|
const seen = new Set<unknown>();
|
package/src/plugin-packages.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
} from "./capability-components";
|
|
11
11
|
import { setSubjectRlsContext, withRlsContext, withWorkspaceRls, type Database } from "./database";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
removeIntegrationFacetBindingOwner,
|
|
14
|
+
removeIntegrationFacetBindingOwnersForOwner,
|
|
15
15
|
} from "./integration-bindings";
|
|
16
16
|
import * as schema from "./schema";
|
|
17
17
|
|
|
@@ -489,13 +489,13 @@ export async function finalizePluginPackageInstall(
|
|
|
489
489
|
);
|
|
490
490
|
}
|
|
491
491
|
const ownedBindings = await tx
|
|
492
|
-
.select({ bindingId: schema.
|
|
493
|
-
.from(schema.
|
|
492
|
+
.select({ bindingId: schema.integrationFacetBindingOwners.bindingId })
|
|
493
|
+
.from(schema.integrationFacetBindingOwners)
|
|
494
494
|
.where(
|
|
495
495
|
and(
|
|
496
|
-
eq(schema.
|
|
497
|
-
eq(schema.
|
|
498
|
-
eq(schema.
|
|
496
|
+
eq(schema.integrationFacetBindingOwners.workspaceId, input.workspaceId),
|
|
497
|
+
eq(schema.integrationFacetBindingOwners.ownerKind, "plugin"),
|
|
498
|
+
eq(schema.integrationFacetBindingOwners.ownerId, input.pluginInstallationId),
|
|
499
499
|
),
|
|
500
500
|
);
|
|
501
501
|
const retainedBindings = new Set(input.retainedBindingIds);
|
|
@@ -506,7 +506,7 @@ export async function finalizePluginPackageInstall(
|
|
|
506
506
|
.filter((candidateId) => !retainedBindings.has(candidateId)),
|
|
507
507
|
),
|
|
508
508
|
]) {
|
|
509
|
-
await
|
|
509
|
+
await removeIntegrationFacetBindingOwner(tx, {
|
|
510
510
|
workspaceId: input.workspaceId,
|
|
511
511
|
bindingId,
|
|
512
512
|
owner: { kind: "plugin", id: input.pluginInstallationId },
|
|
@@ -923,7 +923,7 @@ export async function uninstallPluginPackage(
|
|
|
923
923
|
input.workspaceId,
|
|
924
924
|
plugin.pluginInstallationId,
|
|
925
925
|
);
|
|
926
|
-
await
|
|
926
|
+
await removeIntegrationFacetBindingOwnersForOwner(tx, {
|
|
927
927
|
workspaceId: input.workspaceId,
|
|
928
928
|
owner: { kind: "plugin", id: plugin.pluginInstallationId },
|
|
929
929
|
});
|
package/src/provision-roles.ts
CHANGED
|
@@ -613,6 +613,28 @@ BEGIN
|
|
|
613
613
|
${literal(role)}
|
|
614
614
|
);
|
|
615
615
|
END IF;
|
|
616
|
+
IF to_regprocedure(
|
|
617
|
+
format(
|
|
618
|
+
'%I.create_task_note_for_attempt(uuid,uuid,uuid,uuid,uuid,integer,uuid,text,text,integer)',
|
|
619
|
+
${literal(schema)}
|
|
620
|
+
)
|
|
621
|
+
) IS NOT NULL THEN
|
|
622
|
+
EXECUTE format(
|
|
623
|
+
'GRANT EXECUTE ON FUNCTION %I.create_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, text, text, integer) TO %I',
|
|
624
|
+
${literal(schema)},
|
|
625
|
+
${literal(role)}
|
|
626
|
+
);
|
|
627
|
+
EXECUTE format(
|
|
628
|
+
'GRANT EXECUTE ON FUNCTION %I.archive_task_note_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, uuid, uuid, integer, text) TO %I',
|
|
629
|
+
${literal(schema)},
|
|
630
|
+
${literal(role)}
|
|
631
|
+
);
|
|
632
|
+
EXECUTE format(
|
|
633
|
+
'GRANT EXECUTE ON FUNCTION %I.list_task_notes_for_attempt(uuid, uuid, uuid, uuid, uuid, integer, boolean, integer) TO %I',
|
|
634
|
+
${literal(schema)},
|
|
635
|
+
${literal(role)}
|
|
636
|
+
);
|
|
637
|
+
END IF;
|
|
616
638
|
IF to_regprocedure(
|
|
617
639
|
format(
|
|
618
640
|
'%I.workspace_instruction_policy_get_or_create_snapshot(uuid,uuid,uuid,uuid,uuid,integer)',
|
|
@@ -691,6 +713,18 @@ BEGIN
|
|
|
691
713
|
${literal(role)}
|
|
692
714
|
);
|
|
693
715
|
END IF;
|
|
716
|
+
IF to_regprocedure(
|
|
717
|
+
format(
|
|
718
|
+
'%I.slack_task_policy_update(uuid,text,uuid,uuid,jsonb,uuid,bigint,text,text)',
|
|
719
|
+
${literal(schema)}
|
|
720
|
+
)
|
|
721
|
+
) IS NOT NULL THEN
|
|
722
|
+
EXECUTE format(
|
|
723
|
+
'GRANT EXECUTE ON FUNCTION %I.slack_task_policy_update(uuid, text, uuid, uuid, jsonb, uuid, bigint, text, text) TO %I',
|
|
724
|
+
${literal(schema)},
|
|
725
|
+
${literal(role)}
|
|
726
|
+
);
|
|
727
|
+
END IF;
|
|
694
728
|
IF to_regprocedure(
|
|
695
729
|
format(
|
|
696
730
|
'%I.scoped_knowledge_apply_lifecycle(uuid,text,uuid,text,bigint,text,text,text,text,text,text)',
|
|
@@ -723,6 +757,204 @@ BEGIN
|
|
|
723
757
|
${literal(role)}
|
|
724
758
|
);
|
|
725
759
|
END IF;
|
|
760
|
+
IF to_regprocedure(
|
|
761
|
+
format(
|
|
762
|
+
'%I.ensure_managed_human_personal_workspace(uuid,text,uuid)',
|
|
763
|
+
${literal(schema)}
|
|
764
|
+
)
|
|
765
|
+
) IS NOT NULL THEN
|
|
766
|
+
EXECUTE format(
|
|
767
|
+
'REVOKE ALL ON FUNCTION %I.ensure_managed_human_personal_workspace(uuid, text, uuid) FROM PUBLIC',
|
|
768
|
+
${literal(schema)}
|
|
769
|
+
);
|
|
770
|
+
EXECUTE format(
|
|
771
|
+
'GRANT EXECUTE ON FUNCTION %I.ensure_managed_human_personal_workspace(uuid, text, uuid) TO %I',
|
|
772
|
+
${literal(schema)},
|
|
773
|
+
${literal(role)}
|
|
774
|
+
);
|
|
775
|
+
END IF;
|
|
776
|
+
IF to_regprocedure(format('%I.ensure_canonical_human_identity(text,text)', ${literal(schema)})) IS NOT NULL THEN
|
|
777
|
+
EXECUTE format(
|
|
778
|
+
'REVOKE ALL ON FUNCTION %I.ensure_canonical_human_identity(text, text) FROM PUBLIC',
|
|
779
|
+
${literal(schema)}
|
|
780
|
+
);
|
|
781
|
+
EXECUTE format(
|
|
782
|
+
'GRANT EXECUTE ON FUNCTION %I.ensure_canonical_human_identity(text, text) TO %I',
|
|
783
|
+
${literal(schema)},
|
|
784
|
+
${literal(role)}
|
|
785
|
+
);
|
|
786
|
+
END IF;
|
|
787
|
+
IF to_regprocedure(format('%I.validate_canonical_human_session(text,text,boolean)', ${literal(schema)})) IS NOT NULL THEN
|
|
788
|
+
EXECUTE format(
|
|
789
|
+
'REVOKE ALL ON FUNCTION %I.validate_canonical_human_session(text, text, boolean) FROM PUBLIC',
|
|
790
|
+
${literal(schema)}
|
|
791
|
+
);
|
|
792
|
+
EXECUTE format(
|
|
793
|
+
'GRANT EXECUTE ON FUNCTION %I.validate_canonical_human_session(text, text, boolean) TO %I',
|
|
794
|
+
${literal(schema)},
|
|
795
|
+
${literal(role)}
|
|
796
|
+
);
|
|
797
|
+
END IF;
|
|
798
|
+
IF to_regprocedure(format('%I.get_canonical_human_identity_projection(text)', ${literal(schema)})) IS NOT NULL THEN
|
|
799
|
+
EXECUTE format(
|
|
800
|
+
'REVOKE ALL ON FUNCTION %I.get_canonical_human_identity_projection(text) FROM PUBLIC',
|
|
801
|
+
${literal(schema)}
|
|
802
|
+
);
|
|
803
|
+
EXECUTE format(
|
|
804
|
+
'GRANT EXECUTE ON FUNCTION %I.get_canonical_human_identity_projection(text) TO %I',
|
|
805
|
+
${literal(schema)},
|
|
806
|
+
${literal(role)}
|
|
807
|
+
);
|
|
808
|
+
END IF;
|
|
809
|
+
IF to_regprocedure(format('%I.apply_canonical_human_identity_operation(uuid,text,bigint,text,uuid,text,text,text)', ${literal(schema)})) IS NOT NULL THEN
|
|
810
|
+
EXECUTE format(
|
|
811
|
+
'REVOKE ALL ON FUNCTION %I.apply_canonical_human_identity_operation(uuid, text, bigint, text, uuid, text, text, text) FROM PUBLIC',
|
|
812
|
+
${literal(schema)}
|
|
813
|
+
);
|
|
814
|
+
EXECUTE format(
|
|
815
|
+
'GRANT EXECUTE ON FUNCTION %I.apply_canonical_human_identity_operation(uuid, text, bigint, text, uuid, text, text, text) TO %I',
|
|
816
|
+
${literal(schema)},
|
|
817
|
+
${literal(role)}
|
|
818
|
+
);
|
|
819
|
+
END IF;
|
|
820
|
+
-- Migration 0225 creates these target-schema-local session visibility
|
|
821
|
+
-- capabilities before opengeni_app may exist. Re-converge their exact
|
|
822
|
+
-- EXECUTE grants for migrate-then-provision installs without granting
|
|
823
|
+
-- blanket execution on target-schema routines.
|
|
824
|
+
IF to_regprocedure(
|
|
825
|
+
format(
|
|
826
|
+
'%I.session_private_actor_visible(uuid,uuid,uuid,text)',
|
|
827
|
+
${literal(schema)}
|
|
828
|
+
)
|
|
829
|
+
) IS NOT NULL THEN
|
|
830
|
+
EXECUTE format(
|
|
831
|
+
'REVOKE ALL ON FUNCTION %I.session_private_actor_visible(uuid, uuid, uuid, text) FROM PUBLIC',
|
|
832
|
+
${literal(schema)}
|
|
833
|
+
);
|
|
834
|
+
EXECUTE format(
|
|
835
|
+
'GRANT EXECUTE ON FUNCTION %I.session_private_actor_visible(uuid, uuid, uuid, text) TO %I',
|
|
836
|
+
${literal(schema)},
|
|
837
|
+
${literal(role)}
|
|
838
|
+
);
|
|
839
|
+
END IF;
|
|
840
|
+
IF to_regprocedure(
|
|
841
|
+
format(
|
|
842
|
+
'%I.session_reference_visible(uuid,uuid,uuid)',
|
|
843
|
+
${literal(schema)}
|
|
844
|
+
)
|
|
845
|
+
) IS NOT NULL THEN
|
|
846
|
+
EXECUTE format(
|
|
847
|
+
'REVOKE ALL ON FUNCTION %I.session_reference_visible(uuid, uuid, uuid) FROM PUBLIC',
|
|
848
|
+
${literal(schema)}
|
|
849
|
+
);
|
|
850
|
+
EXECUTE format(
|
|
851
|
+
'GRANT EXECUTE ON FUNCTION %I.session_reference_visible(uuid, uuid, uuid) TO %I',
|
|
852
|
+
${literal(schema)},
|
|
853
|
+
${literal(role)}
|
|
854
|
+
);
|
|
855
|
+
END IF;
|
|
856
|
+
IF to_regprocedure(
|
|
857
|
+
format(
|
|
858
|
+
'%I.transition_session_visibility(uuid,uuid,uuid,text,text,integer,text,text)',
|
|
859
|
+
${literal(schema)}
|
|
860
|
+
)
|
|
861
|
+
) IS NOT NULL THEN
|
|
862
|
+
EXECUTE format(
|
|
863
|
+
'REVOKE ALL ON FUNCTION %I.transition_session_visibility(uuid, uuid, uuid, text, text, integer, text, text) FROM PUBLIC',
|
|
864
|
+
${literal(schema)}
|
|
865
|
+
);
|
|
866
|
+
EXECUTE format(
|
|
867
|
+
'GRANT EXECUTE ON FUNCTION %I.transition_session_visibility(uuid, uuid, uuid, text, text, integer, text, text) TO %I',
|
|
868
|
+
${literal(schema)},
|
|
869
|
+
${literal(role)}
|
|
870
|
+
);
|
|
871
|
+
END IF;
|
|
872
|
+
IF to_regprocedure(
|
|
873
|
+
format(
|
|
874
|
+
'%I.fork_session_content(uuid,uuid,uuid,text,uuid,text,text,text)',
|
|
875
|
+
${literal(schema)}
|
|
876
|
+
)
|
|
877
|
+
) IS NOT NULL THEN
|
|
878
|
+
EXECUTE format(
|
|
879
|
+
'REVOKE ALL ON FUNCTION %I.fork_session_content(uuid, uuid, uuid, text, uuid, text, text, text) FROM PUBLIC',
|
|
880
|
+
${literal(schema)}
|
|
881
|
+
);
|
|
882
|
+
EXECUTE format(
|
|
883
|
+
'GRANT EXECUTE ON FUNCTION %I.fork_session_content(uuid, uuid, uuid, text, uuid, text, text, text) TO %I',
|
|
884
|
+
${literal(schema)},
|
|
885
|
+
${literal(role)}
|
|
886
|
+
);
|
|
887
|
+
END IF;
|
|
888
|
+
IF to_regprocedure(
|
|
889
|
+
format(
|
|
890
|
+
'%I.create_xai_subscription_credential(uuid,uuid,text,text,text,text,text,text,text,timestamptz)',
|
|
891
|
+
${literal(schema)}
|
|
892
|
+
)
|
|
893
|
+
) IS NOT NULL THEN
|
|
894
|
+
EXECUTE format(
|
|
895
|
+
'REVOKE ALL ON FUNCTION %I.create_xai_subscription_credential(uuid, uuid, text, text, text, text, text, text, text, timestamptz) FROM PUBLIC',
|
|
896
|
+
${literal(schema)}
|
|
897
|
+
);
|
|
898
|
+
EXECUTE format(
|
|
899
|
+
'GRANT EXECUTE ON FUNCTION %I.create_xai_subscription_credential(uuid, uuid, text, text, text, text, text, text, text, timestamptz) TO %I',
|
|
900
|
+
${literal(schema)},
|
|
901
|
+
${literal(role)}
|
|
902
|
+
);
|
|
903
|
+
EXECUTE format(
|
|
904
|
+
'REVOKE ALL ON FUNCTION %I.disconnect_xai_subscription_credential(uuid, uuid, text, uuid, jsonb) FROM PUBLIC',
|
|
905
|
+
${literal(schema)}
|
|
906
|
+
);
|
|
907
|
+
EXECUTE format(
|
|
908
|
+
'GRANT EXECUTE ON FUNCTION %I.disconnect_xai_subscription_credential(uuid, uuid, text, uuid, jsonb) TO %I',
|
|
909
|
+
${literal(schema)},
|
|
910
|
+
${literal(role)}
|
|
911
|
+
);
|
|
912
|
+
EXECUTE format(
|
|
913
|
+
'REVOKE ALL ON FUNCTION %I.resolve_xai_authority_pool(uuid, uuid, text, jsonb) FROM PUBLIC',
|
|
914
|
+
${literal(schema)}
|
|
915
|
+
);
|
|
916
|
+
EXECUTE format(
|
|
917
|
+
'GRANT EXECUTE ON FUNCTION %I.resolve_xai_authority_pool(uuid, uuid, text, jsonb) TO %I',
|
|
918
|
+
${literal(schema)},
|
|
919
|
+
${literal(role)}
|
|
920
|
+
);
|
|
921
|
+
EXECUTE format(
|
|
922
|
+
'REVOKE ALL ON FUNCTION %I.revalidate_xai_subscription_authority(uuid, text, uuid, jsonb) FROM PUBLIC',
|
|
923
|
+
${literal(schema)}
|
|
924
|
+
);
|
|
925
|
+
EXECUTE format(
|
|
926
|
+
'GRANT EXECUTE ON FUNCTION %I.revalidate_xai_subscription_authority(uuid, text, uuid, jsonb) TO %I',
|
|
927
|
+
${literal(schema)},
|
|
928
|
+
${literal(role)}
|
|
929
|
+
);
|
|
930
|
+
EXECUTE format(
|
|
931
|
+
'REVOKE ALL ON FUNCTION %I.xai_provider_account_authority_snapshot_v1_valid(jsonb) FROM PUBLIC',
|
|
932
|
+
${literal(schema)}
|
|
933
|
+
);
|
|
934
|
+
EXECUTE format(
|
|
935
|
+
'GRANT EXECUTE ON FUNCTION %I.xai_provider_account_authority_snapshot_v1_valid(jsonb) TO %I',
|
|
936
|
+
${literal(schema)},
|
|
937
|
+
${literal(role)}
|
|
938
|
+
);
|
|
939
|
+
EXECUTE format(
|
|
940
|
+
'REVOKE ALL ON FUNCTION %I.xai_subscription_authority_live(uuid, uuid, text, uuid, text, uuid, uuid, bigint) FROM PUBLIC',
|
|
941
|
+
${literal(schema)}
|
|
942
|
+
);
|
|
943
|
+
EXECUTE format(
|
|
944
|
+
'GRANT EXECUTE ON FUNCTION %I.xai_subscription_authority_live(uuid, uuid, text, uuid, text, uuid, uuid, bigint) TO %I',
|
|
945
|
+
${literal(schema)},
|
|
946
|
+
${literal(role)}
|
|
947
|
+
);
|
|
948
|
+
EXECUTE format(
|
|
949
|
+
'REVOKE ALL ON FUNCTION %I.xai_subscription_pool_visible(uuid, uuid, text, text, uuid) FROM PUBLIC',
|
|
950
|
+
${literal(schema)}
|
|
951
|
+
);
|
|
952
|
+
EXECUTE format(
|
|
953
|
+
'GRANT EXECUTE ON FUNCTION %I.xai_subscription_pool_visible(uuid, uuid, text, text, uuid) TO %I',
|
|
954
|
+
${literal(schema)},
|
|
955
|
+
${literal(role)}
|
|
956
|
+
);
|
|
957
|
+
END IF;
|
|
726
958
|
IF to_regprocedure(
|
|
727
959
|
format(
|
|
728
960
|
'%I.scoped_knowledge_advance_source_acl(uuid,uuid,bigint,bigint,uuid,text,text,text,text,text,text)',
|