@easy-cms/core 0.4.0 → 0.6.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/index.d.ts +249 -14
- package/dist/index.js +1056 -113
- package/dist/live-preview.d.ts +8 -1
- package/dist/live-preview.js +7 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,14 @@ declare const anyone: Access;
|
|
|
56
56
|
declare const isLoggedIn: Access;
|
|
57
57
|
declare const isAdmin: Access;
|
|
58
58
|
|
|
59
|
+
/** What a preview token opens: one document of a collection, or one global. */
|
|
60
|
+
type PreviewTarget = {
|
|
61
|
+
readonly collection: string;
|
|
62
|
+
readonly id: string;
|
|
63
|
+
} | {
|
|
64
|
+
readonly global: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
59
67
|
interface Logger {
|
|
60
68
|
info(message: string): void;
|
|
61
69
|
warn(message: string): void;
|
|
@@ -193,6 +201,11 @@ interface BaseField<TType extends string, TValue> {
|
|
|
193
201
|
readonly access?: FieldAccess;
|
|
194
202
|
/** Stored but never returned by the API nor accepted as input (e.g. a password hash). */
|
|
195
203
|
readonly hidden?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* One value per locale (needs `localization` in the config). Not for groups, arrays or
|
|
206
|
+
* hasMany fields: localize the fields inside a group or array instead.
|
|
207
|
+
*/
|
|
208
|
+
readonly localized?: boolean;
|
|
196
209
|
}
|
|
197
210
|
interface TextField extends BaseField<'text', string> {
|
|
198
211
|
readonly minLength?: number;
|
|
@@ -250,9 +263,32 @@ interface ArrayField extends BaseField<'array', never> {
|
|
|
250
263
|
interface GroupField extends BaseField<'group', never> {
|
|
251
264
|
readonly fields: readonly Field[];
|
|
252
265
|
}
|
|
253
|
-
|
|
266
|
+
/** One kind of block in a `blocks` field. */
|
|
267
|
+
interface Block {
|
|
268
|
+
/** Stored in each row as `blockType`. */
|
|
269
|
+
readonly slug: string;
|
|
270
|
+
readonly labels?: {
|
|
271
|
+
readonly singular?: Label;
|
|
272
|
+
readonly plural?: Label;
|
|
273
|
+
};
|
|
274
|
+
readonly fields: readonly Field[];
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* A list of rows, each one of several block kinds (e.g. hero, text, gallery), for pages that
|
|
278
|
+
* editors lay out themselves. Rows are `{ id, blockType, ...fields }`, stored as JSON.
|
|
279
|
+
*/
|
|
280
|
+
interface BlocksField extends BaseField<'blocks', never> {
|
|
281
|
+
readonly blocks: readonly Block[];
|
|
282
|
+
readonly minRows?: number;
|
|
283
|
+
readonly maxRows?: number;
|
|
284
|
+
}
|
|
285
|
+
/** Fields whose value is a list of rows: `array` and `blocks`. */
|
|
286
|
+
declare const hasRows: (field: Field) => field is ArrayField | BlocksField;
|
|
287
|
+
/** The fields of one row of an `array` or `blocks` field (`undefined` for an unknown block). */
|
|
288
|
+
declare function rowFields(field: ArrayField | BlocksField, row: unknown): readonly Field[] | undefined;
|
|
289
|
+
type Field = TextField | TextareaField | NumberField | BooleanField | DateField | EmailField | JsonField | SelectField | SlugField | RichTextField | UploadField | RelationshipField | ArrayField | GroupField | BlocksField;
|
|
254
290
|
type FieldType = Field['type'];
|
|
255
|
-
declare const FIELD_TYPES: readonly ["text", "textarea", "number", "boolean", "date", "email", "json", "select", "slug", "richText", "upload", "relationship", "array", "group"];
|
|
291
|
+
declare const FIELD_TYPES: readonly ["text", "textarea", "number", "boolean", "date", "email", "json", "select", "slug", "richText", "upload", "relationship", "array", "group", "blocks"];
|
|
256
292
|
|
|
257
293
|
interface StoredFile {
|
|
258
294
|
readonly body: Uint8Array;
|
|
@@ -283,6 +319,39 @@ interface LocalStorageOptions {
|
|
|
283
319
|
/** Stores files on the local disk. Suitable for servers with a persistent filesystem. */
|
|
284
320
|
declare function localStorage(options?: LocalStorageOptions): StorageAdapter;
|
|
285
321
|
|
|
322
|
+
declare const WEBHOOK_EVENTS: readonly ["create", "update", "delete", "publish", "unpublish", "draft"];
|
|
323
|
+
/**
|
|
324
|
+
* `create`, `update`, `delete`: the stored document changed. `publish` / `unpublish`: its status
|
|
325
|
+
* changed (sent with `create` or `update`). `draft`: only a draft was saved; what is live did not
|
|
326
|
+
* change (collections with versions and drafts).
|
|
327
|
+
*/
|
|
328
|
+
type WebhookEvent = (typeof WEBHOOK_EVENTS)[number];
|
|
329
|
+
interface WebhookConfig {
|
|
330
|
+
/** Where to POST events. */
|
|
331
|
+
readonly url: string;
|
|
332
|
+
/** Events to send. Default: all. */
|
|
333
|
+
readonly events?: readonly WebhookEvent[];
|
|
334
|
+
/** Collections to send events for. Default: all; `[]` for none. */
|
|
335
|
+
readonly collections?: readonly string[];
|
|
336
|
+
/** Globals to send events for. Default: all; `[]` for none. */
|
|
337
|
+
readonly globals?: readonly string[];
|
|
338
|
+
/** Signs each body: `x-easy-cms-signature: sha256=<hex HMAC-SHA256 of the body>`. */
|
|
339
|
+
readonly secret?: string;
|
|
340
|
+
/** Extra request headers, e.g. a token the receiver checks. */
|
|
341
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
342
|
+
}
|
|
343
|
+
/** What a webhook receives as JSON. */
|
|
344
|
+
interface WebhookPayload {
|
|
345
|
+
readonly event: WebhookEvent;
|
|
346
|
+
readonly collection?: string;
|
|
347
|
+
readonly global?: string;
|
|
348
|
+
readonly id?: ID;
|
|
349
|
+
/** The stored document (every locale, no hidden fields); for `delete`, as it was. */
|
|
350
|
+
readonly doc: Record<string, unknown>;
|
|
351
|
+
/** ISO time of the change. */
|
|
352
|
+
readonly timestamp: string;
|
|
353
|
+
}
|
|
354
|
+
|
|
286
355
|
type Data$2 = Record<string, unknown>;
|
|
287
356
|
type MaybePromise<T> = T | Promise<T>;
|
|
288
357
|
type Operation = 'create' | 'update';
|
|
@@ -332,13 +401,22 @@ interface GlobalHooks {
|
|
|
332
401
|
readonly afterChange?: readonly AfterChangeHook[];
|
|
333
402
|
readonly afterRead?: readonly AfterReadHook[];
|
|
334
403
|
}
|
|
404
|
+
interface LocalizationConfig {
|
|
405
|
+
/** Content locales, e.g. `['th', 'en']`. */
|
|
406
|
+
readonly locales: readonly string[];
|
|
407
|
+
/** The locale used when none is given; its values also fill empty ones. Default: the first. */
|
|
408
|
+
readonly defaultLocale?: string;
|
|
409
|
+
/** Reads return the default locale's value when a locale's value is empty. Default true. */
|
|
410
|
+
readonly fallback?: boolean;
|
|
411
|
+
}
|
|
335
412
|
/**
|
|
336
413
|
* Where a document is shown on the site, for live preview in the admin: an absolute URL or a
|
|
337
414
|
* path on the site's origin. Return `null` when the document has no page.
|
|
338
415
|
*/
|
|
339
416
|
type PreviewURL = (args: {
|
|
340
417
|
readonly doc: Record<string, unknown>;
|
|
341
|
-
|
|
418
|
+
/** The content locale being edited (with `localization`), otherwise the admin locale. */
|
|
419
|
+
readonly locale: string;
|
|
342
420
|
}) => string | null | undefined;
|
|
343
421
|
interface VersionsConfig {
|
|
344
422
|
/** Versions kept per document; older ones are deleted. Default 50. */
|
|
@@ -362,6 +440,8 @@ interface CollectionConfig {
|
|
|
362
440
|
* it is published again.
|
|
363
441
|
*/
|
|
364
442
|
readonly versions?: boolean | VersionsConfig;
|
|
443
|
+
/** Allow scheduling publish/unpublish for a later time (needs `drafts`). */
|
|
444
|
+
readonly schedule?: boolean;
|
|
365
445
|
/** Live preview: the page that shows a document, e.g. `({ doc }) => \`/posts/${doc.slug}\``. */
|
|
366
446
|
readonly preview?: PreviewURL;
|
|
367
447
|
readonly access?: CollectionAccess;
|
|
@@ -374,6 +454,8 @@ interface GlobalConfig {
|
|
|
374
454
|
readonly drafts?: boolean;
|
|
375
455
|
/** Keep a snapshot of every save. See `CollectionConfig.versions`. */
|
|
376
456
|
readonly versions?: boolean | VersionsConfig;
|
|
457
|
+
/** Allow scheduling publish/unpublish for a later time (needs `drafts`). */
|
|
458
|
+
readonly schedule?: boolean;
|
|
377
459
|
/** Live preview: the page that shows the global. See `CollectionConfig.preview`. */
|
|
378
460
|
readonly preview?: PreviewURL;
|
|
379
461
|
readonly access?: GlobalAccess;
|
|
@@ -442,6 +524,16 @@ interface Config {
|
|
|
442
524
|
* `auth.trustedOrigins` are always allowed, with cookies. Default: none.
|
|
443
525
|
*/
|
|
444
526
|
readonly cors?: readonly string[] | '*';
|
|
527
|
+
/**
|
|
528
|
+
* Lets a cron service run due scheduled jobs: `GET <api>/jobs/run` with
|
|
529
|
+
* `Authorization: Bearer <cronSecret>`. Default: the `CRON_SECRET` environment variable (the
|
|
530
|
+
* convention of Vercel Cron). Logged-in admins can always run jobs.
|
|
531
|
+
*/
|
|
532
|
+
readonly cronSecret?: string;
|
|
533
|
+
/** Endpoints notified when content changes, e.g. to rebuild a static site. */
|
|
534
|
+
readonly webhooks?: readonly WebhookConfig[];
|
|
535
|
+
/** Content in several languages: fields with `localized: true` hold one value per locale. */
|
|
536
|
+
readonly localization?: LocalizationConfig | null;
|
|
445
537
|
readonly routes?: RoutesConfig;
|
|
446
538
|
readonly admin?: AdminConfig;
|
|
447
539
|
readonly upload?: UploadConfig;
|
|
@@ -455,8 +547,10 @@ interface Config {
|
|
|
455
547
|
readonly plugins?: readonly Plugin[];
|
|
456
548
|
}
|
|
457
549
|
/** The config after plugins ran, validation passed and defaults were applied. */
|
|
458
|
-
interface ResolvedConfig extends Omit<Config, 'cors' | 'routes' | 'admin' | 'upload' | 'auth' | 'collections' | 'globals' | 'plugins'> {
|
|
550
|
+
interface ResolvedConfig extends Omit<Config, 'cors' | 'localization' | 'routes' | 'admin' | 'upload' | 'auth' | 'collections' | 'globals' | 'plugins'> {
|
|
459
551
|
readonly cors: readonly string[] | '*';
|
|
552
|
+
/** `null` without localization. */
|
|
553
|
+
readonly localization: Required<LocalizationConfig> | null;
|
|
460
554
|
readonly routes: Required<RoutesConfig>;
|
|
461
555
|
readonly admin: Required<AdminConfig>;
|
|
462
556
|
readonly upload: Required<Omit<UploadConfig, 'storage'>> & Pick<UploadConfig, 'storage'>;
|
|
@@ -570,16 +664,38 @@ type FieldValue<F extends Field, C extends Config = Config> = F extends {
|
|
|
570
664
|
}>[] : F extends {
|
|
571
665
|
readonly type: 'group';
|
|
572
666
|
readonly fields: infer Sub extends readonly Field[];
|
|
573
|
-
} ? FieldsValue<Sub, C> :
|
|
667
|
+
} ? FieldsValue<Sub, C> : F extends {
|
|
668
|
+
readonly type: 'blocks';
|
|
669
|
+
readonly blocks: infer B extends readonly Block[];
|
|
670
|
+
} ? BlockValue<B[number], C>[] : never;
|
|
671
|
+
/** One row of a `blocks` field: the block's fields plus `id` and `blockType` (distributes over kinds). */
|
|
672
|
+
type BlockValue<B, C extends Config> = B extends {
|
|
673
|
+
readonly slug: infer S;
|
|
674
|
+
readonly fields: infer Sub extends readonly Field[];
|
|
675
|
+
} ? Simplify<FieldsValue<Sub, C> & {
|
|
676
|
+
id: string;
|
|
677
|
+
blockType: S;
|
|
678
|
+
}> : never;
|
|
679
|
+
type BlockInput<B> = B extends {
|
|
680
|
+
readonly slug: infer S;
|
|
681
|
+
readonly fields: infer Sub extends readonly Field[];
|
|
682
|
+
} ? Simplify<FieldsInput<Sub> & {
|
|
683
|
+
id?: string;
|
|
684
|
+
blockType: S;
|
|
685
|
+
}> : never;
|
|
574
686
|
type Visible<Fs extends readonly Field[]> = Exclude<Fs[number], {
|
|
575
687
|
readonly hidden: true;
|
|
576
688
|
}>;
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}>;
|
|
580
|
-
type OptionalFields<Fs extends readonly Field[]> = Exclude<Visible<Fs>, {
|
|
689
|
+
/** Always set when read: required fields, and lists and groups (empty `[]` / `{}` otherwise). */
|
|
690
|
+
type Present = {
|
|
581
691
|
readonly required: true;
|
|
582
|
-
}
|
|
692
|
+
} | {
|
|
693
|
+
readonly type: 'array' | 'blocks' | 'group';
|
|
694
|
+
} | {
|
|
695
|
+
readonly hasMany: true;
|
|
696
|
+
};
|
|
697
|
+
type RequiredFields<Fs extends readonly Field[]> = Extract<Visible<Fs>, Present>;
|
|
698
|
+
type OptionalFields<Fs extends readonly Field[]> = Exclude<Visible<Fs>, Present>;
|
|
583
699
|
/** The shape of the data described by a list of fields. */
|
|
584
700
|
type FieldsValue<Fs extends readonly Field[], C extends Config = Config> = Simplify<{
|
|
585
701
|
-readonly [F in RequiredFields<Fs> as F['name']]: FieldValue<F, C>;
|
|
@@ -634,7 +750,10 @@ type InputValue<F extends Field> = F extends {
|
|
|
634
750
|
}>[] : F extends {
|
|
635
751
|
readonly type: 'group';
|
|
636
752
|
readonly fields: infer Sub extends readonly Field[];
|
|
637
|
-
} ? FieldsInput<Sub> :
|
|
753
|
+
} ? FieldsInput<Sub> : F extends {
|
|
754
|
+
readonly type: 'blocks';
|
|
755
|
+
readonly blocks: infer B extends readonly Block[];
|
|
756
|
+
} ? readonly BlockInput<B[number]>[] : FieldValue<F>;
|
|
638
757
|
/** Required fields must be given, unless Easy CMS can fill them (default value, slug from another field). */
|
|
639
758
|
type NeedsInput<F extends Field> = F extends {
|
|
640
759
|
readonly required: true;
|
|
@@ -708,6 +827,11 @@ interface AccessOptions {
|
|
|
708
827
|
interface DepthOptions extends AccessOptions {
|
|
709
828
|
/** How many levels of relationships to populate. Default 1, maximum 3. */
|
|
710
829
|
readonly depth?: number;
|
|
830
|
+
/**
|
|
831
|
+
* With `localization`: the locale to read, and for writes the locale the data is in. Default:
|
|
832
|
+
* the default locale. `'all'` reads (and writes) localized fields as `{ [locale]: value }`.
|
|
833
|
+
*/
|
|
834
|
+
readonly locale?: string;
|
|
711
835
|
}
|
|
712
836
|
interface ReadOptions extends DepthOptions {
|
|
713
837
|
/**
|
|
@@ -715,6 +839,8 @@ interface ReadOptions extends DepthOptions {
|
|
|
715
839
|
* `drafts: true` are returned, including when populating relationships (FR-DRF-04).
|
|
716
840
|
*/
|
|
717
841
|
readonly draft?: boolean;
|
|
842
|
+
/** Use the default locale's value when a localized value is empty. Default: `localization.fallback`. */
|
|
843
|
+
readonly fallbackLocale?: boolean;
|
|
718
844
|
}
|
|
719
845
|
interface FindOptions extends ReadOptions {
|
|
720
846
|
readonly where?: Where;
|
|
@@ -728,6 +854,11 @@ interface FindOptions extends ReadOptions {
|
|
|
728
854
|
interface CreateEasyCMSOptions {
|
|
729
855
|
/** Project root. Default `process.cwd()`. */
|
|
730
856
|
readonly cwd?: string;
|
|
857
|
+
/**
|
|
858
|
+
* Run due scheduled jobs every minute in this process. Default: on when a collection or
|
|
859
|
+
* global has `schedule`. Turn it off where a cron calls `runScheduled` instead.
|
|
860
|
+
*/
|
|
861
|
+
readonly scheduler?: boolean;
|
|
731
862
|
/** Default `verify` when `NODE_ENV=production`, otherwise `push`. */
|
|
732
863
|
readonly schema?: SchemaMode;
|
|
733
864
|
readonly logger?: Logger;
|
|
@@ -735,6 +866,16 @@ interface CreateEasyCMSOptions {
|
|
|
735
866
|
}
|
|
736
867
|
/** Connects to the database and returns the Local API. */
|
|
737
868
|
declare function createEasyCMS<const C extends Config>(config: C, options?: CreateEasyCMSOptions): Promise<EasyCMS<C>>;
|
|
869
|
+
/** A scheduled publish or unpublish. */
|
|
870
|
+
interface ScheduledJob {
|
|
871
|
+
readonly id: ID;
|
|
872
|
+
readonly action: 'publish' | 'unpublish';
|
|
873
|
+
/** ISO time the job runs at (or after). */
|
|
874
|
+
readonly runAt: string;
|
|
875
|
+
readonly state: 'pending' | 'done' | 'failed';
|
|
876
|
+
readonly error: string | null;
|
|
877
|
+
readonly author: ID | null;
|
|
878
|
+
}
|
|
738
879
|
declare class EasyCMS<C extends Config = Config> {
|
|
739
880
|
readonly config: ResolvedConfig;
|
|
740
881
|
readonly db: Database;
|
|
@@ -744,12 +885,14 @@ declare class EasyCMS<C extends Config = Config> {
|
|
|
744
885
|
/** Where uploaded files are stored. */
|
|
745
886
|
readonly storage: StorageAdapter;
|
|
746
887
|
private readonly versions;
|
|
888
|
+
private readonly webhooks;
|
|
747
889
|
constructor(config: ResolvedConfig, db: Database, logger?: Logger, storage?: StorageAdapter);
|
|
748
890
|
find<S extends Slug<C>>(collection: S, options?: FindOptions): Promise<PaginatedDocs<Doc<C, S>>>;
|
|
749
891
|
findById<S extends Slug<C>>(collection: S, id: ID, options?: ReadOptions): Promise<Doc<C, S> | null>;
|
|
750
892
|
count<S extends Slug<C>>(collection: S, options?: {
|
|
751
893
|
where?: Where;
|
|
752
894
|
draft?: boolean;
|
|
895
|
+
locale?: string;
|
|
753
896
|
} & AccessOptions): Promise<number>;
|
|
754
897
|
create<S extends Slug<C>>(collection: S, data: Create<C, S>, options?: DepthOptions): Promise<Doc<C, S>>;
|
|
755
898
|
/**
|
|
@@ -789,6 +932,23 @@ declare class EasyCMS<C extends Config = Config> {
|
|
|
789
932
|
* `afterRead` hooks applied. Nothing is written. Also returns the page URL from `preview`.
|
|
790
933
|
*/
|
|
791
934
|
preview<S extends Slug<C>>(collection: S, id: ID | null, data: Record<string, unknown>, options?: DepthOptions): Promise<LivePreview<Doc<C, S>>>;
|
|
935
|
+
/**
|
|
936
|
+
* A token that lets a page read one document's current draft for a while (default one hour),
|
|
937
|
+
* without a login: `GET /api/cms/:collection/:id?preview=<token>`. The admin adds one to the
|
|
938
|
+
* preview URL as `easy-cms-preview`, for sites on another origin.
|
|
939
|
+
*/
|
|
940
|
+
createPreviewToken(target: {
|
|
941
|
+
collection: string;
|
|
942
|
+
id: ID;
|
|
943
|
+
} | {
|
|
944
|
+
global: string;
|
|
945
|
+
}, options?: {
|
|
946
|
+
expiresIn?: number;
|
|
947
|
+
}): string;
|
|
948
|
+
/** What a preview token opens, or `null` when it is invalid or expired. */
|
|
949
|
+
verifyPreviewToken(token: string | null | undefined): (PreviewTarget & {
|
|
950
|
+
expiresAt: number;
|
|
951
|
+
}) | null;
|
|
792
952
|
/** Live preview of a global. See `preview`. */
|
|
793
953
|
previewGlobal<S extends GSlug<C>>(slug: S, data: Record<string, unknown>, options?: DepthOptions): Promise<LivePreview<GDoc<C, S>>>;
|
|
794
954
|
/** Coerces preview input like a save would, keeping values that would fail validation. */
|
|
@@ -824,7 +984,43 @@ declare class EasyCMS<C extends Config = Config> {
|
|
|
824
984
|
delete: boolean;
|
|
825
985
|
}>;
|
|
826
986
|
/** Closes the database connection. */
|
|
987
|
+
/**
|
|
988
|
+
* Waits until webhook deliveries in progress are done. Call it before a serverless function
|
|
989
|
+
* returns, which may otherwise stop them.
|
|
990
|
+
*/
|
|
991
|
+
flushWebhooks(): Promise<void>;
|
|
827
992
|
destroy(): Promise<void>;
|
|
993
|
+
private schedulerTimer;
|
|
994
|
+
private running;
|
|
995
|
+
/** Runs due jobs every `interval` ms in this process (`createEasyCMS` does this by default). */
|
|
996
|
+
startScheduler(interval?: number): void;
|
|
997
|
+
/**
|
|
998
|
+
* Publishes or unpublishes documents whose scheduled time has come. Safe to call often, e.g.
|
|
999
|
+
* from a cron job (`GET <api>/jobs/run`) where no process keeps running.
|
|
1000
|
+
*/
|
|
1001
|
+
runScheduled(now?: Date): Promise<{
|
|
1002
|
+
ran: number;
|
|
1003
|
+
failed: number;
|
|
1004
|
+
}>;
|
|
1005
|
+
/** Schedules a publish or unpublish, replacing a pending job with the same action. */
|
|
1006
|
+
schedule<S extends Slug<C>>(collection: S, id: ID, job: {
|
|
1007
|
+
action: 'publish' | 'unpublish';
|
|
1008
|
+
at: Date | string;
|
|
1009
|
+
}, options?: AccessOptions): Promise<ScheduledJob>;
|
|
1010
|
+
/** Pending jobs of a document, soonest first. */
|
|
1011
|
+
scheduled<S extends Slug<C>>(collection: S, id: ID, options?: AccessOptions): Promise<ScheduledJob[]>;
|
|
1012
|
+
cancelSchedule<S extends Slug<C>>(collection: S, id: ID, jobId: ID, options?: AccessOptions): Promise<void>;
|
|
1013
|
+
scheduleGlobal<S extends GSlug<C>>(slug: S, job: {
|
|
1014
|
+
action: 'publish' | 'unpublish';
|
|
1015
|
+
at: Date | string;
|
|
1016
|
+
}, options?: AccessOptions): Promise<ScheduledJob>;
|
|
1017
|
+
scheduledGlobal<S extends GSlug<C>>(slug: S, options?: AccessOptions): Promise<ScheduledJob[]>;
|
|
1018
|
+
cancelGlobalSchedule<S extends GSlug<C>>(slug: S, jobId: ID, options?: AccessOptions): Promise<void>;
|
|
1019
|
+
private scheduleTarget;
|
|
1020
|
+
private globalScheduleTarget;
|
|
1021
|
+
private addJob;
|
|
1022
|
+
private pendingJobs;
|
|
1023
|
+
private removeJob;
|
|
828
1024
|
/** @internal */
|
|
829
1025
|
collection(slug: string): CollectionConfig;
|
|
830
1026
|
private global;
|
|
@@ -837,10 +1033,20 @@ declare class EasyCMS<C extends Config = Config> {
|
|
|
837
1033
|
private output;
|
|
838
1034
|
/** Creates a document: access, input filtering, hooks, validation, then afterChange. */
|
|
839
1035
|
private createDocument;
|
|
1036
|
+
/** The locale for an operation; `undefined` without localization. Throws on unknown locales. */
|
|
1037
|
+
private localeOf;
|
|
1038
|
+
/** Stored localized maps → the values of the requested locale. */
|
|
1039
|
+
private pick;
|
|
1040
|
+
/** Input for one locale → stored localized maps, keeping the other locales from `current`. */
|
|
1041
|
+
private toMaps;
|
|
1042
|
+
/** Makes `where` match localized fields in the operation's locale. */
|
|
1043
|
+
private whereFor;
|
|
840
1044
|
/** Drafts are kept as versions (instead of unpublishing) when both are enabled. */
|
|
841
1045
|
private separateDrafts;
|
|
842
1046
|
/** Replaces published documents that have a newer draft with that draft. */
|
|
843
1047
|
private withDrafts;
|
|
1048
|
+
/** Sends webhook events for a change; `before` is the stored status before it, if any. */
|
|
1049
|
+
private emit;
|
|
844
1050
|
/** Records a version after a save, when the collection or global keeps versions. */
|
|
845
1051
|
private saveVersion;
|
|
846
1052
|
private hookArgs;
|
|
@@ -980,6 +1186,8 @@ declare class PayloadTooLargeError extends EasyCMSError {
|
|
|
980
1186
|
constructor(message: string);
|
|
981
1187
|
}
|
|
982
1188
|
|
|
1189
|
+
type Localization = Required<LocalizationConfig>;
|
|
1190
|
+
|
|
983
1191
|
type Data = Record<string, unknown>;
|
|
984
1192
|
/**
|
|
985
1193
|
* Turns text into a URL slug. Keeps letters and digits of any script,
|
|
@@ -987,11 +1195,11 @@ type Data = Record<string, unknown>;
|
|
|
987
1195
|
*/
|
|
988
1196
|
declare function slugify(text: string): string;
|
|
989
1197
|
/** Fills in `defaultValue` for fields that are missing, including inside groups and array rows. */
|
|
990
|
-
declare function applyDefaults(fields: readonly Field[], data: Data): Data;
|
|
1198
|
+
declare function applyDefaults(fields: readonly Field[], data: Data, localization?: Localization | null): Data;
|
|
991
1199
|
/** Gives every field a value (`null`, `[]` or a nested object) so documents always have the same shape. */
|
|
992
1200
|
declare function fillMissing(fields: readonly Field[], data: Data): Data;
|
|
993
1201
|
/** Fills empty `slug` fields from their `from` field. Does not check uniqueness. */
|
|
994
|
-
declare function generateSlugs(fields: readonly Field[], data: Data): Data;
|
|
1202
|
+
declare function generateSlugs(fields: readonly Field[], data: Data, localization?: Localization | null): Data;
|
|
995
1203
|
/**
|
|
996
1204
|
* Merges an update into the stored document. Top-level fields and group
|
|
997
1205
|
* fields merge key by key; arrays and hasMany values are replaced.
|
|
@@ -1011,6 +1219,13 @@ interface ValidateOptions {
|
|
|
1011
1219
|
readonly skipRequired?: boolean;
|
|
1012
1220
|
/** The whole top-level document, passed to custom `validate` functions. */
|
|
1013
1221
|
readonly root: Data;
|
|
1222
|
+
/** Localized fields hold `{ [locale]: value }`; each value is validated. */
|
|
1223
|
+
readonly localization?: Localization | null;
|
|
1224
|
+
/**
|
|
1225
|
+
* The locale being written: `required` and custom `validate` apply to its values, and its
|
|
1226
|
+
* errors use the plain field path. Default: the default locale.
|
|
1227
|
+
*/
|
|
1228
|
+
readonly locale?: string;
|
|
1014
1229
|
}
|
|
1015
1230
|
interface ValidateResult {
|
|
1016
1231
|
/** Only known fields, with values normalized (ids parsed, dates as ISO strings, row ids filled). */
|
|
@@ -1093,8 +1308,19 @@ interface AdminField {
|
|
|
1093
1308
|
minRows?: number;
|
|
1094
1309
|
maxRows?: number;
|
|
1095
1310
|
fields?: AdminField[];
|
|
1311
|
+
/** Block kinds of a `blocks` field. */
|
|
1312
|
+
blocks?: {
|
|
1313
|
+
slug: string;
|
|
1314
|
+
labels?: {
|
|
1315
|
+
singular?: Label;
|
|
1316
|
+
plural?: Label;
|
|
1317
|
+
};
|
|
1318
|
+
fields: AdminField[];
|
|
1319
|
+
}[];
|
|
1096
1320
|
/** The current user may not change this field. */
|
|
1097
1321
|
readOnly?: boolean;
|
|
1322
|
+
/** One value per content locale. */
|
|
1323
|
+
localized?: boolean;
|
|
1098
1324
|
}
|
|
1099
1325
|
interface AdminCollection {
|
|
1100
1326
|
slug: string;
|
|
@@ -1107,6 +1333,8 @@ interface AdminCollection {
|
|
|
1107
1333
|
versions: boolean;
|
|
1108
1334
|
/** Has live preview (`preview` in the config). */
|
|
1109
1335
|
preview: boolean;
|
|
1336
|
+
/** Publishing can be scheduled. */
|
|
1337
|
+
schedule: boolean;
|
|
1110
1338
|
fields: AdminField[];
|
|
1111
1339
|
permissions: {
|
|
1112
1340
|
read: boolean;
|
|
@@ -1122,6 +1350,8 @@ interface AdminGlobal {
|
|
|
1122
1350
|
versions: boolean;
|
|
1123
1351
|
/** Has live preview (`preview` in the config). */
|
|
1124
1352
|
preview: boolean;
|
|
1353
|
+
/** Publishing can be scheduled. */
|
|
1354
|
+
schedule: boolean;
|
|
1125
1355
|
fields: AdminField[];
|
|
1126
1356
|
permissions: {
|
|
1127
1357
|
read: boolean;
|
|
@@ -1130,6 +1360,11 @@ interface AdminGlobal {
|
|
|
1130
1360
|
}
|
|
1131
1361
|
interface AdminSchema {
|
|
1132
1362
|
locale: AdminLocale;
|
|
1363
|
+
/** Content locales, when the config has `localization`. */
|
|
1364
|
+
localization: {
|
|
1365
|
+
locales: string[];
|
|
1366
|
+
defaultLocale: string;
|
|
1367
|
+
} | null;
|
|
1133
1368
|
collections: AdminCollection[];
|
|
1134
1369
|
globals: AdminGlobal[];
|
|
1135
1370
|
}
|
|
@@ -1162,4 +1397,4 @@ declare const BUILTIN_COLLECTIONS: readonly ["users", "media"];
|
|
|
1162
1397
|
/** Checks a config and returns every problem found. An empty array means it is valid. */
|
|
1163
1398
|
declare function validateConfig(config: Config): ConfigIssue[];
|
|
1164
1399
|
|
|
1165
|
-
export { type Access, type AccessArgs, type AccessOptions, type AdminCollection, type AdminConfig, type AdminField, type AdminGlobal, type AdminLocale, type AdminSchema, type AfterChangeHook, type AfterDeleteHook, type AfterReadHook, type ArrayField, Auth, type AuthConfig, type AuthUser, BUILTIN_COLLECTIONS, type BeforeChangeHook, type BeforeDeleteHook, type BeforeValidateHook, type BooleanField, type BuiltinMediaCollection, type BuiltinUsersCollection, type BundleHints, CONFIG_FILE_NAMES, CSRF_COOKIE, CSRF_HEADER, type CollectionAccess, type CollectionConfig, type CollectionDocument, type CollectionHooks, type CollectionSlug, type Config, ConfigError, type ConfigIssue, type CreateEasyCMSOptions, type CreateInput, type CreateMigrationResult, DEFAULT_ADMIN_PATH, DEFAULT_API_PATH, DEFAULT_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_VERSIONS, DEFAULT_TOKEN_EXPIRATION, type Database, type DatabaseAdapter, type DatabaseInitArgs, type DateField, type DepthOptions, EXTENSIONS, EasyCMS, EasyCMSError, type EmailField, FIELD_TYPES, type Field, type FieldAccess, type FieldAccessFn, type FieldError, type FieldType, type FieldValidate, type FieldValidateContext, type FieldValue, type FieldsInput, type FieldsValue, type FindArgs, type FindOptions, ForbiddenError, type GlobalAccess, type GlobalConfig, type GlobalDocument, type GlobalHooks, type GlobalInput, type GlobalSlug, type GroupField, type ID, INTERNAL_COLLECTIONS, type ImageSize, type InferCollection, type InferGlobal, type JsonField, type Label, type LivePreview, type LoadConfigOptions, type LocalStorageOptions, type Logger, type LoginArgs, MAX_DEPTH, MEDIA, MIN_PASSWORD_LENGTH, MIN_SECRET_LENGTH, type MediaDocument, type MediaSize, type MigrationInfo, NotFoundError, type NumberField, type Operation, type PaginatedDocs, PayloadTooLargeError, type Plugin, type PreviewURL, QueryError, type RawDocument, type ReadOptions, type RelationshipField, type ResolvedConfig, type RestHandler, type RestHandlerOptions, type RichTextDocument, type RichTextField, type Role, type RoutesConfig, SESSION_COOKIE, SchemaError, type SchemaMode, type SelectField, type SelectOption, type Session, type SlugField, type StorageAdapter, type StoredFile, type TextField, type TextareaField, TooManyRequestsError, UnauthorizedError, type UpdateInput, type UploadConfig, type UploadField, ValidationError, type Version, type VersionSummary, type VersionsConfig, type Where, type WhereOperators, anyone, applyDefaults, consoleLogger, createEasyCMS, createRestHandler, defineConfig, fillMissing, findConfigFile, generateSlugs, generateTypes, hashPassword, imageDimensions, importConfig, isAdmin, isLoggedIn, loadConfig, localStorage, mergeForUpdate, mimeAllowed, parseId, populate, readCookie, resolveConfig, silentLogger, singularize, slugify, sniffMimeType, validateConfig, validateFields, verifyPassword };
|
|
1400
|
+
export { type Access, type AccessArgs, type AccessOptions, type AdminCollection, type AdminConfig, type AdminField, type AdminGlobal, type AdminLocale, type AdminSchema, type AfterChangeHook, type AfterDeleteHook, type AfterReadHook, type ArrayField, Auth, type AuthConfig, type AuthUser, BUILTIN_COLLECTIONS, type BeforeChangeHook, type BeforeDeleteHook, type BeforeValidateHook, type Block, type BlocksField, type BooleanField, type BuiltinMediaCollection, type BuiltinUsersCollection, type BundleHints, CONFIG_FILE_NAMES, CSRF_COOKIE, CSRF_HEADER, type CollectionAccess, type CollectionConfig, type CollectionDocument, type CollectionHooks, type CollectionSlug, type Config, ConfigError, type ConfigIssue, type CreateEasyCMSOptions, type CreateInput, type CreateMigrationResult, DEFAULT_ADMIN_PATH, DEFAULT_API_PATH, DEFAULT_DEPTH, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_VERSIONS, DEFAULT_TOKEN_EXPIRATION, type Database, type DatabaseAdapter, type DatabaseInitArgs, type DateField, type DepthOptions, EXTENSIONS, EasyCMS, EasyCMSError, type EmailField, FIELD_TYPES, type Field, type FieldAccess, type FieldAccessFn, type FieldError, type FieldType, type FieldValidate, type FieldValidateContext, type FieldValue, type FieldsInput, type FieldsValue, type FindArgs, type FindOptions, ForbiddenError, type GlobalAccess, type GlobalConfig, type GlobalDocument, type GlobalHooks, type GlobalInput, type GlobalSlug, type GroupField, type ID, INTERNAL_COLLECTIONS, type ImageSize, type InferCollection, type InferGlobal, type JsonField, type Label, type LivePreview, type LoadConfigOptions, type LocalStorageOptions, type LocalizationConfig, type Logger, type LoginArgs, MAX_DEPTH, MEDIA, MIN_PASSWORD_LENGTH, MIN_SECRET_LENGTH, type MediaDocument, type MediaSize, type MigrationInfo, NotFoundError, type NumberField, type Operation, type PaginatedDocs, PayloadTooLargeError, type Plugin, type PreviewTarget, type PreviewURL, QueryError, type RawDocument, type ReadOptions, type RelationshipField, type ResolvedConfig, type RestHandler, type RestHandlerOptions, type RichTextDocument, type RichTextField, type Role, type RoutesConfig, SESSION_COOKIE, type ScheduledJob, SchemaError, type SchemaMode, type SelectField, type SelectOption, type Session, type SlugField, type StorageAdapter, type StoredFile, type TextField, type TextareaField, TooManyRequestsError, UnauthorizedError, type UpdateInput, type UploadConfig, type UploadField, ValidationError, type Version, type VersionSummary, type VersionsConfig, WEBHOOK_EVENTS, type WebhookConfig, type WebhookEvent, type WebhookPayload, type Where, type WhereOperators, anyone, applyDefaults, consoleLogger, createEasyCMS, createRestHandler, defineConfig, fillMissing, findConfigFile, generateSlugs, generateTypes, hasRows, hashPassword, imageDimensions, importConfig, isAdmin, isLoggedIn, loadConfig, localStorage, mergeForUpdate, mimeAllowed, parseId, populate, readCookie, resolveConfig, rowFields, silentLogger, singularize, slugify, sniffMimeType, validateConfig, validateFields, verifyPassword };
|