@aphexcms/cms-core 0.1.1 → 0.1.3

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 (98) hide show
  1. package/package.json +22 -5
  2. package/src/api/assets.ts +0 -75
  3. package/src/api/client.ts +0 -150
  4. package/src/api/documents.ts +0 -102
  5. package/src/api/index.ts +0 -7
  6. package/src/api/organizations.ts +0 -154
  7. package/src/api/types.ts +0 -34
  8. package/src/app.d.ts +0 -19
  9. package/src/auth/MULTI_TENANCY_PLAN.md +0 -1183
  10. package/src/auth/auth-errors.ts +0 -23
  11. package/src/auth/auth-hooks.ts +0 -132
  12. package/src/auth/provider.ts +0 -25
  13. package/src/client/index.ts +0 -47
  14. package/src/components/AdminApp.svelte +0 -1078
  15. package/src/components/admin/AdminLayout.svelte +0 -115
  16. package/src/components/admin/DocumentEditor.svelte +0 -795
  17. package/src/components/admin/DocumentTypesList.svelte +0 -97
  18. package/src/components/admin/ObjectModal.svelte +0 -135
  19. package/src/components/admin/SchemaField.svelte +0 -171
  20. package/src/components/admin/fields/ArrayField.svelte +0 -266
  21. package/src/components/admin/fields/BooleanField.svelte +0 -35
  22. package/src/components/admin/fields/ImageField.svelte +0 -284
  23. package/src/components/admin/fields/NumberField.svelte +0 -82
  24. package/src/components/admin/fields/ReferenceField.svelte +0 -260
  25. package/src/components/admin/fields/SlugField.svelte +0 -74
  26. package/src/components/admin/fields/StringField.svelte +0 -40
  27. package/src/components/admin/fields/TextareaField.svelte +0 -40
  28. package/src/components/fields/index.ts +0 -9
  29. package/src/components/index.ts +0 -16
  30. package/src/components/layout/OrganizationSwitcher.svelte +0 -218
  31. package/src/components/layout/Sidebar.svelte +0 -88
  32. package/src/components/layout/sidebar/AppSidebar.svelte +0 -63
  33. package/src/components/layout/sidebar/NavMain.svelte +0 -95
  34. package/src/components/layout/sidebar/NavSecondary.svelte +0 -69
  35. package/src/components/layout/sidebar/NavUser.svelte +0 -85
  36. package/src/config.ts +0 -18
  37. package/src/db/adapters/index.ts +0 -3
  38. package/src/db/index.ts +0 -5
  39. package/src/db/interfaces/asset.ts +0 -61
  40. package/src/db/interfaces/document.ts +0 -53
  41. package/src/db/interfaces/index.ts +0 -98
  42. package/src/db/interfaces/organization.ts +0 -51
  43. package/src/db/interfaces/schema.ts +0 -13
  44. package/src/db/interfaces/user.ts +0 -16
  45. package/src/db/utils/reference-resolver.ts +0 -119
  46. package/src/define.ts +0 -7
  47. package/src/email/index.ts +0 -5
  48. package/src/email/interfaces/email.ts +0 -45
  49. package/src/engine.ts +0 -85
  50. package/src/field-validation/rule.ts +0 -287
  51. package/src/field-validation/utils.ts +0 -91
  52. package/src/hooks.ts +0 -142
  53. package/src/index.ts +0 -5
  54. package/src/lib/is-mobile.svelte.ts +0 -9
  55. package/src/lib/utils.ts +0 -13
  56. package/src/plugins/README.md +0 -154
  57. package/src/routes/assets-by-id.ts +0 -161
  58. package/src/routes/assets-cdn.ts +0 -185
  59. package/src/routes/assets.ts +0 -116
  60. package/src/routes/documents-by-id.ts +0 -188
  61. package/src/routes/documents-publish.ts +0 -211
  62. package/src/routes/documents.ts +0 -172
  63. package/src/routes/index.ts +0 -13
  64. package/src/routes/organizations-by-id.ts +0 -258
  65. package/src/routes/organizations-invitations.ts +0 -183
  66. package/src/routes/organizations-members.ts +0 -301
  67. package/src/routes/organizations-switch.ts +0 -74
  68. package/src/routes/organizations.ts +0 -146
  69. package/src/routes/schemas-by-type.ts +0 -35
  70. package/src/routes/schemas.ts +0 -19
  71. package/src/routes-exports.ts +0 -42
  72. package/src/schema-context.svelte.ts +0 -24
  73. package/src/schema-utils/cleanup.ts +0 -116
  74. package/src/schema-utils/index.ts +0 -4
  75. package/src/schema-utils/utils.ts +0 -47
  76. package/src/schema-utils/validator.ts +0 -58
  77. package/src/server/index.ts +0 -40
  78. package/src/services/asset-service.ts +0 -256
  79. package/src/services/index.ts +0 -6
  80. package/src/storage/adapters/index.ts +0 -2
  81. package/src/storage/adapters/local-storage-adapter.ts +0 -215
  82. package/src/storage/index.ts +0 -8
  83. package/src/storage/interfaces/index.ts +0 -2
  84. package/src/storage/interfaces/storage.ts +0 -114
  85. package/src/storage/providers/storage.ts +0 -83
  86. package/src/types/asset.ts +0 -81
  87. package/src/types/auth.ts +0 -80
  88. package/src/types/config.ts +0 -45
  89. package/src/types/document.ts +0 -38
  90. package/src/types/index.ts +0 -8
  91. package/src/types/organization.ts +0 -119
  92. package/src/types/schemas.ts +0 -151
  93. package/src/types/sidebar.ts +0 -37
  94. package/src/types/user.ts +0 -17
  95. package/src/utils/content-hash.ts +0 -75
  96. package/src/utils/image-url.ts +0 -204
  97. package/src/utils/index.ts +0 -12
  98. package/src/utils/slug.ts +0 -33
