@keetanetwork/anchor 0.0.52 → 0.0.53

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.52",
3
+ "version": "0.0.53",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@keetanetwork/anchor",
9
- "version": "0.0.52",
9
+ "version": "0.0.53",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "dependencies": {
12
12
  "@keetanetwork/currency-info": "1.2.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.52",
3
+ "version": "0.0.53",
4
4
  "description": "KeetaNetwork Network Anchor",
5
5
  "main": "client/index.js",
6
6
  "scripts": {
@@ -648,6 +648,57 @@ export interface QuotaManagedStorage {
648
648
  * Use this type when a backend supports CRUD, search, and quota management.
649
649
  */
650
650
  export type FullStorageBackend = StorageBackend & SearchableStorage & QuotaManagedStorage;
651
+ /**
652
+ * Operations that can be performed on storage objects.
653
+ */
654
+ export type StorageOperation = 'get' | 'put' | 'delete' | 'search' | 'metadata' | 'updateMetadata';
655
+ /**
656
+ * Shared fields available to all policy context variants.
657
+ */
658
+ export interface PathPolicyContextBase {
659
+ account: KeetaNetAccount;
660
+ }
661
+ /**
662
+ * Context for PUT operations.
663
+ * Contains the metadata being written and the encrypted container.
664
+ */
665
+ export interface PutPolicyContext extends PathPolicyContextBase {
666
+ operation: 'put';
667
+ metadata: StoragePutMetadata;
668
+ container: EncryptedContainer;
669
+ }
670
+ /**
671
+ * Context for metadata update operations.
672
+ * Contains the new metadata values and the current object metadata before mutation.
673
+ */
674
+ export interface UpdateMetadataPolicyContext extends PathPolicyContextBase {
675
+ operation: 'updateMetadata';
676
+ metadata: StoragePutMetadata;
677
+ current: StorageObjectMetadata;
678
+ }
679
+ /**
680
+ * Context for GET operations.
681
+ */
682
+ export interface GetPolicyContext extends PathPolicyContextBase {
683
+ operation: 'get';
684
+ }
685
+ /**
686
+ * Context for DELETE operations.
687
+ */
688
+ export interface DeletePolicyContext extends PathPolicyContextBase {
689
+ operation: 'delete';
690
+ }
691
+ /**
692
+ * Context for metadata read operations.
693
+ */
694
+ export interface MetadataPolicyContext extends PathPolicyContextBase {
695
+ operation: 'metadata';
696
+ }
697
+ /**
698
+ * Discriminated union of all policy validation contexts.
699
+ * Narrows on `operation` to access operation-specific fields.
700
+ */
701
+ export type PathPolicyContext = PutPolicyContext | UpdateMetadataPolicyContext | GetPolicyContext | DeletePolicyContext | MetadataPolicyContext;
651
702
  /**
652
703
  * Generic interface for path policies.
653
704
  * Each implementation defines its own parsed type and access control logic.
@@ -672,7 +723,7 @@ export interface PathPolicy<TPathInfo> {
672
723
  * Check if the account has access to perform the operation on the parsed path.
673
724
  * @returns true if access is allowed, false otherwise
674
725
  */
675
- checkAccess(account: KeetaNetAccount, parsed: TPathInfo, operation: 'get' | 'put' | 'delete' | 'search' | 'metadata' | 'updateMetadata'): boolean;
726
+ checkAccess(account: KeetaNetAccount, parsed: TPathInfo, operation: StorageOperation): boolean;
676
727
  /**
677
728
  * Get the account authorized to sign pre-signed URLs for this path.
678
729
  * Used for public object access verification.
@@ -681,25 +732,13 @@ export interface PathPolicy<TPathInfo> {
681
732
  */
682
733
  getAuthorizedSigner(parsed: TPathInfo): KeetaNetAccount | null;
683
734
  /**
684
- * Validate metadata for a path.
685
- * Called during PUT and metadata update operations.
686
- * @param parsed - The parsed path info
687
- * @param metadata - The metadata to validate
688
- * @throws Errors.InvalidMetadata if metadata violates path constraints
689
- */
690
- validateMetadata?(parsed: TPathInfo, metadata: StoragePutMetadata): void;
691
- /**
692
- * Validate the encrypted container during PUT.
693
- * Called after the container is parsed from the raw buffer but before decryption.
694
- * The container's principals getter returns all recipient public keys from the
695
- * ASN.1 header without requiring decryption.
735
+ * Validate the request context for a path.
696
736
  *
697
737
  * @param parsed - The parsed path info
698
- * @param container - The encrypted container parsed from the uploaded data
699
- * @param metadata - The metadata associated with the upload
700
- * @throws Errors.InvalidMetadata if the container violates policy constraints
738
+ * @param context - The operation-specific validation context
739
+ * @throws Errors.InvalidMetadata if the context violates policy constraints
701
740
  */
702
- validateContainer?(parsed: TPathInfo, container: EncryptedContainer, metadata: StoragePutMetadata): void;
741
+ validateContext?(parsed: TPathInfo, context: PathPolicyContext): void;
703
742
  }
704
743
  /**
705
744
  * Parse the decrypted plaintext from an EncryptedContainer.
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/services/storage/common.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/services/storage/common.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/services/storage/common.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAQ5E,2BAA2B;AAE3B,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD,oDAAoD;AACpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,0BAA0B,CAAC;AAEpE,sDAAsD;AACtD,MAAM,CAAC,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAqQnD,MAAM,UAAU,0CAA0C,CACzD,KAA8E;IAE9E,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC;IACjD,MAAM,IAAI,GAAa,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,OAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;AACxD,CAAC;AAiBD;;;GAGG;AACH,MAAM,UAAU,qDAAqD,CACpE,KAA4E;IAE5E,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAS,CAAC,EAAE,CAAC,IAAI,OAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,OAAM,CAAC,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;AACzE,CAAC;AA4BD,MAAM,UAAU,0CAA0C,CACzD,KAAmC;IAEnC,OAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7B,CAAC;AA+BD,MAAM,UAAU,6CAA6C,CAC5D,KAAsC;IAEtC,OAAM,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AA8BD,MAAM,UAAU,6CAA6C,CAC5D,KAAsC;IAEtC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;IAC9C,OAAM,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AACnE,CAAC;AAuBD;;;;;;GAMG;AACH,MAAM,UAAU,4CAA4C,CAC3D,YAA4C;IAE5C,OAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,aAAa;AAEb,wBAAwB;AAExB,MAAM,uCAAwC,SAAQ,oBAAoB;IACzE,MAAM,CAAmB,IAAI,GAAW,yCAAyC,CAAC;IACjE,mDAAmD,CAAU;IACtE,MAAM,CAAU,mDAAmD,GAAG,sCAAsC,CAAC;IAErH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,oBAAoB,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qDAAqD,EAAE;YAClF,KAAK,EAAE,uCAAuC,CAAC,mDAAmD;YAClG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,qDAAqD,EAAE,uCAAuC,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC1L,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,mCAAoC,SAAQ,oBAAoB;IACrE,MAAM,CAAmB,IAAI,GAAW,qCAAqC,CAAC;IAC7D,+CAA+C,CAAU;IAClE,MAAM,CAAU,+CAA+C,GAAG,sCAAsC,CAAC;IAEjH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iDAAiD,EAAE;YAC9E,KAAK,EAAE,mCAAmC,CAAC,+CAA+C;YAC1F,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,iDAAiD,EAAE,mCAAmC,CAAC,+CAA+C,CAAC,CAAC,CAAC;IAC9K,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,kCAAmC,SAAQ,8BAA8B;IAC9E,MAAM,CAAmB,IAAI,GAAW,oCAAoC,CAAC;IAC5D,8CAA8C,CAAU;IACjE,MAAM,CAAU,8CAA8C,GAAG,sCAAsC,CAAC;IAEhH,YAAY,OAAgB;QAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,CAAC,EAAE,EAAE,OAAO,IAAI,qBAAqB,CAAC,CAAC;QAEnH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gDAAgD,EAAE;YAC7E,KAAK,EAAE,kCAAkC,CAAC,8CAA8C;YACxF,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,UAAU,CAAC,KAAc;QACxC,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,gDAAgD,EAAE,kCAAkC,CAAC,8CAA8C,CAAC,CAAC,CAAC;IAC3K,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC5C,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAKF,MAAM,oCAAqC,SAAQ,oBAAoB;IACtE,MAAM,CAAmB,IAAI,GAAW,sCAAsC,CAAC;IAC9D,gDAAgD,CAAU;IACnE,MAAM,CAAU,gDAAgD,GAAG,sCAAsC,CAAC;IAElH,qCAAqC;IAC5B,SAAS,CAAoB;IAEtC,oDAAoD;IAC3C,KAAK,CAAS;IAEvB,6DAA6D;IACpD,OAAO,CAAS;IAEzB,YAAY,OAA2F;QACtG,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,mBAAmB,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,OAAO,qBAAqB,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;QACxH,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAE/B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kDAAkD,EAAE;YAC/E,KAAK,EAAE,oCAAoC,CAAC,gDAAgD;YAC5F,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,kDAAkD,EAAE,oCAAoC,CAAC,gDAAgD,CAAC,CAAC,CAAC;IACjL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACtF,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,wCAAyC,SAAQ,oBAAoB;IAC1E,MAAM,CAAmB,IAAI,GAAW,0CAA0C,CAAC;IAClE,oDAAoD,CAAU;IACvE,MAAM,CAAU,oDAAoD,GAAG,sCAAsC,CAAC;IAEtH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,6CAA6C,CAAC,CAAC;QAChE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sDAAsD,EAAE;YACnF,KAAK,EAAE,wCAAwC,CAAC,oDAAoD;YACpG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,sDAAsD,EAAE,wCAAwC,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAC7L,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,uCAAwC,SAAQ,8BAA8B;IACnF,MAAM,CAAmB,IAAI,GAAW,yCAAyC,CAAC;IACjE,mDAAmD,CAAU;IACtE,MAAM,CAAU,mDAAmD,GAAG,sCAAsC,CAAC;IAErH,YAAY,OAAgB;QAC3B,MAAM,GAAG,GAAG,OAAO,IAAI,2BAA2B,CAAC;QACnD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAE5D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qDAAqD,EAAE;YAClF,KAAK,EAAE,uCAAuC,CAAC,mDAAmD;YAClG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,IAAa,UAAU;QACtB,OAAM,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAED,MAAM,CAAU,UAAU,CAAC,KAAc;QACxC,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,qDAAqD,EAAE,uCAAuC,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC1L,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC5C,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,uCAAwC,SAAQ,oBAAoB;IACzE,MAAM,CAAmB,IAAI,GAAW,yCAAyC,CAAC;IACjE,mDAAmD,CAAU;IACtE,MAAM,CAAU,mDAAmD,GAAG,sCAAsC,CAAC;IAErH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,4BAA4B,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qDAAqD,EAAE;YAClF,KAAK,EAAE,uCAAuC,CAAC,mDAAmD;YAClG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,qDAAqD,EAAE,uCAAuC,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC1L,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,uCAAwC,SAAQ,oBAAoB;IACzE,MAAM,CAAmB,IAAI,GAAW,yCAAyC,CAAC;IACjE,mDAAmD,CAAU;IACtE,MAAM,CAAU,mDAAmD,GAAG,sCAAsC,CAAC;IAErH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,8CAA8C,CAAC,CAAC;QACjE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,qDAAqD,EAAE;YAClF,KAAK,EAAE,uCAAuC,CAAC,mDAAmD;YAClG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,qDAAqD,EAAE,uCAAuC,CAAC,mDAAmD,CAAC,CAAC,CAAC;IAC1L,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,yCAA0C,SAAQ,oBAAoB;IAC3E,MAAM,CAAmB,IAAI,GAAW,2CAA2C,CAAC;IACnE,qDAAqD,CAAU;IACxE,MAAM,CAAU,qDAAqD,GAAG,sCAAsC,CAAC;IAEvH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,sDAAsD,CAAC,CAAC;QACzE,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uDAAuD,EAAE;YACpF,KAAK,EAAE,yCAAyC,CAAC,qDAAqD;YACtG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,uDAAuD,EAAE,yCAAyC,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAChM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,yCAA0C,SAAQ,oBAAoB;IAC3E,MAAM,CAAmB,IAAI,GAAW,2CAA2C,CAAC;IACnE,qDAAqD,CAAU;IACxE,MAAM,CAAU,qDAAqD,GAAG,sCAAsC,CAAC;IAEvH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,+BAA+B,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uDAAuD,EAAE;YACpF,KAAK,EAAE,yCAAyC,CAAC,qDAAqD;YACtG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,uDAAuD,EAAE,yCAAyC,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAChM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,qCAAsC,SAAQ,oBAAoB;IACvE,MAAM,CAAmB,IAAI,GAAW,uCAAuC,CAAC;IAC/D,iDAAiD,CAAU;IACpE,MAAM,CAAU,iDAAiD,GAAG,sCAAsC,CAAC;IAEnH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,8DAA8D,CAAC,CAAC;QACjF,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mDAAmD,EAAE;YAChF,KAAK,EAAE,qCAAqC,CAAC,iDAAiD;YAC9F,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,mDAAmD,EAAE,qCAAqC,CAAC,iDAAiD,CAAC,CAAC,CAAC;IACpL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,sCAAuC,SAAQ,oBAAoB;IACxE,MAAM,CAAmB,IAAI,GAAW,wCAAwC,CAAC;IAChE,kDAAkD,CAAU;IACrE,MAAM,CAAU,kDAAkD,GAAG,sCAAsC,CAAC;IAEpH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,iEAAiE,CAAC,CAAC;QACpF,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oDAAoD,EAAE;YACjF,KAAK,EAAE,sCAAsC,CAAC,kDAAkD;YAChG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,oDAAoD,EAAE,sCAAsC,CAAC,kDAAkD,CAAC,CAAC,CAAC;IACvL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,4CAA6C,SAAQ,oBAAoB;IAC9E,MAAM,CAAmB,IAAI,GAAW,8CAA8C,CAAC;IACtE,wDAAwD,CAAU;IAC3E,MAAM,CAAU,wDAAwD,GAAG,sCAAsC,CAAC;IAE1H,YAAY,SAAkB;QAC7B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC,SAAS,aAAa,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;QAC3G,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,0DAA0D,EAAE;YACvF,KAAK,EAAE,4CAA4C,CAAC,wDAAwD;YAC5G,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,0DAA0D,EAAE,4CAA4C,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACzM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,4CAA6C,SAAQ,oBAAoB;IAC9E,MAAM,CAAmB,IAAI,GAAW,8CAA8C,CAAC;IACtE,wDAAwD,CAAU;IAC3E,MAAM,CAAU,wDAAwD,GAAG,sCAAsC,CAAC;IAE1H,YAAY,MAAe;QAC1B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,sCAAsC,MAAM,EAAE,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC;QACrG,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,0DAA0D,EAAE;YACvF,KAAK,EAAE,4CAA4C,CAAC,wDAAwD;YAC5G,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,0DAA0D,EAAE,4CAA4C,CAAC,wDAAwD,CAAC,CAAC,CAAC;IACzM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,sCAAuC,SAAQ,oBAAoB;IACxE,MAAM,CAAmB,IAAI,GAAW,wCAAwC,CAAC;IAChE,kDAAkD,CAAU;IACrE,MAAM,CAAU,kDAAkD,GAAG,sCAAsC,CAAC;IAEpH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0CAA0C,OAAO,EAAE,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC;QAC/G,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oDAAoD,EAAE;YACjF,KAAK,EAAE,sCAAsC,CAAC,kDAAkD;YAChG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,oDAAoD,EAAE,sCAAsC,CAAC,kDAAkD,CAAC,CAAC,CAAC;IACvL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,2CAA4C,SAAQ,oBAAoB;IAC7E,MAAM,CAAmB,IAAI,GAAW,6CAA6C,CAAC;IACrE,uDAAuD,CAAU;IAC1E,MAAM,CAAU,uDAAuD,GAAG,sCAAsC,CAAC;IAEzH,YAAY,SAAkB;QAC7B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,sCAAsC,SAAS,EAAE,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC;QAC3G,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,yDAAyD,EAAE;YACtF,KAAK,EAAE,2CAA2C,CAAC,uDAAuD;YAC1G,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,yDAAyD,EAAE,2CAA2C,CAAC,uDAAuD,CAAC,CAAC,CAAC;IACtM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,yCAA0C,SAAQ,oBAAoB;IAC3E,MAAM,CAAmB,IAAI,GAAW,2CAA2C,CAAC;IACnE,qDAAqD,CAAU;IACxE,MAAM,CAAU,qDAAqD,GAAG,sCAAsC,CAAC;IAEvH,YAAY,OAAgB;QAC3B,KAAK,CAAC,OAAO,IAAI,8BAA8B,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QAEtB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uDAAuD,EAAE;YACpF,KAAK,EAAE,yCAAyC,CAAC,qDAAqD;YACtG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAc;QAC/B,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,uDAAuD,EAAE,yCAAyC,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAChM,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAc;QACnC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,iCAAkC,SAAQ,8BAA8B;IAC7E,MAAM,CAAmB,IAAI,GAAW,mCAAmC,CAAC;IAC3D,6CAA6C,CAAU;IAChE,MAAM,CAAU,6CAA6C,GAAG,sCAAsC,CAAC;IAE/G,YAAY,OAAgB;QAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,CAAC,EAAE,EAAE,OAAO,IAAI,aAAa,CAAC,CAAC;QAEnG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,+CAA+C,EAAE;YAC5E,KAAK,EAAE,iCAAiC,CAAC,6CAA6C;YACtF,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,UAAU,CAAC,KAAc;QACxC,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,+CAA+C,EAAE,iCAAiC,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACxK,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC5C,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,sCAAuC,SAAQ,8BAA8B;IAClF,MAAM,CAAmB,IAAI,GAAW,wCAAwC,CAAC;IAChE,kDAAkD,CAAU;IACrE,MAAM,CAAU,kDAAkD,GAAG,sCAAsC,CAAC;IAEpH,YAAY,MAAe;QAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC;QAC5E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAE5D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oDAAoD,EAAE;YACjF,KAAK,EAAE,sCAAsC,CAAC,kDAAkD;YAChG,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAU,UAAU,CAAC,KAAc;QACxC,OAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,oDAAoD,EAAE,sCAAsC,CAAC,kDAAkD,CAAC,CAAC,CAAC;IACvL,CAAC;IAED,MAAM,CAAU,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC5C,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAM,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;;AAGF,MAAM,CAAC,MAAM,MAAM,GAoBf;IACH;;OAEG;IACH,gBAAgB,EAAE,uCAAuC;IAEzD;;OAEG;IACH,YAAY,EAAE,mCAAmC;IAEjD;;OAEG;IACH,WAAW,EAAE,kCAAkC;IAE/C;;OAEG;IACH,aAAa,EAAE,oCAAoC;IAEnD;;OAEG;IACH,uBAAuB,EAAE,wCAAwC;IAEjE;;OAEG;IACH,gBAAgB,EAAE,uCAAuC;IAEzD;;OAEG;IACH,gBAAgB,EAAE,uCAAuC;IAEzD;;OAEG;IACH,gBAAgB,EAAE,uCAAuC;IAEzD;;OAEG;IACH,kBAAkB,EAAE,yCAAyC;IAE7D;;OAEG;IACH,kBAAkB,EAAE,yCAAyC;IAE7D;;OAEG;IACH,cAAc,EAAE,qCAAqC;IAErD;;OAEG;IACH,eAAe,EAAE,sCAAsC;IAEvD;;OAEG;IACH,qBAAqB,EAAE,4CAA4C;IAEnE;;OAEG;IACH,qBAAqB,EAAE,4CAA4C;IAEnE;;OAEG;IACH,eAAe,EAAE,sCAAsC;IAEvD;;OAEG;IACH,oBAAoB,EAAE,2CAA2C;IAEjE;;OAEG;IACH,kBAAkB,EAAE,yCAAyC;IAE7D;;OAEG;IACH,UAAU,EAAE,iCAAiC;IAE7C;;OAEG;IACH,eAAe,EAAE,sCAAsC;CACvD,CAAC;AAgNF,aAAa;AAEb,sCAAsC;AAEtC;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAsB;IAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC;QACJ,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,QAAQ,GAAG,yBAAyB,CAAC;QACzC,IAAI,OAAe,CAAC;QACpB,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAChF,MAAM,WAAW,GAAG,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YACzE,MAAM,WAAW,GAAG,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACjE,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;gBACrC,QAAQ,GAAG,WAAW,CAAC;YACxB,CAAC;YACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;gBACrC,OAAO,GAAG,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACP,OAAO,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;aAAM,CAAC;YACP,OAAO,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,OAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,OAAM,CAAC;YACN,QAAQ,EAAE,yBAAyB;YACnC,OAAO,EAAE,uBAAuB,CAAC,SAAS,CAAC;SAC3C,CAAC,CAAC;IACJ,CAAC;AACF,CAAC","sourcesContent":["import type { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';\nimport type { HTTPSignedField } from '../../lib/http-server/common.js';\nimport type { Signable } from '../../lib/utils/signing.js';\nimport type { EncryptedContainer } from '../../lib/encrypted-container.js';\nimport { KeetaAnchorUserError, KeetaAnchorUserValidationError } from '../../lib/error.js';\nimport { Buffer, arrayBufferLikeToBuffer } from '../../lib/utils/buffer.js';\n\n/**\n * Type alias for a KeetaNet Account instance.\n * Used throughout the storage service for account authentication and signing.\n */\nexport type KeetaNetAccount = InstanceType<typeof KeetaNetLib.Account>;\n\n// #region Shared Constants\n\n/** Content type for JSON payloads */\nexport const CONTENT_TYPE_JSON = 'application/json';\n\n/** Content type for binary/octet-stream payloads */\nexport const CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream';\n\n/** Default TTL for signed URLs in seconds (1 hour) */\nexport const DEFAULT_SIGNED_URL_TTL_SECONDS = 3600;\n\n// #endregion\n\n// #region Common Types\n\n/**\n * Visibility of a storage object\n */\nexport type StorageObjectVisibility = 'public' | 'private';\n\n// #endregion\n\n// #region Object Metadata\n\n/**\n * Metadata for a stored object\n */\nexport type StorageObjectMetadata = {\n\t/**\n\t * Full path (the unique ID)\n\t */\n\tpath: string;\n\n\t/**\n\t * Owner's identifier\n\t */\n\towner: string;\n\n\t/**\n\t * Plaintext tags (searchable)\n\t */\n\ttags: string[];\n\n\t/**\n\t * Visibility setting\n\t */\n\tvisibility: StorageObjectVisibility;\n\n\t/**\n\t * Size in bytes\n\t */\n\tsize: number;\n\n\t/**\n\t * ISO timestamp of creation\n\t */\n\tcreatedAt: string;\n\n\t/**\n\t * ISO timestamp of last update\n\t */\n\tupdatedAt?: string;\n};\n\n// #endregion\n\n// #region Search\n\n/**\n * Criteria for searching storage objects.\n * Note: Content/keyword search is not supported (content is encrypted).\n */\nexport type SearchCriteria = {\n\t/**\n\t * Match objects with paths starting with this prefix\n\t * e.g., \"/user/keeta1abc.../contacts/\"\n\t */\n\tpathPrefix?: string;\n\n\t/**\n\t * Match objects that have ANY of these tags\n\t */\n\ttags?: string[];\n\n\t/**\n\t * Match path segment (filename portion)\n\t */\n\tname?: string;\n\n\t/**\n\t * Filter by owner's public key\n\t */\n\towner?: string;\n\n\t/**\n\t * Include objects in nested paths (default: false)\n\t */\n\trecursive?: boolean;\n\n\t/**\n\t * Filter by visibility.\n\t * When 'public', allows searching public objects outside caller's namespace.\n\t */\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Pagination options for search\n */\nexport type SearchPagination = {\n\t/**\n\t * Cursor for pagination (from previous response)\n\t */\n\tcursor?: string;\n\n\t/**\n\t * Maximum number of results to return\n\t */\n\tlimit?: number;\n};\n\n/**\n * Search results with pagination\n */\nexport type SearchResults = {\n\t/**\n\t * Matching objects\n\t */\n\tresults: StorageObjectMetadata[];\n\n\t/**\n\t * Cursor for next page (undefined if no more results)\n\t */\n\tnextCursor?: string;\n};\n\n// #endregion\n\n// #region Quota\n\n/**\n * Quota configuration for the storage service\n */\nexport type QuotaConfig = {\n\t/**\n\t * Maximum size in bytes per object\n\t */\n\tmaxObjectSize: number;\n\n\t/**\n\t * Maximum number of objects per user\n\t */\n\tmaxObjectsPerUser: number;\n\n\t/**\n\t * Maximum total storage in bytes per user\n\t */\n\tmaxStoragePerUser: number;\n\n\t/**\n\t * Maximum number of results per search request\n\t */\n\tmaxSearchLimit: number;\n\n\t/**\n\t * Maximum TTL in seconds for signed URLs\n\t */\n\tmaxSignedUrlTTL: number;\n};\n\n/**\n * Per-user quota limits.\n * Subset of QuotaConfig that can be overridden on a per-user basis.\n */\nexport type QuotaLimits = Pick<QuotaConfig, 'maxObjectsPerUser' | 'maxStoragePerUser' | 'maxObjectSize'>;\n\n/**\n * Current quota status for a user.\n * Backends must provide objectCount and totalSize.\n */\nexport type QuotaStatus = {\n\t/**\n\t * Current number of objects\n\t */\n\tobjectCount: number;\n\n\t/**\n\t * Current total size in bytes\n\t */\n\ttotalSize: number;\n\n\t/**\n\t * Remaining objects allowed (optional, server computes if absent)\n\t */\n\tremainingObjects?: number;\n\n\t/**\n\t * Remaining storage in bytes (optional, server computes if absent)\n\t */\n\tremainingSize?: number;\n};\n\n// #endregion\n\n// #region Request Type Helpers\n\n// #endregion\n\n// #region PUT Object\n\n/**\n * Client-side request to put (create/update) an object\n */\nexport type KeetaStorageAnchorPutClientRequest = {\n\taccount?: KeetaNetAccount;\n\tpath: string;\n\tdata: string; // Base64-encoded EncryptedContainer\n\ttags?: string[];\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Server-side request to put an object\n */\nexport type KeetaStorageAnchorPutRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tpath: string;\n\tdata: string;\n\ttags?: string[];\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Configuration for a contacts client.\n * Contacts are stored in a subdirectory of the account's working directory.\n */\nexport type ContactsClientConfig = {\n\t/**\n\t * The account to use for the contacts client.\n\t */\n\taccount: KeetaNetAccount;\n\t/**\n\t * The base path for the contacts client.\n\t */\n\tbasePath: string;\n};\n\n/**\n * Configuration for an icons client.\n * The icon is stored as a single file under the base path.\n */\nexport type IconsClientConfig = {\n\t/**\n\t * The account to use for the icons client.\n\t */\n\taccount: KeetaNetAccount;\n\t/**\n\t * The base path for the icons client (e.g., `/user/<pubkey>/`).\n\t */\n\tbasePath: string;\n};\n\n/**\n * Generic response type for storage operations.\n */\nexport type StorageResponse<T> = ({ ok: true } & T) | { ok: false; error: string };\n\nexport type KeetaStorageAnchorPutResponse = StorageResponse<{ object: StorageObjectMetadata }>;\n\nexport function getKeetaStorageAnchorPutRequestSigningData(\n\tinput: { path: string; visibility?: StorageObjectVisibility; tags?: string[] }\n): Signable {\n\tconst visibility = input.visibility ?? 'private';\n\tconst tags: string[] = input.tags ?? [];\n\tconst sortedTags = [...tags].sort();\n\treturn(['put', input.path, visibility, ...sortedTags]);\n}\n\n// #endregion\n\n// #region Update Metadata\n\n/**\n * Server-side request to update object metadata.\n * Path is derived from the URL, not the body.\n */\nexport type KeetaStorageAnchorUpdateMetadataRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\ttags: string[];\n\tvisibility: StorageObjectVisibility;\n};\n\n/**\n * Build signing data for an update-metadata request.\n * Tags are sorted with localeCompare for deterministic signatures.\n */\nexport function getKeetaStorageAnchorUpdateMetadataRequestSigningData(\n\tinput: { path: string; visibility: StorageObjectVisibility; tags: string[] }\n): Signable {\n\tconst sortedTags = [...input.tags].sort(function(a, b) { return(a.localeCompare(b)); });\n\treturn(['updateMetadata', input.path, input.visibility, ...sortedTags]);\n}\n\n// #endregion\n\n// #region GET Object\n\n/**\n * Client-side request to get an object\n */\nexport type KeetaStorageAnchorGetClientRequest = {\n\taccount?: KeetaNetAccount;\n\tpath: string;\n};\n\n/**\n * Server-side request to get an object\n */\nexport type KeetaStorageAnchorGetRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tpath: string;\n};\n\nexport type KeetaStorageAnchorGetResponse = StorageResponse<{\n\tdata: string; // Base64-encoded EncryptedContainer\n\tobject: StorageObjectMetadata;\n}>;\n\nexport function getKeetaStorageAnchorGetRequestSigningData(\n\tinput: KeetaStorageAnchorGetRequest\n): Signable {\n\treturn(['get', input.path]);\n}\n\n// #endregion\n\n// #region DELETE Object\n\n/**\n * Client-side request to delete an object\n */\nexport type KeetaStorageAnchorDeleteClientRequest = {\n\taccount?: KeetaNetAccount;\n\t/**\n\t * Path to the object\n\t */\n\tpath: string;\n};\n\n/**\n * Server-side request to delete an object\n */\nexport type KeetaStorageAnchorDeleteRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\t/**\n\t * Path to the object\n\t */\n\tpath: string;\n};\n\nexport type KeetaStorageAnchorDeleteResponse = StorageResponse<{ deleted: boolean }>;\n\nexport function getKeetaStorageAnchorDeleteRequestSigningData(\n\tinput: KeetaStorageAnchorDeleteRequest\n): Signable {\n\treturn(['delete', input.path]);\n}\n\n// #endregion\n\n// #region SEARCH\n\n/**\n * Client-side request to search objects\n */\nexport type KeetaStorageAnchorSearchClientRequest = {\n\taccount?: KeetaNetAccount;\n\tcriteria: SearchCriteria;\n\tpagination?: SearchPagination;\n};\n\n/**\n * Server-side request to search objects\n */\nexport type KeetaStorageAnchorSearchRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tcriteria: SearchCriteria;\n\tpagination?: SearchPagination;\n};\n\nexport type KeetaStorageAnchorSearchResponse = StorageResponse<{\n\tresults: StorageObjectMetadata[];\n\tnextCursor?: string;\n}>;\n\nexport function getKeetaStorageAnchorSearchRequestSigningData(\n\tinput: KeetaStorageAnchorSearchRequest\n): Signable {\n\tconst limit = input.pagination?.limit ?? 0;\n\tconst cursor = input.pagination?.cursor ?? '';\n\treturn(['search', JSON.stringify(input.criteria), limit, cursor]);\n}\n\n// #endregion\n\n// #region Quota\n\n/**\n * Client-side request to get quota status\n */\nexport type KeetaStorageAnchorQuotaClientRequest = {\n\taccount?: KeetaNetAccount;\n};\n\n/**\n * Server-side request to get quota status\n */\nexport type KeetaStorageAnchorQuotaRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n};\n\nexport type KeetaStorageAnchorQuotaResponse = StorageResponse<{ quota: QuotaStatus }>;\n\n/**\n * Get signing data for quota requests.\n * The input is unused because quota requests don't need request-specific signing -\n * authentication alone is sufficient.\n *\n * The parameter was kept for API consistency with other signing functions.\n */\nexport function getKeetaStorageAnchorQuotaRequestSigningData(\n\t_ignoreInput: KeetaStorageAnchorQuotaRequest\n): Signable {\n\treturn(['quota']);\n}\n\n// #endregion\n\n// #region Error Classes\n\nclass KeetaStorageAnchorDocumentNotFoundError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorDocumentNotFoundError';\n\tprivate readonly KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID = 'ac137e18-2827-4542-a852-c650610899b5';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Document not found');\n\t\tthis.statusCode = 404;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorDocumentNotFoundError.KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorDocumentNotFoundError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID', KeetaStorageAnchorDocumentNotFoundError.KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorDocumentNotFoundError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorAccessDeniedError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorAccessDeniedError';\n\tprivate readonly KeetaStorageAnchorAccessDeniedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorAccessDeniedErrorObjectTypeID = 'fb75fa8c-6ef0-47cb-b767-3c2cfbb73617';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Access denied');\n\t\tthis.statusCode = 403;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorAccessDeniedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorAccessDeniedError.KeetaStorageAnchorAccessDeniedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorAccessDeniedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorAccessDeniedErrorObjectTypeID', KeetaStorageAnchorAccessDeniedError.KeetaStorageAnchorAccessDeniedErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorAccessDeniedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidPathError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidPathError';\n\tprivate readonly KeetaStorageAnchorInvalidPathErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidPathErrorObjectTypeID = 'eb0e1c0d-2281-4b93-9f78-87bf166a4829';\n\n\tconstructor(message?: string) {\n\t\tsuper({ fields: [{ path: 'path', message: message ?? 'Invalid path format' }] }, message ?? 'Invalid path format');\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidPathErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidPathError.KeetaStorageAnchorInvalidPathErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidPathError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidPathErrorObjectTypeID', KeetaStorageAnchorInvalidPathError.KeetaStorageAnchorInvalidPathErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidPathError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\ntype QuotaExceededType = 'maxObjectSize' | 'maxObjectsPerUser' | 'maxStoragePerUser';\n\nclass KeetaStorageAnchorQuotaExceededError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorQuotaExceededError';\n\tprivate readonly KeetaStorageAnchorQuotaExceededErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorQuotaExceededErrorObjectTypeID = 'c0b75028-644a-472b-8df4-b0a856814f99';\n\n\t/** Which quota limit was exceeded */\n\treadonly quotaType: QuotaExceededType;\n\n\t/** The configured maximum for the exceeded quota */\n\treadonly limit: number;\n\n\t/** The current or attempted value that exceeded the limit */\n\treadonly current: number;\n\n\tconstructor(options: { quotaType: QuotaExceededType; limit: number; current: number; message?: string }) {\n\t\tsuper(options.message ?? `Quota exceeded: ${options.quotaType} (${options.current} exceeds limit of ${options.limit})`);\n\t\tthis.statusCode = 413;\n\t\tthis.quotaType = options.quotaType;\n\t\tthis.limit = options.limit;\n\t\tthis.current = options.current;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorQuotaExceededErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorQuotaExceededError.KeetaStorageAnchorQuotaExceededErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorQuotaExceededError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorQuotaExceededErrorObjectTypeID', KeetaStorageAnchorQuotaExceededError.KeetaStorageAnchorQuotaExceededErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorQuotaExceededError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this({ quotaType: 'maxObjectSize', limit: 0, current: 0, message });\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorPrincipalRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorPrincipalRequiredError';\n\tprivate readonly KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID = '12e42092-d4db-435e-8a01-798e26f653b4';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Validated path requires anchor as principal');\n\t\tthis.statusCode = 400;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorPrincipalRequiredError.KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorPrincipalRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID', KeetaStorageAnchorPrincipalRequiredError.KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorPrincipalRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorValidationFailedError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorValidationFailedError';\n\tprivate readonly KeetaStorageAnchorValidationFailedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorValidationFailedErrorObjectTypeID = '73cadd95-cf39-466b-b9b6-484e1ae1ca9c';\n\n\tconstructor(message?: string) {\n\t\tconst msg = message ?? 'Content validation failed';\n\t\tsuper({ fields: [{ path: 'content', message: msg }] }, msg);\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorValidationFailedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorValidationFailedError.KeetaStorageAnchorValidationFailedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\toverride get statusCode() {\n\t\treturn(422);\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorValidationFailedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorValidationFailedErrorObjectTypeID', KeetaStorageAnchorValidationFailedError.KeetaStorageAnchorValidationFailedErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorValidationFailedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignatureExpiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignatureExpiredError';\n\tprivate readonly KeetaStorageAnchorSignatureExpiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignatureExpiredErrorObjectTypeID = '3a676e44-882b-4925-bf5f-bc5123cc0b20';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Pre-signed URL has expired');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignatureExpiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignatureExpiredError.KeetaStorageAnchorSignatureExpiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignatureExpiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignatureExpiredErrorObjectTypeID', KeetaStorageAnchorSignatureExpiredError.KeetaStorageAnchorSignatureExpiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignatureExpiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignatureInvalidError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignatureInvalidError';\n\tprivate readonly KeetaStorageAnchorSignatureInvalidErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignatureInvalidErrorObjectTypeID = '91831c73-31e2-4f27-a9d1-4ab9a5ed5663';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Pre-signed URL signature verification failed');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignatureInvalidErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignatureInvalidError.KeetaStorageAnchorSignatureInvalidErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignatureInvalidError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignatureInvalidErrorObjectTypeID', KeetaStorageAnchorSignatureInvalidError.KeetaStorageAnchorSignatureInvalidErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignatureInvalidError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorPrivateKeyRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorPrivateKeyRequiredError';\n\tprivate readonly KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID = '36eaae98-1b1e-412b-ba5b-b9293cc37156';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Account with private key required for this operation');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorPrivateKeyRequiredError.KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorPrivateKeyRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID', KeetaStorageAnchorPrivateKeyRequiredError.KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorPrivateKeyRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorServiceUnavailableError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorServiceUnavailableError';\n\tprivate readonly KeetaStorageAnchorServiceUnavailableErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorServiceUnavailableErrorObjectTypeID = 'b2671cd1-6abb-4bd4-9be2-d8d111c17bcf';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Storage service not available');\n\t\tthis.statusCode = 503;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorServiceUnavailableErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorServiceUnavailableError.KeetaStorageAnchorServiceUnavailableErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorServiceUnavailableError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorServiceUnavailableErrorObjectTypeID', KeetaStorageAnchorServiceUnavailableError.KeetaStorageAnchorServiceUnavailableErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorServiceUnavailableError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignerRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignerRequiredError';\n\tprivate readonly KeetaStorageAnchorSignerRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignerRequiredErrorObjectTypeID = 'ce4a5581-1869-4656-88c6-63f0a29b46ca';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'A Signer or UserClient with an associated Signer is required');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignerRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignerRequiredError.KeetaStorageAnchorSignerRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignerRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignerRequiredErrorObjectTypeID', KeetaStorageAnchorSignerRequiredError.KeetaStorageAnchorSignerRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignerRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorAccountRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorAccountRequiredError';\n\tprivate readonly KeetaStorageAnchorAccountRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorAccountRequiredErrorObjectTypeID = '496e5dbe-535f-4f24-acf4-a44d9d93fb75';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'An Account or UserClient with an associated Account is required');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorAccountRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorAccountRequiredError.KeetaStorageAnchorAccountRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorAccountRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorAccountRequiredErrorObjectTypeID', KeetaStorageAnchorAccountRequiredError.KeetaStorageAnchorAccountRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorAccountRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorOperationNotSupportedError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorOperationNotSupportedError';\n\tprivate readonly KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID = 'ac491ea6-f656-4eab-a430-051a0f201fff';\n\n\tconstructor(operation?: string) {\n\t\tsuper(operation ? `Storage service does not support '${operation}' operation` : 'Operation not supported');\n\t\tthis.statusCode = 501;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorOperationNotSupportedError.KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorOperationNotSupportedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID', KeetaStorageAnchorOperationNotSupportedError.KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorOperationNotSupportedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorUnsupportedAuthMethodError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorUnsupportedAuthMethodError';\n\tprivate readonly KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID = '46cfbab9-934f-44b0-9216-03d397fdd6b6';\n\n\tconstructor(method?: string) {\n\t\tsuper(method ? `Unsupported authentication method: ${method}` : 'Unsupported authentication method');\n\t\tthis.statusCode = 501;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorUnsupportedAuthMethodError.KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorUnsupportedAuthMethodError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID', KeetaStorageAnchorUnsupportedAuthMethodError.KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorUnsupportedAuthMethodError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidResponseError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidResponseError';\n\tprivate readonly KeetaStorageAnchorInvalidResponseErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidResponseErrorObjectTypeID = '02480186-7bc3-4a80-b6a9-23c3a9f606c9';\n\n\tconstructor(details?: string) {\n\t\tsuper(details ? `Invalid response from storage service: ${details}` : 'Invalid response from storage service');\n\t\tthis.statusCode = 502;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidResponseErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidResponseError.KeetaStorageAnchorInvalidResponseErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvalidResponseError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidResponseErrorObjectTypeID', KeetaStorageAnchorInvalidResponseError.KeetaStorageAnchorInvalidResponseErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidResponseError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidAnchorAccountError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidAnchorAccountError';\n\tprivate readonly KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID = '82bb0a94-0a5e-4e0a-b5c1-7532bbe09cd6';\n\n\tconstructor(publicKey?: string) {\n\t\tsuper(publicKey ? `Invalid anchor account public key: ${publicKey}` : 'Invalid anchor account public key');\n\t\tthis.statusCode = 502;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidAnchorAccountError.KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvalidAnchorAccountError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID', KeetaStorageAnchorInvalidAnchorAccountError.KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidAnchorAccountError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvariantViolationError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvariantViolationError';\n\tprivate readonly KeetaStorageAnchorInvariantViolationErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvariantViolationErrorObjectTypeID = 'a7c5d3e1-8b9f-4c2a-b3d4-e5f6a7b8c9d0';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Internal invariant violation');\n\t\tthis.statusCode = 500;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvariantViolationErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvariantViolationError.KeetaStorageAnchorInvariantViolationErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvariantViolationError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvariantViolationErrorObjectTypeID', KeetaStorageAnchorInvariantViolationError.KeetaStorageAnchorInvariantViolationErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvariantViolationError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidTagError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidTagError';\n\tprivate readonly KeetaStorageAnchorInvalidTagErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidTagErrorObjectTypeID = 'b8d6e4f2-9c0a-5d3b-c4e5-f6a7b8c9d0e1';\n\n\tconstructor(message?: string) {\n\t\tsuper({ fields: [{ path: 'tags', message: message ?? 'Invalid tag' }] }, message ?? 'Invalid tag');\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidTagErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidTagError.KeetaStorageAnchorInvalidTagErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidTagError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidTagErrorObjectTypeID', KeetaStorageAnchorInvalidTagError.KeetaStorageAnchorInvalidTagErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidTagError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidMetadataError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidMetadataError';\n\tprivate readonly KeetaStorageAnchorInvalidMetadataErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidMetadataErrorObjectTypeID = 'c9e7f5a3-0d1b-6e4c-d5f6-a7b8c9d0e1f2';\n\n\tconstructor(reason?: string) {\n\t\tconst message = reason ? `Invalid metadata: ${reason}` : 'Invalid metadata';\n\t\tsuper({ fields: [{ path: 'metadata', message }] }, message);\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidMetadataErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidMetadataError.KeetaStorageAnchorInvalidMetadataErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidMetadataError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidMetadataErrorObjectTypeID', KeetaStorageAnchorInvalidMetadataError.KeetaStorageAnchorInvalidMetadataErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidMetadataError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nexport const Errors: {\n\tDocumentNotFound: typeof KeetaStorageAnchorDocumentNotFoundError;\n\tAccessDenied: typeof KeetaStorageAnchorAccessDeniedError;\n\tInvalidPath: typeof KeetaStorageAnchorInvalidPathError;\n\tQuotaExceeded: typeof KeetaStorageAnchorQuotaExceededError;\n\tAnchorPrincipalRequired: typeof KeetaStorageAnchorPrincipalRequiredError;\n\tValidationFailed: typeof KeetaStorageAnchorValidationFailedError;\n\tSignatureExpired: typeof KeetaStorageAnchorSignatureExpiredError;\n\tSignatureInvalid: typeof KeetaStorageAnchorSignatureInvalidError;\n\tPrivateKeyRequired: typeof KeetaStorageAnchorPrivateKeyRequiredError;\n\tServiceUnavailable: typeof KeetaStorageAnchorServiceUnavailableError;\n\tSignerRequired: typeof KeetaStorageAnchorSignerRequiredError;\n\tAccountRequired: typeof KeetaStorageAnchorAccountRequiredError;\n\tOperationNotSupported: typeof KeetaStorageAnchorOperationNotSupportedError;\n\tUnsupportedAuthMethod: typeof KeetaStorageAnchorUnsupportedAuthMethodError;\n\tInvalidResponse: typeof KeetaStorageAnchorInvalidResponseError;\n\tInvalidAnchorAccount: typeof KeetaStorageAnchorInvalidAnchorAccountError;\n\tInvariantViolation: typeof KeetaStorageAnchorInvariantViolationError;\n\tInvalidTag: typeof KeetaStorageAnchorInvalidTagError;\n\tInvalidMetadata: typeof KeetaStorageAnchorInvalidMetadataError;\n} = {\n\t/**\n\t * The requested document/object was not found\n\t */\n\tDocumentNotFound: KeetaStorageAnchorDocumentNotFoundError,\n\n\t/**\n\t * Access to the document/object was denied\n\t */\n\tAccessDenied: KeetaStorageAnchorAccessDeniedError,\n\n\t/**\n\t * Path doesn't match /user/<pubkey>/... format\n\t */\n\tInvalidPath: KeetaStorageAnchorInvalidPathError,\n\n\t/**\n\t * Object size, count, or total storage limit exceeded\n\t */\n\tQuotaExceeded: KeetaStorageAnchorQuotaExceededError,\n\n\t/**\n\t * Validated path requires anchor as principal\n\t */\n\tAnchorPrincipalRequired: KeetaStorageAnchorPrincipalRequiredError,\n\n\t/**\n\t * Namespace validator rejected content\n\t */\n\tValidationFailed: KeetaStorageAnchorValidationFailedError,\n\n\t/**\n\t * Pre-signed URL has expired\n\t */\n\tSignatureExpired: KeetaStorageAnchorSignatureExpiredError,\n\n\t/**\n\t * Pre-signed URL signature verification failed\n\t */\n\tSignatureInvalid: KeetaStorageAnchorSignatureInvalidError,\n\n\t/**\n\t * Account with private key required for this operation\n\t */\n\tPrivateKeyRequired: KeetaStorageAnchorPrivateKeyRequiredError,\n\n\t/**\n\t * Storage service is not available\n\t */\n\tServiceUnavailable: KeetaStorageAnchorServiceUnavailableError,\n\n\t/**\n\t * A Signer or UserClient with an associated Signer is required\n\t */\n\tSignerRequired: KeetaStorageAnchorSignerRequiredError,\n\n\t/**\n\t * An Account or UserClient with an associated Account is required\n\t */\n\tAccountRequired: KeetaStorageAnchorAccountRequiredError,\n\n\t/**\n\t * The requested operation is not supported by this storage service\n\t */\n\tOperationNotSupported: KeetaStorageAnchorOperationNotSupportedError,\n\n\t/**\n\t * The authentication method is not supported\n\t */\n\tUnsupportedAuthMethod: KeetaStorageAnchorUnsupportedAuthMethodError,\n\n\t/**\n\t * Invalid response received from storage service\n\t */\n\tInvalidResponse: KeetaStorageAnchorInvalidResponseError,\n\n\t/**\n\t * Anchor account public key from service metadata is invalid\n\t */\n\tInvalidAnchorAccount: KeetaStorageAnchorInvalidAnchorAccountError,\n\n\t/**\n\t * Internal invariant violation - indicates a bug in the code\n\t */\n\tInvariantViolation: KeetaStorageAnchorInvariantViolationError,\n\n\t/**\n\t * Tag validation failed (invalid format, too long, or too many tags)\n\t */\n\tInvalidTag: KeetaStorageAnchorInvalidTagError,\n\n\t/**\n\t * Metadata validation failed against path policy constraints\n\t */\n\tInvalidMetadata: KeetaStorageAnchorInvalidMetadataError\n};\n\n// #endregion\n\n// #region Storage Backend Interface\n\n/**\n * Metadata input for put operations.\n * Provided by the client when storing an object.\n */\nexport type StoragePutMetadata = {\n\t/** Owner's identifier */\n\towner: string;\n\t/** Tags for categorization and search */\n\ttags: string[];\n\t/** Access visibility setting */\n\tvisibility: StorageObjectVisibility;\n};\n\n/**\n * Result of a get operation.\n * Contains both the raw encrypted data and the object metadata.\n */\nexport type StorageGetResult = {\n\t/** Raw encrypted data (EncryptedContainer) */\n\tdata: Buffer;\n\t/** Object metadata */\n\tmetadata: StorageObjectMetadata;\n};\n\n/**\n * Represents a pending upload quota reservation.\n * Used to reserve quota before an upload and track in-flight uploads.\n */\nexport interface UploadReservation {\n\t/** Unique identifier for this reservation */\n\tid: string;\n\t/** Owner's identifier */\n\towner: string;\n\t/** Target path for the upload */\n\tpath: string;\n\t/** Reserved size in bytes */\n\tsize: number;\n\t/** When the reservation was created */\n\tcreatedAt: string;\n\t/** When the reservation expires - hint for stale cleanup */\n\texpiresAt: string;\n}\n\n/**\n * Core CRUD operations for storage.\n * All backends must implement these operations.\n */\nexport interface StorageBackend {\n\t/**\n\t * Store/update an object at the given path\n\t */\n\tput(path: string, data: Buffer, metadata: StoragePutMetadata): Promise<StorageObjectMetadata>;\n\n\t/**\n\t * Retrieve an object by path\n\t */\n\tget(path: string): Promise<StorageGetResult | null>;\n\n\t/**\n\t * Delete an object by path\n\t */\n\tdelete(path: string): Promise<boolean>;\n\n\t/**\n\t * Update metadata for an existing object without re-uploading data.\n\t * @returns Updated metadata, or null if the object does not exist\n\t */\n\tupdateMetadata?(path: string, metadata: Omit<StoragePutMetadata, 'owner'>): Promise<StorageObjectMetadata | null>;\n}\n\n/**\n * Search capability interface.\n * Optional for backends that don't support indexing (e.g., simple S3-only backends).\n */\nexport interface SearchableStorage {\n\t/**\n\t * Search for objects matching criteria\n\t */\n\tsearch(criteria: SearchCriteria, pagination: SearchPagination): Promise<SearchResults>;\n}\n\n/**\n * Quota management with upload reservations.\n * Handles quota tracking and reservation-based upload flow.\n */\nexport interface QuotaManagedStorage {\n\t/**\n\t * Get quota status for a user.\n\t * Includes both actual usage and pending reservations.\n\t */\n\tgetQuotaStatus(owner: string): Promise<QuotaStatus>;\n\n\t/**\n\t * Get per-user quota limits.\n\t * Return null to use global defaults.\n\t * @param owner - Owner's identifier\n\t */\n\tgetQuotaLimits?(owner: string): Promise<QuotaLimits | null>;\n\n\t/**\n\t * Reserve quota for an upcoming upload.\n\t *\n\t * @param owner - Owner's identifier\n\t * @param path - Target path for the upload\n\t * @param size - Size in bytes to reserve\n\t * @param options.ttlMs - Optional TTL in milliseconds for the reservation\n\t * @param options.quotaLimits - Optional quota limits to enforce (overrides backend defaults)\n\t *\n\t * @returns Reservation that must be committed or released\n\t *\n\t * @throws QuotaExceeded if reservation would exceed limits\n\t */\n\treserveUpload(owner: string, path: string, size: number, options?: {\n\t\tttlMs?: number;\n\t\tquotaLimits?: Pick<QuotaConfig, 'maxObjectsPerUser' | 'maxStoragePerUser'>;\n\t}): Promise<UploadReservation>;\n\n\t/**\n\t * Commit a reservation after successful upload.\n\t * Call after put() succeeds to finalize the quota usage.\n\t * @param reservationId - ID of the reservation to commit\n\t */\n\tcommitUpload(reservationId: string): Promise<void>;\n\n\t/**\n\t * Release a reservation (upload failed or cancelled).\n\t * Frees the reserved quota.\n\t * @param reservationId - ID of the reservation to release\n\t */\n\treleaseUpload(reservationId: string): Promise<void>;\n}\n\n/**\n * Full storage backend combining all capabilities.\n * Use this type when a backend supports CRUD, search, and quota management.\n */\nexport type FullStorageBackend = StorageBackend & SearchableStorage & QuotaManagedStorage;\n\n// #endregion\n\n// #region Path Policy\n\n/**\n * Generic interface for path policies.\n * Each implementation defines its own parsed type and access control logic.\n * Storage Anchors are free to implement whatever pathname structure they wish.\n */\nexport interface PathPolicy<TPathInfo> {\n\t/**\n\t * Parse a path into its components.\n\t * @returns TPathInfo if valid, null otherwise\n\t */\n\tparse(path: string): TPathInfo | null;\n\n\t/**\n\t * Validate a path and return its components.\n\t * @throws Errors.InvalidPath if the path is invalid\n\t */\n\tvalidate(path: string): TPathInfo;\n\n\t/**\n\t * Check if a path is valid.\n\t */\n\tisValid(path: string): boolean;\n\n\t/**\n\t * Check if the account has access to perform the operation on the parsed path.\n\t * @returns true if access is allowed, false otherwise\n\t */\n\tcheckAccess(account: KeetaNetAccount, parsed: TPathInfo, operation: 'get' | 'put' | 'delete' | 'search' | 'metadata' | 'updateMetadata'): boolean;\n\n\t/**\n\t * Get the account authorized to sign pre-signed URLs for this path.\n\t * Used for public object access verification.\n\t *\n\t * @returns The account if only that account can sign (owner-restricted), or `null` if any account can sign\n\t */\n\tgetAuthorizedSigner(parsed: TPathInfo): KeetaNetAccount | null;\n\n\t/**\n\t * Validate metadata for a path.\n\t * Called during PUT and metadata update operations.\n\t * @param parsed - The parsed path info\n\t * @param metadata - The metadata to validate\n\t * @throws Errors.InvalidMetadata if metadata violates path constraints\n\t */\n\tvalidateMetadata?(parsed: TPathInfo, metadata: StoragePutMetadata): void;\n\n\t/**\n\t * Validate the encrypted container during PUT.\n\t * Called after the container is parsed from the raw buffer but before decryption.\n\t * The container's principals getter returns all recipient public keys from the\n\t * ASN.1 header without requiring decryption.\n\t *\n\t * @param parsed - The parsed path info\n\t * @param container - The encrypted container parsed from the uploaded data\n\t * @param metadata - The metadata associated with the upload\n\t * @throws Errors.InvalidMetadata if the container violates policy constraints\n\t */\n\tvalidateContainer?(parsed: TPathInfo, container: EncryptedContainer, metadata: StoragePutMetadata): void;\n}\n\n// #endregion\n\n// #region Container Payload Utilities\n\n/**\n * Parse the decrypted plaintext from an EncryptedContainer.\n * The payload is expected to be JSON with mimeType and base64-encoded data,\n * keeping the mimeType encrypted along with the content.\n *\n * @param plaintext - The decrypted plaintext from an EncryptedContainer\n *\n * @returns Object containing mimeType and content Buffer\n */\nexport function parseContainerPayload(plaintext: ArrayBuffer): { mimeType: string; content: Buffer } {\n\tconst payloadStr = Buffer.from(plaintext).toString('utf-8');\n\ttry {\n\t\tconst payload: unknown = JSON.parse(payloadStr);\n\t\tlet mimeType = CONTENT_TYPE_OCTET_STREAM;\n\t\tlet content: Buffer;\n\t\tif (typeof payload === 'object' && payload !== null && !Array.isArray(payload)) {\n\t\t\tconst payloadMime = 'mimeType' in payload ? payload.mimeType : undefined;\n\t\t\tconst payloadData = 'data' in payload ? payload.data : undefined;\n\t\t\tif (typeof payloadMime === 'string') {\n\t\t\t\tmimeType = payloadMime;\n\t\t\t}\n\t\t\tif (typeof payloadData === 'string') {\n\t\t\t\tcontent = arrayBufferLikeToBuffer(Buffer.from(payloadData, 'base64'));\n\t\t\t} else {\n\t\t\t\tcontent = arrayBufferLikeToBuffer(plaintext);\n\t\t\t}\n\t\t} else {\n\t\t\tcontent = arrayBufferLikeToBuffer(plaintext);\n\t\t}\n\t\treturn({ mimeType, content });\n\t} catch {\n\t\treturn({\n\t\t\tmimeType: CONTENT_TYPE_OCTET_STREAM,\n\t\t\tcontent: arrayBufferLikeToBuffer(plaintext)\n\t\t});\n\t}\n}\n\n// #endregion\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/services/storage/common.ts"],"names":[],"mappings":"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","sourcesContent":["import type { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';\nimport type { HTTPSignedField } from '../../lib/http-server/common.js';\nimport type { Signable } from '../../lib/utils/signing.js';\nimport type { EncryptedContainer } from '../../lib/encrypted-container.js';\nimport { KeetaAnchorUserError, KeetaAnchorUserValidationError } from '../../lib/error.js';\nimport { Buffer, arrayBufferLikeToBuffer } from '../../lib/utils/buffer.js';\n\n/**\n * Type alias for a KeetaNet Account instance.\n * Used throughout the storage service for account authentication and signing.\n */\nexport type KeetaNetAccount = InstanceType<typeof KeetaNetLib.Account>;\n\n// #region Shared Constants\n\n/** Content type for JSON payloads */\nexport const CONTENT_TYPE_JSON = 'application/json';\n\n/** Content type for binary/octet-stream payloads */\nexport const CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream';\n\n/** Default TTL for signed URLs in seconds (1 hour) */\nexport const DEFAULT_SIGNED_URL_TTL_SECONDS = 3600;\n\n// #endregion\n\n// #region Common Types\n\n/**\n * Visibility of a storage object\n */\nexport type StorageObjectVisibility = 'public' | 'private';\n\n// #endregion\n\n// #region Object Metadata\n\n/**\n * Metadata for a stored object\n */\nexport type StorageObjectMetadata = {\n\t/**\n\t * Full path (the unique ID)\n\t */\n\tpath: string;\n\n\t/**\n\t * Owner's identifier\n\t */\n\towner: string;\n\n\t/**\n\t * Plaintext tags (searchable)\n\t */\n\ttags: string[];\n\n\t/**\n\t * Visibility setting\n\t */\n\tvisibility: StorageObjectVisibility;\n\n\t/**\n\t * Size in bytes\n\t */\n\tsize: number;\n\n\t/**\n\t * ISO timestamp of creation\n\t */\n\tcreatedAt: string;\n\n\t/**\n\t * ISO timestamp of last update\n\t */\n\tupdatedAt?: string;\n};\n\n// #endregion\n\n// #region Search\n\n/**\n * Criteria for searching storage objects.\n * Note: Content/keyword search is not supported (content is encrypted).\n */\nexport type SearchCriteria = {\n\t/**\n\t * Match objects with paths starting with this prefix\n\t * e.g., \"/user/keeta1abc.../contacts/\"\n\t */\n\tpathPrefix?: string;\n\n\t/**\n\t * Match objects that have ANY of these tags\n\t */\n\ttags?: string[];\n\n\t/**\n\t * Match path segment (filename portion)\n\t */\n\tname?: string;\n\n\t/**\n\t * Filter by owner's public key\n\t */\n\towner?: string;\n\n\t/**\n\t * Include objects in nested paths (default: false)\n\t */\n\trecursive?: boolean;\n\n\t/**\n\t * Filter by visibility.\n\t * When 'public', allows searching public objects outside caller's namespace.\n\t */\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Pagination options for search\n */\nexport type SearchPagination = {\n\t/**\n\t * Cursor for pagination (from previous response)\n\t */\n\tcursor?: string;\n\n\t/**\n\t * Maximum number of results to return\n\t */\n\tlimit?: number;\n};\n\n/**\n * Search results with pagination\n */\nexport type SearchResults = {\n\t/**\n\t * Matching objects\n\t */\n\tresults: StorageObjectMetadata[];\n\n\t/**\n\t * Cursor for next page (undefined if no more results)\n\t */\n\tnextCursor?: string;\n};\n\n// #endregion\n\n// #region Quota\n\n/**\n * Quota configuration for the storage service\n */\nexport type QuotaConfig = {\n\t/**\n\t * Maximum size in bytes per object\n\t */\n\tmaxObjectSize: number;\n\n\t/**\n\t * Maximum number of objects per user\n\t */\n\tmaxObjectsPerUser: number;\n\n\t/**\n\t * Maximum total storage in bytes per user\n\t */\n\tmaxStoragePerUser: number;\n\n\t/**\n\t * Maximum number of results per search request\n\t */\n\tmaxSearchLimit: number;\n\n\t/**\n\t * Maximum TTL in seconds for signed URLs\n\t */\n\tmaxSignedUrlTTL: number;\n};\n\n/**\n * Per-user quota limits.\n * Subset of QuotaConfig that can be overridden on a per-user basis.\n */\nexport type QuotaLimits = Pick<QuotaConfig, 'maxObjectsPerUser' | 'maxStoragePerUser' | 'maxObjectSize'>;\n\n/**\n * Current quota status for a user.\n * Backends must provide objectCount and totalSize.\n */\nexport type QuotaStatus = {\n\t/**\n\t * Current number of objects\n\t */\n\tobjectCount: number;\n\n\t/**\n\t * Current total size in bytes\n\t */\n\ttotalSize: number;\n\n\t/**\n\t * Remaining objects allowed (optional, server computes if absent)\n\t */\n\tremainingObjects?: number;\n\n\t/**\n\t * Remaining storage in bytes (optional, server computes if absent)\n\t */\n\tremainingSize?: number;\n};\n\n// #endregion\n\n// #region Request Type Helpers\n\n// #endregion\n\n// #region PUT Object\n\n/**\n * Client-side request to put (create/update) an object\n */\nexport type KeetaStorageAnchorPutClientRequest = {\n\taccount?: KeetaNetAccount;\n\tpath: string;\n\tdata: string; // Base64-encoded EncryptedContainer\n\ttags?: string[];\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Server-side request to put an object\n */\nexport type KeetaStorageAnchorPutRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tpath: string;\n\tdata: string;\n\ttags?: string[];\n\tvisibility?: StorageObjectVisibility;\n};\n\n/**\n * Configuration for a contacts client.\n * Contacts are stored in a subdirectory of the account's working directory.\n */\nexport type ContactsClientConfig = {\n\t/**\n\t * The account to use for the contacts client.\n\t */\n\taccount: KeetaNetAccount;\n\t/**\n\t * The base path for the contacts client.\n\t */\n\tbasePath: string;\n};\n\n/**\n * Configuration for an icons client.\n * The icon is stored as a single file under the base path.\n */\nexport type IconsClientConfig = {\n\t/**\n\t * The account to use for the icons client.\n\t */\n\taccount: KeetaNetAccount;\n\t/**\n\t * The base path for the icons client (e.g., `/user/<pubkey>/`).\n\t */\n\tbasePath: string;\n};\n\n/**\n * Generic response type for storage operations.\n */\nexport type StorageResponse<T> = ({ ok: true } & T) | { ok: false; error: string };\n\nexport type KeetaStorageAnchorPutResponse = StorageResponse<{ object: StorageObjectMetadata }>;\n\nexport function getKeetaStorageAnchorPutRequestSigningData(\n\tinput: { path: string; visibility?: StorageObjectVisibility; tags?: string[] }\n): Signable {\n\tconst visibility = input.visibility ?? 'private';\n\tconst tags: string[] = input.tags ?? [];\n\tconst sortedTags = [...tags].sort();\n\treturn(['put', input.path, visibility, ...sortedTags]);\n}\n\n// #endregion\n\n// #region Update Metadata\n\n/**\n * Server-side request to update object metadata.\n * Path is derived from the URL, not the body.\n */\nexport type KeetaStorageAnchorUpdateMetadataRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\ttags: string[];\n\tvisibility: StorageObjectVisibility;\n};\n\n/**\n * Build signing data for an update-metadata request.\n * Tags are sorted with localeCompare for deterministic signatures.\n */\nexport function getKeetaStorageAnchorUpdateMetadataRequestSigningData(\n\tinput: { path: string; visibility: StorageObjectVisibility; tags: string[] }\n): Signable {\n\tconst sortedTags = [...input.tags].sort(function(a, b) { return(a.localeCompare(b)); });\n\treturn(['updateMetadata', input.path, input.visibility, ...sortedTags]);\n}\n\n// #endregion\n\n// #region GET Object\n\n/**\n * Client-side request to get an object\n */\nexport type KeetaStorageAnchorGetClientRequest = {\n\taccount?: KeetaNetAccount;\n\tpath: string;\n};\n\n/**\n * Server-side request to get an object\n */\nexport type KeetaStorageAnchorGetRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tpath: string;\n};\n\nexport type KeetaStorageAnchorGetResponse = StorageResponse<{\n\tdata: string; // Base64-encoded EncryptedContainer\n\tobject: StorageObjectMetadata;\n}>;\n\nexport function getKeetaStorageAnchorGetRequestSigningData(\n\tinput: KeetaStorageAnchorGetRequest\n): Signable {\n\treturn(['get', input.path]);\n}\n\n// #endregion\n\n// #region DELETE Object\n\n/**\n * Client-side request to delete an object\n */\nexport type KeetaStorageAnchorDeleteClientRequest = {\n\taccount?: KeetaNetAccount;\n\t/**\n\t * Path to the object\n\t */\n\tpath: string;\n};\n\n/**\n * Server-side request to delete an object\n */\nexport type KeetaStorageAnchorDeleteRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\t/**\n\t * Path to the object\n\t */\n\tpath: string;\n};\n\nexport type KeetaStorageAnchorDeleteResponse = StorageResponse<{ deleted: boolean }>;\n\nexport function getKeetaStorageAnchorDeleteRequestSigningData(\n\tinput: KeetaStorageAnchorDeleteRequest\n): Signable {\n\treturn(['delete', input.path]);\n}\n\n// #endregion\n\n// #region SEARCH\n\n/**\n * Client-side request to search objects\n */\nexport type KeetaStorageAnchorSearchClientRequest = {\n\taccount?: KeetaNetAccount;\n\tcriteria: SearchCriteria;\n\tpagination?: SearchPagination;\n};\n\n/**\n * Server-side request to search objects\n */\nexport type KeetaStorageAnchorSearchRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n\tcriteria: SearchCriteria;\n\tpagination?: SearchPagination;\n};\n\nexport type KeetaStorageAnchorSearchResponse = StorageResponse<{\n\tresults: StorageObjectMetadata[];\n\tnextCursor?: string;\n}>;\n\nexport function getKeetaStorageAnchorSearchRequestSigningData(\n\tinput: KeetaStorageAnchorSearchRequest\n): Signable {\n\tconst limit = input.pagination?.limit ?? 0;\n\tconst cursor = input.pagination?.cursor ?? '';\n\treturn(['search', JSON.stringify(input.criteria), limit, cursor]);\n}\n\n// #endregion\n\n// #region Quota\n\n/**\n * Client-side request to get quota status\n */\nexport type KeetaStorageAnchorQuotaClientRequest = {\n\taccount?: KeetaNetAccount;\n};\n\n/**\n * Server-side request to get quota status\n */\nexport type KeetaStorageAnchorQuotaRequest = {\n\taccount?: string;\n\tsigned?: HTTPSignedField;\n};\n\nexport type KeetaStorageAnchorQuotaResponse = StorageResponse<{ quota: QuotaStatus }>;\n\n/**\n * Get signing data for quota requests.\n * The input is unused because quota requests don't need request-specific signing -\n * authentication alone is sufficient.\n *\n * The parameter was kept for API consistency with other signing functions.\n */\nexport function getKeetaStorageAnchorQuotaRequestSigningData(\n\t_ignoreInput: KeetaStorageAnchorQuotaRequest\n): Signable {\n\treturn(['quota']);\n}\n\n// #endregion\n\n// #region Error Classes\n\nclass KeetaStorageAnchorDocumentNotFoundError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorDocumentNotFoundError';\n\tprivate readonly KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID = 'ac137e18-2827-4542-a852-c650610899b5';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Document not found');\n\t\tthis.statusCode = 404;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorDocumentNotFoundError.KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorDocumentNotFoundError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID', KeetaStorageAnchorDocumentNotFoundError.KeetaStorageAnchorDocumentNotFoundErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorDocumentNotFoundError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorAccessDeniedError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorAccessDeniedError';\n\tprivate readonly KeetaStorageAnchorAccessDeniedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorAccessDeniedErrorObjectTypeID = 'fb75fa8c-6ef0-47cb-b767-3c2cfbb73617';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Access denied');\n\t\tthis.statusCode = 403;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorAccessDeniedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorAccessDeniedError.KeetaStorageAnchorAccessDeniedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorAccessDeniedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorAccessDeniedErrorObjectTypeID', KeetaStorageAnchorAccessDeniedError.KeetaStorageAnchorAccessDeniedErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorAccessDeniedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidPathError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidPathError';\n\tprivate readonly KeetaStorageAnchorInvalidPathErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidPathErrorObjectTypeID = 'eb0e1c0d-2281-4b93-9f78-87bf166a4829';\n\n\tconstructor(message?: string) {\n\t\tsuper({ fields: [{ path: 'path', message: message ?? 'Invalid path format' }] }, message ?? 'Invalid path format');\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidPathErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidPathError.KeetaStorageAnchorInvalidPathErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidPathError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidPathErrorObjectTypeID', KeetaStorageAnchorInvalidPathError.KeetaStorageAnchorInvalidPathErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidPathError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\ntype QuotaExceededType = 'maxObjectSize' | 'maxObjectsPerUser' | 'maxStoragePerUser';\n\nclass KeetaStorageAnchorQuotaExceededError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorQuotaExceededError';\n\tprivate readonly KeetaStorageAnchorQuotaExceededErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorQuotaExceededErrorObjectTypeID = 'c0b75028-644a-472b-8df4-b0a856814f99';\n\n\t/** Which quota limit was exceeded */\n\treadonly quotaType: QuotaExceededType;\n\n\t/** The configured maximum for the exceeded quota */\n\treadonly limit: number;\n\n\t/** The current or attempted value that exceeded the limit */\n\treadonly current: number;\n\n\tconstructor(options: { quotaType: QuotaExceededType; limit: number; current: number; message?: string }) {\n\t\tsuper(options.message ?? `Quota exceeded: ${options.quotaType} (${options.current} exceeds limit of ${options.limit})`);\n\t\tthis.statusCode = 413;\n\t\tthis.quotaType = options.quotaType;\n\t\tthis.limit = options.limit;\n\t\tthis.current = options.current;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorQuotaExceededErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorQuotaExceededError.KeetaStorageAnchorQuotaExceededErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorQuotaExceededError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorQuotaExceededErrorObjectTypeID', KeetaStorageAnchorQuotaExceededError.KeetaStorageAnchorQuotaExceededErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorQuotaExceededError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this({ quotaType: 'maxObjectSize', limit: 0, current: 0, message });\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorPrincipalRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorPrincipalRequiredError';\n\tprivate readonly KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID = '12e42092-d4db-435e-8a01-798e26f653b4';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Validated path requires anchor as principal');\n\t\tthis.statusCode = 400;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorPrincipalRequiredError.KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorPrincipalRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID', KeetaStorageAnchorPrincipalRequiredError.KeetaStorageAnchorPrincipalRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorPrincipalRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorValidationFailedError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorValidationFailedError';\n\tprivate readonly KeetaStorageAnchorValidationFailedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorValidationFailedErrorObjectTypeID = '73cadd95-cf39-466b-b9b6-484e1ae1ca9c';\n\n\tconstructor(message?: string) {\n\t\tconst msg = message ?? 'Content validation failed';\n\t\tsuper({ fields: [{ path: 'content', message: msg }] }, msg);\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorValidationFailedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorValidationFailedError.KeetaStorageAnchorValidationFailedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\toverride get statusCode() {\n\t\treturn(422);\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorValidationFailedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorValidationFailedErrorObjectTypeID', KeetaStorageAnchorValidationFailedError.KeetaStorageAnchorValidationFailedErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorValidationFailedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignatureExpiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignatureExpiredError';\n\tprivate readonly KeetaStorageAnchorSignatureExpiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignatureExpiredErrorObjectTypeID = '3a676e44-882b-4925-bf5f-bc5123cc0b20';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Pre-signed URL has expired');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignatureExpiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignatureExpiredError.KeetaStorageAnchorSignatureExpiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignatureExpiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignatureExpiredErrorObjectTypeID', KeetaStorageAnchorSignatureExpiredError.KeetaStorageAnchorSignatureExpiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignatureExpiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignatureInvalidError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignatureInvalidError';\n\tprivate readonly KeetaStorageAnchorSignatureInvalidErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignatureInvalidErrorObjectTypeID = '91831c73-31e2-4f27-a9d1-4ab9a5ed5663';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Pre-signed URL signature verification failed');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignatureInvalidErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignatureInvalidError.KeetaStorageAnchorSignatureInvalidErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignatureInvalidError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignatureInvalidErrorObjectTypeID', KeetaStorageAnchorSignatureInvalidError.KeetaStorageAnchorSignatureInvalidErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignatureInvalidError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorPrivateKeyRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorPrivateKeyRequiredError';\n\tprivate readonly KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID = '36eaae98-1b1e-412b-ba5b-b9293cc37156';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Account with private key required for this operation');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorPrivateKeyRequiredError.KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorPrivateKeyRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID', KeetaStorageAnchorPrivateKeyRequiredError.KeetaStorageAnchorPrivateKeyRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorPrivateKeyRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorServiceUnavailableError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorServiceUnavailableError';\n\tprivate readonly KeetaStorageAnchorServiceUnavailableErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorServiceUnavailableErrorObjectTypeID = 'b2671cd1-6abb-4bd4-9be2-d8d111c17bcf';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Storage service not available');\n\t\tthis.statusCode = 503;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorServiceUnavailableErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorServiceUnavailableError.KeetaStorageAnchorServiceUnavailableErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorServiceUnavailableError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorServiceUnavailableErrorObjectTypeID', KeetaStorageAnchorServiceUnavailableError.KeetaStorageAnchorServiceUnavailableErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorServiceUnavailableError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorSignerRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorSignerRequiredError';\n\tprivate readonly KeetaStorageAnchorSignerRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorSignerRequiredErrorObjectTypeID = 'ce4a5581-1869-4656-88c6-63f0a29b46ca';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'A Signer or UserClient with an associated Signer is required');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorSignerRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorSignerRequiredError.KeetaStorageAnchorSignerRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorSignerRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorSignerRequiredErrorObjectTypeID', KeetaStorageAnchorSignerRequiredError.KeetaStorageAnchorSignerRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorSignerRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorAccountRequiredError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorAccountRequiredError';\n\tprivate readonly KeetaStorageAnchorAccountRequiredErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorAccountRequiredErrorObjectTypeID = '496e5dbe-535f-4f24-acf4-a44d9d93fb75';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'An Account or UserClient with an associated Account is required');\n\t\tthis.statusCode = 401;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorAccountRequiredErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorAccountRequiredError.KeetaStorageAnchorAccountRequiredErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorAccountRequiredError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorAccountRequiredErrorObjectTypeID', KeetaStorageAnchorAccountRequiredError.KeetaStorageAnchorAccountRequiredErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorAccountRequiredError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorOperationNotSupportedError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorOperationNotSupportedError';\n\tprivate readonly KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID = 'ac491ea6-f656-4eab-a430-051a0f201fff';\n\n\tconstructor(operation?: string) {\n\t\tsuper(operation ? `Storage service does not support '${operation}' operation` : 'Operation not supported');\n\t\tthis.statusCode = 501;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorOperationNotSupportedError.KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorOperationNotSupportedError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID', KeetaStorageAnchorOperationNotSupportedError.KeetaStorageAnchorOperationNotSupportedErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorOperationNotSupportedError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorUnsupportedAuthMethodError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorUnsupportedAuthMethodError';\n\tprivate readonly KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID = '46cfbab9-934f-44b0-9216-03d397fdd6b6';\n\n\tconstructor(method?: string) {\n\t\tsuper(method ? `Unsupported authentication method: ${method}` : 'Unsupported authentication method');\n\t\tthis.statusCode = 501;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorUnsupportedAuthMethodError.KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorUnsupportedAuthMethodError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID', KeetaStorageAnchorUnsupportedAuthMethodError.KeetaStorageAnchorUnsupportedAuthMethodErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorUnsupportedAuthMethodError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidResponseError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidResponseError';\n\tprivate readonly KeetaStorageAnchorInvalidResponseErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidResponseErrorObjectTypeID = '02480186-7bc3-4a80-b6a9-23c3a9f606c9';\n\n\tconstructor(details?: string) {\n\t\tsuper(details ? `Invalid response from storage service: ${details}` : 'Invalid response from storage service');\n\t\tthis.statusCode = 502;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidResponseErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidResponseError.KeetaStorageAnchorInvalidResponseErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvalidResponseError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidResponseErrorObjectTypeID', KeetaStorageAnchorInvalidResponseError.KeetaStorageAnchorInvalidResponseErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidResponseError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidAnchorAccountError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidAnchorAccountError';\n\tprivate readonly KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID = '82bb0a94-0a5e-4e0a-b5c1-7532bbe09cd6';\n\n\tconstructor(publicKey?: string) {\n\t\tsuper(publicKey ? `Invalid anchor account public key: ${publicKey}` : 'Invalid anchor account public key');\n\t\tthis.statusCode = 502;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidAnchorAccountError.KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvalidAnchorAccountError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID', KeetaStorageAnchorInvalidAnchorAccountError.KeetaStorageAnchorInvalidAnchorAccountErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidAnchorAccountError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvariantViolationError extends KeetaAnchorUserError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvariantViolationError';\n\tprivate readonly KeetaStorageAnchorInvariantViolationErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvariantViolationErrorObjectTypeID = 'a7c5d3e1-8b9f-4c2a-b3d4-e5f6a7b8c9d0';\n\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Internal invariant violation');\n\t\tthis.statusCode = 500;\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvariantViolationErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvariantViolationError.KeetaStorageAnchorInvariantViolationErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic isInstance(input: unknown): input is KeetaStorageAnchorInvariantViolationError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvariantViolationErrorObjectTypeID', KeetaStorageAnchorInvariantViolationError.KeetaStorageAnchorInvariantViolationErrorObjectTypeID));\n\t}\n\n\tstatic async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvariantViolationError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidTagError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidTagError';\n\tprivate readonly KeetaStorageAnchorInvalidTagErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidTagErrorObjectTypeID = 'b8d6e4f2-9c0a-5d3b-c4e5-f6a7b8c9d0e1';\n\n\tconstructor(message?: string) {\n\t\tsuper({ fields: [{ path: 'tags', message: message ?? 'Invalid tag' }] }, message ?? 'Invalid tag');\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidTagErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidTagError.KeetaStorageAnchorInvalidTagErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidTagError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidTagErrorObjectTypeID', KeetaStorageAnchorInvalidTagError.KeetaStorageAnchorInvalidTagErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidTagError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nclass KeetaStorageAnchorInvalidMetadataError extends KeetaAnchorUserValidationError {\n\tstatic override readonly name: string = 'KeetaStorageAnchorInvalidMetadataError';\n\tprivate readonly KeetaStorageAnchorInvalidMetadataErrorObjectTypeID!: string;\n\tprivate static readonly KeetaStorageAnchorInvalidMetadataErrorObjectTypeID = 'c9e7f5a3-0d1b-6e4c-d5f6-a7b8c9d0e1f2';\n\n\tconstructor(reason?: string) {\n\t\tconst message = reason ? `Invalid metadata: ${reason}` : 'Invalid metadata';\n\t\tsuper({ fields: [{ path: 'metadata', message }] }, message);\n\n\t\tObject.defineProperty(this, 'KeetaStorageAnchorInvalidMetadataErrorObjectTypeID', {\n\t\t\tvalue: KeetaStorageAnchorInvalidMetadataError.KeetaStorageAnchorInvalidMetadataErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\t}\n\n\tstatic override isInstance(input: unknown): input is KeetaStorageAnchorInvalidMetadataError {\n\t\treturn(this.hasPropWithValue(input, 'KeetaStorageAnchorInvalidMetadataErrorObjectTypeID', KeetaStorageAnchorInvalidMetadataError.KeetaStorageAnchorInvalidMetadataErrorObjectTypeID));\n\t}\n\n\tstatic override async fromJSON(input: unknown): Promise<KeetaStorageAnchorInvalidMetadataError> {\n\t\tconst { message, other } = this.extractErrorProperties(input, this);\n\t\tconst error = new this(message);\n\t\terror.restoreFromJSON(other);\n\t\treturn(error);\n\t}\n}\n\nexport const Errors: {\n\tDocumentNotFound: typeof KeetaStorageAnchorDocumentNotFoundError;\n\tAccessDenied: typeof KeetaStorageAnchorAccessDeniedError;\n\tInvalidPath: typeof KeetaStorageAnchorInvalidPathError;\n\tQuotaExceeded: typeof KeetaStorageAnchorQuotaExceededError;\n\tAnchorPrincipalRequired: typeof KeetaStorageAnchorPrincipalRequiredError;\n\tValidationFailed: typeof KeetaStorageAnchorValidationFailedError;\n\tSignatureExpired: typeof KeetaStorageAnchorSignatureExpiredError;\n\tSignatureInvalid: typeof KeetaStorageAnchorSignatureInvalidError;\n\tPrivateKeyRequired: typeof KeetaStorageAnchorPrivateKeyRequiredError;\n\tServiceUnavailable: typeof KeetaStorageAnchorServiceUnavailableError;\n\tSignerRequired: typeof KeetaStorageAnchorSignerRequiredError;\n\tAccountRequired: typeof KeetaStorageAnchorAccountRequiredError;\n\tOperationNotSupported: typeof KeetaStorageAnchorOperationNotSupportedError;\n\tUnsupportedAuthMethod: typeof KeetaStorageAnchorUnsupportedAuthMethodError;\n\tInvalidResponse: typeof KeetaStorageAnchorInvalidResponseError;\n\tInvalidAnchorAccount: typeof KeetaStorageAnchorInvalidAnchorAccountError;\n\tInvariantViolation: typeof KeetaStorageAnchorInvariantViolationError;\n\tInvalidTag: typeof KeetaStorageAnchorInvalidTagError;\n\tInvalidMetadata: typeof KeetaStorageAnchorInvalidMetadataError;\n} = {\n\t/**\n\t * The requested document/object was not found\n\t */\n\tDocumentNotFound: KeetaStorageAnchorDocumentNotFoundError,\n\n\t/**\n\t * Access to the document/object was denied\n\t */\n\tAccessDenied: KeetaStorageAnchorAccessDeniedError,\n\n\t/**\n\t * Path doesn't match /user/<pubkey>/... format\n\t */\n\tInvalidPath: KeetaStorageAnchorInvalidPathError,\n\n\t/**\n\t * Object size, count, or total storage limit exceeded\n\t */\n\tQuotaExceeded: KeetaStorageAnchorQuotaExceededError,\n\n\t/**\n\t * Validated path requires anchor as principal\n\t */\n\tAnchorPrincipalRequired: KeetaStorageAnchorPrincipalRequiredError,\n\n\t/**\n\t * Namespace validator rejected content\n\t */\n\tValidationFailed: KeetaStorageAnchorValidationFailedError,\n\n\t/**\n\t * Pre-signed URL has expired\n\t */\n\tSignatureExpired: KeetaStorageAnchorSignatureExpiredError,\n\n\t/**\n\t * Pre-signed URL signature verification failed\n\t */\n\tSignatureInvalid: KeetaStorageAnchorSignatureInvalidError,\n\n\t/**\n\t * Account with private key required for this operation\n\t */\n\tPrivateKeyRequired: KeetaStorageAnchorPrivateKeyRequiredError,\n\n\t/**\n\t * Storage service is not available\n\t */\n\tServiceUnavailable: KeetaStorageAnchorServiceUnavailableError,\n\n\t/**\n\t * A Signer or UserClient with an associated Signer is required\n\t */\n\tSignerRequired: KeetaStorageAnchorSignerRequiredError,\n\n\t/**\n\t * An Account or UserClient with an associated Account is required\n\t */\n\tAccountRequired: KeetaStorageAnchorAccountRequiredError,\n\n\t/**\n\t * The requested operation is not supported by this storage service\n\t */\n\tOperationNotSupported: KeetaStorageAnchorOperationNotSupportedError,\n\n\t/**\n\t * The authentication method is not supported\n\t */\n\tUnsupportedAuthMethod: KeetaStorageAnchorUnsupportedAuthMethodError,\n\n\t/**\n\t * Invalid response received from storage service\n\t */\n\tInvalidResponse: KeetaStorageAnchorInvalidResponseError,\n\n\t/**\n\t * Anchor account public key from service metadata is invalid\n\t */\n\tInvalidAnchorAccount: KeetaStorageAnchorInvalidAnchorAccountError,\n\n\t/**\n\t * Internal invariant violation - indicates a bug in the code\n\t */\n\tInvariantViolation: KeetaStorageAnchorInvariantViolationError,\n\n\t/**\n\t * Tag validation failed (invalid format, too long, or too many tags)\n\t */\n\tInvalidTag: KeetaStorageAnchorInvalidTagError,\n\n\t/**\n\t * Metadata validation failed against path policy constraints\n\t */\n\tInvalidMetadata: KeetaStorageAnchorInvalidMetadataError\n};\n\n// #endregion\n\n// #region Storage Backend Interface\n\n/**\n * Metadata input for put operations.\n * Provided by the client when storing an object.\n */\nexport type StoragePutMetadata = {\n\t/** Owner's identifier */\n\towner: string;\n\t/** Tags for categorization and search */\n\ttags: string[];\n\t/** Access visibility setting */\n\tvisibility: StorageObjectVisibility;\n};\n\n/**\n * Result of a get operation.\n * Contains both the raw encrypted data and the object metadata.\n */\nexport type StorageGetResult = {\n\t/** Raw encrypted data (EncryptedContainer) */\n\tdata: Buffer;\n\t/** Object metadata */\n\tmetadata: StorageObjectMetadata;\n};\n\n/**\n * Represents a pending upload quota reservation.\n * Used to reserve quota before an upload and track in-flight uploads.\n */\nexport interface UploadReservation {\n\t/** Unique identifier for this reservation */\n\tid: string;\n\t/** Owner's identifier */\n\towner: string;\n\t/** Target path for the upload */\n\tpath: string;\n\t/** Reserved size in bytes */\n\tsize: number;\n\t/** When the reservation was created */\n\tcreatedAt: string;\n\t/** When the reservation expires - hint for stale cleanup */\n\texpiresAt: string;\n}\n\n/**\n * Core CRUD operations for storage.\n * All backends must implement these operations.\n */\nexport interface StorageBackend {\n\t/**\n\t * Store/update an object at the given path\n\t */\n\tput(path: string, data: Buffer, metadata: StoragePutMetadata): Promise<StorageObjectMetadata>;\n\n\t/**\n\t * Retrieve an object by path\n\t */\n\tget(path: string): Promise<StorageGetResult | null>;\n\n\t/**\n\t * Delete an object by path\n\t */\n\tdelete(path: string): Promise<boolean>;\n\n\t/**\n\t * Update metadata for an existing object without re-uploading data.\n\t * @returns Updated metadata, or null if the object does not exist\n\t */\n\tupdateMetadata?(path: string, metadata: Omit<StoragePutMetadata, 'owner'>): Promise<StorageObjectMetadata | null>;\n}\n\n/**\n * Search capability interface.\n * Optional for backends that don't support indexing (e.g., simple S3-only backends).\n */\nexport interface SearchableStorage {\n\t/**\n\t * Search for objects matching criteria\n\t */\n\tsearch(criteria: SearchCriteria, pagination: SearchPagination): Promise<SearchResults>;\n}\n\n/**\n * Quota management with upload reservations.\n * Handles quota tracking and reservation-based upload flow.\n */\nexport interface QuotaManagedStorage {\n\t/**\n\t * Get quota status for a user.\n\t * Includes both actual usage and pending reservations.\n\t */\n\tgetQuotaStatus(owner: string): Promise<QuotaStatus>;\n\n\t/**\n\t * Get per-user quota limits.\n\t * Return null to use global defaults.\n\t * @param owner - Owner's identifier\n\t */\n\tgetQuotaLimits?(owner: string): Promise<QuotaLimits | null>;\n\n\t/**\n\t * Reserve quota for an upcoming upload.\n\t *\n\t * @param owner - Owner's identifier\n\t * @param path - Target path for the upload\n\t * @param size - Size in bytes to reserve\n\t * @param options.ttlMs - Optional TTL in milliseconds for the reservation\n\t * @param options.quotaLimits - Optional quota limits to enforce (overrides backend defaults)\n\t *\n\t * @returns Reservation that must be committed or released\n\t *\n\t * @throws QuotaExceeded if reservation would exceed limits\n\t */\n\treserveUpload(owner: string, path: string, size: number, options?: {\n\t\tttlMs?: number;\n\t\tquotaLimits?: Pick<QuotaConfig, 'maxObjectsPerUser' | 'maxStoragePerUser'>;\n\t}): Promise<UploadReservation>;\n\n\t/**\n\t * Commit a reservation after successful upload.\n\t * Call after put() succeeds to finalize the quota usage.\n\t * @param reservationId - ID of the reservation to commit\n\t */\n\tcommitUpload(reservationId: string): Promise<void>;\n\n\t/**\n\t * Release a reservation (upload failed or cancelled).\n\t * Frees the reserved quota.\n\t * @param reservationId - ID of the reservation to release\n\t */\n\treleaseUpload(reservationId: string): Promise<void>;\n}\n\n/**\n * Full storage backend combining all capabilities.\n * Use this type when a backend supports CRUD, search, and quota management.\n */\nexport type FullStorageBackend = StorageBackend & SearchableStorage & QuotaManagedStorage;\n\n// #endregion\n\n// #region Path Policy\n\n/**\n * Operations that can be performed on storage objects.\n */\nexport type StorageOperation = 'get' | 'put' | 'delete' | 'search' | 'metadata' | 'updateMetadata';\n\n/**\n * Shared fields available to all policy context variants.\n */\nexport interface PathPolicyContextBase {\n\taccount: KeetaNetAccount;\n}\n\n/**\n * Context for PUT operations.\n * Contains the metadata being written and the encrypted container.\n */\nexport interface PutPolicyContext extends PathPolicyContextBase {\n\toperation: 'put';\n\tmetadata: StoragePutMetadata;\n\tcontainer: EncryptedContainer;\n}\n\n/**\n * Context for metadata update operations.\n * Contains the new metadata values and the current object metadata before mutation.\n */\nexport interface UpdateMetadataPolicyContext extends PathPolicyContextBase {\n\toperation: 'updateMetadata';\n\tmetadata: StoragePutMetadata;\n\tcurrent: StorageObjectMetadata;\n}\n\n/**\n * Context for GET operations.\n */\nexport interface GetPolicyContext extends PathPolicyContextBase {\n\toperation: 'get';\n}\n\n/**\n * Context for DELETE operations.\n */\nexport interface DeletePolicyContext extends PathPolicyContextBase {\n\toperation: 'delete';\n}\n\n/**\n * Context for metadata read operations.\n */\nexport interface MetadataPolicyContext extends PathPolicyContextBase {\n\toperation: 'metadata';\n}\n\n/**\n * Discriminated union of all policy validation contexts.\n * Narrows on `operation` to access operation-specific fields.\n */\nexport type PathPolicyContext =\n\t| PutPolicyContext\n\t| UpdateMetadataPolicyContext\n\t| GetPolicyContext\n\t| DeletePolicyContext\n\t| MetadataPolicyContext;\n\n/**\n * Generic interface for path policies.\n * Each implementation defines its own parsed type and access control logic.\n * Storage Anchors are free to implement whatever pathname structure they wish.\n */\nexport interface PathPolicy<TPathInfo> {\n\t/**\n\t * Parse a path into its components.\n\t * @returns TPathInfo if valid, null otherwise\n\t */\n\tparse(path: string): TPathInfo | null;\n\n\t/**\n\t * Validate a path and return its components.\n\t * @throws Errors.InvalidPath if the path is invalid\n\t */\n\tvalidate(path: string): TPathInfo;\n\n\t/**\n\t * Check if a path is valid.\n\t */\n\tisValid(path: string): boolean;\n\n\t/**\n\t * Check if the account has access to perform the operation on the parsed path.\n\t * @returns true if access is allowed, false otherwise\n\t */\n\tcheckAccess(account: KeetaNetAccount, parsed: TPathInfo, operation: StorageOperation): boolean;\n\n\t/**\n\t * Get the account authorized to sign pre-signed URLs for this path.\n\t * Used for public object access verification.\n\t *\n\t * @returns The account if only that account can sign (owner-restricted), or `null` if any account can sign\n\t */\n\tgetAuthorizedSigner(parsed: TPathInfo): KeetaNetAccount | null;\n\n\t/**\n\t * Validate the request context for a path.\n\t *\n\t * @param parsed - The parsed path info\n\t * @param context - The operation-specific validation context\n\t * @throws Errors.InvalidMetadata if the context violates policy constraints\n\t */\n\tvalidateContext?(parsed: TPathInfo, context: PathPolicyContext): void;\n}\n\n// #endregion\n\n// #region Container Payload Utilities\n\n/**\n * Parse the decrypted plaintext from an EncryptedContainer.\n * The payload is expected to be JSON with mimeType and base64-encoded data,\n * keeping the mimeType encrypted along with the content.\n *\n * @param plaintext - The decrypted plaintext from an EncryptedContainer\n *\n * @returns Object containing mimeType and content Buffer\n */\nexport function parseContainerPayload(plaintext: ArrayBuffer): { mimeType: string; content: Buffer } {\n\tconst payloadStr = Buffer.from(plaintext).toString('utf-8');\n\ttry {\n\t\tconst payload: unknown = JSON.parse(payloadStr);\n\t\tlet mimeType = CONTENT_TYPE_OCTET_STREAM;\n\t\tlet content: Buffer;\n\t\tif (typeof payload === 'object' && payload !== null && !Array.isArray(payload)) {\n\t\t\tconst payloadMime = 'mimeType' in payload ? payload.mimeType : undefined;\n\t\t\tconst payloadData = 'data' in payload ? payload.data : undefined;\n\t\t\tif (typeof payloadMime === 'string') {\n\t\t\t\tmimeType = payloadMime;\n\t\t\t}\n\t\t\tif (typeof payloadData === 'string') {\n\t\t\t\tcontent = arrayBufferLikeToBuffer(Buffer.from(payloadData, 'base64'));\n\t\t\t} else {\n\t\t\t\tcontent = arrayBufferLikeToBuffer(plaintext);\n\t\t\t}\n\t\t} else {\n\t\t\tcontent = arrayBufferLikeToBuffer(plaintext);\n\t\t}\n\t\treturn({ mimeType, content });\n\t} catch {\n\t\treturn({\n\t\t\tmimeType: CONTENT_TYPE_OCTET_STREAM,\n\t\t\tcontent: arrayBufferLikeToBuffer(plaintext)\n\t\t});\n\t}\n}\n\n// #endregion\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/services/storage/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAIjD,OAAO,KAAK,EAKX,kBAAkB,EAClB,WAAW,EAGX,UAAU,EAIV,MAAM,aAAa,CAAC;AA6BrB,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AA+MzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB,CAAC,2BAA2B;IACxG;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAErD;;;OAGG;IACH,OAAO,EAAE,kBAAkB,CAAC;IAE5B;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAElC;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAElC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;;OAGG;IACH,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAEpC;;OAEG;IACH,aAAa,CAAC,EAAE;QACf,sDAAsD;QACtD,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,+CAA+C;QAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qEAAqE;QACrE,OAAO,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACF;AAkBD,qBAAa,+BAAgC,SAAQ,qBAAqB,CAAC,wBAAwB,CAAC,8BAA8B,CAAC;IAClI,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3E,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1C,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,8BAA8B,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBAEnF,MAAM,EAAE,8BAA8B;cAwDlC,UAAU,CAAC,aAAa,EAAE,8BAA8B,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC;IAqgB1G,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CAqB7F"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/services/storage/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,qBAAqB,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAIjD,OAAO,KAAK,EAKX,kBAAkB,EAClB,WAAW,EAKX,UAAU,EAIV,MAAM,aAAa,CAAC;AA6BrB,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAiNzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB,CAAC,2BAA2B;IACxG;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;IAErD;;;OAGG;IACH,OAAO,EAAE,kBAAkB,CAAC;IAE5B;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAElC;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAElC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;;OAGG;IACH,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAEpC;;OAEG;IACH,aAAa,CAAC,EAAE;QACf,sDAAsD;QACtD,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,+CAA+C;QAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qEAAqE;QACrE,OAAO,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACF;AAkBD,qBAAa,+BAAgC,SAAQ,qBAAqB,CAAC,wBAAwB,CAAC,8BAA8B,CAAC;IAClI,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3E,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1C,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,8BAA8B,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBAEnF,MAAM,EAAE,8BAA8B;cAwDlC,UAAU,CAAC,aAAa,EAAE,8BAA8B,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC;IAohB1G,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CAqB7F"}
@@ -161,12 +161,14 @@ function extractObjectPath(params) {
161
161
  */
162
162
  async function authorizeURLAccess(pathPolicies, params, url, operation, getSigningData, buildRequest) {
163
163
  const objectPath = extractObjectPath(params);
164
- parsePath(pathPolicies, objectPath);
164
+ const { policy, parsed } = parsePath(pathPolicies, objectPath);
165
165
  const account = await verifyURLAuth(url, getSigningData, function (pubKey) {
166
166
  return (buildRequest(objectPath, pubKey));
167
167
  });
168
- assertPathAccess(pathPolicies, account, objectPath, operation);
169
- return ({ account, objectPath });
168
+ if (!policy.checkAccess(account, parsed, operation)) {
169
+ throw (new Errors.AccessDenied('Can only access your own namespace'));
170
+ }
171
+ return ({ account, objectPath, policy, parsed });
170
172
  }
171
173
  // Default quota configuration
172
174
  const DEFAULT_QUOTAS = {
@@ -361,13 +363,11 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
361
363
  // Validate path format, metadata, and ownership
362
364
  const { policy, parsed } = assertPathAccess(pathPolicies, account, objectPath, 'put');
363
365
  const owner = account.publicKeyString.get();
364
- if (policy.validateMetadata) {
365
- policy.validateMetadata(parsed, { owner, tags, visibility });
366
- }
367
366
  // Resolve per-user quota limits, falling back to global config
368
- const userLimits = backend.getQuotaLimits
369
- ? await backend.getQuotaLimits(owner)
370
- : null;
367
+ let userLimits = null;
368
+ if (backend.getQuotaLimits) {
369
+ userLimits = await backend.getQuotaLimits(owner);
370
+ }
371
371
  const effectiveLimits = userLimits ?? quotas;
372
372
  // Body is raw binary (EncryptedContainer)
373
373
  const data = arrayBufferLikeToBuffer(postData);
@@ -380,13 +380,13 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
380
380
  }));
381
381
  }
