@aphexcms/cms-core 0.1.11 → 0.1.12
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.
- package/dist/api/assets.d.ts +48 -0
- package/dist/api/assets.d.ts.map +1 -0
- package/dist/api/assets.js +52 -0
- package/dist/api/client.d.ts +37 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +125 -0
- package/dist/api/documents.d.ts +56 -0
- package/dist/api/documents.d.ts.map +1 -0
- package/dist/api/documents.js +77 -0
- package/dist/api/index.d.ts +7 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +5 -0
- package/dist/api/organizations.d.ts +101 -0
- package/dist/api/organizations.d.ts.map +1 -0
- package/dist/api/organizations.js +92 -0
- package/dist/api/types.d.ts +23 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +1 -0
- package/dist/auth/auth-errors.d.ts +7 -0
- package/dist/auth/auth-errors.d.ts.map +1 -0
- package/dist/auth/auth-errors.js +13 -0
- package/dist/auth/auth-hooks.d.ts +6 -0
- package/dist/auth/auth-hooks.d.ts.map +1 -0
- package/dist/auth/auth-hooks.js +108 -0
- package/dist/auth/provider.d.ts +17 -0
- package/dist/auth/provider.d.ts.map +1 -0
- package/dist/auth/provider.js +1 -0
- package/dist/client/index.d.ts +24 -0
- package/dist/client/index.d.ts.map +1 -0
- package/{src/lib/client/index.ts → dist/client/index.js} +7 -18
- package/dist/components/AdminApp.svelte.d.ts +26 -0
- package/dist/components/AdminApp.svelte.d.ts.map +1 -0
- package/dist/components/admin/AdminLayout.svelte.d.ts +15 -0
- package/dist/components/admin/AdminLayout.svelte.d.ts.map +1 -0
- package/dist/components/admin/DocumentEditor.svelte.d.ts +18 -0
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -0
- package/dist/components/admin/DocumentTypesList.svelte.d.ts +14 -0
- package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +1 -0
- package/dist/components/admin/ObjectModal.svelte.d.ts +15 -0
- package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -0
- package/dist/components/admin/SchemaField.svelte.d.ts +19 -0
- package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ArrayField.svelte.d.ts +12 -0
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/BooleanField.svelte.d.ts +13 -0
- package/dist/components/admin/fields/BooleanField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ImageField.svelte.d.ts +15 -0
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/NumberField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/NumberField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts +12 -0
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/SlugField.svelte.d.ts +15 -0
- package/dist/components/admin/fields/SlugField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/StringField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/TextareaField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/TextareaField.svelte.d.ts.map +1 -0
- package/dist/components/fields/index.d.ts +9 -0
- package/dist/components/fields/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/{src/lib/components/index.ts → dist/components/index.js} +1 -5
- package/dist/components/layout/OrganizationSwitcher.svelte.d.ts +11 -0
- package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +1 -0
- package/dist/components/layout/Sidebar.svelte.d.ts +14 -0
- package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -0
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +4 -0
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -0
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts +19 -0
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -0
- package/dist/components/layout/sidebar/NavSecondary.svelte.d.ts +9 -0
- package/dist/components/layout/sidebar/NavSecondary.svelte.d.ts.map +1 -0
- package/dist/components/layout/sidebar/NavUser.svelte.d.ts +9 -0
- package/dist/components/layout/sidebar/NavUser.svelte.d.ts.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +15 -0
- package/dist/db/adapters/index.d.ts +1 -0
- package/dist/db/adapters/index.d.ts.map +1 -0
- package/{src/lib/db/adapters/index.ts → dist/db/adapters/index.js} +1 -0
- package/dist/db/index.d.ts +2 -0
- package/dist/db/index.d.ts.map +1 -0
- package/{src/lib/db/index.ts → dist/db/index.js} +1 -2
- package/dist/db/interfaces/asset.d.ts +51 -0
- package/dist/db/interfaces/asset.d.ts.map +1 -0
- package/dist/db/interfaces/asset.js +1 -0
- package/dist/db/interfaces/document.d.ts +36 -0
- package/dist/db/interfaces/document.d.ts.map +1 -0
- package/dist/db/interfaces/document.js +1 -0
- package/dist/db/interfaces/index.d.ts +73 -0
- package/dist/db/interfaces/index.d.ts.map +1 -0
- package/dist/db/interfaces/index.js +1 -0
- package/dist/db/interfaces/organization.d.ts +27 -0
- package/dist/db/interfaces/organization.d.ts.map +1 -0
- package/dist/db/interfaces/organization.js +1 -0
- package/dist/db/interfaces/schema.d.ts +21 -0
- package/dist/db/interfaces/schema.d.ts.map +1 -0
- package/dist/db/interfaces/schema.js +1 -0
- package/dist/db/interfaces/user.d.ts +15 -0
- package/dist/db/interfaces/user.d.ts.map +1 -0
- package/dist/db/interfaces/user.js +1 -0
- package/dist/db/utils/reference-resolver.d.ts +18 -0
- package/dist/db/utils/reference-resolver.d.ts.map +1 -0
- package/dist/db/utils/reference-resolver.js +80 -0
- package/dist/define.d.ts +3 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +4 -0
- package/dist/email/index.d.ts +2 -0
- package/dist/email/index.d.ts.map +1 -0
- package/{src/lib/email/index.ts → dist/email/index.js} +1 -2
- package/dist/email/interfaces/email.d.ts +42 -0
- package/dist/email/interfaces/email.d.ts.map +1 -0
- package/dist/email/interfaces/email.js +1 -0
- package/dist/engine.d.ts +26 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +66 -0
- package/dist/field-validation/rule.d.ts +51 -0
- package/dist/field-validation/rule.d.ts.map +1 -0
- package/dist/field-validation/rule.js +221 -0
- package/dist/field-validation/utils.d.ts +21 -0
- package/dist/field-validation/utils.d.ts.map +1 -0
- package/dist/field-validation/utils.js +66 -0
- package/dist/hooks.d.ts +23 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +96 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/lib/index.ts → dist/index.js} +1 -2
- package/dist/is-mobile.svelte.d.ts +5 -0
- package/dist/is-mobile.svelte.d.ts.map +1 -0
- package/{src/lib/is-mobile.svelte.ts → dist/is-mobile.svelte.js} +3 -5
- package/dist/routes/assets-by-id.d.ts +5 -0
- package/dist/routes/assets-by-id.d.ts.map +1 -0
- package/dist/routes/assets-by-id.js +138 -0
- package/dist/routes/assets-cdn.d.ts +3 -0
- package/dist/routes/assets-cdn.d.ts.map +1 -0
- package/dist/routes/assets-cdn.js +155 -0
- package/dist/routes/assets.d.ts +4 -0
- package/dist/routes/assets.d.ts.map +1 -0
- package/dist/routes/assets.js +94 -0
- package/dist/routes/documents-by-id.d.ts +5 -0
- package/dist/routes/documents-by-id.d.ts.map +1 -0
- package/dist/routes/documents-by-id.js +142 -0
- package/dist/routes/documents-publish.d.ts +4 -0
- package/dist/routes/documents-publish.d.ts.map +1 -0
- package/dist/routes/documents-publish.js +151 -0
- package/dist/routes/documents.d.ts +4 -0
- package/dist/routes/documents.d.ts.map +1 -0
- package/dist/routes/documents.js +131 -0
- package/dist/routes/index.d.ts +6 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +10 -0
- package/dist/routes/organizations-by-id.d.ts +5 -0
- package/dist/routes/organizations-by-id.d.ts.map +1 -0
- package/dist/routes/organizations-by-id.js +187 -0
- package/dist/routes/organizations-invitations.d.ts +4 -0
- package/dist/routes/organizations-invitations.d.ts.map +1 -0
- package/dist/routes/organizations-invitations.js +125 -0
- package/dist/routes/organizations-members.d.ts +5 -0
- package/dist/routes/organizations-members.d.ts.map +1 -0
- package/dist/routes/organizations-members.js +206 -0
- package/dist/routes/organizations-switch.d.ts +3 -0
- package/dist/routes/organizations-switch.d.ts.map +1 -0
- package/dist/routes/organizations-switch.js +53 -0
- package/dist/routes/organizations.d.ts +4 -0
- package/dist/routes/organizations.d.ts.map +1 -0
- package/dist/routes/organizations.js +109 -0
- package/dist/routes/schemas-by-type.d.ts +3 -0
- package/dist/routes/schemas-by-type.d.ts.map +1 -0
- package/dist/routes/schemas-by-type.js +25 -0
- package/dist/routes/schemas.d.ts +3 -0
- package/dist/routes/schemas.d.ts.map +1 -0
- package/dist/routes/schemas.js +11 -0
- package/dist/routes-exports.d.ts +14 -0
- package/dist/routes-exports.d.ts.map +1 -0
- package/dist/routes-exports.js +19 -0
- package/dist/schema-context.svelte.d.ts +10 -0
- package/dist/schema-context.svelte.d.ts.map +1 -0
- package/dist/schema-context.svelte.js +18 -0
- package/dist/schema-utils/cleanup.d.ts +21 -0
- package/dist/schema-utils/cleanup.d.ts.map +1 -0
- package/dist/schema-utils/cleanup.js +80 -0
- package/dist/schema-utils/index.d.ts +4 -0
- package/dist/schema-utils/index.d.ts.map +1 -0
- package/dist/schema-utils/index.js +4 -0
- package/dist/schema-utils/utils.d.ts +30 -0
- package/dist/schema-utils/utils.d.ts.map +1 -0
- package/dist/schema-utils/utils.js +37 -0
- package/dist/schema-utils/validator.d.ts +6 -0
- package/dist/schema-utils/validator.d.ts.map +1 -0
- package/dist/schema-utils/validator.js +45 -0
- package/dist/server/index.d.ts +16 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +28 -0
- package/dist/services/asset-service.d.ts +86 -0
- package/dist/services/asset-service.d.ts.map +1 -0
- package/dist/services/asset-service.js +187 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +4 -0
- package/dist/storage/adapters/index.d.ts +2 -0
- package/dist/storage/adapters/index.d.ts.map +1 -0
- package/dist/storage/adapters/index.js +2 -0
- package/dist/storage/adapters/local-storage-adapter.d.ts +54 -0
- package/dist/storage/adapters/local-storage-adapter.d.ts.map +1 -0
- package/dist/storage/adapters/local-storage-adapter.js +187 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/{src/lib/storage/index.ts → dist/storage/index.js} +2 -4
- package/dist/storage/interfaces/index.d.ts +2 -0
- package/dist/storage/interfaces/index.d.ts.map +1 -0
- package/dist/storage/interfaces/index.js +2 -0
- package/dist/storage/interfaces/storage.d.ts +91 -0
- package/dist/storage/interfaces/storage.d.ts.map +1 -0
- package/dist/storage/interfaces/storage.js +1 -0
- package/dist/storage/providers/storage.d.ts +43 -0
- package/dist/storage/providers/storage.d.ts.map +1 -0
- package/dist/storage/providers/storage.js +64 -0
- package/dist/types/asset.d.ts +73 -0
- package/dist/types/asset.d.ts.map +1 -0
- package/dist/types/asset.js +2 -0
- package/dist/types/auth.d.ts +50 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +41 -0
- package/dist/types/config.d.ts +47 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +1 -0
- package/dist/types/document.d.ts +34 -0
- package/dist/types/document.d.ts.map +1 -0
- package/dist/types/document.js +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/organization.d.ts +105 -0
- package/dist/types/organization.d.ts.map +1 -0
- package/dist/types/organization.js +3 -0
- package/dist/types/schemas.d.ts +119 -0
- package/dist/types/schemas.d.ts.map +1 -0
- package/dist/types/schemas.js +1 -0
- package/dist/types/sidebar.d.ts +33 -0
- package/dist/types/sidebar.d.ts.map +1 -0
- package/dist/types/sidebar.js +1 -0
- package/dist/types/user.d.ts +14 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +1 -0
- package/dist/utils/content-hash.d.ts +22 -0
- package/dist/utils/content-hash.d.ts.map +1 -0
- package/dist/utils/content-hash.js +67 -0
- package/dist/utils/image-url.d.ts +88 -0
- package/dist/utils/image-url.d.ts.map +1 -0
- package/dist/utils/image-url.js +165 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/slug.d.ts +13 -0
- package/dist/utils/slug.d.ts.map +1 -0
- package/dist/utils/slug.js +30 -0
- package/dist/utils.d.ts +13 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +5 -0
- package/package.json +2 -2
- package/src/lib/api/assets.ts +0 -75
- package/src/lib/api/client.ts +0 -150
- package/src/lib/api/documents.ts +0 -102
- package/src/lib/api/index.ts +0 -7
- package/src/lib/api/organizations.ts +0 -154
- package/src/lib/api/types.ts +0 -34
- package/src/lib/auth/auth-errors.ts +0 -23
- package/src/lib/auth/auth-hooks.ts +0 -132
- package/src/lib/auth/provider.ts +0 -25
- package/src/lib/config.ts +0 -18
- package/src/lib/db/interfaces/asset.ts +0 -61
- package/src/lib/db/interfaces/document.ts +0 -53
- package/src/lib/db/interfaces/index.ts +0 -98
- package/src/lib/db/interfaces/organization.ts +0 -51
- package/src/lib/db/interfaces/schema.ts +0 -13
- package/src/lib/db/interfaces/user.ts +0 -16
- package/src/lib/db/utils/reference-resolver.ts +0 -119
- package/src/lib/define.ts +0 -7
- package/src/lib/email/interfaces/email.ts +0 -45
- package/src/lib/engine.ts +0 -85
- package/src/lib/field-validation/rule.ts +0 -287
- package/src/lib/field-validation/utils.ts +0 -91
- package/src/lib/hooks.ts +0 -142
- package/src/lib/routes/assets-by-id.ts +0 -161
- package/src/lib/routes/assets-cdn.ts +0 -185
- package/src/lib/routes/assets.ts +0 -116
- package/src/lib/routes/documents-by-id.ts +0 -188
- package/src/lib/routes/documents-publish.ts +0 -211
- package/src/lib/routes/documents.ts +0 -172
- package/src/lib/routes/index.ts +0 -13
- package/src/lib/routes/organizations-by-id.ts +0 -258
- package/src/lib/routes/organizations-invitations.ts +0 -183
- package/src/lib/routes/organizations-members.ts +0 -301
- package/src/lib/routes/organizations-switch.ts +0 -74
- package/src/lib/routes/organizations.ts +0 -147
- package/src/lib/routes/schemas-by-type.ts +0 -35
- package/src/lib/routes/schemas.ts +0 -19
- package/src/lib/routes-exports.ts +0 -42
- package/src/lib/schema-context.svelte.ts +0 -24
- package/src/lib/schema-utils/cleanup.ts +0 -116
- package/src/lib/schema-utils/index.ts +0 -4
- package/src/lib/schema-utils/utils.ts +0 -47
- package/src/lib/schema-utils/validator.ts +0 -58
- package/src/lib/server/index.ts +0 -40
- package/src/lib/services/asset-service.ts +0 -256
- package/src/lib/services/index.ts +0 -6
- package/src/lib/storage/adapters/index.ts +0 -2
- package/src/lib/storage/adapters/local-storage-adapter.ts +0 -215
- package/src/lib/storage/interfaces/index.ts +0 -2
- package/src/lib/storage/interfaces/storage.ts +0 -114
- package/src/lib/storage/providers/storage.ts +0 -83
- package/src/lib/types/asset.ts +0 -81
- package/src/lib/types/auth.ts +0 -80
- package/src/lib/types/config.ts +0 -45
- package/src/lib/types/document.ts +0 -38
- package/src/lib/types/index.ts +0 -8
- package/src/lib/types/organization.ts +0 -119
- package/src/lib/types/schemas.ts +0 -156
- package/src/lib/types/sidebar.ts +0 -37
- package/src/lib/types/user.ts +0 -17
- package/src/lib/utils/content-hash.ts +0 -75
- package/src/lib/utils/image-url.ts +0 -204
- package/src/lib/utils/index.ts +0 -12
- package/src/lib/utils/slug.ts +0 -33
- package/src/lib/utils.ts +0 -13
- /package/{src/lib → dist}/app.d.ts +0 -0
- /package/{src/lib → dist}/auth/MULTI_TENANCY_PLAN.md +0 -0
- /package/{src/lib → dist}/components/AdminApp.svelte +0 -0
- /package/{src/lib → dist}/components/admin/AdminLayout.svelte +0 -0
- /package/{src/lib → dist}/components/admin/DocumentEditor.svelte +0 -0
- /package/{src/lib → dist}/components/admin/DocumentTypesList.svelte +0 -0
- /package/{src/lib → dist}/components/admin/ObjectModal.svelte +0 -0
- /package/{src/lib → dist}/components/admin/SchemaField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/ArrayField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/BooleanField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/ImageField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/NumberField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/ReferenceField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/SlugField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/StringField.svelte +0 -0
- /package/{src/lib → dist}/components/admin/fields/TextareaField.svelte +0 -0
- /package/{src/lib/components/fields/index.ts → dist/components/fields/index.js} +0 -0
- /package/{src/lib → dist}/components/layout/OrganizationSwitcher.svelte +0 -0
- /package/{src/lib → dist}/components/layout/Sidebar.svelte +0 -0
- /package/{src/lib → dist}/components/layout/sidebar/AppSidebar.svelte +0 -0
- /package/{src/lib → dist}/components/layout/sidebar/NavMain.svelte +0 -0
- /package/{src/lib → dist}/components/layout/sidebar/NavSecondary.svelte +0 -0
- /package/{src/lib → dist}/components/layout/sidebar/NavUser.svelte +0 -0
- /package/{src/lib → dist}/plugins/README.md +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// Pure local file system storage adapter - no database operations
|
|
2
|
+
import { writeFile, mkdir, unlink, stat, readdir } from 'fs/promises';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
5
|
+
const DEFAULT_ALLOWED_TYPES = [
|
|
6
|
+
'image/jpeg',
|
|
7
|
+
'image/png',
|
|
8
|
+
'image/webp',
|
|
9
|
+
'image/gif',
|
|
10
|
+
'image/avif',
|
|
11
|
+
'application/pdf',
|
|
12
|
+
'text/plain'
|
|
13
|
+
];
|
|
14
|
+
/**
|
|
15
|
+
* Pure local file system storage adapter - only handles files
|
|
16
|
+
*/
|
|
17
|
+
export class LocalStorageAdapter {
|
|
18
|
+
name = 'local';
|
|
19
|
+
config;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = {
|
|
22
|
+
basePath: config.basePath,
|
|
23
|
+
baseUrl: config.baseUrl || '',
|
|
24
|
+
maxFileSize: config.maxFileSize || DEFAULT_MAX_FILE_SIZE,
|
|
25
|
+
allowedTypes: config.allowedTypes || DEFAULT_ALLOWED_TYPES,
|
|
26
|
+
options: config.options || {}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generate unique filename preserving original name
|
|
31
|
+
*/
|
|
32
|
+
async generateUniqueFilename(originalFilename) {
|
|
33
|
+
const { name, ext } = this.parseFilename(originalFilename);
|
|
34
|
+
let filename = originalFilename;
|
|
35
|
+
let counter = 1;
|
|
36
|
+
// Check if file exists on disk
|
|
37
|
+
while (await this.fileExistsOnDisk(filename)) {
|
|
38
|
+
filename = `${name} (${counter})${ext}`;
|
|
39
|
+
counter++;
|
|
40
|
+
}
|
|
41
|
+
return filename;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse filename into name and extension
|
|
45
|
+
*/
|
|
46
|
+
parseFilename(filename) {
|
|
47
|
+
const lastDotIndex = filename.lastIndexOf('.');
|
|
48
|
+
if (lastDotIndex === -1) {
|
|
49
|
+
return { name: filename, ext: '' };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
name: filename.substring(0, lastDotIndex),
|
|
53
|
+
ext: filename.substring(lastDotIndex)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if file exists on disk
|
|
58
|
+
*/
|
|
59
|
+
async fileExistsOnDisk(filename) {
|
|
60
|
+
try {
|
|
61
|
+
const filePath = join(this.config.basePath, filename);
|
|
62
|
+
await stat(filePath);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Store a file and return storage info
|
|
71
|
+
*/
|
|
72
|
+
async store(data) {
|
|
73
|
+
// Validate file type
|
|
74
|
+
if (!this.config.allowedTypes.includes(data.mimeType)) {
|
|
75
|
+
throw new Error(`Invalid file type: ${data.mimeType}. Allowed types: ${this.config.allowedTypes.join(', ')}`);
|
|
76
|
+
}
|
|
77
|
+
// Validate file size
|
|
78
|
+
if (data.size > this.config.maxFileSize) {
|
|
79
|
+
throw new Error(`File too large: ${data.size} bytes. Maximum size: ${this.config.maxFileSize} bytes`);
|
|
80
|
+
}
|
|
81
|
+
// Generate unique filename
|
|
82
|
+
const filename = await this.generateUniqueFilename(data.filename);
|
|
83
|
+
const filePath = join(this.config.basePath, filename);
|
|
84
|
+
// Store internal path only - URL will be generated by API with asset ID
|
|
85
|
+
// This forces all access through /assets/{id} for proper authorization
|
|
86
|
+
const url = ''; // Will be populated as /assets/{assetId}/{filename} by the API
|
|
87
|
+
console.log('[LocalStorageAdapter] Storing file:', {
|
|
88
|
+
filename,
|
|
89
|
+
filePath,
|
|
90
|
+
note: 'URL will be generated as /assets/{assetId}/{filename}',
|
|
91
|
+
basePath: this.config.basePath
|
|
92
|
+
});
|
|
93
|
+
// Ensure storage directory exists
|
|
94
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
95
|
+
// Save file to disk
|
|
96
|
+
await writeFile(filePath, data.buffer);
|
|
97
|
+
return {
|
|
98
|
+
path: filePath,
|
|
99
|
+
url, // Empty - API will generate clean URL with asset ID
|
|
100
|
+
size: data.size
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Read a file from storage
|
|
105
|
+
* Used by API endpoint to serve files
|
|
106
|
+
*/
|
|
107
|
+
async getObject(path) {
|
|
108
|
+
const { readFile } = await import('fs/promises');
|
|
109
|
+
return await readFile(path);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Delete a file from storage
|
|
113
|
+
*/
|
|
114
|
+
async delete(path) {
|
|
115
|
+
try {
|
|
116
|
+
await unlink(path);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.warn('Could not delete file from disk:', error);
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if file exists
|
|
126
|
+
*/
|
|
127
|
+
async exists(path) {
|
|
128
|
+
try {
|
|
129
|
+
await stat(path);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get public URL for a file path
|
|
138
|
+
*/
|
|
139
|
+
getUrl(path) {
|
|
140
|
+
// Extract filename from path and construct URL
|
|
141
|
+
const filename = path.split('/').pop() || '';
|
|
142
|
+
return `${this.config.baseUrl}/${encodeURIComponent(filename)}`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get storage information
|
|
146
|
+
*/
|
|
147
|
+
async getStorageInfo() {
|
|
148
|
+
try {
|
|
149
|
+
// Calculate total size of files in storage directory
|
|
150
|
+
const files = await readdir(this.config.basePath);
|
|
151
|
+
let totalSize = 0;
|
|
152
|
+
for (const file of files) {
|
|
153
|
+
try {
|
|
154
|
+
const filePath = join(this.config.basePath, file);
|
|
155
|
+
const stats = await stat(filePath);
|
|
156
|
+
if (stats.isFile()) {
|
|
157
|
+
totalSize += stats.size;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Skip files that can't be read
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { totalSize };
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
console.error('Error getting storage info:', error);
|
|
168
|
+
return { totalSize: 0 };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Health check - test if we can write to storage
|
|
173
|
+
*/
|
|
174
|
+
async isHealthy() {
|
|
175
|
+
try {
|
|
176
|
+
const testFile = join(this.config.basePath, `health-check-${Date.now()}.tmp`);
|
|
177
|
+
await mkdir(dirname(testFile), { recursive: true });
|
|
178
|
+
await writeFile(testFile, 'health check');
|
|
179
|
+
await unlink(testFile);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Storage health check failed:', error);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/storage/index.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Aphex CMS Storage Layer
|
|
2
2
|
// Ports and adapters for file storage operations
|
|
3
|
-
|
|
4
3
|
// Interfaces
|
|
5
|
-
export * from './interfaces/index';
|
|
6
|
-
|
|
4
|
+
export * from './interfaces/index.js';
|
|
7
5
|
// Adapters
|
|
8
|
-
export * from './adapters/index';
|
|
6
|
+
export * from './adapters/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/interfaces/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export interface StorageFile {
|
|
2
|
+
path: string;
|
|
3
|
+
url: string;
|
|
4
|
+
size: number;
|
|
5
|
+
}
|
|
6
|
+
export interface UploadFileData {
|
|
7
|
+
buffer: Buffer;
|
|
8
|
+
filename: string;
|
|
9
|
+
mimeType: string;
|
|
10
|
+
size: number;
|
|
11
|
+
}
|
|
12
|
+
export interface StorageConfig {
|
|
13
|
+
basePath: string;
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
maxFileSize?: number;
|
|
16
|
+
allowedTypes?: string[];
|
|
17
|
+
options?: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface StorageObjectMetadata {
|
|
22
|
+
key: string;
|
|
23
|
+
size: number;
|
|
24
|
+
lastModified: Date;
|
|
25
|
+
contentType?: string;
|
|
26
|
+
etag?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ListObjectsOptions {
|
|
29
|
+
prefix?: string;
|
|
30
|
+
maxKeys?: number;
|
|
31
|
+
continuationToken?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ListObjectsResult {
|
|
34
|
+
objects: StorageObjectMetadata[];
|
|
35
|
+
isTruncated: boolean;
|
|
36
|
+
continuationToken?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Pure storage interface - only handles file operations
|
|
40
|
+
* No database operations - completely agnostic
|
|
41
|
+
*/
|
|
42
|
+
export interface StorageAdapter {
|
|
43
|
+
readonly name: string;
|
|
44
|
+
store(data: UploadFileData): Promise<StorageFile>;
|
|
45
|
+
delete(path: string): Promise<boolean>;
|
|
46
|
+
exists(path: string): Promise<boolean>;
|
|
47
|
+
getUrl(path: string): string;
|
|
48
|
+
getStorageInfo(): Promise<{
|
|
49
|
+
totalSize: number;
|
|
50
|
+
availableSpace?: number;
|
|
51
|
+
}>;
|
|
52
|
+
isHealthy(): Promise<boolean>;
|
|
53
|
+
connect?(): Promise<void>;
|
|
54
|
+
disconnect?(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve file contents as Buffer
|
|
57
|
+
* Useful for: image processing, transformations, backups, migrations
|
|
58
|
+
*/
|
|
59
|
+
getObject?(path: string): Promise<Buffer>;
|
|
60
|
+
/**
|
|
61
|
+
* List objects in storage with optional filtering
|
|
62
|
+
* Useful for: admin UI file browser, asset management, cleanup operations
|
|
63
|
+
*/
|
|
64
|
+
listObjects?(options?: ListObjectsOptions): Promise<ListObjectsResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Copy/duplicate an object within storage
|
|
67
|
+
* Useful for: versioning, backups, image variant generation
|
|
68
|
+
*/
|
|
69
|
+
copyObject?(sourcePath: string, destPath: string): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Get object metadata without downloading the file
|
|
72
|
+
* Useful for: verifying file integrity, checking size/type
|
|
73
|
+
*/
|
|
74
|
+
getObjectMetadata?(path: string): Promise<StorageObjectMetadata>;
|
|
75
|
+
/**
|
|
76
|
+
* Generate a signed URL for temporary access to a file
|
|
77
|
+
* Useful for: access control, private files, secure downloads
|
|
78
|
+
* @param path - File path
|
|
79
|
+
* @param expiresIn - Expiration time in seconds (default: 3600)
|
|
80
|
+
* @returns Signed URL that expires after the specified time
|
|
81
|
+
*/
|
|
82
|
+
getSignedUrl?(path: string, expiresIn?: number): Promise<string>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Storage provider factory interface
|
|
86
|
+
*/
|
|
87
|
+
export interface StorageProvider {
|
|
88
|
+
name: string;
|
|
89
|
+
createAdapter(config: StorageConfig): StorageAdapter;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/interfaces/storage.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE;QACT,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACnB,CAAC;CACF;AAED,MAAM,WAAW,qBAAqB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,IAAI,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAE9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAGtB,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAG7B,cAAc,IAAI,OAAO,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IAGH,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG9B,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAI7B;;;OAGG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C;;;OAGG;IACH,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEvE;;;OAGG;IACH,UAAU,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpE;;;OAGG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,CAAC;CACrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { StorageAdapter, StorageProvider, StorageConfig } from '../interfaces/storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* Local file system provider
|
|
4
|
+
*/
|
|
5
|
+
export declare class LocalStorageProvider implements StorageProvider {
|
|
6
|
+
name: string;
|
|
7
|
+
createAdapter(config: StorageConfig): StorageAdapter;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Storage provider registry
|
|
11
|
+
*/
|
|
12
|
+
declare class StorageProviderRegistry {
|
|
13
|
+
private providers;
|
|
14
|
+
constructor();
|
|
15
|
+
register(provider: StorageProvider): void;
|
|
16
|
+
get(name: string): StorageProvider | undefined;
|
|
17
|
+
list(): string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Global storage provider registry
|
|
21
|
+
*
|
|
22
|
+
* External packages can register custom storage providers:
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { storageProviders } from '@aphexcms/cms-core/server';
|
|
27
|
+
* import { R2StorageProvider } from '@aphexcms/storage-r2';
|
|
28
|
+
*
|
|
29
|
+
* // Register before creating config
|
|
30
|
+
* storageProviders.register(new R2StorageProvider());
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const storageProviders: StorageProviderRegistry;
|
|
34
|
+
/**
|
|
35
|
+
* Factory function to create storage adapters
|
|
36
|
+
*/
|
|
37
|
+
export declare function createStorageAdapter(providerName: string, config: StorageConfig): StorageAdapter;
|
|
38
|
+
/**
|
|
39
|
+
* Convenience function for local storage
|
|
40
|
+
*/
|
|
41
|
+
export declare function createLocalStorageAdapter(basePath: string, options?: Partial<StorageConfig>): StorageAdapter;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/providers/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG5F;;GAEG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC3D,IAAI,SAAW;IAEf,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;CAGpD;AAED;;GAEG;AACH,cAAM,uBAAuB;IAC5B,OAAO,CAAC,SAAS,CAAsC;;IAOvD,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAIzC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI9C,IAAI,IAAI,MAAM,EAAE;CAGhB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,yBAAgC,CAAC;AAE9D;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,cAAc,CAWhG;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC9B,cAAc,CAKhB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { LocalStorageAdapter } from '../adapters/local-storage-adapter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Local file system provider
|
|
4
|
+
*/
|
|
5
|
+
export class LocalStorageProvider {
|
|
6
|
+
name = 'local';
|
|
7
|
+
createAdapter(config) {
|
|
8
|
+
return new LocalStorageAdapter(config);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Storage provider registry
|
|
13
|
+
*/
|
|
14
|
+
class StorageProviderRegistry {
|
|
15
|
+
providers = new Map();
|
|
16
|
+
constructor() {
|
|
17
|
+
// Register built-in providers
|
|
18
|
+
this.register(new LocalStorageProvider());
|
|
19
|
+
}
|
|
20
|
+
register(provider) {
|
|
21
|
+
this.providers.set(provider.name.toLowerCase(), provider);
|
|
22
|
+
}
|
|
23
|
+
get(name) {
|
|
24
|
+
return this.providers.get(name.toLowerCase());
|
|
25
|
+
}
|
|
26
|
+
list() {
|
|
27
|
+
return Array.from(this.providers.keys());
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Global storage provider registry
|
|
32
|
+
*
|
|
33
|
+
* External packages can register custom storage providers:
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { storageProviders } from '@aphexcms/cms-core/server';
|
|
38
|
+
* import { R2StorageProvider } from '@aphexcms/storage-r2';
|
|
39
|
+
*
|
|
40
|
+
* // Register before creating config
|
|
41
|
+
* storageProviders.register(new R2StorageProvider());
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export const storageProviders = new StorageProviderRegistry();
|
|
45
|
+
/**
|
|
46
|
+
* Factory function to create storage adapters
|
|
47
|
+
*/
|
|
48
|
+
export function createStorageAdapter(providerName, config) {
|
|
49
|
+
const provider = storageProviders.get(providerName);
|
|
50
|
+
if (!provider) {
|
|
51
|
+
const available = storageProviders.list();
|
|
52
|
+
throw new Error(`Unknown storage provider: ${providerName}. Available providers: ${available.join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
return provider.createAdapter(config);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convenience function for local storage
|
|
58
|
+
*/
|
|
59
|
+
export function createLocalStorageAdapter(basePath, options) {
|
|
60
|
+
return createStorageAdapter('local', {
|
|
61
|
+
basePath,
|
|
62
|
+
...options
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset type - represents uploaded files
|
|
3
|
+
*/
|
|
4
|
+
export interface Asset {
|
|
5
|
+
id: string;
|
|
6
|
+
organizationId: string;
|
|
7
|
+
assetType: string;
|
|
8
|
+
filename: string;
|
|
9
|
+
originalFilename: string;
|
|
10
|
+
mimeType: string;
|
|
11
|
+
size: number;
|
|
12
|
+
url: string;
|
|
13
|
+
path: string;
|
|
14
|
+
storageAdapter: string;
|
|
15
|
+
width: number | null;
|
|
16
|
+
height: number | null;
|
|
17
|
+
metadata: any;
|
|
18
|
+
title: string | null;
|
|
19
|
+
description: string | null;
|
|
20
|
+
alt: string | null;
|
|
21
|
+
creditLine: string | null;
|
|
22
|
+
createdBy: string | null;
|
|
23
|
+
createdAt: Date | null;
|
|
24
|
+
updatedAt: Date | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* New asset input type
|
|
28
|
+
*/
|
|
29
|
+
export interface NewAsset {
|
|
30
|
+
id?: string;
|
|
31
|
+
assetType: string;
|
|
32
|
+
filename: string;
|
|
33
|
+
originalFilename: string;
|
|
34
|
+
mimeType: string;
|
|
35
|
+
size: number;
|
|
36
|
+
url: string;
|
|
37
|
+
path: string;
|
|
38
|
+
storageAdapter: string;
|
|
39
|
+
width?: number | null;
|
|
40
|
+
height?: number | null;
|
|
41
|
+
metadata?: any;
|
|
42
|
+
title?: string | null;
|
|
43
|
+
description?: string | null;
|
|
44
|
+
alt?: string | null;
|
|
45
|
+
creditLine?: string | null;
|
|
46
|
+
createdBy?: string | null;
|
|
47
|
+
createdAt?: Date | null;
|
|
48
|
+
updatedAt?: Date | null;
|
|
49
|
+
}
|
|
50
|
+
export interface ImageAsset {
|
|
51
|
+
_type: 'reference';
|
|
52
|
+
_ref: string;
|
|
53
|
+
}
|
|
54
|
+
export interface ImageCrop {
|
|
55
|
+
top: number;
|
|
56
|
+
bottom: number;
|
|
57
|
+
left: number;
|
|
58
|
+
right: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ImageHotspot {
|
|
61
|
+
x: number;
|
|
62
|
+
y: number;
|
|
63
|
+
height: number;
|
|
64
|
+
width: number;
|
|
65
|
+
}
|
|
66
|
+
export interface ImageValue {
|
|
67
|
+
_type: 'image';
|
|
68
|
+
asset: ImageAsset;
|
|
69
|
+
crop?: ImageCrop;
|
|
70
|
+
hotspot?: ImageHotspot;
|
|
71
|
+
[key: string]: any;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/lib/types/asset.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,KAAK;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAGD,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { CMSUser } from './user.js';
|
|
2
|
+
import type { OrganizationRole } from './organization.js';
|
|
3
|
+
export interface SessionAuth {
|
|
4
|
+
type: 'session';
|
|
5
|
+
user: CMSUser;
|
|
6
|
+
session: {
|
|
7
|
+
id: string;
|
|
8
|
+
expiresAt: Date;
|
|
9
|
+
};
|
|
10
|
+
organizationId: string;
|
|
11
|
+
organizationRole: OrganizationRole;
|
|
12
|
+
organizations?: Array<{
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
slug: string;
|
|
16
|
+
role: OrganizationRole;
|
|
17
|
+
isActive: boolean;
|
|
18
|
+
metadata?: any;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
export interface ApiKeyAuth {
|
|
22
|
+
type: 'api_key';
|
|
23
|
+
keyId: string;
|
|
24
|
+
name: string;
|
|
25
|
+
permissions: ('read' | 'write')[];
|
|
26
|
+
organizationId: string;
|
|
27
|
+
environment?: string;
|
|
28
|
+
lastUsedAt?: Date;
|
|
29
|
+
}
|
|
30
|
+
export type Auth = SessionAuth | ApiKeyAuth;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a user has write permissions based on their organization role
|
|
33
|
+
* Viewers have read-only access
|
|
34
|
+
*/
|
|
35
|
+
export declare function canWrite(auth: Auth): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a user can manage organization members
|
|
38
|
+
* Only owners and admins can manage members
|
|
39
|
+
*/
|
|
40
|
+
export declare function canManageMembers(auth: Auth): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a user can manage API keys
|
|
43
|
+
* Only owners and admins can manage API keys
|
|
44
|
+
*/
|
|
45
|
+
export declare function canManageApiKeys(auth: Auth): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a user is a viewer (read-only access)
|
|
48
|
+
*/
|
|
49
|
+
export declare function isViewer(auth: Auth): boolean;
|
|
50
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/types/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,IAAI,CAAC;KAChB,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,CAAC,EAAE,KAAK,CAAC;QACrB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,gBAAgB,CAAC;QACvB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,GAAG,CAAC;KACf,CAAC,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,MAAM,IAAI,GAAG,WAAW,GAAG,UAAU,CAAC;AAI5C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAM5C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAKpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAKpD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAK5C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Access control utilities
|
|
2
|
+
/**
|
|
3
|
+
* Check if a user has write permissions based on their organization role
|
|
4
|
+
* Viewers have read-only access
|
|
5
|
+
*/
|
|
6
|
+
export function canWrite(auth) {
|
|
7
|
+
if (auth.type === 'api_key') {
|
|
8
|
+
return auth.permissions.includes('write');
|
|
9
|
+
}
|
|
10
|
+
// Viewers are read-only
|
|
11
|
+
return auth.organizationRole !== 'viewer';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check if a user can manage organization members
|
|
15
|
+
* Only owners and admins can manage members
|
|
16
|
+
*/
|
|
17
|
+
export function canManageMembers(auth) {
|
|
18
|
+
if (auth.type === 'api_key') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return auth.organizationRole === 'owner' || auth.organizationRole === 'admin';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if a user can manage API keys
|
|
25
|
+
* Only owners and admins can manage API keys
|
|
26
|
+
*/
|
|
27
|
+
export function canManageApiKeys(auth) {
|
|
28
|
+
if (auth.type === 'api_key') {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return auth.organizationRole === 'owner' || auth.organizationRole === 'admin';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if a user is a viewer (read-only access)
|
|
35
|
+
*/
|
|
36
|
+
export function isViewer(auth) {
|
|
37
|
+
if (auth.type === 'api_key') {
|
|
38
|
+
return !auth.permissions.includes('write');
|
|
39
|
+
}
|
|
40
|
+
return auth.organizationRole === 'viewer';
|
|
41
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AuthProvider } from '../auth/provider.js';
|
|
2
|
+
import type { DatabaseAdapter } from '../db/index.js';
|
|
3
|
+
import type { StorageAdapter } from '../storage/interfaces/index.js';
|
|
4
|
+
import type { EmailAdapter } from '../email/index.js';
|
|
5
|
+
import { SchemaType } from './schemas.js';
|
|
6
|
+
export interface CMSPlugin {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
routes?: {
|
|
10
|
+
[path: string]: (event: any) => Promise<Response> | Response;
|
|
11
|
+
};
|
|
12
|
+
install: (cms: any) => Promise<void>;
|
|
13
|
+
config?: {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface CMSConfig {
|
|
18
|
+
schemaTypes: SchemaType[];
|
|
19
|
+
database: DatabaseAdapter;
|
|
20
|
+
storage?: StorageAdapter | null;
|
|
21
|
+
email?: EmailAdapter | null;
|
|
22
|
+
customization?: {
|
|
23
|
+
branding?: {
|
|
24
|
+
title?: string;
|
|
25
|
+
logo?: string;
|
|
26
|
+
favicon?: string;
|
|
27
|
+
};
|
|
28
|
+
theme?: {
|
|
29
|
+
colors?: Record<string, string>;
|
|
30
|
+
fonts?: Record<string, string>;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
plugins?: CMSPlugin[];
|
|
34
|
+
auth?: {
|
|
35
|
+
provider: AuthProvider;
|
|
36
|
+
loginUrl?: string;
|
|
37
|
+
};
|
|
38
|
+
security?: {
|
|
39
|
+
/**
|
|
40
|
+
* Secret key for signing asset URLs (enables multi-tenant access without exposing API keys)
|
|
41
|
+
* Should be a long, random string (e.g., 32+ characters)
|
|
42
|
+
* Required for signed asset URLs to work
|
|
43
|
+
*/
|
|
44
|
+
assetSigningSecret?: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/types/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;KAAE,CAAC;IAC1E,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,KAAK,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/B,CAAC;KACF,CAAC;IACF,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE;QACN,QAAQ,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE;QACV;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|