@@ -1,23 +0,0 @@
1
- // Custom authentication errors with error codes for better error handling
2
-
3
- export type AuthErrorCode =
4
- | 'no_session'
5
- | 'session_expired'
6
- | 'no_organization'
7
- | 'kicked_from_org'
8
- | 'unauthorized';
9
-
10
- export class AuthError extends Error {
11
- code: AuthErrorCode;
12
-
13
- constructor(code: AuthErrorCode, message: string) {
14
- super(message);
15
- this.code = code;
16
- this.name = 'AuthError';
17
- }
18
- }
19
-
20
- // Helper function to create auth errors
21
- export function createAuthError(code: AuthErrorCode, message: string): AuthError {
22
- return new AuthError(code, message);
23
- }
@@ -1,132 +0,0 @@
1
- import type { RequestEvent } from '@sveltejs/kit';
2
- import { redirect } from '@sveltejs/kit';
3
- import type { DatabaseAdapter } from '../db/';
4
- import type { CMSConfig, Auth } from '../types/index.js';
5
- import type { AuthProvider } from './provider.js';
6
- import { AuthError } from './auth-errors.js';
7
-
8
- export async function handleAuthHook(
9
- event: RequestEvent,
10
- config: CMSConfig,
11
- authProvider: AuthProvider,
12
- db: DatabaseAdapter
13
- ): Promise<Response | null> {
14
- const path = event.url.pathname;
15
-
16
- // 1. Admin UI routes - require session authentication
17
- if (path.startsWith('/admin')) {
18
- try {
19
- const session = await authProvider.requireSession(event.request, db);
20
- event.locals.auth = session;
21
- } catch (error) {
22
- // If it's an AuthError, redirect to login with error code
23
- if (error instanceof AuthError) {
24
- const loginUrl = config.auth?.loginUrl || '/login';
25
- throw redirect(302, `${loginUrl}?error=${error.code}`);
26
- }
27
- // For other errors, redirect without error code
28
- throw redirect(302, config.auth?.loginUrl || '/login');
29
- }
30
- }
31
-
32
- // 2. Asset CDN routes - accept session OR API key OR signed token
33
- // Support both /assets/ and /media/ paths (media is Sanity-style URL)
34
- if (path.startsWith('/assets/') || path.startsWith('/media/')) {
35
- // Try session first (for admin UI)
36
- let auth: Auth | null = await authProvider.getSession(event.request, db);
37
-
38
- // If no session, try API key
39
- if (!auth) {
40
- auth = await authProvider.validateApiKey(event.request, db);
41
- }
42
-
43
- // Make auth available (can be null, route will check for signed token)
44
- if (auth) {
45
- event.locals.auth = auth;
46
- }
47
- }
48
-
49
- // 3. API routes - accept session OR API key
50
- if (path.startsWith('/api/')) {
51
- // Skip auth routes (Better Auth handles these)
52
- if (path.startsWith('/api/auth')) {
53
- return null; // Let the main hook continue
54
- }
55
-
56
- // If API key is explicitly provided, prioritize it over session
57
- // This allows public content access even when user is logged in to a different org
58
- const hasApiKey = event.request.headers.has('x-api-key');
59
- let auth: Auth | null = null;
60
-
61
- if (hasApiKey) {
62
- // API key takes precedence when explicitly provided
63
- auth = await authProvider.validateApiKey(event.request, db);
64
- } else {
65
- // Otherwise, try session (for admin UI making API calls)
66
- auth = await authProvider.getSession(event.request, db);
67
- }
68
-
69
- // Dynamically find the GraphQL endpoint from plugins
70
- let graphqlEndpoint: string | undefined;
71
- const graphqlPlugin = config.plugins?.find((p) => p.name === '@aphexcms/graphql-plugin');
72
- if (graphqlPlugin && graphqlPlugin.routes) {
73
- graphqlEndpoint = Object.keys(graphqlPlugin.routes)[0];
74
- }
75
-
76
- // Require authentication for protected API routes
77
- const protectedApiRoutes = [
78
- '/api/documents',
79
- '/api/assets',
80
- '/api/schemas',
81
- '/api/organizations',
82
- '/api/settings'
83
- ];
84
- if (graphqlEndpoint) {
85
- protectedApiRoutes.push(graphqlEndpoint);
86
- }
87
- const isProtectedRoute = protectedApiRoutes.some((route) => path.startsWith(route));
88
-
89
- if (isProtectedRoute && !auth) {
90
- return new Response(JSON.stringify({ error: 'Unauthorized' }), {
91
- status: 401,
92
- headers: { 'Content-Type': 'application/json' }
93
- });
94
- }
95
-
96
- // Check write permission for mutations
97
- if (auth && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(event.request.method)) {
98
- // Special handling for GraphQL
99
- if (graphqlEndpoint && path.startsWith(graphqlEndpoint)) {
100
- // We need to read the body to check if it's a mutation.
101
- // It's important to clone the request so we don't consume the body stream.
102
- const requestBody = await event.request.clone().text();
103
- const isMutation = requestBody.trim().startsWith('mutation');
104
-
105
- if (isMutation && auth.type === 'api_key' && !auth.permissions.includes('write')) {
106
- return new Response(
107
- JSON.stringify({ error: 'Forbidden: Write permission required for mutations' }),
108
- {
109
- status: 403,
110
- headers: { 'Content-Type': 'application/json' }
111
- }
112
- );
113
- }
114
- } else {
115
- // Existing logic for other API routes
116
- if (auth.type === 'api_key' && !auth.permissions.includes('write')) {
117
- return new Response(JSON.stringify({ error: 'Forbidden: Write permission required' }), {
118
- status: 403,
119
- headers: { 'Content-Type': 'application/json' }
120
- });
121
- }
122
- }
123
- }
124
-
125
- // Make auth available in API routes
126
- if (auth) {
127
- event.locals.auth = auth;
128
- }
129
- }
130
-
131
- return null; // Tell the main hook to continue
132
- }
@@ -1,25 +0,0 @@
1
- // packages/cms-core/src/auth/provider.ts
2
- import type { SessionAuth, ApiKeyAuth } from '../types/index.js';
3
- import type { DatabaseAdapter } from '../db/interfaces/index.js';
4
-
5
- export interface AuthProvider {
6
- // Session auth (browser, admin UI)
7
- getSession(request: Request, db: DatabaseAdapter): Promise<SessionAuth | null>;
8
- requireSession(request: Request, db: DatabaseAdapter): Promise<SessionAuth>;
9
-
10
- // API key auth (programmatic access)
11
- validateApiKey(request: Request, db: DatabaseAdapter): Promise<ApiKeyAuth | null>;
12
- requireApiKey(
13
- request: Request,
14
- db: DatabaseAdapter,
15
- permission?: 'read' | 'write'
16
- ): Promise<ApiKeyAuth>;
17
-
18
- // User management
19
- getUserById(userId: string): Promise<{ id: string; name?: string; email: string } | null>;
20
- changeUserName(userId: string, name: string): Promise<void>;
21
-
22
- // Password reset
23
- requestPasswordReset(email: string, redirectTo?: string): Promise<void>;
24
- resetPassword(token: string, newPassword: string): Promise<void>;
25
- }
@@ -1,47 +0,0 @@
1
- // Aphex CMS Core - Client-side exports
2
- // These are safe to import in the browser (no Node.js dependencies)
3
-
4
- // Core types (shared between client and server)
5
- export * from '../types/index.js';
6
- export type {
7
- SidebarUser,
8
- SidebarNavItem,
9
- SidebarBranding,
10
- SidebarData
11
- } from '../types/sidebar.js';
12
-
13
- // Field validation (client-side validation)
14
- export * from '../field-validation/rule.js';
15
- export * from '../field-validation/utils.js';
16
-
17
- // Content hashing utilities (for client-side change detection)
18
- export { createContentHash, hasUnpublishedChanges } from '../utils/content-hash.js';
19
-
20
- // Schema context (for providing schemas to components)
21
- export { setSchemaContext, getSchemaContext } from '../schema-context.svelte.js';
22
-
23
- // Schema utilities (for working with schemas)
24
- export * from '../schema-utils/index.js';
25
-
26
- // Components (UI components for the admin interface)
27
- export { default as DocumentEditor } from '../components/admin/DocumentEditor.svelte';
28
- export { default as DocumentTypesList } from '../components/admin/DocumentTypesList.svelte';
29
- export { default as SchemaField } from '../components/admin/SchemaField.svelte';
30
- export { default as AdminApp } from '../components/AdminApp.svelte';
31
- export { default as Sidebar } from '../components/layout/Sidebar.svelte';
32
-
33
- // Field components
34
- export { default as StringField } from '../components/admin/fields/StringField.svelte';
35
- export { default as TextareaField } from '../components/admin/fields/TextareaField.svelte';
36
- export { default as NumberField } from '../components/admin/fields/NumberField.svelte';
37
- export { default as BooleanField } from '../components/admin/fields/BooleanField.svelte';
38
- export { default as ImageField } from '../components/admin/fields/ImageField.svelte';
39
- export { default as SlugField } from '../components/admin/fields/SlugField.svelte';
40
- export { default as ArrayField } from '../components/admin/fields/ArrayField.svelte';
41
- export { default as ReferenceField } from '../components/admin/fields/ReferenceField.svelte';
42
-
43
- // Utility functions (browser-safe)
44
- export * from '../utils/index.js';
45
-
46
- export * from '../api/index.js';
47
- export type { ApiResponse } from '../api/index.js';