@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.cjs
CHANGED
|
@@ -335,28 +335,6 @@ function withCapabilitiesReadForSpaces(resources) {
|
|
|
335
335
|
}))
|
|
336
336
|
]);
|
|
337
337
|
}
|
|
338
|
-
function accountRegistryPermissions() {
|
|
339
|
-
return [
|
|
340
|
-
{
|
|
341
|
-
service: "tinycloud.kv",
|
|
342
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
343
|
-
path: ACCOUNT_REGISTRY_PATH,
|
|
344
|
-
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
service: "tinycloud.kv",
|
|
348
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
349
|
-
path: "spaces/",
|
|
350
|
-
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
service: "tinycloud.sql",
|
|
354
|
-
space: ACCOUNT_REGISTRY_SPACE,
|
|
355
|
-
path: "account",
|
|
356
|
-
actions: [SQL.READ, SQL.WRITE, SQL.SCHEMA]
|
|
357
|
-
}
|
|
358
|
-
];
|
|
359
|
-
}
|
|
360
338
|
function composeManifestRequest(inputs, options = {}) {
|
|
361
339
|
if (!Array.isArray(inputs) || inputs.length === 0) {
|
|
362
340
|
throw new Error("composeManifestRequest requires at least one manifest");
|
|
@@ -370,7 +348,12 @@ function composeManifestRequest(inputs, options = {}) {
|
|
|
370
348
|
return explicit.flatMap((entry) => expandPermissionEntry(entry, prefix, space));
|
|
371
349
|
});
|
|
372
350
|
if (includeAccountRegistryPermissions) {
|
|
373
|
-
resources.push(
|
|
351
|
+
resources.push(
|
|
352
|
+
...ACCOUNT_MANIFEST_PERMISSIONS.map((resource) => ({
|
|
353
|
+
...resource,
|
|
354
|
+
actions: [...resource.actions]
|
|
355
|
+
}))
|
|
356
|
+
);
|
|
374
357
|
}
|
|
375
358
|
const manifestsByAppId = /* @__PURE__ */ new Map();
|
|
376
359
|
for (const manifest of manifests) {
|
|
@@ -398,7 +381,7 @@ function composeBootstrapSpaceManifest(space) {
|
|
|
398
381
|
includeAccountRegistryPermissions: false
|
|
399
382
|
});
|
|
400
383
|
}
|
|
401
|
-
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;
|
|
384
|
+
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;
|
|
402
385
|
var init_dist = __esm({
|
|
403
386
|
"../bootstrap/dist/index.js"() {
|
|
404
387
|
"use strict";
|
|
@@ -703,11 +686,60 @@ var init_dist = __esm({
|
|
|
703
686
|
name: BOOTSTRAP_ENCRYPTION_NETWORK_NAME
|
|
704
687
|
}
|
|
705
688
|
};
|
|
689
|
+
ACCOUNT_MANIFEST_PERMISSIONS = Object.freeze([
|
|
690
|
+
{
|
|
691
|
+
service: "tinycloud.kv",
|
|
692
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
693
|
+
path: ACCOUNT_REGISTRY_PATH,
|
|
694
|
+
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
service: "tinycloud.kv",
|
|
698
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
699
|
+
path: "spaces/",
|
|
700
|
+
actions: [KV.GET, KV.PUT, KV.LIST]
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
service: "tinycloud.kv",
|
|
704
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
705
|
+
path: "system/bootstrap/complete",
|
|
706
|
+
actions: [KV.GET, KV.PUT]
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
service: "tinycloud.delegation",
|
|
710
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
711
|
+
path: "",
|
|
712
|
+
actions: ["tinycloud.delegation/list"]
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
service: "tinycloud.sql",
|
|
716
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
717
|
+
path: "account",
|
|
718
|
+
actions: [SQL.READ, SQL.WRITE, SQL.SCHEMA]
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
service: "tinycloud.capabilities",
|
|
722
|
+
space: ACCOUNT_REGISTRY_SPACE,
|
|
723
|
+
path: "",
|
|
724
|
+
actions: [CAPABILITIES2.READ]
|
|
725
|
+
}
|
|
726
|
+
]);
|
|
727
|
+
BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST = composeBootstrapSpaceManifest(BOOTSTRAP_DEFAULT_SPACE);
|
|
728
|
+
BOOTSTRAP_WIDENED_DEFAULT_SESSION_REQUEST = {
|
|
729
|
+
...BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST,
|
|
730
|
+
resources: [
|
|
731
|
+
...BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST.resources,
|
|
732
|
+
...ACCOUNT_MANIFEST_PERMISSIONS.map((resource) => ({
|
|
733
|
+
...resource,
|
|
734
|
+
actions: [...resource.actions]
|
|
735
|
+
}))
|
|
736
|
+
]
|
|
737
|
+
};
|
|
706
738
|
BOOTSTRAP_SESSION_REQUESTS = Object.freeze(
|
|
707
739
|
Object.fromEntries(
|
|
708
740
|
BOOTSTRAP_SPACE_NAMES.map((space) => [
|
|
709
741
|
space,
|
|
710
|
-
composeBootstrapSpaceManifest(space)
|
|
742
|
+
space === BOOTSTRAP_DEFAULT_SPACE ? BOOTSTRAP_WIDENED_DEFAULT_SESSION_REQUEST : composeBootstrapSpaceManifest(space)
|
|
711
743
|
])
|
|
712
744
|
)
|
|
713
745
|
);
|
|
@@ -762,10 +794,10 @@ var require_decrypt_transport_response_error = __commonJS({
|
|
|
762
794
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
763
795
|
var DecryptTransportResponseError_exports = {};
|
|
764
796
|
__export2(DecryptTransportResponseError_exports, {
|
|
765
|
-
DecryptTransportResponseError: () =>
|
|
797
|
+
DecryptTransportResponseError: () => DecryptTransportResponseError2
|
|
766
798
|
});
|
|
767
799
|
module2.exports = __toCommonJS2(DecryptTransportResponseError_exports);
|
|
768
|
-
var
|
|
800
|
+
var DecryptTransportResponseError2 = class extends Error {
|
|
769
801
|
constructor(status, permissionHint) {
|
|
770
802
|
super("Node decrypt request failed");
|
|
771
803
|
this.status = status;
|
|
@@ -2397,7 +2429,7 @@ function encOk(data) {
|
|
|
2397
2429
|
function encErr(error) {
|
|
2398
2430
|
return { ok: false, error };
|
|
2399
2431
|
}
|
|
2400
|
-
var import_zod, import_decrypt_transport_response_error,
|
|
2432
|
+
var import_zod, 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;
|
|
2401
2433
|
var init_dist2 = __esm({
|
|
2402
2434
|
"../sdk-services/dist/index.js"() {
|
|
2403
2435
|
"use strict";
|
|
@@ -2405,8 +2437,6 @@ var init_dist2 = __esm({
|
|
|
2405
2437
|
init_dist();
|
|
2406
2438
|
init_dist();
|
|
2407
2439
|
import_decrypt_transport_response_error = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2408
|
-
import_decrypt_transport_response_error2 = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2409
|
-
import_decrypt_transport_response_error3 = __toESM(require_decrypt_transport_response_error(), 1);
|
|
2410
2440
|
ErrorCodes = {
|
|
2411
2441
|
// Common errors
|
|
2412
2442
|
NOT_FOUND: "NOT_FOUND",
|
|
@@ -3678,6 +3708,7 @@ var init_dist2 = __esm({
|
|
|
3678
3708
|
}
|
|
3679
3709
|
seen.add(path);
|
|
3680
3710
|
}
|
|
3711
|
+
let requestMayHaveDispatched = false;
|
|
3681
3712
|
try {
|
|
3682
3713
|
const body = new FormData();
|
|
3683
3714
|
for (let index = 0; index < items.length; index++) {
|
|
@@ -3695,14 +3726,31 @@ var init_dist2 = __esm({
|
|
|
3695
3726
|
action: KVAction.PUT
|
|
3696
3727
|
}))
|
|
3697
3728
|
);
|
|
3698
|
-
const
|
|
3729
|
+
const url = `${this.host}/invoke`;
|
|
3730
|
+
const init = {
|
|
3699
3731
|
method: "POST",
|
|
3700
3732
|
headers,
|
|
3701
3733
|
body,
|
|
3702
3734
|
signal: this.combineSignals(options?.signal)
|
|
3703
|
-
}
|
|
3735
|
+
};
|
|
3736
|
+
const fetchFn = this.context.fetch;
|
|
3737
|
+
requestMayHaveDispatched = true;
|
|
3738
|
+
const response = await fetchFn(url, init);
|
|
3704
3739
|
if (!response.ok) {
|
|
3705
|
-
|
|
3740
|
+
let errorText;
|
|
3741
|
+
try {
|
|
3742
|
+
errorText = await response.text();
|
|
3743
|
+
} catch (textError) {
|
|
3744
|
+
const cause = textError instanceof Error ? textError : new Error(String(textError));
|
|
3745
|
+
return err(
|
|
3746
|
+
serviceError(
|
|
3747
|
+
ErrorCodes.KV_WRITE_FAILED,
|
|
3748
|
+
`Failed to batch put ${items.length} key(s): ${response.status} - <response body could not be read: ${cause.message}>`,
|
|
3749
|
+
"kv",
|
|
3750
|
+
{ cause, meta: { status: response.status, statusText: response.statusText } }
|
|
3751
|
+
)
|
|
3752
|
+
);
|
|
3753
|
+
}
|
|
3706
3754
|
if (response.status === 401 || response.status === 403) {
|
|
3707
3755
|
const { resource, action } = parseAuthError(errorText);
|
|
3708
3756
|
return err(authUnauthorizedError("kv", errorText, {
|
|
@@ -3728,19 +3776,73 @@ var init_dist2 = __esm({
|
|
|
3728
3776
|
)
|
|
3729
3777
|
);
|
|
3730
3778
|
}
|
|
3731
|
-
|
|
3732
|
-
|
|
3779
|
+
let rawBody;
|
|
3780
|
+
try {
|
|
3781
|
+
rawBody = await response.json();
|
|
3782
|
+
} catch (jsonError) {
|
|
3783
|
+
const cause = jsonError instanceof Error ? jsonError : new Error(String(jsonError));
|
|
3784
|
+
return err(
|
|
3785
|
+
serviceError(
|
|
3786
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3787
|
+
`KV batchPut response was not valid JSON: ${cause.message}`,
|
|
3788
|
+
"kv",
|
|
3789
|
+
{
|
|
3790
|
+
cause,
|
|
3791
|
+
meta: {
|
|
3792
|
+
requestMayHaveDispatched: true,
|
|
3793
|
+
responseReceived: true,
|
|
3794
|
+
status: response.status,
|
|
3795
|
+
outcome: "batch-unconfirmed"
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
)
|
|
3799
|
+
);
|
|
3800
|
+
}
|
|
3801
|
+
const batchResponse = this.normalizeBatchPutResponse(rawBody);
|
|
3802
|
+
if (!batchResponse) {
|
|
3733
3803
|
return err(
|
|
3734
3804
|
serviceError(
|
|
3735
3805
|
ErrorCodes.NETWORK_ERROR,
|
|
3736
3806
|
"KV batchPut response did not include matching written keys and count",
|
|
3737
|
-
"kv"
|
|
3807
|
+
"kv",
|
|
3808
|
+
{
|
|
3809
|
+
meta: {
|
|
3810
|
+
requestMayHaveDispatched: true,
|
|
3811
|
+
responseReceived: true,
|
|
3812
|
+
status: response.status,
|
|
3813
|
+
outcome: "batch-unconfirmed"
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
)
|
|
3817
|
+
);
|
|
3818
|
+
}
|
|
3819
|
+
const requestedPaths = new Set(paths);
|
|
3820
|
+
const writtenPaths = new Set(batchResponse.written);
|
|
3821
|
+
const matchesRequest = batchResponse.count === paths.length && batchResponse.written.length === paths.length && writtenPaths.size === paths.length && batchResponse.written.every((key) => requestedPaths.has(key));
|
|
3822
|
+
if (!matchesRequest) {
|
|
3823
|
+
return err(
|
|
3824
|
+
serviceError(
|
|
3825
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3826
|
+
`KV batchPut response did not confirm all ${paths.length} requested key(s) were written`,
|
|
3827
|
+
"kv",
|
|
3828
|
+
{
|
|
3829
|
+
meta: {
|
|
3830
|
+
requestMayHaveDispatched: true,
|
|
3831
|
+
responseReceived: true,
|
|
3832
|
+
status: response.status,
|
|
3833
|
+
outcome: "batch-unconfirmed"
|
|
3834
|
+
}
|
|
3835
|
+
}
|
|
3738
3836
|
)
|
|
3739
3837
|
);
|
|
3740
3838
|
}
|
|
3741
3839
|
return ok(batchResponse);
|
|
3742
3840
|
} catch (error) {
|
|
3743
|
-
|
|
3841
|
+
const wrapped = wrapError("kv", error);
|
|
3842
|
+
return err({
|
|
3843
|
+
...wrapped,
|
|
3844
|
+
meta: { ...wrapped.meta, requestMayHaveDispatched }
|
|
3845
|
+
});
|
|
3744
3846
|
}
|
|
3745
3847
|
});
|
|
3746
3848
|
}
|
|
@@ -6737,15 +6839,28 @@ function normalizeSpace(space) {
|
|
|
6737
6839
|
function isCapabilitySubset(requested, granted) {
|
|
6738
6840
|
const missing = [];
|
|
6739
6841
|
for (const req of requested) {
|
|
6740
|
-
const
|
|
6741
|
-
|
|
6842
|
+
const matchingScope = granted.filter(
|
|
6843
|
+
(entry) => canonicalizeEntryScopeMatches(req, entry)
|
|
6844
|
+
);
|
|
6845
|
+
const requestedActions = expandActionShortNames(
|
|
6846
|
+
req.service,
|
|
6847
|
+
req.actions
|
|
6848
|
+
);
|
|
6849
|
+
const grantedActions = matchingScope.flatMap(
|
|
6850
|
+
(entry) => expandActionShortNames(entry.service, entry.actions)
|
|
6851
|
+
);
|
|
6852
|
+
const covered = requestedActions.every(
|
|
6853
|
+
(requestedAction) => grantedActions.some(
|
|
6854
|
+
(grantedAction) => actionContains(grantedAction, requestedAction)
|
|
6855
|
+
)
|
|
6856
|
+
);
|
|
6857
|
+
if (!covered) {
|
|
6742
6858
|
missing.push(cloneEntry(req));
|
|
6743
|
-
continue;
|
|
6744
6859
|
}
|
|
6745
6860
|
}
|
|
6746
6861
|
return { subset: missing.length === 0, missing };
|
|
6747
6862
|
}
|
|
6748
|
-
function
|
|
6863
|
+
function canonicalizeEntryScopeMatches(requested, granted) {
|
|
6749
6864
|
if (requested.service !== granted.service) {
|
|
6750
6865
|
return false;
|
|
6751
6866
|
}
|
|
@@ -6755,15 +6870,6 @@ function canonicalizeEntryMatches(requested, granted) {
|
|
|
6755
6870
|
if (!pathContains(granted.path, requested.path)) {
|
|
6756
6871
|
return false;
|
|
6757
6872
|
}
|
|
6758
|
-
const reqActions = new Set(
|
|
6759
|
-
expandActionShortNames(requested.service, requested.actions)
|
|
6760
|
-
);
|
|
6761
|
-
const grantedActions = expandActionShortNames(granted.service, granted.actions);
|
|
6762
|
-
for (const a of reqActions) {
|
|
6763
|
-
if (!grantedActions.some((grantedAction) => actionContains(grantedAction, a))) {
|
|
6764
|
-
return false;
|
|
6765
|
-
}
|
|
6766
|
-
}
|
|
6767
6873
|
if (!recapCaveatsEqual(requested.caveats, granted.caveats)) {
|
|
6768
6874
|
return false;
|
|
6769
6875
|
}
|