@sentry/junior 0.75.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/junior.mjs +4 -66
- package/dist/agent-hooks-ZOE7RIED.js +37 -0
- package/dist/api-reference.d.ts +2 -0
- package/dist/app.js +317 -118
- package/dist/build/virtual-config.d.ts +2 -2
- package/dist/chat/agent-dispatch/runner.d.ts +2 -0
- package/dist/chat/config.d.ts +1 -0
- package/dist/chat/credentials/state-adapter-token-store.d.ts +2 -0
- package/dist/chat/credentials/user-token-store.d.ts +17 -12
- package/dist/chat/db.d.ts +8 -0
- package/dist/chat/mcp/auth-store.d.ts +2 -1
- package/dist/chat/mcp/oauth.d.ts +2 -1
- package/dist/chat/oauth-flow.d.ts +3 -1
- package/dist/chat/pi/client.d.ts +15 -7
- package/dist/chat/plugins/agent-hooks.d.ts +7 -0
- package/dist/chat/plugins/auth/oauth-request.d.ts +11 -7
- package/dist/chat/plugins/model.d.ts +9 -0
- package/dist/chat/plugins/prompt.d.ts +5 -0
- package/dist/chat/plugins/task-callback.d.ts +5 -0
- package/dist/chat/plugins/task-message.d.ts +23 -0
- package/dist/chat/plugins/task-queue.d.ts +5 -0
- package/dist/chat/plugins/task-runner.d.ts +12 -0
- package/dist/chat/plugins/task-signing.d.ts +31 -0
- package/dist/chat/prompt.d.ts +4 -0
- package/dist/chat/requester.d.ts +6 -5
- package/dist/chat/respond-helpers.d.ts +2 -0
- package/dist/chat/respond.d.ts +4 -2
- package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
- package/dist/chat/runtime/reply-executor.d.ts +5 -1
- package/dist/chat/runtime/slack-resume.d.ts +10 -2
- package/dist/chat/sentry.d.ts +1 -0
- package/dist/chat/services/mcp-auth-orchestration.d.ts +2 -1
- package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
- package/dist/chat/services/subscribed-decision.d.ts +2 -2
- package/dist/chat/services/turn-session-record.d.ts +11 -7
- package/dist/chat/state/turn-session.d.ts +8 -5
- package/dist/chat/tools/agent-tools.d.ts +8 -1
- package/dist/chat/tools/slack/context.d.ts +2 -2
- package/dist/chat/tools/types.d.ts +4 -4
- package/dist/chat/vercel-queue-client.d.ts +3 -0
- package/dist/{chunk-C3AM4Z4J.js → chunk-2ECJXSVQ.js} +5 -5
- package/dist/{chunk-OJODNL2P.js → chunk-4SCWV7TJ.js} +2 -2
- package/dist/chunk-4UO6FK4G.js +64 -0
- package/dist/{chunk-BNJIEFQC.js → chunk-56TBVRJG.js} +2 -2
- package/dist/{chunk-OK4KKR7B.js → chunk-EJN6G5A2.js} +28 -12
- package/dist/{chunk-TQ74BATR.js → chunk-HHDUKWVG.js} +428 -111
- package/dist/{chunk-XJHDZUGD.js → chunk-JBASI5VV.js} +4 -4
- package/dist/chunk-KNFROR7R.js +127 -0
- package/dist/{chunk-VNTLUFTY.js → chunk-KOIMO7S3.js} +126 -87
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/{chunk-NPVUAXUE.js → chunk-NFTMTIP3.js} +303 -33
- package/dist/chunk-NYKJ3KON.js +1082 -0
- package/dist/{chunk-SJHUF3DP.js → chunk-OJ53FYVG.js} +2 -10
- package/dist/{chunk-62FUNJYS.js → chunk-Q6XFTRV5.js} +54 -3
- package/dist/{chunk-UJ7OTHPO.js → chunk-R6Z5XWY3.js} +12 -670
- package/dist/chunk-RV5RYIJW.js +56 -0
- package/dist/{chunk-EE6PJWY4.js → chunk-SG5WAA7H.js} +7 -5
- package/dist/chunk-ST6YNAXG.js +54 -0
- package/dist/{chunk-FCZO7LAR.js → chunk-T77LUIX3.js} +139 -153
- package/dist/{chunk-EIYL7I4S.js → chunk-VALUBQ7R.js} +22 -30
- package/dist/{chunk-OZSPLAQ4.js → chunk-XBBC6W45.js} +1 -1
- package/dist/{chunk-ZNNTSPNF.js → chunk-Y5OFBCBZ.js} +1 -1
- package/dist/{chunk-74HO27II.js → chunk-Z4CIQ3EB.js} +5 -1
- package/dist/{chunk-2RWFUS5F.js → chunk-ZLMBNBUG.js} +101 -44
- package/dist/{chunk-JEELK46E.js → chunk-ZQB37HUX.js} +11 -11
- package/dist/cli/chat.js +52 -23
- package/dist/cli/check.js +7 -7
- package/dist/cli/env.js +4 -53
- package/dist/cli/init.js +6 -1
- package/dist/cli/main.js +84 -0
- package/dist/cli/plugins.js +244 -0
- package/dist/cli/run.js +5 -52
- package/dist/cli/snapshot-warmup.js +9 -9
- package/dist/cli/upgrade.js +167 -48
- package/dist/db-7A7PFRGL.js +17 -0
- package/dist/deployment.d.ts +1 -0
- package/dist/instrumentation.js +14 -18
- package/dist/nitro.d.ts +1 -1
- package/dist/nitro.js +43 -22
- package/dist/plugins-PZMDS7AT.js +15 -0
- package/dist/plugins.d.ts +4 -2
- package/dist/{registry-NLZFIW23.js → registry-OIPAJU2O.js} +6 -6
- package/dist/reporting.js +34 -26
- package/dist/{runner-LUQZ5G67.js → runner-KPLNHDCV.js} +76 -23
- package/dist/sentry-4CP5NNQ5.js +31 -0
- package/dist/validation-SLA6IGF7.js +15 -0
- package/dist/vercel.js +1 -1
- package/package.json +7 -6
- package/dist/agent-hooks-2HEB4C3Q.js +0 -33
- package/dist/chat/conversations/configured.d.ts +0 -7
- package/dist/chat/conversations/state.d.ts +0 -4
- package/dist/chat/plugins/db.d.ts +0 -31
- package/dist/chunk-2KG3PWR4.js +0 -17
- package/dist/chunk-D7NFH5GD.js +0 -570
- package/dist/chunk-MCMROINU.js +0 -12
- package/dist/chunk-WBZ4M5N5.js +0 -59
- package/dist/db-A3ILH67H.js +0 -20
- package/dist/plugins-OMJKLRJ2.js +0 -13
- package/dist/validation-VMCPP3YO.js +0 -15
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ConversationStore } from "./store";
|
|
2
|
-
/** Return the process-configured conversation record store. */
|
|
3
|
-
export declare function getConfiguredConversationStore(): ConversationStore;
|
|
4
|
-
/** Return whether conversation records use the configured SQL store. */
|
|
5
|
-
export declare function hasConfiguredSqlConversationStore(): boolean;
|
|
6
|
-
/** Close the configured SQL conversation store if one has been created. */
|
|
7
|
-
export declare function closeConfiguredConversationStore(): Promise<void>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { StateAdapter } from "chat";
|
|
2
|
-
import type { ConversationStore } from "./store";
|
|
3
|
-
/** Create the no-SQL conversation record store backed by task-execution state. */
|
|
4
|
-
export declare function createStateConversationStore(state?: StateAdapter): ConversationStore;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { PluginDb, PluginRegistration } from "@sentry/junior-plugin-api";
|
|
2
|
-
import type { JuniorSqlMigrationExecutor } from "@/chat/sql/db";
|
|
3
|
-
export interface PluginMigration {
|
|
4
|
-
checksum: string;
|
|
5
|
-
filename: string;
|
|
6
|
-
id: string;
|
|
7
|
-
pluginName: string;
|
|
8
|
-
sql: string;
|
|
9
|
-
}
|
|
10
|
-
export interface PluginMigrationRoot {
|
|
11
|
-
/** Absolute path to the plugin's migrations directory. */
|
|
12
|
-
dir: string;
|
|
13
|
-
pluginName: string;
|
|
14
|
-
}
|
|
15
|
-
export interface PluginMigrationResult {
|
|
16
|
-
existing: number;
|
|
17
|
-
migrated: number;
|
|
18
|
-
scanned: number;
|
|
19
|
-
}
|
|
20
|
-
/** Close the configured plugin DB executor if one has been created. */
|
|
21
|
-
export declare function closeConfiguredPluginDb(): Promise<void>;
|
|
22
|
-
/** Adapt the shared Junior SQL executor to the plugin-facing DB surface. */
|
|
23
|
-
export declare function createPluginDbForExecutor(executor: JuniorSqlMigrationExecutor): PluginDb;
|
|
24
|
-
/** Return a configured plugin DB only for plugins that declare database usage. */
|
|
25
|
-
export declare function getPluginDbForRegistration(registration: PluginRegistration): PluginDb | undefined;
|
|
26
|
-
/** Fail early when a plugin declares DB access without SQL config. */
|
|
27
|
-
export declare function validatePluginDatabaseRequirements(registrations: PluginRegistration[]): void;
|
|
28
|
-
/** Read committed SQL migration artifacts for one enabled plugin root. */
|
|
29
|
-
export declare function readPluginMigrations(root: PluginMigrationRoot): PluginMigration[];
|
|
30
|
-
/** Apply plugin-owned SQL migrations after core Junior migrations. */
|
|
31
|
-
export declare function migratePluginSchemas(executor: JuniorSqlMigrationExecutor, migrations: readonly PluginMigration[]): Promise<PluginMigrationResult>;
|
package/dist/chunk-2KG3PWR4.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __copyProps = (to, from, except, desc) => {
|
|
6
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
-
for (let key of __getOwnPropNames(from))
|
|
8
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
-
}
|
|
11
|
-
return to;
|
|
12
|
-
};
|
|
13
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
__reExport
|
|
17
|
-
};
|
package/dist/chunk-D7NFH5GD.js
DELETED
|
@@ -1,570 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getChatConfig
|
|
3
|
-
} from "./chunk-FCZO7LAR.js";
|
|
4
|
-
|
|
5
|
-
// src/chat/plugins/db.ts
|
|
6
|
-
import { createHash } from "crypto";
|
|
7
|
-
import { readdirSync, readFileSync, statSync } from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import { z } from "zod";
|
|
10
|
-
|
|
11
|
-
// src/chat/sql/neon.ts
|
|
12
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
13
|
-
import {
|
|
14
|
-
Pool
|
|
15
|
-
} from "@neondatabase/serverless";
|
|
16
|
-
import { drizzle } from "drizzle-orm/neon-serverless";
|
|
17
|
-
|
|
18
|
-
// src/chat/conversations/sql/schema/conversations.ts
|
|
19
|
-
import { sql } from "drizzle-orm";
|
|
20
|
-
import { index as index3, integer, jsonb as jsonb3, pgTable as pgTable3, text as text3 } from "drizzle-orm/pg-core";
|
|
21
|
-
|
|
22
|
-
// src/chat/conversations/sql/schema/destinations.ts
|
|
23
|
-
import { index, jsonb, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
|
|
24
|
-
|
|
25
|
-
// src/chat/conversations/sql/schema/timestamps.ts
|
|
26
|
-
import { timestamp } from "drizzle-orm/pg-core";
|
|
27
|
-
var timestamptz = (name) => timestamp(name, { withTimezone: true });
|
|
28
|
-
|
|
29
|
-
// src/chat/conversations/sql/schema/destinations.ts
|
|
30
|
-
var juniorDestinations = pgTable(
|
|
31
|
-
"junior_destinations",
|
|
32
|
-
{
|
|
33
|
-
id: text("id").primaryKey(),
|
|
34
|
-
provider: text("provider").notNull(),
|
|
35
|
-
providerTenantId: text("provider_tenant_id").notNull().default(""),
|
|
36
|
-
providerDestinationId: text("provider_destination_id").notNull(),
|
|
37
|
-
kind: text("kind").$type().notNull(),
|
|
38
|
-
parentDestinationId: text("parent_destination_id"),
|
|
39
|
-
displayName: text("display_name"),
|
|
40
|
-
visibility: text("visibility").$type().notNull().default("unknown"),
|
|
41
|
-
metadata: jsonb("metadata_json"),
|
|
42
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
43
|
-
updatedAt: timestamptz("updated_at").notNull()
|
|
44
|
-
},
|
|
45
|
-
(table) => [
|
|
46
|
-
uniqueIndex("junior_destinations_provider_destination_uidx").on(
|
|
47
|
-
table.provider,
|
|
48
|
-
table.providerTenantId,
|
|
49
|
-
table.providerDestinationId
|
|
50
|
-
),
|
|
51
|
-
index("junior_destinations_provider_kind_idx").on(
|
|
52
|
-
table.provider,
|
|
53
|
-
table.kind
|
|
54
|
-
)
|
|
55
|
-
]
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// src/chat/conversations/sql/schema/identities.ts
|
|
59
|
-
import { index as index2, jsonb as jsonb2, pgTable as pgTable2, text as text2, uniqueIndex as uniqueIndex2 } from "drizzle-orm/pg-core";
|
|
60
|
-
var juniorIdentities = pgTable2(
|
|
61
|
-
"junior_identities",
|
|
62
|
-
{
|
|
63
|
-
id: text2("id").primaryKey(),
|
|
64
|
-
kind: text2("kind").$type().notNull(),
|
|
65
|
-
provider: text2("provider").notNull(),
|
|
66
|
-
providerTenantId: text2("provider_tenant_id").notNull().default(""),
|
|
67
|
-
providerSubjectId: text2("provider_subject_id").notNull(),
|
|
68
|
-
displayName: text2("display_name"),
|
|
69
|
-
handle: text2("handle"),
|
|
70
|
-
email: text2("email"),
|
|
71
|
-
avatarUrl: text2("avatar_url"),
|
|
72
|
-
metadata: jsonb2("metadata_json"),
|
|
73
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
74
|
-
updatedAt: timestamptz("updated_at").notNull()
|
|
75
|
-
},
|
|
76
|
-
(table) => [
|
|
77
|
-
uniqueIndex2("junior_identities_provider_subject_uidx").on(
|
|
78
|
-
table.provider,
|
|
79
|
-
table.providerTenantId,
|
|
80
|
-
table.providerSubjectId
|
|
81
|
-
),
|
|
82
|
-
index2("junior_identities_kind_provider_idx").on(table.kind, table.provider)
|
|
83
|
-
]
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
// src/chat/conversations/sql/schema/conversations.ts
|
|
87
|
-
var juniorConversations = pgTable3(
|
|
88
|
-
"junior_conversations",
|
|
89
|
-
{
|
|
90
|
-
conversationId: text3("conversation_id").primaryKey(),
|
|
91
|
-
schemaVersion: integer("schema_version").notNull().default(1),
|
|
92
|
-
source: text3("source").$type(),
|
|
93
|
-
originType: text3("origin_type"),
|
|
94
|
-
originId: text3("origin_id"),
|
|
95
|
-
originRunId: text3("origin_run_id"),
|
|
96
|
-
destinationId: text3("destination_id").references(
|
|
97
|
-
() => juniorDestinations.id
|
|
98
|
-
),
|
|
99
|
-
destination: jsonb3("destination_json").$type(),
|
|
100
|
-
actorIdentityId: text3("actor_identity_id").references(
|
|
101
|
-
() => juniorIdentities.id
|
|
102
|
-
),
|
|
103
|
-
requesterIdentityId: text3("requester_identity_id").references(
|
|
104
|
-
() => juniorIdentities.id
|
|
105
|
-
),
|
|
106
|
-
creatorIdentityId: text3("creator_identity_id").references(
|
|
107
|
-
() => juniorIdentities.id
|
|
108
|
-
),
|
|
109
|
-
credentialSubjectIdentityId: text3(
|
|
110
|
-
"credential_subject_identity_id"
|
|
111
|
-
).references(() => juniorIdentities.id),
|
|
112
|
-
requester: jsonb3("requester_json").$type(),
|
|
113
|
-
channelName: text3("channel_name"),
|
|
114
|
-
title: text3("title"),
|
|
115
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
116
|
-
lastActivityAt: timestamptz("last_activity_at").notNull(),
|
|
117
|
-
updatedAt: timestamptz("updated_at").notNull(),
|
|
118
|
-
executionUpdatedAt: timestamptz("execution_updated_at"),
|
|
119
|
-
executionStatus: text3("execution_status").$type().notNull(),
|
|
120
|
-
runId: text3("run_id"),
|
|
121
|
-
lastCheckpointAt: timestamptz("last_checkpoint_at"),
|
|
122
|
-
lastEnqueuedAt: timestamptz("last_enqueued_at")
|
|
123
|
-
},
|
|
124
|
-
(table) => [
|
|
125
|
-
index3("junior_conversations_last_activity_idx").on(
|
|
126
|
-
table.lastActivityAt.desc(),
|
|
127
|
-
table.conversationId
|
|
128
|
-
),
|
|
129
|
-
index3("junior_conversations_active_idx").using(
|
|
130
|
-
"btree",
|
|
131
|
-
sql`coalesce(${table.executionUpdatedAt}, ${table.updatedAt})`,
|
|
132
|
-
table.conversationId
|
|
133
|
-
).where(sql`${table.executionStatus} <> 'idle'`),
|
|
134
|
-
index3("junior_conversations_destination_activity_idx").on(
|
|
135
|
-
table.destinationId,
|
|
136
|
-
table.lastActivityAt.desc()
|
|
137
|
-
),
|
|
138
|
-
index3("junior_conversations_actor_activity_idx").on(
|
|
139
|
-
table.actorIdentityId,
|
|
140
|
-
table.lastActivityAt.desc()
|
|
141
|
-
),
|
|
142
|
-
index3("junior_conversations_requester_activity_idx").on(
|
|
143
|
-
table.requesterIdentityId,
|
|
144
|
-
table.lastActivityAt.desc()
|
|
145
|
-
),
|
|
146
|
-
index3("junior_conversations_origin_idx").on(
|
|
147
|
-
table.originType,
|
|
148
|
-
table.originId,
|
|
149
|
-
table.lastActivityAt.desc()
|
|
150
|
-
)
|
|
151
|
-
]
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
// src/chat/conversations/sql/schema/migrations.ts
|
|
155
|
-
import { pgTable as pgTable4, text as text4 } from "drizzle-orm/pg-core";
|
|
156
|
-
var juniorSchemaMigrations = pgTable4("junior_schema_migrations", {
|
|
157
|
-
id: text4("id").primaryKey(),
|
|
158
|
-
checksum: text4("checksum").notNull(),
|
|
159
|
-
appliedAt: timestamptz("applied_at").notNull().defaultNow()
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// src/chat/conversations/sql/schema.ts
|
|
163
|
-
var schema = {
|
|
164
|
-
juniorConversations,
|
|
165
|
-
juniorDestinations,
|
|
166
|
-
juniorIdentities,
|
|
167
|
-
juniorSchemaMigrations
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// src/chat/sql/schema.ts
|
|
171
|
-
var juniorSqlSchema = {
|
|
172
|
-
...schema
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// src/chat/sql/neon.ts
|
|
176
|
-
var NeonExecutor = class {
|
|
177
|
-
constructor(pool) {
|
|
178
|
-
this.pool = pool;
|
|
179
|
-
}
|
|
180
|
-
pool;
|
|
181
|
-
transactionClient = new AsyncLocalStorage();
|
|
182
|
-
savepointId = 0;
|
|
183
|
-
db() {
|
|
184
|
-
return drizzle(this.queryClient(), {
|
|
185
|
-
schema: juniorSqlSchema
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
async execute(statement, params = []) {
|
|
189
|
-
await this.queryClient().query(statement, [...params]);
|
|
190
|
-
}
|
|
191
|
-
async query(statement, params = []) {
|
|
192
|
-
const result = await this.queryClient().query(statement, [
|
|
193
|
-
...params
|
|
194
|
-
]);
|
|
195
|
-
return result.rows;
|
|
196
|
-
}
|
|
197
|
-
async transaction(callback) {
|
|
198
|
-
const existingClient = this.transactionClient.getStore();
|
|
199
|
-
if (existingClient) {
|
|
200
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
201
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
202
|
-
try {
|
|
203
|
-
const result = await callback();
|
|
204
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
205
|
-
return result;
|
|
206
|
-
} catch (error) {
|
|
207
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
208
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const client = await this.pool.connect();
|
|
213
|
-
try {
|
|
214
|
-
await client.query("BEGIN");
|
|
215
|
-
const result = await this.transactionClient.run(client, callback);
|
|
216
|
-
await client.query("COMMIT");
|
|
217
|
-
return result;
|
|
218
|
-
} catch (error) {
|
|
219
|
-
await client.query("ROLLBACK");
|
|
220
|
-
throw error;
|
|
221
|
-
} finally {
|
|
222
|
-
client.release();
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
async withLock(lockName, callback) {
|
|
226
|
-
if (!lockName) {
|
|
227
|
-
throw new Error("SQL lock name is required");
|
|
228
|
-
}
|
|
229
|
-
const existingClient = this.transactionClient.getStore();
|
|
230
|
-
if (existingClient) {
|
|
231
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
232
|
-
lockName
|
|
233
|
-
]);
|
|
234
|
-
return await callback();
|
|
235
|
-
}
|
|
236
|
-
const client = await this.pool.connect();
|
|
237
|
-
try {
|
|
238
|
-
await client.query("BEGIN");
|
|
239
|
-
return await this.transactionClient.run(client, async () => {
|
|
240
|
-
try {
|
|
241
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
242
|
-
lockName
|
|
243
|
-
]);
|
|
244
|
-
const result = await callback();
|
|
245
|
-
await client.query("COMMIT");
|
|
246
|
-
return result;
|
|
247
|
-
} catch (error) {
|
|
248
|
-
await client.query("ROLLBACK");
|
|
249
|
-
throw error;
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
} finally {
|
|
253
|
-
client.release();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
async close() {
|
|
257
|
-
await this.pool.end();
|
|
258
|
-
}
|
|
259
|
-
queryClient() {
|
|
260
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
function createNeonJuniorSqlExecutor(args) {
|
|
264
|
-
return new NeonExecutor(
|
|
265
|
-
new Pool({
|
|
266
|
-
connectionString: args.connectionString,
|
|
267
|
-
max: 3
|
|
268
|
-
})
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// src/chat/sql/postgres.ts
|
|
273
|
-
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
274
|
-
import pg from "pg";
|
|
275
|
-
import { drizzle as drizzle2 } from "drizzle-orm/node-postgres";
|
|
276
|
-
var { Pool: Pool2 } = pg;
|
|
277
|
-
var PostgresExecutor = class {
|
|
278
|
-
constructor(pool) {
|
|
279
|
-
this.pool = pool;
|
|
280
|
-
}
|
|
281
|
-
pool;
|
|
282
|
-
transactionClient = new AsyncLocalStorage2();
|
|
283
|
-
savepointId = 0;
|
|
284
|
-
db() {
|
|
285
|
-
return drizzle2(this.queryClient(), {
|
|
286
|
-
schema: juniorSqlSchema
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
async execute(statement, params = []) {
|
|
290
|
-
await this.queryClient().query(statement, [...params]);
|
|
291
|
-
}
|
|
292
|
-
async query(statement, params = []) {
|
|
293
|
-
const result = await this.queryClient().query(statement, [
|
|
294
|
-
...params
|
|
295
|
-
]);
|
|
296
|
-
return result.rows;
|
|
297
|
-
}
|
|
298
|
-
async transaction(callback) {
|
|
299
|
-
const existingClient = this.transactionClient.getStore();
|
|
300
|
-
if (existingClient) {
|
|
301
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
302
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
303
|
-
try {
|
|
304
|
-
const result = await callback();
|
|
305
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
306
|
-
return result;
|
|
307
|
-
} catch (error) {
|
|
308
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
309
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
310
|
-
throw error;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const client = await this.pool.connect();
|
|
314
|
-
try {
|
|
315
|
-
await client.query("BEGIN");
|
|
316
|
-
const result = await this.transactionClient.run(client, callback);
|
|
317
|
-
await client.query("COMMIT");
|
|
318
|
-
return result;
|
|
319
|
-
} catch (error) {
|
|
320
|
-
await client.query("ROLLBACK");
|
|
321
|
-
throw error;
|
|
322
|
-
} finally {
|
|
323
|
-
client.release();
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
async withLock(lockName, callback) {
|
|
327
|
-
if (!lockName) {
|
|
328
|
-
throw new Error("SQL lock name is required");
|
|
329
|
-
}
|
|
330
|
-
const existingClient = this.transactionClient.getStore();
|
|
331
|
-
if (existingClient) {
|
|
332
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
333
|
-
lockName
|
|
334
|
-
]);
|
|
335
|
-
return await callback();
|
|
336
|
-
}
|
|
337
|
-
const client = await this.pool.connect();
|
|
338
|
-
try {
|
|
339
|
-
await client.query("BEGIN");
|
|
340
|
-
return await this.transactionClient.run(client, async () => {
|
|
341
|
-
try {
|
|
342
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
343
|
-
lockName
|
|
344
|
-
]);
|
|
345
|
-
const result = await callback();
|
|
346
|
-
await client.query("COMMIT");
|
|
347
|
-
return result;
|
|
348
|
-
} catch (error) {
|
|
349
|
-
await client.query("ROLLBACK");
|
|
350
|
-
throw error;
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
} finally {
|
|
354
|
-
client.release();
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
async close() {
|
|
358
|
-
await this.pool.end();
|
|
359
|
-
}
|
|
360
|
-
queryClient() {
|
|
361
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
function createPostgresJuniorSqlExecutor(args) {
|
|
365
|
-
return new PostgresExecutor(
|
|
366
|
-
new Pool2({
|
|
367
|
-
application_name: args.applicationName,
|
|
368
|
-
connectionString: args.connectionString,
|
|
369
|
-
max: 3
|
|
370
|
-
})
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// src/chat/sql/executor.ts
|
|
375
|
-
function createJuniorSqlExecutor(args) {
|
|
376
|
-
if (args.driver === "postgres") {
|
|
377
|
-
return createPostgresJuniorSqlExecutor(args);
|
|
378
|
-
}
|
|
379
|
-
return createNeonJuniorSqlExecutor(args);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// src/chat/plugins/db.ts
|
|
383
|
-
var PLUGIN_SCHEMA_LOCK_NAME = "junior_plugin_schema";
|
|
384
|
-
var MIGRATION_FILENAME_RE = /^[0-9]{4}_[a-z0-9_]+\.sql$/;
|
|
385
|
-
var migrationRecordSchema = z.object({
|
|
386
|
-
id: z.string().min(1),
|
|
387
|
-
checksum: z.string().min(1)
|
|
388
|
-
}).strict();
|
|
389
|
-
var configuredPluginDb;
|
|
390
|
-
function checksumSql(sql2) {
|
|
391
|
-
return createHash("sha256").update(sql2).digest("hex");
|
|
392
|
-
}
|
|
393
|
-
function parseStoredMigrationRecord(value) {
|
|
394
|
-
return migrationRecordSchema.parse(value);
|
|
395
|
-
}
|
|
396
|
-
function assertMigrationFilename(filename) {
|
|
397
|
-
if (!filename || filename !== path.basename(filename) || !MIGRATION_FILENAME_RE.test(filename)) {
|
|
398
|
-
throw new Error(`Plugin migration filename "${filename}" is invalid`);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
function assertUniqueMigrationIds(migrations) {
|
|
402
|
-
const seen = /* @__PURE__ */ new Set();
|
|
403
|
-
for (const migration of migrations) {
|
|
404
|
-
if (seen.has(migration.id)) {
|
|
405
|
-
throw new Error(`Duplicate plugin migration id ${migration.id}`);
|
|
406
|
-
}
|
|
407
|
-
seen.add(migration.id);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
function migrationId(pluginName, filename) {
|
|
411
|
-
return `plugin:${pluginName}/${filename}`;
|
|
412
|
-
}
|
|
413
|
-
function createMigrationTableSql() {
|
|
414
|
-
return `
|
|
415
|
-
CREATE TABLE IF NOT EXISTS junior_schema_migrations (
|
|
416
|
-
id TEXT PRIMARY KEY,
|
|
417
|
-
checksum TEXT NOT NULL,
|
|
418
|
-
applied_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
419
|
-
)
|
|
420
|
-
`;
|
|
421
|
-
}
|
|
422
|
-
function createPluginDb(executor) {
|
|
423
|
-
const db = executor.db();
|
|
424
|
-
const pluginDb = {
|
|
425
|
-
delete: db.delete.bind(db),
|
|
426
|
-
execute: (statement, params) => executor.execute(statement, params),
|
|
427
|
-
insert: db.insert.bind(db),
|
|
428
|
-
query: (statement, params) => executor.query(statement, params),
|
|
429
|
-
select: db.select.bind(db),
|
|
430
|
-
transaction: async (callback) => await executor.transaction(
|
|
431
|
-
async () => await callback(createPluginDb(executor))
|
|
432
|
-
),
|
|
433
|
-
update: db.update.bind(db)
|
|
434
|
-
};
|
|
435
|
-
return pluginDb;
|
|
436
|
-
}
|
|
437
|
-
function getConfiguredPluginDb() {
|
|
438
|
-
const databaseUrl = getChatConfig().sql.databaseUrl;
|
|
439
|
-
const driver = getChatConfig().sql.driver;
|
|
440
|
-
if (!databaseUrl) {
|
|
441
|
-
return void 0;
|
|
442
|
-
}
|
|
443
|
-
if (configuredPluginDb?.databaseUrl !== databaseUrl || configuredPluginDb.driver !== driver) {
|
|
444
|
-
void configuredPluginDb?.executor.close().catch(() => void 0);
|
|
445
|
-
const executor = createJuniorSqlExecutor({
|
|
446
|
-
connectionString: databaseUrl,
|
|
447
|
-
driver
|
|
448
|
-
});
|
|
449
|
-
configuredPluginDb = {
|
|
450
|
-
databaseUrl,
|
|
451
|
-
driver,
|
|
452
|
-
executor,
|
|
453
|
-
db: createPluginDb(executor)
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
return configuredPluginDb.db;
|
|
457
|
-
}
|
|
458
|
-
async function closeConfiguredPluginDb() {
|
|
459
|
-
const current = configuredPluginDb;
|
|
460
|
-
configuredPluginDb = void 0;
|
|
461
|
-
await current?.executor.close();
|
|
462
|
-
}
|
|
463
|
-
async function listAppliedMigrations(executor) {
|
|
464
|
-
const rows = await executor.query(
|
|
465
|
-
"SELECT id, checksum FROM junior_schema_migrations ORDER BY id ASC"
|
|
466
|
-
);
|
|
467
|
-
const records = /* @__PURE__ */ new Map();
|
|
468
|
-
for (const row of rows) {
|
|
469
|
-
const record = parseStoredMigrationRecord(row);
|
|
470
|
-
records.set(record.id, record);
|
|
471
|
-
}
|
|
472
|
-
return records;
|
|
473
|
-
}
|
|
474
|
-
async function applyPluginMigration(executor, migration) {
|
|
475
|
-
await executor.transaction(async () => {
|
|
476
|
-
await executor.execute(migration.sql);
|
|
477
|
-
await executor.execute(
|
|
478
|
-
"INSERT INTO junior_schema_migrations (id, checksum) VALUES ($1, $2)",
|
|
479
|
-
[migration.id, migration.checksum]
|
|
480
|
-
);
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
function createPluginDbForExecutor(executor) {
|
|
484
|
-
return createPluginDb(executor);
|
|
485
|
-
}
|
|
486
|
-
function getPluginDbForRegistration(registration) {
|
|
487
|
-
if (!registration.database) {
|
|
488
|
-
return void 0;
|
|
489
|
-
}
|
|
490
|
-
return getConfiguredPluginDb();
|
|
491
|
-
}
|
|
492
|
-
function validatePluginDatabaseRequirements(registrations) {
|
|
493
|
-
if (getChatConfig().sql.databaseUrl) {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
const databasePlugins = registrations.filter((registration) => registration.database).map((registration) => registration.manifest.name);
|
|
497
|
-
if (databasePlugins.length > 0) {
|
|
498
|
-
throw new Error(
|
|
499
|
-
`Plugin database access requires JUNIOR_DATABASE_URL or DATABASE_URL for: ${databasePlugins.join(", ")}`
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
function readPluginMigrations(root) {
|
|
504
|
-
const migrationsDir = root.dir;
|
|
505
|
-
let stat;
|
|
506
|
-
try {
|
|
507
|
-
stat = statSync(migrationsDir);
|
|
508
|
-
} catch {
|
|
509
|
-
return [];
|
|
510
|
-
}
|
|
511
|
-
if (!stat.isDirectory()) {
|
|
512
|
-
throw new Error(
|
|
513
|
-
`Plugin "${root.pluginName}" migrations path is not a directory`
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
return readdirSync(migrationsDir).filter((filename) => filename.endsWith(".sql")).sort((left, right) => left.localeCompare(right)).map((filename) => {
|
|
517
|
-
assertMigrationFilename(filename);
|
|
518
|
-
const sql2 = readFileSync(path.join(migrationsDir, filename), "utf8");
|
|
519
|
-
if (!sql2.trim()) {
|
|
520
|
-
throw new Error(
|
|
521
|
-
`Plugin "${root.pluginName}" migration "${filename}" is empty`
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
return {
|
|
525
|
-
checksum: checksumSql(sql2),
|
|
526
|
-
filename,
|
|
527
|
-
id: migrationId(root.pluginName, filename),
|
|
528
|
-
pluginName: root.pluginName,
|
|
529
|
-
sql: sql2
|
|
530
|
-
};
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
async function migratePluginSchemas(executor, migrations) {
|
|
534
|
-
assertUniqueMigrationIds(migrations);
|
|
535
|
-
const result = {
|
|
536
|
-
existing: 0,
|
|
537
|
-
migrated: 0,
|
|
538
|
-
scanned: migrations.length
|
|
539
|
-
};
|
|
540
|
-
await executor.withLock(PLUGIN_SCHEMA_LOCK_NAME, async () => {
|
|
541
|
-
await executor.execute(createMigrationTableSql());
|
|
542
|
-
const applied = await listAppliedMigrations(executor);
|
|
543
|
-
for (const migration of migrations) {
|
|
544
|
-
const existing = applied.get(migration.id);
|
|
545
|
-
if (existing) {
|
|
546
|
-
if (existing.checksum !== migration.checksum) {
|
|
547
|
-
throw new Error(`Plugin migration ${migration.id} checksum changed`);
|
|
548
|
-
}
|
|
549
|
-
result.existing++;
|
|
550
|
-
continue;
|
|
551
|
-
}
|
|
552
|
-
await applyPluginMigration(executor, migration);
|
|
553
|
-
result.migrated++;
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
return result;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
export {
|
|
560
|
-
juniorDestinations,
|
|
561
|
-
juniorIdentities,
|
|
562
|
-
juniorConversations,
|
|
563
|
-
createJuniorSqlExecutor,
|
|
564
|
-
closeConfiguredPluginDb,
|
|
565
|
-
createPluginDbForExecutor,
|
|
566
|
-
getPluginDbForRegistration,
|
|
567
|
-
validatePluginDatabaseRequirements,
|
|
568
|
-
readPluginMigrations,
|
|
569
|
-
migratePluginSchemas
|
|
570
|
-
};
|
package/dist/chunk-MCMROINU.js
DELETED
package/dist/chunk-WBZ4M5N5.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
normalizeSlackConversationId
|
|
3
|
-
} from "./chunk-62FUNJYS.js";
|
|
4
|
-
import {
|
|
5
|
-
isSlackConversationId,
|
|
6
|
-
isSlackTeamId
|
|
7
|
-
} from "./chunk-MCMROINU.js";
|
|
8
|
-
|
|
9
|
-
// src/chat/destination.ts
|
|
10
|
-
import {
|
|
11
|
-
destinationSchema
|
|
12
|
-
} from "@sentry/junior-plugin-api";
|
|
13
|
-
function createSlackDestination(input) {
|
|
14
|
-
const channelId = normalizeSlackConversationId(input.channelId);
|
|
15
|
-
const teamId = input.teamId?.trim();
|
|
16
|
-
if (!channelId || !teamId) {
|
|
17
|
-
return void 0;
|
|
18
|
-
}
|
|
19
|
-
if (!isSlackConversationId(channelId) || !isSlackTeamId(teamId)) {
|
|
20
|
-
return void 0;
|
|
21
|
-
}
|
|
22
|
-
return { platform: "slack", teamId, channelId };
|
|
23
|
-
}
|
|
24
|
-
function parseDestination(value) {
|
|
25
|
-
const parsed = destinationSchema.safeParse(value);
|
|
26
|
-
return parsed.success ? parsed.data : void 0;
|
|
27
|
-
}
|
|
28
|
-
function requireSlackDestination(destination, action) {
|
|
29
|
-
if (destination?.platform === "slack") {
|
|
30
|
-
return destination;
|
|
31
|
-
}
|
|
32
|
-
throw new Error(`${action} requires a Slack destination`);
|
|
33
|
-
}
|
|
34
|
-
function sameDestination(left, right) {
|
|
35
|
-
if (left.platform !== right.platform) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
if (left.platform === "local" && right.platform === "local") {
|
|
39
|
-
return left.conversationId === right.conversationId;
|
|
40
|
-
}
|
|
41
|
-
if (left.platform === "slack" && right.platform === "slack") {
|
|
42
|
-
return left.teamId === right.teamId && left.channelId === right.channelId;
|
|
43
|
-
}
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
function destinationKey(destination) {
|
|
47
|
-
if (destination.platform === "local") {
|
|
48
|
-
return destination.conversationId;
|
|
49
|
-
}
|
|
50
|
-
return `slack:${destination.teamId}:${destination.channelId}`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export {
|
|
54
|
-
createSlackDestination,
|
|
55
|
-
parseDestination,
|
|
56
|
-
requireSlackDestination,
|
|
57
|
-
sameDestination,
|
|
58
|
-
destinationKey
|
|
59
|
-
};
|