@tinycloud/node-sdk 3.7.0 → 3.8.0-beta.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.
@@ -275,7 +275,9 @@ interface NodeUserAuthorizationConfig {
275
275
  * unrestricted `get` covering it is already requested. Storage and
276
276
  * scheduling never reach this layer.
277
277
  */
278
- replication?: Pick<ReplicationOptions, "enabled" | "prefixes" | "allowSecrets">;
278
+ replication?: Pick<ReplicationOptions, "enabled" | "prefixes" | "allowSecrets" | "syncScope">;
279
+ /** Extra top-level resource URIs and their abilities added to the sign-in ReCap (e.g. named-key prefixes). */
280
+ additionalRawAbilities?: Record<string, string[]>;
279
281
  /**
280
282
  * Mints the replica session stamp on each fresh sign-in (TC-858 §4). Returns
281
283
  * `undefined` when replication is off, so the persisted session carries no stamp.
@@ -348,6 +350,7 @@ declare class NodeUserAuthorization implements IUserAuthorization {
348
350
  private readonly localNodeIdentityStore?;
349
351
  private readonly enablePublicSpace;
350
352
  private readonly replication?;
353
+ private readonly additionalRawAbilities?;
351
354
  private readonly establishReplicaStamp?;
352
355
  private readonly nonce?;
353
356
  private readonly siweConfig?;
@@ -558,7 +561,9 @@ declare class NodeUserAuthorization implements IUserAuthorization {
558
561
  */
559
562
  replicationSignInEntries(): PermissionEntry[];
560
563
  private defaultEncryptionNetworkId;
564
+ /** Sign-in capabilities plus the caller's additional top-level resource abilities. */
561
565
  private resolveSignInCapabilities;
566
+ private resolveBaseSignInCapabilities;
562
567
  /**
563
568
  * Build SIWE overrides from the top-level nonce and siweConfig.
564
569
  * - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
@@ -1090,6 +1095,8 @@ interface TinyCloudNodeConfig {
1090
1095
  * the same cross-process profile lock as SQLite and pending writes. Browser storage uses
1091
1096
  * its mandatory origin Web Lock instead. Missing guards gate the replica, not the session.
1092
1097
  */
1098
+ /** Extra top-level resource URIs and their abilities added to the sign-in ReCap (e.g. named-key prefixes). */
1099
+ additionalRawAbilities?: Record<string, string[]>;
1093
1100
  replication?: ReplicationOptions & {
1094
1101
  storage: KVReplicaStorage;
1095
1102
  mode?: "background" | "foreground";
@@ -1393,6 +1400,9 @@ declare class TinyCloudNode {
1393
1400
  reason?: string;
1394
1401
  warnings?: BootstrapWarning[];
1395
1402
  };
1403
+ private _freshEncryptionNetworkCreated;
1404
+ /** Whether the last sign-in's fresh account bootstrap created its encryption network. */
1405
+ get freshEncryptionNetworkCreated(): boolean;
1396
1406
  /**
1397
1407
  * Turns every service's storage rejections into one `storage.full` event,
1398
1408
  * and remembers whose storage is full so sign-in and listing skip their
@@ -275,7 +275,9 @@ interface NodeUserAuthorizationConfig {
275
275
  * unrestricted `get` covering it is already requested. Storage and
276
276
  * scheduling never reach this layer.
277
277
  */
278
- replication?: Pick<ReplicationOptions, "enabled" | "prefixes" | "allowSecrets">;
278
+ replication?: Pick<ReplicationOptions, "enabled" | "prefixes" | "allowSecrets" | "syncScope">;
279
+ /** Extra top-level resource URIs and their abilities added to the sign-in ReCap (e.g. named-key prefixes). */
280
+ additionalRawAbilities?: Record<string, string[]>;
279
281
  /**
280
282
  * Mints the replica session stamp on each fresh sign-in (TC-858 §4). Returns
281
283
  * `undefined` when replication is off, so the persisted session carries no stamp.
@@ -348,6 +350,7 @@ declare class NodeUserAuthorization implements IUserAuthorization {
348
350
  private readonly localNodeIdentityStore?;
349
351
  private readonly enablePublicSpace;
350
352
  private readonly replication?;
353
+ private readonly additionalRawAbilities?;
351
354
  private readonly establishReplicaStamp?;
352
355
  private readonly nonce?;
353
356
  private readonly siweConfig?;
@@ -558,7 +561,9 @@ declare class NodeUserAuthorization implements IUserAuthorization {
558
561
  */
559
562
  replicationSignInEntries(): PermissionEntry[];
560
563
  private defaultEncryptionNetworkId;
564
+ /** Sign-in capabilities plus the caller's additional top-level resource abilities. */
561
565
  private resolveSignInCapabilities;
566
+ private resolveBaseSignInCapabilities;
562
567
  /**
563
568
  * Build SIWE overrides from the top-level nonce and siweConfig.
564
569
  * - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
@@ -1090,6 +1095,8 @@ interface TinyCloudNodeConfig {
1090
1095
  * the same cross-process profile lock as SQLite and pending writes. Browser storage uses
1091
1096
  * its mandatory origin Web Lock instead. Missing guards gate the replica, not the session.
1092
1097
  */
1098
+ /** Extra top-level resource URIs and their abilities added to the sign-in ReCap (e.g. named-key prefixes). */
1099
+ additionalRawAbilities?: Record<string, string[]>;
1093
1100
  replication?: ReplicationOptions & {
1094
1101
  storage: KVReplicaStorage;
1095
1102
  mode?: "background" | "foreground";
@@ -1393,6 +1400,9 @@ declare class TinyCloudNode {
1393
1400
  reason?: string;
1394
1401
  warnings?: BootstrapWarning[];
1395
1402
  };
1403
+ private _freshEncryptionNetworkCreated;
1404
+ /** Whether the last sign-in's fresh account bootstrap created its encryption network. */
1405
+ get freshEncryptionNetworkCreated(): boolean;
1396
1406
  /**
1397
1407
  * Turns every service's storage rejections into one `storage.full` event,
1398
1408
  * and remembers whose storage is full so sign-in and listing skip their
@@ -1,7 +1,7 @@
1
1
  import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
2
2
  import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
3
3
  import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
4
- import { T as TinyCloudNode } from './TinyCloudNode-DD7qjyLU.cjs';
4
+ import { T as TinyCloudNode } from './TinyCloudNode-DDfx8Fx5.cjs';
5
5
 
6
6
  /** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
7
7
  declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
@@ -12,7 +12,7 @@ declare function hasUnrestrictedGetCoverage(entries: readonly PermissionEntry[],
12
12
  declare function augmentSignInEntriesWithReplication(input: {
13
13
  entries: readonly PermissionEntry[];
14
14
  primarySpaceId: string;
15
- replication?: Pick<ReplicationOptions, "prefixes" | "allowSecrets">;
15
+ replication?: Pick<ReplicationOptions, "prefixes" | "allowSecrets" | "syncScope">;
16
16
  }): PermissionEntry[];
17
17
 
18
18
  /** Report a completed deny from the already-loaded authority; delivery was revoked synchronously. */
@@ -1,7 +1,7 @@
1
1
  import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
2
2
  import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
3
3
  import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
4
- import { T as TinyCloudNode } from './TinyCloudNode-Cw00iiSP.js';
4
+ import { T as TinyCloudNode } from './TinyCloudNode-Ckqu_fqH.js';
5
5
 
6
6
  /** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
7
7
  declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
@@ -12,7 +12,7 @@ declare function hasUnrestrictedGetCoverage(entries: readonly PermissionEntry[],
12
12
  declare function augmentSignInEntriesWithReplication(input: {
13
13
  entries: readonly PermissionEntry[];
14
14
  primarySpaceId: string;
15
- replication?: Pick<ReplicationOptions, "prefixes" | "allowSecrets">;
15
+ replication?: Pick<ReplicationOptions, "prefixes" | "allowSecrets" | "syncScope">;
16
16
  }): PermissionEntry[];
17
17
 
18
18
  /** Report a completed deny from the already-loaded authority; delivery was revoked synchronously. */
package/dist/core.cjs CHANGED
@@ -375,7 +375,7 @@ function augmentSignInEntriesWithReplication(input) {
375
375
  }
376
376
  eligiblePaths.push(path);
377
377
  }
378
- if (eligiblePaths.length === replication.prefixes.length && eligiblePaths.length > 0 && hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, "")) {
378
+ if (replication.syncScope !== "prefixes" && eligiblePaths.length === replication.prefixes.length && eligiblePaths.length > 0 && hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, "")) {
379
379
  return [{
380
380
  service: KV_SERVICE,
381
381
  space: input.primarySpaceId,
@@ -547,6 +547,7 @@ var NodeUserAuthorization = class {
547
547
  this.includeAccountRegistryPermissions = config.includeAccountRegistryPermissions ?? true;
548
548
  this.replication = config.replication?.enabled === true ? config.replication : void 0;
549
549
  this.establishReplicaStamp = config.establishReplicaStamp;
550
+ this.additionalRawAbilities = config.additionalRawAbilities;
550
551
  this._manifest = config.manifest;
551
552
  this._capabilityRequest = config.capabilityRequest;
552
553
  this.sessionManager = config.sessionManager ?? this.wasm.createSessionManager();
@@ -977,7 +978,18 @@ var NodeUserAuthorization = class {
977
978
  defaultEncryptionNetworkId(address, chainId) {
978
979
  return `urn:tinycloud:encryption:${(0, import_sdk_core5.pkhDid)(address, chainId)}:default`;
979
980
  }
981
+ /** Sign-in capabilities plus the caller's additional top-level resource abilities. */
980
982
  resolveSignInCapabilities(address, chainId) {
983
+ const base = this.resolveBaseSignInCapabilities(address, chainId);
984
+ const extra = this.additionalRawAbilities;
985
+ if (extra === void 0 || Object.keys(extra).length === 0) return base;
986
+ const rawAbilities = { ...base.rawAbilities ?? {} };
987
+ for (const [resource, actions] of Object.entries(extra)) {
988
+ for (const action of actions) addRawAbility(rawAbilities, resource, action);
989
+ }
990
+ return { ...base, rawAbilities };
991
+ }
992
+ resolveBaseSignInCapabilities(address, chainId) {
981
993
  const request = this.getCapabilityRequest();
982
994
  if (request === void 0) {
983
995
  const defaultNetworkId = this.defaultEncryptionNetworkId(address, chainId);
@@ -3849,6 +3861,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3849
3861
  this._bootstrapStatus = {
3850
3862
  skipped: false
3851
3863
  };
3864
+ this._freshEncryptionNetworkCreated = false;
3852
3865
  /**
3853
3866
  * Turns every service's storage rejections into one `storage.full` event,
3854
3867
  * and remembers whose storage is full so sign-in and listing skip their
@@ -4012,6 +4025,10 @@ var _TinyCloudNode = class _TinyCloudNode {
4012
4025
  get bootstrapStatus() {
4013
4026
  return this._bootstrapStatus;
4014
4027
  }
4028
+ /** Whether the last sign-in's fresh account bootstrap created its encryption network. */
4029
+ get freshEncryptionNetworkCreated() {
4030
+ return this._freshEncryptionNetworkCreated;
4031
+ }
4015
4032
  /**
4016
4033
  * Subscribe to `storage.full`. It fires on the first write any service had
4017
4034
  * rejected because the owner's TinyCloud storage is full
@@ -4214,6 +4231,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4214
4231
  signStrategy: config.signStrategy ?? { type: "auto-sign" },
4215
4232
  wasmBindings: this.wasmBindings,
4216
4233
  ...config.replication?.enabled === true ? { establishReplicaStamp: this.establishReplicaStamp } : {},
4234
+ ...config.additionalRawAbilities === void 0 ? {} : { additionalRawAbilities: config.additionalRawAbilities },
4217
4235
  sessionManager: this.sessionManager,
4218
4236
  sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
4219
4237
  domain: this.siweDomain,
@@ -4242,7 +4260,8 @@ var _TinyCloudNode = class _TinyCloudNode {
4242
4260
  replication: config.replication?.enabled === true ? {
4243
4261
  enabled: true,
4244
4262
  prefixes: config.replication.prefixes,
4245
- allowSecrets: config.replication.allowSecrets === true
4263
+ allowSecrets: config.replication.allowSecrets === true,
4264
+ syncScope: config.replication.syncScope
4246
4265
  } : void 0
4247
4266
  });
4248
4267
  this.tc = new import_sdk_core11.TinyCloud(this.auth, {
@@ -4779,6 +4798,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4779
4798
  async bootstrapAccountIfNeeded() {
4780
4799
  this._bootstrapSkipped = false;
4781
4800
  this._bootstrapStatus = { skipped: false };
4801
+ this._freshEncryptionNetworkCreated = false;
4782
4802
  if (this.config.autoBootstrapAccount === false) {
4783
4803
  this._bootstrapStatus = { skipped: true, reason: "auto-bootstrap-disabled" };
4784
4804
  return false;
@@ -5068,6 +5088,7 @@ var _TinyCloudNode = class _TinyCloudNode {
5068
5088
  }
5069
5089
  if (step.kind === "encryption-network-create") {
5070
5090
  await this.ensureEncryptionNetwork(step.networkId, { assumeMissing: mode === "fresh" });
5091
+ if (mode === "fresh") this._freshEncryptionNetworkCreated = true;
5071
5092
  }
5072
5093
  if (step.kind === "secret-records-schema") {
5073
5094
  const db = this.sqlForSpace(step.spaceId).db(step.database);
@@ -6662,7 +6683,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6662
6683
  replication: this.config.replication?.enabled === true ? {
6663
6684
  enabled: true,
6664
6685
  prefixes: this.config.replication.prefixes,
6665
- allowSecrets: this.config.replication.allowSecrets === true
6686
+ allowSecrets: this.config.replication.allowSecrets === true,
6687
+ syncScope: this.config.replication.syncScope
6666
6688
  } : void 0
6667
6689
  });
6668
6690
  this.tc = new import_sdk_core11.TinyCloud(this.auth, {
@@ -6724,7 +6746,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6724
6746
  replication: this.config.replication?.enabled === true ? {
6725
6747
  enabled: true,
6726
6748
  prefixes: this.config.replication.prefixes,
6727
- allowSecrets: this.config.replication.allowSecrets === true
6749
+ allowSecrets: this.config.replication.allowSecrets === true,
6750
+ syncScope: this.config.replication.syncScope
6728
6751
  } : void 0
6729
6752
  });
6730
6753
  this.tc = new import_sdk_core11.TinyCloud(this.auth, {