@inkeep/agents-core 0.59.3 → 0.59.4
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/auth/auth-schema.d.ts +108 -108
- package/dist/auth/auth-validation-schemas.d.ts +137 -137
- package/dist/auth/auth.d.ts +6 -6
- package/dist/auth/auth.js +2 -2
- package/dist/auth/permissions.d.ts +13 -13
- package/dist/data-access/manage/credentialReferences.js +1 -1
- package/dist/data-access/manage/dataComponents.js +1 -1
- package/dist/data-access/manage/skills.d.ts +1 -1
- package/dist/data-access/runtime/messages.d.ts +9 -9
- package/dist/db/manage/manage-schema.d.ts +449 -449
- package/dist/db/runtime/runtime-schema.d.ts +328 -328
- package/dist/db/runtime/test-runtime-client.js +1 -1
- package/dist/dolt/advisory-lock.d.ts +7 -0
- package/dist/dolt/advisory-lock.js +18 -0
- package/dist/dolt/branches-api.d.ts +19 -9
- package/dist/dolt/branches-api.js +58 -29
- package/dist/dolt/index.d.ts +7 -4
- package/dist/dolt/index.js +7 -4
- package/dist/dolt/merge.d.ts +41 -5
- package/dist/dolt/merge.js +161 -24
- package/dist/dolt/pk-map.d.ts +6 -0
- package/dist/dolt/pk-map.js +27 -0
- package/dist/dolt/ref-middleware.d.ts +2 -1
- package/dist/dolt/ref-middleware.js +18 -4
- package/dist/dolt/resolve-conflicts.d.ts +10 -0
- package/dist/dolt/resolve-conflicts.js +100 -0
- package/dist/dolt/schema-sync.js +17 -17
- package/dist/index.d.ts +8 -5
- package/dist/index.js +9 -6
- package/dist/utils/index.js +1 -1
- package/dist/validation/dolt-schemas.d.ts +95 -2
- package/dist/validation/dolt-schemas.js +54 -2
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +2 -2
- package/dist/validation/schemas.d.ts +1261 -1261
- package/package.json +2 -2
|
@@ -57,7 +57,7 @@ async function closeTestRuntimeDatabase(db) {
|
|
|
57
57
|
* This is a helper for tests that need organization records before creating projects/agents
|
|
58
58
|
*/
|
|
59
59
|
async function createTestOrganization(db, tenantId) {
|
|
60
|
-
const slug = tenantId.replace(/^test-tenant-/, "")
|
|
60
|
+
const slug = tenantId.replace(/^test-tenant-/, "");
|
|
61
61
|
await db.insert(organization).values({
|
|
62
62
|
id: tenantId,
|
|
63
63
|
name: `Test Organization ${tenantId}`,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
2
|
+
|
|
3
|
+
//#region src/dolt/advisory-lock.d.ts
|
|
4
|
+
declare const tryAdvisoryLock: (db: AgentsManageDatabaseClient) => (prefix: string, identifier: string) => Promise<boolean>;
|
|
5
|
+
declare const releaseAdvisoryLock: (db: AgentsManageDatabaseClient) => (prefix: string, identifier: string) => Promise<void>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { releaseAdvisoryLock, tryAdvisoryLock };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
|
|
4
|
+
//#region src/dolt/advisory-lock.ts
|
|
5
|
+
function computeLockKey(prefix, identifier) {
|
|
6
|
+
return createHash("sha256").update(`${prefix}${identifier}`).digest().readBigInt64BE(0);
|
|
7
|
+
}
|
|
8
|
+
const tryAdvisoryLock = (db) => async (prefix, identifier) => {
|
|
9
|
+
const key = computeLockKey(prefix, identifier);
|
|
10
|
+
return (await db.execute(sql`SELECT pg_try_advisory_lock(CAST(${key} AS bigint)) as acquired`)).rows[0]?.acquired === true;
|
|
11
|
+
};
|
|
12
|
+
const releaseAdvisoryLock = (db) => async (prefix, identifier) => {
|
|
13
|
+
const key = computeLockKey(prefix, identifier);
|
|
14
|
+
await db.execute(sql`SELECT pg_advisory_unlock(CAST(${key} AS bigint))`);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { releaseAdvisoryLock, tryAdvisoryLock };
|
|
@@ -5,6 +5,9 @@ import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
|
5
5
|
|
|
6
6
|
//#region src/dolt/branches-api.d.ts
|
|
7
7
|
declare const MAIN_BRANCH_SUFFIX = "main";
|
|
8
|
+
declare class invalidBranchParamsError extends Error {
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
8
11
|
/**
|
|
9
12
|
* Get the tenant-scoped main branch name
|
|
10
13
|
*/
|
|
@@ -13,24 +16,23 @@ declare const getTenantMainBranch: (tenantId: string) => string;
|
|
|
13
16
|
* Check if a branch name (without tenant/project prefix) is a protected branch
|
|
14
17
|
*/
|
|
15
18
|
declare const isProtectedBranchName: (branchName: string) => boolean;
|
|
19
|
+
declare const getTempBranchSuffix: (prefix: string) => string;
|
|
20
|
+
declare const isTempBranchName: (fullName: string) => boolean;
|
|
16
21
|
type CreateBranchParams = {
|
|
17
22
|
tenantId: string;
|
|
18
23
|
projectId: string;
|
|
19
24
|
name: string;
|
|
20
|
-
/** Branch to create from. Defaults to tenant main branch. */
|
|
21
|
-
|
|
25
|
+
/** Branch name to create from. Defaults to tenant main branch. */
|
|
26
|
+
fromBranch?: string;
|
|
27
|
+
/** Commit hash to create from. Mutually exclusive with fromBranch. */
|
|
28
|
+
fromCommit?: string;
|
|
22
29
|
/**
|
|
23
30
|
* Whether to sync schema on the source branch before creating.
|
|
24
31
|
* This ensures the new branch starts with the latest schema from main.
|
|
25
|
-
* Default: true
|
|
32
|
+
* Default: true. Ignored when fromCommit is set.
|
|
26
33
|
*/
|
|
27
34
|
syncSchemaOnSource?: boolean;
|
|
28
35
|
};
|
|
29
|
-
type DeleteBranchParams = {
|
|
30
|
-
tenantId: string;
|
|
31
|
-
projectId: string;
|
|
32
|
-
name: string;
|
|
33
|
-
};
|
|
34
36
|
type GetBranchParams = {
|
|
35
37
|
tenantId: string;
|
|
36
38
|
projectId: string;
|
|
@@ -79,6 +81,7 @@ type CheckoutBranchResult = {
|
|
|
79
81
|
* @returns Function that takes checkout params and returns checkout result
|
|
80
82
|
*/
|
|
81
83
|
declare const checkoutBranch: (db: AgentsManageDatabaseClient) => (params: CheckoutBranchParams) => Promise<CheckoutBranchResult>;
|
|
84
|
+
declare const syncSchemaOnBranch: (db: AgentsManageDatabaseClient) => (branchName: string) => Promise<void>;
|
|
82
85
|
/**
|
|
83
86
|
* Create a new branch with optional schema synchronization.
|
|
84
87
|
*
|
|
@@ -88,8 +91,15 @@ declare const checkoutBranch: (db: AgentsManageDatabaseClient) => (params: Check
|
|
|
88
91
|
*
|
|
89
92
|
* By syncing schema on the source branch first, we ensure the new branch
|
|
90
93
|
* starts with the latest schema, avoiding schema conflicts later.
|
|
94
|
+
* If you want to create a branch from a commit hash, use the fromCommit parameter.
|
|
91
95
|
*/
|
|
92
96
|
declare const createBranch: (db: AgentsManageDatabaseClient) => (params: CreateBranchParams) => Promise<BranchInfo>;
|
|
97
|
+
type DeleteBranchParams = {
|
|
98
|
+
tenantId: string;
|
|
99
|
+
projectId: string;
|
|
100
|
+
branchName: string;
|
|
101
|
+
force?: boolean;
|
|
102
|
+
};
|
|
93
103
|
/**
|
|
94
104
|
* Delete a branch
|
|
95
105
|
*/
|
|
@@ -106,4 +116,4 @@ declare const getBranch: (db: AgentsManageDatabaseClient) => (params: GetBranchP
|
|
|
106
116
|
declare const listBranches: (db: AgentsManageDatabaseClient) => (params: ProjectScopeConfig) => Promise<BranchInfo[]>;
|
|
107
117
|
declare const listBranchesForAgent: (db: AgentsManageDatabaseClient) => (params: AgentScopeConfig) => Promise<BranchInfo[]>;
|
|
108
118
|
//#endregion
|
|
109
|
-
export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, GetBranchParams, MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent };
|
|
119
|
+
export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, GetBranchParams, MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTempBranchSuffix, getTenantMainBranch, invalidBranchParamsError, isProtectedBranchName, isTempBranchName, listBranches, listBranchesForAgent, syncSchemaOnBranch };
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import { doltHashOf } from "./commit.js";
|
|
1
2
|
import { SCHEMA_SOURCE_BRANCH, ensureSchemaSync, getSchemaDiff, syncSchemaFromMain } from "./schema-sync.js";
|
|
2
3
|
import { doltBranch, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches } from "./branch.js";
|
|
3
4
|
import { sql } from "drizzle-orm";
|
|
4
5
|
|
|
5
6
|
//#region src/dolt/branches-api.ts
|
|
6
7
|
const MAIN_BRANCH_SUFFIX = "main";
|
|
8
|
+
var invalidBranchParamsError = class extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "invalidBranchParamsError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
7
14
|
/**
|
|
8
15
|
* Get the tenant-scoped main branch name
|
|
9
16
|
*/
|
|
@@ -14,6 +21,12 @@ const getTenantMainBranch = (tenantId) => `${tenantId}_${MAIN_BRANCH_SUFFIX}`;
|
|
|
14
21
|
const isProtectedBranchName = (branchName) => {
|
|
15
22
|
return branchName === MAIN_BRANCH_SUFFIX;
|
|
16
23
|
};
|
|
24
|
+
const getTempBranchSuffix = (prefix) => {
|
|
25
|
+
return `temp-${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
26
|
+
};
|
|
27
|
+
const isTempBranchName = (fullName) => {
|
|
28
|
+
return /temp-[a-z-]+_\d+_[a-z0-9]+$/.test(fullName);
|
|
29
|
+
};
|
|
17
30
|
/**
|
|
18
31
|
* Checkout a branch with optional schema synchronization from main.
|
|
19
32
|
*
|
|
@@ -49,6 +62,13 @@ const checkoutBranch = (db) => async (params) => {
|
|
|
49
62
|
}
|
|
50
63
|
};
|
|
51
64
|
};
|
|
65
|
+
const syncSchemaOnBranch = (db) => async (branchName) => {
|
|
66
|
+
if ((await getSchemaDiff(db)(branchName)).length > 0) {
|
|
67
|
+
await doltCheckout(db)({ branch: branchName });
|
|
68
|
+
const syncResult = await syncSchemaFromMain(db)({ autoCommitPending: true });
|
|
69
|
+
if (syncResult.error && !syncResult.synced) throw new Error(`Failed to sync schema on source branch '${branchName}': ${syncResult.error}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
52
72
|
/**
|
|
53
73
|
* Create a new branch with optional schema synchronization.
|
|
54
74
|
*
|
|
@@ -58,55 +78,64 @@ const checkoutBranch = (db) => async (params) => {
|
|
|
58
78
|
*
|
|
59
79
|
* By syncing schema on the source branch first, we ensure the new branch
|
|
60
80
|
* starts with the latest schema, avoiding schema conflicts later.
|
|
81
|
+
* If you want to create a branch from a commit hash, use the fromCommit parameter.
|
|
61
82
|
*/
|
|
62
83
|
const createBranch = (db) => async (params) => {
|
|
63
|
-
const { tenantId, projectId, name,
|
|
64
|
-
if (
|
|
84
|
+
const { tenantId, projectId, name, fromBranch, fromCommit, syncSchemaOnSource = true } = params;
|
|
85
|
+
if (fromBranch && fromCommit) throw new invalidBranchParamsError("Cannot specify both fromBranch and fromCommit");
|
|
86
|
+
if (!name || name.trim() === "") throw new invalidBranchParamsError("Branch name cannot be empty");
|
|
65
87
|
const fullName = doltGetBranchNamespace({
|
|
66
88
|
tenantId,
|
|
67
89
|
projectId,
|
|
68
90
|
branchName: name
|
|
69
91
|
})();
|
|
70
|
-
if ((await doltListBranches(db)()).some((b) => b.name === fullName)) throw new
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
else
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
92
|
+
if ((await doltListBranches(db)()).some((b) => b.name === fullName)) throw new invalidBranchParamsError(`Branch '${name}' already exists`);
|
|
93
|
+
if (fromCommit) {
|
|
94
|
+
await doltBranch(db)({
|
|
95
|
+
name: fullName,
|
|
96
|
+
startPoint: fromCommit
|
|
97
|
+
});
|
|
98
|
+
if (syncSchemaOnSource) await syncSchemaOnBranch(db)(fullName);
|
|
99
|
+
} else {
|
|
100
|
+
let fromFullBranchName;
|
|
101
|
+
if (fromBranch) fromFullBranchName = doltGetBranchNamespace({
|
|
102
|
+
tenantId,
|
|
103
|
+
projectId,
|
|
104
|
+
branchName: fromBranch
|
|
105
|
+
})();
|
|
106
|
+
else fromFullBranchName = doltGetBranchNamespace({
|
|
107
|
+
tenantId,
|
|
108
|
+
projectId,
|
|
109
|
+
branchName: MAIN_BRANCH_SUFFIX
|
|
110
|
+
})();
|
|
111
|
+
if (syncSchemaOnSource && fromFullBranchName !== SCHEMA_SOURCE_BRANCH) await syncSchemaOnBranch(db)(fromFullBranchName);
|
|
112
|
+
await doltBranch(db)({
|
|
113
|
+
name: fullName,
|
|
114
|
+
startPoint: fromFullBranchName
|
|
115
|
+
});
|
|
84
116
|
}
|
|
85
|
-
await doltBranch(db)({
|
|
86
|
-
name: fullName,
|
|
87
|
-
startPoint: fromFullBranchName
|
|
88
|
-
});
|
|
89
|
-
const newBranch = (await doltListBranches(db)()).find((b) => b.name === fullName);
|
|
90
|
-
if (!newBranch) throw new Error("Failed to create branch");
|
|
91
117
|
return {
|
|
92
118
|
baseName: name,
|
|
93
119
|
fullName,
|
|
94
|
-
hash:
|
|
120
|
+
hash: await doltHashOf(db)({ revision: fullName })
|
|
95
121
|
};
|
|
96
122
|
};
|
|
97
123
|
/**
|
|
98
124
|
* Delete a branch
|
|
99
125
|
*/
|
|
100
126
|
const deleteBranch = (db) => async (params) => {
|
|
101
|
-
const { tenantId, projectId,
|
|
102
|
-
if (isProtectedBranchName(
|
|
127
|
+
const { tenantId, projectId, branchName, force } = params;
|
|
128
|
+
if (isProtectedBranchName(branchName)) throw new invalidBranchParamsError(`Cannot delete protected branch '${branchName}'`);
|
|
103
129
|
const fullName = doltGetBranchNamespace({
|
|
104
130
|
tenantId,
|
|
105
131
|
projectId,
|
|
106
|
-
branchName
|
|
132
|
+
branchName
|
|
107
133
|
})();
|
|
108
|
-
if (!(await doltListBranches(db)()).some((b) => b.name === fullName)) throw new
|
|
109
|
-
await doltDeleteBranch(db)({
|
|
134
|
+
if (!(await doltListBranches(db)()).some((b) => b.name === fullName)) throw new invalidBranchParamsError(`Branch '${branchName}' not found`);
|
|
135
|
+
await doltDeleteBranch(db)({
|
|
136
|
+
name: fullName,
|
|
137
|
+
force
|
|
138
|
+
});
|
|
110
139
|
};
|
|
111
140
|
/**
|
|
112
141
|
* Get a single branch
|
|
@@ -159,4 +188,4 @@ const listBranchesForAgent = (db) => async (params) => {
|
|
|
159
188
|
};
|
|
160
189
|
|
|
161
190
|
//#endregion
|
|
162
|
-
export { MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent };
|
|
191
|
+
export { MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTempBranchSuffix, getTenantMainBranch, invalidBranchParamsError, isProtectedBranchName, isTempBranchName, listBranches, listBranchesForAgent, syncSchemaOnBranch };
|
package/dist/dolt/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { releaseAdvisoryLock, tryAdvisoryLock } from "./advisory-lock.js";
|
|
1
2
|
import { branchScopes, doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists } from "./branch.js";
|
|
2
|
-
import { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, GetBranchParams, MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent } from "./branches-api.js";
|
|
3
|
+
import { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, GetBranchParams, MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTempBranchSuffix, getTenantMainBranch, invalidBranchParamsError, isProtectedBranchName, isTempBranchName, listBranches, listBranchesForAgent, syncSchemaOnBranch } from "./branches-api.js";
|
|
3
4
|
import { doltAdd, doltAddAndCommit, doltCommit, doltDeleteTag, doltHashOf, doltListTags, doltLog, doltReset, doltStatus, doltTag } from "./commit.js";
|
|
4
5
|
import { doltDiff, doltDiffSummary } from "./diff.js";
|
|
5
|
-
import { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts } from "./merge.js";
|
|
6
|
+
import { MergeConflictError, doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts } from "./merge.js";
|
|
7
|
+
import { PkMap, isValidManageTable, managePkMap } from "./pk-map.js";
|
|
6
8
|
import { RefType, checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveProjectMainRefs, resolveRef } from "./ref-helpers.js";
|
|
7
|
-
import { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
|
|
9
|
+
import { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, isMergeRoute, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
|
|
8
10
|
import { NestedRefScopeError, WithRefOptions, getCurrentRefScope, getRefScopedDb, isInRefScope, withRef } from "./ref-scope.js";
|
|
11
|
+
import { ResolutionValidationError, applyResolutions } from "./resolve-conflicts.js";
|
|
9
12
|
import { EnsureSchemaSyncOptions, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, areBranchesSchemaCompatible, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getSchemaDiff, hasSchemaDifferences, hasUncommittedChanges, isLocalhostUrl, syncSchemaFromMain } from "./schema-sync.js";
|
|
10
|
-
export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, EnsureSchemaSyncOptions, GetBranchParams, MAIN_BRANCH_SUFFIX, NestedRefScopeError, RefContext, RefMiddlewareOptions, RefType, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, WithRefOptions, areBranchesSchemaCompatible, branchScopes, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, isInRefScope, isLocalhostUrl, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, refMiddlewareFactory, resolveProjectMainRefs, resolveRef, syncSchemaFromMain, withRef, writeProtectionMiddlewareFactory };
|
|
13
|
+
export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, EnsureSchemaSyncOptions, GetBranchParams, MAIN_BRANCH_SUFFIX, MergeConflictError, NestedRefScopeError, PkMap, RefContext, RefMiddlewareOptions, RefType, ResolutionValidationError, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, WithRefOptions, applyResolutions, areBranchesSchemaCompatible, branchScopes, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTempBranchSuffix, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, invalidBranchParamsError, isInRefScope, isLocalhostUrl, isMergeRoute, isProtectedBranchName, isRefWritable, isTempBranchName, isValidCommitHash, isValidManageTable, listBranches, listBranchesForAgent, managePkMap, refMiddlewareFactory, releaseAdvisoryLock, resolveProjectMainRefs, resolveRef, syncSchemaFromMain, syncSchemaOnBranch, tryAdvisoryLock, withRef, writeProtectionMiddlewareFactory };
|
package/dist/dolt/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { doltAdd, doltAddAndCommit, doltCommit, doltDeleteTag, doltHashOf, doltListTags, doltLog, doltReset, doltStatus, doltTag } from "./commit.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isValidManageTable, managePkMap } from "./pk-map.js";
|
|
3
|
+
import { ResolutionValidationError, applyResolutions } from "./resolve-conflicts.js";
|
|
4
|
+
import { MergeConflictError, doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts } from "./merge.js";
|
|
3
5
|
import { SCHEMA_SOURCE_BRANCH, areBranchesSchemaCompatible, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getSchemaDiff, hasSchemaDifferences, hasUncommittedChanges, isLocalhostUrl, syncSchemaFromMain } from "./schema-sync.js";
|
|
4
|
-
import { MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent } from "./branches-api.js";
|
|
6
|
+
import { MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTempBranchSuffix, getTenantMainBranch, invalidBranchParamsError, isProtectedBranchName, isTempBranchName, listBranches, listBranchesForAgent, syncSchemaOnBranch } from "./branches-api.js";
|
|
5
7
|
import { checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveProjectMainRefs, resolveRef } from "./ref-helpers.js";
|
|
6
8
|
import { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists } from "./branch.js";
|
|
9
|
+
import { releaseAdvisoryLock, tryAdvisoryLock } from "./advisory-lock.js";
|
|
7
10
|
import { doltDiff, doltDiffSummary } from "./diff.js";
|
|
8
|
-
import { createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
|
|
11
|
+
import { createRefMiddleware, createWriteProtectionMiddleware, isMergeRoute, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
|
|
9
12
|
import { NestedRefScopeError, getCurrentRefScope, getRefScopedDb, isInRefScope, withRef } from "./ref-scope.js";
|
|
10
13
|
|
|
11
|
-
export { MAIN_BRANCH_SUFFIX, NestedRefScopeError, SCHEMA_SOURCE_BRANCH, areBranchesSchemaCompatible, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, isInRefScope, isLocalhostUrl, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, refMiddlewareFactory, resolveProjectMainRefs, resolveRef, syncSchemaFromMain, withRef, writeProtectionMiddlewareFactory };
|
|
14
|
+
export { MAIN_BRANCH_SUFFIX, MergeConflictError, NestedRefScopeError, ResolutionValidationError, SCHEMA_SOURCE_BRANCH, applyResolutions, areBranchesSchemaCompatible, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTempBranchSuffix, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, invalidBranchParamsError, isInRefScope, isLocalhostUrl, isMergeRoute, isProtectedBranchName, isRefWritable, isTempBranchName, isValidCommitHash, isValidManageTable, listBranches, listBranchesForAgent, managePkMap, refMiddlewareFactory, releaseAdvisoryLock, resolveProjectMainRefs, resolveRef, syncSchemaFromMain, syncSchemaOnBranch, tryAdvisoryLock, withRef, writeProtectionMiddlewareFactory };
|
package/dist/dolt/merge.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
+
import { ConflictResolution } from "../validation/dolt-schemas.js";
|
|
1
2
|
import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
2
3
|
|
|
3
4
|
//#region src/dolt/merge.d.ts
|
|
4
|
-
|
|
5
|
+
declare class MergeConflictError extends Error {
|
|
6
|
+
readonly conflictCount: number;
|
|
7
|
+
readonly fromBranch: string;
|
|
8
|
+
readonly toBranch: string;
|
|
9
|
+
constructor(message: string, conflictCount: number, fromBranch: string, toBranch: string);
|
|
10
|
+
}
|
|
5
11
|
/**
|
|
6
|
-
* Merge
|
|
7
|
-
*
|
|
12
|
+
* Merge a branch into the currently checked out branch.
|
|
13
|
+
*
|
|
14
|
+
* Runs inside an explicit transaction so that conflicts and
|
|
15
|
+
* constraint-violations are surfaced to the caller instead of being
|
|
16
|
+
* auto-rolled-back by Dolt's AUTOCOMMIT mode.
|
|
17
|
+
*
|
|
18
|
+
* If conflicts arise and `resolutions` are provided, they are applied
|
|
19
|
+
* and the merge is committed. If conflicts arise without resolutions
|
|
20
|
+
* (or with insufficient resolutions), the transaction is rolled back
|
|
21
|
+
* and a `MergeConflictError` is thrown.
|
|
8
22
|
*/
|
|
9
23
|
declare const doltMerge: (db: AgentsManageDatabaseClient) => (params: {
|
|
10
24
|
fromBranch: string;
|
|
@@ -15,8 +29,9 @@ declare const doltMerge: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
15
29
|
name: string;
|
|
16
30
|
email: string;
|
|
17
31
|
};
|
|
32
|
+
resolutions?: ConflictResolution[];
|
|
18
33
|
}) => Promise<{
|
|
19
|
-
status: "success"
|
|
34
|
+
status: "success";
|
|
20
35
|
from: string;
|
|
21
36
|
to: string;
|
|
22
37
|
toHead?: string;
|
|
@@ -52,6 +67,27 @@ declare const doltTableConflicts: (db: AgentsManageDatabaseClient) => (params: {
|
|
|
52
67
|
* Get schema conflicts
|
|
53
68
|
*/
|
|
54
69
|
declare const doltSchemaConflicts: (db: AgentsManageDatabaseClient) => () => Promise<any[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Preview merge conflicts without modifying the database (dry-run).
|
|
72
|
+
* Returns a summary of which tables have conflicts.
|
|
73
|
+
*/
|
|
74
|
+
declare const doltPreviewMergeConflictsSummary: (db: AgentsManageDatabaseClient) => (params: {
|
|
75
|
+
baseBranch: string;
|
|
76
|
+
mergeBranch: string;
|
|
77
|
+
}) => Promise<{
|
|
78
|
+
table: string;
|
|
79
|
+
numDataConflicts: number;
|
|
80
|
+
numSchemaConflicts: number;
|
|
81
|
+
}[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Preview detailed merge conflicts for a specific table without modifying the database (dry-run).
|
|
84
|
+
* Returns the same column shape as dolt_conflicts_$table.
|
|
85
|
+
*/
|
|
86
|
+
declare const doltPreviewMergeConflicts: (db: AgentsManageDatabaseClient) => (params: {
|
|
87
|
+
baseBranch: string;
|
|
88
|
+
mergeBranch: string;
|
|
89
|
+
tableName: string;
|
|
90
|
+
}) => Promise<Record<string, unknown>[]>;
|
|
55
91
|
/**
|
|
56
92
|
* Resolve conflicts for a table using a strategy
|
|
57
93
|
*/
|
|
@@ -60,4 +96,4 @@ declare const doltResolveConflicts: (db: AgentsManageDatabaseClient) => (params:
|
|
|
60
96
|
strategy: "ours" | "theirs";
|
|
61
97
|
}) => Promise<void>;
|
|
62
98
|
//#endregion
|
|
63
|
-
export { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
|
99
|
+
export { MergeConflictError, doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
package/dist/dolt/merge.js
CHANGED
|
@@ -1,36 +1,150 @@
|
|
|
1
|
+
import { getLogger } from "../utils/logger.js";
|
|
2
|
+
import { doltAddAndCommit } from "./commit.js";
|
|
3
|
+
import { createApiError } from "../utils/error.js";
|
|
4
|
+
import { managePkMap } from "./pk-map.js";
|
|
5
|
+
import { ResolutionValidationError, applyResolutions } from "./resolve-conflicts.js";
|
|
1
6
|
import { doltCheckout } from "./branch.js";
|
|
2
7
|
import { sql } from "drizzle-orm";
|
|
3
8
|
|
|
4
9
|
//#region src/dolt/merge.ts
|
|
10
|
+
const logger = getLogger("dolt-merge");
|
|
11
|
+
const TIMESTAMP_COLUMNS = new Set(["created_at", "updated_at"]);
|
|
12
|
+
var MergeConflictError = class extends Error {
|
|
13
|
+
constructor(message, conflictCount, fromBranch, toBranch) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.conflictCount = conflictCount;
|
|
16
|
+
this.fromBranch = fromBranch;
|
|
17
|
+
this.toBranch = toBranch;
|
|
18
|
+
this.name = "MergeConflictError";
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
function extractConflictCount(row) {
|
|
22
|
+
if (typeof row.conflicts === "number" || typeof row.conflicts === "string") return Number(row.conflicts);
|
|
23
|
+
const doltMerge$1 = row.dolt_merge;
|
|
24
|
+
if (Array.isArray(doltMerge$1)) return Number(doltMerge$1[2] ?? 0);
|
|
25
|
+
throw new Error(`Unexpected DOLT_MERGE result format: ${JSON.stringify(row)}`);
|
|
26
|
+
}
|
|
27
|
+
function isTimestampOnlyConflictRow(row, pkColumns) {
|
|
28
|
+
if (row.our_diff_type !== "modified" || row.their_diff_type !== "modified") return false;
|
|
29
|
+
const pkSet = new Set(pkColumns);
|
|
30
|
+
for (const key of Object.keys(row)) {
|
|
31
|
+
if (!key.startsWith("base_")) continue;
|
|
32
|
+
const col = key.slice(5);
|
|
33
|
+
if (col === "diff_type" || pkSet.has(col) || TIMESTAMP_COLUMNS.has(col)) continue;
|
|
34
|
+
if (String(row[`base_${col}`] ?? "") !== String(row[`our_${col}`] ?? "") || String(row[`base_${col}`] ?? "") !== String(row[`their_${col}`] ?? "")) return false;
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
function buildTimestampAutoResolution(tableName, row, pkColumns) {
|
|
39
|
+
const primaryKey = {};
|
|
40
|
+
for (const col of pkColumns) primaryKey[col] = String(row[`base_${col}`] ?? row[`our_${col}`] ?? row[`their_${col}`]);
|
|
41
|
+
return {
|
|
42
|
+
table: tableName,
|
|
43
|
+
primaryKey,
|
|
44
|
+
rowDefaultPick: (row.our_updated_at ? new Date(String(row.our_updated_at)) : /* @__PURE__ */ new Date(0)) >= (row.their_updated_at ? new Date(String(row.their_updated_at)) : /* @__PURE__ */ new Date(0)) ? "ours" : "theirs"
|
|
45
|
+
};
|
|
46
|
+
}
|
|
5
47
|
/**
|
|
6
|
-
* Merge
|
|
7
|
-
*
|
|
48
|
+
* Merge a branch into the currently checked out branch.
|
|
49
|
+
*
|
|
50
|
+
* Runs inside an explicit transaction so that conflicts and
|
|
51
|
+
* constraint-violations are surfaced to the caller instead of being
|
|
52
|
+
* auto-rolled-back by Dolt's AUTOCOMMIT mode.
|
|
53
|
+
*
|
|
54
|
+
* If conflicts arise and `resolutions` are provided, they are applied
|
|
55
|
+
* and the merge is committed. If conflicts arise without resolutions
|
|
56
|
+
* (or with insufficient resolutions), the transaction is rolled back
|
|
57
|
+
* and a `MergeConflictError` is thrown.
|
|
8
58
|
*/
|
|
9
59
|
const doltMerge = (db) => async (params) => {
|
|
10
|
-
|
|
60
|
+
logger.info({
|
|
61
|
+
fromBranch: params.fromBranch,
|
|
62
|
+
toBranch: params.toBranch
|
|
63
|
+
}, "Merging branch");
|
|
11
64
|
await doltCheckout(db)({ branch: params.toBranch });
|
|
12
65
|
const toHead = (await db.execute(sql`SELECT HASHOF('HEAD') as hash`)).rows[0]?.hash;
|
|
13
|
-
const args = [`'${params.fromBranch}'`];
|
|
66
|
+
const args = [`'${params.fromBranch.replace(/'/g, "''")}'`];
|
|
14
67
|
if (params.noFastForward) args.push("'--no-ff'");
|
|
15
|
-
if (params.message)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
68
|
+
if (params.message) {
|
|
69
|
+
const cleanedMessage = params.message.replace(/'/g, "''");
|
|
70
|
+
args.push("'-m'", `'${cleanedMessage}'`);
|
|
71
|
+
}
|
|
72
|
+
const cleanedAuthor = params.author?.name?.replace(/'/g, "''");
|
|
73
|
+
const cleanedEmail = params.author?.email?.replace(/'/g, "''");
|
|
74
|
+
if (params.author) args.push("'--author'", `'${cleanedAuthor} <${cleanedEmail}>'`);
|
|
75
|
+
await db.execute(sql.raw("START TRANSACTION"));
|
|
76
|
+
let txFinalized = false;
|
|
77
|
+
try {
|
|
78
|
+
let result;
|
|
79
|
+
try {
|
|
80
|
+
result = await db.execute(sql.raw(`SELECT DOLT_MERGE(${args.join(", ")})`));
|
|
81
|
+
logger.info({ result }, "DOLT_MERGE result");
|
|
82
|
+
} catch (error) {
|
|
83
|
+
const cause = error?.cause;
|
|
84
|
+
logger.error({
|
|
85
|
+
message: error?.message,
|
|
86
|
+
code: cause?.code,
|
|
87
|
+
severity: cause?.severity,
|
|
88
|
+
detail: cause?.detail,
|
|
89
|
+
hint: cause?.hint,
|
|
90
|
+
query: error?.query,
|
|
91
|
+
fromBranch: params.fromBranch,
|
|
92
|
+
toBranch: params.toBranch
|
|
93
|
+
}, "Error merging branch");
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
const conflicts = extractConflictCount(result.rows[0] ?? {});
|
|
97
|
+
if (Number.isFinite(conflicts) && conflicts > 0) {
|
|
98
|
+
const userResolutions = params.resolutions ?? [];
|
|
99
|
+
const autoResolutions = [];
|
|
100
|
+
const conflictTables = await doltConflicts(db)();
|
|
101
|
+
let manualConflicts = 0;
|
|
102
|
+
for (const ct of conflictTables) {
|
|
103
|
+
const tableConflicts = await doltTableConflicts(db)({ tableName: ct.table });
|
|
104
|
+
const pkColumns = managePkMap[ct.table] ?? [];
|
|
105
|
+
for (const row of tableConflicts) if (isTimestampOnlyConflictRow(row, pkColumns)) autoResolutions.push(buildTimestampAutoResolution(ct.table, row, pkColumns));
|
|
106
|
+
else manualConflicts++;
|
|
107
|
+
}
|
|
108
|
+
if (manualConflicts > 0 && userResolutions.length < manualConflicts) throw new MergeConflictError(manualConflicts > 0 && userResolutions.length === 0 ? "Merge has conflicts but no resolutions were provided." : `Resolutions provided (${userResolutions.length}) do not cover all conflicts (${manualConflicts}). All conflicts must be resolved.`, manualConflicts, params.fromBranch, params.toBranch);
|
|
109
|
+
const allResolutions = [...autoResolutions, ...userResolutions];
|
|
110
|
+
try {
|
|
111
|
+
await applyResolutions(db)(allResolutions);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error instanceof ResolutionValidationError) throw createApiError({
|
|
114
|
+
code: "bad_request",
|
|
115
|
+
message: `Invalid resolution: ${error.message}`
|
|
116
|
+
});
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
await doltAddAndCommit(db)({
|
|
120
|
+
message: params.message ? `${params.message} (with conflict resolution)` : `Merge ${params.fromBranch} into ${params.toBranch} (with conflict resolution)`,
|
|
121
|
+
author: params.author
|
|
122
|
+
});
|
|
123
|
+
txFinalized = true;
|
|
124
|
+
return {
|
|
125
|
+
status: "success",
|
|
126
|
+
from: params.fromBranch,
|
|
127
|
+
to: params.toBranch,
|
|
128
|
+
toHead,
|
|
129
|
+
hasConflicts: true
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
await db.execute(sql.raw("COMMIT"));
|
|
133
|
+
txFinalized = true;
|
|
134
|
+
return {
|
|
135
|
+
status: "success",
|
|
136
|
+
from: params.fromBranch,
|
|
137
|
+
to: params.toBranch,
|
|
138
|
+
toHead,
|
|
139
|
+
hasConflicts: false
|
|
140
|
+
};
|
|
141
|
+
} finally {
|
|
142
|
+
if (!txFinalized) try {
|
|
143
|
+
await db.execute(sql.raw("ROLLBACK"));
|
|
144
|
+
} catch (rollbackError) {
|
|
145
|
+
logger.error({ error: rollbackError }, "Failed to rollback transaction");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
34
148
|
};
|
|
35
149
|
/**
|
|
36
150
|
* Abort a merge
|
|
@@ -70,6 +184,29 @@ const doltSchemaConflicts = (db) => async () => {
|
|
|
70
184
|
return (await db.execute(sql`SELECT * FROM dolt_schema_conflicts`)).rows;
|
|
71
185
|
};
|
|
72
186
|
/**
|
|
187
|
+
* Preview merge conflicts without modifying the database (dry-run).
|
|
188
|
+
* Returns a summary of which tables have conflicts.
|
|
189
|
+
*/
|
|
190
|
+
const doltPreviewMergeConflictsSummary = (db) => async (params) => {
|
|
191
|
+
const escapedBaseBranch = params.baseBranch.replace(/'/g, "''");
|
|
192
|
+
const escapedMergeBranch = params.mergeBranch.replace(/'/g, "''");
|
|
193
|
+
return (await db.execute(sql.raw(`SELECT * FROM DOLT_PREVIEW_MERGE_CONFLICTS_SUMMARY('${escapedBaseBranch}', '${escapedMergeBranch}')`))).rows.map((row) => ({
|
|
194
|
+
table: row.table.replace("public.", ""),
|
|
195
|
+
numDataConflicts: Number(row.num_data_conflicts ?? 0),
|
|
196
|
+
numSchemaConflicts: Number(row.num_schema_conflicts ?? 0)
|
|
197
|
+
}));
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Preview detailed merge conflicts for a specific table without modifying the database (dry-run).
|
|
201
|
+
* Returns the same column shape as dolt_conflicts_$table.
|
|
202
|
+
*/
|
|
203
|
+
const doltPreviewMergeConflicts = (db) => async (params) => {
|
|
204
|
+
const escapedBaseBranch = params.baseBranch.replace(/'/g, "''");
|
|
205
|
+
const escapedMergeBranch = params.mergeBranch.replace(/'/g, "''");
|
|
206
|
+
const escapedTableName = params.tableName.replace(/'/g, "''");
|
|
207
|
+
return (await db.execute(sql.raw(`SELECT * FROM DOLT_PREVIEW_MERGE_CONFLICTS('${escapedBaseBranch}', '${escapedMergeBranch}', '${escapedTableName}')`))).rows;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
73
210
|
* Resolve conflicts for a table using a strategy
|
|
74
211
|
*/
|
|
75
212
|
const doltResolveConflicts = (db) => async (params) => {
|
|
@@ -78,4 +215,4 @@ const doltResolveConflicts = (db) => async (params) => {
|
|
|
78
215
|
};
|
|
79
216
|
|
|
80
217
|
//#endregion
|
|
81
|
-
export { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
|
218
|
+
export { MergeConflictError, doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltPreviewMergeConflicts, doltPreviewMergeConflictsSummary, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { manage_schema_exports } from "../db/manage/manage-schema.js";
|
|
2
|
+
import { getTableConfig } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
//#region src/dolt/pk-map.ts
|
|
5
|
+
function buildPkMapFromSchema() {
|
|
6
|
+
const pkMap = {};
|
|
7
|
+
for (const value of Object.values(manage_schema_exports)) {
|
|
8
|
+
if (value == null || typeof value !== "object") continue;
|
|
9
|
+
let config;
|
|
10
|
+
try {
|
|
11
|
+
config = getTableConfig(value);
|
|
12
|
+
} catch {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (!config?.name || !config.primaryKeys?.length) continue;
|
|
16
|
+
const pkColumns = config.primaryKeys[0]?.columns.map((col) => col.name);
|
|
17
|
+
if (pkColumns && pkColumns.length > 0) pkMap[config.name] = pkColumns;
|
|
18
|
+
}
|
|
19
|
+
return pkMap;
|
|
20
|
+
}
|
|
21
|
+
const managePkMap = buildPkMapFromSchema();
|
|
22
|
+
const isValidManageTable = (tableName) => {
|
|
23
|
+
return tableName in managePkMap;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { isValidManageTable, managePkMap };
|
|
@@ -3,6 +3,7 @@ import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
|
3
3
|
import { Context, Next } from "hono";
|
|
4
4
|
|
|
5
5
|
//#region src/dolt/ref-middleware.d.ts
|
|
6
|
+
declare function isMergeRoute(path: string): boolean;
|
|
6
7
|
type RefContext = {
|
|
7
8
|
resolvedRef?: ResolvedRef;
|
|
8
9
|
};
|
|
@@ -79,4 +80,4 @@ declare const refMiddlewareFactory: (db: AgentsManageDatabaseClient, options?: R
|
|
|
79
80
|
*/
|
|
80
81
|
declare const writeProtectionMiddlewareFactory: () => (c: Context, next: Next) => Promise<void>;
|
|
81
82
|
//#endregion
|
|
82
|
-
export { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory };
|
|
83
|
+
export { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, isMergeRoute, refMiddlewareFactory, writeProtectionMiddlewareFactory };
|