Docs/Reference/API Reference

    API Reference

    Complete TypeScript API surface for the S3WORM ecosystem.


    @decoperations/s3worm

    The core package. Provides the ORM client, entities, repositories, schema-driven models, ACLs, keychain, and access tokens.

    S3Worm

    The main entry point for all operations.

    import { S3Worm } from "@decoperations/s3worm";
    

    Constructor

    const worm = new S3Worm(config: S3WormConfig);
    
    interface S3WormConfig {
      /** S3 bucket name */
      bucket: string;
      /** AWS region */
      region?: string;
      /** S3 endpoint URL */
      endpoint?: string;
      /** AWS credentials */
      credentials?: {
        accessKeyId: string;
        secretAccessKey: string;
      };
      /** Optional keychain for credential + identity management */
      keychain?: Keychain;
      /** Optional access token for token-based auth */
      token?: AccessTokenData;
      /** Optional signing key for token creation */
      signingKey?: string;
    }
    

    Document Operations

    // Create a document (throws if path already exists)
    await worm.create(path: string, data: any): Promise<void>;
    
    // Read a document
    await worm.read<T>(path: string): Promise<T | null>;
    
    // Update a document (throws if path does not exist)
    await worm.update(path: string, data: any): Promise<void>;
    
    // Upsert a document (create or update)
    await worm.save(path: string, data: any): Promise<void>;
    
    // Delete a document
    await worm.delete(path: string): Promise<void>;
    
    // Check if a document exists
    await worm.exists(path: string): Promise<boolean>;
    
    // List all keys under a prefix
    await worm.list(prefix: string): Promise<string[]>;
    
    // List keys with metadata
    await worm.listWithMetadata(prefix: string): Promise<WormListEntry[]>;
    
    // Get object metadata
    await worm.headObject(key: string): Promise<{
      size: number;
      contentType: string;
      lastModifiedIso: string;
      etag?: string;
    }>;
    
    // Get a public URL for a key
    worm.getPublicUrl(key: string): string | undefined;
    

    Binary Operations

    // Upload raw bytes
    await worm.putBytes(
      key: string,
      data: Uint8Array | ArrayBuffer | Blob,
      contentType: string,
      options?: PutBytesOptions
    ): Promise<{ url?: string }>;
    
    // Low-level string get/put
    await worm.getString(entity: WormEntity): Promise<string | null>;
    await worm.putString(entity: WormEntity, data: string): Promise<void>;
    await worm.getJSON<T>(entity: WormEntity): Promise<T | null>;
    await worm.putJSON(entity: WormEntity, data: any): Promise<void>;
    

    Schema Operations

    // Load a schema from file path or object
    worm.loadSchema(pathOrSchema: string | WormSchemaConfig): void;
    
    // Get a schema-driven repository
    worm.model(name: string): SchemaRepository;
    
    // Get a pre-configured view
    worm.view(name: string): { findAll(overrides?: Record<string, unknown>): Promise<SchemaEntity[]> };
    
    // Get model names
    worm.getModelNames(): string[];
    
    // Get the loaded schema
    worm.getSchema(): WormSchemaConfig | undefined;
    

    ACL Operations

    // Get the resolved principal
    await worm.getPrincipal(): Promise<Principal>;
    
    // Set principal explicitly
    worm.setPrincipal(principal: Principal): void;
    
    // Clear cached principal
    worm.clearPrincipal(): void;
    
    // Dry-run ACL check
    await worm.checkAccess(
      modelName: string,
      operation: AclOperation,
      entityId?: string
    ): Promise<{ allowed: boolean; reason?: AclDenyReason }>;
    
    // Enforce ACL (throws AclDeniedError on deny)
    await worm.enforceAccess(
      modelName: string,
      operation: AclOperation,
      entityId?: string
    ): Promise<void>;
    
    // Get the ACL evaluator
    worm.getAclEvaluator(): AclEvaluator;
    
    // Get the keychain
    worm.getKeychain(): Keychain | undefined;
    

    Token Operations

    // Create a scoped access token
    await worm.createAccessToken(options: {
      subject: string;
      permissions: TokenPermission[];
      expiresIn?: string;
      expiresAt?: string;
    }): Promise<AccessTokenData>;
    
    // Verify a token
    await worm.verifyAccessToken(token: AccessTokenData): Promise<{
      valid: boolean;
      reason?: string;
    }>;
    
    // Revoke a token
    await worm.revokeAccessToken(tokenId: string): Promise<void>;
    

    Class-Based Repository

    // Get a repository for a hand-written Entity class
    worm.getRepository<T extends Entity>(entityClass: EntityConstructor<T>): Repository<T>;
    

    Entity

    Base class for hand-written entity types.

    import { Entity } from "@decoperations/s3worm";
    
    class BlogPost extends Entity {
      title: string = "";
      content: string = "";
    
      static getBasePath(): string {
        return "posts";
      }
    }
    

    Properties

    PropertyTypeDescription
    idstringEntity ID (auto-generated on save)
    createdAtstring?ISO 8601 creation timestamp
    updatedAtstring?ISO 8601 last-modified timestamp

    Methods

    MethodReturnsDescription
    static getBasePath()stringS3 prefix for this entity type
    getFileName()stringFilename ({id}.json by default)
    getPath()stringFull S3 key (basePath/fileName)
    clone()thisShallow clone
    toJSON()objectPlain object (for JSON.stringify)
    toObject()objectPlain object
    beforeSave()voidSets timestamps (called automatically)

    Static Helpers

    Entity.forUser(address: string, filename: string): WormEntity;
    Entity.forCollection(address: string, collection: string): WormEntity;
    Entity.parse(key: string): WormEntity;
    

    Repository

    Class-based CRUD repository for hand-written Entity types.

    const repo = worm.getRepository(BlogPost);
    
    MethodSignatureDescription
    findById(id: string) => Promise<T | null>Find entity by ID
    findAll(options?: FindAllOptions<T>) => Promise<T[]>Find all with filter/sort/pagination
    save(entity: T) => Promise<T>Save entity (auto-generates ID)
    delete(entityOrId: T | string) => Promise<boolean>Delete entity
    create(data?: Partial<T>) => TCreate instance without saving
    interface FindAllOptions<T> {
      filter?: (item: T) => boolean;
      sort?: (a: T, b: T) => number;
      limit?: number;
      offset?: number;
    }
    

    SchemaRepository

    Schema-driven repository returned by worm.model(). Provides typed CRUD, validation, filtering, aggregation, entity links, and more.

    const customers = worm.model("Customer");
    

    CRUD

    // Create an entity instance (does not persist)
    customers.create(data: Record<string, unknown>): SchemaEntity;
    
    // Save (create or update)
    await customers.save(entity: SchemaEntity, options?: { actor?: string }): Promise<SchemaEntity>;
    
    // Find by ID
    await customers.findById(id: string, options?: {
      select?: string[];
      populate?: PopulateSpec;
    }): Promise<SchemaEntity | null>;
    
    // Find all with query options
    await customers.findAll(options?: {
      filter?: Record<string, unknown>;
      sort?: { field: string; order: "asc" | "desc" };
      limit?: number;
      offset?: number;
      select?: string[];
      populate?: PopulateSpec;
    }): Promise<SchemaEntity[]>;
    
    // Count entities
    await customers.count(filter?: Record<string, unknown>): Promise<number>;
    
    // Check existence
    await customers.exists(id: string): Promise<boolean>;
    
    // Delete
    await customers.delete(id: string, options?: { actor?: string }): Promise<boolean>;
    

    Soft Delete

    await customers.listTrashed(): Promise<SchemaEntity[]>;
    await customers.restore(id: string): Promise<SchemaEntity | null>;
    await customers.purge(id: string): Promise<boolean>;
    await customers.purgeExpired(): Promise<number>;
    

    Oplog

    await customers.getHistory(id: string): Promise<OplogEntry[]>;
    await customers.rollback(id: string, options: { toSeq: number }): Promise<SchemaEntity | null>;
    

    Snapshots

    await customers.snapshot(id: string): Promise<void>;
    await customers.listSnapshots(id: string): Promise<{ ts: string; size: number }[]>;
    await customers.restoreSnapshot(id: string, ts: string): Promise<SchemaEntity | null>;
    

    Entity Links

    await customers.findRelated(id: string, refName: string, options?: FindRelatedOptions): Promise<SchemaEntity[]>;
    await customers.populate(entity: SchemaEntity, spec: PopulateSpec): Promise<SchemaEntity>;
    

    Aggregation

    await customers.aggregate(options: AggregateOptions): Promise<AggregateResult>;
    

    Properties

    PropertyTypeDescription
    modeAccessMode"readonly" | "readwrite" | "append"
    schemaModelDefinitionThe model definition from schema.json

    Core Types

    WormListEntry

    interface WormListEntry {
      key: string;
      size: number;
      contentType: string;
      lastModifiedIso: string;
    }
    

    PutBytesOptions

    interface PutBytesOptions {
      onProgress?: (percentage: number) => void;
    }
    

    S3WormOptions

    interface S3WormOptions {
      bucketName: string;
      region?: string;
      credentials?: any;
      endpoint?: string;
    }
    

    Schema Types

    WormSchemaConfig

    interface WormSchemaConfig {
      schemaVersion: string;
      sourceOfTruth: "local" | "remote" | "bidirectional" | string;
      symbols?: Record<string, string>;
      dynamicTypes?: Record<string, DynamicTypeDefinition>;
      operators?: Record<string, OperatorDefinition>;
      storage?: StorageConfig;
      paths?: string[];
      models?: Record<string, ModelDefinition>;
      views?: Record<string, ViewDefinition>;
      rules?: Record<string, WormRule>;
      acl?: BucketAcl;
    }
    

    ModelDefinition

    interface ModelDefinition {
      path: string;
      idType?: string;
      fields: Record<string, FieldDefinition>;
      file: string;
      mode?: AccessMode;             // "readonly" | "readwrite" | "append"
      singleton?: boolean;
      oplog?: boolean;
      softDelete?: boolean;
      snapshots?: SnapshotConfig;
      refs?: Record<string, RefDefinition>;
      integrity?: IntegrityConfig;
      manifest?: ManifestConfig;
      indexes?: Record<string, IndexDefinition>;
      acl?: ModelAcl;
    }
    

    FieldDefinition

    interface FieldDefinition {
      type: FieldType;               // "string" | "number" | "boolean" | "datetime" | "object" | "string[]" | "number[]" | "object[]"
      required?: boolean;
      enum?: string[];
      default?: unknown;
      ref?: string;
      auto?: boolean;
      embedded?: boolean;
      encrypted?: boolean;
      acl?: string[];
    }
    

    WormRule

    interface WormRule {
      applyTo?: string;
      acl?: string | ModelAcl;
      scope?: string;
      validator?: string;
      onWrite?: string;
      [key: string]: unknown;
    }
    

    ACL Types

    Principal Types

    interface Principal {
      id: string;
      name?: string;
      type: "user" | "service" | "anonymous";
      roles?: string[];
    }
    
    interface UserPrincipal extends Principal {
      type: "user";
      identity:
        | { method: "evm"; address: string }
        | { method: "solana"; address: string }
        | { method: "email"; email: string };
    }
    
    interface ServicePrincipal extends Principal {
      type: "service";
      keyId: string;
    }
    
    interface AnonymousPrincipal extends Principal {
      type: "anonymous";
      id: "anonymous";
    }
    

    BucketAcl

    interface BucketAcl {
      defaultPolicy: "deny" | "allow";
      principals?: Record<string, PrincipalDefinition>;
      grants?: BucketGrant[];
      accessLog?: AccessLogConfig;
    }
    

    ModelAcl

    interface ModelAcl {
      read?: string[];
      write?: string[];
      delete?: string[];
      list?: string[];
    }
    

    AclDenyReason

    type AclDenyReason =
      | { layer: "mode"; model: string; mode: AccessMode; operation: string }
      | { layer: "bucket"; principal: string; operation: string; policy: string }
      | { layer: "model"; principal: string; model: string; operation: string }
      | { layer: "entity"; principal: string; rule: string; scope: string }
      | { layer: "token"; principal: string; operation: string; reason: string };
    

    AccessTokenData

    interface AccessTokenData {
      id: string;
      issuer: string;
      subject: string;
      permissions: TokenPermission[];
      issuedAt: string;
      expiresAt: string;
      signature: string;
    }
    
    interface TokenPermission {
      model: string;
      operations: AclOperation[];
      ids?: string[];
      filter?: Record<string, unknown>;
    }
    

    Link Types

    RefDefinition

    interface RefDefinition {
      field?: string;
      model: string;
      foreignKey?: string;
      type: "belongsTo" | "hasMany" | "hasOne";
      onDelete?: "cascade" | "nullify" | "restrict" | "none";
      through?: ThroughConfig;
      index?: boolean;
      eager?: boolean;
    }
    

    PopulateSpec

    type PopulateSpec = string[] | Record<string, true | PopulateRefOptions>;
    
    interface PopulateRefOptions {
      populate?: PopulateSpec;
      select?: string[];
    }
    

    Manifest Types

    ManifestConfig

    interface ManifestConfig {
      enabled: boolean;
      fields?: string[];
      autoUpdate?: boolean;
      partitionThreshold?: number;
      maxPartitions?: number;
    }
    

    IndexDefinition

    interface IndexDefinition {
      field: string;
      unique?: boolean;
      type?: "standard" | "multiValue";
    }
    

    AggregateOptions

    interface AggregateOptions {
      groupBy?: string;
      count?: boolean;
      sum?: string;
      avg?: string;
      min?: string;
      max?: string;
      filter?: Record<string, unknown>;
    }
    

    @decoperations/bucket-sync

    Exports from main entry

    import {
      LocalBucket,
      BlobStore,
      ManifestDB,
      SyncEngine,
      CacheManager,
      TabCoordinator,
      CryptoManager,
      hashBlob,
      hashBuffer,
    } from "@decoperations/bucket-sync";
    

    Exports from service-worker entry

    import {
      registerBucketSW,
      unregisterBucketSW,
    } from "@decoperations/bucket-sync/service-worker";
    

    @decoperations/s3worm-gateway

    Exports from main entry

    import {
      Gateway,
      GatewayError,
      resolveAuth,
      AuthError,
    } from "@decoperations/s3worm-gateway";
    
    import type {
      GatewayConfig,
      CorsConfig,
      OperationContext,
      ParsedQuery,
      GatewayRequest,
      GatewayResponse,
      AuthConfig,
      JwtAuthConfig,
      ApiKeyAuthConfig,
      AuthResult,
      JwtClaims,
    } from "@decoperations/s3worm-gateway";
    

    Exports from nextjs entry

    import {
      createWormHandler,
      createModelHandlers,
      createEntityHandlers,
    } from "@decoperations/s3worm-gateway/nextjs";
    
    import type {
      NextRouteHandler,
      WormHandlerOptions,
    } from "@decoperations/s3worm-gateway/nextjs";
    

    Export Paths

    PackageEntryDescription
    @decoperations/s3wormmainCore ORM client, entities, types
    @decoperations/s3worm/server/serverServer-only utilities
    @decoperations/s3worm/edge/edgeEdge runtime utilities
    @decoperations/bucket-syncmainLocalBucket, SyncEngine, CryptoManager
    @decoperations/bucket-sync/service-worker/service-workerSW registration and bucket SW
    @decoperations/s3worm-gatewaymainGateway, auth resolvers
    @decoperations/s3worm-gateway/nextjs/nextjsNext.js App Router adapter