@contractspec/lib.files 1.46.2 → 1.48.0

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 +1 @@
1
- {"version":3,"file":"index.js","names":["filesSchemaContribution: ModuleSchemaContribution"],"sources":["../../src/entities/index.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\nimport type { ModuleSchemaContribution } from '@contractspec/lib.schema';\n\n/**\n * Storage provider enum.\n */\nexport const StorageProviderEnum = defineEntityEnum({\n name: 'StorageProvider',\n values: ['LOCAL', 'S3', 'GCS', 'AZURE', 'CLOUDFLARE'] as const,\n schema: 'lssm_files',\n description: 'Storage backend provider.',\n});\n\n/**\n * File status enum.\n */\nexport const FileStatusEnum = defineEntityEnum({\n name: 'FileStatus',\n values: [\n 'PENDING',\n 'UPLOADED',\n 'PROCESSING',\n 'READY',\n 'ERROR',\n 'DELETED',\n ] as const,\n schema: 'lssm_files',\n description: 'File processing status.',\n});\n\n/**\n * File entity - represents an uploaded file.\n */\nexport const FileEntity = defineEntity({\n name: 'File',\n description: 'An uploaded file.',\n schema: 'lssm_files',\n map: 'file',\n fields: {\n id: field.id({ description: 'Unique file identifier' }),\n\n // File info\n name: field.string({ description: 'Original file name' }),\n mimeType: field.string({ description: 'MIME type' }),\n size: field.int({ description: 'File size in bytes' }),\n\n // Storage\n storageProvider: field.enum('StorageProvider', {\n default: 'LOCAL',\n description: 'Storage backend',\n }),\n storagePath: field.string({ description: 'Path in storage backend' }),\n storageKey: field.string({\n isOptional: true,\n description: 'Storage key/bucket',\n }),\n\n // Integrity\n checksum: field.string({\n isOptional: true,\n description: 'SHA-256 checksum',\n }),\n etag: field.string({ isOptional: true, description: 'Storage ETag' }),\n\n // Status\n status: field.enum('FileStatus', {\n default: 'PENDING',\n description: 'File status',\n }),\n\n // Access\n isPublic: field.boolean({\n default: false,\n description: 'Whether file is publicly accessible',\n }),\n expiresAt: field.dateTime({\n isOptional: true,\n description: 'Auto-delete timestamp',\n }),\n\n // Ownership\n ownerId: field.string({ description: 'User who uploaded' }),\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope',\n }),\n\n // Metadata\n metadata: field.json({\n isOptional: true,\n description: 'Additional metadata',\n }),\n tags: field.json({\n isOptional: true,\n description: 'Tags for categorization',\n }),\n\n // Image-specific\n width: field.int({\n isOptional: true,\n description: 'Image width in pixels',\n }),\n height: field.int({\n isOptional: true,\n description: 'Image height in pixels',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n versions: field.hasMany('FileVersion'),\n attachments: field.hasMany('Attachment'),\n },\n indexes: [\n index.on(['ownerId']),\n index.on(['orgId']),\n index.on(['status']),\n index.on(['mimeType']),\n index.on(['storageProvider', 'storagePath']),\n ],\n enums: [StorageProviderEnum, FileStatusEnum],\n});\n\n/**\n * FileVersion entity - version history for files.\n */\nexport const FileVersionEntity = defineEntity({\n name: 'FileVersion',\n description: 'A version of a file.',\n schema: 'lssm_files',\n map: 'file_version',\n fields: {\n id: field.id({ description: 'Unique version identifier' }),\n fileId: field.foreignKey({ description: 'Parent file' }),\n\n // Version info\n version: field.int({ description: 'Version number' }),\n size: field.int({ description: 'Version size in bytes' }),\n\n // Storage\n storagePath: field.string({ description: 'Path in storage backend' }),\n checksum: field.string({\n isOptional: true,\n description: 'SHA-256 checksum',\n }),\n\n // Metadata\n comment: field.string({ isOptional: true, description: 'Version comment' }),\n changes: field.json({\n isOptional: true,\n description: 'Change description',\n }),\n\n // Creator\n createdBy: field.string({ description: 'User who created version' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n\n // Relations\n file: field.belongsTo('File', ['fileId'], ['id'], { onDelete: 'Cascade' }),\n },\n indexes: [\n index.on(['fileId', 'version']),\n index.unique(['fileId', 'version'], { name: 'file_version_unique' }),\n ],\n});\n\n/**\n * Attachment entity - polymorphic link between files and entities.\n */\nexport const AttachmentEntity = defineEntity({\n name: 'Attachment',\n description: 'Links a file to an entity.',\n schema: 'lssm_files',\n map: 'attachment',\n fields: {\n id: field.id({ description: 'Unique attachment identifier' }),\n fileId: field.foreignKey({ description: 'Attached file' }),\n\n // Target entity (polymorphic)\n entityType: field.string({\n description: 'Target entity type (deal, listing, etc.)',\n }),\n entityId: field.string({ description: 'Target entity ID' }),\n\n // Attachment metadata\n attachmentType: field.string({\n isOptional: true,\n description: 'Type of attachment (document, image, avatar, etc.)',\n }),\n name: field.string({\n isOptional: true,\n description: 'Display name (overrides file name)',\n }),\n description: field.string({\n isOptional: true,\n description: 'Attachment description',\n }),\n\n // Ordering\n order: field.int({ default: 0, description: 'Display order' }),\n\n // Metadata\n metadata: field.json({\n isOptional: true,\n description: 'Attachment-specific metadata',\n }),\n\n // Creator\n createdBy: field.string({ description: 'User who created attachment' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n file: field.belongsTo('File', ['fileId'], ['id'], { onDelete: 'Cascade' }),\n },\n indexes: [\n index.on(['entityType', 'entityId']),\n index.on(['fileId']),\n index.on(['entityType', 'entityId', 'attachmentType']),\n index.unique(['fileId', 'entityType', 'entityId'], {\n name: 'attachment_unique',\n }),\n ],\n});\n\n/**\n * UploadSession entity - tracks multipart uploads.\n */\nexport const UploadSessionEntity = defineEntity({\n name: 'UploadSession',\n description: 'Tracks a multipart upload session.',\n schema: 'lssm_files',\n map: 'upload_session',\n fields: {\n id: field.id({ description: 'Unique session identifier' }),\n\n // File info\n fileName: field.string({ description: 'Target file name' }),\n mimeType: field.string({ description: 'Expected MIME type' }),\n totalSize: field.int({ description: 'Total file size' }),\n\n // Upload state\n uploadId: field.string({\n isOptional: true,\n description: 'Storage upload ID',\n }),\n uploadedBytes: field.int({\n default: 0,\n description: 'Bytes uploaded so far',\n }),\n uploadedParts: field.json({\n isOptional: true,\n description: 'Completed part info',\n }),\n\n // Status\n status: field.string({\n default: '\"pending\"',\n description: 'Session status',\n }),\n error: field.string({\n isOptional: true,\n description: 'Error message if failed',\n }),\n\n // Result\n fileId: field.string({\n isOptional: true,\n description: 'Resulting file ID',\n }),\n\n // Context\n ownerId: field.string({ description: 'User who initiated upload' }),\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope',\n }),\n\n // Expiry\n expiresAt: field.dateTime({ description: 'Session expiry time' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n },\n indexes: [index.on(['status', 'expiresAt']), index.on(['ownerId'])],\n});\n\n/**\n * All file entities for schema composition.\n */\nexport const fileEntities = [\n FileEntity,\n FileVersionEntity,\n AttachmentEntity,\n UploadSessionEntity,\n];\n\n/**\n * Module schema contribution for files.\n */\nexport const filesSchemaContribution: ModuleSchemaContribution = {\n moduleId: '@contractspec/lib.files',\n entities: fileEntities,\n enums: [StorageProviderEnum, FileStatusEnum],\n};\n"],"mappings":";;;;;;AAWA,MAAa,sBAAsB,iBAAiB;CAClD,MAAM;CACN,QAAQ;EAAC;EAAS;EAAM;EAAO;EAAS;EAAa;CACrD,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,iBAAiB,iBAAiB;CAC7C,MAAM;CACN,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,aAAa,aAAa;CACrC,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,0BAA0B,CAAC;EAGvD,MAAM,MAAM,OAAO,EAAE,aAAa,sBAAsB,CAAC;EACzD,UAAU,MAAM,OAAO,EAAE,aAAa,aAAa,CAAC;EACpD,MAAM,MAAM,IAAI,EAAE,aAAa,sBAAsB,CAAC;EAGtD,iBAAiB,MAAM,KAAK,mBAAmB;GAC7C,SAAS;GACT,aAAa;GACd,CAAC;EACF,aAAa,MAAM,OAAO,EAAE,aAAa,2BAA2B,CAAC;EACrE,YAAY,MAAM,OAAO;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,UAAU,MAAM,OAAO;GACrB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,MAAM,MAAM,OAAO;GAAE,YAAY;GAAM,aAAa;GAAgB,CAAC;EAGrE,QAAQ,MAAM,KAAK,cAAc;GAC/B,SAAS;GACT,aAAa;GACd,CAAC;EAGF,UAAU,MAAM,QAAQ;GACtB,SAAS;GACT,aAAa;GACd,CAAC;EACF,WAAW,MAAM,SAAS;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,SAAS,MAAM,OAAO,EAAE,aAAa,qBAAqB,CAAC;EAC3D,OAAO,MAAM,OAAO;GAClB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,UAAU,MAAM,KAAK;GACnB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,MAAM,MAAM,KAAK;GACf,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,OAAO,MAAM,IAAI;GACf,YAAY;GACZ,aAAa;GACd,CAAC;EACF,QAAQ,MAAM,IAAI;GAChB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,UAAU,MAAM,QAAQ,cAAc;EACtC,aAAa,MAAM,QAAQ,aAAa;EACzC;CACD,SAAS;EACP,MAAM,GAAG,CAAC,UAAU,CAAC;EACrB,MAAM,GAAG,CAAC,QAAQ,CAAC;EACnB,MAAM,GAAG,CAAC,SAAS,CAAC;EACpB,MAAM,GAAG,CAAC,WAAW,CAAC;EACtB,MAAM,GAAG,CAAC,mBAAmB,cAAc,CAAC;EAC7C;CACD,OAAO,CAAC,qBAAqB,eAAe;CAC7C,CAAC;;;;AAKF,MAAa,oBAAoB,aAAa;CAC5C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,6BAA6B,CAAC;EAC1D,QAAQ,MAAM,WAAW,EAAE,aAAa,eAAe,CAAC;EAGxD,SAAS,MAAM,IAAI,EAAE,aAAa,kBAAkB,CAAC;EACrD,MAAM,MAAM,IAAI,EAAE,aAAa,yBAAyB,CAAC;EAGzD,aAAa,MAAM,OAAO,EAAE,aAAa,2BAA2B,CAAC;EACrE,UAAU,MAAM,OAAO;GACrB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,SAAS,MAAM,OAAO;GAAE,YAAY;GAAM,aAAa;GAAmB,CAAC;EAC3E,SAAS,MAAM,KAAK;GAClB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,OAAO,EAAE,aAAa,4BAA4B,CAAC;EAGpE,WAAW,MAAM,WAAW;EAG5B,MAAM,MAAM,UAAU,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,UAAU,WAAW,CAAC;EAC3E;CACD,SAAS,CACP,MAAM,GAAG,CAAC,UAAU,UAAU,CAAC,EAC/B,MAAM,OAAO,CAAC,UAAU,UAAU,EAAE,EAAE,MAAM,uBAAuB,CAAC,CACrE;CACF,CAAC;;;;AAKF,MAAa,mBAAmB,aAAa;CAC3C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,gCAAgC,CAAC;EAC7D,QAAQ,MAAM,WAAW,EAAE,aAAa,iBAAiB,CAAC;EAG1D,YAAY,MAAM,OAAO,EACvB,aAAa,4CACd,CAAC;EACF,UAAU,MAAM,OAAO,EAAE,aAAa,oBAAoB,CAAC;EAG3D,gBAAgB,MAAM,OAAO;GAC3B,YAAY;GACZ,aAAa;GACd,CAAC;EACF,MAAM,MAAM,OAAO;GACjB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,aAAa,MAAM,OAAO;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,OAAO,MAAM,IAAI;GAAE,SAAS;GAAG,aAAa;GAAiB,CAAC;EAG9D,UAAU,MAAM,KAAK;GACnB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,OAAO,EAAE,aAAa,+BAA+B,CAAC;EAGvE,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,MAAM,MAAM,UAAU,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,UAAU,WAAW,CAAC;EAC3E;CACD,SAAS;EACP,MAAM,GAAG,CAAC,cAAc,WAAW,CAAC;EACpC,MAAM,GAAG,CAAC,SAAS,CAAC;EACpB,MAAM,GAAG;GAAC;GAAc;GAAY;GAAiB,CAAC;EACtD,MAAM,OAAO;GAAC;GAAU;GAAc;GAAW,EAAE,EACjD,MAAM,qBACP,CAAC;EACH;CACF,CAAC;;;;AAKF,MAAa,sBAAsB,aAAa;CAC9C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,6BAA6B,CAAC;EAG1D,UAAU,MAAM,OAAO,EAAE,aAAa,oBAAoB,CAAC;EAC3D,UAAU,MAAM,OAAO,EAAE,aAAa,sBAAsB,CAAC;EAC7D,WAAW,MAAM,IAAI,EAAE,aAAa,mBAAmB,CAAC;EAGxD,UAAU,MAAM,OAAO;GACrB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,eAAe,MAAM,IAAI;GACvB,SAAS;GACT,aAAa;GACd,CAAC;EACF,eAAe,MAAM,KAAK;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,QAAQ,MAAM,OAAO;GACnB,SAAS;GACT,aAAa;GACd,CAAC;EACF,OAAO,MAAM,OAAO;GAClB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,QAAQ,MAAM,OAAO;GACnB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,SAAS,MAAM,OAAO,EAAE,aAAa,6BAA6B,CAAC;EACnE,OAAO,MAAM,OAAO;GAClB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,SAAS,EAAE,aAAa,uBAAuB,CAAC;EAGjE,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAC7B;CACD,SAAS,CAAC,MAAM,GAAG,CAAC,UAAU,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;CACpE,CAAC;;;;AAKF,MAAa,eAAe;CAC1B;CACA;CACA;CACA;CACD;;;;AAKD,MAAaA,0BAAoD;CAC/D,UAAU;CACV,UAAU;CACV,OAAO,CAAC,qBAAqB,eAAe;CAC7C"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/entities/index.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\nimport type { ModuleSchemaContribution } from '@contractspec/lib.schema';\n\n/**\n * Storage provider enum.\n */\nexport const StorageProviderEnum = defineEntityEnum({\n name: 'StorageProvider',\n values: ['LOCAL', 'S3', 'GCS', 'AZURE', 'CLOUDFLARE'] as const,\n schema: 'lssm_files',\n description: 'Storage backend provider.',\n});\n\n/**\n * File status enum.\n */\nexport const FileStatusEnum = defineEntityEnum({\n name: 'FileStatus',\n values: [\n 'PENDING',\n 'UPLOADED',\n 'PROCESSING',\n 'READY',\n 'ERROR',\n 'DELETED',\n ] as const,\n schema: 'lssm_files',\n description: 'File processing status.',\n});\n\n/**\n * File entity - represents an uploaded file.\n */\nexport const FileEntity = defineEntity({\n name: 'File',\n description: 'An uploaded file.',\n schema: 'lssm_files',\n map: 'file',\n fields: {\n id: field.id({ description: 'Unique file identifier' }),\n\n // File info\n name: field.string({ description: 'Original file name' }),\n mimeType: field.string({ description: 'MIME type' }),\n size: field.int({ description: 'File size in bytes' }),\n\n // Storage\n storageProvider: field.enum('StorageProvider', {\n default: 'LOCAL',\n description: 'Storage backend',\n }),\n storagePath: field.string({ description: 'Path in storage backend' }),\n storageKey: field.string({\n isOptional: true,\n description: 'Storage key/bucket',\n }),\n\n // Integrity\n checksum: field.string({\n isOptional: true,\n description: 'SHA-256 checksum',\n }),\n etag: field.string({ isOptional: true, description: 'Storage ETag' }),\n\n // Status\n status: field.enum('FileStatus', {\n default: 'PENDING',\n description: 'File status',\n }),\n\n // Access\n isPublic: field.boolean({\n default: false,\n description: 'Whether file is publicly accessible',\n }),\n expiresAt: field.dateTime({\n isOptional: true,\n description: 'Auto-delete timestamp',\n }),\n\n // Ownership\n ownerId: field.string({ description: 'User who uploaded' }),\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope',\n }),\n\n // Metadata\n metadata: field.json({\n isOptional: true,\n description: 'Additional metadata',\n }),\n tags: field.json({\n isOptional: true,\n description: 'Tags for categorization',\n }),\n\n // Image-specific\n width: field.int({\n isOptional: true,\n description: 'Image width in pixels',\n }),\n height: field.int({\n isOptional: true,\n description: 'Image height in pixels',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n versions: field.hasMany('FileVersion'),\n attachments: field.hasMany('Attachment'),\n },\n indexes: [\n index.on(['ownerId']),\n index.on(['orgId']),\n index.on(['status']),\n index.on(['mimeType']),\n index.on(['storageProvider', 'storagePath']),\n ],\n enums: [StorageProviderEnum, FileStatusEnum],\n});\n\n/**\n * FileVersion entity - version history for files.\n */\nexport const FileVersionEntity = defineEntity({\n name: 'FileVersion',\n description: 'A version of a file.',\n schema: 'lssm_files',\n map: 'file_version',\n fields: {\n id: field.id({ description: 'Unique version identifier' }),\n fileId: field.foreignKey({ description: 'Parent file' }),\n\n // Version info\n version: field.int({ description: 'Version number' }),\n size: field.int({ description: 'Version size in bytes' }),\n\n // Storage\n storagePath: field.string({ description: 'Path in storage backend' }),\n checksum: field.string({\n isOptional: true,\n description: 'SHA-256 checksum',\n }),\n\n // Metadata\n comment: field.string({ isOptional: true, description: 'Version comment' }),\n changes: field.json({\n isOptional: true,\n description: 'Change description',\n }),\n\n // Creator\n createdBy: field.string({ description: 'User who created version' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n\n // Relations\n file: field.belongsTo('File', ['fileId'], ['id'], { onDelete: 'Cascade' }),\n },\n indexes: [\n index.on(['fileId', 'version']),\n index.unique(['fileId', 'version'], { name: 'file_version_unique' }),\n ],\n});\n\n/**\n * Attachment entity - polymorphic link between files and entities.\n */\nexport const AttachmentEntity = defineEntity({\n name: 'Attachment',\n description: 'Links a file to an entity.',\n schema: 'lssm_files',\n map: 'attachment',\n fields: {\n id: field.id({ description: 'Unique attachment identifier' }),\n fileId: field.foreignKey({ description: 'Attached file' }),\n\n // Target entity (polymorphic)\n entityType: field.string({\n description: 'Target entity type (deal, listing, etc.)',\n }),\n entityId: field.string({ description: 'Target entity ID' }),\n\n // Attachment metadata\n attachmentType: field.string({\n isOptional: true,\n description: 'Type of attachment (document, image, avatar, etc.)',\n }),\n name: field.string({\n isOptional: true,\n description: 'Display name (overrides file name)',\n }),\n description: field.string({\n isOptional: true,\n description: 'Attachment description',\n }),\n\n // Ordering\n order: field.int({ default: 0, description: 'Display order' }),\n\n // Metadata\n metadata: field.json({\n isOptional: true,\n description: 'Attachment-specific metadata',\n }),\n\n // Creator\n createdBy: field.string({ description: 'User who created attachment' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n file: field.belongsTo('File', ['fileId'], ['id'], { onDelete: 'Cascade' }),\n },\n indexes: [\n index.on(['entityType', 'entityId']),\n index.on(['fileId']),\n index.on(['entityType', 'entityId', 'attachmentType']),\n index.unique(['fileId', 'entityType', 'entityId'], {\n name: 'attachment_unique',\n }),\n ],\n});\n\n/**\n * UploadSession entity - tracks multipart uploads.\n */\nexport const UploadSessionEntity = defineEntity({\n name: 'UploadSession',\n description: 'Tracks a multipart upload session.',\n schema: 'lssm_files',\n map: 'upload_session',\n fields: {\n id: field.id({ description: 'Unique session identifier' }),\n\n // File info\n fileName: field.string({ description: 'Target file name' }),\n mimeType: field.string({ description: 'Expected MIME type' }),\n totalSize: field.int({ description: 'Total file size' }),\n\n // Upload state\n uploadId: field.string({\n isOptional: true,\n description: 'Storage upload ID',\n }),\n uploadedBytes: field.int({\n default: 0,\n description: 'Bytes uploaded so far',\n }),\n uploadedParts: field.json({\n isOptional: true,\n description: 'Completed part info',\n }),\n\n // Status\n status: field.string({\n default: '\"pending\"',\n description: 'Session status',\n }),\n error: field.string({\n isOptional: true,\n description: 'Error message if failed',\n }),\n\n // Result\n fileId: field.string({\n isOptional: true,\n description: 'Resulting file ID',\n }),\n\n // Context\n ownerId: field.string({ description: 'User who initiated upload' }),\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope',\n }),\n\n // Expiry\n expiresAt: field.dateTime({ description: 'Session expiry time' }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n },\n indexes: [index.on(['status', 'expiresAt']), index.on(['ownerId'])],\n});\n\n/**\n * All file entities for schema composition.\n */\nexport const fileEntities = [\n FileEntity,\n FileVersionEntity,\n AttachmentEntity,\n UploadSessionEntity,\n];\n\n/**\n * Module schema contribution for files.\n */\nexport const filesSchemaContribution: ModuleSchemaContribution = {\n moduleId: '@contractspec/lib.files',\n entities: fileEntities,\n enums: [StorageProviderEnum, FileStatusEnum],\n};\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import * as _contractspec_lib_contracts27 from "@contractspec/lib.contracts";
2
+
3
+ //#region src/files.capability.d.ts
4
+ declare const FilesCapability: _contractspec_lib_contracts27.CapabilitySpec;
5
+ declare const AttachmentsCapability: _contractspec_lib_contracts27.CapabilitySpec;
6
+ //#endregion
7
+ export { AttachmentsCapability, FilesCapability };
8
+ //# sourceMappingURL=files.capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.capability.d.ts","names":[],"sources":["../src/files.capability.ts"],"sourcesContent":[],"mappings":";;;cAEa,iBAUX,6BAAA,CAV0B;cAYf,uBAUX,6BAAA,CAVgC"}
@@ -0,0 +1,25 @@
1
+ import { StabilityEnum, defineCapability } from "@contractspec/lib.contracts";
2
+
3
+ //#region src/files.capability.ts
4
+ const FilesCapability = defineCapability({ meta: {
5
+ key: "files",
6
+ version: "1.0.0",
7
+ kind: "data",
8
+ stability: StabilityEnum.Experimental,
9
+ description: "File storage and management",
10
+ owners: ["@platform.core"],
11
+ tags: ["files", "storage"]
12
+ } });
13
+ const AttachmentsCapability = defineCapability({ meta: {
14
+ key: "attachments",
15
+ version: "1.0.0",
16
+ kind: "data",
17
+ stability: StabilityEnum.Experimental,
18
+ description: "File attachments for entities",
19
+ owners: ["@platform.core"],
20
+ tags: ["attachments", "files"]
21
+ } });
22
+
23
+ //#endregion
24
+ export { AttachmentsCapability, FilesCapability };
25
+ //# sourceMappingURL=files.capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.capability.js","names":[],"sources":["../src/files.capability.ts"],"sourcesContent":["import { defineCapability, StabilityEnum } from '@contractspec/lib.contracts';\n\nexport const FilesCapability = defineCapability({\n meta: {\n key: 'files',\n version: '1.0.0',\n kind: 'data',\n stability: StabilityEnum.Experimental,\n description: 'File storage and management',\n owners: ['@platform.core'],\n tags: ['files', 'storage'],\n },\n});\n\nexport const AttachmentsCapability = defineCapability({\n meta: {\n key: 'attachments',\n version: '1.0.0',\n kind: 'data',\n stability: StabilityEnum.Experimental,\n description: 'File attachments for entities',\n owners: ['@platform.core'],\n tags: ['attachments', 'files'],\n },\n});\n"],"mappings":";;;AAEA,MAAa,kBAAkB,iBAAiB,EAC9C,MAAM;CACJ,KAAK;CACL,SAAS;CACT,MAAM;CACN,WAAW,cAAc;CACzB,aAAa;CACb,QAAQ,CAAC,iBAAiB;CAC1B,MAAM,CAAC,SAAS,UAAU;CAC3B,EACF,CAAC;AAEF,MAAa,wBAAwB,iBAAiB,EACpD,MAAM;CACJ,KAAK;CACL,SAAS;CACT,MAAM;CACN,WAAW,cAAc;CACzB,aAAa;CACb,QAAQ,CAAC,iBAAiB;CAC1B,MAAM,CAAC,eAAe,QAAQ;CAC/B,EACF,CAAC"}
@@ -1,12 +1,12 @@
1
- import { FeatureModuleSpec } from "@contractspec/lib.contracts";
1
+ import * as _contractspec_lib_contracts29 from "@contractspec/lib.contracts";
2
2
 
3
3
  //#region src/files.feature.d.ts
4
4
 
5
5
  /**
6
- * Files feature module that bundles file upload, versioning,
7
- * and attachment management capabilities.
6
+ * Files feature module that bundles file storage,
7
+ * attachments, and media processing capabilities.
8
8
  */
9
- declare const FilesFeature: FeatureModuleSpec;
9
+ declare const FilesFeature: _contractspec_lib_contracts29.FeatureModuleSpec;
10
10
  //#endregion
11
11
  export { FilesFeature };
12
12
  //# sourceMappingURL=files.feature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"files.feature.d.ts","names":[],"sources":["../src/files.feature.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAWa,cAAc"}
1
+ {"version":3,"file":"files.feature.d.ts","names":[],"sources":["../src/files.feature.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;cAAa,cAgEX,6BAAA,CAhEuB"}
@@ -1,14 +1,21 @@
1
+ import { defineFeature } from "@contractspec/lib.contracts";
2
+
1
3
  //#region src/files.feature.ts
2
4
  /**
3
- * Files feature module that bundles file upload, versioning,
4
- * and attachment management capabilities.
5
+ * Files Feature Module Specification
6
+ *
7
+ * Defines the feature module for file management capabilities.
8
+ */
9
+ /**
10
+ * Files feature module that bundles file storage,
11
+ * attachments, and media processing capabilities.
5
12
  */
6
- const FilesFeature = {
13
+ const FilesFeature = defineFeature({
7
14
  meta: {
8
15
  key: "files",
9
16
  version: "1.0.0",
10
17
  title: "File Management",
11
- description: "File upload, versioning, and attachment management with presigned URLs",
18
+ description: "File storage, attachments, and media processing with presigned URLs",
12
19
  domain: "platform",
13
20
  owners: ["@platform.files"],
14
21
  tags: [
@@ -119,7 +126,7 @@ const FilesFeature = {
119
126
  version: "1.0.0"
120
127
  }]
121
128
  }
122
- };
129
+ });
123
130
 
124
131
  //#endregion
125
132
  export { FilesFeature };
@@ -1 +1 @@
1
- {"version":3,"file":"files.feature.js","names":["FilesFeature: FeatureModuleSpec"],"sources":["../src/files.feature.ts"],"sourcesContent":["/**\n * Files Feature Module Specification\n *\n * Defines the feature module for file management capabilities.\n */\nimport type { FeatureModuleSpec } from '@contractspec/lib.contracts';\n\n/**\n * Files feature module that bundles file upload, versioning,\n * and attachment management capabilities.\n */\nexport const FilesFeature: FeatureModuleSpec = {\n meta: {\n key: 'files',\n version: '1.0.0',\n title: 'File Management',\n description:\n 'File upload, versioning, and attachment management with presigned URLs',\n domain: 'platform',\n owners: ['@platform.files'],\n tags: ['files', 'upload', 'attachments', 'storage'],\n stability: 'stable',\n },\n\n // All contract operations included in this feature\n operations: [\n // File CRUD operations\n { key: 'file.upload', version: '1.0.0' },\n { key: 'file.update', version: '1.0.0' },\n { key: 'file.delete', version: '1.0.0' },\n { key: 'file.get', version: '1.0.0' },\n { key: 'file.list', version: '1.0.0' },\n { key: 'file.downloadUrl', version: '1.0.0' },\n { key: 'file.presignedUrl.create', version: '1.0.0' },\n\n // Version operations\n { key: 'file.version.create', version: '1.0.0' },\n { key: 'file.version.list', version: '1.0.0' },\n\n // Attachment operations\n { key: 'attachment.attach', version: '1.0.0' },\n { key: 'attachment.detach', version: '1.0.0' },\n { key: 'attachment.list', version: '1.0.0' },\n ],\n\n // Events emitted by this feature\n events: [\n // File events\n { key: 'file.uploaded', version: '1.0.0' },\n { key: 'file.updated', version: '1.0.0' },\n { key: 'file.deleted', version: '1.0.0' },\n { key: 'file.version_created', version: '1.0.0' },\n\n // Attachment events\n { key: 'attachment.attached', version: '1.0.0' },\n { key: 'attachment.detached', version: '1.0.0' },\n\n // Upload session events\n { key: 'upload.session_started', version: '1.0.0' },\n { key: 'upload.session_completed', version: '1.0.0' },\n ],\n\n // No presentations for this library feature\n presentations: [],\n opToPresentation: [],\n presentationsTargets: [],\n\n // Capability definitions\n capabilities: {\n provides: [\n { key: 'files', version: '1.0.0' },\n { key: 'attachments', version: '1.0.0' },\n ],\n requires: [{ key: 'identity', version: '1.0.0' }],\n },\n};\n"],"mappings":";;;;;AAWA,MAAaA,eAAkC;CAC7C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,kBAAkB;EAC3B,MAAM;GAAC;GAAS;GAAU;GAAe;GAAU;EACnD,WAAW;EACZ;CAGD,YAAY;EAEV;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAY,SAAS;GAAS;EACrC;GAAE,KAAK;GAAa,SAAS;GAAS;EACtC;GAAE,KAAK;GAAoB,SAAS;GAAS;EAC7C;GAAE,KAAK;GAA4B,SAAS;GAAS;EAGrD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAqB,SAAS;GAAS;EAG9C;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC7C;CAGD,QAAQ;EAEN;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAwB,SAAS;GAAS;EAGjD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAGhD;GAAE,KAAK;GAA0B,SAAS;GAAS;EACnD;GAAE,KAAK;GAA4B,SAAS;GAAS;EACtD;CAGD,eAAe,EAAE;CACjB,kBAAkB,EAAE;CACpB,sBAAsB,EAAE;CAGxB,cAAc;EACZ,UAAU,CACR;GAAE,KAAK;GAAS,SAAS;GAAS,EAClC;GAAE,KAAK;GAAe,SAAS;GAAS,CACzC;EACD,UAAU,CAAC;GAAE,KAAK;GAAY,SAAS;GAAS,CAAC;EAClD;CACF"}
1
+ {"version":3,"file":"files.feature.js","names":[],"sources":["../src/files.feature.ts"],"sourcesContent":["/**\n * Files Feature Module Specification\n *\n * Defines the feature module for file management capabilities.\n */\nimport { defineFeature } from '@contractspec/lib.contracts';\n\n/**\n * Files feature module that bundles file storage,\n * attachments, and media processing capabilities.\n */\nexport const FilesFeature = defineFeature({\n meta: {\n key: 'files',\n version: '1.0.0',\n title: 'File Management',\n description:\n 'File storage, attachments, and media processing with presigned URLs',\n domain: 'platform',\n owners: ['@platform.files'],\n tags: ['files', 'upload', 'attachments', 'storage'],\n stability: 'stable',\n },\n\n // All contract operations included in this feature\n operations: [\n // File CRUD operations\n { key: 'file.upload', version: '1.0.0' },\n { key: 'file.update', version: '1.0.0' },\n { key: 'file.delete', version: '1.0.0' },\n { key: 'file.get', version: '1.0.0' },\n { key: 'file.list', version: '1.0.0' },\n { key: 'file.downloadUrl', version: '1.0.0' },\n { key: 'file.presignedUrl.create', version: '1.0.0' },\n\n // Version operations\n { key: 'file.version.create', version: '1.0.0' },\n { key: 'file.version.list', version: '1.0.0' },\n\n // Attachment operations\n { key: 'attachment.attach', version: '1.0.0' },\n { key: 'attachment.detach', version: '1.0.0' },\n { key: 'attachment.list', version: '1.0.0' },\n ],\n\n // Events emitted by this feature\n events: [\n // File events\n { key: 'file.uploaded', version: '1.0.0' },\n { key: 'file.updated', version: '1.0.0' },\n { key: 'file.deleted', version: '1.0.0' },\n { key: 'file.version_created', version: '1.0.0' },\n\n // Attachment events\n { key: 'attachment.attached', version: '1.0.0' },\n { key: 'attachment.detached', version: '1.0.0' },\n\n // Upload session events\n { key: 'upload.session_started', version: '1.0.0' },\n { key: 'upload.session_completed', version: '1.0.0' },\n ],\n\n // No presentations for this library feature\n presentations: [],\n opToPresentation: [],\n presentationsTargets: [],\n\n // Capability definitions\n capabilities: {\n provides: [\n { key: 'files', version: '1.0.0' },\n { key: 'attachments', version: '1.0.0' },\n ],\n requires: [{ key: 'identity', version: '1.0.0' }],\n },\n});\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,eAAe,cAAc;CACxC,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,kBAAkB;EAC3B,MAAM;GAAC;GAAS;GAAU;GAAe;GAAU;EACnD,WAAW;EACZ;CAGD,YAAY;EAEV;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAe,SAAS;GAAS;EACxC;GAAE,KAAK;GAAY,SAAS;GAAS;EACrC;GAAE,KAAK;GAAa,SAAS;GAAS;EACtC;GAAE,KAAK;GAAoB,SAAS;GAAS;EAC7C;GAAE,KAAK;GAA4B,SAAS;GAAS;EAGrD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAqB,SAAS;GAAS;EAG9C;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAqB,SAAS;GAAS;EAC9C;GAAE,KAAK;GAAmB,SAAS;GAAS;EAC7C;CAGD,QAAQ;EAEN;GAAE,KAAK;GAAiB,SAAS;GAAS;EAC1C;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAgB,SAAS;GAAS;EACzC;GAAE,KAAK;GAAwB,SAAS;GAAS;EAGjD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAChD;GAAE,KAAK;GAAuB,SAAS;GAAS;EAGhD;GAAE,KAAK;GAA0B,SAAS;GAAS;EACnD;GAAE,KAAK;GAA4B,SAAS;GAAS;EACtD;CAGD,eAAe,EAAE;CACjB,kBAAkB,EAAE;CACpB,sBAAsB,EAAE;CAGxB,cAAc;EACZ,UAAU,CACR;GAAE,KAAK;GAAS,SAAS;GAAS,EAClC;GAAE,KAAK;GAAe,SAAS;GAAS,CACzC;EACD,UAAU,CAAC;GAAE,KAAK;GAAY,SAAS;GAAS,CAAC;EAClD;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["files: StorageFile[]","metadata: StorageFile","path"],"sources":["../../src/storage/index.ts"],"sourcesContent":["/**\n * File storage adapters for different backends.\n */\n\n// ============ Types ============\n\nexport type StorageProvider = 'LOCAL' | 'S3' | 'GCS' | 'AZURE' | 'CLOUDFLARE';\n\nexport interface StorageFile {\n path: string;\n size: number;\n mimeType: string;\n checksum?: string;\n etag?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface UploadOptions {\n /** Target path in storage */\n path: string;\n /** File content */\n content: Buffer | string;\n /** MIME type */\n mimeType: string;\n /** Additional metadata */\n metadata?: Record<string, string>;\n /** Whether file should be publicly accessible */\n isPublic?: boolean;\n}\n\nexport interface PresignedUploadOptions {\n /** Target path in storage */\n path: string;\n /** MIME type */\n mimeType: string;\n /** File size in bytes */\n size: number;\n /** Expiration time in seconds */\n expiresIn?: number;\n /** Additional conditions */\n conditions?: Record<string, unknown>[];\n}\n\nexport interface PresignedDownloadOptions {\n /** File path in storage */\n path: string;\n /** Expiration time in seconds */\n expiresIn?: number;\n /** Response content disposition */\n contentDisposition?: string;\n}\n\nexport interface PresignedUrl {\n url: string;\n fields?: Record<string, string>;\n expiresAt: Date;\n}\n\nexport interface ListOptions {\n /** Path prefix */\n prefix?: string;\n /** Maximum results */\n limit?: number;\n /** Continuation token */\n cursor?: string;\n}\n\nexport interface ListResult {\n files: StorageFile[];\n cursor?: string;\n hasMore: boolean;\n}\n\n// ============ Storage Adapter Interface ============\n\nexport interface StorageAdapter {\n /** Storage provider type */\n readonly provider: StorageProvider;\n\n /**\n * Upload a file to storage.\n */\n upload(options: UploadOptions): Promise<StorageFile>;\n\n /**\n * Download a file from storage.\n */\n download(path: string): Promise<Buffer>;\n\n /**\n * Delete a file from storage.\n */\n delete(path: string): Promise<void>;\n\n /**\n * Check if a file exists.\n */\n exists(path: string): Promise<boolean>;\n\n /**\n * Get file metadata.\n */\n getMetadata(path: string): Promise<StorageFile | null>;\n\n /**\n * List files in a directory.\n */\n list(options?: ListOptions): Promise<ListResult>;\n\n /**\n * Generate a presigned URL for uploading.\n */\n createPresignedUpload(options: PresignedUploadOptions): Promise<PresignedUrl>;\n\n /**\n * Generate a presigned URL for downloading.\n */\n createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl>;\n\n /**\n * Get public URL for a file (if applicable).\n */\n getPublicUrl(path: string): string | null;\n\n /**\n * Copy a file within storage.\n */\n copy(sourcePath: string, destinationPath: string): Promise<StorageFile>;\n}\n\n// ============ Local Storage Adapter ============\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\n\nexport interface LocalStorageOptions {\n /** Base directory for file storage */\n basePath: string;\n /** Base URL for serving files (optional) */\n baseUrl?: string;\n}\n\n/**\n * Local filesystem storage adapter.\n * For development and testing purposes.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'LOCAL';\n private basePath: string;\n private baseUrl?: string;\n\n constructor(options: LocalStorageOptions) {\n this.basePath = options.basePath;\n this.baseUrl = options.baseUrl;\n }\n\n async upload(options: UploadOptions): Promise<StorageFile> {\n const fullPath = path.join(this.basePath, options.path);\n const dir = path.dirname(fullPath);\n\n // Ensure directory exists\n await fs.mkdir(dir, { recursive: true });\n\n // Write file\n const content =\n typeof options.content === 'string'\n ? Buffer.from(options.content, 'base64')\n : options.content;\n\n await fs.writeFile(fullPath, content);\n\n // Calculate checksum\n const checksum = crypto.createHash('sha256').update(content).digest('hex');\n\n return {\n path: options.path,\n size: content.length,\n mimeType: options.mimeType,\n checksum,\n metadata: options.metadata,\n };\n }\n\n async download(filePath: string): Promise<Buffer> {\n const fullPath = path.join(this.basePath, filePath);\n return fs.readFile(fullPath);\n }\n\n async delete(filePath: string): Promise<void> {\n const fullPath = path.join(this.basePath, filePath);\n await fs.unlink(fullPath);\n }\n\n async exists(filePath: string): Promise<boolean> {\n const fullPath = path.join(this.basePath, filePath);\n try {\n await fs.access(fullPath);\n return true;\n } catch {\n return false;\n }\n }\n\n async getMetadata(filePath: string): Promise<StorageFile | null> {\n const fullPath = path.join(this.basePath, filePath);\n try {\n const stat = await fs.stat(fullPath);\n return {\n path: filePath,\n size: stat.size,\n mimeType: 'application/octet-stream', // Would need mime type detection\n };\n } catch {\n return null;\n }\n }\n\n async list(options?: ListOptions): Promise<ListResult> {\n const dir = options?.prefix\n ? path.join(this.basePath, options.prefix)\n : this.basePath;\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const files: StorageFile[] = [];\n\n for (const entry of entries) {\n if (entry.isFile()) {\n const filePath = options?.prefix\n ? path.join(options.prefix, entry.name)\n : entry.name;\n const stat = await fs.stat(path.join(dir, entry.name));\n files.push({\n path: filePath,\n size: stat.size,\n mimeType: 'application/octet-stream',\n });\n }\n }\n\n const limit = options?.limit || files.length;\n return {\n files: files.slice(0, limit),\n hasMore: files.length > limit,\n };\n } catch {\n return { files: [], hasMore: false };\n }\n }\n\n async createPresignedUpload(\n options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n // Local storage doesn't support real presigned URLs\n // Return a placeholder that would work with a local upload endpoint\n const expiresIn = options.expiresIn || 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return {\n url: this.baseUrl\n ? `${this.baseUrl}/upload?path=${encodeURIComponent(options.path)}`\n : `/upload?path=${encodeURIComponent(options.path)}`,\n fields: {\n path: options.path,\n mimeType: options.mimeType,\n },\n expiresAt,\n };\n }\n\n async createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n const expiresIn = options.expiresIn || 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return {\n url: this.baseUrl\n ? `${this.baseUrl}/download/${options.path}`\n : `/download/${options.path}`,\n expiresAt,\n };\n }\n\n getPublicUrl(filePath: string): string | null {\n if (!this.baseUrl) return null;\n return `${this.baseUrl}/${filePath}`;\n }\n\n async copy(\n sourcePath: string,\n destinationPath: string\n ): Promise<StorageFile> {\n const sourceFullPath = path.join(this.basePath, sourcePath);\n const destFullPath = path.join(this.basePath, destinationPath);\n const destDir = path.dirname(destFullPath);\n\n await fs.mkdir(destDir, { recursive: true });\n await fs.copyFile(sourceFullPath, destFullPath);\n\n const stat = await fs.stat(destFullPath);\n return {\n path: destinationPath,\n size: stat.size,\n mimeType: 'application/octet-stream',\n };\n }\n}\n\n// ============ S3 Storage Adapter Interface ============\n\nexport interface S3StorageOptions {\n /** S3 bucket name */\n bucket: string;\n /** AWS region */\n region: string;\n /** AWS access key ID */\n accessKeyId?: string;\n /** AWS secret access key */\n secretAccessKey?: string;\n /** Endpoint URL (for S3-compatible services) */\n endpoint?: string;\n /** Force path style (for S3-compatible services) */\n forcePathStyle?: boolean;\n /** Default ACL for uploads */\n defaultAcl?: 'private' | 'public-read';\n}\n\n/**\n * S3 storage adapter interface.\n * Implementation would use AWS SDK or compatible client.\n *\n * This is a placeholder that defines the interface.\n * Actual implementation would require @aws-sdk/client-s3 dependency.\n */\nexport class S3StorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'S3';\n private config: S3StorageOptions;\n\n constructor(options: S3StorageOptions) {\n this.config = options;\n }\n\n async upload(_options: UploadOptions): Promise<StorageFile> {\n // Placeholder - actual implementation would use S3 SDK\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the upload method.'\n );\n }\n\n async download(_filePath: string): Promise<Buffer> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the download method.'\n );\n }\n\n async delete(_filePath: string): Promise<void> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the delete method.'\n );\n }\n\n async exists(_filePath: string): Promise<boolean> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the exists method.'\n );\n }\n\n async getMetadata(_filePath: string): Promise<StorageFile | null> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the getMetadata method.'\n );\n }\n\n async list(_options?: ListOptions): Promise<ListResult> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the list method.'\n );\n }\n\n async createPresignedUpload(\n _options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the createPresignedUpload method.'\n );\n }\n\n async createPresignedDownload(\n _options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the createPresignedDownload method.'\n );\n }\n\n getPublicUrl(filePath: string): string | null {\n const { bucket, region, endpoint } = this.config;\n if (endpoint) {\n return `${endpoint}/${bucket}/${filePath}`;\n }\n return `https://${bucket}.s3.${region}.amazonaws.com/${filePath}`;\n }\n\n async copy(\n _sourcePath: string,\n _destinationPath: string\n ): Promise<StorageFile> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the copy method.'\n );\n }\n}\n\n// ============ In-Memory Storage Adapter ============\n\n/**\n * In-memory storage adapter for testing.\n */\nexport class InMemoryStorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'LOCAL';\n private files = new Map<string, { content: Buffer; metadata: StorageFile }>();\n\n async upload(options: UploadOptions): Promise<StorageFile> {\n const content =\n typeof options.content === 'string'\n ? Buffer.from(options.content, 'base64')\n : options.content;\n\n const checksum = crypto.createHash('sha256').update(content).digest('hex');\n\n const metadata: StorageFile = {\n path: options.path,\n size: content.length,\n mimeType: options.mimeType,\n checksum,\n metadata: options.metadata,\n };\n\n this.files.set(options.path, { content, metadata });\n return metadata;\n }\n\n async download(filePath: string): Promise<Buffer> {\n const file = this.files.get(filePath);\n if (!file) {\n throw new Error(`File not found: ${filePath}`);\n }\n return file.content;\n }\n\n async delete(filePath: string): Promise<void> {\n this.files.delete(filePath);\n }\n\n async exists(filePath: string): Promise<boolean> {\n return this.files.has(filePath);\n }\n\n async getMetadata(filePath: string): Promise<StorageFile | null> {\n const file = this.files.get(filePath);\n return file?.metadata || null;\n }\n\n async list(options?: ListOptions): Promise<ListResult> {\n const prefix = options?.prefix || '';\n const files: StorageFile[] = [];\n\n for (const [path, file] of this.files) {\n if (path.startsWith(prefix)) {\n files.push(file.metadata);\n }\n }\n\n const limit = options?.limit || files.length;\n return {\n files: files.slice(0, limit),\n hasMore: files.length > limit,\n };\n }\n\n async createPresignedUpload(\n options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n const expiresAt = new Date(Date.now() + (options.expiresIn || 3600) * 1000);\n return {\n url: `/upload?path=${encodeURIComponent(options.path)}`,\n fields: { path: options.path },\n expiresAt,\n };\n }\n\n async createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n const expiresAt = new Date(Date.now() + (options.expiresIn || 3600) * 1000);\n return {\n url: `/download/${options.path}`,\n expiresAt,\n };\n }\n\n getPublicUrl(filePath: string): string | null {\n return `/files/${filePath}`;\n }\n\n async copy(\n sourcePath: string,\n destinationPath: string\n ): Promise<StorageFile> {\n const source = this.files.get(sourcePath);\n if (!source) {\n throw new Error(`Source file not found: ${sourcePath}`);\n }\n\n const metadata: StorageFile = {\n ...source.metadata,\n path: destinationPath,\n };\n\n this.files.set(destinationPath, { content: source.content, metadata });\n return metadata;\n }\n\n clear(): void {\n this.files.clear();\n }\n}\n\n// ============ Factory ============\n\nexport interface StorageConfig {\n provider: StorageProvider;\n local?: LocalStorageOptions;\n s3?: S3StorageOptions;\n}\n\n/**\n * Create a storage adapter based on configuration.\n */\nexport function createStorageAdapter(config: StorageConfig): StorageAdapter {\n switch (config.provider) {\n case 'LOCAL':\n if (!config.local) {\n throw new Error('Local storage configuration required');\n }\n return new LocalStorageAdapter(config.local);\n\n case 'S3':\n if (!config.s3) {\n throw new Error('S3 storage configuration required');\n }\n return new S3StorageAdapter(config.s3);\n\n default:\n throw new Error(`Unsupported storage provider: ${config.provider}`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["path"],"sources":["../../src/storage/index.ts"],"sourcesContent":["/**\n * File storage adapters for different backends.\n */\n\n// ============ Types ============\n\nexport type StorageProvider = 'LOCAL' | 'S3' | 'GCS' | 'AZURE' | 'CLOUDFLARE';\n\nexport interface StorageFile {\n path: string;\n size: number;\n mimeType: string;\n checksum?: string;\n etag?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface UploadOptions {\n /** Target path in storage */\n path: string;\n /** File content */\n content: Buffer | string;\n /** MIME type */\n mimeType: string;\n /** Additional metadata */\n metadata?: Record<string, string>;\n /** Whether file should be publicly accessible */\n isPublic?: boolean;\n}\n\nexport interface PresignedUploadOptions {\n /** Target path in storage */\n path: string;\n /** MIME type */\n mimeType: string;\n /** File size in bytes */\n size: number;\n /** Expiration time in seconds */\n expiresIn?: number;\n /** Additional conditions */\n conditions?: Record<string, unknown>[];\n}\n\nexport interface PresignedDownloadOptions {\n /** File path in storage */\n path: string;\n /** Expiration time in seconds */\n expiresIn?: number;\n /** Response content disposition */\n contentDisposition?: string;\n}\n\nexport interface PresignedUrl {\n url: string;\n fields?: Record<string, string>;\n expiresAt: Date;\n}\n\nexport interface ListOptions {\n /** Path prefix */\n prefix?: string;\n /** Maximum results */\n limit?: number;\n /** Continuation token */\n cursor?: string;\n}\n\nexport interface ListResult {\n files: StorageFile[];\n cursor?: string;\n hasMore: boolean;\n}\n\n// ============ Storage Adapter Interface ============\n\nexport interface StorageAdapter {\n /** Storage provider type */\n readonly provider: StorageProvider;\n\n /**\n * Upload a file to storage.\n */\n upload(options: UploadOptions): Promise<StorageFile>;\n\n /**\n * Download a file from storage.\n */\n download(path: string): Promise<Buffer>;\n\n /**\n * Delete a file from storage.\n */\n delete(path: string): Promise<void>;\n\n /**\n * Check if a file exists.\n */\n exists(path: string): Promise<boolean>;\n\n /**\n * Get file metadata.\n */\n getMetadata(path: string): Promise<StorageFile | null>;\n\n /**\n * List files in a directory.\n */\n list(options?: ListOptions): Promise<ListResult>;\n\n /**\n * Generate a presigned URL for uploading.\n */\n createPresignedUpload(options: PresignedUploadOptions): Promise<PresignedUrl>;\n\n /**\n * Generate a presigned URL for downloading.\n */\n createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl>;\n\n /**\n * Get public URL for a file (if applicable).\n */\n getPublicUrl(path: string): string | null;\n\n /**\n * Copy a file within storage.\n */\n copy(sourcePath: string, destinationPath: string): Promise<StorageFile>;\n}\n\n// ============ Local Storage Adapter ============\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\n\nexport interface LocalStorageOptions {\n /** Base directory for file storage */\n basePath: string;\n /** Base URL for serving files (optional) */\n baseUrl?: string;\n}\n\n/**\n * Local filesystem storage adapter.\n * For development and testing purposes.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'LOCAL';\n private basePath: string;\n private baseUrl?: string;\n\n constructor(options: LocalStorageOptions) {\n this.basePath = options.basePath;\n this.baseUrl = options.baseUrl;\n }\n\n async upload(options: UploadOptions): Promise<StorageFile> {\n const fullPath = path.join(this.basePath, options.path);\n const dir = path.dirname(fullPath);\n\n // Ensure directory exists\n await fs.mkdir(dir, { recursive: true });\n\n // Write file\n const content =\n typeof options.content === 'string'\n ? Buffer.from(options.content, 'base64')\n : options.content;\n\n await fs.writeFile(fullPath, content);\n\n // Calculate checksum\n const checksum = crypto.createHash('sha256').update(content).digest('hex');\n\n return {\n path: options.path,\n size: content.length,\n mimeType: options.mimeType,\n checksum,\n metadata: options.metadata,\n };\n }\n\n async download(filePath: string): Promise<Buffer> {\n const fullPath = path.join(this.basePath, filePath);\n return fs.readFile(fullPath);\n }\n\n async delete(filePath: string): Promise<void> {\n const fullPath = path.join(this.basePath, filePath);\n await fs.unlink(fullPath);\n }\n\n async exists(filePath: string): Promise<boolean> {\n const fullPath = path.join(this.basePath, filePath);\n try {\n await fs.access(fullPath);\n return true;\n } catch {\n return false;\n }\n }\n\n async getMetadata(filePath: string): Promise<StorageFile | null> {\n const fullPath = path.join(this.basePath, filePath);\n try {\n const stat = await fs.stat(fullPath);\n return {\n path: filePath,\n size: stat.size,\n mimeType: 'application/octet-stream', // Would need mime type detection\n };\n } catch {\n return null;\n }\n }\n\n async list(options?: ListOptions): Promise<ListResult> {\n const dir = options?.prefix\n ? path.join(this.basePath, options.prefix)\n : this.basePath;\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const files: StorageFile[] = [];\n\n for (const entry of entries) {\n if (entry.isFile()) {\n const filePath = options?.prefix\n ? path.join(options.prefix, entry.name)\n : entry.name;\n const stat = await fs.stat(path.join(dir, entry.name));\n files.push({\n path: filePath,\n size: stat.size,\n mimeType: 'application/octet-stream',\n });\n }\n }\n\n const limit = options?.limit || files.length;\n return {\n files: files.slice(0, limit),\n hasMore: files.length > limit,\n };\n } catch {\n return { files: [], hasMore: false };\n }\n }\n\n async createPresignedUpload(\n options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n // Local storage doesn't support real presigned URLs\n // Return a placeholder that would work with a local upload endpoint\n const expiresIn = options.expiresIn || 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return {\n url: this.baseUrl\n ? `${this.baseUrl}/upload?path=${encodeURIComponent(options.path)}`\n : `/upload?path=${encodeURIComponent(options.path)}`,\n fields: {\n path: options.path,\n mimeType: options.mimeType,\n },\n expiresAt,\n };\n }\n\n async createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n const expiresIn = options.expiresIn || 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return {\n url: this.baseUrl\n ? `${this.baseUrl}/download/${options.path}`\n : `/download/${options.path}`,\n expiresAt,\n };\n }\n\n getPublicUrl(filePath: string): string | null {\n if (!this.baseUrl) return null;\n return `${this.baseUrl}/${filePath}`;\n }\n\n async copy(\n sourcePath: string,\n destinationPath: string\n ): Promise<StorageFile> {\n const sourceFullPath = path.join(this.basePath, sourcePath);\n const destFullPath = path.join(this.basePath, destinationPath);\n const destDir = path.dirname(destFullPath);\n\n await fs.mkdir(destDir, { recursive: true });\n await fs.copyFile(sourceFullPath, destFullPath);\n\n const stat = await fs.stat(destFullPath);\n return {\n path: destinationPath,\n size: stat.size,\n mimeType: 'application/octet-stream',\n };\n }\n}\n\n// ============ S3 Storage Adapter Interface ============\n\nexport interface S3StorageOptions {\n /** S3 bucket name */\n bucket: string;\n /** AWS region */\n region: string;\n /** AWS access key ID */\n accessKeyId?: string;\n /** AWS secret access key */\n secretAccessKey?: string;\n /** Endpoint URL (for S3-compatible services) */\n endpoint?: string;\n /** Force path style (for S3-compatible services) */\n forcePathStyle?: boolean;\n /** Default ACL for uploads */\n defaultAcl?: 'private' | 'public-read';\n}\n\n/**\n * S3 storage adapter interface.\n * Implementation would use AWS SDK or compatible client.\n *\n * This is a placeholder that defines the interface.\n * Actual implementation would require @aws-sdk/client-s3 dependency.\n */\nexport class S3StorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'S3';\n private config: S3StorageOptions;\n\n constructor(options: S3StorageOptions) {\n this.config = options;\n }\n\n async upload(_options: UploadOptions): Promise<StorageFile> {\n // Placeholder - actual implementation would use S3 SDK\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the upload method.'\n );\n }\n\n async download(_filePath: string): Promise<Buffer> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the download method.'\n );\n }\n\n async delete(_filePath: string): Promise<void> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the delete method.'\n );\n }\n\n async exists(_filePath: string): Promise<boolean> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the exists method.'\n );\n }\n\n async getMetadata(_filePath: string): Promise<StorageFile | null> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the getMetadata method.'\n );\n }\n\n async list(_options?: ListOptions): Promise<ListResult> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the list method.'\n );\n }\n\n async createPresignedUpload(\n _options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the createPresignedUpload method.'\n );\n }\n\n async createPresignedDownload(\n _options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the createPresignedDownload method.'\n );\n }\n\n getPublicUrl(filePath: string): string | null {\n const { bucket, region, endpoint } = this.config;\n if (endpoint) {\n return `${endpoint}/${bucket}/${filePath}`;\n }\n return `https://${bucket}.s3.${region}.amazonaws.com/${filePath}`;\n }\n\n async copy(\n _sourcePath: string,\n _destinationPath: string\n ): Promise<StorageFile> {\n throw new Error(\n 'S3 adapter requires @aws-sdk/client-s3. Install it and implement the copy method.'\n );\n }\n}\n\n// ============ In-Memory Storage Adapter ============\n\n/**\n * In-memory storage adapter for testing.\n */\nexport class InMemoryStorageAdapter implements StorageAdapter {\n readonly provider: StorageProvider = 'LOCAL';\n private files = new Map<string, { content: Buffer; metadata: StorageFile }>();\n\n async upload(options: UploadOptions): Promise<StorageFile> {\n const content =\n typeof options.content === 'string'\n ? Buffer.from(options.content, 'base64')\n : options.content;\n\n const checksum = crypto.createHash('sha256').update(content).digest('hex');\n\n const metadata: StorageFile = {\n path: options.path,\n size: content.length,\n mimeType: options.mimeType,\n checksum,\n metadata: options.metadata,\n };\n\n this.files.set(options.path, { content, metadata });\n return metadata;\n }\n\n async download(filePath: string): Promise<Buffer> {\n const file = this.files.get(filePath);\n if (!file) {\n throw new Error(`File not found: ${filePath}`);\n }\n return file.content;\n }\n\n async delete(filePath: string): Promise<void> {\n this.files.delete(filePath);\n }\n\n async exists(filePath: string): Promise<boolean> {\n return this.files.has(filePath);\n }\n\n async getMetadata(filePath: string): Promise<StorageFile | null> {\n const file = this.files.get(filePath);\n return file?.metadata || null;\n }\n\n async list(options?: ListOptions): Promise<ListResult> {\n const prefix = options?.prefix || '';\n const files: StorageFile[] = [];\n\n for (const [path, file] of this.files) {\n if (path.startsWith(prefix)) {\n files.push(file.metadata);\n }\n }\n\n const limit = options?.limit || files.length;\n return {\n files: files.slice(0, limit),\n hasMore: files.length > limit,\n };\n }\n\n async createPresignedUpload(\n options: PresignedUploadOptions\n ): Promise<PresignedUrl> {\n const expiresAt = new Date(Date.now() + (options.expiresIn || 3600) * 1000);\n return {\n url: `/upload?path=${encodeURIComponent(options.path)}`,\n fields: { path: options.path },\n expiresAt,\n };\n }\n\n async createPresignedDownload(\n options: PresignedDownloadOptions\n ): Promise<PresignedUrl> {\n const expiresAt = new Date(Date.now() + (options.expiresIn || 3600) * 1000);\n return {\n url: `/download/${options.path}`,\n expiresAt,\n };\n }\n\n getPublicUrl(filePath: string): string | null {\n return `/files/${filePath}`;\n }\n\n async copy(\n sourcePath: string,\n destinationPath: string\n ): Promise<StorageFile> {\n const source = this.files.get(sourcePath);\n if (!source) {\n throw new Error(`Source file not found: ${sourcePath}`);\n }\n\n const metadata: StorageFile = {\n ...source.metadata,\n path: destinationPath,\n };\n\n this.files.set(destinationPath, { content: source.content, metadata });\n return metadata;\n }\n\n clear(): void {\n this.files.clear();\n }\n}\n\n// ============ Factory ============\n\nexport interface StorageConfig {\n provider: StorageProvider;\n local?: LocalStorageOptions;\n s3?: S3StorageOptions;\n}\n\n/**\n * Create a storage adapter based on configuration.\n */\nexport function createStorageAdapter(config: StorageConfig): StorageAdapter {\n switch (config.provider) {\n case 'LOCAL':\n if (!config.local) {\n throw new Error('Local storage configuration required');\n }\n return new LocalStorageAdapter(config.local);\n\n case 'S3':\n if (!config.s3) {\n throw new Error('S3 storage configuration required');\n }\n return new S3StorageAdapter(config.s3);\n\n default:\n throw new Error(`Unsupported storage provider: ${config.provider}`);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.files",
3
- "version": "1.46.2",
3
+ "version": "1.48.0",
4
4
  "description": "Files, documents and attachments module for ContractSpec applications",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -10,7 +10,6 @@
10
10
  "attachments",
11
11
  "typescript"
12
12
  ],
13
- "main": "./dist/index.js",
14
13
  "types": "./dist/index.d.ts",
15
14
  "type": "module",
16
15
  "scripts": {
@@ -26,13 +25,13 @@
26
25
  "lint:check": "eslint src"
27
26
  },
28
27
  "dependencies": {
29
- "@contractspec/lib.schema": "1.46.2",
30
- "@contractspec/lib.contracts": "1.46.2",
31
- "zod": "^4.1.13"
28
+ "@contractspec/lib.schema": "1.48.0",
29
+ "@contractspec/lib.contracts": "1.48.0",
30
+ "zod": "^4.3.5"
32
31
  },
33
32
  "devDependencies": {
34
- "@contractspec/tool.typescript": "1.46.2",
35
- "@contractspec/tool.tsdown": "1.46.2",
33
+ "@contractspec/tool.typescript": "1.48.0",
34
+ "@contractspec/tool.tsdown": "1.48.0",
36
35
  "typescript": "^5.9.3"
37
36
  },
38
37
  "exports": {
@@ -42,11 +41,11 @@
42
41
  "./docs/files.docblock": "./dist/docs/files.docblock.js",
43
42
  "./entities": "./dist/entities/index.js",
44
43
  "./events": "./dist/events.js",
44
+ "./files.capability": "./dist/files.capability.js",
45
45
  "./files.feature": "./dist/files.feature.js",
46
46
  "./storage": "./dist/storage/index.js",
47
47
  "./*": "./*"
48
48
  },
49
- "module": "./dist/index.js",
50
49
  "files": [
51
50
  "dist",
52
51
  "README.md"