@contractspec/lib.files 1.57.0 → 1.59.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.
Files changed (44) hide show
  1. package/dist/contracts/index.d.ts +1080 -1086
  2. package/dist/contracts/index.d.ts.map +1 -1
  3. package/dist/contracts/index.js +575 -854
  4. package/dist/docs/files.docblock.d.ts +2 -1
  5. package/dist/docs/files.docblock.d.ts.map +1 -0
  6. package/dist/docs/files.docblock.js +17 -22
  7. package/dist/docs/index.d.ts +2 -1
  8. package/dist/docs/index.d.ts.map +1 -0
  9. package/dist/docs/index.js +66 -1
  10. package/dist/entities/index.d.ts +134 -139
  11. package/dist/entities/index.d.ts.map +1 -1
  12. package/dist/entities/index.js +228 -257
  13. package/dist/events.d.ts +357 -363
  14. package/dist/events.d.ts.map +1 -1
  15. package/dist/events.js +217 -400
  16. package/dist/files.capability.d.ts +2 -7
  17. package/dist/files.capability.d.ts.map +1 -1
  18. package/dist/files.capability.js +29 -25
  19. package/dist/files.feature.d.ts +1 -6
  20. package/dist/files.feature.d.ts.map +1 -1
  21. package/dist/files.feature.js +50 -131
  22. package/dist/index.d.ts +7 -6
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +1411 -8
  25. package/dist/node/contracts/index.js +576 -0
  26. package/dist/node/docs/files.docblock.js +65 -0
  27. package/dist/node/docs/index.js +65 -0
  28. package/dist/node/entities/index.js +235 -0
  29. package/dist/node/events.js +219 -0
  30. package/dist/node/files.capability.js +28 -0
  31. package/dist/node/files.feature.js +51 -0
  32. package/dist/node/index.js +1410 -0
  33. package/dist/node/storage/index.js +268 -0
  34. package/dist/storage/index.d.ts +163 -166
  35. package/dist/storage/index.d.ts.map +1 -1
  36. package/dist/storage/index.js +266 -266
  37. package/package.json +104 -30
  38. package/dist/contracts/index.js.map +0 -1
  39. package/dist/docs/files.docblock.js.map +0 -1
  40. package/dist/entities/index.js.map +0 -1
  41. package/dist/events.js.map +0 -1
  42. package/dist/files.capability.js.map +0 -1
  43. package/dist/files.feature.js.map +0 -1
  44. package/dist/storage/index.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.files",
3
- "version": "1.57.0",
3
+ "version": "1.59.0",
4
4
  "description": "Files, documents and attachments module for ContractSpec applications",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -15,36 +15,41 @@
15
15
  "scripts": {
16
16
  "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
17
17
  "publish:pkg:canary": "bun publish:pkg --tag canary",
18
- "build": "bun build:types && bun build:bundle",
19
- "build:bundle": "tsdown",
20
- "build:types": "tsc --noEmit",
21
- "dev": "bun build:bundle --watch",
18
+ "build": "bun run prebuild && bun run build:bundle && bun run build:types",
19
+ "build:bundle": "contractspec-bun-build transpile",
20
+ "build:types": "contractspec-bun-build types",
21
+ "dev": "contractspec-bun-build dev",
22
22
  "clean": "rimraf dist .turbo",
23
23
  "lint": "bun lint:fix",
24
24
  "lint:fix": "eslint src --fix",
25
- "lint:check": "eslint src"
25
+ "lint:check": "eslint src",
26
+ "prebuild": "contractspec-bun-build prebuild",
27
+ "typecheck": "tsc --noEmit"
26
28
  },
27
29
  "dependencies": {
28
- "@contractspec/lib.schema": "1.57.0",
29
- "@contractspec/lib.contracts": "1.57.0",
30
+ "@contractspec/lib.schema": "1.59.0",
31
+ "@contractspec/lib.contracts": "1.59.0",
30
32
  "zod": "^4.3.5"
31
33
  },
