@vibecms/core 0.1.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.
- package/dist/engine/index.d.mts +4 -0
- package/dist/engine/index.d.ts +4 -0
- package/dist/engine/index.js +1226 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/index.mjs +1184 -0
- package/dist/engine/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +27 -0
- package/dist/hooks/index.d.ts +27 -0
- package/dist/hooks/index.js +75 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +47 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index-C3P1J_of.d.ts +339 -0
- package/dist/index-CO4uwTdH.d.mts +339 -0
- package/dist/index.css +2326 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +412 -0
- package/dist/index.d.ts +412 -0
- package/dist/index.js +3715 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3587 -0
- package/dist/index.mjs.map +1 -0
- package/dist/storage/index.d.mts +32 -0
- package/dist/storage/index.d.ts +32 -0
- package/dist/storage/index.js +103 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.mjs +75 -0
- package/dist/storage/index.mjs.map +1 -0
- package/dist/types-BkDsDmQJ.d.mts +83 -0
- package/dist/types-BkDsDmQJ.d.ts +83 -0
- package/dist/ui/index.d.mts +127 -0
- package/dist/ui/index.d.ts +127 -0
- package/dist/ui/index.js +1119 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/index.mjs +1030 -0
- package/dist/ui/index.mjs.map +1 -0
- package/dist/vite-plugin.d.mts +8 -0
- package/dist/vite-plugin.d.ts +8 -0
- package/dist/vite-plugin.js +193 -0
- package/dist/vite-plugin.js.map +1 -0
- package/dist/vite-plugin.mjs +165 -0
- package/dist/vite-plugin.mjs.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { S as StorageDriver, a as SyncEngine, V as VibeEngineConfig, C as CommitAuthor, L as ListOptions, H as HistoryEntry } from './types-BkDsDmQJ.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
|
+
|
|
5
|
+
type VibeRole = 'owner' | 'editor' | 'viewer';
|
|
6
|
+
interface VibeUser {
|
|
7
|
+
name?: string | null;
|
|
8
|
+
email?: string | null;
|
|
9
|
+
image?: string | null;
|
|
10
|
+
role?: VibeRole;
|
|
11
|
+
}
|
|
12
|
+
interface VibeAccessRule {
|
|
13
|
+
email: string;
|
|
14
|
+
role: VibeRole;
|
|
15
|
+
}
|
|
16
|
+
interface AuthProvider {
|
|
17
|
+
getSession(): Promise<{
|
|
18
|
+
user: VibeUser;
|
|
19
|
+
accessToken?: string;
|
|
20
|
+
} | null>;
|
|
21
|
+
signIn(): Promise<void>;
|
|
22
|
+
signOut(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type VibeEventType = 'content:save' | 'content:publish' | 'content:unpublish' | 'content:delete' | 'content:commit' | 'media:upload' | 'media:prune';
|
|
26
|
+
interface VibeEvent {
|
|
27
|
+
type: VibeEventType;
|
|
28
|
+
collection?: string;
|
|
29
|
+
slug?: string;
|
|
30
|
+
data?: any;
|
|
31
|
+
timestamp: number;
|
|
32
|
+
author?: {
|
|
33
|
+
name: string;
|
|
34
|
+
email: string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface WebhookConfig {
|
|
38
|
+
/** URL to send the POST request to */
|
|
39
|
+
url: string;
|
|
40
|
+
/** Which events trigger this webhook. Empty = all events. */
|
|
41
|
+
events?: VibeEventType[];
|
|
42
|
+
/** Optional secret for HMAC signature verification (X-Vibe-Signature header) */
|
|
43
|
+
secret?: string;
|
|
44
|
+
}
|
|
45
|
+
type EventListener = (event: VibeEvent) => void | Promise<void>;
|
|
46
|
+
declare class VibeEventBus {
|
|
47
|
+
private listeners;
|
|
48
|
+
private webhooks;
|
|
49
|
+
/**
|
|
50
|
+
* Register webhooks from config.
|
|
51
|
+
*/
|
|
52
|
+
registerWebhooks(webhooks: WebhookConfig[]): void;
|
|
53
|
+
/**
|
|
54
|
+
* Subscribe to a specific event type or '*' for all events.
|
|
55
|
+
*/
|
|
56
|
+
on(type: VibeEventType | '*', listener: EventListener): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Emit an event. Notifies all listeners and fires webhooks.
|
|
59
|
+
*/
|
|
60
|
+
emit(event: VibeEvent): Promise<void>;
|
|
61
|
+
private fireWebhooks;
|
|
62
|
+
}
|
|
63
|
+
declare const vibeEvents: VibeEventBus;
|
|
64
|
+
|
|
65
|
+
interface VibeCollection {
|
|
66
|
+
name: string;
|
|
67
|
+
schema: z.ZodTypeAny;
|
|
68
|
+
/** Restrict which roles can edit this collection. Default: ['owner', 'editor'] */
|
|
69
|
+
editRoles?: VibeRole[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Registration entry for a custom block renderer.
|
|
73
|
+
*/
|
|
74
|
+
interface VibeBlockRegistration {
|
|
75
|
+
/** The `_type` value in your block schema */
|
|
76
|
+
type: string;
|
|
77
|
+
/** React component to render this block. Receives `{ data, index }` props. */
|
|
78
|
+
component: ComponentType<{
|
|
79
|
+
data: any;
|
|
80
|
+
index: string | number;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
interface VibeConfig {
|
|
84
|
+
/**
|
|
85
|
+
* VibeCMS license key. Set via `VIBE_LICENSE_KEY` env var (preferred) or here.
|
|
86
|
+
* Get your key at https://vibecms.com/pricing
|
|
87
|
+
*/
|
|
88
|
+
licenseKey?: string;
|
|
89
|
+
contentDir?: string;
|
|
90
|
+
publicDir?: string;
|
|
91
|
+
auth?: AuthProvider;
|
|
92
|
+
media?: {
|
|
93
|
+
driver: StorageDriver;
|
|
94
|
+
};
|
|
95
|
+
collections?: Record<string, VibeCollection>;
|
|
96
|
+
/**
|
|
97
|
+
* Single global documents that do not have a list view (e.g., globals, navigation, footer).
|
|
98
|
+
* They behave like collections but are enforced to have a single slug 'index'.
|
|
99
|
+
*/
|
|
100
|
+
singletons?: Record<string, VibeCollection>;
|
|
101
|
+
/**
|
|
102
|
+
* Register custom block renderers. These are merged with built-in blocks.
|
|
103
|
+
* Custom registrations take precedence over built-in blocks with the same `_type`.
|
|
104
|
+
*
|
|
105
|
+
* Example:
|
|
106
|
+
* blocks: [
|
|
107
|
+
* { type: 'comparison-table', component: ComparisonTable },
|
|
108
|
+
* { type: 'hero', component: CustomHero }, // overrides built-in hero
|
|
109
|
+
* ]
|
|
110
|
+
*/
|
|
111
|
+
blocks?: VibeBlockRegistration[];
|
|
112
|
+
/**
|
|
113
|
+
* Access control list. The first entry should be the owner.
|
|
114
|
+
* Users not in this list are denied access to the CMS editor.
|
|
115
|
+
*
|
|
116
|
+
* Example:
|
|
117
|
+
* access: [
|
|
118
|
+
* { email: 'owner@example.com', role: 'owner' },
|
|
119
|
+
* { email: 'editor@company.de', role: 'editor' },
|
|
120
|
+
* { email: 'viewer@company.de', role: 'viewer' },
|
|
121
|
+
* ]
|
|
122
|
+
*/
|
|
123
|
+
access?: VibeAccessRule[];
|
|
124
|
+
/**
|
|
125
|
+
* Webhooks to notify on content lifecycle events.
|
|
126
|
+
*
|
|
127
|
+
* Example:
|
|
128
|
+
* webhooks: [
|
|
129
|
+
* { url: 'https://hooks.example.com/deploy', events: ['content:publish'], secret: 'whsec_...' },
|
|
130
|
+
* ]
|
|
131
|
+
*/
|
|
132
|
+
webhooks?: WebhookConfig[];
|
|
133
|
+
/**
|
|
134
|
+
* Localization support. Specify all locales you want the CMS to generate files for.
|
|
135
|
+
* If enabled, documents are saved as `[slug].[locale].json`.
|
|
136
|
+
*/
|
|
137
|
+
locales?: string[];
|
|
138
|
+
defaultLocale?: string;
|
|
139
|
+
}
|
|
140
|
+
declare function defineConfig(config: VibeConfig): VibeConfig;
|
|
141
|
+
declare function registerCollectionSchemas(collections?: Record<string, VibeCollection>, singletons?: Record<string, VibeCollection>): void;
|
|
142
|
+
declare function getCollectionSchema(collection: string): z.ZodTypeAny | undefined;
|
|
143
|
+
/**
|
|
144
|
+
* Validate data against a collection's schema.
|
|
145
|
+
* Returns { success: true, data } or { success: false, errors }.
|
|
146
|
+
*/
|
|
147
|
+
declare function validateCollectionData(collection: string, data: unknown): {
|
|
148
|
+
success: true;
|
|
149
|
+
data: any;
|
|
150
|
+
} | {
|
|
151
|
+
success: false;
|
|
152
|
+
errors: string[];
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the role for a given email from the access list.
|
|
156
|
+
* Returns null if the user is not whitelisted.
|
|
157
|
+
*/
|
|
158
|
+
declare function resolveUserRole(config: VibeConfig, email: string | null | undefined): VibeRole | null;
|
|
159
|
+
/**
|
|
160
|
+
* Check whether a role is allowed to edit a specific collection.
|
|
161
|
+
*/
|
|
162
|
+
declare function canEditCollection(config: VibeConfig, role: VibeRole | null, collectionKey: string): boolean;
|
|
163
|
+
declare function registerCustomBlocks(blocks: VibeBlockRegistration[]): void;
|
|
164
|
+
declare function getCustomBlockComponent(type: string): ComponentType<{
|
|
165
|
+
data: any;
|
|
166
|
+
index: string | number;
|
|
167
|
+
}> | undefined;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Validate a content slug. Slugs are used as filenames and must be safe
|
|
171
|
+
* for filesystem paths and shell arguments.
|
|
172
|
+
*/
|
|
173
|
+
declare function validateSlug(slug: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Validate a git commit OID (SHA-1 hex hash).
|
|
176
|
+
*/
|
|
177
|
+
declare function validateCommitOid(oid: string): boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Validate a collection name.
|
|
180
|
+
*/
|
|
181
|
+
declare function validateCollection(collection: string): boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Assert slug is valid, throw if not.
|
|
184
|
+
*/
|
|
185
|
+
declare function assertValidSlug(slug: string): void;
|
|
186
|
+
/**
|
|
187
|
+
* Assert commit OID is valid, throw if not.
|
|
188
|
+
*/
|
|
189
|
+
declare function assertValidCommitOid(oid: string): void;
|
|
190
|
+
/**
|
|
191
|
+
* Assert collection name is valid, throw if not.
|
|
192
|
+
*/
|
|
193
|
+
declare function assertValidCollection(collection: string): void;
|
|
194
|
+
/**
|
|
195
|
+
* Sanitize a redirect path to prevent open redirects.
|
|
196
|
+
* Returns '/' if the path is invalid.
|
|
197
|
+
*/
|
|
198
|
+
declare function sanitizeRedirectPath(path: string | null | undefined): string;
|
|
199
|
+
|
|
200
|
+
declare class NodeEngine implements SyncEngine {
|
|
201
|
+
private contentDir;
|
|
202
|
+
private publicDir;
|
|
203
|
+
private config?;
|
|
204
|
+
private contentCache;
|
|
205
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
206
|
+
private resolveFilename;
|
|
207
|
+
read(collection: string, slug: string, options?: {
|
|
208
|
+
locale?: string;
|
|
209
|
+
}): Promise<any>;
|
|
210
|
+
write(collection: string, slug: string, data: any, options?: {
|
|
211
|
+
locale?: string;
|
|
212
|
+
}): Promise<void>;
|
|
213
|
+
delete(collection: string, slug: string, options?: {
|
|
214
|
+
locale?: string;
|
|
215
|
+
}): Promise<void>;
|
|
216
|
+
isDirty(): Promise<boolean>;
|
|
217
|
+
revert(): Promise<void>;
|
|
218
|
+
commit(_message: string, _author?: CommitAuthor): Promise<void>;
|
|
219
|
+
push(): Promise<void>;
|
|
220
|
+
pull(): Promise<void>;
|
|
221
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<string | {
|
|
222
|
+
url: string;
|
|
223
|
+
width?: number;
|
|
224
|
+
height?: number;
|
|
225
|
+
alt?: string;
|
|
226
|
+
}>;
|
|
227
|
+
listMedia(): Promise<string[]>;
|
|
228
|
+
deleteMedia(filename: string): Promise<void>;
|
|
229
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
230
|
+
pruneMedia(): Promise<{
|
|
231
|
+
deletedCount: number;
|
|
232
|
+
bytesFreed: number;
|
|
233
|
+
}>;
|
|
234
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
235
|
+
list(collection: string, options?: ListOptions): Promise<any[]>;
|
|
236
|
+
getHistory(collection: string, slug: string): Promise<HistoryEntry[]>;
|
|
237
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
declare class BrowserEngine implements SyncEngine {
|
|
241
|
+
private fs;
|
|
242
|
+
private pfs;
|
|
243
|
+
private dir;
|
|
244
|
+
private contentDir;
|
|
245
|
+
private publicDir;
|
|
246
|
+
private gitProxyUrl;
|
|
247
|
+
private isInitializing;
|
|
248
|
+
private initialized;
|
|
249
|
+
private config?;
|
|
250
|
+
constructor();
|
|
251
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
252
|
+
private resolveFilename;
|
|
253
|
+
read(collection: string, slug: string, options?: {
|
|
254
|
+
locale?: string;
|
|
255
|
+
}): Promise<any>;
|
|
256
|
+
write(collection: string, slug: string, data: any, options?: {
|
|
257
|
+
locale?: string;
|
|
258
|
+
}): Promise<void>;
|
|
259
|
+
delete(collection: string, slug: string, options?: {
|
|
260
|
+
locale?: string;
|
|
261
|
+
}): Promise<void>;
|
|
262
|
+
isDirty(collection: string, slug: string): Promise<boolean>;
|
|
263
|
+
revert(collection: string, slug: string): Promise<void>;
|
|
264
|
+
commit(message: string, author?: CommitAuthor): Promise<void>;
|
|
265
|
+
push(oauthToken: string): Promise<void>;
|
|
266
|
+
pull(): Promise<void>;
|
|
267
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<string | {
|
|
268
|
+
url: string;
|
|
269
|
+
width?: number;
|
|
270
|
+
height?: number;
|
|
271
|
+
alt?: string;
|
|
272
|
+
}>;
|
|
273
|
+
pruneMedia(): Promise<{
|
|
274
|
+
deletedCount: number;
|
|
275
|
+
bytesFreed: number;
|
|
276
|
+
}>;
|
|
277
|
+
listMedia(): Promise<string[]>;
|
|
278
|
+
deleteMedia(filename: string): Promise<void>;
|
|
279
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
280
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
281
|
+
list(collection: string, options?: ListOptions): Promise<any>;
|
|
282
|
+
getHistory(collection: string, slug: string): Promise<HistoryEntry[]>;
|
|
283
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
declare class DevEngine implements SyncEngine {
|
|
287
|
+
private apiBase;
|
|
288
|
+
private config?;
|
|
289
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
290
|
+
private fetchApi;
|
|
291
|
+
read<T = any>(collection: string, slug: string, options?: {
|
|
292
|
+
locale?: string;
|
|
293
|
+
}): Promise<T | null>;
|
|
294
|
+
write<T = any>(collection: string, slug: string, data: T, options?: {
|
|
295
|
+
locale?: string;
|
|
296
|
+
}): Promise<void>;
|
|
297
|
+
delete(collection: string, slug: string, options?: {
|
|
298
|
+
locale?: string;
|
|
299
|
+
}): Promise<void>;
|
|
300
|
+
isDirty(): Promise<boolean>;
|
|
301
|
+
revert(): Promise<void>;
|
|
302
|
+
commit(_message: string, _author?: CommitAuthor): Promise<void>;
|
|
303
|
+
push(): Promise<void>;
|
|
304
|
+
pull(): Promise<void>;
|
|
305
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<any>;
|
|
306
|
+
listMedia(): Promise<string[]>;
|
|
307
|
+
deleteMedia(filename: string): Promise<void>;
|
|
308
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
309
|
+
pruneMedia(): Promise<{
|
|
310
|
+
deletedCount: number;
|
|
311
|
+
bytesFreed: number;
|
|
312
|
+
}>;
|
|
313
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
314
|
+
list(collection: string, options?: ListOptions): Promise<any>;
|
|
315
|
+
getHistory(_collection: string, _slug: string): Promise<HistoryEntry[]>;
|
|
316
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Proxy guard: prevents using VibeEngine methods without a valid license.
|
|
321
|
+
* All function calls (except init) require `_licensed === true`, which is
|
|
322
|
+
* only set by `initVibeEngine()` after successful license validation.
|
|
323
|
+
*/
|
|
324
|
+
declare const VibeEngine: SyncEngine;
|
|
325
|
+
/**
|
|
326
|
+
* Initialize the engine with license validation, then register collection schemas.
|
|
327
|
+
* Call this once at app startup (e.g. in EditProvider or AdminShell).
|
|
328
|
+
*
|
|
329
|
+
* @throws {Error} if the license key is missing, invalid, or expired
|
|
330
|
+
*/
|
|
331
|
+
declare function initVibeEngine(config: VibeEngineConfig & {
|
|
332
|
+
licenseKey?: string;
|
|
333
|
+
}, collections?: Record<string, VibeCollection>, singletons?: Record<string, VibeCollection>): Promise<void>;
|
|
334
|
+
declare function populate(document: any, refs: {
|
|
335
|
+
field: string;
|
|
336
|
+
collection: string;
|
|
337
|
+
}[]): Promise<any>;
|
|
338
|
+
|
|
339
|
+
export { type AuthProvider as A, BrowserEngine as B, DevEngine as D, NodeEngine as N, type VibeAccessRule as V, type WebhookConfig as W, type VibeBlockRegistration as a, type VibeCollection as b, type VibeConfig as c, VibeEngine as d, type VibeEvent as e, type VibeEventType as f, type VibeRole as g, type VibeUser as h, assertValidCollection as i, assertValidCommitOid as j, assertValidSlug as k, canEditCollection as l, defineConfig as m, getCollectionSchema as n, getCustomBlockComponent as o, initVibeEngine as p, populate as q, registerCollectionSchemas as r, registerCustomBlocks as s, resolveUserRole as t, sanitizeRedirectPath as u, validateCollection as v, validateCollectionData as w, validateCommitOid as x, validateSlug as y, vibeEvents as z };
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { S as StorageDriver, a as SyncEngine, V as VibeEngineConfig, C as CommitAuthor, L as ListOptions, H as HistoryEntry } from './types-BkDsDmQJ.mjs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
|
+
|
|
5
|
+
type VibeRole = 'owner' | 'editor' | 'viewer';
|
|
6
|
+
interface VibeUser {
|
|
7
|
+
name?: string | null;
|
|
8
|
+
email?: string | null;
|
|
9
|
+
image?: string | null;
|
|
10
|
+
role?: VibeRole;
|
|
11
|
+
}
|
|
12
|
+
interface VibeAccessRule {
|
|
13
|
+
email: string;
|
|
14
|
+
role: VibeRole;
|
|
15
|
+
}
|
|
16
|
+
interface AuthProvider {
|
|
17
|
+
getSession(): Promise<{
|
|
18
|
+
user: VibeUser;
|
|
19
|
+
accessToken?: string;
|
|
20
|
+
} | null>;
|
|
21
|
+
signIn(): Promise<void>;
|
|
22
|
+
signOut(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type VibeEventType = 'content:save' | 'content:publish' | 'content:unpublish' | 'content:delete' | 'content:commit' | 'media:upload' | 'media:prune';
|
|
26
|
+
interface VibeEvent {
|
|
27
|
+
type: VibeEventType;
|
|
28
|
+
collection?: string;
|
|
29
|
+
slug?: string;
|
|
30
|
+
data?: any;
|
|
31
|
+
timestamp: number;
|
|
32
|
+
author?: {
|
|
33
|
+
name: string;
|
|
34
|
+
email: string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface WebhookConfig {
|
|
38
|
+
/** URL to send the POST request to */
|
|
39
|
+
url: string;
|
|
40
|
+
/** Which events trigger this webhook. Empty = all events. */
|
|
41
|
+
events?: VibeEventType[];
|
|
42
|
+
/** Optional secret for HMAC signature verification (X-Vibe-Signature header) */
|
|
43
|
+
secret?: string;
|
|
44
|
+
}
|
|
45
|
+
type EventListener = (event: VibeEvent) => void | Promise<void>;
|
|
46
|
+
declare class VibeEventBus {
|
|
47
|
+
private listeners;
|
|
48
|
+
private webhooks;
|
|
49
|
+
/**
|
|
50
|
+
* Register webhooks from config.
|
|
51
|
+
*/
|
|
52
|
+
registerWebhooks(webhooks: WebhookConfig[]): void;
|
|
53
|
+
/**
|
|
54
|
+
* Subscribe to a specific event type or '*' for all events.
|
|
55
|
+
*/
|
|
56
|
+
on(type: VibeEventType | '*', listener: EventListener): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Emit an event. Notifies all listeners and fires webhooks.
|
|
59
|
+
*/
|
|
60
|
+
emit(event: VibeEvent): Promise<void>;
|
|
61
|
+
private fireWebhooks;
|
|
62
|
+
}
|
|
63
|
+
declare const vibeEvents: VibeEventBus;
|
|
64
|
+
|
|
65
|
+
interface VibeCollection {
|
|
66
|
+
name: string;
|
|
67
|
+
schema: z.ZodTypeAny;
|
|
68
|
+
/** Restrict which roles can edit this collection. Default: ['owner', 'editor'] */
|
|
69
|
+
editRoles?: VibeRole[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Registration entry for a custom block renderer.
|
|
73
|
+
*/
|
|
74
|
+
interface VibeBlockRegistration {
|
|
75
|
+
/** The `_type` value in your block schema */
|
|
76
|
+
type: string;
|
|
77
|
+
/** React component to render this block. Receives `{ data, index }` props. */
|
|
78
|
+
component: ComponentType<{
|
|
79
|
+
data: any;
|
|
80
|
+
index: string | number;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
interface VibeConfig {
|
|
84
|
+
/**
|
|
85
|
+
* VibeCMS license key. Set via `VIBE_LICENSE_KEY` env var (preferred) or here.
|
|
86
|
+
* Get your key at https://vibecms.com/pricing
|
|
87
|
+
*/
|
|
88
|
+
licenseKey?: string;
|
|
89
|
+
contentDir?: string;
|
|
90
|
+
publicDir?: string;
|
|
91
|
+
auth?: AuthProvider;
|
|
92
|
+
media?: {
|
|
93
|
+
driver: StorageDriver;
|
|
94
|
+
};
|
|
95
|
+
collections?: Record<string, VibeCollection>;
|
|
96
|
+
/**
|
|
97
|
+
* Single global documents that do not have a list view (e.g., globals, navigation, footer).
|
|
98
|
+
* They behave like collections but are enforced to have a single slug 'index'.
|
|
99
|
+
*/
|
|
100
|
+
singletons?: Record<string, VibeCollection>;
|
|
101
|
+
/**
|
|
102
|
+
* Register custom block renderers. These are merged with built-in blocks.
|
|
103
|
+
* Custom registrations take precedence over built-in blocks with the same `_type`.
|
|
104
|
+
*
|
|
105
|
+
* Example:
|
|
106
|
+
* blocks: [
|
|
107
|
+
* { type: 'comparison-table', component: ComparisonTable },
|
|
108
|
+
* { type: 'hero', component: CustomHero }, // overrides built-in hero
|
|
109
|
+
* ]
|
|
110
|
+
*/
|
|
111
|
+
blocks?: VibeBlockRegistration[];
|
|
112
|
+
/**
|
|
113
|
+
* Access control list. The first entry should be the owner.
|
|
114
|
+
* Users not in this list are denied access to the CMS editor.
|
|
115
|
+
*
|
|
116
|
+
* Example:
|
|
117
|
+
* access: [
|
|
118
|
+
* { email: 'owner@example.com', role: 'owner' },
|
|
119
|
+
* { email: 'editor@company.de', role: 'editor' },
|
|
120
|
+
* { email: 'viewer@company.de', role: 'viewer' },
|
|
121
|
+
* ]
|
|
122
|
+
*/
|
|
123
|
+
access?: VibeAccessRule[];
|
|
124
|
+
/**
|
|
125
|
+
* Webhooks to notify on content lifecycle events.
|
|
126
|
+
*
|
|
127
|
+
* Example:
|
|
128
|
+
* webhooks: [
|
|
129
|
+
* { url: 'https://hooks.example.com/deploy', events: ['content:publish'], secret: 'whsec_...' },
|
|
130
|
+
* ]
|
|
131
|
+
*/
|
|
132
|
+
webhooks?: WebhookConfig[];
|
|
133
|
+
/**
|
|
134
|
+
* Localization support. Specify all locales you want the CMS to generate files for.
|
|
135
|
+
* If enabled, documents are saved as `[slug].[locale].json`.
|
|
136
|
+
*/
|
|
137
|
+
locales?: string[];
|
|
138
|
+
defaultLocale?: string;
|
|
139
|
+
}
|
|
140
|
+
declare function defineConfig(config: VibeConfig): VibeConfig;
|
|
141
|
+
declare function registerCollectionSchemas(collections?: Record<string, VibeCollection>, singletons?: Record<string, VibeCollection>): void;
|
|
142
|
+
declare function getCollectionSchema(collection: string): z.ZodTypeAny | undefined;
|
|
143
|
+
/**
|
|
144
|
+
* Validate data against a collection's schema.
|
|
145
|
+
* Returns { success: true, data } or { success: false, errors }.
|
|
146
|
+
*/
|
|
147
|
+
declare function validateCollectionData(collection: string, data: unknown): {
|
|
148
|
+
success: true;
|
|
149
|
+
data: any;
|
|
150
|
+
} | {
|
|
151
|
+
success: false;
|
|
152
|
+
errors: string[];
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the role for a given email from the access list.
|
|
156
|
+
* Returns null if the user is not whitelisted.
|
|
157
|
+
*/
|
|
158
|
+
declare function resolveUserRole(config: VibeConfig, email: string | null | undefined): VibeRole | null;
|
|
159
|
+
/**
|
|
160
|
+
* Check whether a role is allowed to edit a specific collection.
|
|
161
|
+
*/
|
|
162
|
+
declare function canEditCollection(config: VibeConfig, role: VibeRole | null, collectionKey: string): boolean;
|
|
163
|
+
declare function registerCustomBlocks(blocks: VibeBlockRegistration[]): void;
|
|
164
|
+
declare function getCustomBlockComponent(type: string): ComponentType<{
|
|
165
|
+
data: any;
|
|
166
|
+
index: string | number;
|
|
167
|
+
}> | undefined;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Validate a content slug. Slugs are used as filenames and must be safe
|
|
171
|
+
* for filesystem paths and shell arguments.
|
|
172
|
+
*/
|
|
173
|
+
declare function validateSlug(slug: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Validate a git commit OID (SHA-1 hex hash).
|
|
176
|
+
*/
|
|
177
|
+
declare function validateCommitOid(oid: string): boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Validate a collection name.
|
|
180
|
+
*/
|
|
181
|
+
declare function validateCollection(collection: string): boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Assert slug is valid, throw if not.
|
|
184
|
+
*/
|
|
185
|
+
declare function assertValidSlug(slug: string): void;
|
|
186
|
+
/**
|
|
187
|
+
* Assert commit OID is valid, throw if not.
|
|
188
|
+
*/
|
|
189
|
+
declare function assertValidCommitOid(oid: string): void;
|
|
190
|
+
/**
|
|
191
|
+
* Assert collection name is valid, throw if not.
|
|
192
|
+
*/
|
|
193
|
+
declare function assertValidCollection(collection: string): void;
|
|
194
|
+
/**
|
|
195
|
+
* Sanitize a redirect path to prevent open redirects.
|
|
196
|
+
* Returns '/' if the path is invalid.
|
|
197
|
+
*/
|
|
198
|
+
declare function sanitizeRedirectPath(path: string | null | undefined): string;
|
|
199
|
+
|
|
200
|
+
declare class NodeEngine implements SyncEngine {
|
|
201
|
+
private contentDir;
|
|
202
|
+
private publicDir;
|
|
203
|
+
private config?;
|
|
204
|
+
private contentCache;
|
|
205
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
206
|
+
private resolveFilename;
|
|
207
|
+
read(collection: string, slug: string, options?: {
|
|
208
|
+
locale?: string;
|
|
209
|
+
}): Promise<any>;
|
|
210
|
+
write(collection: string, slug: string, data: any, options?: {
|
|
211
|
+
locale?: string;
|
|
212
|
+
}): Promise<void>;
|
|
213
|
+
delete(collection: string, slug: string, options?: {
|
|
214
|
+
locale?: string;
|
|
215
|
+
}): Promise<void>;
|
|
216
|
+
isDirty(): Promise<boolean>;
|
|
217
|
+
revert(): Promise<void>;
|
|
218
|
+
commit(_message: string, _author?: CommitAuthor): Promise<void>;
|
|
219
|
+
push(): Promise<void>;
|
|
220
|
+
pull(): Promise<void>;
|
|
221
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<string | {
|
|
222
|
+
url: string;
|
|
223
|
+
width?: number;
|
|
224
|
+
height?: number;
|
|
225
|
+
alt?: string;
|
|
226
|
+
}>;
|
|
227
|
+
listMedia(): Promise<string[]>;
|
|
228
|
+
deleteMedia(filename: string): Promise<void>;
|
|
229
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
230
|
+
pruneMedia(): Promise<{
|
|
231
|
+
deletedCount: number;
|
|
232
|
+
bytesFreed: number;
|
|
233
|
+
}>;
|
|
234
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
235
|
+
list(collection: string, options?: ListOptions): Promise<any[]>;
|
|
236
|
+
getHistory(collection: string, slug: string): Promise<HistoryEntry[]>;
|
|
237
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
declare class BrowserEngine implements SyncEngine {
|
|
241
|
+
private fs;
|
|
242
|
+
private pfs;
|
|
243
|
+
private dir;
|
|
244
|
+
private contentDir;
|
|
245
|
+
private publicDir;
|
|
246
|
+
private gitProxyUrl;
|
|
247
|
+
private isInitializing;
|
|
248
|
+
private initialized;
|
|
249
|
+
private config?;
|
|
250
|
+
constructor();
|
|
251
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
252
|
+
private resolveFilename;
|
|
253
|
+
read(collection: string, slug: string, options?: {
|
|
254
|
+
locale?: string;
|
|
255
|
+
}): Promise<any>;
|
|
256
|
+
write(collection: string, slug: string, data: any, options?: {
|
|
257
|
+
locale?: string;
|
|
258
|
+
}): Promise<void>;
|
|
259
|
+
delete(collection: string, slug: string, options?: {
|
|
260
|
+
locale?: string;
|
|
261
|
+
}): Promise<void>;
|
|
262
|
+
isDirty(collection: string, slug: string): Promise<boolean>;
|
|
263
|
+
revert(collection: string, slug: string): Promise<void>;
|
|
264
|
+
commit(message: string, author?: CommitAuthor): Promise<void>;
|
|
265
|
+
push(oauthToken: string): Promise<void>;
|
|
266
|
+
pull(): Promise<void>;
|
|
267
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<string | {
|
|
268
|
+
url: string;
|
|
269
|
+
width?: number;
|
|
270
|
+
height?: number;
|
|
271
|
+
alt?: string;
|
|
272
|
+
}>;
|
|
273
|
+
pruneMedia(): Promise<{
|
|
274
|
+
deletedCount: number;
|
|
275
|
+
bytesFreed: number;
|
|
276
|
+
}>;
|
|
277
|
+
listMedia(): Promise<string[]>;
|
|
278
|
+
deleteMedia(filename: string): Promise<void>;
|
|
279
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
280
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
281
|
+
list(collection: string, options?: ListOptions): Promise<any>;
|
|
282
|
+
getHistory(collection: string, slug: string): Promise<HistoryEntry[]>;
|
|
283
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
declare class DevEngine implements SyncEngine {
|
|
287
|
+
private apiBase;
|
|
288
|
+
private config?;
|
|
289
|
+
init(config?: VibeEngineConfig): Promise<void>;
|
|
290
|
+
private fetchApi;
|
|
291
|
+
read<T = any>(collection: string, slug: string, options?: {
|
|
292
|
+
locale?: string;
|
|
293
|
+
}): Promise<T | null>;
|
|
294
|
+
write<T = any>(collection: string, slug: string, data: T, options?: {
|
|
295
|
+
locale?: string;
|
|
296
|
+
}): Promise<void>;
|
|
297
|
+
delete(collection: string, slug: string, options?: {
|
|
298
|
+
locale?: string;
|
|
299
|
+
}): Promise<void>;
|
|
300
|
+
isDirty(): Promise<boolean>;
|
|
301
|
+
revert(): Promise<void>;
|
|
302
|
+
commit(_message: string, _author?: CommitAuthor): Promise<void>;
|
|
303
|
+
push(): Promise<void>;
|
|
304
|
+
pull(): Promise<void>;
|
|
305
|
+
writeMedia(file: File, author?: CommitAuthor): Promise<any>;
|
|
306
|
+
listMedia(): Promise<string[]>;
|
|
307
|
+
deleteMedia(filename: string): Promise<void>;
|
|
308
|
+
renameMedia(oldFilename: string, newFilename: string): Promise<void>;
|
|
309
|
+
pruneMedia(): Promise<{
|
|
310
|
+
deletedCount: number;
|
|
311
|
+
bytesFreed: number;
|
|
312
|
+
}>;
|
|
313
|
+
getMediaUrl(relativePath: string): Promise<string>;
|
|
314
|
+
list(collection: string, options?: ListOptions): Promise<any>;
|
|
315
|
+
getHistory(_collection: string, _slug: string): Promise<HistoryEntry[]>;
|
|
316
|
+
getVersionContent(commitOid: string, collection: string, slug: string): Promise<any>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Proxy guard: prevents using VibeEngine methods without a valid license.
|
|
321
|
+
* All function calls (except init) require `_licensed === true`, which is
|
|
322
|
+
* only set by `initVibeEngine()` after successful license validation.
|
|
323
|
+
*/
|
|
324
|
+
declare const VibeEngine: SyncEngine;
|
|
325
|
+
/**
|
|
326
|
+
* Initialize the engine with license validation, then register collection schemas.
|
|
327
|
+
* Call this once at app startup (e.g. in EditProvider or AdminShell).
|
|
328
|
+
*
|
|
329
|
+
* @throws {Error} if the license key is missing, invalid, or expired
|
|
330
|
+
*/
|
|
331
|
+
declare function initVibeEngine(config: VibeEngineConfig & {
|
|
332
|
+
licenseKey?: string;
|
|
333
|
+
}, collections?: Record<string, VibeCollection>, singletons?: Record<string, VibeCollection>): Promise<void>;
|
|
334
|
+
declare function populate(document: any, refs: {
|
|
335
|
+
field: string;
|
|
336
|
+
collection: string;
|
|
337
|
+
}[]): Promise<any>;
|
|
338
|
+
|
|
339
|
+
export { type AuthProvider as A, BrowserEngine as B, DevEngine as D, NodeEngine as N, type VibeAccessRule as V, type WebhookConfig as W, type VibeBlockRegistration as a, type VibeCollection as b, type VibeConfig as c, VibeEngine as d, type VibeEvent as e, type VibeEventType as f, type VibeRole as g, type VibeUser as h, assertValidCollection as i, assertValidCommitOid as j, assertValidSlug as k, canEditCollection as l, defineConfig as m, getCollectionSchema as n, getCustomBlockComponent as o, initVibeEngine as p, populate as q, registerCollectionSchemas as r, registerCustomBlocks as s, resolveUserRole as t, sanitizeRedirectPath as u, validateCollection as v, validateCollectionData as w, validateCommitOid as x, validateSlug as y, vibeEvents as z };
|