@hasna/cloud 0.1.27 → 0.1.29
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/cli/index.js +8 -6
- package/dist/index.js +14 -7
- package/dist/mcp/index.js +8 -6
- package/dist/mcp-helpers.d.ts +7 -2
- package/dist/mcp-helpers.d.ts.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -11838,9 +11838,9 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
11838
11838
|
const batch = rows.slice(offset, offset + batchSize);
|
|
11839
11839
|
try {
|
|
11840
11840
|
if (isAsyncAdapter(target)) {
|
|
11841
|
-
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
|
|
11841
|
+
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
11842
11842
|
} else {
|
|
11843
|
-
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
|
|
11843
|
+
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
11844
11844
|
}
|
|
11845
11845
|
result.rowsWritten += batch.length;
|
|
11846
11846
|
} catch (err) {
|
|
@@ -11887,7 +11887,7 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
11887
11887
|
}
|
|
11888
11888
|
return results;
|
|
11889
11889
|
}
|
|
11890
|
-
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
|
|
11890
|
+
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
11891
11891
|
if (batch.length === 0)
|
|
11892
11892
|
return;
|
|
11893
11893
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
@@ -11897,20 +11897,22 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
|
|
|
11897
11897
|
}).join(", ");
|
|
11898
11898
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
11899
11899
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
11900
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
11900
11901
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
11901
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
11902
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
11902
11903
|
const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
|
|
11903
11904
|
await target.run(sql, ...params);
|
|
11904
11905
|
}
|
|
11905
|
-
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
|
|
11906
|
+
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
11906
11907
|
if (batch.length === 0)
|
|
11907
11908
|
return;
|
|
11908
11909
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
11909
11910
|
const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
|
|
11910
11911
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
11911
11912
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
11913
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
11912
11914
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
11913
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
11915
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
11914
11916
|
const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
|
|
11915
11917
|
target.run(sql, ...params);
|
|
11916
11918
|
}
|
package/dist/index.js
CHANGED
|
@@ -9766,9 +9766,9 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
9766
9766
|
const batch = rows.slice(offset, offset + batchSize);
|
|
9767
9767
|
try {
|
|
9768
9768
|
if (isAsyncAdapter(target)) {
|
|
9769
|
-
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
|
|
9769
|
+
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
9770
9770
|
} else {
|
|
9771
|
-
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
|
|
9771
|
+
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
9772
9772
|
}
|
|
9773
9773
|
result.rowsWritten += batch.length;
|
|
9774
9774
|
} catch (err) {
|
|
@@ -9815,7 +9815,7 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
9815
9815
|
}
|
|
9816
9816
|
return results;
|
|
9817
9817
|
}
|
|
9818
|
-
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
|
|
9818
|
+
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
9819
9819
|
if (batch.length === 0)
|
|
9820
9820
|
return;
|
|
9821
9821
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
@@ -9825,20 +9825,22 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
|
|
|
9825
9825
|
}).join(", ");
|
|
9826
9826
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
9827
9827
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
9828
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
9828
9829
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
9829
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
9830
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
9830
9831
|
const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
|
|
9831
9832
|
await target.run(sql, ...params);
|
|
9832
9833
|
}
|
|
9833
|
-
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
|
|
9834
|
+
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
9834
9835
|
if (batch.length === 0)
|
|
9835
9836
|
return;
|
|
9836
9837
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
9837
9838
|
const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
|
|
9838
9839
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
9839
9840
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
9841
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
9840
9842
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
9841
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
9843
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
9842
9844
|
const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
|
|
9843
9845
|
target.run(sql, ...params);
|
|
9844
9846
|
}
|
|
@@ -10973,7 +10975,7 @@ init_zod();
|
|
|
10973
10975
|
init_config();
|
|
10974
10976
|
init_dotfile();
|
|
10975
10977
|
init_adapter();
|
|
10976
|
-
function registerCloudTools(server, serviceName) {
|
|
10978
|
+
function registerCloudTools(server, serviceName, opts = {}) {
|
|
10977
10979
|
server.tool(`${serviceName}_cloud_status`, "Show cloud configuration and connection health", {}, async () => {
|
|
10978
10980
|
const config = getCloudConfig();
|
|
10979
10981
|
const lines = [
|
|
@@ -11008,6 +11010,11 @@ function registerCloudTools(server, serviceName) {
|
|
|
11008
11010
|
}
|
|
11009
11011
|
const local = new SqliteAdapter(getDbPath(serviceName));
|
|
11010
11012
|
const cloud = new PgAdapterAsync(getConnectionString(serviceName));
|
|
11013
|
+
if (opts.migrations?.length) {
|
|
11014
|
+
for (const sql of opts.migrations) {
|
|
11015
|
+
await cloud.run(sql);
|
|
11016
|
+
}
|
|
11017
|
+
}
|
|
11011
11018
|
const tableList = tablesStr ? tablesStr.split(",").map((t) => t.trim()) : listSqliteTables(local);
|
|
11012
11019
|
const results = await syncPush(local, cloud, { tables: tableList });
|
|
11013
11020
|
local.close();
|
package/dist/mcp/index.js
CHANGED
|
@@ -25491,9 +25491,9 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
25491
25491
|
const batch = rows.slice(offset, offset + batchSize);
|
|
25492
25492
|
try {
|
|
25493
25493
|
if (isAsyncAdapter(target)) {
|
|
25494
|
-
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch);
|
|
25494
|
+
await batchUpsertPg(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
25495
25495
|
} else {
|
|
25496
|
-
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch);
|
|
25496
|
+
batchUpsertSqlite(target, table, columns, updateCols, pkColumns, batch, columns.includes(conflictColumn) ? conflictColumn : undefined);
|
|
25497
25497
|
}
|
|
25498
25498
|
result.rowsWritten += batch.length;
|
|
25499
25499
|
} catch (err) {
|
|
@@ -25540,7 +25540,7 @@ async function syncTransfer(source, target, options, _direction) {
|
|
|
25540
25540
|
}
|
|
25541
25541
|
return results;
|
|
25542
25542
|
}
|
|
25543
|
-
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch) {
|
|
25543
|
+
async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
25544
25544
|
if (batch.length === 0)
|
|
25545
25545
|
return;
|
|
25546
25546
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
@@ -25550,20 +25550,22 @@ async function batchUpsertPg(target, table, columns, updateCols, primaryKeys, ba
|
|
|
25550
25550
|
}).join(", ");
|
|
25551
25551
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
25552
25552
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
25553
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
25553
25554
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
25554
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
25555
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
25555
25556
|
const params = batch.flatMap((row) => columns.map((c) => row[c] ?? null));
|
|
25556
25557
|
await target.run(sql, ...params);
|
|
25557
25558
|
}
|
|
25558
|
-
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch) {
|
|
25559
|
+
function batchUpsertSqlite(target, table, columns, updateCols, primaryKeys, batch, conflictColumn) {
|
|
25559
25560
|
if (batch.length === 0)
|
|
25560
25561
|
return;
|
|
25561
25562
|
const colList = columns.map((c) => `"${c}"`).join(", ");
|
|
25562
25563
|
const valuePlaceholders = batch.map(() => `(${columns.map(() => "?").join(", ")})`).join(", ");
|
|
25563
25564
|
const pkList = primaryKeys.map((c) => `"${c}"`).join(", ");
|
|
25564
25565
|
const setClause = updateCols.length > 0 ? updateCols.map((c) => `"${c}" = EXCLUDED."${c}"`).join(", ") : `"${primaryKeys[0]}" = EXCLUDED."${primaryKeys[0]}"`;
|
|
25566
|
+
const whereClause = conflictColumn && updateCols.includes(conflictColumn) ? ` WHERE "${table}"."${conflictColumn}" IS NULL OR EXCLUDED."${conflictColumn}" >= "${table}"."${conflictColumn}"` : "";
|
|
25565
25567
|
const sql = `INSERT INTO "${table}" (${colList}) VALUES ${valuePlaceholders}
|
|
25566
|
-
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}`;
|
|
25568
|
+
ON CONFLICT (${pkList}) DO UPDATE SET ${setClause}${whereClause}`;
|
|
25567
25569
|
const params = batch.flatMap((row) => columns.map((c) => coerceForSqlite(row[c])));
|
|
25568
25570
|
target.run(sql, ...params);
|
|
25569
25571
|
}
|
package/dist/mcp-helpers.d.ts
CHANGED
|
@@ -3,14 +3,19 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
* Register cloud-related MCP tools onto an existing MCP server.
|
|
4
4
|
* Services call this to embed cloud sync/feedback tools into their own MCP server.
|
|
5
5
|
*
|
|
6
|
+
* @param migrations - Optional list of SQL statements to run against PG before pushing.
|
|
7
|
+
* Use this to ensure the cloud schema exists (CREATE TABLE IF NOT EXISTS ...).
|
|
8
|
+
*
|
|
6
9
|
* @example
|
|
7
10
|
* ```ts
|
|
8
11
|
* import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
12
|
* import { registerCloudTools } from "@hasna/cloud";
|
|
10
13
|
*
|
|
11
14
|
* const server = new McpServer({ name: "my-service", version: "0.1.0" });
|
|
12
|
-
* registerCloudTools(server, "my-service");
|
|
15
|
+
* registerCloudTools(server, "my-service", { migrations: PG_MIGRATIONS });
|
|
13
16
|
* ```
|
|
14
17
|
*/
|
|
15
|
-
export declare function registerCloudTools(server: McpServer, serviceName: string
|
|
18
|
+
export declare function registerCloudTools(server: McpServer, serviceName: string, opts?: {
|
|
19
|
+
migrations?: string[];
|
|
20
|
+
}): void;
|
|
16
21
|
//# sourceMappingURL=mcp-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-helpers.d.ts","sourceRoot":"","sources":["../src/mcp-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE
|
|
1
|
+
{"version":3,"file":"mcp-helpers.d.ts","sourceRoot":"","sources":["../src/mcp-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GACnC,IAAI,CA2JN"}
|
package/dist/sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kCAAkC;IAClC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kCAAkC;IAClC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;AAMD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE,CAAC,CAGvB;AAsvBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,CAKxD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKxE"}
|
package/package.json
CHANGED