@eldrin-project/eldrin-app-core 0.0.4 → 0.0.5

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/README.md CHANGED
@@ -2,17 +2,33 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@eldrin-project/eldrin-app-core.svg)](https://www.npmjs.com/package/@eldrin-project/eldrin-app-core)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/)
6
5
 
7
- Standard library for building Eldrin marketplace apps. Provides database migrations, React hooks for D1 database access, single-spa lifecycle management, and CLI tools for releasing to the Eldrin marketplace.
6
+ Framework-agnostic core library for building Eldrin marketplace apps on Cloudflare Workers with D1 databases.
8
7
 
9
- ## Features
8
+ ## Overview
10
9
 
11
- - **Zero-config migrations** - SQL migrations run automatically during app bootstrap
12
- - **Type-safe database access** - React hooks with full TypeScript support
13
- - **Single-spa compatible** - Seamless integration with micro-frontend architecture
14
- - **Cloudflare Workers ready** - Built for D1 databases and Workers runtime
15
- - **CLI tools included** - Release and submit apps to the Eldrin marketplace
10
+ This package is the **foundation layer** of the Eldrin ecosystem:
11
+
12
+ ```
13
+ ┌─────────────────────────────────────────────────────────────┐
14
+ │ Your App │
15
+ ├─────────────────────────────────────────────────────────────┤
16
+ │ Framework Adapter (choose one) │
17
+ │ • @eldrin-project/eldrin-app-angular │
18
+ │ • @eldrin-project/eldrin-app-react │
19
+ │ • @eldrin-project/eldrin-app-vue │
20
+ ├─────────────────────────────────────────────────────────────┤
21
+ │ @eldrin-project/eldrin-app-core │
22
+ │ • Database migrations with checksum verification │
23
+ │ • JWT authentication & permission checking │
24
+ │ • Permission middleware for API routes │
25
+ │ • Event system for inter-app communication │
26
+ │ • Vite plugin for build-time SQL loading │
27
+ │ • CLI tools for marketplace release/submission │
28
+ ├─────────────────────────────────────────────────────────────┤
29
+ │ Cloudflare Workers + D1 Database │
30
+ └─────────────────────────────────────────────────────────────┘
31
+ ```
16
32
 
17
33
  ## Installation
18
34
 
@@ -20,142 +36,244 @@ Standard library for building Eldrin marketplace apps. Provides database migrati
20
36
  npm install @eldrin-project/eldrin-app-core
21
37
  ```
22
38
 
23
- ## Quick Start
39
+ ## Features
40
+
41
+ ### 1. Database Migrations
24
42
 
25
- ### 1. Create your app entry point
43
+ Run SQL migrations against Cloudflare D1 with automatic tracking, checksum verification, and rollback support.
26
44
 
27
- ```tsx
28
- // src/index.tsx
29
- import { createApp } from '@eldrin-project/eldrin-app-core';
30
- import migrations from 'virtual:eldrin/migrations';
31
- import App from './App';
45
+ ```typescript
46
+ import { runMigrations, getMigrationStatus } from '@eldrin-project/eldrin-app-core';
32
47
 
33
- export const { bootstrap, mount, unmount } = createApp({
34
- name: 'my-app',
35
- root: App,
36
- migrations,
48
+ // Run pending migrations
49
+ const result = await runMigrations(db, {
50
+ migrations: [
51
+ { name: '20250101120000-create-users.sql', content: 'CREATE TABLE users...' },
52
+ { name: '20250102100000-add-email.sql', content: 'ALTER TABLE users...' },
53
+ ],
54
+ onLog: (msg, level) => console.log(`[${level}] ${msg}`),
37
55
  });
38
- ```
39
56
 
40
- ### 2. Configure Vite
57
+ if (result.success) {
58
+ console.log(`Executed ${result.executed} migrations`);
59
+ } else {
60
+ console.error(`Failed at ${result.error?.migration}: ${result.error?.message}`);
61
+ }
41
62
 
42
- ```ts
43
- // vite.config.ts
44
- import { defineConfig } from 'vite';
45
- import { eldrinPlugin } from '@eldrin-project/eldrin-app-core/vite';
63
+ // Check migration status
64
+ const status = await getMigrationStatus(db, migrations);
65
+ console.log('Pending:', status.pending);
66
+ console.log('Executed:', status.executed.length);
67
+ ```
46
68
 
47
- export default defineConfig({
48
- plugins: [
49
- eldrinPlugin({
50
- migrationsDir: './migrations',
51
- seedsDir: './seeds',
52
- }),
53
- ],
54
- });
69
+ **Migration file naming:** `YYYYMMDDHHMMSS-description.sql`
70
+
71
+ Migrations are tracked in `_eldrin_migrations` table with SHA-256 checksums to detect tampering.
72
+
73
+ ### 2. Authentication & Authorization
74
+
75
+ Verify JWT tokens and check permissions in your Cloudflare Worker:
76
+
77
+ ```typescript
78
+ import {
79
+ verifyJWT,
80
+ requireJWTAuth,
81
+ requireJWTPermission,
82
+ hasPermission,
83
+ isPlatformAdmin,
84
+ } from '@eldrin-project/eldrin-app-core';
85
+
86
+ export default {
87
+ async fetch(request: Request, env: Env) {
88
+ // Option 1: Manual verification
89
+ const result = await verifyJWT(request, {
90
+ secret: env.JWT_SECRET,
91
+ appId: 'my-app',
92
+ });
93
+
94
+ if (!result.success) {
95
+ return Response.json({ error: result.error }, { status: 401 });
96
+ }
97
+
98
+ const { auth } = result;
99
+ console.log('User:', auth.email);
100
+ console.log('Permissions:', auth.permissions);
101
+
102
+ // Option 2: Require auth (returns Response on failure)
103
+ const auth = await requireJWTAuth(request, {
104
+ secret: env.JWT_SECRET,
105
+ appId: 'my-app',
106
+ });
107
+
108
+ if (auth instanceof Response) return auth; // 401
109
+
110
+ // Option 3: Require specific permission
111
+ const auth = await requireJWTPermission(
112
+ request,
113
+ { secret: env.JWT_SECRET, appId: 'my-app' },
114
+ 'invoices',
115
+ 'write'
116
+ );
117
+
118
+ if (auth instanceof Response) return auth; // 401 or 403
119
+
120
+ // Check permissions manually
121
+ if (hasPermission(auth, 'invoices', 'delete')) {
122
+ // User can delete invoices
123
+ }
124
+
125
+ if (isPlatformAdmin(auth)) {
126
+ // User is platform admin (has all permissions)
127
+ }
128
+ },
129
+ };
55
130
  ```
56
131
 
57
- ### 3. Add TypeScript support for virtual modules
132
+ ### 3. Permission Middleware
58
133
 
59
- ```ts
60
- // src/vite-env.d.ts
61
- /// <reference types="@eldrin-project/eldrin-app-core/vite-env" />
62
- ```
134
+ Manifest-driven middleware that automatically enforces route permissions:
63
135
 
64
- ### 4. Use the database in components
136
+ ```typescript
137
+ import { createPermissionMiddleware } from '@eldrin-project/eldrin-app-core';
138
+ import manifest from './eldrin-app.manifest.json';
65
139
 
66
- ```tsx
67
- import { useDatabase } from '@eldrin-project/eldrin-app-core';
140
+ const middleware = createPermissionMiddleware<Env>({
141
+ manifest,
142
+ getSecret: (env) => env.JWT_SECRET,
143
+ cors: {
144
+ allowOrigin: '*',
145
+ allowMethods: 'GET, POST, PUT, DELETE, OPTIONS',
146
+ allowHeaders: 'Content-Type, Authorization',
147
+ },
148
+ });
68
149
 
69
- function InvoiceList() {
70
- const db = useDatabase();
71
- const [invoices, setInvoices] = useState([]);
150
+ export default {
151
+ async fetch(request: Request, env: Env): Promise<Response> {
152
+ const result = await middleware.handle(request, env);
72
153
 
73
- useEffect(() => {
74
- if (!db) return;
75
- db.prepare('SELECT * FROM invoices ORDER BY created_at DESC')
76
- .all()
77
- .then(({ results }) => setInvoices(results));
78
- }, [db]);
154
+ // Rejected request (401, 403, or CORS preflight)
155
+ if (result.response) {
156
+ return result.response;
157
+ }
79
158
 
80
- return <ul>{invoices.map(inv => <li key={inv.id}>{inv.name}</li>)}</ul>;
159
+ // Authorized - access auth context and route params
160
+ const { auth, url, params } = result;
161
+ console.log('User:', auth.email);
162
+ console.log('Route params:', params); // e.g., { id: '123' }
163
+
164
+ // Handle the request...
165
+ },
166
+ };
167
+ ```
168
+
169
+ **Manifest API configuration:**
170
+
171
+ ```json
172
+ {
173
+ "id": "my-app",
174
+ "developer_id": "acme",
175
+ "api": {
176
+ "defaultPolicy": "deny",
177
+ "publicRoutes": ["/api/health"],
178
+ "routes": [
179
+ { "method": "GET", "path": "/api/items", "permission": "items:read" },
180
+ { "method": "POST", "path": "/api/items", "permission": "items:write" },
181
+ { "method": "GET", "path": "/api/items/:id", "permission": "items:read" },
182
+ { "method": "DELETE", "path": "/api/items/:id", "permission": "items:delete" }
183
+ ]
184
+ }
81
185
  }
82
186
  ```
83
187
 
84
- ## Migrations
188
+ ### 4. Event System
85
189
 
86
- Create SQL migration files in your `migrations/` directory:
190
+ Publish/subscribe events for inter-app communication:
87
191
 
88
- ```
89
- migrations/
90
- ├── 20250101120000-create-invoices.sql
91
- ├── 20250101120000-create-invoices.rollback.sql
92
- └── 20250102100000-add-status-column.sql
93
- ```
192
+ ```typescript
193
+ import { createEventClient } from '@eldrin-project/eldrin-app-core';
94
194
 
95
- Migration filenames must follow the pattern: `YYYYMMDDHHMMSS-description.sql`
195
+ export default {
196
+ async fetch(request: Request, env: Env) {
197
+ const events = createEventClient(env, 'invoicing');
96
198
 
97
- Migrations run automatically during the app bootstrap phase. The system tracks executed migrations in the `_eldrin_migrations` table with SHA-256 checksums to detect tampering.
199
+ // Emit an event
200
+ await events.emit('invoice.created', {
201
+ invoiceId: 'inv_123',
202
+ customerId: 'cust_456',
203
+ total: 1500,
204
+ });
98
205
 
99
- ### Migration Hooks
206
+ // Poll for events (in a scheduled worker)
207
+ const pending = await events.poll({ limit: 10 });
100
208
 
101
- ```tsx
102
- export const { bootstrap, mount, unmount } = createApp({
103
- name: 'my-app',
104
- root: App,
105
- migrations,
106
- onMigrationsComplete: (result) => {
107
- console.log(`Executed ${result.executed} migrations`);
108
- },
109
- onMigrationError: (error) => {
110
- console.error('Migration failed:', error);
209
+ for (const delivery of pending.events) {
210
+ try {
211
+ await processEvent(delivery.event);
212
+ await events.ack(delivery.id);
213
+ } catch (error) {
214
+ await events.nack(delivery.id, error.message);
215
+ }
216
+ }
111
217
  },
112
- });
218
+ };
113
219
  ```
114
220
 
115
- ## API Reference
116
-
117
- ### createApp(options)
221
+ **Declare events in manifest:**
118
222
 
119
- Creates a single-spa compatible app lifecycle.
223
+ ```json
224
+ {
225
+ "events": {
226
+ "emits": ["invoice.created", "invoice.paid"],
227
+ "subscribes": ["payment.received", "customer.updated"]
228
+ }
229
+ }
230
+ ```
120
231
 
121
- | Option | Type | Description |
122
- |--------|------|-------------|
123
- | `name` | `string` | Unique app identifier |
124
- | `root` | `React.ComponentType` | Root React component |
125
- | `migrations` | `MigrationFile[]` | Migration files (from virtual module) |
126
- | `onMigrationsComplete` | `(result) => void` | Called after successful migrations |
127
- | `onMigrationError` | `(error) => void` | Called if migrations fail |
232
+ ### 5. Vite Plugin
128
233
 
129
- ### useDatabase()
234
+ Load SQL migrations at build time (Workers have no filesystem access at runtime):
130
235
 
131
- React hook that returns the D1 database instance or `null`.
236
+ ```typescript
237
+ // vite.config.ts
238
+ import { defineConfig } from 'vite';
239
+ import { eldrinPlugin } from '@eldrin-project/eldrin-app-core/vite';
132
240
 
133
- ```tsx
134
- const db = useDatabase();
241
+ export default defineConfig({
242
+ plugins: [
243
+ eldrinPlugin({
244
+ migrationsDir: './migrations',
245
+ seedsDir: './seeds',
246
+ }),
247
+ ],
248
+ });
135
249
  ```
136
250
 
137
- ### useDatabaseContext()
138
-
139
- React hook that returns the full database context including migration status.
140
-
141
- ```tsx
142
- const { db, migrationsComplete, migrationResult } = useDatabaseContext();
251
+ ```typescript
252
+ // Add type declarations
253
+ // src/vite-env.d.ts
254
+ /// <reference types="@eldrin-project/eldrin-app-core/vite-env" />
143
255
  ```
144
256
 
145
- ### useMigrationsComplete()
257
+ ```typescript
258
+ // Import migrations in your code
259
+ import migrations from 'virtual:eldrin/migrations';
260
+ import seeds from 'virtual:eldrin/seeds';
261
+ ```
146
262
 
147
- React hook that returns `true` when migrations have finished.
263
+ ## Package Exports
148
264
 
149
- ```tsx
150
- const ready = useMigrationsComplete();
151
- if (!ready) return <Loading />;
152
- ```
265
+ | Export | Environment | Description |
266
+ |--------|-------------|-------------|
267
+ | `@eldrin-project/eldrin-app-core` | Browser/Worker | Main exports (migrations, auth, events, middleware) |
268
+ | `@eldrin-project/eldrin-app-core/node` | Node.js only | Marketplace utilities (generateMigrationManifest) |
269
+ | `@eldrin-project/eldrin-app-core/vite` | Node.js only | Vite plugin for loading SQL files |
270
+ | `@eldrin-project/eldrin-app-core/vite-env` | Types only | TypeScript declarations for virtual modules |
153
271
 
154
272
  ## CLI Tools
155
273
 
156
274
  ### eldrin-release
157
275
 
158
- Prepares your app for marketplace submission.
276
+ Prepares your app for marketplace submission:
159
277
 
160
278
  ```bash
161
279
  npx eldrin-release [options]
@@ -168,18 +286,25 @@ Options:
168
286
  -o, --output <path> Output directory
169
287
  ```
170
288
 
171
- Creates a release package at `dist/release/{developerId}/{appId}/v{version}/` containing:
172
- - `eldrin-app.manifest.json` - App metadata
173
- - `bundle.js` - Built app bundle
174
- - `deploy-bundle.json` - Worker + client assets (if applicable)
175
- - `migrations/` - Migration files with checksums
289
+ Creates a release package at `dist/release/{developerId}/{appId}/v{version}/`:
290
+
291
+ ```
292
+ dist/release/acme/invoicing/
293
+ ├── migrations/ # Shared across versions
294
+ │ ├── index.json # Manifest with checksums
295
+ │ └── *.sql # Migration files
296
+ └── v1.0.0/
297
+ ├── eldrin-app.manifest.json # App metadata
298
+ ├── bundle.js # Worker bundle
299
+ └── deploy-bundle.json # Worker + client assets
300
+ ```
176
301
 
177
302
  ### eldrin-submit
178
303
 
179
- Submits a release to the Eldrin marketplace.
304
+ Submits a release to the Eldrin marketplace:
180
305
 
181
306
  ```bash
182
- npx eldrin-submit -d ./dist/release/eldrin.io/my-app/v1.0.0
307
+ npx eldrin-submit -d ./dist/release/acme/invoicing/v1.0.0
183
308
 
184
309
  Options:
185
310
  -d, --release-dir <dir> Release directory to submit
@@ -188,7 +313,7 @@ Options:
188
313
  --dry-run Preview without submitting
189
314
  ```
190
315
 
191
- Environment variables:
316
+ **Environment variables:**
192
317
  - `ELDRIN_API_KEY` - Your developer API key
193
318
  - `ELDRIN_DEVELOPER_ID` - Your developer ID
194
319
  - `ELDRIN_MARKETPLACE_URL` - Marketplace URL (default: https://eldrin.io)
@@ -199,11 +324,11 @@ Create `.eldrinrc.json` in your project root:
199
324
 
200
325
  ```json
201
326
  {
202
- "developerId": "your-developer-id",
327
+ "developerId": "acme",
203
328
  "marketplaceUrl": "https://eldrin.io",
204
- "manifestPath": "./eldrin-app.manifest.json",
329
+ "manifestPath": "./public/eldrin-app.manifest.json",
205
330
  "migrationsDir": "./migrations",
206
- "buildCommand": "npm run build:lib",
331
+ "buildCommand": "npm run build",
207
332
  "clientDir": "dist/client",
208
333
  "workerEntry": "dist/worker/index.js"
209
334
  }
@@ -215,34 +340,99 @@ Create `eldrin-app.manifest.json`:
215
340
 
216
341
  ```json
217
342
  {
218
- "id": "my-app",
219
- "name": "My App",
343
+ "id": "invoicing",
344
+ "name": "Invoicing App",
220
345
  "version": "1.0.0",
221
- "description": "Description of my app",
222
- "developer": {
223
- "id": "your-developer-id",
224
- "name": "Your Name"
346
+ "description": "Create and manage invoices",
347
+ "developer_id": "acme",
348
+ "permissions": [
349
+ { "resource": "invoices", "actions": ["read", "write", "delete"] },
350
+ { "resource": "customers", "actions": ["read"] }
351
+ ],
352
+ "groups": [
353
+ {
354
+ "id": "admin",
355
+ "name": "Invoice Admin",
356
+ "permissions": ["invoices:*", "customers:read"]
357
+ },
358
+ {
359
+ "id": "viewer",
360
+ "name": "Viewer",
361
+ "permissions": ["invoices:read", "customers:read"]
362
+ }
363
+ ],
364
+ "events": {
365
+ "emits": ["invoice.created", "invoice.paid"],
366
+ "subscribes": ["payment.received"]
225
367
  },
226
- "entry": "bundle.js"
368
+ "api": {
369
+ "defaultPolicy": "deny",
370
+ "publicRoutes": ["/api/health"],
371
+ "routes": [
372
+ { "method": "GET", "path": "/api/invoices", "permission": "invoices:read" },
373
+ { "method": "POST", "path": "/api/invoices", "permission": "invoices:write" }
374
+ ]
375
+ }
227
376
  }
228
377
  ```
229
378
 
230
- ## Requirements
379
+ ## Framework Adapters
231
380
 
232
- - Node.js 18.0.0 or later
233
- - React 18.x or 19.x
234
- - Vite 6.x or 7.x
381
+ This core package is framework-agnostic. Use these adapters for framework-specific integrations:
235
382
 
236
- ## Contributing
383
+ | Framework | Package | Features |
384
+ |-----------|---------|----------|
385
+ | Angular | `@eldrin-project/eldrin-app-angular` | InjectionTokens, providers, single-spa lifecycle |
386
+ | React | `@eldrin-project/eldrin-app-react` | Hooks (useDatabase), Context, single-spa lifecycle |
387
+ | Vue | `@eldrin-project/eldrin-app-vue` | Composables, provide/inject, single-spa lifecycle |
237
388
 
238
- Contributions are welcome! Please feel free to submit a Pull Request.
389
+ ## API Reference
239
390
 
240
- 1. Fork the repository
241
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
242
- 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
243
- 4. Push to the branch (`git push origin feature/amazing-feature`)
244
- 5. Open a Pull Request
391
+ ### Migrations
392
+
393
+ | Function | Description |
394
+ |----------|-------------|
395
+ | `runMigrations(db, options)` | Execute pending migrations |
396
+ | `getMigrationStatus(db, migrations)` | Get pending/executed/orphaned migrations |
397
+ | `rollbackMigrations(db, options)` | Rollback migrations (with .rollback.sql files) |
398
+ | `calculateChecksum(content)` | Calculate SHA-256 checksum of migration content |
399
+ | `verifyChecksum(content, checksum)` | Verify content matches stored checksum |
400
+
401
+ ### Auth
402
+
403
+ | Function | Description |
404
+ |----------|-------------|
405
+ | `verifyJWT(request, options)` | Verify JWT and extract auth context |
406
+ | `getAuthContextFromJWT(request, options)` | Get auth context (JWT or proxy headers) |
407
+ | `requireJWTAuth(request, options)` | Require valid JWT (returns Response on failure) |
408
+ | `requireJWTPermission(request, options, resource, action)` | Require specific permission |
409
+ | `hasPermission(auth, resource, action)` | Check if auth has permission |
410
+ | `isPlatformAdmin(auth)` | Check if auth is platform admin |
411
+
412
+ ### Middleware
413
+
414
+ | Function | Description |
415
+ |----------|-------------|
416
+ | `createPermissionMiddleware(config)` | Create manifest-driven permission middleware |
417
+ | `compileRoutes(routes, prefix)` | Pre-compile route patterns for matching |
418
+ | `matchRoute(method, path, routes)` | Match request against compiled routes |
419
+
420
+ ### Events
421
+
422
+ | Class/Function | Description |
423
+ |----------------|-------------|
424
+ | `EldrinEventClient` | Client for pub/sub event communication |
425
+ | `createEventClient(env, appId)` | Create event client from worker env |
426
+ | `client.emit(type, payload)` | Emit an event |
427
+ | `client.poll(options)` | Poll for pending events |
428
+ | `client.ack(deliveryId)` | Acknowledge successful processing |
429
+ | `client.nack(deliveryId, error)` | Negative acknowledge (retry later) |
430
+
431
+ ## Requirements
432
+
433
+ - Node.js 18.0.0 or later
434
+ - Vite 6.x or 7.x (optional, for Vite plugin)
245
435
 
246
436
  ## License
247
437
 
248
- MIT - see [LICENSE](LICENSE) for details.
438
+ MIT
package/dist/index.cjs CHANGED
@@ -1,9 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var promises = require('fs/promises');
4
- var fs = require('fs');
5
- var path = require('path');
6
-
7
3
  // src/migrations/checksum.ts
8
4
  var CHECKSUM_PREFIX = "sha256:";
9
5
  async function calculateChecksum(content, options = {}) {
@@ -371,75 +367,6 @@ async function rollbackMigrations(db, options) {
371
367
  };
372
368
  }
373
369
  }
374
- async function readMigrationFiles(dir) {
375
- if (!fs.existsSync(dir)) {
376
- return [];
377
- }
378
- const files = await promises.readdir(dir);
379
- const sqlFiles = files.filter((f) => isValidMigrationFilename(f)).sort();
380
- const migrations = [];
381
- for (const file of sqlFiles) {
382
- const content = await promises.readFile(path.resolve(dir, file), "utf-8");
383
- migrations.push({
384
- name: path.basename(file),
385
- content
386
- });
387
- }
388
- return migrations;
389
- }
390
- async function generateMigrationManifest(options) {
391
- const { migrationsDir, database } = options;
392
- const files = await readMigrationFiles(migrationsDir);
393
- const migrations = await Promise.all(
394
- files.map(async (file) => {
395
- const timestamp = extractTimestamp(file.name);
396
- const checksum = await calculatePrefixedChecksum(file.content);
397
- return {
398
- id: timestamp || file.name.replace(".sql", ""),
399
- file: file.name,
400
- checksum
401
- };
402
- })
403
- );
404
- return {
405
- manifest: {
406
- database,
407
- migrations
408
- },
409
- files
410
- };
411
- }
412
- async function validateMigrationManifest(manifest, files) {
413
- const errors = [];
414
- for (const entry of manifest.migrations) {
415
- const file = files.find((f) => f.name === entry.file);
416
- if (!file) {
417
- errors.push(`Missing file: ${entry.file}`);
418
- continue;
419
- }
420
- const actualChecksum = await calculatePrefixedChecksum(file.content);
421
- if (actualChecksum !== entry.checksum) {
422
- errors.push(
423
- `Checksum mismatch for ${entry.file}: expected ${entry.checksum}, got ${actualChecksum}`
424
- );
425
- }
426
- const timestamp = extractTimestamp(file.name);
427
- if (timestamp !== entry.id) {
428
- errors.push(
429
- `ID mismatch for ${entry.file}: expected ${timestamp}, got ${entry.id}`
430
- );
431
- }
432
- }
433
- for (const file of files) {
434
- if (!manifest.migrations.some((m) => m.file === file.name)) {
435
- errors.push(`File not in manifest: ${file.name}`);
436
- }
437
- }
438
- return {
439
- valid: errors.length === 0,
440
- errors
441
- };
442
- }
443
370
 
444
371
  // src/events/client.ts
445
372
  var EldrinEventClient = class {
@@ -1052,7 +979,6 @@ exports.compileRoutes = compileRoutes;
1052
979
  exports.createEventClient = createEventClient;
1053
980
  exports.createPermissionMiddleware = createPermissionMiddleware;
1054
981
  exports.extractTimestamp = extractTimestamp;
1055
- exports.generateMigrationManifest = generateMigrationManifest;
1056
982
  exports.getAuthContext = getAuthContext;
1057
983
  exports.getAuthContextFromJWT = getAuthContextFromJWT;
1058
984
  exports.getMigrationStatus = getMigrationStatus;
@@ -1073,7 +999,6 @@ exports.requireJWTPermission = requireJWTPermission;
1073
999
  exports.requirePermission = requirePermission;
1074
1000
  exports.rollbackMigrations = rollbackMigrations;
1075
1001
  exports.runMigrations = runMigrations;
1076
- exports.validateMigrationManifest = validateMigrationManifest;
1077
1002
  exports.verifyChecksum = verifyChecksum;
1078
1003
  exports.verifyJWT = verifyJWT;
1079
1004
  //# sourceMappingURL=index.cjs.map