@tinycloud/sdk-core 2.2.0-beta.6 → 2.2.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -63,6 +63,7 @@ __export(index_exports, {
63
63
  SERVICE_SHORT_TO_LONG: () => SERVICE_SHORT_TO_LONG,
64
64
  SQLAction: () => import_sdk_services4.SQLAction,
65
65
  SQLService: () => import_sdk_services4.SQLService,
66
+ SecretsService: () => import_sdk_services4.SecretsService,
66
67
  ServiceContext: () => import_sdk_services4.ServiceContext,
67
68
  SessionExpiredError: () => SessionExpiredError,
68
69
  SharingService: () => SharingService,
@@ -269,6 +270,7 @@ var Space = class {
269
270
  this._id = config.id;
270
271
  this._name = config.name;
271
272
  this._kv = config.createKV(config.id);
273
+ this._vault = config.createVault(config.id);
272
274
  this._delegations = config.createDelegations(config.id);
273
275
  this._sharing = config.createSharing(config.id);
274
276
  this._getInfo = config.getInfo;
@@ -291,6 +293,12 @@ var Space = class {
291
293
  get kv() {
292
294
  return this._kv;
293
295
  }
296
+ /**
297
+ * Data Vault operations scoped to this space.
298
+ */
299
+ get vault() {
300
+ return this._vault;
301
+ }
294
302
  /**
295
303
  * Delegation operations scoped to this space.
296
304
  */
@@ -674,6 +682,8 @@ var SpaceConfigSchema = import_zod4.z.object({
674
682
  name: import_zod4.z.string(),
675
683
  /** Factory function to create a space-scoped KV service */
676
684
  createKV: import_zod4.z.function(),
685
+ /** Factory function to create a space-scoped Data Vault service */
686
+ createVault: import_zod4.z.function(),
677
687
  /** Factory function to create space-scoped delegations */
678
688
  createDelegations: import_zod4.z.function(),
679
689
  /** Factory function to create space-scoped sharing */
@@ -694,6 +704,8 @@ var SpaceServiceConfigSchema = import_zod4.z.object({
694
704
  capabilityRegistry: import_zod4.z.unknown().optional(),
695
705
  /** Factory function to create a space-scoped KV service */
696
706
  createKVService: import_zod4.z.function().optional(),
707
+ /** Factory function to create a space-scoped Data Vault service */
708
+ createVaultService: import_zod4.z.function().optional(),
697
709
  /** User's PKH DID (derived from address or provided explicitly) */
698
710
  userDid: import_zod4.z.string().optional(),
699
711
  /** Optional SharingService for v2 sharing links (client-side) */
@@ -935,6 +947,7 @@ var SpaceService = class {
935
947
  this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
936
948
  this.capabilityRegistry = config.capabilityRegistry;
937
949
  this.createKVServiceFn = config.createKVService;
950
+ this.createVaultServiceFn = config.createVaultService;
938
951
  this._userDid = config.userDid;
939
952
  this.sharingService = config.sharingService;
940
953
  this.createDelegationFn = config.createDelegation;
@@ -949,6 +962,7 @@ var SpaceService = class {
949
962
  if (config.fetch) this.fetchFn = config.fetch;
950
963
  if (config.capabilityRegistry) this.capabilityRegistry = config.capabilityRegistry;
951
964
  if (config.createKVService) this.createKVServiceFn = config.createKVService;
965
+ if (config.createVaultService) this.createVaultServiceFn = config.createVaultService;
952
966
  if (config.userDid !== void 0) this._userDid = config.userDid;
953
967
  if (config.sharingService) this.sharingService = config.sharingService;
954
968
  if (config.createDelegation) this.createDelegationFn = config.createDelegation;
@@ -1231,6 +1245,7 @@ var SpaceService = class {
1231
1245
  id: spaceId,
1232
1246
  name,
1233
1247
  createKV: this.createSpaceScopedKV.bind(this),
1248
+ createVault: this.createSpaceScopedVault.bind(this),
1234
1249
  createDelegations: this.createSpaceScopedDelegations.bind(this),
1235
1250
  createSharing: this.createSpaceScopedSharing.bind(this),
1236
1251
  getInfo: this.getSpaceInfo.bind(this)
@@ -1360,6 +1375,21 @@ var SpaceService = class {
1360
1375
  }
1361
1376
  });
1362
1377
  }
1378
+ /**
1379
+ * Create a space-scoped Data Vault service.
1380
+ */
1381
+ createSpaceScopedVault(spaceId) {
1382
+ if (this.createVaultServiceFn) {
1383
+ return this.createVaultServiceFn(spaceId);
1384
+ }
1385
+ return new Proxy({}, {
1386
+ get: () => {
1387
+ throw new Error(
1388
+ "Vault service factory not configured. Provide createVaultService in SpaceServiceConfig."
1389
+ );
1390
+ }
1391
+ });
1392
+ }
1363
1393
  /**
1364
1394
  * Create space-scoped delegation operations.
1365
1395
  */
@@ -2765,6 +2795,8 @@ var DEFAULT_MANIFEST_VERSION = 1;
2765
2795
  var DEFAULT_MANIFEST_SPACE = "applications";
2766
2796
  var ACCOUNT_REGISTRY_SPACE = "account";
2767
2797
  var ACCOUNT_REGISTRY_PATH = "applications/";
2798
+ var SECRETS_SPACE = "secrets";
2799
+ var SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
2768
2800
  var SERVICE_SHORT_TO_LONG = Object.freeze({
2769
2801
  kv: "tinycloud.kv",
2770
2802
  sql: "tinycloud.sql",
@@ -2918,8 +2950,39 @@ function validateManifest(input) {
2918
2950
  (p, i) => validatePermissionEntry(p, `permissions[${i}]`)
2919
2951
  );
2920
2952
  }
2953
+ if (m.secrets !== void 0) {
2954
+ validateManifestSecrets(m.secrets);
2955
+ }
2921
2956
  return m;
2922
2957
  }
2958
+ function validateManifestSecrets(secrets) {
2959
+ if (secrets === null || typeof secrets !== "object" || Array.isArray(secrets)) {
2960
+ throw new ManifestValidationError("manifest.secrets must be an object");
2961
+ }
2962
+ for (const [name, spec] of Object.entries(secrets)) {
2963
+ if (!SECRET_NAME_RE.test(name)) {
2964
+ throw new ManifestValidationError(
2965
+ `manifest.secrets.${name} must match ${SECRET_NAME_RE.source}`
2966
+ );
2967
+ }
2968
+ const actions = secretActionsFromSpec(name, spec);
2969
+ if (actions.length === 0) {
2970
+ throw new ManifestValidationError(
2971
+ `manifest.secrets.${name} actions must be non-empty`
2972
+ );
2973
+ }
2974
+ for (const action of actions) {
2975
+ if (typeof action !== "string" || action.length === 0) {
2976
+ throw new ManifestValidationError(
2977
+ `manifest.secrets.${name} actions must be non-empty strings`
2978
+ );
2979
+ }
2980
+ }
2981
+ if (spec !== null && typeof spec === "object" && !Array.isArray(spec) && spec.expiry !== void 0) {
2982
+ parseExpiry(spec.expiry);
2983
+ }
2984
+ }
2985
+ }
2923
2986
  function validatePermissionEntry(p, path) {
2924
2987
  if (p === null || typeof p !== "object") {
2925
2988
  throw new ManifestValidationError(`${path} must be an object`);
@@ -2985,7 +3048,12 @@ function resolveManifest(input) {
2985
3048
  const tier = normalizeDefaults(manifest.defaults);
2986
3049
  const defaultEntries = defaultEntriesForTier(tier);
2987
3050
  const explicitEntries = manifest.permissions ?? [];
2988
- const allEntries = [...defaultEntries, ...explicitEntries];
3051
+ const secretEntries = secretEntriesForManifest(manifest.secrets);
3052
+ const allEntries = [
3053
+ ...defaultEntries,
3054
+ ...explicitEntries,
3055
+ ...secretEntries
3056
+ ];
2989
3057
  const resources = withCapabilitiesReadForSpaces(
2990
3058
  allEntries.map((entry) => resolveEntry(entry, prefix, expiryMs, space))
2991
3059
  );
@@ -3007,6 +3075,92 @@ function resolveManifest(input) {
3007
3075
  additionalDelegates
3008
3076
  };
3009
3077
  }
3078
+ function normalizeSecretActions(actions) {
3079
+ const out = [];
3080
+ const seen = /* @__PURE__ */ new Set();
3081
+ const add = (action) => {
3082
+ if (!seen.has(action)) {
3083
+ out.push(action);
3084
+ seen.add(action);
3085
+ }
3086
+ };
3087
+ for (const action of actions) {
3088
+ if (action === "read") {
3089
+ add("get");
3090
+ continue;
3091
+ }
3092
+ if (action === "write") {
3093
+ add("put");
3094
+ continue;
3095
+ }
3096
+ if (action === "delete") {
3097
+ add("del");
3098
+ continue;
3099
+ }
3100
+ if (action === "get" || action === "put" || action === "del" || action === "list" || action === "metadata") {
3101
+ add(action);
3102
+ continue;
3103
+ }
3104
+ if (action === "tinycloud.kv/get" || action === "tinycloud.kv/put" || action === "tinycloud.kv/del" || action === "tinycloud.kv/list" || action === "tinycloud.kv/metadata") {
3105
+ add(action);
3106
+ continue;
3107
+ }
3108
+ throw new ManifestValidationError(
3109
+ `unknown secret action ${JSON.stringify(action)}; expected read, write, delete, list, or metadata`
3110
+ );
3111
+ }
3112
+ return out;
3113
+ }
3114
+ function secretActionsFromSpec(name, spec) {
3115
+ if (spec === true) {
3116
+ return ["read"];
3117
+ }
3118
+ if (typeof spec === "string") {
3119
+ return [spec];
3120
+ }
3121
+ if (Array.isArray(spec)) {
3122
+ return spec;
3123
+ }
3124
+ if (spec === null || typeof spec !== "object") {
3125
+ throw new ManifestValidationError(
3126
+ `manifest.secrets.${name} must be true, a string action, an actions array, or an object`
3127
+ );
3128
+ }
3129
+ if (spec.actions === void 0) {
3130
+ return ["read"];
3131
+ }
3132
+ if (typeof spec.actions === "string") {
3133
+ return [spec.actions];
3134
+ }
3135
+ if (Array.isArray(spec.actions)) {
3136
+ return spec.actions;
3137
+ }
3138
+ throw new ManifestValidationError(
3139
+ `manifest.secrets.${name}.actions must be a string or array`
3140
+ );
3141
+ }
3142
+ function secretEntriesForManifest(secrets) {
3143
+ if (secrets === void 0) {
3144
+ return [];
3145
+ }
3146
+ const entries = [];
3147
+ for (const [name, spec] of Object.entries(secrets)) {
3148
+ const actions = secretActionsFromSpec(name, spec);
3149
+ const extra = spec !== true && typeof spec === "object" && !Array.isArray(spec) ? spec : {};
3150
+ for (const base of ["keys", "vault"]) {
3151
+ entries.push({
3152
+ service: "tinycloud.kv",
3153
+ space: SECRETS_SPACE,
3154
+ path: `${base}/secrets/${name}`,
3155
+ actions: normalizeSecretActions(actions),
3156
+ skipPrefix: true,
3157
+ ...extra.expiry !== void 0 ? { expiry: extra.expiry } : {},
3158
+ ...extra.description !== void 0 ? { description: extra.description } : {}
3159
+ });
3160
+ }
3161
+ }
3162
+ return entries;
3163
+ }
3010
3164
  function resolveEntry(entry, prefix, _inheritedExpiryMs, inheritedSpace) {
3011
3165
  const resolvedPath = applyPrefix(
3012
3166
  prefix,
@@ -4883,6 +5037,7 @@ function parseRecapCapabilities(parseWasm, siwe) {
4883
5037
  SERVICE_SHORT_TO_LONG,
4884
5038
  SQLAction,
4885
5039
  SQLService,
5040
+ SecretsService,
4886
5041
  ServiceContext,
4887
5042
  SessionExpiredError,
4888
5043
  SharingService,