32
34
  "devDependencies": {
33
- "@contractspec/tool.typescript": "1.57.0",
34
- "@contractspec/tool.tsdown": "1.57.0",
35
- "typescript": "^5.9.3"
35
+ "@contractspec/tool.typescript": "1.59.0",
36
+ "typescript": "^5.9.3",
37
+ "@contractspec/tool.bun": "1.58.0"
36
38
  },
37
39
  "exports": {
38
- ".": "./dist/index.js",
39
- "./contracts": "./dist/contracts/index.js",
40
- "./docs": "./dist/docs/index.js",
41
- "./docs/files.docblock": "./dist/docs/files.docblock.js",
42
- "./entities": "./dist/entities/index.js",
43
- "./events": "./dist/events.js",
44
- "./files.capability": "./dist/files.capability.js",
45
- "./files.feature": "./dist/files.feature.js",
46
- "./storage": "./dist/storage/index.js",
47
- "./*": "./*"
40
+ ".": "./src/index.ts",
41
+ "./contracts": "./src/contracts/index.ts",
42
+ "./contracts/index": "./src/contracts/index.ts",
43
+ "./docs": "./src/docs/index.ts",
44
+ "./docs/files.docblock": "./src/docs/files.docblock.ts",
45
+ "./docs/index": "./src/docs/index.ts",
46
+ "./entities": "./src/entities/index.ts",
47
+ "./entities/index": "./src/entities/index.ts",
48
+ "./events": "./src/events.ts",
49
+ "./files.capability": "./src/files.capability.ts",
50
+ "./files.feature": "./src/files.feature.ts",
51
+ "./storage": "./src/storage/index.ts",
52
+ "./storage/index": "./src/storage/index.ts"
48
53
  },