382
382
  const needsValidation = requiresValidation(objectPath, validators);
383
- const needsContainerValidation = !!policy.validateContainer;
383
+ const needsContextValidation = !!policy.validateContext;
384
384
  const needsAnchorDecryption = needsValidation || visibility === 'public';
385
- if (needsContainerValidation || needsAnchorDecryption) {
385
+ if (needsContextValidation || needsAnchorDecryption) {
386
386
  try {
387
387
  const container = EncryptedContainer.fromEncryptedBuffer(data, [anchorAccount]);
388
- if (policy.validateContainer) {
389
- policy.validateContainer(parsed, container, { owner, tags, visibility });
388
+ if (policy.validateContext) {
389
+ policy.validateContext(parsed, { operation: 'put', account, metadata: { owner, tags, visibility }, container });
390
390
  }
391
391
  if (needsAnchorDecryption) {
392
392
  const plaintext = await container.getPlaintext();
@@ -458,9 +458,12 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
458
458
  };
459
459
  // GET /api/object/* - Retrieve an object
460
460
  routes['GET /api/object/**'] = async function (params, _postData, _headers, url) {
461
- const { objectPath } = await authorizeURLAccess(pathPolicies, params, url, 'get', getKeetaStorageAnchorGetRequestSigningData, function (path, pubKey) {
461
+ const { objectPath, policy, parsed, account } = await authorizeURLAccess(pathPolicies, params, url, 'get', getKeetaStorageAnchorGetRequestSigningData, function (path, pubKey) {
462
462
  return (assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));
463
463
  });
464
+ if (policy.validateContext) {
465
+ policy.validateContext(parsed, { operation: 'get', account });
466
+ }
464
467
  const headers = {};
465
468
  if (authenticatedCorsOrigin) {
466
469
  headers['Access-Control-Allow-Origin'] = authenticatedCorsOrigin;
@@ -474,9 +477,12 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
474
477
  };
475
478
  // DELETE /api/object/* - Delete an object
476
479
  routes['DELETE /api/object/**'] = async function (params, _postData, _headers, url) {
477
- const { objectPath } = await authorizeURLAccess(pathPolicies, params, url, 'delete', getKeetaStorageAnchorDeleteRequestSigningData, function (path, pubKey) {
480
+ const { objectPath, policy, parsed, account } = await authorizeURLAccess(pathPolicies, params, url, 'delete', getKeetaStorageAnchorDeleteRequestSigningData, function (path, pubKey) {
478
481
  return ({ path, account: pubKey });
479
482
  });
483
+ if (policy.validateContext) {
484
+ policy.validateContext(parsed, { operation: 'delete', account });
485
+ }
480
486
  const deleted = await backend.delete(objectPath);
481
487
  const response = {
482
488
  ok: true,
@@ -486,9 +492,12 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
486
492
  };
487
493
  // GET /api/metadata/* - Get object metadata
488
494
  routes['GET /api/metadata/**'] = async function (params, _postData, _headers, url) {
489
- const { objectPath } = await authorizeURLAccess(pathPolicies, params, url, 'metadata', getKeetaStorageAnchorGetRequestSigningData, function (path, pubKey) {
495
+ const { objectPath, policy, parsed, account } = await authorizeURLAccess(pathPolicies, params, url, 'metadata', getKeetaStorageAnchorGetRequestSigningData, function (path, pubKey) {
490
496
  return (assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));
491
497
  });
498
+ if (policy.validateContext) {
499
+ policy.validateContext(parsed, { operation: 'metadata', account });
500
+ }
492
501
  const result = await requireObject(objectPath);
493
502
  return (jsonResponse({ ok: true, object: result.metadata }, assertKeetaStorageAnchorPutResponse));
494
503
  };
@@ -508,8 +517,8 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
508
517
  const tags = request.tags;
509
518
  // Confirm object exists and preserve existing owner
510
519
  const existing = await requireObject(objectPath);
511
- if (policy.validateMetadata) {
512
- policy.validateMetadata(parsed, { owner: existing.metadata.owner, tags, visibility });
520
+ if (policy.validateContext) {
521
+ policy.validateContext(parsed, { operation: 'updateMetadata', account, metadata: { owner: existing.metadata.owner, tags, visibility }, current: existing.metadata });
513
522
  }
514
523
  if (!backend.updateMetadata) {
515
524
  throw (new Errors.OperationNotSupported('updateMetadata'));
@@ -552,9 +561,10 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
552
561
  const account = await verifyURLAuth(url, getKeetaStorageAnchorQuotaRequestSigningData, function () { return ({}); });
553
562
  // Get current usage from backend and compute remaining using per-user or global limits
554
563
  const owner = account.publicKeyString.get();
555
- const userLimits = backend.getQuotaLimits
556
- ? await backend.getQuotaLimits(owner)
557
- : null;
564
+ let userLimits = null;
565
+ if (backend.getQuotaLimits) {
566
+ userLimits = await backend.getQuotaLimits(owner);
567
+ }
558
568
  const effectiveLimits = userLimits ?? quotas;
559
569
  const backendStatus = await backend.getQuotaStatus(owner);
560
570
  // Compute remaining from config limits
@@ -631,6 +641,9 @@ export class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.Keeta
631
641
  }
632
642
  throw (new Errors.SignatureInvalid('Signature verification failed'));
633
643
  }
644
+ if (policy.validateContext) {
645
+ policy.validateContext(parsed, { operation: 'get', account: signerAccount });
646
+ }
634
647
  const result = await requireObject(objectPath);
635
648
  if (result.metadata.visibility !== 'public') {
636
649
  throw (new Errors.AccessDenied('Object is not public'));
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/storage/server.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceMetadata } from '../../lib/resolver.ts';\nimport type { Signable } from '../../lib/utils/signing.js';\nimport type { NamespaceValidator } from './lib/validators.js';\nimport * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport type {\n\tKeetaStorageAnchorDeleteResponse,\n\tKeetaStorageAnchorPutResponse,\n\tKeetaStorageAnchorSearchResponse,\n\tKeetaStorageAnchorQuotaResponse,\n\tFullStorageBackend,\n\tQuotaConfig,\n\tStorageObjectVisibility,\n\tStorageObjectMetadata,\n\tPathPolicy,\n\tSearchResults,\n\tStorageGetResult,\n\tSearchPagination\n} from './common.ts';\nimport {\n\tassertKeetaStorageAnchorDeleteResponse,\n\tassertKeetaStorageAnchorPutResponse,\n\tassertKeetaStorageAnchorGetRequest,\n\tassertKeetaStorageAnchorSearchRequest,\n\tassertKeetaStorageAnchorSearchResponse,\n\tassertKeetaStorageAnchorQuotaResponse,\n\tassertKeetaStorageAnchorUpdateMetadataRequest\n} from './common.generated.js';\nimport {\n\tgetKeetaStorageAnchorDeleteRequestSigningData,\n\tgetKeetaStorageAnchorPutRequestSigningData,\n\tgetKeetaStorageAnchorGetRequestSigningData,\n\tgetKeetaStorageAnchorSearchRequestSigningData,\n\tgetKeetaStorageAnchorQuotaRequestSigningData,\n\tgetKeetaStorageAnchorUpdateMetadataRequestSigningData,\n\tparseContainerPayload,\n\tErrors,\n\tCONTENT_TYPE_OCTET_STREAM,\n\tDEFAULT_SIGNED_URL_TTL_SECONDS\n} from './common.js';\nimport { VerifySignedData } from '../../lib/utils/signing.js';\nimport { assertHTTPSignedField, parseSignatureFromURL } from '../../lib/http-server/common.js';\nimport { arrayBufferLikeToBuffer, Buffer } from '../../lib/utils/buffer.js';\nimport { requiresValidation, findMatchingValidators } from './lib/validators.js';\nimport { EncryptedContainer, EncryptedContainerError } from '../../lib/encrypted-container.js';\nimport { assertVisibility } from './utils.js';\n\ntype Account = InstanceType<typeof KeetaNet.lib.Account>;\n\n/**\n * Build a standardized search response from search results.\n */\nfunction buildSearchResponse(results: SearchResults): KeetaStorageAnchorSearchResponse {\n\tconst response: KeetaStorageAnchorSearchResponse = {\n\t\tok: true,\n\t\tresults: results.results\n\t};\n\tif (results.nextCursor !== undefined) {\n\t\tresponse.nextCursor = results.nextCursor;\n\t}\n\treturn(response);\n}\n\n// #region Module-Level Helpers\n\n/**\n * Find a matching policy for a path, validate it, and check access.\n *\n * @param pathPolicies - Array of path policies to check against\n * @param account - The account to check access for\n * @param path - The path to check\n * @param operation - The operation being performed\n */\nfunction assertPathAccess(\n\tpathPolicies: PathPolicy<unknown>[],\n\taccount: Account,\n\tpath: string,\n\toperation: 'get' | 'put' | 'delete' | 'search' | 'metadata' | 'updateMetadata'\n): { policy: PathPolicy<unknown>; parsed: unknown } {\n\tfor (const policy of pathPolicies) {\n\t\tconst parsed = policy.parse(path);\n\t\tif (parsed !== null) {\n\t\t\tpolicy.validate(path);\n\n\t\t\tif (!policy.checkAccess(account, parsed, operation)) {\n\t\t\t\tthrow(new Errors.AccessDenied('Can only access your own namespace'));\n\t\t\t}\n\n\t\t\treturn({ policy, parsed });\n\t\t}\n\t}\n\n\tthrow(new Errors.InvalidPath('Path does not match any policy'));\n}\n\n/**\n * Find a matching policy and parse a path.\n * Used for public endpoints where auth is optional.\n *\n * @param pathPolicies - Array of path policies to check against\n * @param path - The path to parse\n */\nfunction parsePath(\n\tpathPolicies: PathPolicy<unknown>[],\n\tpath: string\n): { policy: PathPolicy<unknown>; parsed: unknown } {\n\tfor (const policy of pathPolicies) {\n\t\tconst parsed = policy.parse(path);\n\t\tif (parsed !== null) {\n\t\t\tpolicy.validate(path);\n\t\t\treturn({ policy, parsed });\n\t\t}\n\t}\n\n\tthrow(new Errors.InvalidPath('Path does not match any policy'));\n}\n\n/**\n * Verify a signed request from POST body.\n * Extracts account and signature from the request, verifies the signature,\n * and returns the authenticated account.\n *\n * @typeParam T - Request type containing optional account and signed fields\n *\n * @param request - The request object containing account and signed fields\n * @param getSigningData - Function to extract signable data from the request\n *\n * @returns The authenticated account\n *\n * @throws KeetaAnchorUserError if authentication is missing or invalid\n */\nasync function verifyBodyAuth<T extends { account?: string; signed?: unknown }>(\n\trequest: T,\n\tgetSigningData: (req: T) => Signable\n): Promise<Account> {\n\tif (!request.account || !request.signed) {\n\t\tthrow(new KeetaAnchorUserError('Authentication required'));\n\t}\n\n\tconst account = KeetaNet.lib.Account.fromPublicKeyString(request.account).assertAccount();\n\tconst signable = getSigningData(request);\n\tconst signed = assertHTTPSignedField(request.signed);\n\n\tconst valid = await VerifySignedData(account, signable, signed);\n\tif (!valid) {\n\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t}\n\n\treturn(account);\n}\n\n/**\n * Verify a signed request from URL query parameters.\n * Parses signature from URL, builds a request object, verifies the signature,\n * and returns the authenticated account.\n *\n * @typeParam T - Request type to build from the account public key\n *\n * @param url - The URL containing signature query parameters\n * @param getSigningData - Function to extract signable data from the request\n * @param buildRequest - Function to build a request object from the account public key\n *\n * @returns The authenticated account\n *\n * @throws KeetaAnchorUserError if authentication is missing or invalid\n */\nasync function verifyURLAuth<T>(\n\turl: URL | string,\n\tgetSigningData: (req: T) => Signable,\n\tbuildRequest: (accountPubKey: string) => T\n): Promise<Account> {\n\tlet urlString: string;\n\tif (typeof url === 'string') {\n\t\turlString = url;\n\t} else {\n\t\turlString = url.href;\n\t}\n\n\tconst parsed = parseSignatureFromURL(urlString);\n\tif (!parsed.account || !parsed.signedField) {\n\t\tthrow(new KeetaAnchorUserError('Authentication required'));\n\t}\n\n\tconst request = buildRequest(parsed.account.publicKeyString.get());\n\tconst signable = getSigningData(request);\n\n\tconst valid = await VerifySignedData(parsed.account, signable, parsed.signedField);\n\tif (!valid) {\n\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t}\n\n\treturn(parsed.account);\n}\n\n/**\n * Extract object path from wildcard route parameter.\n * Prepends a leading slash to create a valid storage path.\n *\n * @param params - Route parameters containing the wildcard match\n *\n * @returns The object path with leading slash\n *\n * @throws InvalidPath if wildcard parameter is missing\n */\nfunction extractObjectPath(params: Map<string, string>): string {\n\tconst wildcardPath = params.get('**');\n\tif (!wildcardPath) {\n\t\tthrow(new Errors.InvalidPath());\n\t}\n\n\treturn('/' + wildcardPath);\n}\n\n/**\n * Authorize access to an object path via URL-signed request.\n * Combines path validation, signature verification, and access control.\n *\n * @typeParam T - Request type to build from path and account\n *\n * @param pathPolicies - Array of path policies to check against\n * @param params - Route parameters containing the wildcard path\n * @param url - The URL containing signature query parameters\n * @param operation - The operation being authorized\n * @param getSigningData - Function to extract signable data from the request\n * @param buildRequest - Function to build a request object from path and account\n *\n * @returns The authenticated account and validated object path\n *\n * @throws InvalidPath if path is invalid or doesn't match any policy\n * @throws AccessDenied if user doesn't have access to the path\n * @throws KeetaAnchorUserError if signature is invalid\n */\nasync function authorizeURLAccess<T>(\n\tpathPolicies: PathPolicy<unknown>[],\n\tparams: Map<string, string>,\n\turl: URL | string,\n\toperation: 'get' | 'put' | 'delete' | 'metadata',\n\tgetSigningData: (req: T) => Signable,\n\tbuildRequest: (path: string, accountPubKey: string) => T\n): Promise<{ account: Account; objectPath: string }> {\n\tconst objectPath = extractObjectPath(params);\n\tparsePath(pathPolicies, objectPath);\n\n\tconst account = await verifyURLAuth(url, getSigningData, function(pubKey) {\n\t\treturn(buildRequest(objectPath, pubKey));\n\t});\n\n\tassertPathAccess(pathPolicies, account, objectPath, operation);\n\n\treturn({ account, objectPath });\n}\n\n// #endregion\n\n/**\n * Configuration for the Storage Anchor\n *\n * The Storage Anchor provides encrypted object storage with the following operations:\n *\n * PUT (Create/Update):\n * 1. Client creates EncryptedContainer with data, shares with anchor for public objects\n * 2. Client signs request (path, visibility, tags) and sends to server\n * 3. Server reserves quota, validates, stores object, commits reservation\n *\n * GET (Retrieve):\n * 1. Client signs request (path) and sends to server\n * 2. Server verifies access, returns EncryptedContainer\n * 3. Client decrypts with their private key\n *\n * DELETE:\n * 1. Client signs request (path) and sends to server\n * 2. Server verifies ownership, removes object\n *\n * SEARCH:\n * 1. Client signs request with criteria (tags, prefix, etc.)\n * 2. Server returns matching metadata (scoped to user's namespace)\n *\n * PUBLIC ACCESS (Pre-signed URLs):\n * 1. Client generates pre-signed URL with expiry, signed by owner\n * 2. Anyone can fetch via URL (no auth headers)\n * 3. Server verifies signature, expiry, and visibility\n * 4. Server decrypts and returns plaintext content\n *\n *\n * +-------------------+ +---------------------+ +------------------+\n * | Client | | Storage Anchor | | Storage Backend |\n * +-------------------+ +---------------------+ +------------------+\n * | | |\n * (PUT) Create EncryptedContainer | |\n * | Sign(path, visibility, tags) | |\n * |---------------------------------->| |\n * | | reserveUpload() ---------------->|\n * | | validate, put() ---------------->|\n * | | commitUpload() ----------------->|\n * |<--------------------------------- | { ok: true, object: metadata } |\n * | | |\n * (GET) Sign(path) ------------------------>| |\n * | | get() -------------------------->|\n * |<--------------------------------- | EncryptedContainer (binary) |\n * | Decrypt with private key | |\n * | | |\n * (PUBLIC) Generate pre-signed URL | |\n * | URL with expires, signature | |\n * (Anyone) Fetch URL ---------------------->| |\n * | | verify signature, expiry |\n * | | get(), decrypt ----------------->|\n * |<--------------------------------- | Plaintext content |\n */\nexport interface KeetaAnchorStorageServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {\n\t/**\n\t * The data to use for the index page (optional)\n\t */\n\thomepage?: string | (() => Promise<string> | string);\n\n\t/**\n\t * The storage backend to use for storing documents.\n\t * Must implement full capabilities: CRUD, search, and quota management.\n\t */\n\tbackend: FullStorageBackend;\n\n\t/**\n\t * The anchor's account for decrypting objects.\n\t */\n\tanchorAccount: Account;\n\n\t/**\n\t * Quota configuration for storage limits.\n\t * Partial values are merged with defaults.\n\t */\n\tquotas?: Partial<QuotaConfig>;\n\n\t/**\n\t * Namespace validators for special paths\n\t */\n\tvalidators?: NamespaceValidator[];\n\n\t/**\n\t * Default TTL in seconds for pre-signed URLs (default: 3600)\n\t */\n\tsignedUrlDefaultTTL?: number;\n\n\t/**\n\t * CORS origin for public endpoints (default: false).\n\t * - '*' allows all origins\n\t * - specific origin string restricts to that origin\n\t * - false (default) disables CORS headers on public responses\n\t */\n\tpublicCORSOrigin?: string | false;\n\n\t/**\n\t * CORS origin for authenticated object endpoints (default: '*').\n\t * - '*' allows all origins\n\t * - specific origin string restricts to that origin\n\t */\n\tauthenticatedCORSOrigin?: string;\n\n\t/**\n\t * Path policies for parsing, validating, and access control of storage paths.\n\t * Each policy handles a specific path pattern. First matching policy wins.\n\t */\n\tpathPolicies: PathPolicy<unknown>[];\n\n\t/**\n\t * Tag validation configuration.\n\t */\n\ttagValidation?: {\n\t\t/** Maximum number of tags per object (default: 10) */\n\t\tmaxTags?: number;\n\t\t/** Maximum length of each tag (default: 50) */\n\t\tmaxTagLength?: number;\n\t\t/** Pattern for valid tag characters (default: /^[a-zA-Z0-9_-]+$/) */\n\t\tpattern?: RegExp;\n\t};\n}\n\n// Default quota configuration\nconst DEFAULT_QUOTAS: QuotaConfig = {\n\tmaxObjectSize: 10 * 1024 * 1024, // 10MB\n\tmaxObjectsPerUser: 1000,\n\tmaxStoragePerUser: 100 * 1024 * 1024, // 100MB\n\tmaxSearchLimit: 100,\n\tmaxSignedUrlTTL: 86400 // 24 hours\n};\n\n// Default tag validation configuration\nconst DEFAULT_TAG_VALIDATION = {\n\tmaxTags: 10,\n\tmaxTagLength: 50,\n\tpattern: /^[a-zA-Z0-9_-]+$/\n};\n\nexport class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorStorageServerConfig> {\n\treadonly homepage: NonNullable<KeetaAnchorStorageServerConfig['homepage']>;\n\treadonly backend: FullStorageBackend;\n\treadonly anchorAccount: Account;\n\treadonly quotas: QuotaConfig;\n\treadonly validators: NamespaceValidator[];\n\treadonly signedUrlDefaultTTL: number;\n\treadonly publicCorsOrigin: string | false;\n\treadonly authenticatedCorsOrigin: string;\n\treadonly pathPolicies: PathPolicy<unknown>[];\n\treadonly tagValidation: Required<NonNullable<KeetaAnchorStorageServerConfig['tagValidation']>>;\n\n\tconstructor(config: KeetaAnchorStorageServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.backend = config.backend;\n\t\tthis.anchorAccount = config.anchorAccount;\n\t\tthis.quotas = { ...DEFAULT_QUOTAS, ...config.quotas };\n\t\tthis.validators = config.validators ?? [];\n\t\tthis.signedUrlDefaultTTL = config.signedUrlDefaultTTL ?? DEFAULT_SIGNED_URL_TTL_SECONDS;\n\t\tthis.publicCorsOrigin = config.publicCORSOrigin ?? false;\n\t\tthis.authenticatedCorsOrigin = config.authenticatedCORSOrigin ?? '*';\n\t\tthis.pathPolicies = config.pathPolicies;\n\t\tthis.tagValidation = {\n\t\t\tmaxTags: config.tagValidation?.maxTags ?? DEFAULT_TAG_VALIDATION.maxTags,\n\t\t\tmaxTagLength: config.tagValidation?.maxTagLength ?? DEFAULT_TAG_VALIDATION.maxTagLength,\n\t\t\tpattern: config.tagValidation?.pattern ?? DEFAULT_TAG_VALIDATION.pattern\n\t\t};\n\n\t\t// Validate anchorAccount has private key\n\t\tif (!this.anchorAccount.hasPrivateKey) {\n\t\t\tthrow(new Error('anchorAccount must have a private key'));\n\t\t}\n\n\t\t// Validate at least one path policy is provided\n\t\tif (this.pathPolicies.length === 0) {\n\t\t\tthrow(new Error('At least one path policy must be provided'));\n\t\t}\n\n\t\t// Validate quota configuration values are positive\n\t\tif (this.quotas.maxObjectSize <= 0) {\n\t\t\tthrow(new Error('quotas.maxObjectSize must be positive'));\n\t\t}\n\t\tif (this.quotas.maxObjectsPerUser <= 0) {\n\t\t\tthrow(new Error('quotas.maxObjectsPerUser must be positive'));\n\t\t}\n\t\tif (this.quotas.maxStoragePerUser <= 0) {\n\t\t\tthrow(new Error('quotas.maxStoragePerUser must be positive'));\n\t\t}\n\t\tif (this.quotas.maxSearchLimit <= 0) {\n\t\t\tthrow(new Error('quotas.maxSearchLimit must be positive'));\n\t\t}\n\t\tif (this.quotas.maxSignedUrlTTL <= 0) {\n\t\t\tthrow(new Error('quotas.maxSignedUrlTTL must be positive'));\n\t\t}\n\n\t\t// Validate tag validation configuration\n\t\tif (this.tagValidation.maxTags <= 0) {\n\t\t\tthrow(new Error('tagValidation.maxTags must be positive'));\n\t\t}\n\t\tif (this.tagValidation.maxTagLength <= 0) {\n\t\t\tthrow(new Error('tagValidation.maxTagLength must be positive'));\n\t\t}\n\t}\n\n\t// Note: We use this.* properties instead of config.*.\n\t// The config parameter is required by the abstract method signature but unused here.\n\tprotected async initRoutes(_ignoreConfig: KeetaAnchorStorageServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\n\t\tconst backend = this.backend;\n\t\tconst anchorAccount = this.anchorAccount;\n\t\tconst quotas = this.quotas;\n\t\tconst validators = this.validators;\n\t\tconst publicCorsOrigin = this.publicCorsOrigin;\n\t\tconst authenticatedCorsOrigin = this.authenticatedCorsOrigin;\n\t\tconst pathPolicies = this.pathPolicies;\n\t\tconst tagValidation = this.tagValidation;\n\t\tconst logger = this.logger;\n\n\t\t/**\n\t\t * Validate tags against configured limits.\n\t\t * @throws Errors.InvalidTag if any tag violates constraints\n\t\t */\n\t\tfunction validateTags(tags: string[]): void {\n\t\t\tconst { maxTags, maxTagLength, pattern: tagPattern } = tagValidation;\n\t\t\tfor (const tag of tags) {\n\t\t\t\tif (tag.length > maxTagLength) {\n\t\t\t\t\tthrow(new Errors.InvalidTag(`Tag exceeds maximum length of ${maxTagLength}: \"${tag}\"`));\n\t\t\t\t}\n\t\t\t\ttagPattern.lastIndex = 0;\n\t\t\t\tif (!tagPattern.test(tag)) {\n\t\t\t\t\tthrow(new Errors.InvalidTag(`Tag contains invalid characters: \"${tag}\"`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (tags.length > maxTags) {\n\t\t\t\tthrow(new Errors.InvalidTag(`Too many tags: ${tags.length} exceeds maximum of ${maxTags}`));\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Build a JSON response with assertion.\n\t\t */\n\t\tfunction jsonResponse<T>(response: T, assertionHandler: (input: unknown) => T): { output: string } {\n\t\t\treturn({ output: JSON.stringify(assertionHandler(response)) });\n\t\t}\n\n\t\t/**\n\t\t * Get an object or throw DocumentNotFound.\n\t\t */\n\t\tasync function requireObject(path: string): Promise<StorageGetResult> {\n\t\t\tconst result = await backend.get(path);\n\t\t\tif (!result) {\n\t\t\t\tthrow(new Errors.DocumentNotFound());\n\t\t\t}\n\n\t\t\treturn(result);\n\t\t}\n\n\t\t/**\n\t\t * Enforce server-side search limit cap.\n\t\t */\n\t\tfunction enforceSearchLimit(pagination: SearchPagination | undefined): SearchPagination {\n\t\t\tconst requestedLimit = pagination?.limit ?? quotas.maxSearchLimit;\n\t\t\treturn({ ...pagination, limit: Math.min(requestedLimit, quotas.maxSearchLimit) });\n\t\t}\n\n\t\t/**\n\t\t * Validate search results match expected constraints.\n\t\t */\n\t\tfunction assertSearchResults(\n\t\t\tresults: SearchResults,\n\t\t\tconstraint: { visibility?: 'public'; owner?: string }\n\t\t): void {\n\t\t\tfor (const obj of results.results) {\n\t\t\t\tif (constraint.visibility && obj.visibility !== constraint.visibility) {\n\t\t\t\t\tthrow(new Errors.InvariantViolation(\n\t\t\t\t\t\t`Backend returned ${obj.visibility} object in ${constraint.visibility} search`\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t\tif (constraint.owner && obj.owner !== constraint.owner) {\n\t\t\t\t\tthrow(new Errors.InvariantViolation(\n\t\t\t\t\t\t`Backend returned object owned by ${obj.owner} in search for ${constraint.owner}`\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * If a homepage is provided, setup the route for it\n\t\t */\n\t\tconst homepage = this.homepage;\n\t\tif (homepage) {\n\t\t\troutes['GET /'] = async function() {\n\t\t\t\tlet homepageData: string;\n\t\t\t\tif (typeof homepage === 'string') {\n\t\t\t\t\thomepageData = homepage;\n\t\t\t\t} else {\n\t\t\t\t\thomepageData = await homepage();\n\t\t\t\t}\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: homepageData,\n\t\t\t\t\tcontentType: 'text/html'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t// #region API Routes\n\n\t\t// PUT /api/object/* - Create or update an object\n\t\troutes['PUT /api/object/**'] = {\n\t\t\tbodyType: 'raw',\n\t\t\tmaxBodySize: quotas.maxObjectSize,\n\t\t\thandler: async function(params, postData, _headers, url) {\n\t\t\t\tconst objectPath = extractObjectPath(params);\n\n\t\t\t\t// Get metadata from query params\n\t\t\t\tconst parsedUrl = new URL(url);\n\t\t\t\tconst visibilityParam = parsedUrl.searchParams.get('visibility');\n\t\t\t\tconst tagsParam = parsedUrl.searchParams.get('tags');\n\n\t\t\t\t// Default to private when absent, assert valid value otherwise\n\t\t\t\tlet visibility: StorageObjectVisibility = 'private';\n\t\t\t\tif (visibilityParam !== null) {\n\t\t\t\t\tvisibility = assertVisibility(visibilityParam);\n\t\t\t\t}\n\n\t\t\t\tconst rawTags: string[] = (tagsParam ?? '')\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map(function(t) {\n\t\t\t\t\t\treturn(t.trim());\n\t\t\t\t\t})\n\t\t\t\t\t.filter(function(t) {\n\t\t\t\t\t\treturn(t.length > 0);\n\t\t\t\t\t});\n\n\t\t\t\t// Verify signature\n\t\t\t\tconst account = await verifyURLAuth(url, getKeetaStorageAnchorPutRequestSigningData, function() {\n\t\t\t\t\treturn({ path: objectPath, visibility, tags: rawTags });\n\t\t\t\t});\n\n\t\t\t\tvalidateTags(rawTags);\n\t\t\t\tconst tags = rawTags;\n\n\t\t\t\t// Validate path format, metadata, and ownership\n\t\t\t\tconst { policy, parsed } = assertPathAccess(pathPolicies, account, objectPath, 'put');\n\t\t\t\tconst owner = account.publicKeyString.get();\n\t\t\t\tif (policy.validateMetadata) {\n\t\t\t\t\tpolicy.validateMetadata(parsed, { owner, tags, visibility });\n\t\t\t\t}\n\n\t\t\t\t// Resolve per-user quota limits, falling back to global config\n\t\t\t\tconst userLimits = backend.getQuotaLimits\n\t\t\t\t\t? await backend.getQuotaLimits(owner)\n\t\t\t\t\t: null;\n\t\t\t\tconst effectiveLimits = userLimits ?? quotas;\n\n\t\t\t\t// Body is raw binary (EncryptedContainer)\n\t\t\t\tconst data = arrayBufferLikeToBuffer(postData);\n\t\t\t\tconst objectSize = data.byteLength;\n\t\t\t\tif (objectSize > effectiveLimits.maxObjectSize) {\n\t\t\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\t\t\tquotaType: 'maxObjectSize',\n\t\t\t\t\t\tlimit: effectiveLimits.maxObjectSize,\n\t\t\t\t\t\tcurrent: objectSize\n\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\tconst needsValidation = requiresValidation(objectPath, validators);\n\t\t\t\tconst needsContainerValidation = !!policy.validateContainer;\n\t\t\t\tconst needsAnchorDecryption = needsValidation || visibility === 'public';\n\t\t\t\tif (needsContainerValidation || needsAnchorDecryption) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst container = EncryptedContainer.fromEncryptedBuffer(data, [anchorAccount]);\n\n\t\t\t\t\t\tif (policy.validateContainer) {\n\t\t\t\t\t\t\tpolicy.validateContainer(parsed, container, { owner, tags, visibility });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (needsAnchorDecryption) {\n\t\t\t\t\t\t\tconst plaintext = await container.getPlaintext();\n\t\t\t\t\t\t\tif (needsValidation) {\n\t\t\t\t\t\t\t\t// Extract content and mimeType from encrypted payload\n\t\t\t\t\t\t\t\tconst { content, mimeType } = parseContainerPayload(plaintext);\n\t\t\t\t\t\t\t\tconst matchingValidators = findMatchingValidators(objectPath, validators);\n\t\t\t\t\t\t\t\tfor (const validator of matchingValidators) {\n\t\t\t\t\t\t\t\t\tconst result = await validator.validate(objectPath, content, mimeType);\n\t\t\t\t\t\t\t\t\tif (!result.valid) {\n\t\t\t\t\t\t\t\t\t\tthrow(new Errors.ValidationFailed(result.error));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (Errors.InvalidMetadata.isInstance(e)) {\n\t\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Errors.ValidationFailed.isInstance(e)) {\n\t\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (EncryptedContainerError.isInstance(e)) {\n\t\t\t\t\t\t\tif (e.code.startsWith('MALFORMED_')) {\n\t\t\t\t\t\t\t\tthrow(new Errors.ValidationFailed(`Invalid encrypted container: ${e.message}`));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.code === 'NO_MATCHING_KEY' || e.code === 'DECRYPTION_FAILED') {\n\t\t\t\t\t\t\t\tthrow(new Errors.AnchorPrincipalRequired());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reserve quota before upload\n\t\t\t\tconst reservation = await backend.reserveUpload(owner, objectPath, objectSize, {\n\t\t\t\t\tquotaLimits: {\n\t\t\t\t\t\tmaxObjectsPerUser: effectiveLimits.maxObjectsPerUser,\n\t\t\t\t\t\tmaxStoragePerUser: effectiveLimits.maxStoragePerUser\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tlet objectMetadata: StorageObjectMetadata;\n\t\t\t\ttry {\n\t\t\t\t\tobjectMetadata = await backend.put(objectPath, data, {\n\t\t\t\t\t\towner,\n\t\t\t\t\t\ttags,\n\t\t\t\t\t\tvisibility\n\t\t\t\t\t});\n\n\t\t\t\t\tawait backend.commitUpload(reservation.id);\n\t\t\t\t} catch (e) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait backend.releaseUpload(reservation.id);\n\t\t\t\t\t} catch (releaseError) {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This provides a hint for cleanup\n\t\t\t\t\t\t */\n\t\t\t\t\t\tlogger?.warn('Failed to release upload reservation', { reservationId: reservation.id, error: releaseError });\n\t\t\t\t\t}\n\t\t\t\t\tthrow(e);\n\t\t\t\t}\n\n\t\t\t\tconst response: KeetaStorageAnchorPutResponse = {\n\t\t\t\t\tok: true,\n\t\t\t\t\tobject: objectMetadata\n\t\t\t\t};\n\n\t\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorPutResponse));\n\t\t\t}\n\t\t};\n\n\t\t// GET /api/object/* - Retrieve an object\n\t\troutes['GET /api/object/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'get',\n\t\t\t\tgetKeetaStorageAnchorGetRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn(assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\tif (authenticatedCorsOrigin) {\n\t\t\t\theaders['Access-Control-Allow-Origin'] = authenticatedCorsOrigin;\n\t\t\t}\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\treturn({\n\t\t\t\theaders,\n\t\t\t\toutput: result.data,\n\t\t\t\tcontentType: CONTENT_TYPE_OCTET_STREAM\n\t\t\t});\n\t\t};\n\n\t\t// DELETE /api/object/* - Delete an object\n\t\troutes['DELETE /api/object/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'delete',\n\t\t\t\tgetKeetaStorageAnchorDeleteRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn({ path, account: pubKey });\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst deleted = await backend.delete(objectPath);\n\t\t\tconst response: KeetaStorageAnchorDeleteResponse = {\n\t\t\t\tok: true,\n\t\t\t\tdeleted\n\t\t\t};\n\n\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorDeleteResponse));\n\t\t};\n\n\t\t// GET /api/metadata/* - Get object metadata\n\t\troutes['GET /api/metadata/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'metadata',\n\t\t\t\tgetKeetaStorageAnchorGetRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn(assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\treturn(jsonResponse({ ok: true, object: result.metadata }, assertKeetaStorageAnchorPutResponse));\n\t\t};\n\n\t\t// PUT /api/metadata/* - Update object metadata without re-uploading data\n\t\troutes['PUT /api/metadata/**'] = async function(params, postData) {\n\t\t\tconst objectPath = extractObjectPath(params);\n\t\t\tconst request = assertKeetaStorageAnchorUpdateMetadataRequest(postData);\n\n\t\t\tconst signable = getKeetaStorageAnchorUpdateMetadataRequestSigningData({\n\t\t\t\tpath: objectPath,\n\t\t\t\tvisibility: request.visibility,\n\t\t\t\ttags: request.tags\n\t\t\t});\n\t\t\tconst account = await verifyBodyAuth(request, function() { return(signable); });\n\n\t\t\tconst { policy, parsed } = assertPathAccess(pathPolicies, account, objectPath, 'updateMetadata');\n\n\t\t\tvalidateTags(request.tags);\n\n\t\t\tconst visibility = assertVisibility(request.visibility);\n\t\t\tconst tags = request.tags;\n\n\t\t\t// Confirm object exists and preserve existing owner\n\t\t\tconst existing = await requireObject(objectPath);\n\t\t\tif (policy.validateMetadata) {\n\t\t\t\tpolicy.validateMetadata(parsed, { owner: existing.metadata.owner, tags, visibility });\n\t\t\t}\n\n\t\t\tif (!backend.updateMetadata) {\n\t\t\t\tthrow(new Errors.OperationNotSupported('updateMetadata'));\n\t\t\t}\n\n\t\t\tconst updated = await backend.updateMetadata(objectPath, { tags, visibility });\n\t\t\tif (!updated) {\n\t\t\t\tthrow(new Errors.DocumentNotFound());\n\t\t\t}\n\n\t\t\treturn(jsonResponse({ ok: true, object: updated }, assertKeetaStorageAnchorPutResponse));\n\t\t};\n\n\t\t// POST /api/search - Search for objects\n\t\troutes['POST /api/search'] = async function(_params, postData) {\n\t\t\tconst request = assertKeetaStorageAnchorSearchRequest(postData);\n\t\t\tconst account = await verifyBodyAuth(request, getKeetaStorageAnchorSearchRequestSigningData);\n\t\t\tconst accountPubKey = account.publicKeyString.get();\n\n\t\t\t// Check if searching for public objects outside namespace\n\t\t\tconst searchingPublic = request.criteria.visibility === 'public';\n\t\t\tif (searchingPublic) {\n\t\t\t\t// When searching for public objects, we allow searching outside the caller's namespace\n\t\t\t\t// but only for objects with visibility: 'public'\n\t\t\t\tconst scopedCriteria = {\n\t\t\t\t\t...request.criteria,\n\t\t\t\t\tvisibility: 'public' as const\n\t\t\t\t};\n\n\t\t\t\tconst results = await backend.search(\n\t\t\t\t\tscopedCriteria,\n\t\t\t\t\tenforceSearchLimit(request.pagination)\n\t\t\t\t);\n\n\t\t\t\tassertSearchResults(results, { visibility: 'public' });\n\n\t\t\t\treturn(jsonResponse(buildSearchResponse(results), assertKeetaStorageAnchorSearchResponse));\n\t\t\t}\n\n\t\t\t// Scope search to authenticated account's namespace\n\t\t\tconst scopedCriteria = {\n\t\t\t\t...request.criteria,\n\t\t\t\towner: accountPubKey\n\t\t\t};\n\n\t\t\tconst results = await backend.search(\n\t\t\t\tscopedCriteria,\n\t\t\t\tenforceSearchLimit(request.pagination)\n\t\t\t);\n\n\t\t\tassertSearchResults(results, { owner: accountPubKey });\n\n\t\t\treturn(jsonResponse(buildSearchResponse(results), assertKeetaStorageAnchorSearchResponse));\n\t\t};\n\n\t\t// GET /api/quota - Get quota status\n\t\troutes['GET /api/quota'] = async function(_params, _postData, _headers, url) {\n\t\t\tconst account = await verifyURLAuth(\n\t\t\t\turl,\n\t\t\t\tgetKeetaStorageAnchorQuotaRequestSigningData,\n\t\t\t\tfunction() { return({}); }\n\t\t\t);\n\n\t\t\t// Get current usage from backend and compute remaining using per-user or global limits\n\t\t\tconst owner = account.publicKeyString.get();\n\t\t\tconst userLimits = backend.getQuotaLimits\n\t\t\t\t? await backend.getQuotaLimits(owner)\n\t\t\t\t: null;\n\t\t\tconst effectiveLimits = userLimits ?? quotas;\n\n\t\t\tconst backendStatus = await backend.getQuotaStatus(owner);\n\n\t\t\t// Compute remaining from config limits\n\t\t\tlet remainingObjects = Math.max(0, effectiveLimits.maxObjectsPerUser - backendStatus.objectCount);\n\t\t\tlet remainingSize = Math.max(0, effectiveLimits.maxStoragePerUser - backendStatus.totalSize);\n\n\t\t\t// If backend reports its own remaining values, use the tighter constraint\n\t\t\tif (backendStatus.remainingObjects !== undefined && backendStatus.remainingObjects > 0) {\n\t\t\t\tremainingObjects = Math.min(backendStatus.remainingObjects, remainingObjects);\n\t\t\t}\n\t\t\tif (backendStatus.remainingSize !== undefined && backendStatus.remainingSize > 0) {\n\t\t\t\tremainingSize = Math.min(backendStatus.remainingSize, remainingSize);\n\t\t\t}\n\n\t\t\tconst response: KeetaStorageAnchorQuotaResponse = {\n\t\t\t\tok: true,\n\t\t\t\tquota: {\n\t\t\t\t\tobjectCount: backendStatus.objectCount,\n\t\t\t\t\ttotalSize: backendStatus.totalSize,\n\t\t\t\t\tremainingObjects,\n\t\t\t\t\tremainingSize\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorQuotaResponse));\n\t\t};\n\n\t\t// GET /api/public/** - Public object access via pre-signed URL\n\t\troutes['GET /api/public/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst objectPath = extractObjectPath(params);\n\t\t\tconst { policy, parsed } = parsePath(pathPolicies, objectPath);\n\n\t\t\t// Parse signature using standard signed field convention\n\t\t\tconst urlParsed = parseSignatureFromURL(url);\n\t\t\tif (!urlParsed.signedField) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing required signature parameters'));\n\t\t\t}\n\n\t\t\t// Resolve signer: policy-specified or from URL account param (any-signer for public objects)\n\t\t\tconst signerAccount = policy.getAuthorizedSigner(parsed) ?? urlParsed.account ?? null;\n\t\t\tif (!signerAccount) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing signer'));\n\t\t\t}\n\t\t\tconst signerPubKey = signerAccount.publicKeyString.get();\n\n\t\t\t// Parse and validate expires param\n\t\t\tconst parsedUrl = typeof url === 'string' ? new URL(url) : url;\n\t\t\tconst expiresParam = parsedUrl.searchParams.get('expires');\n\t\t\tif (!expiresParam) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing expires parameter'));\n\t\t\t}\n\t\t\tconst expiresAt = parseInt(expiresParam, 10);\n\t\t\tif (!Number.isFinite(expiresAt)) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Invalid expires parameter'));\n\t\t\t}\n\t\t\tif (Date.now() > expiresAt * 1000) {\n\t\t\t\tthrow(new Errors.SignatureExpired());\n\t\t\t}\n\n\t\t\t// Enforce maximum TTL\n\t\t\tconst maxExpiresAt = Math.floor(Date.now() / 1000) + quotas.maxSignedUrlTTL;\n\t\t\tif (expiresAt > maxExpiresAt) {\n\t\t\t\tthrow(new Errors.SignatureExpired('Signed URL TTL exceeds maximum allowed'));\n\t\t\t}\n\n\t\t\t// Pre-validate signature is valid base64 with reasonable length\n\t\t\tconst signatureBuffer = Buffer.from(urlParsed.signedField.signature, 'base64');\n\t\t\tif (signatureBuffer.length < 64 || signatureBuffer.length > 256) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Invalid signature format'));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Allow 5 minutes of clock skew for signature verification\n\t\t\t\tconst valid = await VerifySignedData(signerAccount, [objectPath, expiresAt, signerPubKey], urlParsed.signedField, {\n\t\t\t\t\tmaxSkewMs: 5 * 60 * 1000\n\t\t\t\t});\n\t\t\t\tif (!valid) {\n\t\t\t\t\tthrow(new Errors.SignatureInvalid());\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tif (Errors.SignatureInvalid.isInstance(e)) {\n\t\t\t\t\tthrow(e);\n\t\t\t\t}\n\n\t\t\t\tthrow(new Errors.SignatureInvalid('Signature verification failed'));\n\t\t\t}\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\tif (result.metadata.visibility !== 'public') {\n\t\t\t\tthrow(new Errors.AccessDenied('Object is not public'));\n\t\t\t}\n\n\t\t\t// Decrypt using anchor account and extract mimeType from encrypted payload\n\t\t\tconst data = arrayBufferLikeToBuffer(result.data);\n\t\t\tconst container = EncryptedContainer.fromEncryptedBuffer(data, [anchorAccount]);\n\t\t\tconst plaintext = await container.getPlaintext();\n\t\t\tconst { content, mimeType } = parseContainerPayload(plaintext);\n\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\tif (publicCorsOrigin) {\n\t\t\t\theaders['Access-Control-Allow-Origin'] = publicCorsOrigin;\n\t\t\t}\n\n\t\t\treturn({\n\t\t\t\toutput: content,\n\t\t\t\tcontentType: mimeType,\n\t\t\t\theaders\n\t\t\t});\n\t\t};\n\n\t\t// #endregion\n\n\t\treturn(routes);\n\t}\n\n\tasync serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['storage']>[string]> {\n\t\tconst authRequired = { options: { authentication: { type: 'required' as const, method: 'keeta-account' as const }}};\n\t\tconst operations: NonNullable<ServiceMetadata['services']['storage']>[string]['operations'] = {\n\t\t\tput: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tget: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tdelete: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tmetadata: { url: (new URL('/api/metadata', this.url)).toString(), ...authRequired },\n\t\t\tupdateMetadata: { url: (new URL('/api/metadata', this.url)).toString(), ...authRequired },\n\t\t\tsearch: { url: (new URL('/api/search', this.url)).toString(), ...authRequired },\n\t\t\tpublic: (new URL('/api/public', this.url)).toString(),\n\t\t\tquota: { url: (new URL('/api/quota', this.url)).toString(), ...authRequired }\n\t\t};\n\n\t\treturn({\n\t\t\toperations,\n\t\t\tanchorAccount: this.anchorAccount.publicKeyString.get(),\n\t\t\tquotas: this.quotas,\n\t\t\tsignedUrlDefaultTTL: this.signedUrlDefaultTTL,\n\t\t\tsearchableFields: ['owner', 'tags', 'visibility', 'pathPrefix']\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/services/storage/server.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServiceMetadata } from '../../lib/resolver.ts';\nimport type { Signable } from '../../lib/utils/signing.js';\nimport type { NamespaceValidator } from './lib/validators.js';\nimport * as KeetaAnchorHTTPServer from '../../lib/http-server/index.js';\nimport { KeetaNet } from '../../client/index.js';\nimport {\n\tKeetaAnchorUserError\n} from '../../lib/error.js';\nimport type {\n\tKeetaStorageAnchorDeleteResponse,\n\tKeetaStorageAnchorPutResponse,\n\tKeetaStorageAnchorSearchResponse,\n\tKeetaStorageAnchorQuotaResponse,\n\tFullStorageBackend,\n\tQuotaConfig,\n\tQuotaLimits,\n\tStorageOperation,\n\tStorageObjectVisibility,\n\tStorageObjectMetadata,\n\tPathPolicy,\n\tSearchResults,\n\tStorageGetResult,\n\tSearchPagination\n} from './common.ts';\nimport {\n\tassertKeetaStorageAnchorDeleteResponse,\n\tassertKeetaStorageAnchorPutResponse,\n\tassertKeetaStorageAnchorGetRequest,\n\tassertKeetaStorageAnchorSearchRequest,\n\tassertKeetaStorageAnchorSearchResponse,\n\tassertKeetaStorageAnchorQuotaResponse,\n\tassertKeetaStorageAnchorUpdateMetadataRequest\n} from './common.generated.js';\nimport {\n\tgetKeetaStorageAnchorDeleteRequestSigningData,\n\tgetKeetaStorageAnchorPutRequestSigningData,\n\tgetKeetaStorageAnchorGetRequestSigningData,\n\tgetKeetaStorageAnchorSearchRequestSigningData,\n\tgetKeetaStorageAnchorQuotaRequestSigningData,\n\tgetKeetaStorageAnchorUpdateMetadataRequestSigningData,\n\tparseContainerPayload,\n\tErrors,\n\tCONTENT_TYPE_OCTET_STREAM,\n\tDEFAULT_SIGNED_URL_TTL_SECONDS\n} from './common.js';\nimport { VerifySignedData } from '../../lib/utils/signing.js';\nimport { assertHTTPSignedField, parseSignatureFromURL } from '../../lib/http-server/common.js';\nimport { arrayBufferLikeToBuffer, Buffer } from '../../lib/utils/buffer.js';\nimport { requiresValidation, findMatchingValidators } from './lib/validators.js';\nimport { EncryptedContainer, EncryptedContainerError } from '../../lib/encrypted-container.js';\nimport { assertVisibility } from './utils.js';\n\ntype Account = InstanceType<typeof KeetaNet.lib.Account>;\n\n/**\n * Build a standardized search response from search results.\n */\nfunction buildSearchResponse(results: SearchResults): KeetaStorageAnchorSearchResponse {\n\tconst response: KeetaStorageAnchorSearchResponse = {\n\t\tok: true,\n\t\tresults: results.results\n\t};\n\tif (results.nextCursor !== undefined) {\n\t\tresponse.nextCursor = results.nextCursor;\n\t}\n\treturn(response);\n}\n\n// #region Module-Level Helpers\n\n/**\n * Find a matching policy for a path, validate it, and check access.\n *\n * @param pathPolicies - Array of path policies to check against\n * @param account - The account to check access for\n * @param path - The path to check\n * @param operation - The operation being performed\n */\nfunction assertPathAccess(\n\tpathPolicies: PathPolicy<unknown>[],\n\taccount: Account,\n\tpath: string,\n\toperation: StorageOperation\n): { policy: PathPolicy<unknown>; parsed: unknown } {\n\tfor (const policy of pathPolicies) {\n\t\tconst parsed = policy.parse(path);\n\t\tif (parsed !== null) {\n\t\t\tpolicy.validate(path);\n\n\t\t\tif (!policy.checkAccess(account, parsed, operation)) {\n\t\t\t\tthrow(new Errors.AccessDenied('Can only access your own namespace'));\n\t\t\t}\n\n\t\t\treturn({ policy, parsed });\n\t\t}\n\t}\n\n\tthrow(new Errors.InvalidPath('Path does not match any policy'));\n}\n\n/**\n * Find a matching policy and parse a path.\n * Used for public endpoints where auth is optional.\n *\n * @param pathPolicies - Array of path policies to check against\n * @param path - The path to parse\n */\nfunction parsePath(\n\tpathPolicies: PathPolicy<unknown>[],\n\tpath: string\n): { policy: PathPolicy<unknown>; parsed: unknown } {\n\tfor (const policy of pathPolicies) {\n\t\tconst parsed = policy.parse(path);\n\t\tif (parsed !== null) {\n\t\t\tpolicy.validate(path);\n\t\t\treturn({ policy, parsed });\n\t\t}\n\t}\n\n\tthrow(new Errors.InvalidPath('Path does not match any policy'));\n}\n\n/**\n * Verify a signed request from POST body.\n * Extracts account and signature from the request, verifies the signature,\n * and returns the authenticated account.\n *\n * @typeParam T - Request type containing optional account and signed fields\n *\n * @param request - The request object containing account and signed fields\n * @param getSigningData - Function to extract signable data from the request\n *\n * @returns The authenticated account\n *\n * @throws KeetaAnchorUserError if authentication is missing or invalid\n */\nasync function verifyBodyAuth<T extends { account?: string; signed?: unknown }>(\n\trequest: T,\n\tgetSigningData: (req: T) => Signable\n): Promise<Account> {\n\tif (!request.account || !request.signed) {\n\t\tthrow(new KeetaAnchorUserError('Authentication required'));\n\t}\n\n\tconst account = KeetaNet.lib.Account.fromPublicKeyString(request.account).assertAccount();\n\tconst signable = getSigningData(request);\n\tconst signed = assertHTTPSignedField(request.signed);\n\n\tconst valid = await VerifySignedData(account, signable, signed);\n\tif (!valid) {\n\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t}\n\n\treturn(account);\n}\n\n/**\n * Verify a signed request from URL query parameters.\n * Parses signature from URL, builds a request object, verifies the signature,\n * and returns the authenticated account.\n *\n * @typeParam T - Request type to build from the account public key\n *\n * @param url - The URL containing signature query parameters\n * @param getSigningData - Function to extract signable data from the request\n * @param buildRequest - Function to build a request object from the account public key\n *\n * @returns The authenticated account\n *\n * @throws KeetaAnchorUserError if authentication is missing or invalid\n */\nasync function verifyURLAuth<T>(\n\turl: URL | string,\n\tgetSigningData: (req: T) => Signable,\n\tbuildRequest: (accountPubKey: string) => T\n): Promise<Account> {\n\tlet urlString: string;\n\tif (typeof url === 'string') {\n\t\turlString = url;\n\t} else {\n\t\turlString = url.href;\n\t}\n\n\tconst parsed = parseSignatureFromURL(urlString);\n\tif (!parsed.account || !parsed.signedField) {\n\t\tthrow(new KeetaAnchorUserError('Authentication required'));\n\t}\n\n\tconst request = buildRequest(parsed.account.publicKeyString.get());\n\tconst signable = getSigningData(request);\n\n\tconst valid = await VerifySignedData(parsed.account, signable, parsed.signedField);\n\tif (!valid) {\n\t\tthrow(new KeetaAnchorUserError('Invalid signature'));\n\t}\n\n\treturn(parsed.account);\n}\n\n/**\n * Extract object path from wildcard route parameter.\n * Prepends a leading slash to create a valid storage path.\n *\n * @param params - Route parameters containing the wildcard match\n *\n * @returns The object path with leading slash\n *\n * @throws InvalidPath if wildcard parameter is missing\n */\nfunction extractObjectPath(params: Map<string, string>): string {\n\tconst wildcardPath = params.get('**');\n\tif (!wildcardPath) {\n\t\tthrow(new Errors.InvalidPath());\n\t}\n\n\treturn('/' + wildcardPath);\n}\n\n/**\n * Authorize access to an object path via URL-signed request.\n * Combines path validation, signature verification, and access control.\n *\n * @typeParam T - Request type to build from path and account\n *\n * @param pathPolicies - Array of path policies to check against\n * @param params - Route parameters containing the wildcard path\n * @param url - The URL containing signature query parameters\n * @param operation - The operation being authorized\n * @param getSigningData - Function to extract signable data from the request\n * @param buildRequest - Function to build a request object from path and account\n *\n * @returns The authenticated account and validated object path\n *\n * @throws InvalidPath if path is invalid or doesn't match any policy\n * @throws AccessDenied if user doesn't have access to the path\n * @throws KeetaAnchorUserError if signature is invalid\n */\nasync function authorizeURLAccess<T>(\n\tpathPolicies: PathPolicy<unknown>[],\n\tparams: Map<string, string>,\n\turl: URL | string,\n\toperation: StorageOperation,\n\tgetSigningData: (req: T) => Signable,\n\tbuildRequest: (path: string, accountPubKey: string) => T\n): Promise<{ account: Account; objectPath: string; policy: PathPolicy<unknown>; parsed: unknown }> {\n\tconst objectPath = extractObjectPath(params);\n\tconst { policy, parsed } = parsePath(pathPolicies, objectPath);\n\n\tconst account = await verifyURLAuth(url, getSigningData, function(pubKey) {\n\t\treturn(buildRequest(objectPath, pubKey));\n\t});\n\n\tif (!policy.checkAccess(account, parsed, operation)) {\n\t\tthrow(new Errors.AccessDenied('Can only access your own namespace'));\n\t}\n\n\treturn({ account, objectPath, policy, parsed });\n}\n\n// #endregion\n\n/**\n * Configuration for the Storage Anchor\n *\n * The Storage Anchor provides encrypted object storage with the following operations:\n *\n * PUT (Create/Update):\n * 1. Client creates EncryptedContainer with data, shares with anchor for public objects\n * 2. Client signs request (path, visibility, tags) and sends to server\n * 3. Server reserves quota, validates, stores object, commits reservation\n *\n * GET (Retrieve):\n * 1. Client signs request (path) and sends to server\n * 2. Server verifies access, returns EncryptedContainer\n * 3. Client decrypts with their private key\n *\n * DELETE:\n * 1. Client signs request (path) and sends to server\n * 2. Server verifies ownership, removes object\n *\n * SEARCH:\n * 1. Client signs request with criteria (tags, prefix, etc.)\n * 2. Server returns matching metadata (scoped to user's namespace)\n *\n * PUBLIC ACCESS (Pre-signed URLs):\n * 1. Client generates pre-signed URL with expiry, signed by owner\n * 2. Anyone can fetch via URL (no auth headers)\n * 3. Server verifies signature, expiry, and visibility\n * 4. Server decrypts and returns plaintext content\n *\n *\n * +-------------------+ +---------------------+ +------------------+\n * | Client | | Storage Anchor | | Storage Backend |\n * +-------------------+ +---------------------+ +------------------+\n * | | |\n * (PUT) Create EncryptedContainer | |\n * | Sign(path, visibility, tags) | |\n * |---------------------------------->| |\n * | | reserveUpload() ---------------->|\n * | | validate, put() ---------------->|\n * | | commitUpload() ----------------->|\n * |<--------------------------------- | { ok: true, object: metadata } |\n * | | |\n * (GET) Sign(path) ------------------------>| |\n * | | get() -------------------------->|\n * |<--------------------------------- | EncryptedContainer (binary) |\n * | Decrypt with private key | |\n * | | |\n * (PUBLIC) Generate pre-signed URL | |\n * | URL with expires, signature | |\n * (Anyone) Fetch URL ---------------------->| |\n * | | verify signature, expiry |\n * | | get(), decrypt ----------------->|\n * |<--------------------------------- | Plaintext content |\n */\nexport interface KeetaAnchorStorageServerConfig extends KeetaAnchorHTTPServer.KeetaAnchorHTTPServerConfig {\n\t/**\n\t * The data to use for the index page (optional)\n\t */\n\thomepage?: string | (() => Promise<string> | string);\n\n\t/**\n\t * The storage backend to use for storing documents.\n\t * Must implement full capabilities: CRUD, search, and quota management.\n\t */\n\tbackend: FullStorageBackend;\n\n\t/**\n\t * The anchor's account for decrypting objects.\n\t */\n\tanchorAccount: Account;\n\n\t/**\n\t * Quota configuration for storage limits.\n\t * Partial values are merged with defaults.\n\t */\n\tquotas?: Partial<QuotaConfig>;\n\n\t/**\n\t * Namespace validators for special paths\n\t */\n\tvalidators?: NamespaceValidator[];\n\n\t/**\n\t * Default TTL in seconds for pre-signed URLs (default: 3600)\n\t */\n\tsignedUrlDefaultTTL?: number;\n\n\t/**\n\t * CORS origin for public endpoints (default: false).\n\t * - '*' allows all origins\n\t * - specific origin string restricts to that origin\n\t * - false (default) disables CORS headers on public responses\n\t */\n\tpublicCORSOrigin?: string | false;\n\n\t/**\n\t * CORS origin for authenticated object endpoints (default: '*').\n\t * - '*' allows all origins\n\t * - specific origin string restricts to that origin\n\t */\n\tauthenticatedCORSOrigin?: string;\n\n\t/**\n\t * Path policies for parsing, validating, and access control of storage paths.\n\t * Each policy handles a specific path pattern. First matching policy wins.\n\t */\n\tpathPolicies: PathPolicy<unknown>[];\n\n\t/**\n\t * Tag validation configuration.\n\t */\n\ttagValidation?: {\n\t\t/** Maximum number of tags per object (default: 10) */\n\t\tmaxTags?: number;\n\t\t/** Maximum length of each tag (default: 50) */\n\t\tmaxTagLength?: number;\n\t\t/** Pattern for valid tag characters (default: /^[a-zA-Z0-9_-]+$/) */\n\t\tpattern?: RegExp;\n\t};\n}\n\n// Default quota configuration\nconst DEFAULT_QUOTAS: QuotaConfig = {\n\tmaxObjectSize: 10 * 1024 * 1024, // 10MB\n\tmaxObjectsPerUser: 1000,\n\tmaxStoragePerUser: 100 * 1024 * 1024, // 100MB\n\tmaxSearchLimit: 100,\n\tmaxSignedUrlTTL: 86400 // 24 hours\n};\n\n// Default tag validation configuration\nconst DEFAULT_TAG_VALIDATION = {\n\tmaxTags: 10,\n\tmaxTagLength: 50,\n\tpattern: /^[a-zA-Z0-9_-]+$/\n};\n\nexport class KeetaNetStorageAnchorHTTPServer extends KeetaAnchorHTTPServer.KeetaNetAnchorHTTPServer<KeetaAnchorStorageServerConfig> {\n\treadonly homepage: NonNullable<KeetaAnchorStorageServerConfig['homepage']>;\n\treadonly backend: FullStorageBackend;\n\treadonly anchorAccount: Account;\n\treadonly quotas: QuotaConfig;\n\treadonly validators: NamespaceValidator[];\n\treadonly signedUrlDefaultTTL: number;\n\treadonly publicCorsOrigin: string | false;\n\treadonly authenticatedCorsOrigin: string;\n\treadonly pathPolicies: PathPolicy<unknown>[];\n\treadonly tagValidation: Required<NonNullable<KeetaAnchorStorageServerConfig['tagValidation']>>;\n\n\tconstructor(config: KeetaAnchorStorageServerConfig) {\n\t\tsuper(config);\n\n\t\tthis.homepage = config.homepage ?? '';\n\t\tthis.backend = config.backend;\n\t\tthis.anchorAccount = config.anchorAccount;\n\t\tthis.quotas = { ...DEFAULT_QUOTAS, ...config.quotas };\n\t\tthis.validators = config.validators ?? [];\n\t\tthis.signedUrlDefaultTTL = config.signedUrlDefaultTTL ?? DEFAULT_SIGNED_URL_TTL_SECONDS;\n\t\tthis.publicCorsOrigin = config.publicCORSOrigin ?? false;\n\t\tthis.authenticatedCorsOrigin = config.authenticatedCORSOrigin ?? '*';\n\t\tthis.pathPolicies = config.pathPolicies;\n\t\tthis.tagValidation = {\n\t\t\tmaxTags: config.tagValidation?.maxTags ?? DEFAULT_TAG_VALIDATION.maxTags,\n\t\t\tmaxTagLength: config.tagValidation?.maxTagLength ?? DEFAULT_TAG_VALIDATION.maxTagLength,\n\t\t\tpattern: config.tagValidation?.pattern ?? DEFAULT_TAG_VALIDATION.pattern\n\t\t};\n\n\t\t// Validate anchorAccount has private key\n\t\tif (!this.anchorAccount.hasPrivateKey) {\n\t\t\tthrow(new Error('anchorAccount must have a private key'));\n\t\t}\n\n\t\t// Validate at least one path policy is provided\n\t\tif (this.pathPolicies.length === 0) {\n\t\t\tthrow(new Error('At least one path policy must be provided'));\n\t\t}\n\n\t\t// Validate quota configuration values are positive\n\t\tif (this.quotas.maxObjectSize <= 0) {\n\t\t\tthrow(new Error('quotas.maxObjectSize must be positive'));\n\t\t}\n\t\tif (this.quotas.maxObjectsPerUser <= 0) {\n\t\t\tthrow(new Error('quotas.maxObjectsPerUser must be positive'));\n\t\t}\n\t\tif (this.quotas.maxStoragePerUser <= 0) {\n\t\t\tthrow(new Error('quotas.maxStoragePerUser must be positive'));\n\t\t}\n\t\tif (this.quotas.maxSearchLimit <= 0) {\n\t\t\tthrow(new Error('quotas.maxSearchLimit must be positive'));\n\t\t}\n\t\tif (this.quotas.maxSignedUrlTTL <= 0) {\n\t\t\tthrow(new Error('quotas.maxSignedUrlTTL must be positive'));\n\t\t}\n\n\t\t// Validate tag validation configuration\n\t\tif (this.tagValidation.maxTags <= 0) {\n\t\t\tthrow(new Error('tagValidation.maxTags must be positive'));\n\t\t}\n\t\tif (this.tagValidation.maxTagLength <= 0) {\n\t\t\tthrow(new Error('tagValidation.maxTagLength must be positive'));\n\t\t}\n\t}\n\n\t// Note: We use this.* properties instead of config.*.\n\t// The config parameter is required by the abstract method signature but unused here.\n\tprotected async initRoutes(_ignoreConfig: KeetaAnchorStorageServerConfig): Promise<KeetaAnchorHTTPServer.Routes> {\n\t\tconst routes: KeetaAnchorHTTPServer.Routes = {};\n\t\tconst backend = this.backend;\n\t\tconst anchorAccount = this.anchorAccount;\n\t\tconst quotas = this.quotas;\n\t\tconst validators = this.validators;\n\t\tconst publicCorsOrigin = this.publicCorsOrigin;\n\t\tconst authenticatedCorsOrigin = this.authenticatedCorsOrigin;\n\t\tconst pathPolicies = this.pathPolicies;\n\t\tconst tagValidation = this.tagValidation;\n\t\tconst logger = this.logger;\n\n\t\t/**\n\t\t * Validate tags against configured limits.\n\t\t * @throws Errors.InvalidTag if any tag violates constraints\n\t\t */\n\t\tfunction validateTags(tags: string[]): void {\n\t\t\tconst { maxTags, maxTagLength, pattern: tagPattern } = tagValidation;\n\t\t\tfor (const tag of tags) {\n\t\t\t\tif (tag.length > maxTagLength) {\n\t\t\t\t\tthrow(new Errors.InvalidTag(`Tag exceeds maximum length of ${maxTagLength}: \"${tag}\"`));\n\t\t\t\t}\n\t\t\t\ttagPattern.lastIndex = 0;\n\t\t\t\tif (!tagPattern.test(tag)) {\n\t\t\t\t\tthrow(new Errors.InvalidTag(`Tag contains invalid characters: \"${tag}\"`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (tags.length > maxTags) {\n\t\t\t\tthrow(new Errors.InvalidTag(`Too many tags: ${tags.length} exceeds maximum of ${maxTags}`));\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Build a JSON response with assertion.\n\t\t */\n\t\tfunction jsonResponse<T>(response: T, assertionHandler: (input: unknown) => T): { output: string } {\n\t\t\treturn({ output: JSON.stringify(assertionHandler(response)) });\n\t\t}\n\n\t\t/**\n\t\t * Get an object or throw DocumentNotFound.\n\t\t */\n\t\tasync function requireObject(path: string): Promise<StorageGetResult> {\n\t\t\tconst result = await backend.get(path);\n\t\t\tif (!result) {\n\t\t\t\tthrow(new Errors.DocumentNotFound());\n\t\t\t}\n\n\t\t\treturn(result);\n\t\t}\n\n\t\t/**\n\t\t * Enforce server-side search limit cap.\n\t\t */\n\t\tfunction enforceSearchLimit(pagination: SearchPagination | undefined): SearchPagination {\n\t\t\tconst requestedLimit = pagination?.limit ?? quotas.maxSearchLimit;\n\t\t\treturn({ ...pagination, limit: Math.min(requestedLimit, quotas.maxSearchLimit) });\n\t\t}\n\n\t\t/**\n\t\t * Validate search results match expected constraints.\n\t\t */\n\t\tfunction assertSearchResults(\n\t\t\tresults: SearchResults,\n\t\t\tconstraint: { visibility?: 'public'; owner?: string }\n\t\t): void {\n\t\t\tfor (const obj of results.results) {\n\t\t\t\tif (constraint.visibility && obj.visibility !== constraint.visibility) {\n\t\t\t\t\tthrow(new Errors.InvariantViolation(\n\t\t\t\t\t\t`Backend returned ${obj.visibility} object in ${constraint.visibility} search`\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t\tif (constraint.owner && obj.owner !== constraint.owner) {\n\t\t\t\t\tthrow(new Errors.InvariantViolation(\n\t\t\t\t\t\t`Backend returned object owned by ${obj.owner} in search for ${constraint.owner}`\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * If a homepage is provided, setup the route for it\n\t\t */\n\t\tconst homepage = this.homepage;\n\t\tif (homepage) {\n\t\t\troutes['GET /'] = async function() {\n\t\t\t\tlet homepageData: string;\n\t\t\t\tif (typeof homepage === 'string') {\n\t\t\t\t\thomepageData = homepage;\n\t\t\t\t} else {\n\t\t\t\t\thomepageData = await homepage();\n\t\t\t\t}\n\n\t\t\t\treturn({\n\t\t\t\t\toutput: homepageData,\n\t\t\t\t\tcontentType: 'text/html'\n\t\t\t\t});\n\t\t\t};\n\t\t}\n\n\t\t// #region API Routes\n\n\t\t// PUT /api/object/* - Create or update an object\n\t\troutes['PUT /api/object/**'] = {\n\t\t\tbodyType: 'raw',\n\t\t\tmaxBodySize: quotas.maxObjectSize,\n\t\t\thandler: async function(params, postData, _headers, url) {\n\t\t\t\tconst objectPath = extractObjectPath(params);\n\n\t\t\t\t// Get metadata from query params\n\t\t\t\tconst parsedUrl = new URL(url);\n\t\t\t\tconst visibilityParam = parsedUrl.searchParams.get('visibility');\n\t\t\t\tconst tagsParam = parsedUrl.searchParams.get('tags');\n\n\t\t\t\t// Default to private when absent, assert valid value otherwise\n\t\t\t\tlet visibility: StorageObjectVisibility = 'private';\n\t\t\t\tif (visibilityParam !== null) {\n\t\t\t\t\tvisibility = assertVisibility(visibilityParam);\n\t\t\t\t}\n\n\t\t\t\tconst rawTags: string[] = (tagsParam ?? '')\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map(function(t) {\n\t\t\t\t\t\treturn(t.trim());\n\t\t\t\t\t})\n\t\t\t\t\t.filter(function(t) {\n\t\t\t\t\t\treturn(t.length > 0);\n\t\t\t\t\t});\n\n\t\t\t\t// Verify signature\n\t\t\t\tconst account = await verifyURLAuth(url, getKeetaStorageAnchorPutRequestSigningData, function() {\n\t\t\t\t\treturn({ path: objectPath, visibility, tags: rawTags });\n\t\t\t\t});\n\n\t\t\t\tvalidateTags(rawTags);\n\t\t\t\tconst tags = rawTags;\n\n\t\t\t\t// Validate path format, metadata, and ownership\n\t\t\t\tconst { policy, parsed } = assertPathAccess(pathPolicies, account, objectPath, 'put');\n\t\t\t\tconst owner = account.publicKeyString.get();\n\n\t\t\t\t// Resolve per-user quota limits, falling back to global config\n\t\t\t\tlet userLimits: QuotaLimits | null = null;\n\t\t\t\tif (backend.getQuotaLimits) {\n\t\t\t\t\tuserLimits = await backend.getQuotaLimits(owner);\n\t\t\t\t}\n\n\t\t\t\tconst effectiveLimits = userLimits ?? quotas;\n\t\t\t\t// Body is raw binary (EncryptedContainer)\n\t\t\t\tconst data = arrayBufferLikeToBuffer(postData);\n\t\t\t\tconst objectSize = data.byteLength;\n\t\t\t\tif (objectSize > effectiveLimits.maxObjectSize) {\n\t\t\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\t\t\tquotaType: 'maxObjectSize',\n\t\t\t\t\t\tlimit: effectiveLimits.maxObjectSize,\n\t\t\t\t\t\tcurrent: objectSize\n\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\tconst needsValidation = requiresValidation(objectPath, validators);\n\t\t\t\tconst needsContextValidation = !!policy.validateContext;\n\t\t\t\tconst needsAnchorDecryption = needsValidation || visibility === 'public';\n\t\t\t\tif (needsContextValidation || needsAnchorDecryption) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst container = EncryptedContainer.fromEncryptedBuffer(data, [anchorAccount]);\n\n\t\t\t\t\t\tif (policy.validateContext) {\n\t\t\t\t\t\t\tpolicy.validateContext(parsed, { operation: 'put', account, metadata: { owner, tags, visibility }, container });\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (needsAnchorDecryption) {\n\t\t\t\t\t\t\tconst plaintext = await container.getPlaintext();\n\t\t\t\t\t\t\tif (needsValidation) {\n\t\t\t\t\t\t\t\t// Extract content and mimeType from encrypted payload\n\t\t\t\t\t\t\t\tconst { content, mimeType } = parseContainerPayload(plaintext);\n\t\t\t\t\t\t\t\tconst matchingValidators = findMatchingValidators(objectPath, validators);\n\t\t\t\t\t\t\t\tfor (const validator of matchingValidators) {\n\t\t\t\t\t\t\t\t\tconst result = await validator.validate(objectPath, content, mimeType);\n\t\t\t\t\t\t\t\t\tif (!result.valid) {\n\t\t\t\t\t\t\t\t\t\tthrow(new Errors.ValidationFailed(result.error));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (Errors.InvalidMetadata.isInstance(e)) {\n\t\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Errors.ValidationFailed.isInstance(e)) {\n\t\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (EncryptedContainerError.isInstance(e)) {\n\t\t\t\t\t\t\tif (e.code.startsWith('MALFORMED_')) {\n\t\t\t\t\t\t\t\tthrow(new Errors.ValidationFailed(`Invalid encrypted container: ${e.message}`));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.code === 'NO_MATCHING_KEY' || e.code === 'DECRYPTION_FAILED') {\n\t\t\t\t\t\t\t\tthrow(new Errors.AnchorPrincipalRequired());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reserve quota before upload\n\t\t\t\tconst reservation = await backend.reserveUpload(owner, objectPath, objectSize, {\n\t\t\t\t\tquotaLimits: {\n\t\t\t\t\t\tmaxObjectsPerUser: effectiveLimits.maxObjectsPerUser,\n\t\t\t\t\t\tmaxStoragePerUser: effectiveLimits.maxStoragePerUser\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tlet objectMetadata: StorageObjectMetadata;\n\t\t\t\ttry {\n\t\t\t\t\tobjectMetadata = await backend.put(objectPath, data, {\n\t\t\t\t\t\towner,\n\t\t\t\t\t\ttags,\n\t\t\t\t\t\tvisibility\n\t\t\t\t\t});\n\n\t\t\t\t\tawait backend.commitUpload(reservation.id);\n\t\t\t\t} catch (e) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait backend.releaseUpload(reservation.id);\n\t\t\t\t\t} catch (releaseError) {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This provides a hint for cleanup\n\t\t\t\t\t\t */\n\t\t\t\t\t\tlogger?.warn('Failed to release upload reservation', { reservationId: reservation.id, error: releaseError });\n\t\t\t\t\t}\n\t\t\t\t\tthrow(e);\n\t\t\t\t}\n\n\t\t\t\tconst response: KeetaStorageAnchorPutResponse = {\n\t\t\t\t\tok: true,\n\t\t\t\t\tobject: objectMetadata\n\t\t\t\t};\n\n\t\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorPutResponse));\n\t\t\t}\n\t\t};\n\n\t\t// GET /api/object/* - Retrieve an object\n\t\troutes['GET /api/object/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath, policy, parsed, account } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'get',\n\t\t\t\tgetKeetaStorageAnchorGetRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn(assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (policy.validateContext) {\n\t\t\t\tpolicy.validateContext(parsed, { operation: 'get', account });\n\t\t\t}\n\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\tif (authenticatedCorsOrigin) {\n\t\t\t\theaders['Access-Control-Allow-Origin'] = authenticatedCorsOrigin;\n\t\t\t}\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\treturn({\n\t\t\t\theaders,\n\t\t\t\toutput: result.data,\n\t\t\t\tcontentType: CONTENT_TYPE_OCTET_STREAM\n\t\t\t});\n\t\t};\n\n\t\t// DELETE /api/object/* - Delete an object\n\t\troutes['DELETE /api/object/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath, policy, parsed, account } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'delete',\n\t\t\t\tgetKeetaStorageAnchorDeleteRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn({ path, account: pubKey });\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (policy.validateContext) {\n\t\t\t\tpolicy.validateContext(parsed, { operation: 'delete', account });\n\t\t\t}\n\n\t\t\tconst deleted = await backend.delete(objectPath);\n\t\t\tconst response: KeetaStorageAnchorDeleteResponse = {\n\t\t\t\tok: true,\n\t\t\t\tdeleted\n\t\t\t};\n\n\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorDeleteResponse));\n\t\t};\n\n\t\t// GET /api/metadata/* - Get object metadata\n\t\troutes['GET /api/metadata/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst { objectPath, policy, parsed, account } = await authorizeURLAccess(\n\t\t\t\tpathPolicies,\n\t\t\t\tparams,\n\t\t\t\turl,\n\t\t\t\t'metadata',\n\t\t\t\tgetKeetaStorageAnchorGetRequestSigningData,\n\t\t\t\tfunction(path, pubKey) {\n\t\t\t\t\treturn(assertKeetaStorageAnchorGetRequest({ path, account: pubKey }));\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tif (policy.validateContext) {\n\t\t\t\tpolicy.validateContext(parsed, { operation: 'metadata', account });\n\t\t\t}\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\treturn(jsonResponse({ ok: true, object: result.metadata }, assertKeetaStorageAnchorPutResponse));\n\t\t};\n\n\t\t// PUT /api/metadata/* - Update object metadata without re-uploading data\n\t\troutes['PUT /api/metadata/**'] = async function(params, postData) {\n\t\t\tconst objectPath = extractObjectPath(params);\n\t\t\tconst request = assertKeetaStorageAnchorUpdateMetadataRequest(postData);\n\n\t\t\tconst signable = getKeetaStorageAnchorUpdateMetadataRequestSigningData({\n\t\t\t\tpath: objectPath,\n\t\t\t\tvisibility: request.visibility,\n\t\t\t\ttags: request.tags\n\t\t\t});\n\t\t\tconst account = await verifyBodyAuth(request, function() { return(signable); });\n\n\t\t\tconst { policy, parsed } = assertPathAccess(pathPolicies, account, objectPath, 'updateMetadata');\n\n\t\t\tvalidateTags(request.tags);\n\n\t\t\tconst visibility = assertVisibility(request.visibility);\n\t\t\tconst tags = request.tags;\n\n\t\t\t// Confirm object exists and preserve existing owner\n\t\t\tconst existing = await requireObject(objectPath);\n\t\t\tif (policy.validateContext) {\n\t\t\t\tpolicy.validateContext(parsed, { operation: 'updateMetadata', account, metadata: { owner: existing.metadata.owner, tags, visibility }, current: existing.metadata });\n\t\t\t}\n\n\t\t\tif (!backend.updateMetadata) {\n\t\t\t\tthrow(new Errors.OperationNotSupported('updateMetadata'));\n\t\t\t}\n\n\t\t\tconst updated = await backend.updateMetadata(objectPath, { tags, visibility });\n\t\t\tif (!updated) {\n\t\t\t\tthrow(new Errors.DocumentNotFound());\n\t\t\t}\n\n\t\t\treturn(jsonResponse({ ok: true, object: updated }, assertKeetaStorageAnchorPutResponse));\n\t\t};\n\n\t\t// POST /api/search - Search for objects\n\t\troutes['POST /api/search'] = async function(_params, postData) {\n\t\t\tconst request = assertKeetaStorageAnchorSearchRequest(postData);\n\t\t\tconst account = await verifyBodyAuth(request, getKeetaStorageAnchorSearchRequestSigningData);\n\t\t\tconst accountPubKey = account.publicKeyString.get();\n\n\t\t\t// Check if searching for public objects outside namespace\n\t\t\tconst searchingPublic = request.criteria.visibility === 'public';\n\t\t\tif (searchingPublic) {\n\t\t\t\t// When searching for public objects, we allow searching outside the caller's namespace\n\t\t\t\t// but only for objects with visibility: 'public'\n\t\t\t\tconst scopedCriteria = {\n\t\t\t\t\t...request.criteria,\n\t\t\t\t\tvisibility: 'public' as const\n\t\t\t\t};\n\n\t\t\t\tconst results = await backend.search(\n\t\t\t\t\tscopedCriteria,\n\t\t\t\t\tenforceSearchLimit(request.pagination)\n\t\t\t\t);\n\n\t\t\t\tassertSearchResults(results, { visibility: 'public' });\n\n\t\t\t\treturn(jsonResponse(buildSearchResponse(results), assertKeetaStorageAnchorSearchResponse));\n\t\t\t}\n\n\t\t\t// Scope search to authenticated account's namespace\n\t\t\tconst scopedCriteria = {\n\t\t\t\t...request.criteria,\n\t\t\t\towner: accountPubKey\n\t\t\t};\n\n\t\t\tconst results = await backend.search(\n\t\t\t\tscopedCriteria,\n\t\t\t\tenforceSearchLimit(request.pagination)\n\t\t\t);\n\n\t\t\tassertSearchResults(results, { owner: accountPubKey });\n\n\t\t\treturn(jsonResponse(buildSearchResponse(results), assertKeetaStorageAnchorSearchResponse));\n\t\t};\n\n\t\t// GET /api/quota - Get quota status\n\t\troutes['GET /api/quota'] = async function(_params, _postData, _headers, url) {\n\t\t\tconst account = await verifyURLAuth(\n\t\t\t\turl,\n\t\t\t\tgetKeetaStorageAnchorQuotaRequestSigningData,\n\t\t\t\tfunction() { return({}); }\n\t\t\t);\n\n\t\t\t// Get current usage from backend and compute remaining using per-user or global limits\n\t\t\tconst owner = account.publicKeyString.get();\n\t\t\tlet userLimits: QuotaLimits | null = null;\n\t\t\tif (backend.getQuotaLimits) {\n\t\t\t\tuserLimits = await backend.getQuotaLimits(owner);\n\t\t\t}\n\n\t\t\tconst effectiveLimits = userLimits ?? quotas;\n\t\t\tconst backendStatus = await backend.getQuotaStatus(owner);\n\n\t\t\t// Compute remaining from config limits\n\t\t\tlet remainingObjects = Math.max(0, effectiveLimits.maxObjectsPerUser - backendStatus.objectCount);\n\t\t\tlet remainingSize = Math.max(0, effectiveLimits.maxStoragePerUser - backendStatus.totalSize);\n\n\t\t\t// If backend reports its own remaining values, use the tighter constraint\n\t\t\tif (backendStatus.remainingObjects !== undefined && backendStatus.remainingObjects > 0) {\n\t\t\t\tremainingObjects = Math.min(backendStatus.remainingObjects, remainingObjects);\n\t\t\t}\n\t\t\tif (backendStatus.remainingSize !== undefined && backendStatus.remainingSize > 0) {\n\t\t\t\tremainingSize = Math.min(backendStatus.remainingSize, remainingSize);\n\t\t\t}\n\n\t\t\tconst response: KeetaStorageAnchorQuotaResponse = {\n\t\t\t\tok: true,\n\t\t\t\tquota: {\n\t\t\t\t\tobjectCount: backendStatus.objectCount,\n\t\t\t\t\ttotalSize: backendStatus.totalSize,\n\t\t\t\t\tremainingObjects,\n\t\t\t\t\tremainingSize\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn(jsonResponse(response, assertKeetaStorageAnchorQuotaResponse));\n\t\t};\n\n\t\t// GET /api/public/** - Public object access via pre-signed URL\n\t\troutes['GET /api/public/**'] = async function(params, _postData, _headers, url) {\n\t\t\tconst objectPath = extractObjectPath(params);\n\t\t\tconst { policy, parsed } = parsePath(pathPolicies, objectPath);\n\n\t\t\t// Parse signature using standard signed field convention\n\t\t\tconst urlParsed = parseSignatureFromURL(url);\n\t\t\tif (!urlParsed.signedField) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing required signature parameters'));\n\t\t\t}\n\n\t\t\t// Resolve signer: policy-specified or from URL account param (any-signer for public objects)\n\t\t\tconst signerAccount = policy.getAuthorizedSigner(parsed) ?? urlParsed.account ?? null;\n\t\t\tif (!signerAccount) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing signer'));\n\t\t\t}\n\t\t\tconst signerPubKey = signerAccount.publicKeyString.get();\n\n\t\t\t// Parse and validate expires param\n\t\t\tconst parsedUrl = typeof url === 'string' ? new URL(url) : url;\n\t\t\tconst expiresParam = parsedUrl.searchParams.get('expires');\n\t\t\tif (!expiresParam) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Missing expires parameter'));\n\t\t\t}\n\t\t\tconst expiresAt = parseInt(expiresParam, 10);\n\t\t\tif (!Number.isFinite(expiresAt)) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Invalid expires parameter'));\n\t\t\t}\n\t\t\tif (Date.now() > expiresAt * 1000) {\n\t\t\t\tthrow(new Errors.SignatureExpired());\n\t\t\t}\n\n\t\t\t// Enforce maximum TTL\n\t\t\tconst maxExpiresAt = Math.floor(Date.now() / 1000) + quotas.maxSignedUrlTTL;\n\t\t\tif (expiresAt > maxExpiresAt) {\n\t\t\t\tthrow(new Errors.SignatureExpired('Signed URL TTL exceeds maximum allowed'));\n\t\t\t}\n\n\t\t\t// Pre-validate signature is valid base64 with reasonable length\n\t\t\tconst signatureBuffer = Buffer.from(urlParsed.signedField.signature, 'base64');\n\t\t\tif (signatureBuffer.length < 64 || signatureBuffer.length > 256) {\n\t\t\t\tthrow(new Errors.SignatureInvalid('Invalid signature format'));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Allow 5 minutes of clock skew for signature verification\n\t\t\t\tconst valid = await VerifySignedData(signerAccount, [objectPath, expiresAt, signerPubKey], urlParsed.signedField, {\n\t\t\t\t\tmaxSkewMs: 5 * 60 * 1000\n\t\t\t\t});\n\t\t\t\tif (!valid) {\n\t\t\t\t\tthrow(new Errors.SignatureInvalid());\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tif (Errors.SignatureInvalid.isInstance(e)) {\n\t\t\t\t\tthrow(e);\n\t\t\t\t}\n\n\t\t\t\tthrow(new Errors.SignatureInvalid('Signature verification failed'));\n\t\t\t}\n\n\t\t\tif (policy.validateContext) {\n\t\t\t\tpolicy.validateContext(parsed, { operation: 'get', account: signerAccount });\n\t\t\t}\n\n\t\t\tconst result = await requireObject(objectPath);\n\t\t\tif (result.metadata.visibility !== 'public') {\n\t\t\t\tthrow(new Errors.AccessDenied('Object is not public'));\n\t\t\t}\n\n\t\t\t// Decrypt using anchor account and extract mimeType from encrypted payload\n\t\t\tconst data = arrayBufferLikeToBuffer(result.data);\n\t\t\tconst container = EncryptedContainer.fromEncryptedBuffer(data, [anchorAccount]);\n\t\t\tconst plaintext = await container.getPlaintext();\n\t\t\tconst { content, mimeType } = parseContainerPayload(plaintext);\n\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\tif (publicCorsOrigin) {\n\t\t\t\theaders['Access-Control-Allow-Origin'] = publicCorsOrigin;\n\t\t\t}\n\n\t\t\treturn({\n\t\t\t\toutput: content,\n\t\t\t\tcontentType: mimeType,\n\t\t\t\theaders\n\t\t\t});\n\t\t};\n\n\t\t// #endregion\n\n\t\treturn(routes);\n\t}\n\n\tasync serviceMetadata(): Promise<NonNullable<ServiceMetadata['services']['storage']>[string]> {\n\t\tconst authRequired = { options: { authentication: { type: 'required' as const, method: 'keeta-account' as const }}};\n\t\tconst operations: NonNullable<ServiceMetadata['services']['storage']>[string]['operations'] = {\n\t\t\tput: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tget: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tdelete: { url: (new URL('/api/object', this.url)).toString(), ...authRequired },\n\t\t\tmetadata: { url: (new URL('/api/metadata', this.url)).toString(), ...authRequired },\n\t\t\tupdateMetadata: { url: (new URL('/api/metadata', this.url)).toString(), ...authRequired },\n\t\t\tsearch: { url: (new URL('/api/search', this.url)).toString(), ...authRequired },\n\t\t\tpublic: (new URL('/api/public', this.url)).toString(),\n\t\t\tquota: { url: (new URL('/api/quota', this.url)).toString(), ...authRequired }\n\t\t};\n\n\t\treturn({\n\t\t\toperations,\n\t\t\tanchorAccount: this.anchorAccount.publicKeyString.get(),\n\t\t\tquotas: this.quotas,\n\t\t\tsignedUrlDefaultTTL: this.signedUrlDefaultTTL,\n\t\t\tsearchableFields: ['owner', 'tags', 'visibility', 'pathPrefix']\n\t\t});\n\t}\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { PathPolicy, FullStorageBackend, StorageObjectMetadata, StoragePutMetadata, StorageGetResult, SearchCriteria, SearchPagination, SearchResults, QuotaStatus, QuotaLimits, UploadReservation } from './common.js';
1
+ import type { PathPolicy, PathPolicyContext, FullStorageBackend, StorageObjectMetadata, StoragePutMetadata, StorageGetResult, SearchCriteria, SearchPagination, SearchResults, QuotaStatus, QuotaLimits, UploadReservation } from './common.js';
2
2
  import type { KeetaStorageAnchorProvider } from './client.js';
3
3
  import { KeetaNet } from '../../client/index.js';
4
4
  import { Buffer } from '../../lib/utils/buffer.js';
@@ -22,7 +22,7 @@ export declare class TestPathPolicy implements PathPolicy<TestParsedPath> {
22
22
  isValid(path: string): boolean;
23
23
  checkAccess(account: InstanceType<typeof KeetaNet.lib.Account>, parsed: TestParsedPath, _ignoreOperation: 'get' | 'put' | 'delete' | 'search' | 'metadata'): boolean;
24
24
  getAuthorizedSigner(parsed: TestParsedPath): InstanceType<typeof KeetaNet.lib.Account> | null;
25
- validateMetadata(parsed: TestParsedPath, metadata: StoragePutMetadata): void;
25
+ validateContext(parsed: TestParsedPath, context: PathPolicyContext): void;
26
26
  /**
27
27
  * Helper to construct a path for a given owner and relative path.
28
28
  */
@@ -40,6 +40,10 @@ export declare const testPathPolicy: TestPathPolicy;
40
40
  * Create test metadata with sensible defaults.
41
41
  */
42
42
  export declare function testMetadata(owner: string, overrides?: Partial<StoragePutMetadata>): StoragePutMetadata;
43
+ /**
44
+ * Create test object metadata with sensible defaults.
45
+ */
46
+ export declare function testObjectMetadata(path: string, owner: string, overrides?: Partial<StorageObjectMetadata>): StorageObjectMetadata;
43
47
  /**
44
48
  * In-memory storage backend with full capabilities: CRUD, search, and quota management.
45
49
  * Intended for testing and development purposes.
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../src/services/storage/test-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../src/services/storage/test-utils.ts"],"names":[],"mappings":"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"}
@@ -48,10 +48,11 @@ export class TestPathPolicy {
48
48
  getAuthorizedSigner(parsed) {
49
49
  return (KeetaNet.lib.Account.fromPublicKeyString(parsed.owner).assertAccount());
50
50
  }
51
- validateMetadata(parsed, metadata) {
52
- // Require public visibility for paths under public/
53
- if (parsed.relativePath.startsWith('public/') && metadata.visibility !== 'public') {
54
- throw (new Errors.InvalidMetadata('Objects under /public/ must have public visibility'));
51
+ validateContext(parsed, context) {
52
+ if (context.operation === 'put' || context.operation === 'updateMetadata') {
53
+ if (parsed.relativePath.startsWith('public/') && context.metadata.visibility !== 'public') {
54
+ throw (new Errors.InvalidMetadata('Objects under /public/ must have public visibility'));
55
+ }
55
56
  }
56
57
  }
57
58
  /**
@@ -82,6 +83,20 @@ export function testMetadata(owner, overrides) {
82
83
  ...overrides
83
84
  });
84
85
  }
86
+ /**
87
+ * Create test object metadata with sensible defaults.
88
+ */
89
+ export function testObjectMetadata(path, owner, overrides) {
90
+ return ({
91
+ path,
92
+ owner,
93
+ tags: [],
94
+ visibility: 'private',
95
+ size: 0,
96
+ createdAt: new Date().toISOString(),
97
+ ...overrides
98
+ });
99
+ }
85
100
  // #endregion
86
101
  // #region Shared Storage Operations
87
102
  function putToStorage(storage, path, data, metadata) {
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../../src/services/storage/test-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tPathPolicy,\n\tFullStorageBackend,\n\tStorageObjectMetadata,\n\tStoragePutMetadata,\n\tStorageGetResult,\n\tSearchCriteria,\n\tSearchPagination,\n\tSearchResults,\n\tQuotaStatus,\n\tQuotaLimits,\n\tUploadReservation\n} from './common.js';\nimport type { KeetaStorageAnchorProvider } from './client.js';\nimport { KeetaNet } from '../../client/index.js';\nimport { createNodeAndClient, setResolverInfo } from '../../lib/utils/tests/node.js';\nimport { KeetaNetStorageAnchorHTTPServer } from './server.js';\nimport { Errors } from './common.js';\nimport { Buffer } from '../../lib/utils/buffer.js';\nimport KeetaAnchorResolver from '../../lib/resolver.js';\nimport KeetaStorageAnchorClient from './client.js';\n\n// #region Test Path Policy\n\n/**\n * Parsed path for the test path policy: /user/<pubkey>/<relativePath>\n */\nexport type TestParsedPath = {\n\tpath: string;\n\towner: string;\n\trelativePath: string;\n};\n\n/**\n * Test path policy implementing the /user/<pubkey>/<path> pattern.\n * Owner-based access control: only the owner can access their namespace.\n */\nexport class TestPathPolicy implements PathPolicy<TestParsedPath> {\n\t// Matches /user/<owner> or /user/<owner>/ or /user/<owner>/<path>\n\treadonly #pattern = /^\\/user\\/([^/]+)(\\/(.*))?$/;\n\n\tparse(path: string): TestParsedPath | null {\n\t\tconst match = path.match(this.#pattern);\n\t\tif (!match?.[1]) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn({ path, owner: match[1], relativePath: match[3] ?? '' });\n\t}\n\n\tvalidate(path: string): TestParsedPath {\n\t\tconst parsed = this.parse(path);\n\t\tif (!parsed) {\n\t\t\tthrow(new Errors.InvalidPath('Path must match /user/<pubkey>/<path>'));\n\t\t}\n\n\t\t// Reject empty segments in original path\n\t\tif (path.includes('//')) {\n\t\t\tthrow(new Errors.InvalidPath('Path contains empty segments'));\n\t\t}\n\n\t\t// Reject path traversal attempts\n\t\tconst segments = parsed.relativePath.split('/');\n\t\tfor (const seg of segments) {\n\t\t\tif (seg === '..' || seg === '.') {\n\t\t\t\tthrow(new Errors.InvalidPath('Path contains relative segments'));\n\t\t\t}\n\t\t}\n\n\t\treturn(parsed);\n\t}\n\n\tisValid(path: string): boolean {\n\t\treturn(this.parse(path) !== null);\n\t}\n\n\tcheckAccess(\n\t\taccount: InstanceType<typeof KeetaNet.lib.Account>,\n\t\tparsed: TestParsedPath,\n\t\t_ignoreOperation: 'get' | 'put' | 'delete' | 'search' | 'metadata'\n\t): boolean {\n\t\t// Owner-based access: account must match the path owner\n\t\treturn(parsed.owner === account.publicKeyString.get());\n\t}\n\n\tgetAuthorizedSigner(parsed: TestParsedPath): InstanceType<typeof KeetaNet.lib.Account> | null {\n\t\treturn(KeetaNet.lib.Account.fromPublicKeyString(parsed.owner).assertAccount());\n\t}\n\n\tvalidateMetadata(parsed: TestParsedPath, metadata: StoragePutMetadata): void {\n\t\t// Require public visibility for paths under public/\n\t\tif (parsed.relativePath.startsWith('public/') && metadata.visibility !== 'public') {\n\t\t\tthrow(new Errors.InvalidMetadata('Objects under /public/ must have public visibility'));\n\t\t}\n\t}\n\n\t/**\n\t * Helper to construct a path for a given owner and relative path.\n\t */\n\tmakePath(owner: string, relativePath: string): string {\n\t\treturn(`/user/${owner}/${relativePath}`);\n\t}\n\n\t/**\n\t * Helper to get the namespace prefix for an owner.\n\t */\n\tgetNamespacePrefix(owner: string): string {\n\t\treturn(`/user/${owner}/`);\n\t}\n}\n\n/**\n * Shared instance of TestPathPolicy for use in tests.\n */\nexport const testPathPolicy: TestPathPolicy = new TestPathPolicy();\n\n/**\n * Create test metadata with sensible defaults.\n */\nexport function testMetadata(\n\towner: string,\n\toverrides?: Partial<StoragePutMetadata>\n): StoragePutMetadata {\n\treturn({\n\t\towner,\n\t\ttags: [],\n\t\tvisibility: 'private',\n\t\t...overrides\n\t});\n}\n\n// #endregion\n\n// #region Types\n\ntype StorageEntry = {\n\tdata: Buffer;\n\tmetadata: StorageObjectMetadata;\n};\n\ntype QuotaConfig = {\n\tmaxObjectsPerUser: number;\n\tmaxStoragePerUser: number;\n};\n\n// #endregion\n\n// #region Shared Storage Operations\n\nfunction putToStorage(\n\tstorage: Map<string, StorageEntry>,\n\tpath: string,\n\tdata: Buffer,\n\tmetadata: StoragePutMetadata\n): StorageObjectMetadata {\n\tconst now = new Date().toISOString();\n\tconst existing = storage.get(path);\n\tconst objectMetadata: StorageObjectMetadata = {\n\t\tpath,\n\t\towner: metadata.owner,\n\t\ttags: metadata.tags,\n\t\tvisibility: metadata.visibility,\n\t\tsize: data.length,\n\t\tcreatedAt: existing?.metadata.createdAt ?? now,\n\t\t...(existing ? { updatedAt: now } : {})\n\t};\n\n\tstorage.set(path, { data, metadata: objectMetadata });\n\treturn(objectMetadata);\n}\n\nfunction getFromStorage(\n\tstorage: Map<string, StorageEntry>,\n\tpath: string\n): StorageGetResult | null {\n\tconst entry = storage.get(path);\n\tif (!entry) {\n\t\treturn(null);\n\t}\n\n\treturn({\n\t\tdata: Buffer.from(entry.data),\n\t\tmetadata: { ...entry.metadata }\n\t});\n}\n\nfunction searchStorage(\n\tstorage: Map<string, StorageEntry>,\n\tcriteria: SearchCriteria,\n\tpagination: SearchPagination\n): SearchResults {\n\tconst results: StorageObjectMetadata[] = [];\n\tconst limit = pagination.limit ?? 100;\n\tconst startAfter = pagination.cursor;\n\tlet foundCursor = !startAfter;\n\n\tfor (const [path, entry] of storage.entries()) {\n\t\tif (!foundCursor) {\n\t\t\tif (path === startAfter) {\n\t\t\t\tfoundCursor = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst metadata = entry.metadata;\n\n\t\tif (criteria.pathPrefix) {\n\t\t\tconst prefix = criteria.pathPrefix.endsWith('/')\n\t\t\t\t? criteria.pathPrefix\n\t\t\t\t: criteria.pathPrefix + '/';\n\t\t\tif (!path.startsWith(prefix) && path !== criteria.pathPrefix) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!criteria.recursive) {\n\t\t\t\tconst remainder = path.slice(prefix.length);\n\t\t\t\tif (remainder.includes('/')) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.owner && metadata.owner !== criteria.owner) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (criteria.tags && criteria.tags.length > 0) {\n\t\t\tconst hasMatchingTag = criteria.tags.some(function(tag) {\n\t\t\t\treturn(metadata.tags.includes(tag));\n\t\t\t});\n\t\t\tif (!hasMatchingTag) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.name) {\n\t\t\tconst filename = path.split('/').pop();\n\t\t\tif (!filename?.includes(criteria.name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.visibility && metadata.visibility !== criteria.visibility) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tresults.push(metadata);\n\n\t\tif (results.length >= limit) {\n\t\t\treturn({ results, nextCursor: path });\n\t\t}\n\t}\n\n\treturn({ results });\n}\n\nfunction computeQuotaStatus(\n\tstorage: Map<string, StorageEntry>,\n\towner: string,\n\tquotaConfig: QuotaConfig\n): QuotaStatus {\n\tlet objectCount = 0;\n\tlet totalSize = 0;\n\tfor (const entry of storage.values()) {\n\t\tif (entry.metadata.owner === owner) {\n\t\t\tobjectCount++;\n\n\t\t\ttotalSize += entry.metadata.size;\n\t\t}\n\t}\n\n\treturn({\n\t\tobjectCount,\n\t\ttotalSize,\n\t\tremainingObjects: Math.max(0, quotaConfig.maxObjectsPerUser - objectCount),\n\t\tremainingSize: Math.max(0, quotaConfig.maxStoragePerUser - totalSize)\n\t});\n}\n\n// #endregion\n\n// #region Memory Storage Backend\n\n/**\n * In-memory storage backend with full capabilities: CRUD, search, and quota management.\n * Intended for testing and development purposes.\n */\nexport class MemoryStorageBackend implements FullStorageBackend {\n\tprivate storage = new Map<string, StorageEntry>();\n\tprivate reservations = new Map<string, UploadReservation>();\n\treadonly #reservationsByPath = new Map<string, string>(); // \"owner:path\" -> reservationId\n\tprivate reservationCounter = 0;\n\treadonly #quotaLimitsPerUser = new Map<string, QuotaLimits>();\n\n\tprivate readonly quotaConfig: QuotaConfig = {\n\t\tmaxObjectsPerUser: 1000,\n\t\tmaxStoragePerUser: 100 * 1024 * 1024 // 100MB\n\t};\n\n\t/**\n\t * Prune expired reservations to keep quota accounting accurate.\n\t */\n\t#pruneExpiredReservations(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [id, reservation] of this.reservations) {\n\t\t\tif (new Date(reservation.expiresAt).getTime() <= now) {\n\t\t\t\tthis.reservations.delete(id);\n\t\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync put(path: string, data: Buffer, metadata: StoragePutMetadata): Promise<StorageObjectMetadata> {\n\t\treturn(putToStorage(this.storage, path, data, metadata));\n\t}\n\n\tasync get(path: string): Promise<StorageGetResult | null> {\n\t\treturn(getFromStorage(this.storage, path));\n\t}\n\n\tasync delete(path: string): Promise<boolean> {\n\t\treturn(this.storage.delete(path));\n\t}\n\n\tasync updateMetadata(path: string, metadata: Omit<StoragePutMetadata, 'owner'>): Promise<StorageObjectMetadata | null> {\n\t\tconst entry = this.storage.get(path);\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\tconst now = new Date().toISOString();\n\t\tconst updated: StorageObjectMetadata = {\n\t\t\t...entry.metadata,\n\t\t\ttags: metadata.tags,\n\t\t\tvisibility: metadata.visibility,\n\t\t\tupdatedAt: now\n\t\t};\n\n\t\tthis.storage.set(path, { data: entry.data, metadata: updated });\n\t\treturn(updated);\n\t}\n\n\tasync search(criteria: SearchCriteria, pagination: SearchPagination): Promise<SearchResults> {\n\t\treturn(searchStorage(this.storage, criteria, pagination));\n\t}\n\n\tasync getQuotaStatus(owner: string): Promise<QuotaStatus> {\n\t\t// Prune expired reservations first\n\t\tthis.#pruneExpiredReservations();\n\n\t\t// Get base quota from actual storage\n\t\tconst baseQuota = computeQuotaStatus(this.storage, owner, this.quotaConfig);\n\n\t\t// Add pending reservations for this owner\n\t\tlet reservedObjects = 0;\n\t\tlet reservedSize = 0;\n\t\tfor (const reservation of this.reservations.values()) {\n\t\t\tif (reservation.owner === owner) {\n\t\t\t\t// Only count as new object if path doesn't exist\n\t\t\t\tif (!this.storage.has(reservation.path)) {\n\t\t\t\t\treservedObjects++;\n\t\t\t\t}\n\n\t\t\t\treservedSize += reservation.size;\n\t\t\t}\n\t\t}\n\n\t\tconst objectCount = baseQuota.objectCount + reservedObjects;\n\t\tconst totalSize = baseQuota.totalSize + reservedSize;\n\t\tconst remainingObjects = Math.max(0, (baseQuota.remainingObjects ?? 0) - reservedObjects);\n\t\tconst remainingSize = Math.max(0, (baseQuota.remainingSize ?? 0) - reservedSize);\n\t\treturn({\n\t\t\tobjectCount,\n\t\t\ttotalSize,\n\t\t\tremainingObjects,\n\t\t\tremainingSize\n\t\t});\n\t}\n\n\tasync getQuotaLimits(owner: string): Promise<QuotaLimits | null> {\n\t\treturn(this.#quotaLimitsPerUser.get(owner) ?? null);\n\t}\n\n\tsetQuotaLimits(owner: string, limits: QuotaLimits): void {\n\t\tthis.#quotaLimitsPerUser.set(owner, limits);\n\t}\n\n\tasync reserveUpload(owner: string, path: string, size: number, options?: {\n\t\tttlMs?: number;\n\t\tquotaLimits?: { maxObjectsPerUser: number; maxStoragePerUser: number };\n\t}): Promise<UploadReservation> {\n\t\t// Validate size parameter\n\t\tif (size < 0) {\n\t\t\tthrow(new Errors.InvariantViolation('Reservation size cannot be negative'));\n\t\t}\n\n\t\t// Prune expired reservations first\n\t\tthis.#pruneExpiredReservations();\n\n\t\t// Default TTL: 5 minutes\n\t\tconst DEFAULT_RESERVATION_TTL_MS = 5 * 60 * 1000;\n\t\tconst ttl = options?.ttlMs ?? DEFAULT_RESERVATION_TTL_MS;\n\n\t\t// Use provided quota limits or fall back to backend defaults\n\t\tconst limits = options?.quotaLimits ?? this.quotaConfig;\n\n\t\t// Check if this would exceed quota\n\t\tconst quotaStatus = await this.getQuotaStatus(owner);\n\t\tconst isNewObject = !this.storage.has(path);\n\t\tconst existingSize = this.storage.get(path)?.data.length ?? 0;\n\t\tconst sizeDelta = size - existingSize;\n\n\t\t// Calculate remaining based on provided limits\n\t\tconst remainingObjects = limits.maxObjectsPerUser - quotaStatus.objectCount;\n\t\tconst remainingSize = limits.maxStoragePerUser - quotaStatus.totalSize;\n\n\t\tif (isNewObject && remainingObjects <= 0) {\n\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\tquotaType: 'maxObjectsPerUser',\n\t\t\t\tlimit: limits.maxObjectsPerUser,\n\t\t\t\tcurrent: quotaStatus.objectCount\n\t\t\t}));\n\t\t}\n\n\t\tif (sizeDelta > 0 && remainingSize < sizeDelta) {\n\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\tquotaType: 'maxStoragePerUser',\n\t\t\t\tlimit: limits.maxStoragePerUser,\n\t\t\t\tcurrent: quotaStatus.totalSize + sizeDelta\n\t\t\t}));\n\t\t}\n\n\t\t// Check for existing reservation for this (owner, path)\n\t\t// If a reservation already exists, we calculate the additional quota needed\n\t\t// by comparing the new sizeDelta with the existing reservation's reserved size.\n\t\tconst pathKey = `${owner}:${path}`;\n\t\tconst existingId = this.#reservationsByPath.get(pathKey);\n\t\tif (existingId) {\n\t\t\tconst existing = this.reservations.get(existingId);\n\t\t\tif (existing) {\n\t\t\t\tconst clampedSizeDelta = Math.max(0, sizeDelta);\n\t\t\t\tconst additionalSize = clampedSizeDelta - existing.size;\n\n\t\t\t\t// Re-check quota if size is increasing beyond current reservation\n\t\t\t\tif (additionalSize > 0 && remainingSize < additionalSize) {\n\t\t\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\t\t\tquotaType: 'maxStoragePerUser',\n\t\t\t\t\t\tlimit: limits.maxStoragePerUser,\n\t\t\t\t\t\tcurrent: quotaStatus.totalSize + additionalSize\n\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\t// Update to max size, extend expiry\n\t\t\t\texisting.size = Math.max(existing.size, clampedSizeDelta);\n\t\t\t\texisting.expiresAt = new Date(Date.now() + ttl).toISOString();\n\t\t\t\treturn(existing);\n\t\t\t}\n\t\t}\n\n\t\tconst now = new Date();\n\t\tconst reservation: UploadReservation = {\n\t\t\tid: `res_${++this.reservationCounter}`,\n\t\t\towner,\n\t\t\tpath,\n\t\t\tsize: Math.max(0, sizeDelta),\n\t\t\tcreatedAt: now.toISOString(),\n\t\t\texpiresAt: new Date(now.getTime() + ttl).toISOString()\n\t\t};\n\n\t\tthis.reservations.set(reservation.id, reservation);\n\t\tthis.#reservationsByPath.set(pathKey, reservation.id);\n\t\treturn(reservation);\n\t}\n\n\tasync commitUpload(reservationId: string): Promise<void> {\n\t\t// Simply remove the reservation - the actual storage was already updated via put()\n\t\tconst reservation = this.reservations.get(reservationId);\n\t\tif (reservation) {\n\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t}\n\n\t\tthis.reservations.delete(reservationId);\n\t}\n\n\tasync releaseUpload(reservationId: string): Promise<void> {\n\t\t// Remove the reservation, freeing the reserved quota\n\t\tconst reservation = this.reservations.get(reservationId);\n\t\tif (reservation) {\n\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t}\n\n\t\tthis.reservations.delete(reservationId);\n\t}\n\n\tclear(): void {\n\t\tthis.storage.clear();\n\t\tthis.reservations.clear();\n\t\tthis.#reservationsByPath.clear();\n\t}\n\n\tget size(): number {\n\t\treturn(this.storage.size);\n\t}\n}\n\n// #endregion\n\n// #region Shared Test Harness\n\nexport type Account = InstanceType<typeof KeetaNet.lib.Account>;\n\nexport function randomSeed(): string | ArrayBuffer {\n\treturn(KeetaNet.lib.Account.generateRandomSeed());\n}\n\nexport interface StorageProviderTestContext {\n\tprovider: KeetaStorageAnchorProvider;\n\taccount: Account;\n\tstorageClient: KeetaStorageAnchorClient;\n}\n\n/**\n * Shared test harness that stands up a storage server, resolves a provider,\n * and passes the provider context to the test function.\n */\nexport async function withStorageProvider(\n\tseed: string | ArrayBuffer,\n\ttestFunction: (ctx: StorageProviderTestContext) => Promise<void>\n): Promise<void> {\n\tconst account = KeetaNet.lib.Account.fromSeed(seed, 0);\n\tconst anchorAccount = KeetaNet.lib.Account.fromSeed(seed, 50);\n\n\tawait using nodeAndClient = await createNodeAndClient(account);\n\n\tconst userClient = nodeAndClient.userClient;\n\tnodeAndClient.fees.disable();\n\n\tconst backend = new MemoryStorageBackend();\n\n\tawait using server = new KeetaNetStorageAnchorHTTPServer({\n\t\tbackend,\n\t\tanchorAccount,\n\t\tpathPolicies: [testPathPolicy]\n\t});\n\n\tawait server.start();\n\n\tconst rootAccount = KeetaNet.lib.Account.fromSeed(seed, 100);\n\tconst serviceMetadata = await server.serviceMetadata();\n\n\tawait setResolverInfo(rootAccount, userClient, {\n\t\tversion: 1,\n\t\tcurrencyMap: {},\n\t\tservices: {\n\t\t\tstorage: {\n\t\t\t\t'test-provider': serviceMetadata\n\t\t\t}\n\t\t}\n\t});\n\n\tconst resolver = new KeetaAnchorResolver({\n\t\troot: rootAccount,\n\t\tclient: userClient,\n\t\ttrustedCAs: []\n\t});\n\n\tconst storageClient = new KeetaStorageAnchorClient(userClient, { resolver });\n\tconst maybeProvider = await storageClient.getProviderByID('test-provider');\n\tif (!maybeProvider) {\n\t\tthrow(new Error('Provider not found'));\n\t}\n\n\tawait testFunction({ provider: maybeProvider, account, storageClient });\n}\n\n// #endregion\n"]}
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../../src/services/storage/test-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tPathPolicy,\n\tPathPolicyContext,\n\tFullStorageBackend,\n\tStorageObjectMetadata,\n\tStoragePutMetadata,\n\tStorageGetResult,\n\tSearchCriteria,\n\tSearchPagination,\n\tSearchResults,\n\tQuotaStatus,\n\tQuotaLimits,\n\tUploadReservation\n} from './common.js';\nimport type { KeetaStorageAnchorProvider } from './client.js';\nimport { KeetaNet } from '../../client/index.js';\nimport { createNodeAndClient, setResolverInfo } from '../../lib/utils/tests/node.js';\nimport { KeetaNetStorageAnchorHTTPServer } from './server.js';\nimport { Errors } from './common.js';\nimport { Buffer } from '../../lib/utils/buffer.js';\nimport KeetaAnchorResolver from '../../lib/resolver.js';\nimport KeetaStorageAnchorClient from './client.js';\n\n// #region Test Path Policy\n\n/**\n * Parsed path for the test path policy: /user/<pubkey>/<relativePath>\n */\nexport type TestParsedPath = {\n\tpath: string;\n\towner: string;\n\trelativePath: string;\n};\n\n/**\n * Test path policy implementing the /user/<pubkey>/<path> pattern.\n * Owner-based access control: only the owner can access their namespace.\n */\nexport class TestPathPolicy implements PathPolicy<TestParsedPath> {\n\t// Matches /user/<owner> or /user/<owner>/ or /user/<owner>/<path>\n\treadonly #pattern = /^\\/user\\/([^/]+)(\\/(.*))?$/;\n\n\tparse(path: string): TestParsedPath | null {\n\t\tconst match = path.match(this.#pattern);\n\t\tif (!match?.[1]) {\n\t\t\treturn(null);\n\t\t}\n\n\t\treturn({ path, owner: match[1], relativePath: match[3] ?? '' });\n\t}\n\n\tvalidate(path: string): TestParsedPath {\n\t\tconst parsed = this.parse(path);\n\t\tif (!parsed) {\n\t\t\tthrow(new Errors.InvalidPath('Path must match /user/<pubkey>/<path>'));\n\t\t}\n\n\t\t// Reject empty segments in original path\n\t\tif (path.includes('//')) {\n\t\t\tthrow(new Errors.InvalidPath('Path contains empty segments'));\n\t\t}\n\n\t\t// Reject path traversal attempts\n\t\tconst segments = parsed.relativePath.split('/');\n\t\tfor (const seg of segments) {\n\t\t\tif (seg === '..' || seg === '.') {\n\t\t\t\tthrow(new Errors.InvalidPath('Path contains relative segments'));\n\t\t\t}\n\t\t}\n\n\t\treturn(parsed);\n\t}\n\n\tisValid(path: string): boolean {\n\t\treturn(this.parse(path) !== null);\n\t}\n\n\tcheckAccess(\n\t\taccount: InstanceType<typeof KeetaNet.lib.Account>,\n\t\tparsed: TestParsedPath,\n\t\t_ignoreOperation: 'get' | 'put' | 'delete' | 'search' | 'metadata'\n\t): boolean {\n\t\t// Owner-based access: account must match the path owner\n\t\treturn(parsed.owner === account.publicKeyString.get());\n\t}\n\n\tgetAuthorizedSigner(parsed: TestParsedPath): InstanceType<typeof KeetaNet.lib.Account> | null {\n\t\treturn(KeetaNet.lib.Account.fromPublicKeyString(parsed.owner).assertAccount());\n\t}\n\n\tvalidateContext(parsed: TestParsedPath, context: PathPolicyContext): void {\n\t\tif (context.operation === 'put' || context.operation === 'updateMetadata') {\n\t\t\tif (parsed.relativePath.startsWith('public/') && context.metadata.visibility !== 'public') {\n\t\t\t\tthrow(new Errors.InvalidMetadata('Objects under /public/ must have public visibility'));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper to construct a path for a given owner and relative path.\n\t */\n\tmakePath(owner: string, relativePath: string): string {\n\t\treturn(`/user/${owner}/${relativePath}`);\n\t}\n\n\t/**\n\t * Helper to get the namespace prefix for an owner.\n\t */\n\tgetNamespacePrefix(owner: string): string {\n\t\treturn(`/user/${owner}/`);\n\t}\n}\n\n/**\n * Shared instance of TestPathPolicy for use in tests.\n */\nexport const testPathPolicy: TestPathPolicy = new TestPathPolicy();\n\n/**\n * Create test metadata with sensible defaults.\n */\nexport function testMetadata(\n\towner: string,\n\toverrides?: Partial<StoragePutMetadata>\n): StoragePutMetadata {\n\treturn({\n\t\towner,\n\t\ttags: [],\n\t\tvisibility: 'private',\n\t\t...overrides\n\t});\n}\n\n/**\n * Create test object metadata with sensible defaults.\n */\nexport function testObjectMetadata(\n\tpath: string,\n\towner: string,\n\toverrides?: Partial<StorageObjectMetadata>\n): StorageObjectMetadata {\n\treturn({\n\t\tpath,\n\t\towner,\n\t\ttags: [],\n\t\tvisibility: 'private',\n\t\tsize: 0,\n\t\tcreatedAt: new Date().toISOString(),\n\t\t...overrides\n\t});\n}\n\n// #endregion\n\n// #region Types\n\ntype StorageEntry = {\n\tdata: Buffer;\n\tmetadata: StorageObjectMetadata;\n};\n\ntype QuotaConfig = {\n\tmaxObjectsPerUser: number;\n\tmaxStoragePerUser: number;\n};\n\n// #endregion\n\n// #region Shared Storage Operations\n\nfunction putToStorage(\n\tstorage: Map<string, StorageEntry>,\n\tpath: string,\n\tdata: Buffer,\n\tmetadata: StoragePutMetadata\n): StorageObjectMetadata {\n\tconst now = new Date().toISOString();\n\tconst existing = storage.get(path);\n\tconst objectMetadata: StorageObjectMetadata = {\n\t\tpath,\n\t\towner: metadata.owner,\n\t\ttags: metadata.tags,\n\t\tvisibility: metadata.visibility,\n\t\tsize: data.length,\n\t\tcreatedAt: existing?.metadata.createdAt ?? now,\n\t\t...(existing ? { updatedAt: now } : {})\n\t};\n\n\tstorage.set(path, { data, metadata: objectMetadata });\n\treturn(objectMetadata);\n}\n\nfunction getFromStorage(\n\tstorage: Map<string, StorageEntry>,\n\tpath: string\n): StorageGetResult | null {\n\tconst entry = storage.get(path);\n\tif (!entry) {\n\t\treturn(null);\n\t}\n\n\treturn({\n\t\tdata: Buffer.from(entry.data),\n\t\tmetadata: { ...entry.metadata }\n\t});\n}\n\nfunction searchStorage(\n\tstorage: Map<string, StorageEntry>,\n\tcriteria: SearchCriteria,\n\tpagination: SearchPagination\n): SearchResults {\n\tconst results: StorageObjectMetadata[] = [];\n\tconst limit = pagination.limit ?? 100;\n\tconst startAfter = pagination.cursor;\n\tlet foundCursor = !startAfter;\n\n\tfor (const [path, entry] of storage.entries()) {\n\t\tif (!foundCursor) {\n\t\t\tif (path === startAfter) {\n\t\t\t\tfoundCursor = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst metadata = entry.metadata;\n\n\t\tif (criteria.pathPrefix) {\n\t\t\tconst prefix = criteria.pathPrefix.endsWith('/')\n\t\t\t\t? criteria.pathPrefix\n\t\t\t\t: criteria.pathPrefix + '/';\n\t\t\tif (!path.startsWith(prefix) && path !== criteria.pathPrefix) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!criteria.recursive) {\n\t\t\t\tconst remainder = path.slice(prefix.length);\n\t\t\t\tif (remainder.includes('/')) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.owner && metadata.owner !== criteria.owner) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (criteria.tags && criteria.tags.length > 0) {\n\t\t\tconst hasMatchingTag = criteria.tags.some(function(tag) {\n\t\t\t\treturn(metadata.tags.includes(tag));\n\t\t\t});\n\t\t\tif (!hasMatchingTag) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.name) {\n\t\t\tconst filename = path.split('/').pop();\n\t\t\tif (!filename?.includes(criteria.name)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (criteria.visibility && metadata.visibility !== criteria.visibility) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tresults.push(metadata);\n\n\t\tif (results.length >= limit) {\n\t\t\treturn({ results, nextCursor: path });\n\t\t}\n\t}\n\n\treturn({ results });\n}\n\nfunction computeQuotaStatus(\n\tstorage: Map<string, StorageEntry>,\n\towner: string,\n\tquotaConfig: QuotaConfig\n): QuotaStatus {\n\tlet objectCount = 0;\n\tlet totalSize = 0;\n\tfor (const entry of storage.values()) {\n\t\tif (entry.metadata.owner === owner) {\n\t\t\tobjectCount++;\n\n\t\t\ttotalSize += entry.metadata.size;\n\t\t}\n\t}\n\n\treturn({\n\t\tobjectCount,\n\t\ttotalSize,\n\t\tremainingObjects: Math.max(0, quotaConfig.maxObjectsPerUser - objectCount),\n\t\tremainingSize: Math.max(0, quotaConfig.maxStoragePerUser - totalSize)\n\t});\n}\n\n// #endregion\n\n// #region Memory Storage Backend\n\n/**\n * In-memory storage backend with full capabilities: CRUD, search, and quota management.\n * Intended for testing and development purposes.\n */\nexport class MemoryStorageBackend implements FullStorageBackend {\n\tprivate storage = new Map<string, StorageEntry>();\n\tprivate reservations = new Map<string, UploadReservation>();\n\treadonly #reservationsByPath = new Map<string, string>(); // \"owner:path\" -> reservationId\n\tprivate reservationCounter = 0;\n\treadonly #quotaLimitsPerUser = new Map<string, QuotaLimits>();\n\n\tprivate readonly quotaConfig: QuotaConfig = {\n\t\tmaxObjectsPerUser: 1000,\n\t\tmaxStoragePerUser: 100 * 1024 * 1024 // 100MB\n\t};\n\n\t/**\n\t * Prune expired reservations to keep quota accounting accurate.\n\t */\n\t#pruneExpiredReservations(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [id, reservation] of this.reservations) {\n\t\t\tif (new Date(reservation.expiresAt).getTime() <= now) {\n\t\t\t\tthis.reservations.delete(id);\n\t\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync put(path: string, data: Buffer, metadata: StoragePutMetadata): Promise<StorageObjectMetadata> {\n\t\treturn(putToStorage(this.storage, path, data, metadata));\n\t}\n\n\tasync get(path: string): Promise<StorageGetResult | null> {\n\t\treturn(getFromStorage(this.storage, path));\n\t}\n\n\tasync delete(path: string): Promise<boolean> {\n\t\treturn(this.storage.delete(path));\n\t}\n\n\tasync updateMetadata(path: string, metadata: Omit<StoragePutMetadata, 'owner'>): Promise<StorageObjectMetadata | null> {\n\t\tconst entry = this.storage.get(path);\n\t\tif (!entry) {\n\t\t\treturn(null);\n\t\t}\n\n\t\tconst now = new Date().toISOString();\n\t\tconst updated: StorageObjectMetadata = {\n\t\t\t...entry.metadata,\n\t\t\ttags: metadata.tags,\n\t\t\tvisibility: metadata.visibility,\n\t\t\tupdatedAt: now\n\t\t};\n\n\t\tthis.storage.set(path, { data: entry.data, metadata: updated });\n\t\treturn(updated);\n\t}\n\n\tasync search(criteria: SearchCriteria, pagination: SearchPagination): Promise<SearchResults> {\n\t\treturn(searchStorage(this.storage, criteria, pagination));\n\t}\n\n\tasync getQuotaStatus(owner: string): Promise<QuotaStatus> {\n\t\t// Prune expired reservations first\n\t\tthis.#pruneExpiredReservations();\n\n\t\t// Get base quota from actual storage\n\t\tconst baseQuota = computeQuotaStatus(this.storage, owner, this.quotaConfig);\n\n\t\t// Add pending reservations for this owner\n\t\tlet reservedObjects = 0;\n\t\tlet reservedSize = 0;\n\t\tfor (const reservation of this.reservations.values()) {\n\t\t\tif (reservation.owner === owner) {\n\t\t\t\t// Only count as new object if path doesn't exist\n\t\t\t\tif (!this.storage.has(reservation.path)) {\n\t\t\t\t\treservedObjects++;\n\t\t\t\t}\n\n\t\t\t\treservedSize += reservation.size;\n\t\t\t}\n\t\t}\n\n\t\tconst objectCount = baseQuota.objectCount + reservedObjects;\n\t\tconst totalSize = baseQuota.totalSize + reservedSize;\n\t\tconst remainingObjects = Math.max(0, (baseQuota.remainingObjects ?? 0) - reservedObjects);\n\t\tconst remainingSize = Math.max(0, (baseQuota.remainingSize ?? 0) - reservedSize);\n\t\treturn({\n\t\t\tobjectCount,\n\t\t\ttotalSize,\n\t\t\tremainingObjects,\n\t\t\tremainingSize\n\t\t});\n\t}\n\n\tasync getQuotaLimits(owner: string): Promise<QuotaLimits | null> {\n\t\treturn(this.#quotaLimitsPerUser.get(owner) ?? null);\n\t}\n\n\tsetQuotaLimits(owner: string, limits: QuotaLimits): void {\n\t\tthis.#quotaLimitsPerUser.set(owner, limits);\n\t}\n\n\tasync reserveUpload(owner: string, path: string, size: number, options?: {\n\t\tttlMs?: number;\n\t\tquotaLimits?: { maxObjectsPerUser: number; maxStoragePerUser: number };\n\t}): Promise<UploadReservation> {\n\t\t// Validate size parameter\n\t\tif (size < 0) {\n\t\t\tthrow(new Errors.InvariantViolation('Reservation size cannot be negative'));\n\t\t}\n\n\t\t// Prune expired reservations first\n\t\tthis.#pruneExpiredReservations();\n\n\t\t// Default TTL: 5 minutes\n\t\tconst DEFAULT_RESERVATION_TTL_MS = 5 * 60 * 1000;\n\t\tconst ttl = options?.ttlMs ?? DEFAULT_RESERVATION_TTL_MS;\n\n\t\t// Use provided quota limits or fall back to backend defaults\n\t\tconst limits = options?.quotaLimits ?? this.quotaConfig;\n\n\t\t// Check if this would exceed quota\n\t\tconst quotaStatus = await this.getQuotaStatus(owner);\n\t\tconst isNewObject = !this.storage.has(path);\n\t\tconst existingSize = this.storage.get(path)?.data.length ?? 0;\n\t\tconst sizeDelta = size - existingSize;\n\n\t\t// Calculate remaining based on provided limits\n\t\tconst remainingObjects = limits.maxObjectsPerUser - quotaStatus.objectCount;\n\t\tconst remainingSize = limits.maxStoragePerUser - quotaStatus.totalSize;\n\n\t\tif (isNewObject && remainingObjects <= 0) {\n\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\tquotaType: 'maxObjectsPerUser',\n\t\t\t\tlimit: limits.maxObjectsPerUser,\n\t\t\t\tcurrent: quotaStatus.objectCount\n\t\t\t}));\n\t\t}\n\n\t\tif (sizeDelta > 0 && remainingSize < sizeDelta) {\n\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\tquotaType: 'maxStoragePerUser',\n\t\t\t\tlimit: limits.maxStoragePerUser,\n\t\t\t\tcurrent: quotaStatus.totalSize + sizeDelta\n\t\t\t}));\n\t\t}\n\n\t\t// Check for existing reservation for this (owner, path)\n\t\t// If a reservation already exists, we calculate the additional quota needed\n\t\t// by comparing the new sizeDelta with the existing reservation's reserved size.\n\t\tconst pathKey = `${owner}:${path}`;\n\t\tconst existingId = this.#reservationsByPath.get(pathKey);\n\t\tif (existingId) {\n\t\t\tconst existing = this.reservations.get(existingId);\n\t\t\tif (existing) {\n\t\t\t\tconst clampedSizeDelta = Math.max(0, sizeDelta);\n\t\t\t\tconst additionalSize = clampedSizeDelta - existing.size;\n\n\t\t\t\t// Re-check quota if size is increasing beyond current reservation\n\t\t\t\tif (additionalSize > 0 && remainingSize < additionalSize) {\n\t\t\t\t\tthrow(new Errors.QuotaExceeded({\n\t\t\t\t\t\tquotaType: 'maxStoragePerUser',\n\t\t\t\t\t\tlimit: limits.maxStoragePerUser,\n\t\t\t\t\t\tcurrent: quotaStatus.totalSize + additionalSize\n\t\t\t\t\t}));\n\t\t\t\t}\n\n\t\t\t\t// Update to max size, extend expiry\n\t\t\t\texisting.size = Math.max(existing.size, clampedSizeDelta);\n\t\t\t\texisting.expiresAt = new Date(Date.now() + ttl).toISOString();\n\t\t\t\treturn(existing);\n\t\t\t}\n\t\t}\n\n\t\tconst now = new Date();\n\t\tconst reservation: UploadReservation = {\n\t\t\tid: `res_${++this.reservationCounter}`,\n\t\t\towner,\n\t\t\tpath,\n\t\t\tsize: Math.max(0, sizeDelta),\n\t\t\tcreatedAt: now.toISOString(),\n\t\t\texpiresAt: new Date(now.getTime() + ttl).toISOString()\n\t\t};\n\n\t\tthis.reservations.set(reservation.id, reservation);\n\t\tthis.#reservationsByPath.set(pathKey, reservation.id);\n\t\treturn(reservation);\n\t}\n\n\tasync commitUpload(reservationId: string): Promise<void> {\n\t\t// Simply remove the reservation - the actual storage was already updated via put()\n\t\tconst reservation = this.reservations.get(reservationId);\n\t\tif (reservation) {\n\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t}\n\n\t\tthis.reservations.delete(reservationId);\n\t}\n\n\tasync releaseUpload(reservationId: string): Promise<void> {\n\t\t// Remove the reservation, freeing the reserved quota\n\t\tconst reservation = this.reservations.get(reservationId);\n\t\tif (reservation) {\n\t\t\tthis.#reservationsByPath.delete(`${reservation.owner}:${reservation.path}`);\n\t\t}\n\n\t\tthis.reservations.delete(reservationId);\n\t}\n\n\tclear(): void {\n\t\tthis.storage.clear();\n\t\tthis.reservations.clear();\n\t\tthis.#reservationsByPath.clear();\n\t}\n\n\tget size(): number {\n\t\treturn(this.storage.size);\n\t}\n}\n\n// #endregion\n\n// #region Shared Test Harness\n\nexport type Account = InstanceType<typeof KeetaNet.lib.Account>;\n\nexport function randomSeed(): string | ArrayBuffer {\n\treturn(KeetaNet.lib.Account.generateRandomSeed());\n}\n\nexport interface StorageProviderTestContext {\n\tprovider: KeetaStorageAnchorProvider;\n\taccount: Account;\n\tstorageClient: KeetaStorageAnchorClient;\n}\n\n/**\n * Shared test harness that stands up a storage server, resolves a provider,\n * and passes the provider context to the test function.\n */\nexport async function withStorageProvider(\n\tseed: string | ArrayBuffer,\n\ttestFunction: (ctx: StorageProviderTestContext) => Promise<void>\n): Promise<void> {\n\tconst account = KeetaNet.lib.Account.fromSeed(seed, 0);\n\tconst anchorAccount = KeetaNet.lib.Account.fromSeed(seed, 50);\n\n\tawait using nodeAndClient = await createNodeAndClient(account);\n\n\tconst userClient = nodeAndClient.userClient;\n\tnodeAndClient.fees.disable();\n\n\tconst backend = new MemoryStorageBackend();\n\n\tawait using server = new KeetaNetStorageAnchorHTTPServer({\n\t\tbackend,\n\t\tanchorAccount,\n\t\tpathPolicies: [testPathPolicy]\n\t});\n\n\tawait server.start();\n\n\tconst rootAccount = KeetaNet.lib.Account.fromSeed(seed, 100);\n\tconst serviceMetadata = await server.serviceMetadata();\n\n\tawait setResolverInfo(rootAccount, userClient, {\n\t\tversion: 1,\n\t\tcurrencyMap: {},\n\t\tservices: {\n\t\t\tstorage: {\n\t\t\t\t'test-provider': serviceMetadata\n\t\t\t}\n\t\t}\n\t});\n\n\tconst resolver = new KeetaAnchorResolver({\n\t\troot: rootAccount,\n\t\tclient: userClient,\n\t\ttrustedCAs: []\n\t});\n\n\tconst storageClient = new KeetaStorageAnchorClient(userClient, { resolver });\n\tconst maybeProvider = await storageClient.getProviderByID('test-provider');\n\tif (!maybeProvider) {\n\t\tthrow(new Error('Provider not found'));\n\t}\n\n\tawait testFunction({ provider: maybeProvider, account, storageClient });\n}\n\n// #endregion\n"]}