@tinycloud/sdk-core 2.4.0-beta.8 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/index.cjs +25 -0
- package/dist/bootstrap/index.cjs.map +1 -0
- package/dist/bootstrap/index.d.cts +1 -0
- package/dist/bootstrap/index.d.ts +1 -0
- package/dist/bootstrap/index.js +3 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/index.cjs +367 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -10
- package/dist/index.d.ts +110 -10
- package/dist/index.js +364 -71
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
package/dist/index.js
CHANGED
|
@@ -188,7 +188,15 @@ var PersistedSessionDataSchema = z2.object({
|
|
|
188
188
|
/** Schema version for migrations */
|
|
189
189
|
version: z2.string(),
|
|
190
190
|
/** Optional ENS data */
|
|
191
|
-
ens: EnsDataSchema2.optional()
|
|
191
|
+
ens: EnsDataSchema2.optional(),
|
|
192
|
+
/**
|
|
193
|
+
* TinyCloud hosts this session was created against. Persisted so a
|
|
194
|
+
* restored session resolves to the same node without re-running the
|
|
195
|
+
* registry/fallback resolution (or the wallet sign-in flow). Optional
|
|
196
|
+
* for backward compatibility with sessions persisted before this field
|
|
197
|
+
* existed — those restore and lazily re-resolve their hosts.
|
|
198
|
+
*/
|
|
199
|
+
tinycloudHosts: z2.array(z2.string()).optional()
|
|
192
200
|
});
|
|
193
201
|
var TinyCloudSessionSchema = z2.object({
|
|
194
202
|
/** User's Ethereum address */
|
|
@@ -2172,6 +2180,7 @@ import {
|
|
|
2172
2180
|
// src/manifest.ts
|
|
2173
2181
|
import ms from "ms";
|
|
2174
2182
|
import { resolveSecretPath, SECRET_NAME_RE } from "@tinycloud/sdk-services";
|
|
2183
|
+
var DEFAULT_KNOWLEDGE_ROOT = "knowledge/index.md";
|
|
2175
2184
|
var ManifestValidationError = class extends Error {
|
|
2176
2185
|
constructor(message) {
|
|
2177
2186
|
super(`Manifest validation failed: ${message}`);
|
|
@@ -2226,7 +2235,7 @@ var DEFAULT_ADMIN_ENTRIES = [
|
|
|
2226
2235
|
service: "tinycloud.sql",
|
|
2227
2236
|
space: DEFAULT_MANIFEST_SPACE,
|
|
2228
2237
|
path: "/",
|
|
2229
|
-
actions: ["read", "write", "
|
|
2238
|
+
actions: ["read", "write", "schema"]
|
|
2230
2239
|
}
|
|
2231
2240
|
];
|
|
2232
2241
|
var DEFAULT_ALL_ENTRIES = [
|
|
@@ -2240,7 +2249,7 @@ var DEFAULT_ALL_ENTRIES = [
|
|
|
2240
2249
|
service: "tinycloud.sql",
|
|
2241
2250
|
space: DEFAULT_MANIFEST_SPACE,
|
|
2242
2251
|
path: "/",
|
|
2243
|
-
actions: ["read", "write", "
|
|
2252
|
+
actions: ["read", "write", "schema"]
|
|
2244
2253
|
},
|
|
2245
2254
|
{
|
|
2246
2255
|
service: "tinycloud.duckdb",
|
|
@@ -2398,6 +2407,9 @@ function validateManifest(input) {
|
|
|
2398
2407
|
if (m.expiry !== void 0) {
|
|
2399
2408
|
parseExpiry(m.expiry);
|
|
2400
2409
|
}
|
|
2410
|
+
if (m.knowledge !== void 0) {
|
|
2411
|
+
resolveManifestKnowledgeRoot(m.knowledge);
|
|
2412
|
+
}
|
|
2401
2413
|
if (m.permissions !== void 0) {
|
|
2402
2414
|
if (!Array.isArray(m.permissions)) {
|
|
2403
2415
|
throw new ManifestValidationError(
|
|
@@ -2413,6 +2425,25 @@ function validateManifest(input) {
|
|
|
2413
2425
|
}
|
|
2414
2426
|
return m;
|
|
2415
2427
|
}
|
|
2428
|
+
function resolveManifestKnowledgeRoot(knowledge) {
|
|
2429
|
+
if (knowledge === void 0) {
|
|
2430
|
+
return void 0;
|
|
2431
|
+
}
|
|
2432
|
+
if (knowledge === true) {
|
|
2433
|
+
return DEFAULT_KNOWLEDGE_ROOT;
|
|
2434
|
+
}
|
|
2435
|
+
if (typeof knowledge !== "string" || knowledge.length === 0) {
|
|
2436
|
+
throw new ManifestValidationError(
|
|
2437
|
+
"manifest.knowledge must be true or a knowledge/*.md root path"
|
|
2438
|
+
);
|
|
2439
|
+
}
|
|
2440
|
+
if (!/^knowledge\/.+\.md$/.test(knowledge)) {
|
|
2441
|
+
throw new ManifestValidationError(
|
|
2442
|
+
"manifest.knowledge must be true or a knowledge/*.md root path"
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
return knowledge;
|
|
2446
|
+
}
|
|
2416
2447
|
function validateManifestSecrets(secrets) {
|
|
2417
2448
|
if (secrets === null || typeof secrets !== "object" || Array.isArray(secrets)) {
|
|
2418
2449
|
throw new ManifestValidationError("manifest.secrets must be an object");
|
|
@@ -2812,7 +2843,7 @@ function accountRegistryIndexPermission() {
|
|
|
2812
2843
|
service: "tinycloud.sql",
|
|
2813
2844
|
space: ACCOUNT_REGISTRY_SPACE,
|
|
2814
2845
|
path: "account",
|
|
2815
|
-
actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/
|
|
2846
|
+
actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/schema"]
|
|
2816
2847
|
};
|
|
2817
2848
|
}
|
|
2818
2849
|
function composeManifestRequest(inputs, options = {}) {
|
|
@@ -2917,14 +2948,26 @@ function manifestAbilitiesUnion(resolved) {
|
|
|
2917
2948
|
}
|
|
2918
2949
|
|
|
2919
2950
|
// src/account/AccountService.ts
|
|
2951
|
+
import { ACCOUNT_INDEX_SCHEMA } from "@tinycloud/bootstrap";
|
|
2920
2952
|
var SERVICE_NAME2 = "account";
|
|
2921
2953
|
var ACCOUNT_INDEX_DB = "account";
|
|
2954
|
+
var ACCOUNT_INDEX_NAMESPACE = "tinycloud.account.index";
|
|
2922
2955
|
var ACCOUNT_SPACES_PATH = "spaces/";
|
|
2923
2956
|
var AccountService = class {
|
|
2924
2957
|
constructor(config) {
|
|
2925
2958
|
this.config = config;
|
|
2926
2959
|
this.applications = {
|
|
2927
|
-
list: async () => {
|
|
2960
|
+
list: async (options = {}) => {
|
|
2961
|
+
if (options.preferIndex) {
|
|
2962
|
+
const indexed = await this.index.applications.list();
|
|
2963
|
+
if (indexed.ok && indexed.data.length > 0) return indexed;
|
|
2964
|
+
if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
|
|
2965
|
+
const canonical = await this.applications.list();
|
|
2966
|
+
if (canonical.ok && options.refreshIndex !== false) {
|
|
2967
|
+
await this.replaceApplicationsIndexQuietly(canonical.data);
|
|
2968
|
+
}
|
|
2969
|
+
return canonical;
|
|
2970
|
+
}
|
|
2928
2971
|
const kvResult = this.accountKV();
|
|
2929
2972
|
if (!kvResult.ok) return kvResult;
|
|
2930
2973
|
const listed = await kvResult.data.list({ prefix: ACCOUNT_REGISTRY_PATH });
|
|
@@ -2983,8 +3026,7 @@ var AccountService = class {
|
|
|
2983
3026
|
const written = await kvResult.data.put(record.key, stored);
|
|
2984
3027
|
if (!written.ok) return accountErr(written.error);
|
|
2985
3028
|
registered = applicationFromRecord(record.key, stored);
|
|
2986
|
-
|
|
2987
|
-
if (!indexed.ok) return indexed;
|
|
3029
|
+
await this.upsertApplicationIndexQuietly(registered);
|
|
2988
3030
|
}
|
|
2989
3031
|
return ok3(registered);
|
|
2990
3032
|
},
|
|
@@ -2993,13 +3035,22 @@ var AccountService = class {
|
|
|
2993
3035
|
if (!kvResult.ok) return kvResult;
|
|
2994
3036
|
const removed = await kvResult.data.delete(applicationKey(appId));
|
|
2995
3037
|
if (!removed.ok) return accountErr(removed.error);
|
|
2996
|
-
|
|
2997
|
-
if (!indexed.ok) return indexed;
|
|
3038
|
+
await this.deleteApplicationIndexQuietly(appId);
|
|
2998
3039
|
return ok3(void 0);
|
|
2999
3040
|
}
|
|
3000
3041
|
};
|
|
3001
3042
|
this.spaces = {
|
|
3002
|
-
list: async () => {
|
|
3043
|
+
list: async (options = {}) => {
|
|
3044
|
+
if (options.preferIndex) {
|
|
3045
|
+
const indexed = await this.index.spaces.list();
|
|
3046
|
+
if (indexed.ok && indexed.data.length > 0) return indexed;
|
|
3047
|
+
if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
|
|
3048
|
+
const canonical = await this.spaces.syncAccessible();
|
|
3049
|
+
if (canonical.ok && options.refreshIndex !== false) {
|
|
3050
|
+
await this.replaceSpacesIndexQuietly(canonical.data);
|
|
3051
|
+
}
|
|
3052
|
+
return canonical;
|
|
3053
|
+
}
|
|
3003
3054
|
const kvResult = this.accountKV();
|
|
3004
3055
|
if (!kvResult.ok) return kvResult;
|
|
3005
3056
|
const listed = await kvResult.data.list({ prefix: ACCOUNT_SPACES_PATH });
|
|
@@ -3028,8 +3079,7 @@ var AccountService = class {
|
|
|
3028
3079
|
const written = await kvResult.data.put(spaceKey(stored.space_id), stored);
|
|
3029
3080
|
if (!written.ok) return accountErr(written.error);
|
|
3030
3081
|
const registered = spaceFromRecord(spaceKey(stored.space_id), stored);
|
|
3031
|
-
|
|
3032
|
-
if (!indexed.ok) return indexed;
|
|
3082
|
+
await this.upsertSpaceIndexQuietly(registered);
|
|
3033
3083
|
return ok3(registered);
|
|
3034
3084
|
},
|
|
3035
3085
|
syncAccessible: async () => {
|
|
@@ -3048,13 +3098,25 @@ var AccountService = class {
|
|
|
3048
3098
|
if (!kvResult.ok) return kvResult;
|
|
3049
3099
|
const removed = await kvResult.data.delete(spaceKey(spaceId));
|
|
3050
3100
|
if (!removed.ok) return accountErr(removed.error);
|
|
3051
|
-
|
|
3052
|
-
if (!indexed.ok) return indexed;
|
|
3101
|
+
await this.deleteSpaceIndexQuietly(spaceId);
|
|
3053
3102
|
return ok3(void 0);
|
|
3054
3103
|
}
|
|
3055
3104
|
};
|
|
3056
3105
|
this.delegations = {
|
|
3057
3106
|
list: async (options = {}) => {
|
|
3107
|
+
if (options.preferIndex) {
|
|
3108
|
+
const indexed = await this.index.delegations.list(options);
|
|
3109
|
+
if (indexed.ok && indexed.data.length > 0) return indexed;
|
|
3110
|
+
if (!indexed.ok && !isMissingIndexError(indexed.error)) return indexed;
|
|
3111
|
+
const live = await this.delegations.list({
|
|
3112
|
+
direction: options.direction,
|
|
3113
|
+
space: options.space
|
|
3114
|
+
});
|
|
3115
|
+
if (live.ok && options.refreshIndex !== false) {
|
|
3116
|
+
await this.replaceDelegationsIndexQuietly(live.data);
|
|
3117
|
+
}
|
|
3118
|
+
return live;
|
|
3119
|
+
}
|
|
3058
3120
|
const spaces = await this.config.getSpaces().list();
|
|
3059
3121
|
if (!spaces.ok) return accountErr(spaces.error);
|
|
3060
3122
|
const targetSpaces = options.space ? spaces.data.filter((space) => space.id === options.space || space.name === options.space) : spaces.data;
|
|
@@ -3084,6 +3146,13 @@ var AccountService = class {
|
|
|
3084
3146
|
}
|
|
3085
3147
|
};
|
|
3086
3148
|
this.index = {
|
|
3149
|
+
ensure: async () => {
|
|
3150
|
+
const dbResult = this.accountDb();
|
|
3151
|
+
if (!dbResult.ok) return dbResult;
|
|
3152
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3153
|
+
if (!schema.ok) return schema;
|
|
3154
|
+
return ok3({ database: ACCOUNT_INDEX_DB });
|
|
3155
|
+
},
|
|
3087
3156
|
rebuild: async () => {
|
|
3088
3157
|
const dbResult = this.accountDb();
|
|
3089
3158
|
if (!dbResult.ok) return dbResult;
|
|
@@ -3094,8 +3163,9 @@ var AccountService = class {
|
|
|
3094
3163
|
const delegations = await this.delegations.list();
|
|
3095
3164
|
if (!delegations.ok) return delegations;
|
|
3096
3165
|
const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3166
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3167
|
+
if (!schema.ok) return schema;
|
|
3097
3168
|
const statements = [
|
|
3098
|
-
...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
|
|
3099
3169
|
{ sql: "DELETE FROM applications" },
|
|
3100
3170
|
{ sql: "DELETE FROM application_state" },
|
|
3101
3171
|
{ sql: "DELETE FROM spaces" },
|
|
@@ -3227,9 +3297,15 @@ var AccountService = class {
|
|
|
3227
3297
|
const queried = await dbResult.data.query(
|
|
3228
3298
|
"SELECT source, synced_at, count FROM sync_state ORDER BY source"
|
|
3229
3299
|
);
|
|
3230
|
-
if (!queried.ok)
|
|
3300
|
+
if (!queried.ok) {
|
|
3301
|
+
if (isMissingIndexError(queried.error)) {
|
|
3302
|
+
return ok3({ database: ACCOUNT_INDEX_DB, state: "missing", sources: [] });
|
|
3303
|
+
}
|
|
3304
|
+
return accountErr(queried.error);
|
|
3305
|
+
}
|
|
3231
3306
|
return ok3({
|
|
3232
3307
|
database: ACCOUNT_INDEX_DB,
|
|
3308
|
+
state: "ready",
|
|
3233
3309
|
sources: queried.data.rows.map(([source, syncedAt, count]) => ({
|
|
3234
3310
|
source,
|
|
3235
3311
|
syncedAt,
|
|
@@ -3286,7 +3362,7 @@ var AccountService = class {
|
|
|
3286
3362
|
async indexHasApplicationHash(appId, manifestHash) {
|
|
3287
3363
|
const dbResult = this.accountDb();
|
|
3288
3364
|
if (!dbResult.ok) return false;
|
|
3289
|
-
const schema = await dbResult.data
|
|
3365
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3290
3366
|
if (!schema.ok) return false;
|
|
3291
3367
|
const queried = await dbResult.data.query(
|
|
3292
3368
|
"SELECT 1 FROM application_state WHERE app_id = ? AND manifest_hash = ? LIMIT 1",
|
|
@@ -3294,13 +3370,17 @@ var AccountService = class {
|
|
|
3294
3370
|
);
|
|
3295
3371
|
return queried.ok && queried.data.rows.length > 0;
|
|
3296
3372
|
}
|
|
3373
|
+
async upsertApplicationIndexQuietly(app) {
|
|
3374
|
+
await ignoreIndexFailure(() => this.upsertApplicationIndex(app));
|
|
3375
|
+
}
|
|
3297
3376
|
async upsertApplicationIndex(app) {
|
|
3298
3377
|
const dbResult = this.accountDb();
|
|
3299
3378
|
if (!dbResult.ok) return ok3(void 0);
|
|
3379
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3380
|
+
if (!schema.ok) return schema;
|
|
3300
3381
|
const updatedAt = app.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
3301
3382
|
const manifestHash = app.manifestHash ?? hashJson(app.manifests);
|
|
3302
3383
|
const written = await dbResult.data.batch([
|
|
3303
|
-
...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
|
|
3304
3384
|
{
|
|
3305
3385
|
sql: "INSERT OR REPLACE INTO applications (app_id, name, description, updated_at, manifest_json) VALUES (?, ?, ?, ?, ?)",
|
|
3306
3386
|
params: [
|
|
@@ -3319,23 +3399,31 @@ var AccountService = class {
|
|
|
3319
3399
|
if (!written.ok) return accountErr(written.error);
|
|
3320
3400
|
return ok3(void 0);
|
|
3321
3401
|
}
|
|
3402
|
+
async deleteApplicationIndexQuietly(appId) {
|
|
3403
|
+
await ignoreIndexFailure(() => this.deleteApplicationIndex(appId));
|
|
3404
|
+
}
|
|
3322
3405
|
async deleteApplicationIndex(appId) {
|
|
3323
3406
|
const dbResult = this.accountDb();
|
|
3324
3407
|
if (!dbResult.ok) return ok3(void 0);
|
|
3408
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3409
|
+
if (!schema.ok) return schema;
|
|
3325
3410
|
const deleted = await dbResult.data.batch([
|
|
3326
|
-
...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
|
|
3327
3411
|
{ sql: "DELETE FROM applications WHERE app_id = ?", params: [appId] },
|
|
3328
3412
|
{ sql: "DELETE FROM application_state WHERE app_id = ?", params: [appId] }
|
|
3329
3413
|
]);
|
|
3330
3414
|
if (!deleted.ok) return accountErr(deleted.error);
|
|
3331
3415
|
return ok3(void 0);
|
|
3332
3416
|
}
|
|
3417
|
+
async upsertSpaceIndexQuietly(space) {
|
|
3418
|
+
await ignoreIndexFailure(() => this.upsertSpaceIndex(space));
|
|
3419
|
+
}
|
|
3333
3420
|
async upsertSpaceIndex(space) {
|
|
3334
3421
|
const dbResult = this.accountDb();
|
|
3335
3422
|
if (!dbResult.ok) return ok3(void 0);
|
|
3423
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3424
|
+
if (!schema.ok) return schema;
|
|
3336
3425
|
const updatedAt = space.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
3337
3426
|
const written = await dbResult.data.batch([
|
|
3338
|
-
...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
|
|
3339
3427
|
{
|
|
3340
3428
|
sql: "INSERT OR REPLACE INTO spaces (space_id, name, owner_did, type, permissions_json, status, registered_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
3341
3429
|
params: [
|
|
@@ -3354,11 +3442,15 @@ var AccountService = class {
|
|
|
3354
3442
|
if (!written.ok) return accountErr(written.error);
|
|
3355
3443
|
return ok3(void 0);
|
|
3356
3444
|
}
|
|
3445
|
+
async deleteSpaceIndexQuietly(spaceId) {
|
|
3446
|
+
await ignoreIndexFailure(() => this.deleteSpaceIndex(spaceId));
|
|
3447
|
+
}
|
|
3357
3448
|
async deleteSpaceIndex(spaceId) {
|
|
3358
3449
|
const dbResult = this.accountDb();
|
|
3359
3450
|
if (!dbResult.ok) return ok3(void 0);
|
|
3451
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3452
|
+
if (!schema.ok) return schema;
|
|
3360
3453
|
const deleted = await dbResult.data.batch([
|
|
3361
|
-
...ACCOUNT_INDEX_SCHEMA.map((sql) => ({ sql })),
|
|
3362
3454
|
{ sql: "DELETE FROM spaces WHERE space_id = ?", params: [spaceId] }
|
|
3363
3455
|
]);
|
|
3364
3456
|
if (!deleted.ok) return accountErr(deleted.error);
|
|
@@ -3375,57 +3467,115 @@ var AccountService = class {
|
|
|
3375
3467
|
}
|
|
3376
3468
|
return ok3(found);
|
|
3377
3469
|
}
|
|
3470
|
+
async replaceApplicationsIndexQuietly(applications) {
|
|
3471
|
+
await ignoreIndexFailure(async () => {
|
|
3472
|
+
const dbResult = this.accountDb();
|
|
3473
|
+
if (!dbResult.ok) return;
|
|
3474
|
+
const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3475
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3476
|
+
if (!schema.ok) return;
|
|
3477
|
+
await dbResult.data.batch([
|
|
3478
|
+
{ sql: "DELETE FROM applications" },
|
|
3479
|
+
{ sql: "DELETE FROM application_state" },
|
|
3480
|
+
...applications.map((app) => ({
|
|
3481
|
+
sql: "INSERT OR REPLACE INTO applications (app_id, name, description, updated_at, manifest_json) VALUES (?, ?, ?, ?, ?)",
|
|
3482
|
+
params: [
|
|
3483
|
+
app.appId,
|
|
3484
|
+
app.name ?? null,
|
|
3485
|
+
app.description ?? null,
|
|
3486
|
+
app.updatedAt ?? syncedAt,
|
|
3487
|
+
JSON.stringify(app.manifests)
|
|
3488
|
+
]
|
|
3489
|
+
})),
|
|
3490
|
+
...applications.map((app) => ({
|
|
3491
|
+
sql: "INSERT OR REPLACE INTO application_state (app_id, manifest_hash, indexed_at) VALUES (?, ?, ?)",
|
|
3492
|
+
params: [app.appId, app.manifestHash ?? hashJson(app.manifests), syncedAt]
|
|
3493
|
+
})),
|
|
3494
|
+
{
|
|
3495
|
+
sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
|
|
3496
|
+
params: ["applications", syncedAt, applications.length]
|
|
3497
|
+
}
|
|
3498
|
+
]);
|
|
3499
|
+
});
|
|
3500
|
+
}
|
|
3501
|
+
async replaceSpacesIndexQuietly(spaces) {
|
|
3502
|
+
await ignoreIndexFailure(async () => {
|
|
3503
|
+
const dbResult = this.accountDb();
|
|
3504
|
+
if (!dbResult.ok) return;
|
|
3505
|
+
const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3506
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3507
|
+
if (!schema.ok) return;
|
|
3508
|
+
await dbResult.data.batch([
|
|
3509
|
+
{ sql: "DELETE FROM spaces" },
|
|
3510
|
+
...spaces.map((space) => ({
|
|
3511
|
+
sql: "INSERT OR REPLACE INTO spaces (space_id, name, owner_did, type, permissions_json, status, registered_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
3512
|
+
params: [
|
|
3513
|
+
space.spaceId,
|
|
3514
|
+
space.name,
|
|
3515
|
+
space.ownerDid,
|
|
3516
|
+
space.type,
|
|
3517
|
+
JSON.stringify(space.permissions),
|
|
3518
|
+
space.status,
|
|
3519
|
+
space.registeredAt ?? syncedAt,
|
|
3520
|
+
space.updatedAt ?? syncedAt,
|
|
3521
|
+
space.expiresAt?.toISOString() ?? null
|
|
3522
|
+
]
|
|
3523
|
+
})),
|
|
3524
|
+
{
|
|
3525
|
+
sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
|
|
3526
|
+
params: ["spaces", syncedAt, spaces.length]
|
|
3527
|
+
}
|
|
3528
|
+
]);
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
async replaceDelegationsIndexQuietly(delegations) {
|
|
3532
|
+
await ignoreIndexFailure(async () => {
|
|
3533
|
+
const dbResult = this.accountDb();
|
|
3534
|
+
if (!dbResult.ok) return;
|
|
3535
|
+
const syncedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3536
|
+
const schema = await this.ensureAccountIndex(dbResult.data);
|
|
3537
|
+
if (!schema.ok) return;
|
|
3538
|
+
await dbResult.data.batch([
|
|
3539
|
+
{ sql: "DELETE FROM delegations" },
|
|
3540
|
+
...delegations.map((delegation) => ({
|
|
3541
|
+
sql: "INSERT OR REPLACE INTO delegations (cid, direction, space_id, space_name, counterparty_did, delegate_did, delegator_did, path, actions_json, expiry, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
3542
|
+
params: [
|
|
3543
|
+
delegation.cid,
|
|
3544
|
+
delegation.direction,
|
|
3545
|
+
delegation.spaceId,
|
|
3546
|
+
delegation.spaceName ?? null,
|
|
3547
|
+
delegation.counterpartyDid,
|
|
3548
|
+
delegation.delegateDid,
|
|
3549
|
+
delegation.delegatorDid ?? null,
|
|
3550
|
+
delegation.path,
|
|
3551
|
+
JSON.stringify(delegation.actions),
|
|
3552
|
+
delegation.expiry.toISOString(),
|
|
3553
|
+
delegation.status,
|
|
3554
|
+
delegation.createdAt?.toISOString() ?? null,
|
|
3555
|
+
syncedAt
|
|
3556
|
+
]
|
|
3557
|
+
})),
|
|
3558
|
+
{
|
|
3559
|
+
sql: "INSERT OR REPLACE INTO sync_state (source, synced_at, count) VALUES (?, ?, ?)",
|
|
3560
|
+
params: ["delegations", syncedAt, delegations.length]
|
|
3561
|
+
}
|
|
3562
|
+
]);
|
|
3563
|
+
});
|
|
3564
|
+
}
|
|
3565
|
+
async ensureAccountIndex(db) {
|
|
3566
|
+
const migrated = await db.migrations.apply({
|
|
3567
|
+
namespace: ACCOUNT_INDEX_NAMESPACE,
|
|
3568
|
+
migrations: [
|
|
3569
|
+
{
|
|
3570
|
+
id: "001_initial",
|
|
3571
|
+
sql: [...ACCOUNT_INDEX_SCHEMA]
|
|
3572
|
+
}
|
|
3573
|
+
]
|
|
3574
|
+
});
|
|
3575
|
+
if (!migrated.ok) return accountErr(migrated.error);
|
|
3576
|
+
return ok3(void 0);
|
|
3577
|
+
}
|
|
3378
3578
|
};
|
|
3379
|
-
var ACCOUNT_INDEX_SCHEMA = [
|
|
3380
|
-
`CREATE TABLE IF NOT EXISTS applications (
|
|
3381
|
-
app_id TEXT PRIMARY KEY,
|
|
3382
|
-
name TEXT,
|
|
3383
|
-
description TEXT,
|
|
3384
|
-
updated_at TEXT,
|
|
3385
|
-
manifest_json TEXT NOT NULL
|
|
3386
|
-
)`,
|
|
3387
|
-
`CREATE TABLE IF NOT EXISTS application_state (
|
|
3388
|
-
app_id TEXT PRIMARY KEY,
|
|
3389
|
-
manifest_hash TEXT NOT NULL,
|
|
3390
|
-
indexed_at TEXT NOT NULL
|
|
3391
|
-
)`,
|
|
3392
|
-
`CREATE TABLE IF NOT EXISTS spaces (
|
|
3393
|
-
space_id TEXT PRIMARY KEY,
|
|
3394
|
-
name TEXT NOT NULL,
|
|
3395
|
-
owner_did TEXT NOT NULL,
|
|
3396
|
-
type TEXT NOT NULL,
|
|
3397
|
-
permissions_json TEXT NOT NULL,
|
|
3398
|
-
status TEXT NOT NULL,
|
|
3399
|
-
registered_at TEXT,
|
|
3400
|
-
updated_at TEXT NOT NULL,
|
|
3401
|
-
expires_at TEXT
|
|
3402
|
-
)`,
|
|
3403
|
-
`CREATE TABLE IF NOT EXISTS delegations (
|
|
3404
|
-
cid TEXT PRIMARY KEY,
|
|
3405
|
-
direction TEXT NOT NULL,
|
|
3406
|
-
space_id TEXT NOT NULL,
|
|
3407
|
-
space_name TEXT,
|
|
3408
|
-
counterparty_did TEXT NOT NULL,
|
|
3409
|
-
delegate_did TEXT NOT NULL,
|
|
3410
|
-
delegator_did TEXT,
|
|
3411
|
-
path TEXT NOT NULL,
|
|
3412
|
-
actions_json TEXT NOT NULL,
|
|
3413
|
-
expiry TEXT NOT NULL,
|
|
3414
|
-
status TEXT NOT NULL,
|
|
3415
|
-
created_at TEXT,
|
|
3416
|
-
updated_at TEXT NOT NULL
|
|
3417
|
-
)`,
|
|
3418
|
-
`CREATE TABLE IF NOT EXISTS sync_state (
|
|
3419
|
-
source TEXT PRIMARY KEY,
|
|
3420
|
-
synced_at TEXT NOT NULL,
|
|
3421
|
-
count INTEGER NOT NULL
|
|
3422
|
-
)`,
|
|
3423
|
-
"CREATE INDEX IF NOT EXISTS idx_delegations_direction ON delegations(direction)",
|
|
3424
|
-
"CREATE INDEX IF NOT EXISTS idx_delegations_space ON delegations(space_id)",
|
|
3425
|
-
"CREATE INDEX IF NOT EXISTS idx_delegations_counterparty ON delegations(counterparty_did)",
|
|
3426
|
-
"CREATE INDEX IF NOT EXISTS idx_spaces_owner ON spaces(owner_did)",
|
|
3427
|
-
"CREATE INDEX IF NOT EXISTS idx_spaces_type ON spaces(type)"
|
|
3428
|
-
];
|
|
3429
3579
|
function applicationKey(appId) {
|
|
3430
3580
|
return `${ACCOUNT_REGISTRY_PATH}${appId}`;
|
|
3431
3581
|
}
|
|
@@ -3581,6 +3731,15 @@ function mapDelegation(delegation, space, direction) {
|
|
|
3581
3731
|
function accountErr(error) {
|
|
3582
3732
|
return err3(serviceError3(error.code, error.message, SERVICE_NAME2, { cause: error.cause, meta: error.meta }));
|
|
3583
3733
|
}
|
|
3734
|
+
function isMissingIndexError(error) {
|
|
3735
|
+
return /no such table:/i.test(error.message);
|
|
3736
|
+
}
|
|
3737
|
+
async function ignoreIndexFailure(task) {
|
|
3738
|
+
try {
|
|
3739
|
+
await task();
|
|
3740
|
+
} catch {
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3584
3743
|
|
|
3585
3744
|
// src/index.ts
|
|
3586
3745
|
import {
|
|
@@ -3591,6 +3750,13 @@ import {
|
|
|
3591
3750
|
err as err5,
|
|
3592
3751
|
serviceError as serviceError5,
|
|
3593
3752
|
ErrorCodes as ErrorCodes2,
|
|
3753
|
+
TinyCloudDebugLogger,
|
|
3754
|
+
tinyCloudDebugLogger,
|
|
3755
|
+
enableTinyCloudDebug,
|
|
3756
|
+
disableTinyCloudDebug,
|
|
3757
|
+
getTinyCloudDebugLogs,
|
|
3758
|
+
clearTinyCloudDebugLogs,
|
|
3759
|
+
installTinyCloudDebugGlobals,
|
|
3594
3760
|
defaultRetryPolicy as defaultRetryPolicy2,
|
|
3595
3761
|
SQLService as SQLService2,
|
|
3596
3762
|
DatabaseHandle,
|
|
@@ -5391,6 +5557,76 @@ function createCapabilityKeyRegistry() {
|
|
|
5391
5557
|
}
|
|
5392
5558
|
|
|
5393
5559
|
// src/authorization/strategies.ts
|
|
5560
|
+
async function resolveOpenKeyToken(token) {
|
|
5561
|
+
return typeof token === "function" ? token() : token;
|
|
5562
|
+
}
|
|
5563
|
+
async function resolveOpenKeyHeaders(headers) {
|
|
5564
|
+
return typeof headers === "function" ? headers() : headers ?? {};
|
|
5565
|
+
}
|
|
5566
|
+
function openKeyApprovalReason(body) {
|
|
5567
|
+
if (body.reason) return body.reason;
|
|
5568
|
+
if (body.error) return body.error;
|
|
5569
|
+
if (body.approvalUrl) {
|
|
5570
|
+
return `OpenKey explicit approval required: ${body.approvalUrl}`;
|
|
5571
|
+
}
|
|
5572
|
+
return "OpenKey explicit approval required";
|
|
5573
|
+
}
|
|
5574
|
+
function createOpenKeyCallbackSigningStrategy(options) {
|
|
5575
|
+
return {
|
|
5576
|
+
type: "callback",
|
|
5577
|
+
openKeyAutoSign: true,
|
|
5578
|
+
handler: async (request) => {
|
|
5579
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
5580
|
+
if (!fetchImpl) {
|
|
5581
|
+
throw new Error("OpenKey signing strategy requires a fetch implementation");
|
|
5582
|
+
}
|
|
5583
|
+
const token = await resolveOpenKeyToken(options.token);
|
|
5584
|
+
const extraHeaders = await resolveOpenKeyHeaders(options.headers);
|
|
5585
|
+
const body = {
|
|
5586
|
+
...request,
|
|
5587
|
+
...options.keyId ? { keyId: options.keyId } : {}
|
|
5588
|
+
};
|
|
5589
|
+
const response = await fetchImpl(options.endpoint, {
|
|
5590
|
+
method: "POST",
|
|
5591
|
+
credentials: options.credentials,
|
|
5592
|
+
headers: {
|
|
5593
|
+
"content-type": "application/json",
|
|
5594
|
+
...token ? { authorization: `Bearer ${token}` } : {},
|
|
5595
|
+
...extraHeaders
|
|
5596
|
+
},
|
|
5597
|
+
body: JSON.stringify(body)
|
|
5598
|
+
});
|
|
5599
|
+
let parsed;
|
|
5600
|
+
try {
|
|
5601
|
+
parsed = await response.json();
|
|
5602
|
+
} catch {
|
|
5603
|
+
parsed = void 0;
|
|
5604
|
+
}
|
|
5605
|
+
if (!response.ok) {
|
|
5606
|
+
return {
|
|
5607
|
+
approved: false,
|
|
5608
|
+
reason: parsed?.reason ?? parsed?.error ?? `OpenKey signing failed with HTTP ${response.status}`
|
|
5609
|
+
};
|
|
5610
|
+
}
|
|
5611
|
+
if (parsed?.needsApproval || parsed?.approved === false) {
|
|
5612
|
+
return {
|
|
5613
|
+
approved: false,
|
|
5614
|
+
reason: openKeyApprovalReason(parsed)
|
|
5615
|
+
};
|
|
5616
|
+
}
|
|
5617
|
+
if (typeof parsed?.signature === "string" && parsed.signature.length > 0) {
|
|
5618
|
+
return {
|
|
5619
|
+
approved: true,
|
|
5620
|
+
signature: parsed.signature
|
|
5621
|
+
};
|
|
5622
|
+
}
|
|
5623
|
+
return {
|
|
5624
|
+
approved: false,
|
|
5625
|
+
reason: "OpenKey signing response did not include a signature"
|
|
5626
|
+
};
|
|
5627
|
+
}
|
|
5628
|
+
};
|
|
5629
|
+
}
|
|
5394
5630
|
var defaultSignStrategy = { type: "auto-sign" };
|
|
5395
5631
|
|
|
5396
5632
|
// src/authorization/spaceCreation.ts
|
|
@@ -5466,6 +5702,31 @@ async function checkNodeInfo(host, sdkProtocol, fetchFn = globalThis.fetch.bind(
|
|
|
5466
5702
|
};
|
|
5467
5703
|
}
|
|
5468
5704
|
|
|
5705
|
+
// src/index.ts
|
|
5706
|
+
import {
|
|
5707
|
+
ACCOUNT_INDEX_SCHEMA as ACCOUNT_INDEX_SCHEMA2,
|
|
5708
|
+
BOOTSTRAP_ALLOWLIST,
|
|
5709
|
+
BOOTSTRAP_DEFAULT_SPACE,
|
|
5710
|
+
BOOTSTRAP_ENCRYPTION_NETWORK_NAME,
|
|
5711
|
+
BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE,
|
|
5712
|
+
BOOTSTRAP_MANIFEST,
|
|
5713
|
+
BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS,
|
|
5714
|
+
BOOTSTRAP_PUBLIC_SPACE,
|
|
5715
|
+
BOOTSTRAP_SESSION_REQUESTS,
|
|
5716
|
+
BOOTSTRAP_SPACE_MANIFESTS,
|
|
5717
|
+
BOOTSTRAP_SPACE_NAMES,
|
|
5718
|
+
SECRET_RECORDS_SCHEMA,
|
|
5719
|
+
TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
|
|
5720
|
+
TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
|
|
5721
|
+
TINYCLOUD_DEFAULT_SPACE_MANIFEST,
|
|
5722
|
+
TINYCLOUD_PUBLIC_SPACE_MANIFEST,
|
|
5723
|
+
TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
|
|
5724
|
+
bootstrapEncryptionNetworkId,
|
|
5725
|
+
bootstrapSpaceId,
|
|
5726
|
+
bootstrapSteps,
|
|
5727
|
+
composeBootstrapSpaceManifest
|
|
5728
|
+
} from "@tinycloud/bootstrap";
|
|
5729
|
+
|
|
5469
5730
|
// src/location.ts
|
|
5470
5731
|
import { multiaddr } from "@multiformats/multiaddr";
|
|
5471
5732
|
import { multiaddrToUri } from "@multiformats/multiaddr-to-uri";
|
|
@@ -5975,10 +6236,21 @@ function parseRecapCapabilities(parseWasm, siwe) {
|
|
|
5975
6236
|
return normalized;
|
|
5976
6237
|
}
|
|
5977
6238
|
export {
|
|
6239
|
+
ACCOUNT_INDEX_SCHEMA2 as ACCOUNT_INDEX_SCHEMA,
|
|
5978
6240
|
ACCOUNT_REGISTRY_PATH,
|
|
5979
6241
|
ACCOUNT_REGISTRY_SPACE,
|
|
5980
6242
|
AccountService,
|
|
5981
6243
|
AutoApproveSpaceCreationHandler,
|
|
6244
|
+
BOOTSTRAP_ALLOWLIST,
|
|
6245
|
+
BOOTSTRAP_DEFAULT_SPACE,
|
|
6246
|
+
BOOTSTRAP_ENCRYPTION_NETWORK_NAME,
|
|
6247
|
+
BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE,
|
|
6248
|
+
BOOTSTRAP_MANIFEST,
|
|
6249
|
+
BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS,
|
|
6250
|
+
BOOTSTRAP_PUBLIC_SPACE,
|
|
6251
|
+
BOOTSTRAP_SESSION_REQUESTS,
|
|
6252
|
+
BOOTSTRAP_SPACE_MANIFESTS,
|
|
6253
|
+
BOOTSTRAP_SPACE_NAMES,
|
|
5982
6254
|
CapabilityKeyRegistry,
|
|
5983
6255
|
CapabilityKeyRegistryErrorCodes,
|
|
5984
6256
|
ClientSessionSchema,
|
|
@@ -5990,6 +6262,7 @@ export {
|
|
|
5990
6262
|
DEFAULT_ENCRYPTION_ALG,
|
|
5991
6263
|
DEFAULT_EXPIRY,
|
|
5992
6264
|
DEFAULT_KEY_VERSION,
|
|
6265
|
+
DEFAULT_KNOWLEDGE_ROOT,
|
|
5993
6266
|
DEFAULT_MANIFEST_SPACE,
|
|
5994
6267
|
DEFAULT_MANIFEST_VERSION,
|
|
5995
6268
|
DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
@@ -6022,7 +6295,9 @@ export {
|
|
|
6022
6295
|
PermissionNotInManifestError,
|
|
6023
6296
|
PrefixedKVService,
|
|
6024
6297
|
ProtocolMismatchError,
|
|
6298
|
+
SECRETS_SPACE,
|
|
6025
6299
|
SECRET_NAME_RE2 as SECRET_NAME_RE,
|
|
6300
|
+
SECRET_RECORDS_SCHEMA,
|
|
6026
6301
|
SERVICE_LONG_TO_SHORT,
|
|
6027
6302
|
SERVICE_SHORT_TO_LONG,
|
|
6028
6303
|
SQLAction,
|
|
@@ -6037,7 +6312,13 @@ export {
|
|
|
6037
6312
|
Space,
|
|
6038
6313
|
SpaceErrorCodes,
|
|
6039
6314
|
SpaceService,
|
|
6315
|
+
TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
|
|
6316
|
+
TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
|
|
6317
|
+
TINYCLOUD_DEFAULT_SPACE_MANIFEST,
|
|
6318
|
+
TINYCLOUD_PUBLIC_SPACE_MANIFEST,
|
|
6319
|
+
TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
|
|
6040
6320
|
TinyCloud,
|
|
6321
|
+
TinyCloudDebugLogger,
|
|
6041
6322
|
UnsupportedFeatureError,
|
|
6042
6323
|
VAULT_PERMISSION_SERVICE,
|
|
6043
6324
|
VaultHeaders,
|
|
@@ -6046,6 +6327,9 @@ export {
|
|
|
6046
6327
|
activateSessionWithHost,
|
|
6047
6328
|
addressStorageKey,
|
|
6048
6329
|
applyPrefix,
|
|
6330
|
+
bootstrapEncryptionNetworkId,
|
|
6331
|
+
bootstrapSpaceId,
|
|
6332
|
+
bootstrapSteps,
|
|
6049
6333
|
buildCanonicalDecryptRequest,
|
|
6050
6334
|
buildDecryptAttenuation,
|
|
6051
6335
|
buildDecryptFacts,
|
|
@@ -6063,8 +6347,11 @@ export {
|
|
|
6063
6347
|
canonicalizeSecretScope,
|
|
6064
6348
|
checkDecryptInvocationInput,
|
|
6065
6349
|
checkNodeInfo,
|
|
6350
|
+
clearTinyCloudDebugLogs,
|
|
6351
|
+
composeBootstrapSpaceManifest,
|
|
6066
6352
|
composeManifestRequest,
|
|
6067
6353
|
createCapabilityKeyRegistry,
|
|
6354
|
+
createOpenKeyCallbackSigningStrategy,
|
|
6068
6355
|
createSharingService,
|
|
6069
6356
|
createSpaceService,
|
|
6070
6357
|
createVaultCrypto,
|
|
@@ -6075,7 +6362,9 @@ export {
|
|
|
6075
6362
|
deriveSignedReceiverKey,
|
|
6076
6363
|
didCacheKey,
|
|
6077
6364
|
didEquals,
|
|
6365
|
+
disableTinyCloudDebug,
|
|
6078
6366
|
discoverNetwork,
|
|
6367
|
+
enableTinyCloudDebug,
|
|
6079
6368
|
encryptToNetwork,
|
|
6080
6369
|
base64Decode as encryptionBase64Decode,
|
|
6081
6370
|
base64Encode as encryptionBase64Encode,
|
|
@@ -6090,9 +6379,11 @@ export {
|
|
|
6090
6379
|
fetchLocationRecord,
|
|
6091
6380
|
fetchPeerId,
|
|
6092
6381
|
generateRandomReceiverKey,
|
|
6382
|
+
getTinyCloudDebugLogs,
|
|
6093
6383
|
hexDecode,
|
|
6094
6384
|
hexEncode,
|
|
6095
6385
|
httpUrlToMultiaddr,
|
|
6386
|
+
installTinyCloudDebugGlobals,
|
|
6096
6387
|
isCapabilitySubset,
|
|
6097
6388
|
isEvmAddress,
|
|
6098
6389
|
isNetworkId,
|
|
@@ -6117,6 +6408,7 @@ export {
|
|
|
6117
6408
|
principalDidEquals,
|
|
6118
6409
|
resolveCloudLocation,
|
|
6119
6410
|
resolveManifest,
|
|
6411
|
+
resolveManifestKnowledgeRoot,
|
|
6120
6412
|
resolveSecretListPrefix,
|
|
6121
6413
|
resolveSecretPath2 as resolveSecretPath,
|
|
6122
6414
|
resolveTinyCloudHosts,
|
|
@@ -6125,6 +6417,7 @@ export {
|
|
|
6125
6417
|
serviceError5 as serviceError,
|
|
6126
6418
|
signLocationRecord,
|
|
6127
6419
|
submitHostDelegation,
|
|
6420
|
+
tinyCloudDebugLogger,
|
|
6128
6421
|
validateClientSession,
|
|
6129
6422
|
validateEnvelope,
|
|
6130
6423
|
validateLocationRecord,
|