@tinycloud/operations 0.3.2-beta.1 → 0.3.2-beta.11
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/coverage.json +7 -3
- package/dist/artifacts.cjs +155 -51
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.js +155 -51
- package/dist/artifacts.js.map +1 -1
- package/dist/cli-runtime.cjs +156 -50
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.js +156 -50
- package/dist/cli-runtime.js.map +1 -1
- package/dist/index.cjs +156 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +156 -50
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/cli-runtime.js
CHANGED
|
@@ -333,28 +333,6 @@ function withCapabilitiesReadForSpaces(resources) {
|
|
|
333
333
|
}))
|
|
334
334
|
]);
|
|
335
335
|
}
|
|
336
|
-
function accountRegistryPermissions() {
|
|
337
|
-
return [
|
|
338
|
-
{
|
|
339
|
-
service: "tinycloud.kv",
|
|
340
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
341
|
-
path: ACCOUNT_REGISTRY_PATH,
|
|
342
|
-
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
service: "tinycloud.kv",
|
|
346
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
347
|
-
path: "spaces/",
|
|
348
|
-
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
service: "tinycloud.sql",
|
|
352
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
353
|
-
path: "account",
|
|
354
|
-
actions: [SQL.READ, SQL.WRITE, SQL.SCHEMA]
|
|
355
|
-
}
|
|
356
|
-
];
|
|
357
|
-
}
|
|
358
336
|
function composeManifestRequest(inputs, options = {}) {
|
|
359
337
|
if (!Array.isArray(inputs) || inputs.length === 0) {
|
|
360
338
|
throw new Error("composeManifestRequest requires at least one manifest");
|
|
@@ -368,7 +346,12 @@ function composeManifestRequest(inputs, options = {}) {
|
|
|
368
346
|
return explicit.flatMap((entry) => expandPermissionEntry(entry, prefix, space));
|
|
369
347
|
});
|
|
370
348
|
if (includeAccountRegistryPermissions) {
|
|
371
|
-
resources.push(
|
|
349
|
+
resources.push(
|
|
350
|
+
...ACCOUNT_MANIFEST_PERMISSIONS.map((resource) => ({
|
|
351
|
+
...resource,
|
|
352
|
+
actions: [...resource.actions]
|
|
353
|
+
}))
|
|
354
|
+
);
|
|
372
355
|
}
|
|
373
356
|
const manifestsByAppId = /* @__PURE__ */ new Map();
|
|
374
357
|
for (const manifest of manifests) {
|
|
@@ -396,7 +379,7 @@ function composeBootstrapSpaceManifest(space) {
|
|
|
396
379
|
includeAccountRegistryPermissions: false
|
|
397
380
|
});
|
|
398
381
|
}
|
|
399
|
-
var CAPABILITIES, KV, SQL, DUCKDB, CAPABILITIES2, HOOKS, ENCRYPTION, SPACE, DEFAULT_MANIFEST_SPACE, ACCOUNT_REGISTRY_SPACE, ACCOUNT_REGISTRY_PATH, SECRETS_SPACE, BOOTSTRAP_DEFAULT_SPACE, BOOTSTRAP_PUBLIC_SPACE, BOOTSTRAP_ENCRYPTION_NETWORK_NAME, BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE, DEFAULT_EXPIRY_MS, VAULT_PERMISSION_SERVICE, ENCRYPTION_PERMISSION_SERVICE, ENCRYPTION_MANIFEST_SPACE, NETWORK_CREATE_ACTION, BOOTSTRAP_SPACE_NAMES, TINYCLOUD_DEFAULT_SPACE_MANIFEST, TINYCLOUD_APPLICATIONS_SPACE_MANIFEST, TINYCLOUD_ACCOUNT_SPACE_MANIFEST, TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST, TINYCLOUD_PUBLIC_SPACE_MANIFEST, BOOTSTRAP_SPACE_MANIFESTS, BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS, ACCOUNT_INDEX_SCHEMA, SECRET_RECORDS_SCHEMA, BOOTSTRAP_MANIFEST, BOOTSTRAP_SESSION_REQUESTS, ACCOUNT_SESSION_RAW_ALLOWLIST, BOOTSTRAP_ALLOWLIST;
|
|
382
|
+
var CAPABILITIES, KV, SQL, DUCKDB, CAPABILITIES2, HOOKS, ENCRYPTION, SPACE, DEFAULT_MANIFEST_SPACE, ACCOUNT_REGISTRY_SPACE, ACCOUNT_REGISTRY_PATH, SECRETS_SPACE, BOOTSTRAP_DEFAULT_SPACE, BOOTSTRAP_PUBLIC_SPACE, BOOTSTRAP_ENCRYPTION_NETWORK_NAME, BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE, DEFAULT_EXPIRY_MS, VAULT_PERMISSION_SERVICE, ENCRYPTION_PERMISSION_SERVICE, ENCRYPTION_MANIFEST_SPACE, NETWORK_CREATE_ACTION, BOOTSTRAP_SPACE_NAMES, TINYCLOUD_DEFAULT_SPACE_MANIFEST, TINYCLOUD_APPLICATIONS_SPACE_MANIFEST, TINYCLOUD_ACCOUNT_SPACE_MANIFEST, TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST, TINYCLOUD_PUBLIC_SPACE_MANIFEST, BOOTSTRAP_SPACE_MANIFESTS, BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS, ACCOUNT_INDEX_SCHEMA, SECRET_RECORDS_SCHEMA, BOOTSTRAP_MANIFEST, ACCOUNT_MANIFEST_PERMISSIONS, BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST, BOOTSTRAP_WIDENED_DEFAULT_SESSION_REQUEST, BOOTSTRAP_SESSION_REQUESTS, ACCOUNT_SESSION_RAW_ALLOWLIST, BOOTSTRAP_ALLOWLIST;
|
|
400
383
|
var init_dist = __esm({
|
|
401
384
|
"../bootstrap/dist/index.js"() {
|
|
402
385
|
"use strict";
|
|
@@ -701,11 +684,60 @@ var init_dist = __esm({
|
|
|
701
684
|
name: BOOTSTRAP_ENCRYPTION_NETWORK_NAME
|
|
702
685
|
}
|
|
703
686
|
};
|
|
687
|
+
ACCOUNT_MANIFEST_PERMISSIONS = Object.freeze([
|
|
688
|
+
{
|
|
689
|
+
service: "tinycloud.kv",
|
|
690
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
691
|
+
path: ACCOUNT_REGISTRY_PATH,
|
|
692
|
+
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
service: "tinycloud.kv",
|
|
696
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
697
|
+
path: "spaces/",
|
|
698
|
+
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
service: "tinycloud.kv",
|
|
702
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
703
|
+
path: "system/bootstrap/complete",
|
|
704
|
+
actions: [KV.GET, KV.PUT]
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
service: "tinycloud.delegation",
|
|
708
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
709
|
+
path: "",
|
|
710
|
+
actions: ["tinycloud.delegation/list"]
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
service: "tinycloud.sql",
|
|
714
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
715
|
+
path: "account",
|
|
716
|
+
actions: [SQL.READ, SQL.WRITE, SQL.SCHEMA]
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
service: "tinycloud.capabilities",
|
|
720
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
721
|
+
path: "",
|
|
722
|
+
actions: [CAPABILITIES2.READ]
|
|
723
|
+
}
|
|
724
|
+
]);
|
|
725
|
+
BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST = composeBootstrapSpaceManifest(BOOTSTRAP_DEFAULT_SPACE);
|
|
726
|
+
BOOTSTRAP_WIDENED_DEFAULT_SESSION_REQUEST = {
|
|
727
|
+
...BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST,
|
|
728
|
+
resources: [
|
|
729
|
+
...BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST.resources,
|
|
730
|
+
...ACCOUNT_MANIFEST_PERMISSIONS.map((resource) => ({
|
|
731
|
+
...resource,
|
|
732
|
+
actions: [...resource.actions]
|
|
733
|
+
}))
|
|
734
|
+
]
|
|
735
|
+
};
|
|
704
736
|
BOOTSTRAP_SESSION_REQUESTS = Object.freeze(
|
|
705
737
|
Object.fromEntries(
|
|
706
738
|
BOOTSTRAP_SPACE_NAMES.map((space) => [
|
|
707
739
|
space,
|
|
708
|
-
composeBootstrapSpaceManifest(space)
|
|
740
|
+
space === BOOTSTRAP_DEFAULT_SPACE ? BOOTSTRAP_WIDENED_DEFAULT_SESSION_REQUEST : composeBootstrapSpaceManifest(space)
|
|
709
741
|
])
|
|
710
742
|
)
|
|
711
743
|
);
|
|
@@ -760,10 +792,10 @@ var require_decrypt_transport_response_error = __commonJS({
|
|
|
760
792
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
761
793
|
var DecryptTransportResponseError_exports = {};
|
|
762
794
|
__export2(DecryptTransportResponseError_exports, {
|
|
763
|
-
DecryptTransportResponseError: () =>
|
|
795
|
+
DecryptTransportResponseError: () => DecryptTransportResponseError2
|
|
764
796
|
});
|
|
765
797
|
module.exports = __toCommonJS(DecryptTransportResponseError_exports);
|
|
766
|
-
var
|
|
798
|
+
var DecryptTransportResponseError2 = class extends Error {
|
|
767
799
|
constructor(status, permissionHint) {
|
|
768
800
|
super("Node decrypt request failed");
|
|
769
801
|
this.status = status;
|
|
@@ -2396,15 +2428,13 @@ function encOk(data) {
|
|
|
2396
2428
|
function encErr(error) {
|
|
2397
2429
|
return { ok: false, error };
|
|
2398
2430
|
}
|
|
2399
|
-
var import_decrypt_transport_response_error,
|
|
2431
|
+
var import_decrypt_transport_response_error, ErrorCodes, defaultRetryPolicy, TelemetryEvents, REDACTED, SAFE_NUMBER_FIELDS, SAFE_BOOLEAN_FIELDS, DEBUG_FLAG, MAX_EVENTS, TinyCloudDebugLogger, tinyCloudDebugLogger, ServiceErrorSchema, GenericResultSchema, KVResponseHeadersSchema, GenericKVResponseSchema, KVListResponseSchema, KVListResultSchema, ServiceRequestEventSchema, ServiceResponseEventSchema, ServiceErrorEventSchema, ServiceRetryEventSchema, TelemetrySpanEventSchema, RetryPolicySchema, ServiceSessionSchema, BaseService, PrefixedKVService, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, KVAction, MAX_KV_BATCH_READ_ITEMS, KVService, SQLMigrations, DatabaseHandle, SQLAction, DDL_TOKENS, MIGRATIONS_TABLE, MIGRATIONS_SCHEMA, MIGRATIONS_META_NAMESPACE, MIGRATIONS_META_ID, SQLService, DuckDbDatabaseHandle, DuckDbAction, DuckDbService, AsyncQueue, HooksService, VaultVersionConfig, CURRENT_VAULT_VERSION, VaultHeaders, DB_NAME, DB_VERSION, STORE_NAME, WRAP_KEY_ID, DataVaultService, HEX, URN_PREFIX, NETWORK_NAME_RE, PKH_EIP155_DID_RE, NetworkIdError, DEFAULT_ENCRYPTION_ALG, ENVELOPE_VERSION, DEFAULT_KEY_VERSION, DECRYPT_FACT_TYPE, DECRYPT_RESULT_TYPE, EncryptionService;
|
|
2400
2432
|
var init_dist2 = __esm({
|
|
2401
2433
|
"../sdk-services/dist/index.js"() {
|
|
2402
2434
|
"use strict";
|
|
2403
2435
|
init_dist();
|
|
2404
2436
|
init_dist();
|
|
2405
2437
|
import_decrypt_transport_response_error = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2406
|
-
import_decrypt_transport_response_error2 = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2407
|
-
import_decrypt_transport_response_error3 = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2408
2438
|
ErrorCodes = {
|
|
2409
2439
|
// Common errors
|
|
2410
2440
|
NOT_FOUND: "NOT_FOUND",
|
|
@@ -3676,6 +3706,7 @@ var init_dist2 = __esm({
|
|
|
3676
3706
|
}
|
|
3677
3707
|
seen.add(path);
|
|
3678
3708
|
}
|
|
3709
|
+
let requestMayHaveDispatched = false;
|
|
3679
3710
|
try {
|
|
3680
3711
|
const body = new FormData();
|
|
3681
3712
|
for (let index = 0; index < items.length; index++) {
|
|
@@ -3693,14 +3724,31 @@ var init_dist2 = __esm({
|
|
|
3693
3724
|
action: KVAction.PUT
|
|
3694
3725
|
}))
|
|
3695
3726
|
);
|
|
3696
|
-
const
|
|
3727
|
+
const url = `${this.host}/invoke`;
|
|
3728
|
+
const init = {
|
|
3697
3729
|
method: "POST",
|
|
3698
3730
|
headers,
|
|
3699
3731
|
body,
|
|
3700
3732
|
signal: this.combineSignals(options?.signal)
|
|
3701
|
-
}
|
|
3733
|
+
};
|
|
3734
|
+
const fetchFn = this.context.fetch;
|
|
3735
|
+
requestMayHaveDispatched = true;
|
|
3736
|
+
const response = await fetchFn(url, init);
|
|
3702
3737
|
if (!response.ok) {
|
|
3703
|
-
|
|
3738
|
+
let errorText;
|
|
3739
|
+
try {
|
|
3740
|
+
errorText = await response.text();
|
|
3741
|
+
} catch (textError) {
|
|
3742
|
+
const cause = textError instanceof Error ? textError : new Error(String(textError));
|
|
3743
|
+
return err(
|
|
3744
|
+
serviceError(
|
|
3745
|
+
ErrorCodes.KV_WRITE_FAILED,
|
|
3746
|
+
`Failed to batch put ${items.length} key(s): ${response.status} - <response body could not be read: ${cause.message}>`,
|
|
3747
|
+
"kv",
|
|
3748
|
+
{ cause, meta: { status: response.status, statusText: response.statusText } }
|
|
3749
|
+
)
|
|
3750
|
+
);
|
|
3751
|
+
}
|
|
3704
3752
|
if (response.status === 401 || response.status === 403) {
|
|
3705
3753
|
const { resource, action } = parseAuthError(errorText);
|
|
3706
3754
|
return err(authUnauthorizedError("kv", errorText, {
|
|
@@ -3726,19 +3774,73 @@ var init_dist2 = __esm({
|
|
|
3726
3774
|
)
|
|
3727
3775
|
);
|
|
3728
3776
|
}
|
|
3729
|
-
|
|
3730
|
-
|
|
3777
|
+
let rawBody;
|
|
3778
|
+
try {
|
|
3779
|
+
rawBody = await response.json();
|
|
3780
|
+
} catch (jsonError) {
|
|
3781
|
+
const cause = jsonError instanceof Error ? jsonError : new Error(String(jsonError));
|
|
3782
|
+
return err(
|
|
3783
|
+
serviceError(
|
|
3784
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3785
|
+
`KV batchPut response was not valid JSON: ${cause.message}`,
|
|
3786
|
+
"kv",
|
|
3787
|
+
{
|
|
3788
|
+
cause,
|
|
3789
|
+
meta: {
|
|
3790
|
+
requestMayHaveDispatched: true,
|
|
3791
|
+
responseReceived: true,
|
|
3792
|
+
status: response.status,
|
|
3793
|
+
outcome: "batch-unconfirmed"
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
)
|
|
3797
|
+
);
|
|
3798
|
+
}
|
|
3799
|
+
const batchResponse = this.normalizeBatchPutResponse(rawBody);
|
|
3800
|
+
if (!batchResponse) {
|
|
3731
3801
|
return err(
|
|
3732
3802
|
serviceError(
|
|
3733
3803
|
ErrorCodes.NETWORK_ERROR,
|
|
3734
3804
|
"KV batchPut response did not include matching written keys and count",
|
|
3735
|
-
"kv"
|
|
3805
|
+
"kv",
|
|
3806
|
+
{
|
|
3807
|
+
meta: {
|
|
3808
|
+
requestMayHaveDispatched: true,
|
|
3809
|
+
responseReceived: true,
|
|
3810
|
+
status: response.status,
|
|
3811
|
+
outcome: "batch-unconfirmed"
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
)
|
|
3815
|
+
);
|
|
3816
|
+
}
|
|
3817
|
+
const requestedPaths = new Set(paths);
|
|
3818
|
+
const writtenPaths = new Set(batchResponse.written);
|
|
3819
|
+
const matchesRequest = batchResponse.count === paths.length && batchResponse.written.length === paths.length && writtenPaths.size === paths.length && batchResponse.written.every((key) => requestedPaths.has(key));
|
|
3820
|
+
if (!matchesRequest) {
|
|
3821
|
+
return err(
|
|
3822
|
+
serviceError(
|
|
3823
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3824
|
+
`KV batchPut response did not confirm all ${paths.length} requested key(s) were written`,
|
|
3825
|
+
"kv",
|
|
3826
|
+
{
|
|
3827
|
+
meta: {
|
|
3828
|
+
requestMayHaveDispatched: true,
|
|
3829
|
+
responseReceived: true,
|
|
3830
|
+
status: response.status,
|
|
3831
|
+
outcome: "batch-unconfirmed"
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3736
3834
|
)
|
|
3737
3835
|
);
|
|
3738
3836
|
}
|
|
3739
3837
|
return ok(batchResponse);
|
|
3740
3838
|
} catch (error) {
|
|
3741
|
-
|
|
3839
|
+
const wrapped = wrapError("kv", error);
|
|
3840
|
+
return err({
|
|
3841
|
+
...wrapped,
|
|
3842
|
+
meta: { ...wrapped.meta, requestMayHaveDispatched }
|
|
3843
|
+
});
|
|
3742
3844
|
}
|
|
3743
3845
|
});
|
|
3744
3846
|
}
|
|
@@ -6735,15 +6837,28 @@ function normalizeSpace(space) {
|
|
|
6735
6837
|
function isCapabilitySubset(requested, granted) {
|
|
6736
6838
|
const missing = [];
|
|
6737
6839
|
for (const req of requested) {
|
|
6738
|
-
const
|
|
6739
|
-
|
|
6840
|
+
const matchingScope = granted.filter(
|
|
6841
|
+
(entry) => canonicalizeEntryScopeMatches(req, entry)
|
|
6842
|
+
);
|
|
6843
|
+
const requestedActions = expandActionShortNames(
|
|
6844
|
+
req.service,
|
|
6845
|
+
req.actions
|
|
6846
|
+
);
|
|
6847
|
+
const grantedActions = matchingScope.flatMap(
|
|
6848
|
+
(entry) => expandActionShortNames(entry.service, entry.actions)
|
|
6849
|
+
);
|
|
6850
|
+
const covered = requestedActions.every(
|
|
6851
|
+
(requestedAction) => grantedActions.some(
|
|
6852
|
+
(grantedAction) => actionContains(grantedAction, requestedAction)
|
|
6853
|
+
)
|
|
6854
|
+
);
|
|
6855
|
+
if (!covered) {
|
|
6740
6856
|
missing.push(cloneEntry(req));
|
|
6741
|
-
continue;
|
|
6742
6857
|
}
|
|
6743
6858
|
}
|
|
6744
6859
|
return { subset: missing.length === 0, missing };
|
|
6745
6860
|
}
|
|
6746
|
-
function
|
|
6861
|
+
function canonicalizeEntryScopeMatches(requested, granted) {
|
|
6747
6862
|
if (requested.service !== granted.service) {
|
|
6748
6863
|
return false;
|
|
6749
6864
|
}
|
|
@@ -6753,15 +6868,6 @@ function canonicalizeEntryMatches(requested, granted) {
|
|
|
6753
6868
|
if (!pathContains(granted.path, requested.path)) {
|
|
6754
6869
|
return false;
|
|
6755
6870
|
}
|
|
6756
|
-
const reqActions = new Set(
|
|
6757
|
-
expandActionShortNames(requested.service, requested.actions)
|
|
6758
|
-
);
|
|
6759
|
-
const grantedActions = expandActionShortNames(granted.service, granted.actions);
|
|
6760
|
-
for (const a of reqActions) {
|
|
6761
|
-
if (!grantedActions.some((grantedAction) => actionContains(grantedAction, a))) {
|
|
6762
|
-
return false;
|
|
6763
|
-
}
|
|
6764
|
-
}
|
|
6765
6871
|
if (!recapCaveatsEqual(requested.caveats, granted.caveats)) {
|
|
6766
6872
|
return false;
|
|
6767
6873
|
}
|