@mathrunet/masamune_cloudflare_turso 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +363 -0
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/functions/test.d.ts +1 -0
- package/dist/functions/test.js +71 -0
- package/dist/functions/test.js.map +1 -0
- package/dist/functions/turso.d.ts +1 -0
- package/dist/functions/turso.js +50 -0
- package/dist/functions/turso.js.map +1 -0
- package/dist/functions/turso_token.d.ts +1 -0
- package/dist/functions/turso_token.js +40 -0
- package/dist/functions/turso_token.js.map +1 -0
- package/dist/functions.d.ts +21 -0
- package/dist/functions.js +24 -0
- package/dist/functions.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +183 -0
- package/dist/lib/api.js +144 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/crud.d.ts +10 -0
- package/dist/lib/crud.js +203 -0
- package/dist/lib/crud.js.map +1 -0
- package/dist/lib/exntensions/firestore.extension.d.ts +247 -0
- package/dist/lib/exntensions/firestore.extension.js +386 -0
- package/dist/lib/exntensions/firestore.extension.js.map +1 -0
- package/dist/lib/exntensions/string.extension.d.ts +214 -0
- package/dist/lib/exntensions/string.extension.js +223 -0
- package/dist/lib/exntensions/string.extension.js.map +1 -0
- package/dist/lib/model_field_value/converters/basic_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/basic_converter.js +51 -0
- package/dist/lib/model_field_value/converters/basic_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/enum_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/enum_converter.js +51 -0
- package/dist/lib/model_field_value/converters/enum_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_counter_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_counter_converter.js +216 -0
- package/dist/lib/model_field_value/converters/model_counter_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_date_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_date_converter.js +271 -0
- package/dist/lib/model_field_value/converters/model_date_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_date_range_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_date_range_converter.js +225 -0
- package/dist/lib/model_field_value/converters/model_date_range_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_geo_value_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_geo_value_converter.js +216 -0
- package/dist/lib/model_field_value/converters/model_geo_value_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_image_uri_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_image_uri_converter.js +184 -0
- package/dist/lib/model_field_value/converters/model_image_uri_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_locale_converter.d.ts +51 -0
- package/dist/lib/model_field_value/converters/model_locale_converter.js +228 -0
- package/dist/lib/model_field_value/converters/model_locale_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_localized_value_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_localized_value_converter.js +145 -0
- package/dist/lib/model_field_value/converters/model_localized_value_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_ref_base_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_ref_base_converter.js +159 -0
- package/dist/lib/model_field_value/converters/model_ref_base_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_search_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_search_converter.js +138 -0
- package/dist/lib/model_field_value/converters/model_search_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_server_command_base_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_server_command_base_converter.js +119 -0
- package/dist/lib/model_field_value/converters/model_server_command_base_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_time_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_time_converter.js +271 -0
- package/dist/lib/model_field_value/converters/model_time_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_time_range_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_time_range_converter.js +225 -0
- package/dist/lib/model_field_value/converters/model_time_range_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_timestamp_converter.d.ts +66 -0
- package/dist/lib/model_field_value/converters/model_timestamp_converter.js +297 -0
- package/dist/lib/model_field_value/converters/model_timestamp_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_timestamp_range_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_timestamp_range_converter.js +225 -0
- package/dist/lib/model_field_value/converters/model_timestamp_range_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_token_converter.d.ts +48 -0
- package/dist/lib/model_field_value/converters/model_token_converter.js +137 -0
- package/dist/lib/model_field_value/converters/model_token_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_uri_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_uri_converter.js +184 -0
- package/dist/lib/model_field_value/converters/model_uri_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_vector_value_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_vector_value_converter.js +125 -0
- package/dist/lib/model_field_value/converters/model_vector_value_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/model_video_uri_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/model_video_uri_converter.js +184 -0
- package/dist/lib/model_field_value/converters/model_video_uri_converter.js.map +1 -0
- package/dist/lib/model_field_value/converters/null_converter.d.ts +49 -0
- package/dist/lib/model_field_value/converters/null_converter.js +72 -0
- package/dist/lib/model_field_value/converters/null_converter.js.map +1 -0
- package/dist/lib/model_field_value/default_model_field_value_converter.d.ts +155 -0
- package/dist/lib/model_field_value/default_model_field_value_converter.js +303 -0
- package/dist/lib/model_field_value/default_model_field_value_converter.js.map +1 -0
- package/dist/lib/model_field_value/model_field_value.d.ts +467 -0
- package/dist/lib/model_field_value/model_field_value.js +665 -0
- package/dist/lib/model_field_value/model_field_value.js.map +1 -0
- package/dist/lib/model_field_value/model_field_value_converter.d.ts +117 -0
- package/dist/lib/model_field_value/model_field_value_converter.js +49 -0
- package/dist/lib/model_field_value/model_field_value_converter.js.map +1 -0
- package/dist/lib/regions.d.ts +6 -0
- package/dist/lib/regions.js +3 -0
- package/dist/lib/regions.js.map +1 -0
- package/dist/lib/request.d.ts +12 -0
- package/dist/lib/request.js +213 -0
- package/dist/lib/request.js.map +1 -0
- package/dist/lib/rules.d.ts +32 -0
- package/dist/lib/rules.js +299 -0
- package/dist/lib/rules.js.map +1 -0
- package/dist/lib/schema.d.ts +15 -0
- package/dist/lib/schema.js +141 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/src/call_process_function_base.d.ts +39 -0
- package/dist/lib/src/call_process_function_base.js +72 -0
- package/dist/lib/src/call_process_function_base.js.map +1 -0
- package/dist/lib/src/firebase_loader.d.ts +30 -0
- package/dist/lib/src/firebase_loader.js +96 -0
- package/dist/lib/src/firebase_loader.js.map +1 -0
- package/dist/lib/src/firestore_base.d.ts +114 -0
- package/dist/lib/src/firestore_base.js +363 -0
- package/dist/lib/src/firestore_base.js.map +1 -0
- package/dist/lib/src/firestore_triggered_process_function_base.d.ts +40 -0
- package/dist/lib/src/firestore_triggered_process_function_base.js +72 -0
- package/dist/lib/src/firestore_triggered_process_function_base.js.map +1 -0
- package/dist/lib/src/functions_base.d.ts +327 -0
- package/dist/lib/src/functions_base.js +63 -0
- package/dist/lib/src/functions_base.js.map +1 -0
- package/dist/lib/src/functions_data.d.ts +10 -0
- package/dist/lib/src/functions_data.js +19 -0
- package/dist/lib/src/functions_data.js.map +1 -0
- package/dist/lib/src/request_process_function_base.d.ts +39 -0
- package/dist/lib/src/request_process_function_base.js +70 -0
- package/dist/lib/src/request_process_function_base.js.map +1 -0
- package/dist/lib/src/request_process_workders_base.d.ts +37 -0
- package/dist/lib/src/request_process_workders_base.js +27 -0
- package/dist/lib/src/request_process_workders_base.js.map +1 -0
- package/dist/lib/src/schedule_process_function_base.d.ts +33 -0
- package/dist/lib/src/schedule_process_function_base.js +71 -0
- package/dist/lib/src/schedule_process_function_base.js.map +1 -0
- package/dist/lib/src/sql_api_base.d.ts +185 -0
- package/dist/lib/src/sql_api_base.js +83 -0
- package/dist/lib/src/sql_api_base.js.map +1 -0
- package/dist/lib/src/workers_base.d.ts +74 -0
- package/dist/lib/src/workers_base.js +57 -0
- package/dist/lib/src/workers_base.js.map +1 -0
- package/dist/lib/src/workers_data.d.ts +10 -0
- package/dist/lib/src/workers_data.js +21 -0
- package/dist/lib/src/workers_data.js.map +1 -0
- package/dist/lib/token.d.ts +12 -0
- package/dist/lib/token.js +123 -0
- package/dist/lib/token.js.map +1 -0
- package/dist/lib/turso_client.d.ts +14 -0
- package/dist/lib/turso_client.js +130 -0
- package/dist/lib/turso_client.js.map +1 -0
- package/dist/lib/types.d.ts +71 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utils.d.ts +82 -0
- package/dist/lib/utils.js +141 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/workers/test.d.ts +1 -0
- package/dist/workers/test.js +14 -0
- package/dist/workers/test.js.map +1 -0
- package/dist/workers/turso.d.ts +1 -0
- package/dist/workers/turso.js +50 -0
- package/dist/workers/turso.js.map +1 -0
- package/dist/workers/turso_token.d.ts +1 -0
- package/dist/workers/turso_token.js +40 -0
- package/dist/workers/turso_token.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.issueScopedToken = issueScopedToken;
|
|
4
|
+
exports.buildTursoPermissions = buildTursoPermissions;
|
|
5
|
+
async function issueScopedToken({ database, scope, ttlSeconds, options, }) {
|
|
6
|
+
const now = Math.floor(Date.now() / 1000);
|
|
7
|
+
const maxTtl = options.maxTtlSeconds ?? 3600;
|
|
8
|
+
const ttl = Math.max(1, Math.min(ttlSeconds ?? 600, maxTtl));
|
|
9
|
+
const expiresAt = now + ttl;
|
|
10
|
+
const payload = {
|
|
11
|
+
iss: options.tokenIssuer?.issuer ?? "masamune_cloudflare_turso",
|
|
12
|
+
aud: options.tokenIssuer?.audience ?? "turso",
|
|
13
|
+
iat: now,
|
|
14
|
+
exp: expiresAt,
|
|
15
|
+
database,
|
|
16
|
+
scope,
|
|
17
|
+
permissions: buildTursoPermissions(scope),
|
|
18
|
+
};
|
|
19
|
+
if (options.organizationName && options.platformApiToken) {
|
|
20
|
+
const jwt = await issuePlatformDatabaseToken({
|
|
21
|
+
database,
|
|
22
|
+
ttlSeconds: ttl,
|
|
23
|
+
permissions: payload.permissions,
|
|
24
|
+
options,
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
token: jwt,
|
|
28
|
+
expiresAt,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const secret = options.tokenIssuer?.secret ?? options.authToken;
|
|
32
|
+
if (!secret) {
|
|
33
|
+
throw new Error("tokenIssuer.secret or authToken is required to issue scoped tokens.");
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
token: await signHs256(payload, secret),
|
|
37
|
+
expiresAt,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function buildTursoPermissions(scope) {
|
|
41
|
+
const permissions = {};
|
|
42
|
+
for (const item of scope) {
|
|
43
|
+
const tablePermissions = permissions[item.table] ?? new Set();
|
|
44
|
+
for (const operation of item.operations) {
|
|
45
|
+
for (const permission of operationToPermissions(operation)) {
|
|
46
|
+
tablePermissions.add(permission);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
permissions[item.table] = tablePermissions;
|
|
50
|
+
}
|
|
51
|
+
return Object.fromEntries(Object.entries(permissions).map(([table, values]) => {
|
|
52
|
+
return [table, [...values].sort()];
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
async function signHs256(payload, secret) {
|
|
56
|
+
const header = {
|
|
57
|
+
alg: "HS256",
|
|
58
|
+
typ: "JWT",
|
|
59
|
+
};
|
|
60
|
+
const unsigned = `${base64UrlEncodeJson(header)}.${base64UrlEncodeJson(payload)}`;
|
|
61
|
+
const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), {
|
|
62
|
+
name: "HMAC",
|
|
63
|
+
hash: "SHA-256",
|
|
64
|
+
}, false, ["sign"]);
|
|
65
|
+
const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(unsigned));
|
|
66
|
+
return `${unsigned}.${base64UrlEncode(signature)}`;
|
|
67
|
+
}
|
|
68
|
+
function operationToPermissions(operation) {
|
|
69
|
+
switch (operation) {
|
|
70
|
+
case "read":
|
|
71
|
+
case "get":
|
|
72
|
+
return ["data_read"];
|
|
73
|
+
case "create":
|
|
74
|
+
return ["data_add"];
|
|
75
|
+
case "update":
|
|
76
|
+
return ["data_update"];
|
|
77
|
+
case "delete":
|
|
78
|
+
return ["data_delete"];
|
|
79
|
+
case "write":
|
|
80
|
+
return ["data_add", "data_update", "data_delete"];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function issuePlatformDatabaseToken({ database, ttlSeconds, permissions, options, }) {
|
|
84
|
+
const databaseName = `${options.databaseNamePrefix ?? ""}${database}`;
|
|
85
|
+
const organizationName = options.organizationName;
|
|
86
|
+
const platformApiToken = options.platformApiToken;
|
|
87
|
+
if (!organizationName || !platformApiToken) {
|
|
88
|
+
throw new Error("organizationName and platformApiToken are required.");
|
|
89
|
+
}
|
|
90
|
+
const response = await fetch("https://api.turso.tech/v1/organizations/" +
|
|
91
|
+
`${encodeURIComponent(organizationName)}/databases/${encodeURIComponent(databaseName)}` +
|
|
92
|
+
`/auth/tokens?expiration=${ttlSeconds}s&authorization=full-access`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: {
|
|
95
|
+
Authorization: `Bearer ${platformApiToken}`,
|
|
96
|
+
"Content-Type": "application/json",
|
|
97
|
+
},
|
|
98
|
+
body: JSON.stringify({ permissions }),
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`Failed to issue Turso token: ${response.status}`);
|
|
102
|
+
}
|
|
103
|
+
const body = await response.json();
|
|
104
|
+
if (!body.jwt) {
|
|
105
|
+
throw new Error("Turso token response did not include jwt.");
|
|
106
|
+
}
|
|
107
|
+
return body.jwt;
|
|
108
|
+
}
|
|
109
|
+
function base64UrlEncodeJson(value) {
|
|
110
|
+
return base64UrlEncode(new TextEncoder().encode(JSON.stringify(value)));
|
|
111
|
+
}
|
|
112
|
+
function base64UrlEncode(value) {
|
|
113
|
+
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
114
|
+
let binary = "";
|
|
115
|
+
for (const byte of bytes) {
|
|
116
|
+
binary += String.fromCharCode(byte);
|
|
117
|
+
}
|
|
118
|
+
return btoa(binary)
|
|
119
|
+
.replace(/\+/g, "-")
|
|
120
|
+
.replace(/\//g, "_")
|
|
121
|
+
.replace(/=+$/g, "");
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/lib/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TursoDatabaseConnection, TursoWorkersOptions } from "./types";
|
|
2
|
+
export interface TursoResultSet {
|
|
3
|
+
rows: unknown[];
|
|
4
|
+
}
|
|
5
|
+
export interface TursoClient {
|
|
6
|
+
execute(statement: string | {
|
|
7
|
+
sql: string;
|
|
8
|
+
args?: SqlValue[];
|
|
9
|
+
}): Promise<TursoResultSet>;
|
|
10
|
+
execute(sql: string, args?: SqlValue[]): Promise<TursoResultSet>;
|
|
11
|
+
}
|
|
12
|
+
export type SqlValue = null | string | number | bigint | ArrayBuffer | boolean | Uint8Array | Date;
|
|
13
|
+
export declare function createTursoClient(connection: TursoDatabaseConnection): TursoClient;
|
|
14
|
+
export declare function resolveDatabaseConnection(database: string, options: TursoWorkersOptions): Promise<TursoDatabaseConnection>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTursoClient = createTursoClient;
|
|
4
|
+
exports.resolveDatabaseConnection = resolveDatabaseConnection;
|
|
5
|
+
const request_1 = require("./request");
|
|
6
|
+
const connectionCache = new Map();
|
|
7
|
+
function createTursoClient(connection) {
|
|
8
|
+
const { createClient } = require("@tursodatabase/serverless/compat");
|
|
9
|
+
return createClient({
|
|
10
|
+
url: connection.url,
|
|
11
|
+
authToken: connection.authToken,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
async function resolveDatabaseConnection(database, options) {
|
|
15
|
+
const normalizedDatabase = (0, request_1.validateLogicalName)(database, "database");
|
|
16
|
+
const configured = options.databases?.[normalizedDatabase];
|
|
17
|
+
if (configured) {
|
|
18
|
+
return configured;
|
|
19
|
+
}
|
|
20
|
+
if ((options.defaultDatabase ?? "main") === normalizedDatabase && options.url) {
|
|
21
|
+
return {
|
|
22
|
+
url: options.url,
|
|
23
|
+
authToken: options.authToken,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const databaseName = `${options.databaseNamePrefix ?? ""}${normalizedDatabase}`;
|
|
27
|
+
const cached = connectionCache.get(databaseName);
|
|
28
|
+
if (cached) {
|
|
29
|
+
return cached;
|
|
30
|
+
}
|
|
31
|
+
if (options.autoCreateDatabase === false) {
|
|
32
|
+
throw new request_1.HttpError(404, `Database is not configured: ${normalizedDatabase}`);
|
|
33
|
+
}
|
|
34
|
+
const created = await ensurePlatformDatabase(databaseName, options);
|
|
35
|
+
connectionCache.set(databaseName, created);
|
|
36
|
+
return created;
|
|
37
|
+
}
|
|
38
|
+
async function ensurePlatformDatabase(databaseName, options) {
|
|
39
|
+
const organizationName = options.organizationName;
|
|
40
|
+
const platformApiToken = options.platformApiToken;
|
|
41
|
+
if (!organizationName || !platformApiToken) {
|
|
42
|
+
throw new request_1.HttpError(500, "organizationName and platformApiToken are required to create Turso databases.");
|
|
43
|
+
}
|
|
44
|
+
const groupName = resolveDatabaseGroupName(options);
|
|
45
|
+
const baseUrl = `https://api.turso.tech/v1/organizations/${encodeURIComponent(organizationName)}`;
|
|
46
|
+
const headers = {
|
|
47
|
+
Authorization: `Bearer ${platformApiToken}`,
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
};
|
|
50
|
+
const existing = await fetch(`${baseUrl}/databases/${encodeURIComponent(databaseName)}`, {
|
|
51
|
+
headers,
|
|
52
|
+
});
|
|
53
|
+
if (existing.status === 404) {
|
|
54
|
+
const response = await fetch(`${baseUrl}/databases`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers,
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
name: databaseName,
|
|
59
|
+
group: groupName,
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
throw new request_1.HttpError(500, `Failed to create Turso database: ${response.status}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (!existing.ok) {
|
|
67
|
+
throw new request_1.HttpError(500, `Failed to get Turso database: ${existing.status}`);
|
|
68
|
+
}
|
|
69
|
+
const infoResponse = await fetch(`${baseUrl}/databases/${encodeURIComponent(databaseName)}`, {
|
|
70
|
+
headers,
|
|
71
|
+
});
|
|
72
|
+
if (!infoResponse.ok) {
|
|
73
|
+
throw new request_1.HttpError(500, `Failed to resolve Turso database: ${infoResponse.status}`);
|
|
74
|
+
}
|
|
75
|
+
const info = await infoResponse.json();
|
|
76
|
+
const url = findDatabaseUrl(info);
|
|
77
|
+
if (!url) {
|
|
78
|
+
throw new request_1.HttpError(500, "Turso database URL was not found in Platform API response.");
|
|
79
|
+
}
|
|
80
|
+
const authToken = await createDatabaseToken(baseUrl, databaseName, headers);
|
|
81
|
+
return {
|
|
82
|
+
url,
|
|
83
|
+
authToken,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function createDatabaseToken(baseUrl, databaseName, headers) {
|
|
87
|
+
const response = await fetch(`${baseUrl}/databases/${encodeURIComponent(databaseName)}/auth/tokens`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers,
|
|
90
|
+
body: JSON.stringify({}),
|
|
91
|
+
});
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const body = await response.json();
|
|
96
|
+
const token = body.jwt ?? body.token;
|
|
97
|
+
return typeof token === "string" ? token : undefined;
|
|
98
|
+
}
|
|
99
|
+
function resolveDatabaseGroupName(options) {
|
|
100
|
+
const groupName = firstNonEmpty(options.groupName, typeof process !== "undefined" ? process.env?.TURSO_GROUP_NAME : undefined);
|
|
101
|
+
if (!groupName) {
|
|
102
|
+
throw new request_1.HttpError(500, "groupName or TURSO_GROUP_NAME is required to create Turso databases.");
|
|
103
|
+
}
|
|
104
|
+
return groupName;
|
|
105
|
+
}
|
|
106
|
+
function firstNonEmpty(...values) {
|
|
107
|
+
for (const value of values) {
|
|
108
|
+
const trimmed = value?.trim();
|
|
109
|
+
if (trimmed) {
|
|
110
|
+
return trimmed;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
function findDatabaseUrl(value) {
|
|
116
|
+
if (typeof value === "string" && /^libsql:\/\//.test(value)) {
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
if (typeof value !== "object" || value === null) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
for (const item of Object.values(value)) {
|
|
123
|
+
const found = findDatabaseUrl(item);
|
|
124
|
+
if (found) {
|
|
125
|
+
return found;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=turso_client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turso_client.js","sourceRoot":"","sources":["../../src/lib/turso_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { WorkersOptions } from "@mathrunet/masamune_cloudflare";
|
|
2
|
+
export type TursoCrudMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
3
|
+
export type RulesOperation = "get" | "create" | "update" | "delete";
|
|
4
|
+
export type RulesOperationAlias = "read" | "write";
|
|
5
|
+
export type RulesOperationKey = RulesOperation | RulesOperationAlias;
|
|
6
|
+
export type RulesAccessRule = "deny" | "allow" | "authenticated" | {
|
|
7
|
+
type: "fieldMatch";
|
|
8
|
+
field: string;
|
|
9
|
+
};
|
|
10
|
+
export type RulesEntry = Partial<Record<RulesOperationKey, RulesAccessRule>>;
|
|
11
|
+
export interface RulesConfig {
|
|
12
|
+
version: string;
|
|
13
|
+
rules: Record<string, RulesEntry>;
|
|
14
|
+
}
|
|
15
|
+
export interface TursoDatabaseConnection {
|
|
16
|
+
url: string;
|
|
17
|
+
authToken?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface TursoTokenIssuerOptions {
|
|
20
|
+
secret?: string | undefined;
|
|
21
|
+
issuer?: string | undefined;
|
|
22
|
+
audience?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface TursoWorkersOptions extends Omit<WorkersOptions, "rules"> {
|
|
25
|
+
url?: string | undefined;
|
|
26
|
+
authToken?: string | undefined;
|
|
27
|
+
databases?: Record<string, TursoDatabaseConnection> | undefined;
|
|
28
|
+
defaultDatabase?: string | undefined;
|
|
29
|
+
databaseNamePrefix?: string | undefined;
|
|
30
|
+
organizationName?: string | undefined;
|
|
31
|
+
groupName?: string | undefined;
|
|
32
|
+
platformApiToken?: string | undefined;
|
|
33
|
+
autoCreateDatabase?: boolean | undefined;
|
|
34
|
+
autoCreateTable?: boolean | undefined;
|
|
35
|
+
autoMigrateAddColumns?: boolean | undefined;
|
|
36
|
+
maxTtlSeconds?: number | undefined;
|
|
37
|
+
rules?: RulesConfig | undefined;
|
|
38
|
+
tokenIssuer?: TursoTokenIssuerOptions | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface TursoRequestBody {
|
|
41
|
+
database?: string | undefined;
|
|
42
|
+
table?: string | undefined;
|
|
43
|
+
indexKey?: string | undefined;
|
|
44
|
+
where?: TursoWhereCondition[] | undefined;
|
|
45
|
+
orderBy?: TursoOrderCondition[] | undefined;
|
|
46
|
+
limit?: number | undefined;
|
|
47
|
+
value?: Record<string, unknown> | undefined;
|
|
48
|
+
count?: boolean | undefined;
|
|
49
|
+
}
|
|
50
|
+
export interface TursoWhereCondition {
|
|
51
|
+
type?: string | undefined;
|
|
52
|
+
key?: string | undefined;
|
|
53
|
+
value?: unknown;
|
|
54
|
+
}
|
|
55
|
+
export interface TursoOrderCondition {
|
|
56
|
+
key?: string | undefined;
|
|
57
|
+
descending?: boolean | undefined;
|
|
58
|
+
}
|
|
59
|
+
export interface TursoTokenScopeInput {
|
|
60
|
+
table: string;
|
|
61
|
+
operations: RulesOperationKey[];
|
|
62
|
+
}
|
|
63
|
+
export interface TursoTokenRequestBody {
|
|
64
|
+
database?: string | undefined;
|
|
65
|
+
scope?: TursoTokenScopeInput[] | undefined;
|
|
66
|
+
ttlSeconds?: number | undefined;
|
|
67
|
+
}
|
|
68
|
+
export interface AuthenticationContext {
|
|
69
|
+
uid?: string | undefined;
|
|
70
|
+
token?: unknown;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if [value] is {[key: string]: any}.
|
|
3
|
+
*
|
|
4
|
+
* [value]が{[key: string]: any}であるかどうかをチェックします。
|
|
5
|
+
*
|
|
6
|
+
* @param value
|
|
7
|
+
* Value to be checked.
|
|
8
|
+
*
|
|
9
|
+
* チェックしたい値。
|
|
10
|
+
*
|
|
11
|
+
* @returns
|
|
12
|
+
* If [value] is {[key: string]: any}, returns true; otherwise, returns false.
|
|
13
|
+
*
|
|
14
|
+
* [value]が{[key: string]: any}ならtrue、そうでなければfalseを返します。
|
|
15
|
+
*/
|
|
16
|
+
export declare function isDynamicMap(value: any): value is {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Converts strings, numbers, etc. to the appropriate type.
|
|
21
|
+
*
|
|
22
|
+
* 文字列や数値などを適切な型に変換します。
|
|
23
|
+
*
|
|
24
|
+
* @param {string | number} value
|
|
25
|
+
* Strings and numbers.
|
|
26
|
+
* 文字列か数値。
|
|
27
|
+
*
|
|
28
|
+
* @return {bool | number | string}
|
|
29
|
+
* If it is a string, a numeric value is returned;
|
|
30
|
+
* otherwise, the input value is returned.
|
|
31
|
+
* 文字列なら数値、そうでなければ入力値が返却されます。
|
|
32
|
+
*/
|
|
33
|
+
export declare function parse(value: string | number): string | number | boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Generate and retrieve the UUID for Version 7.
|
|
36
|
+
*
|
|
37
|
+
* The strings can be sorted in chronological order of generation.
|
|
38
|
+
*
|
|
39
|
+
* Returned as a string with 32 hyphenated characters removed.
|
|
40
|
+
*
|
|
41
|
+
* If [baseTime] is specified, the date and time to be generated can be adjusted.
|
|
42
|
+
* If [reverse] is specified, the elapsed time from [baseTime] is reversed.
|
|
43
|
+
*
|
|
44
|
+
* Version7のUUIDを生成し取得します。
|
|
45
|
+
*
|
|
46
|
+
* 文字列を生成した時系列順にソート可能です。
|
|
47
|
+
*
|
|
48
|
+
* 32文字のハイフンが取り除かれた文字列として返されます。
|
|
49
|
+
*
|
|
50
|
+
* [baseTime]を指定した場合、生成する日時を調節できます。
|
|
51
|
+
* [reverse]を指定した場合は、[baseTime]からの経過時間を反転させた値を使用します。
|
|
52
|
+
*
|
|
53
|
+
* @param {Object} options - Options for UUID generation
|
|
54
|
+
* @param {Date} [options.baseTime] - Base time for UUID generation (defaults to current time)
|
|
55
|
+
* @param {boolean} [options.reverse=false] - Whether to reverse the timestamp
|
|
56
|
+
* @return {string} UUID v7 without hyphens
|
|
57
|
+
*/
|
|
58
|
+
export declare function uuid(options?: {
|
|
59
|
+
baseTime?: Date;
|
|
60
|
+
reverse?: boolean;
|
|
61
|
+
}): string;
|
|
62
|
+
/**
|
|
63
|
+
* Divides an array into pieces of the specified size.
|
|
64
|
+
*
|
|
65
|
+
* 配列を指定したサイズで分割します。
|
|
66
|
+
*
|
|
67
|
+
* @param array
|
|
68
|
+
* Array to be divided.
|
|
69
|
+
*
|
|
70
|
+
* 分割したい配列。
|
|
71
|
+
*
|
|
72
|
+
* @param chunkSize
|
|
73
|
+
* Size of each piece.
|
|
74
|
+
*
|
|
75
|
+
* 1つのピースのサイズ。
|
|
76
|
+
*
|
|
77
|
+
* @returns {T[][]}
|
|
78
|
+
* Array divided into pieces.
|
|
79
|
+
*
|
|
80
|
+
* 分割された配列。
|
|
81
|
+
*/
|
|
82
|
+
export declare function splitArray<T>(array: T[], chunkSize: number): T[][];
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDynamicMap = isDynamicMap;
|
|
4
|
+
exports.parse = parse;
|
|
5
|
+
exports.uuid = uuid;
|
|
6
|
+
exports.splitArray = splitArray;
|
|
7
|
+
const uuid_1 = require("uuid");
|
|
8
|
+
/**
|
|
9
|
+
* Checks if [value] is {[key: string]: any}.
|
|
10
|
+
*
|
|
11
|
+
* [value]が{[key: string]: any}であるかどうかをチェックします。
|
|
12
|
+
*
|
|
13
|
+
* @param value
|
|
14
|
+
* Value to be checked.
|
|
15
|
+
*
|
|
16
|
+
* チェックしたい値。
|
|
17
|
+
*
|
|
18
|
+
* @returns
|
|
19
|
+
* If [value] is {[key: string]: any}, returns true; otherwise, returns false.
|
|
20
|
+
*
|
|
21
|
+
* [value]が{[key: string]: any}ならtrue、そうでなければfalseを返します。
|
|
22
|
+
*/
|
|
23
|
+
function isDynamicMap(value) {
|
|
24
|
+
return value !== null && typeof value === 'object' && !(value instanceof Array);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Converts strings, numbers, etc. to the appropriate type.
|
|
28
|
+
*
|
|
29
|
+
* 文字列や数値などを適切な型に変換します。
|
|
30
|
+
*
|
|
31
|
+
* @param {string | number} value
|
|
32
|
+
* Strings and numbers.
|
|
33
|
+
* 文字列か数値。
|
|
34
|
+
*
|
|
35
|
+
* @return {bool | number | string}
|
|
36
|
+
* If it is a string, a numeric value is returned;
|
|
37
|
+
* otherwise, the input value is returned.
|
|
38
|
+
* 文字列なら数値、そうでなければ入力値が返却されます。
|
|
39
|
+
*/
|
|
40
|
+
function parse(value) {
|
|
41
|
+
if (typeof value === "string") {
|
|
42
|
+
if (value === "false") {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
else if (value === "true") {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
else if (value.match(new RegExp("^[0-9]+$"))) {
|
|
49
|
+
const i = parseInt(value);
|
|
50
|
+
if (isNaN(i)) {
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return i;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Generate and retrieve the UUID for Version 7.
|
|
67
|
+
*
|
|
68
|
+
* The strings can be sorted in chronological order of generation.
|
|
69
|
+
*
|
|
70
|
+
* Returned as a string with 32 hyphenated characters removed.
|
|
71
|
+
*
|
|
72
|
+
* If [baseTime] is specified, the date and time to be generated can be adjusted.
|
|
73
|
+
* If [reverse] is specified, the elapsed time from [baseTime] is reversed.
|
|
74
|
+
*
|
|
75
|
+
* Version7のUUIDを生成し取得します。
|
|
76
|
+
*
|
|
77
|
+
* 文字列を生成した時系列順にソート可能です。
|
|
78
|
+
*
|
|
79
|
+
* 32文字のハイフンが取り除かれた文字列として返されます。
|
|
80
|
+
*
|
|
81
|
+
* [baseTime]を指定した場合、生成する日時を調節できます。
|
|
82
|
+
* [reverse]を指定した場合は、[baseTime]からの経過時間を反転させた値を使用します。
|
|
83
|
+
*
|
|
84
|
+
* @param {Object} options - Options for UUID generation
|
|
85
|
+
* @param {Date} [options.baseTime] - Base time for UUID generation (defaults to current time)
|
|
86
|
+
* @param {boolean} [options.reverse=false] - Whether to reverse the timestamp
|
|
87
|
+
* @return {string} UUID v7 without hyphens
|
|
88
|
+
*/
|
|
89
|
+
function uuid(options) {
|
|
90
|
+
const baseTime = options?.baseTime ?? new Date();
|
|
91
|
+
const reverse = options?.reverse ?? false;
|
|
92
|
+
const generated = (0, uuid_1.v7)({ msecs: baseTime.getTime() }).replace(/-/g, "");
|
|
93
|
+
if (reverse) {
|
|
94
|
+
return _createComplementaryString(generated);
|
|
95
|
+
}
|
|
96
|
+
return generated;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Divides an array into pieces of the specified size.
|
|
100
|
+
*
|
|
101
|
+
* 配列を指定したサイズで分割します。
|
|
102
|
+
*
|
|
103
|
+
* @param array
|
|
104
|
+
* Array to be divided.
|
|
105
|
+
*
|
|
106
|
+
* 分割したい配列。
|
|
107
|
+
*
|
|
108
|
+
* @param chunkSize
|
|
109
|
+
* Size of each piece.
|
|
110
|
+
*
|
|
111
|
+
* 1つのピースのサイズ。
|
|
112
|
+
*
|
|
113
|
+
* @returns {T[][]}
|
|
114
|
+
* Array divided into pieces.
|
|
115
|
+
*
|
|
116
|
+
* 分割された配列。
|
|
117
|
+
*/
|
|
118
|
+
function splitArray(array, chunkSize) {
|
|
119
|
+
let index = 0;
|
|
120
|
+
let arrayLength = array.length;
|
|
121
|
+
let tempArray = [];
|
|
122
|
+
for (index = 0; index < arrayLength; index += chunkSize) {
|
|
123
|
+
let chunk = array.slice(index, index + chunkSize);
|
|
124
|
+
tempArray.push(chunk);
|
|
125
|
+
}
|
|
126
|
+
return tempArray;
|
|
127
|
+
}
|
|
128
|
+
function _createComplementaryString(originalString) {
|
|
129
|
+
let buffer = "";
|
|
130
|
+
const charList = "0123456789abcdef";
|
|
131
|
+
for (let i = 0; i < originalString.length; i++) {
|
|
132
|
+
const charIndex = charList.indexOf(originalString[i]);
|
|
133
|
+
if (charIndex == -1) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const complementIndex = charList.length - charIndex - 1;
|
|
137
|
+
buffer += charList[complementIndex];
|
|
138
|
+
}
|
|
139
|
+
return buffer;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Endpoints for testing.
|
|
5
|
+
*
|
|
6
|
+
* テストを行うためのエンドポイントです。
|
|
7
|
+
*/
|
|
8
|
+
module.exports = (hono, options, data) => {
|
|
9
|
+
hono.get("/", async (c) => {
|
|
10
|
+
return c.json({ message: "Hello, World!" });
|
|
11
|
+
});
|
|
12
|
+
return hono;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/workers/test.ts"],"names":[],"mappings":";;AAIA;;;;GAIG;AACH,MAAM,CAAC,OAAO,GAAG,CACf,IAAU,EACV,OAAuB,EACvB,IAA4B,EAC5B,EAAE;IACF,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const crud_1 = require("../lib/crud");
|
|
4
|
+
const request_1 = require("../lib/request");
|
|
5
|
+
const rules_1 = require("../lib/rules");
|
|
6
|
+
const turso_client_1 = require("../lib/turso_client");
|
|
7
|
+
module.exports = (hono, options, data) => {
|
|
8
|
+
hono.get("/", async (context) => handleCrud(context, options, "GET"));
|
|
9
|
+
hono.post("/", async (context) => handleCrud(context, options, "POST"));
|
|
10
|
+
hono.put("/", async (context) => handleCrud(context, options, "PUT"));
|
|
11
|
+
hono.delete("/", async (context) => handleCrud(context, options, "DELETE"));
|
|
12
|
+
return hono;
|
|
13
|
+
};
|
|
14
|
+
async function handleCrud(context, options, method) {
|
|
15
|
+
try {
|
|
16
|
+
const request = await (0, request_1.parseCrudRequest)(context);
|
|
17
|
+
const connection = await (0, turso_client_1.resolveDatabaseConnection)(request.database, options);
|
|
18
|
+
const client = (0, turso_client_1.createTursoClient)(connection);
|
|
19
|
+
const engine = new rules_1.RulesEngine(options.rules);
|
|
20
|
+
const authentication = context.get("authentication");
|
|
21
|
+
const result = await engine.evaluate({
|
|
22
|
+
path: (0, rules_1.buildRulesPath)({
|
|
23
|
+
database: request.database,
|
|
24
|
+
table: request.table,
|
|
25
|
+
indexKey: request.indexKey ?? "*",
|
|
26
|
+
}),
|
|
27
|
+
operation: (0, rules_1.normalizeHttpMethodToRulesOperation)(method),
|
|
28
|
+
authentication,
|
|
29
|
+
fetchDocument: async () => (0, crud_1.fetchDocumentForRules)(client, request),
|
|
30
|
+
});
|
|
31
|
+
if (!result.allowed) {
|
|
32
|
+
return context.json({
|
|
33
|
+
error: "denied",
|
|
34
|
+
rule: result.rulePath,
|
|
35
|
+
}, 403);
|
|
36
|
+
}
|
|
37
|
+
const response = await (0, crud_1.executeCrud)({
|
|
38
|
+
client,
|
|
39
|
+
method,
|
|
40
|
+
request,
|
|
41
|
+
autoCreateTable: options.autoCreateTable !== false,
|
|
42
|
+
autoMigrateAddColumns: options.autoMigrateAddColumns !== false,
|
|
43
|
+
});
|
|
44
|
+
return context.json({ data: response });
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
return (0, request_1.jsonError)(context, error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=turso.js.map
|