@tinycloud/sdk-services 2.4.0-beta.1 → 2.4.0-beta.8
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/index.cjs +68 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +68 -30
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs +28 -21
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +12 -0
- package/dist/kv/index.d.ts +12 -0
- package/dist/kv/index.js +28 -21
- package/dist/kv/index.js.map +1 -1
- package/dist/sql/index.cjs +40 -9
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.d.cts +4 -1
- package/dist/sql/index.d.ts +4 -1
- package/dist/sql/index.js +40 -9
- package/dist/sql/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -983,6 +983,31 @@ var KVService = class extends BaseService {
|
|
|
983
983
|
}
|
|
984
984
|
return void 0;
|
|
985
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* Classify a KV 404 by reading the response body once.
|
|
988
|
+
*
|
|
989
|
+
* The server returns 404 both for a genuinely missing key AND for an
|
|
990
|
+
* un-hosted space (body "Space not found"). Previously get/head/delete
|
|
991
|
+
* collapsed every 404 to KV_NOT_FOUND before reading the body, so an
|
|
992
|
+
* un-hosted-space read was indistinguishable from a missing key. We now
|
|
993
|
+
* preserve status + the "Space not found" body for the un-hosted case (so the
|
|
994
|
+
* CLI/SDK can normalize it to SPACE_NOT_HOSTED, matching put/list/sql), and
|
|
995
|
+
* fall through to KV_NOT_FOUND for a real missing key.
|
|
996
|
+
*/
|
|
997
|
+
async classifyNotFound(response, key) {
|
|
998
|
+
const errorText = await response.text();
|
|
999
|
+
if (/space not found/i.test(errorText)) {
|
|
1000
|
+
return err(
|
|
1001
|
+
serviceError(
|
|
1002
|
+
ErrorCodes.KV_NOT_FOUND,
|
|
1003
|
+
`KV ${response.status} - ${errorText}`,
|
|
1004
|
+
"kv",
|
|
1005
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
1006
|
+
)
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
return err(serviceError(ErrorCodes.KV_NOT_FOUND, `Key not found: ${key}`, "kv"));
|
|
1010
|
+
}
|
|
986
1011
|
/**
|
|
987
1012
|
* Get the full path with optional prefix.
|
|
988
1013
|
*
|
|
@@ -1229,13 +1254,7 @@ var KVService = class extends BaseService {
|
|
|
1229
1254
|
}));
|
|
1230
1255
|
}
|
|
1231
1256
|
if (response.status === 404) {
|
|
1232
|
-
return
|
|
1233
|
-
serviceError(
|
|
1234
|
-
ErrorCodes.KV_NOT_FOUND,
|
|
1235
|
-
`Key not found: ${key}`,
|
|
1236
|
-
"kv"
|
|
1237
|
-
)
|
|
1238
|
-
);
|
|
1257
|
+
return this.classifyNotFound(response, key);
|
|
1239
1258
|
}
|
|
1240
1259
|
const errorText = await response.text();
|
|
1241
1260
|
return err(
|
|
@@ -1496,13 +1515,7 @@ var KVService = class extends BaseService {
|
|
|
1496
1515
|
}));
|
|
1497
1516
|
}
|
|
1498
1517
|
if (response.status === 404) {
|
|
1499
|
-
return
|
|
1500
|
-
serviceError(
|
|
1501
|
-
ErrorCodes.KV_NOT_FOUND,
|
|
1502
|
-
`Key not found: ${key}`,
|
|
1503
|
-
"kv"
|
|
1504
|
-
)
|
|
1505
|
-
);
|
|
1518
|
+
return this.classifyNotFound(response, key);
|
|
1506
1519
|
}
|
|
1507
1520
|
const errorText = await response.text();
|
|
1508
1521
|
return err(
|
|
@@ -1547,13 +1560,7 @@ var KVService = class extends BaseService {
|
|
|
1547
1560
|
}));
|
|
1548
1561
|
}
|
|
1549
1562
|
if (response.status === 404) {
|
|
1550
|
-
return
|
|
1551
|
-
serviceError(
|
|
1552
|
-
ErrorCodes.KV_NOT_FOUND,
|
|
1553
|
-
`Key not found: ${key}`,
|
|
1554
|
-
"kv"
|
|
1555
|
-
)
|
|
1556
|
-
);
|
|
1563
|
+
return this.classifyNotFound(response, key);
|
|
1557
1564
|
}
|
|
1558
1565
|
const errorText = await response.text();
|
|
1559
1566
|
return err(
|
|
@@ -1707,6 +1714,7 @@ var DatabaseHandle = class {
|
|
|
1707
1714
|
var SQLAction = {
|
|
1708
1715
|
READ: "tinycloud.sql/read",
|
|
1709
1716
|
WRITE: "tinycloud.sql/write",
|
|
1717
|
+
DDL: "tinycloud.sql/ddl",
|
|
1710
1718
|
ADMIN: "tinycloud.sql/admin",
|
|
1711
1719
|
SELECT: "tinycloud.sql/select",
|
|
1712
1720
|
INSERT: "tinycloud.sql/insert",
|
|
@@ -1718,6 +1726,7 @@ var SQLAction = {
|
|
|
1718
1726
|
};
|
|
1719
1727
|
|
|
1720
1728
|
// src/sql/SQLService.ts
|
|
1729
|
+
var DDL_TOKENS = /* @__PURE__ */ new Set(["alter", "create", "drop"]);
|
|
1721
1730
|
var SQLService = class extends BaseService {
|
|
1722
1731
|
constructor(config = {}) {
|
|
1723
1732
|
super();
|
|
@@ -1793,9 +1802,15 @@ var SQLService = class extends BaseService {
|
|
|
1793
1802
|
if (options?.schema) {
|
|
1794
1803
|
body.schema = options.schema;
|
|
1795
1804
|
}
|
|
1805
|
+
const actions = [
|
|
1806
|
+
this.actionForSql(sql, SQLAction.WRITE),
|
|
1807
|
+
...(options?.schema ?? []).map(
|
|
1808
|
+
(statement) => this.actionForSql(statement, SQLAction.DDL)
|
|
1809
|
+
)
|
|
1810
|
+
];
|
|
1796
1811
|
const response = await this.invokeSQL(
|
|
1797
1812
|
dbName,
|
|
1798
|
-
this.
|
|
1813
|
+
this.dedupeActions(actions),
|
|
1799
1814
|
body,
|
|
1800
1815
|
options?.signal
|
|
1801
1816
|
);
|
|
@@ -1817,7 +1832,7 @@ var SQLService = class extends BaseService {
|
|
|
1817
1832
|
try {
|
|
1818
1833
|
const response = await this.invokeSQL(
|
|
1819
1834
|
dbName,
|
|
1820
|
-
this.
|
|
1835
|
+
this.actionsForSqlBatch(statements),
|
|
1821
1836
|
{ action: "batch", statements },
|
|
1822
1837
|
options?.signal
|
|
1823
1838
|
);
|
|
@@ -1881,9 +1896,10 @@ var SQLService = class extends BaseService {
|
|
|
1881
1896
|
});
|
|
1882
1897
|
}
|
|
1883
1898
|
// === Private helpers ===
|
|
1884
|
-
async invokeSQL(dbName,
|
|
1899
|
+
async invokeSQL(dbName, actions, body, signal) {
|
|
1885
1900
|
const session = this.context.session;
|
|
1886
|
-
const
|
|
1901
|
+
const actionList = Array.isArray(actions) ? actions : [actions];
|
|
1902
|
+
const headers = actionList.length === 1 ? this.context.invoke(session, "sql", dbName, actionList[0]) : this.invokeSQLAny(session, dbName, actionList);
|
|
1887
1903
|
return this.context.fetch(`${this.host}/invoke`, {
|
|
1888
1904
|
method: "POST",
|
|
1889
1905
|
headers: {
|
|
@@ -1895,12 +1911,34 @@ var SQLService = class extends BaseService {
|
|
|
1895
1911
|
});
|
|
1896
1912
|
}
|
|
1897
1913
|
actionForSql(sql, fallback) {
|
|
1898
|
-
|
|
1914
|
+
const token = firstSqlToken(sql);
|
|
1915
|
+
if (token === "pragma") return SQLAction.ADMIN;
|
|
1916
|
+
if (token !== void 0 && DDL_TOKENS.has(token)) return SQLAction.DDL;
|
|
1917
|
+
return fallback;
|
|
1918
|
+
}
|
|
1919
|
+
actionsForSqlBatch(statements) {
|
|
1920
|
+
return this.dedupeActions(
|
|
1921
|
+
statements.map((statement) => this.actionForSql(statement.sql, SQLAction.WRITE))
|
|
1922
|
+
);
|
|
1899
1923
|
}
|
|
1900
|
-
|
|
1901
|
-
return
|
|
1902
|
-
|
|
1903
|
-
|
|
1924
|
+
dedupeActions(actions) {
|
|
1925
|
+
return [...new Set(actions)];
|
|
1926
|
+
}
|
|
1927
|
+
invokeSQLAny(session, dbName, actions) {
|
|
1928
|
+
if (!this.context.invokeAny) {
|
|
1929
|
+
throw new Error(
|
|
1930
|
+
`SQL operation requires multiple permissions (${actions.join(", ")}) but this SDK runtime does not support multi-resource invocations`
|
|
1931
|
+
);
|
|
1932
|
+
}
|
|
1933
|
+
return this.context.invokeAny(
|
|
1934
|
+
session,
|
|
1935
|
+
actions.map((action) => ({
|
|
1936
|
+
spaceId: session.spaceId,
|
|
1937
|
+
service: "sql",
|
|
1938
|
+
path: dbName,
|
|
1939
|
+
action
|
|
1940
|
+
}))
|
|
1941
|
+
);
|
|
1904
1942
|
}
|
|
1905
1943
|
async handleErrorResponse(response, operation) {
|
|
1906
1944
|
const errorText = await response.text();
|