49
54
  "files": [
50
55
  "dist",
@@ -53,15 +58,84 @@
53
58
  "publishConfig": {
54
59
  "access": "public",
55
60
  "exports": {
56
- ".": "./dist/index.js",
57
- "./contracts": "./dist/contracts/index.js",
58
- "./docs": "./dist/docs/index.js",
59
- "./docs/files.docblock": "./dist/docs/files.docblock.js",
60
- "./entities": "./dist/entities/index.js",
61
- "./events": "./dist/events.js",
62
- "./files.feature": "./dist/files.feature.js",
63
- "./storage": "./dist/storage/index.js",
64
- "./*": "./*"
61
+ ".": {
62
+ "types": "./dist/index.d.ts",
63
+ "bun": "./dist/index.js",
64
+ "node": "./dist/node/index.mjs",
65
+ "default": "./dist/index.js"
66
+ },
67
+ "./contracts": {
68
+ "types": "./dist/contracts/index.d.ts",
69
+ "bun": "./dist/contracts/index.js",
70
+ "node": "./dist/node/contracts/index.mjs",
71
+ "default": "./dist/contracts/index.js"
72
+ },
73
+ "./contracts/index": {
74
+ "types": "./dist/contracts/index.d.ts",
75
+ "bun": "./dist/contracts/index.js",
76
+ "node": "./dist/node/contracts/index.mjs",
77
+ "default": "./dist/contracts/index.js"
78
+ },
79
+ "./docs": {
80
+ "types": "./dist/docs/index.d.ts",
81
+ "bun": "./dist/docs/index.js",
82
+ "node": "./dist/node/docs/index.mjs",
83
+ "default": "./dist/docs/index.js"
84
+ },
85
+ "./docs/files.docblock": {
86
+ "types": "./dist/docs/files.docblock.d.ts",
87
+ "bun": "./dist/docs/files.docblock.js",
88
+ "node": "./dist/node/docs/files.docblock.mjs",
89
+ "default": "./dist/docs/files.docblock.js"
90
+ },
91
+ "./docs/index": {
92
+ "types": "./dist/docs/index.d.ts",
93
+ "bun": "./dist/docs/index.js",
94
+ "node": "./dist/node/docs/index.mjs",
95
+ "default": "./dist/docs/index.js"
96
+ },
97
+ "./entities": {
98
+ "types": "./dist/entities/index.d.ts",
99
+ "bun": "./dist/entities/index.js",
100
+ "node": "./dist/node/entities/index.mjs",
101
+ "default": "./dist/entities/index.js"
102
+ },
103
+ "./entities/index": {
104
+ "types": "./dist/entities/index.d.ts",
105
+ "bun": "./dist/entities/index.js",
106
+ "node": "./dist/node/entities/index.mjs",
107
+ "default": "./dist/entities/index.js"
108
+ },
109
+ "./events": {
110
+ "types": "./dist/events.d.ts",
111
+ "bun": "./dist/events.js",
112
+ "node": "./dist/node/events.mjs",
113
+ "default": "./dist/events.js"
114
+ },
115
+ "./files.capability": {
116
+ "types": "./dist/files.capability.d.ts",
117
+ "bun": "./dist/files.capability.js",
118
+ "node": "./dist/node/files.capability.mjs",
119
+ "default": "./dist/files.capability.js"
120
+ },
121
+ "./files.feature": {
122
+ "types": "./dist/files.feature.d.ts",
123
+ "bun": "./dist/files.feature.js",
124
+ "node": "./dist/node/files.feature.mjs",
125
+ "default": "./dist/files.feature.js"
126
+ },
127
+ "./storage": {
128
+ "types": "./dist/storage/index.d.ts",
129
+ "bun": "./dist/storage/index.js",
130
+ "node": "./dist/node/storage/index.mjs",
131
+ "default": "./dist/storage/index.js"
132
+ },
133
+ "./storage/index": {
134
+ "types": "./dist/storage/index.d.ts",
135
+ "bun": "./dist/storage/index.js",
136
+ "node": "./dist/node/storage/index.mjs",
137
+ "default": "./dist/storage/index.js"
138
+ }
65
139
  },
66
140
  "registry": "https://registry.npmjs.org/"
67
141
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/contracts/index.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineCommand, defineQuery } from '@contractspec/lib.contracts';\n\nconst OWNERS = ['platform.files'] as const;\n\n// ============ Schema Models ============\n\nexport const FileModel = defineSchemaModel({\n name: 'File',\n description: 'Represents an uploaded file',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n storageProvider: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n storagePath: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n checksum: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n width: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n height: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const FileVersionModel = defineSchemaModel({\n name: 'FileVersion',\n description: 'Represents a file version',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n version: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n storagePath: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n checksum: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n comment: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n createdBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const AttachmentModel = defineSchemaModel({\n name: 'Attachment',\n description: 'Represents an attachment',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n attachmentType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n order: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n createdBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n file: { type: FileModel, isOptional: true },\n },\n});\n\nexport const PresignedUrlModel = defineSchemaModel({\n name: 'PresignedUrl',\n description: 'A presigned URL for file operations',\n fields: {\n url: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fields: { type: ScalarTypeEnum.JSON(), isOptional: true },\n expiresAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n sessionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n// ============ Input/Output Models ============\n\nconst UploadFileInput = defineSchemaModel({\n name: 'UploadFileInput',\n description: 'Input for uploading a file',\n fields: {\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n content: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }, // Base64 encoded\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst UpdateFileInput = defineSchemaModel({\n name: 'UpdateFileInput',\n description: 'Input for updating a file',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n isPublic: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst DeleteFileInput = defineSchemaModel({\n name: 'DeleteFileInput',\n description: 'Input for deleting a file',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst GetFileInput = defineSchemaModel({\n name: 'GetFileInput',\n description: 'Input for getting a file',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst ListFilesInput = defineSchemaModel({\n name: 'ListFilesInput',\n description: 'Input for listing files',\n fields: {\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n offset: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nconst ListFilesOutput = defineSchemaModel({\n name: 'ListFilesOutput',\n description: 'Output for listing files',\n fields: {\n files: { type: FileModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nconst GetDownloadUrlInput = defineSchemaModel({\n name: 'GetDownloadUrlInput',\n description: 'Input for getting a download URL',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n expiresInSeconds: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nconst CreateVersionInput = defineSchemaModel({\n name: 'CreateVersionInput',\n description: 'Input for creating a file version',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n content: { type: ScalarTypeEnum.String_unsecure(), isOptional: false }, // Base64 encoded\n comment: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nconst GetVersionsInput = defineSchemaModel({\n name: 'GetVersionsInput',\n description: 'Input for getting file versions',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n offset: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nconst GetVersionsOutput = defineSchemaModel({\n name: 'GetVersionsOutput',\n description: 'Output for getting file versions',\n fields: {\n versions: { type: FileVersionModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nconst AttachFileInput = defineSchemaModel({\n name: 'AttachFileInput',\n description: 'Input for attaching a file to an entity',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n attachmentType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n order: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n metadata: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst DetachFileInput = defineSchemaModel({\n name: 'DetachFileInput',\n description: 'Input for detaching a file',\n fields: {\n attachmentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst ListAttachmentsInput = defineSchemaModel({\n name: 'ListAttachmentsInput',\n description: 'Input for listing attachments',\n fields: {\n entityType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n attachmentType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n },\n});\n\nconst ListAttachmentsOutput = defineSchemaModel({\n name: 'ListAttachmentsOutput',\n description: 'Output for listing attachments',\n fields: {\n attachments: { type: AttachmentModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nconst CreatePresignedUrlInput = defineSchemaModel({\n name: 'CreatePresignedUrlInput',\n description: 'Input for creating a presigned upload URL',\n fields: {\n fileName: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n expiresInSeconds: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nconst SuccessOutput = defineSchemaModel({\n name: 'SuccessOutput',\n description: 'Generic success output',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n});\n\n// ============ Contracts ============\n\n/**\n * Upload a file.\n */\nexport const UploadFileContract = defineCommand({\n meta: {\n key: 'file.upload',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'upload'],\n description: 'Upload a new file.',\n goal: 'Store a file and create a file record.',\n context: 'Called when uploading files directly.',\n },\n io: {\n input: UploadFileInput,\n output: FileModel,\n errors: {\n FILE_TOO_LARGE: {\n description: 'File exceeds size limit',\n http: 413,\n gqlCode: 'FILE_TOO_LARGE',\n when: 'File size exceeds configured limit',\n },\n INVALID_MIME_TYPE: {\n description: 'MIME type not allowed',\n http: 415,\n gqlCode: 'INVALID_MIME_TYPE',\n when: 'File type is not in allowed list',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Update a file.\n */\nexport const UpdateFileContract = defineCommand({\n meta: {\n key: 'file.update',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'update'],\n description: 'Update file metadata.',\n goal: 'Modify file properties without replacing content.',\n context: 'Called when renaming or updating file metadata.',\n },\n io: {\n input: UpdateFileInput,\n output: FileModel,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Delete a file.\n */\nexport const DeleteFileContract = defineCommand({\n meta: {\n key: 'file.delete',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'delete'],\n description: 'Delete a file.',\n goal: 'Remove a file and all its versions and attachments.',\n context: 'Called when removing a file permanently.',\n },\n io: {\n input: DeleteFileInput,\n output: SuccessOutput,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Get a file by ID.\n */\nexport const GetFileContract = defineQuery({\n meta: {\n key: 'file.get',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'get'],\n description: 'Get a file by ID.',\n goal: 'Retrieve file metadata.',\n context: 'Called to inspect file details.',\n },\n io: {\n input: GetFileInput,\n output: FileModel,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * List files.\n */\nexport const ListFilesContract = defineQuery({\n meta: {\n key: 'file.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'list'],\n description: 'List files with filtering.',\n goal: 'Browse uploaded files.',\n context: 'Called to browse file library.',\n },\n io: {\n input: ListFilesInput,\n output: ListFilesOutput,\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Get download URL.\n */\nexport const GetDownloadUrlContract = defineQuery({\n meta: {\n key: 'file.downloadUrl',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'download'],\n description: 'Get a presigned download URL.',\n goal: 'Generate a temporary URL for downloading.',\n context: 'Called when user wants to download a file.',\n },\n io: {\n input: GetDownloadUrlInput,\n output: PresignedUrlModel,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Create a file version.\n */\nexport const CreateVersionContract = defineCommand({\n meta: {\n key: 'file.version.create',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'version', 'create'],\n description: 'Create a new version of a file.',\n goal: 'Upload a new version while preserving history.',\n context: 'Called when updating a document.',\n },\n io: {\n input: CreateVersionInput,\n output: FileVersionModel,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Get file versions.\n */\nexport const GetVersionsContract = defineQuery({\n meta: {\n key: 'file.version.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'version', 'list'],\n description: 'Get file version history.',\n goal: 'View all versions of a file.',\n context: 'Called to browse file history.',\n },\n io: {\n input: GetVersionsInput,\n output: GetVersionsOutput,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Attach a file to an entity.\n */\nexport const AttachFileContract = defineCommand({\n meta: {\n key: 'attachment.attach',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'attachment', 'attach'],\n description: 'Attach a file to an entity.',\n goal: 'Link a file to a business entity.',\n context: 'Called when associating files with entities.',\n },\n io: {\n input: AttachFileInput,\n output: AttachmentModel,\n errors: {\n FILE_NOT_FOUND: {\n description: 'File does not exist',\n http: 404,\n gqlCode: 'FILE_NOT_FOUND',\n when: 'File ID is invalid',\n },\n ATTACHMENT_EXISTS: {\n description: 'Attachment already exists',\n http: 409,\n gqlCode: 'ATTACHMENT_EXISTS',\n when: 'File is already attached to this entity',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Detach a file from an entity.\n */\nexport const DetachFileContract = defineCommand({\n meta: {\n key: 'attachment.detach',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'attachment', 'detach'],\n description: 'Detach a file from an entity.',\n goal: 'Remove a file association.',\n context: 'Called when removing file from entity.',\n },\n io: {\n input: DetachFileInput,\n output: SuccessOutput,\n errors: {\n ATTACHMENT_NOT_FOUND: {\n description: 'Attachment does not exist',\n http: 404,\n gqlCode: 'ATTACHMENT_NOT_FOUND',\n when: 'Attachment ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * List attachments for an entity.\n */\nexport const ListAttachmentsContract = defineQuery({\n meta: {\n key: 'attachment.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'attachment', 'list'],\n description: 'List attachments for an entity.',\n goal: 'Get all files attached to an entity.',\n context: 'Called to display attached files.',\n },\n io: {\n input: ListAttachmentsInput,\n output: ListAttachmentsOutput,\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * Create a presigned upload URL.\n */\nexport const CreatePresignedUrlContract = defineCommand({\n meta: {\n key: 'file.presignedUrl.create',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['files', 'presigned', 'upload'],\n description: 'Create a presigned URL for direct upload.',\n goal: 'Enable direct-to-storage uploads.',\n context: 'Called for large file uploads.',\n },\n io: {\n input: CreatePresignedUrlInput,\n output: PresignedUrlModel,\n errors: {\n FILE_TOO_LARGE: {\n description: 'File exceeds size limit',\n http: 413,\n gqlCode: 'FILE_TOO_LARGE',\n when: 'Requested file size exceeds limit',\n },\n INVALID_MIME_TYPE: {\n description: 'MIME type not allowed',\n http: 415,\n gqlCode: 'INVALID_MIME_TYPE',\n when: 'File type is not in allowed list',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n"],"mappings":";;;;AAGA,MAAM,SAAS,CAAC,iBAAiB;AAIjC,MAAa,YAAY,kBAAkB;CACzC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACnE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,MAAM;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAChE,iBAAiB;GACf,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EAC1E,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,UAAU;GAAE,MAAM,eAAe,SAAS;GAAE,YAAY;GAAO;EAC/D,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,OAAO;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACnE,UAAU;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC3D,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAChE,QAAQ;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EACjE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACjE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAa,mBAAmB,kBAAkB;CAChD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,MAAM;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAChE,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EAC1E,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACrE,WAAW;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACxE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAa,kBAAkB,kBAAkB;CAC/C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EAClE,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACzE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACjE,UAAU;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC3D,WAAW;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACxE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACjE,MAAM;GAAE,MAAM;GAAW,YAAY;GAAM;EAC5C;CACF,CAAC;AAEF,MAAa,oBAAoB,kBAAkB;CACjD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,KAAK;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EAClE,QAAQ;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EACzD,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACjE,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACpE,WAAW;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACxE;CACF,CAAC;AAIF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACnE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,MAAM;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAChE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,OAAO;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACnE,UAAU;GAAE,MAAM,eAAe,SAAS;GAAE,YAAY;GAAM;EAC9D,UAAU;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC3D,MAAM;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EACxD;CACF,CAAC;AAEF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EAClE,UAAU;GAAE,MAAM,eAAe,SAAS;GAAE,YAAY;GAAM;EAC9D,UAAU;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC3D,MAAM;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EACxD;CACF,CAAC;AAEF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ,EACN,QAAQ;EAAE,MAAM,eAAe,iBAAiB;EAAE,YAAY;EAAO,EACtE;CACF,CAAC;AAEF,MAAM,eAAe,kBAAkB;CACrC,MAAM;CACN,aAAa;CACb,QAAQ,EACN,QAAQ;EAAE,MAAM,eAAe,iBAAiB;EAAE,YAAY;EAAO,EACtE;CACF,CAAC;AAEF,MAAM,iBAAiB,kBAAkB;CACvC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,OAAO;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACnE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACrE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACpE,MAAM;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EACvD,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAChE,QAAQ;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAClE;CACF,CAAC;AAEF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,OAAO;GAAE,MAAM;GAAW,SAAS;GAAM,YAAY;GAAO;EAC5D,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAM,sBAAsB,kBAAkB;CAC5C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,kBAAkB;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAC5E;CACF,CAAC;AAEF,MAAM,qBAAqB,kBAAkB;CAC3C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE;CACF,CAAC;AAEF,MAAM,mBAAmB,kBAAkB;CACzC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAChE,QAAQ;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAClE;CACF,CAAC;AAEF,MAAM,oBAAoB,kBAAkB;CAC1C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,UAAU;GAAE,MAAM;GAAkB,SAAS;GAAM,YAAY;GAAO;EACtE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ;EACN,QAAQ;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACrE,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,MAAM;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EAClE,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACzE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAChE,UAAU;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC5D;CACF,CAAC;AAEF,MAAM,kBAAkB,kBAAkB;CACxC,MAAM;CACN,aAAa;CACb,QAAQ,EACN,cAAc;EAAE,MAAM,eAAe,iBAAiB;EAAE,YAAY;EAAO,EAC5E;CACF,CAAC;AAEF,MAAM,uBAAuB,kBAAkB;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACF;CACF,CAAC;AAEF,MAAM,wBAAwB,kBAAkB;CAC9C,MAAM;CACN,aAAa;CACb,QAAQ;EACN,aAAa;GAAE,MAAM;GAAiB,SAAS;GAAM,YAAY;GAAO;EACxE,OAAO;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;AAEF,MAAM,0BAA0B,kBAAkB;CAChD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,MAAM;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EAChE,OAAO;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACnE,kBAAkB;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EAC5E;CACF,CAAC;AAEF,MAAM,gBAAgB,kBAAkB;CACtC,MAAM;CACN,aAAa;CACb,QAAQ,EACN,SAAS;EAAE,MAAM,eAAe,SAAS;EAAE,YAAY;EAAO,EAC/D;CACF,CAAC;;;;AAOF,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,SAAS;EACzB,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,gBAAgB;IACd,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,mBAAmB;IACjB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,SAAS;EACzB,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,SAAS;EACzB,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,kBAAkB,YAAY;CACzC,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,MAAM;EACtB,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,oBAAoB,YAAY;CAC3C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,OAAO;EACvB,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,yBAAyB,YAAY;CAChD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM,CAAC,SAAS,WAAW;EAC3B,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,wBAAwB,cAAc;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAW;GAAS;EACpC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,sBAAsB,YAAY;CAC7C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAW;GAAO;EAClC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,gBAAgB;GACd,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAc;GAAS;EACvC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,gBAAgB;IACd,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,mBAAmB;IACjB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,qBAAqB,cAAc;CAC9C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAc;GAAS;EACvC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ,EACN,sBAAsB;GACpB,aAAa;GACb,MAAM;GACN,SAAS;GACT,MAAM;GACP,EACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,0BAA0B,YAAY;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAc;GAAO;EACrC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACT;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC;;;;AAKF,MAAa,6BAA6B,cAAc;CACtD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,GAAG,OAAO;EACnB,MAAM;GAAC;GAAS;GAAa;GAAS;EACtC,aAAa;EACb,MAAM;EACN,SAAS;EACV;CACD,IAAI;EACF,OAAO;EACP,QAAQ;EACR,QAAQ;GACN,gBAAgB;IACd,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACD,mBAAmB;IACjB,aAAa;IACb,MAAM;IACN,SAAS;IACT,MAAM;IACP;GACF;EACF;CACD,QAAQ,EACN,MAAM,QACP;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"files.docblock.js","names":[],"sources":["../../src/docs/files.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@contractspec/lib.contracts/docs';\nimport { registerDocBlocks } from '@contractspec/lib.contracts/docs';\n\nconst filesDocBlocks: DocBlock[] = [\n {\n id: 'docs.files.attachments',\n title: 'Files, Versions & Attachments',\n summary:\n 'Spec-first file management with storage adapters, versioning, presigned URLs, and polymorphic attachments for any entity.',\n kind: 'reference',\n visibility: 'public',\n route: '/docs/files/attachments',\n tags: ['files', 'attachments', 'storage', 'versions'],\n body: `## Capabilities\n\n- **Entities**: File, FileVersion, Attachment, UploadSession with retention, checksum, ACLs.\n- **Contracts**: upload/update/delete/list/get files; presigned upload/download; version create/list; attach/detach/list attachments.\n- **Storage**: pluggable adapters (Local, S3 placeholder + interface), in-memory for tests.\n- **Events**: file.uploaded/deleted, attachment.added/removed (see events export).\n\n## Usage\n\n1) Compose schema\n- Include \\`filesSchemaContribution\\` in your schema composition.\n\n2) Register contracts/events\n- Import contracts and events from \\`@contractspec/lib.files\\` in your spec registry.\n\n3) Wire storage\n- Provide a \\`StorageAdapter\\` implementation (local/in-memory or S3 via custom impl).\n- Use \\`createStorageAdapter\\` with config to instantiate.\n\n4) Attach to domain entities\n- Use \\`attachment.attach\\` with \\`entityType/entityId\\` to link files to deals, orders, runs, etc.\n\n## Example\n\n${'```'}ts\nimport {\n UploadFileContract,\n AttachFileContract,\n InMemoryStorageAdapter,\n} from '@contractspec/lib.files';\n\n// storage\nconst storage = new InMemoryStorageAdapter();\n\n// upload\nconst file = await storage.upload({\n path: 'org-1/reports/r1.pdf',\n content: Buffer.from(pdfBytes),\n mimeType: 'application/pdf',\n});\n\n// attach\nawait AttachFileContract; // register in spec to enable attach flows\n${'```'},\n\n## Guardrails\n\n- Enforce size/MIME limits in your handlers; avoid storing PII in paths.\n- Keep \\`orgId\\` scoped for multi-tenant isolation; prefer presigned URLs for public delivery.\n- Persist checksums for integrity; emit audit + events for access/retention changes.\n`,\n },\n];\n\nregisterDocBlocks(filesDocBlocks);\n"],"mappings":";;;AAmEA,kBAhEmC,CACjC;CACE,IAAI;CACJ,OAAO;CACP,SACE;CACF,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EAAC;EAAS;EAAe;EAAW;EAAW;CACrD,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDP,CACF,CAEgC"}
@@ -1 +0,0 @@
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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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../src/events.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@contractspec/lib.schema';\nimport { defineEvent } from '@contractspec/lib.contracts';\n\n// ============ Event Payloads ============\n\nconst FileUploadedPayload = defineSchemaModel({\n name: 'FileUploadedEventPayload',\n description: 'Payload when a file is uploaded',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n storageProvider: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n uploadedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst FileUpdatedPayload = defineSchemaModel({\n name: 'FileUpdatedEventPayload',\n description: 'Payload when a file is updated',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n changes: { type: ScalarTypeEnum.JSON(), isOptional: false },\n updatedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst FileDeletedPayload = defineSchemaModel({\n name: 'FileDeletedEventPayload',\n description: 'Payload when a file is deleted',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n storageProvider: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n storagePath: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n deletedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n deletedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst FileVersionCreatedPayload = defineSchemaModel({\n name: 'FileVersionCreatedEventPayload',\n description: 'Payload when a file version is created',\n fields: {\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n versionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n version: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n createdBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n comment: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst AttachmentAttachedPayload = defineSchemaModel({\n name: 'AttachmentAttachedEventPayload',\n description: 'Payload when a file is attached to an entity',\n fields: {\n attachmentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n attachmentType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n attachedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n attachedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst AttachmentDetachedPayload = defineSchemaModel({\n name: 'AttachmentDetachedEventPayload',\n description: 'Payload when a file is detached from an entity',\n fields: {\n attachmentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n entityId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n detachedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n detachedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst UploadSessionStartedPayload = defineSchemaModel({\n name: 'UploadSessionStartedEventPayload',\n description: 'Payload when an upload session starts',\n fields: {\n sessionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileName: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mimeType: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n totalSize: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n ownerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nconst UploadSessionCompletedPayload = defineSchemaModel({\n name: 'UploadSessionCompletedEventPayload',\n description: 'Payload when an upload session completes',\n fields: {\n sessionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fileName: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n size: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n// ============ Events ============\n\n/**\n * Emitted when a file is uploaded.\n */\nexport const FileUploadedEvent = defineEvent({\n meta: {\n key: 'file.uploaded',\n version: '1.0.0',\n description: 'A file has been uploaded.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'upload'],\n },\n payload: FileUploadedPayload,\n});\n\n/**\n * Emitted when a file is updated.\n */\nexport const FileUpdatedEvent = defineEvent({\n meta: {\n key: 'file.updated',\n version: '1.0.0',\n description: 'A file has been updated.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'update'],\n },\n payload: FileUpdatedPayload,\n});\n\n/**\n * Emitted when a file is deleted.\n */\nexport const FileDeletedEvent = defineEvent({\n meta: {\n key: 'file.deleted',\n version: '1.0.0',\n description: 'A file has been deleted.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'delete'],\n },\n payload: FileDeletedPayload,\n});\n\n/**\n * Emitted when a file version is created.\n */\nexport const FileVersionCreatedEvent = defineEvent({\n meta: {\n key: 'file.version_created',\n version: '1.0.0',\n description: 'A new file version has been created.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'version', 'create'],\n },\n payload: FileVersionCreatedPayload,\n});\n\n/**\n * Emitted when a file is attached to an entity.\n */\nexport const AttachmentAttachedEvent = defineEvent({\n meta: {\n key: 'attachment.attached',\n version: '1.0.0',\n description: 'A file has been attached to an entity.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'attachment', 'attach'],\n },\n payload: AttachmentAttachedPayload,\n});\n\n/**\n * Emitted when a file is detached from an entity.\n */\nexport const AttachmentDetachedEvent = defineEvent({\n meta: {\n key: 'attachment.detached',\n version: '1.0.0',\n description: 'A file has been detached from an entity.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'attachment', 'detach'],\n },\n payload: AttachmentDetachedPayload,\n});\n\n/**\n * Emitted when an upload session starts.\n */\nexport const UploadSessionStartedEvent = defineEvent({\n meta: {\n key: 'upload.session_started',\n version: '1.0.0',\n description: 'An upload session has started.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'upload', 'session', 'start'],\n },\n payload: UploadSessionStartedPayload,\n});\n\n/**\n * Emitted when an upload session completes.\n */\nexport const UploadSessionCompletedEvent = defineEvent({\n meta: {\n key: 'upload.session_completed',\n version: '1.0.0',\n description: 'An upload session has completed.',\n stability: 'stable',\n owners: ['@platform.files'],\n tags: ['files', 'upload', 'session', 'complete'],\n },\n payload: UploadSessionCompletedPayload,\n});\n\n/**\n * All file events.\n */\nexport const FileEvents = {\n FileUploadedEvent,\n FileUpdatedEvent,\n FileDeletedEvent,\n FileVersionCreatedEvent,\n AttachmentAttachedEvent,\n AttachmentDetachedEvent,\n UploadSessionStartedEvent,\n UploadSessionCompletedEvent,\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
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 +0,0 @@
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 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"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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"}