@easy-cms/core 1.10.0 → 1.11.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/{chunk-54UFTH6S.js → chunk-TMO4JTGJ.js} +114 -18
- package/dist/{config-DL4beesW.d.ts → config-n7PtGl4V.d.ts} +36 -0
- package/dist/{handler--JrVIdYW.d.ts → handler-DV-1ICVz.d.ts} +1 -1
- package/dist/index.d.ts +16 -5
- package/dist/index.js +3 -1
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +1 -1
- package/dist/{plugin-BXHlV5IZ.d.ts → plugin-C_vknKa2.d.ts} +1 -1
- package/dist/plugin.d.ts +2 -2
- package/package.json +1 -1
|
@@ -3874,7 +3874,7 @@ var VersionStore = class {
|
|
|
3874
3874
|
};
|
|
3875
3875
|
|
|
3876
3876
|
// src/local-api.ts
|
|
3877
|
-
import { createHash as
|
|
3877
|
+
import { createHash as createHash5, createHmac as createHmac6, randomBytes as randomBytes6, randomUUID as randomUUID3, timingSafeEqual as timingSafeEqual5 } from "crypto";
|
|
3878
3878
|
|
|
3879
3879
|
// src/auth/common-passwords.ts
|
|
3880
3880
|
var LIST = `
|
|
@@ -4426,7 +4426,7 @@ function read(response, maxBytes, deadline) {
|
|
|
4426
4426
|
var keys = (list) => new Set(list.split(/\s+/).filter(Boolean));
|
|
4427
4427
|
var CONFIG = keys(`secret db serverURL cors cronSecret timeZone webhooks events jobs localization routes admin
|
|
4428
4428
|
upload auth collections globals endpoints cliCommands onRequest fieldTypes apiKeys email backups
|
|
4429
|
-
audit logs countCacheSeconds maxPage plugins`);
|
|
4429
|
+
audit logs countCacheSeconds maxPage httpCache plugins`);
|
|
4430
4430
|
var ADMIN = keys("path locale brand siteURL nav commands modules pages dashboard switcher");
|
|
4431
4431
|
var AUTH = keys(`roles rbac tokenExpiration maxLoginAttempts lockWindow trustedOrigins
|
|
4432
4432
|
resetPasswordExpiration inviteExpiration providers providerSignUp password setupCode members emails`);
|
|
@@ -4436,8 +4436,10 @@ var BACKUPS = keys("frequency at keep dir storage sqlite encryptionKey");
|
|
|
4436
4436
|
var AUDIT = keys("keepDays values failedLogins scope");
|
|
4437
4437
|
var LOGS = keys("format requests");
|
|
4438
4438
|
var COLLECTION = keys(`slug labels fields useAsTitle drafts versions schedule preview access hooks
|
|
4439
|
-
admin`);
|
|
4440
|
-
var GLOBAL = keys(
|
|
4439
|
+
admin httpCache`);
|
|
4440
|
+
var GLOBAL = keys(
|
|
4441
|
+
"slug label fields drafts versions schedule preview access hooks scope admin httpCache"
|
|
4442
|
+
);
|
|
4441
4443
|
var CONTAINER_ADMIN = keys("icon order sidebar layout group");
|
|
4442
4444
|
var COLLECTION_ADMIN = keys(
|
|
4443
4445
|
"icon order sidebar layout group editIn badge count empty list ownerField confirmDelete"
|
|
@@ -4891,6 +4893,7 @@ function validateConfig(config) {
|
|
|
4891
4893
|
validateLogs(config, add);
|
|
4892
4894
|
validateCountCache(config, add);
|
|
4893
4895
|
validateMaxPage(config, add);
|
|
4896
|
+
validateHttpCache(config, add);
|
|
4894
4897
|
validateAuth(config, add);
|
|
4895
4898
|
validateCors(config.cors, add);
|
|
4896
4899
|
validateLocalization(config, add);
|
|
@@ -5513,6 +5516,26 @@ function validateUpload(config, add) {
|
|
|
5513
5516
|
var FOLDER_KEY = /^[a-z0-9][a-z0-9_-]{0,59}$/;
|
|
5514
5517
|
var MIME_PATTERN = /^([\w.+-]+\/(\*|[\w.+-]+)|documents|office|archives)$/i;
|
|
5515
5518
|
var HOST_PATTERN = /^(\*|(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*)$/i;
|
|
5519
|
+
function validateHttpCache(config, add) {
|
|
5520
|
+
const times = (value, path, purge) => {
|
|
5521
|
+
if (value === void 0) return;
|
|
5522
|
+
if (value === false && !purge) return;
|
|
5523
|
+
if (typeof value !== "object" || value === null) {
|
|
5524
|
+
add(path, purge ? "must be an object" : "must be false or an object");
|
|
5525
|
+
return;
|
|
5526
|
+
}
|
|
5527
|
+
const v = value;
|
|
5528
|
+
for (const key of ["sMaxAge", "staleWhileRevalidate"])
|
|
5529
|
+
if (v[key] !== void 0 && !(Number.isInteger(v[key]) && v[key] >= 0))
|
|
5530
|
+
add(`${path}.${key}`, "must be a whole number of seconds, 0 or more");
|
|
5531
|
+
if (purge && v.purge !== void 0 && typeof v.purge !== "function")
|
|
5532
|
+
add(`${path}.purge`, "must be a function");
|
|
5533
|
+
};
|
|
5534
|
+
times(config.httpCache, "httpCache", true);
|
|
5535
|
+
for (const c of config.collections ?? [])
|
|
5536
|
+
times(c?.httpCache, `collections.${c?.slug}.httpCache`, false);
|
|
5537
|
+
for (const g of config.globals ?? []) times(g?.httpCache, `globals.${g?.slug}.httpCache`, false);
|
|
5538
|
+
}
|
|
5516
5539
|
function validateMaxPage(config, add) {
|
|
5517
5540
|
const max = config.maxPage;
|
|
5518
5541
|
if (max !== void 0 && !(Number.isInteger(max) && max >= 1))
|
|
@@ -6413,6 +6436,41 @@ function resolveAudit(audit) {
|
|
|
6413
6436
|
};
|
|
6414
6437
|
}
|
|
6415
6438
|
|
|
6439
|
+
// src/rest/http-cache.ts
|
|
6440
|
+
import { createHash as createHash4 } from "crypto";
|
|
6441
|
+
var cacheTags = {
|
|
6442
|
+
collection: (slug2) => ["ecms", `ecms:${slug2}`],
|
|
6443
|
+
document: (slug2, id) => ["ecms", `ecms:${slug2}`, `ecms:${slug2}:${id}`],
|
|
6444
|
+
global: (slug2) => ["ecms", `ecms:global:${slug2}`]
|
|
6445
|
+
};
|
|
6446
|
+
function cacheTimes(config, container) {
|
|
6447
|
+
const own = container.httpCache;
|
|
6448
|
+
if (own === false || own === void 0 && config.httpCache === void 0) return null;
|
|
6449
|
+
return {
|
|
6450
|
+
sMaxAge: own?.sMaxAge ?? config.httpCache?.sMaxAge ?? 60,
|
|
6451
|
+
staleWhileRevalidate: own?.staleWhileRevalidate ?? config.httpCache?.staleWhileRevalidate ?? 300
|
|
6452
|
+
};
|
|
6453
|
+
}
|
|
6454
|
+
function matches2(header, etag) {
|
|
6455
|
+
if (!header) return false;
|
|
6456
|
+
if (header.trim() === "*") return true;
|
|
6457
|
+
const bare = (tag) => tag.trim().replace(/^W\//, "");
|
|
6458
|
+
return header.split(",").some((tag) => bare(tag) === bare(etag));
|
|
6459
|
+
}
|
|
6460
|
+
function cacheableResponse(request, body, status, headers, times, tags) {
|
|
6461
|
+
headers.set(
|
|
6462
|
+
"cache-control",
|
|
6463
|
+
`public, max-age=0, s-maxage=${times.sMaxAge}, stale-while-revalidate=${times.staleWhileRevalidate}`
|
|
6464
|
+
);
|
|
6465
|
+
headers.set("cache-tag", tags.join(","));
|
|
6466
|
+
headers.set("surrogate-key", tags.join(" "));
|
|
6467
|
+
const etag = `W/"${createHash4("sha1").update(body).digest("base64url")}"`;
|
|
6468
|
+
headers.set("etag", etag);
|
|
6469
|
+
if (matches2(request.headers.get("if-none-match"), etag))
|
|
6470
|
+
return new Response(null, { status: 304, headers });
|
|
6471
|
+
return new Response(request.method.toUpperCase() === "HEAD" ? null : body, { status, headers });
|
|
6472
|
+
}
|
|
6473
|
+
|
|
6416
6474
|
// src/local-api.ts
|
|
6417
6475
|
async function createEasyCMS(config, options = {}) {
|
|
6418
6476
|
const resolved3 = await resolveConfig(config);
|
|
@@ -8391,11 +8449,11 @@ var EasyCMS = class {
|
|
|
8391
8449
|
const access = allowed2 === false ? false : andWhere(own === true ? void 0 : own, allowed2) ?? true;
|
|
8392
8450
|
if (access === true) return;
|
|
8393
8451
|
if (access !== false) {
|
|
8394
|
-
const
|
|
8452
|
+
const matches3 = await this.db.count({
|
|
8395
8453
|
collection: config.slug,
|
|
8396
8454
|
where: andWhere(access, { id: { equals: id } })
|
|
8397
8455
|
});
|
|
8398
|
-
if (
|
|
8456
|
+
if (matches3 > 0) return;
|
|
8399
8457
|
}
|
|
8400
8458
|
throw deny(guard.user);
|
|
8401
8459
|
}
|
|
@@ -8449,11 +8507,11 @@ var EasyCMS = class {
|
|
|
8449
8507
|
await this.hidingDenied(collection2, guard, id, async () => {
|
|
8450
8508
|
const own = await this.checkGrant(guard, { collection: collection2 }, operation);
|
|
8451
8509
|
if (own === true) return;
|
|
8452
|
-
const
|
|
8510
|
+
const matches3 = await this.db.count({
|
|
8453
8511
|
collection: collection2,
|
|
8454
8512
|
where: andWhere(own, { id: { equals: id } })
|
|
8455
8513
|
});
|
|
8456
|
-
if (
|
|
8514
|
+
if (matches3 === 0) throw deny(guard.user);
|
|
8457
8515
|
});
|
|
8458
8516
|
}
|
|
8459
8517
|
/** Runs afterRead hooks, populates relationships and removes what the caller may not see. */
|
|
@@ -8615,6 +8673,20 @@ var EasyCMS = class {
|
|
|
8615
8673
|
return version && doc.status === "published" && version.status === "draft" ? draftOf(doc, version) : doc;
|
|
8616
8674
|
});
|
|
8617
8675
|
}
|
|
8676
|
+
/**
|
|
8677
|
+
* `httpCache.purge`: what readers see changed (anything, without drafts; with drafts, a
|
|
8678
|
+
* published document saved, published, unpublished or deleted). Not awaited; failures are
|
|
8679
|
+
* logged.
|
|
8680
|
+
*/
|
|
8681
|
+
purgePublic(config, isGlobal, event, doc, before) {
|
|
8682
|
+
const purge = this.config.httpCache?.purge;
|
|
8683
|
+
if (!purge || config.httpCache === false || event === "draft") return;
|
|
8684
|
+
if (config.drafts && doc.status !== "published" && before !== "published") return;
|
|
8685
|
+
const tags = isGlobal ? cacheTags.global(config.slug) : cacheTags.document(config.slug, doc.id);
|
|
8686
|
+
void Promise.resolve().then(() => purge(tags)).catch(
|
|
8687
|
+
(error) => this.logger.error(`httpCache.purge failed: ${error.message}`, { error })
|
|
8688
|
+
);
|
|
8689
|
+
}
|
|
8618
8690
|
/** Sends webhook events for a change; `before` is the stored status before it, if any. */
|
|
8619
8691
|
emitChange(config, event, doc, before) {
|
|
8620
8692
|
const isGlobal = !this.config.collections.includes(config);
|
|
@@ -8627,6 +8699,7 @@ var EasyCMS = class {
|
|
|
8627
8699
|
};
|
|
8628
8700
|
const target = isGlobal ? { global: config.slug } : { collection: config.slug, id: doc.id };
|
|
8629
8701
|
this.webhooks.emit(event, target, body);
|
|
8702
|
+
this.purgePublic(config, isGlobal, event, doc, before);
|
|
8630
8703
|
if (event === "draft" || event === "delete" || !config.drafts) return;
|
|
8631
8704
|
const after = doc.status;
|
|
8632
8705
|
if (after === "published" && before !== "published") this.webhooks.emit("publish", target, body);
|
|
@@ -9076,7 +9149,7 @@ function durationSeconds(value) {
|
|
|
9076
9149
|
}
|
|
9077
9150
|
function cursorQuery(collection2, where, sort, locale, draft) {
|
|
9078
9151
|
const key = JSON.stringify([collection2, where ?? null, sort, locale ?? null, draft]);
|
|
9079
|
-
return
|
|
9152
|
+
return createHash5("sha256").update(key).digest("base64url").slice(0, 16);
|
|
9080
9153
|
}
|
|
9081
9154
|
function writeCursor(keys2, query) {
|
|
9082
9155
|
return Buffer.from(JSON.stringify({ k: keys2, q: query })).toString("base64url");
|
|
@@ -9827,7 +9900,7 @@ function rank(role, config) {
|
|
|
9827
9900
|
}
|
|
9828
9901
|
|
|
9829
9902
|
// src/rest/admin-modules.ts
|
|
9830
|
-
import { createHash as
|
|
9903
|
+
import { createHash as createHash6 } from "crypto";
|
|
9831
9904
|
import { readFile as readFile3 } from "fs/promises";
|
|
9832
9905
|
import { createRequire } from "module";
|
|
9833
9906
|
import { join as join3 } from "path";
|
|
@@ -9868,11 +9941,11 @@ async function readAdminModule(cms, index) {
|
|
|
9868
9941
|
if (!file) return void 0;
|
|
9869
9942
|
const body = await readFile3(file, "utf8").catch(() => void 0);
|
|
9870
9943
|
if (body === void 0) return void 0;
|
|
9871
|
-
return { body, etag: `"${
|
|
9944
|
+
return { body, etag: `"${createHash6("sha1").update(body).digest("base64url")}"` };
|
|
9872
9945
|
}
|
|
9873
9946
|
|
|
9874
9947
|
// src/version.ts
|
|
9875
|
-
var VERSION = true ? "1.
|
|
9948
|
+
var VERSION = true ? "1.11.0" : "0.0.0-dev";
|
|
9876
9949
|
|
|
9877
9950
|
// src/rest/handler.ts
|
|
9878
9951
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
@@ -10917,7 +10990,18 @@ async function respondNow(cms, request, url, path, root, options, production, re
|
|
|
10917
10990
|
);
|
|
10918
10991
|
if (!result) throw new HttpError("Not found", 404);
|
|
10919
10992
|
if (result.body instanceof Response) return result.body;
|
|
10920
|
-
|
|
10993
|
+
const body = JSON.stringify(result.body);
|
|
10994
|
+
const times = result.cache && !user && !ctx.via && !ctx.token && !url.searchParams.has("draft") ? cacheTimes(cms.config, result.cache.container) : null;
|
|
10995
|
+
if (times && result.cache)
|
|
10996
|
+
return cacheableResponse(
|
|
10997
|
+
request,
|
|
10998
|
+
body,
|
|
10999
|
+
result.status ?? 200,
|
|
11000
|
+
headers,
|
|
11001
|
+
times,
|
|
11002
|
+
result.cache.tags
|
|
11003
|
+
);
|
|
11004
|
+
return new Response(body, { status: result.status ?? 200, headers });
|
|
10921
11005
|
} catch (error) {
|
|
10922
11006
|
return errorResponse(cms, error, headers, production);
|
|
10923
11007
|
}
|
|
@@ -11501,7 +11585,11 @@ async function route(cms, ctx, method, path, options) {
|
|
|
11501
11585
|
})
|
|
11502
11586
|
};
|
|
11503
11587
|
}
|
|
11504
|
-
|
|
11588
|
+
const global2 = cms.config.globals.find((g) => g.slug === second);
|
|
11589
|
+
return {
|
|
11590
|
+
body: await cms.findGlobal(second, { ...access, ...parseDepth(ctx.url), draft }),
|
|
11591
|
+
cache: { container: global2, tags: cacheTags.global(second) }
|
|
11592
|
+
};
|
|
11505
11593
|
}
|
|
11506
11594
|
if (method === "PATCH" || method === "POST") {
|
|
11507
11595
|
if (method === "POST")
|
|
@@ -11598,7 +11686,8 @@ async function route(cms, ctx, method, path, options) {
|
|
|
11598
11686
|
body: await cms.find(
|
|
11599
11687
|
collection2,
|
|
11600
11688
|
query.cursor === void 0 ? { ...options2, page } : options2
|
|
11601
|
-
)
|
|
11689
|
+
),
|
|
11690
|
+
cache: { container: cms.collection(collection2), tags: cacheTags.collection(collection2) }
|
|
11602
11691
|
};
|
|
11603
11692
|
}
|
|
11604
11693
|
if (method === "POST") {
|
|
@@ -11625,7 +11714,13 @@ async function route(cms, ctx, method, path, options) {
|
|
|
11625
11714
|
if (method === "GET") {
|
|
11626
11715
|
const doc = await cms.findById(collection2, id, { ...access, ...parseDepth(ctx.url), draft });
|
|
11627
11716
|
if (!doc) throw new NotFoundError(collection2, id);
|
|
11628
|
-
return {
|
|
11717
|
+
return {
|
|
11718
|
+
body: doc,
|
|
11719
|
+
cache: {
|
|
11720
|
+
container: cms.collection(collection2),
|
|
11721
|
+
tags: cacheTags.document(collection2, doc.id)
|
|
11722
|
+
}
|
|
11723
|
+
};
|
|
11629
11724
|
}
|
|
11630
11725
|
if (method === "PATCH") {
|
|
11631
11726
|
const body = await readJson(ctx.request);
|
|
@@ -11784,8 +11879,8 @@ function withPreviewToken(url, token) {
|
|
|
11784
11879
|
}
|
|
11785
11880
|
async function requirePreview(cms, ctx, target) {
|
|
11786
11881
|
const opened = cms.verifyPreviewToken(ctx.url.searchParams.get("preview"));
|
|
11787
|
-
const
|
|
11788
|
-
if (!
|
|
11882
|
+
const matches3 = opened !== null && ("global" in target ? "global" in opened && opened.global === target.global : "collection" in opened && opened.collection === target.collection && opened.id === target.id);
|
|
11883
|
+
if (!matches3) throw new UnauthorizedError("Invalid or expired preview token");
|
|
11789
11884
|
if (opened.user === void 0) return {};
|
|
11790
11885
|
const id = parseId(opened.user);
|
|
11791
11886
|
const issuer = id === void 0 ? null : await cms.auth.activeUser(id);
|
|
@@ -12293,6 +12388,7 @@ export {
|
|
|
12293
12388
|
DEFAULT_TOKEN_EXPIRATION,
|
|
12294
12389
|
applyPlugins,
|
|
12295
12390
|
resolveConfig,
|
|
12391
|
+
cacheTags,
|
|
12296
12392
|
createEasyCMS,
|
|
12297
12393
|
EasyCMS,
|
|
12298
12394
|
resolveAdminModule,
|
|
@@ -2183,6 +2183,12 @@ declare class EasyCMS<C extends Config = Config> {
|
|
|
2183
2183
|
private separateDrafts;
|
|
2184
2184
|
/** Replaces published documents that have a newer draft with that draft. */
|
|
2185
2185
|
private withDrafts;
|
|
2186
|
+
/**
|
|
2187
|
+
* `httpCache.purge`: what readers see changed (anything, without drafts; with drafts, a
|
|
2188
|
+
* published document saved, published, unpublished or deleted). Not awaited; failures are
|
|
2189
|
+
* logged.
|
|
2190
|
+
*/
|
|
2191
|
+
private purgePublic;
|
|
2186
2192
|
/** Sends webhook events for a change; `before` is the stored status before it, if any. */
|
|
2187
2193
|
private emitChange;
|
|
2188
2194
|
/**
|
|
@@ -2786,6 +2792,11 @@ interface CollectionConfig {
|
|
|
2786
2792
|
readonly versions?: boolean | VersionsConfig;
|
|
2787
2793
|
/** Allow scheduling publish/unpublish for a later time (needs `drafts`). */
|
|
2788
2794
|
readonly schedule?: boolean;
|
|
2795
|
+
/**
|
|
2796
|
+
* HTTP caching of public reads of this content (no login, published only), for a CDN in front.
|
|
2797
|
+
* Overrides the config's `httpCache` for this one; `false` keeps every read `no-store`.
|
|
2798
|
+
*/
|
|
2799
|
+
readonly httpCache?: false | HttpCacheTimes;
|
|
2789
2800
|
/** Live preview: the page that shows a document, e.g. `({ doc }) => \`/posts/${doc.slug}\``. */
|
|
2790
2801
|
readonly preview?: PreviewURL;
|
|
2791
2802
|
readonly access?: CollectionAccess;
|
|
@@ -2793,6 +2804,20 @@ interface CollectionConfig {
|
|
|
2793
2804
|
/** How the collection looks in the admin: its menu item, list, edit page and components. */
|
|
2794
2805
|
readonly admin?: CollectionAdmin;
|
|
2795
2806
|
}
|
|
2807
|
+
/** How long a CDN may keep a public read. */
|
|
2808
|
+
interface HttpCacheTimes {
|
|
2809
|
+
/** Seconds a CDN serves it without asking again (`s-maxage`). Default 60. */
|
|
2810
|
+
readonly sMaxAge?: number;
|
|
2811
|
+
/** Seconds after that it may still serve it while it fetches a fresh one. Default 300. */
|
|
2812
|
+
readonly staleWhileRevalidate?: number;
|
|
2813
|
+
}
|
|
2814
|
+
interface HttpCacheConfig extends HttpCacheTimes {
|
|
2815
|
+
/**
|
|
2816
|
+
* Called after public content changes, with the cache tags of what changed: purge them from
|
|
2817
|
+
* your CDN, or call Next's `revalidateTag` for each. Not awaited; a failure is logged.
|
|
2818
|
+
*/
|
|
2819
|
+
readonly purge?: (tags: string[]) => void | Promise<void>;
|
|
2820
|
+
}
|
|
2796
2821
|
interface GlobalConfig {
|
|
2797
2822
|
readonly slug: string;
|
|
2798
2823
|
readonly label?: Label;
|
|
@@ -2802,6 +2827,11 @@ interface GlobalConfig {
|
|
|
2802
2827
|
readonly versions?: boolean | VersionsConfig;
|
|
2803
2828
|
/** Allow scheduling publish/unpublish for a later time (needs `drafts`). */
|
|
2804
2829
|
readonly schedule?: boolean;
|
|
2830
|
+
/**
|
|
2831
|
+
* HTTP caching of public reads of this content (no login, published only), for a CDN in front.
|
|
2832
|
+
* Overrides the config's `httpCache` for this one; `false` keeps every read `no-store`.
|
|
2833
|
+
*/
|
|
2834
|
+
readonly httpCache?: false | HttpCacheTimes;
|
|
2805
2835
|
/** Live preview: the page that shows the global. See `CollectionConfig.preview`. */
|
|
2806
2836
|
readonly preview?: PreviewURL;
|
|
2807
2837
|
readonly access?: GlobalAccess;
|
|
@@ -3379,6 +3409,12 @@ interface Config {
|
|
|
3379
3409
|
* Default 5.
|
|
3380
3410
|
*/
|
|
3381
3411
|
readonly countCacheSeconds?: number;
|
|
3412
|
+
/**
|
|
3413
|
+
* HTTP caching of public reads (no login, no API key, published content) by a CDN or proxy in
|
|
3414
|
+
* front: `Cache-Control` with `s-maxage`, an `ETag`, and cache tags to purge by. Off by default:
|
|
3415
|
+
* every response is `no-store`. Collections and globals can override it.
|
|
3416
|
+
*/
|
|
3417
|
+
readonly httpCache?: HttpCacheConfig;
|
|
3382
3418
|
/**
|
|
3383
3419
|
* The deepest `page` the REST API serves to API clients (not to the signed-in admin); deeper
|
|
3384
3420
|
* requests get `400`, pointing to `cursor`. Deep pages are read row by row. Default: no limit.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as ID, ab as Config, av as EasyCMS, bh as LocalizationConfig, aE as Field, aI as FieldError, aT as FilterOptions, af as CreateEasyCMSOptions, bO as ResolvedConfig } from './config-
|
|
1
|
+
import { I as ID, ab as Config, av as EasyCMS, bh as LocalizationConfig, aE as Field, aI as FieldError, aT as FilterOptions, af as CreateEasyCMSOptions, bO as ResolvedConfig } from './config-n7PtGl4V.js';
|
|
2
2
|
|
|
3
3
|
/** Decrypts a file from `encryptBackup`; throws for another key or a changed file. */
|
|
4
4
|
declare function decryptBackup(data: Uint8Array, encryptionKey: string): Uint8Array;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { P as PaginatedDocs, I as ID, E as EmailSetting } from './config-
|
|
2
|
-
export { A as ADAPTER_API_VERSION, a as ADMIN_ICONS, b as Access, c as AccessArgs, d as AccessOptions, e as AdminBrand, f as AdminCommand, g as AdminComponent, h as AdminConfig, i as AdminFieldArgs, j as AdminIcon, k as AdminLocale, l as AdminPage, m as AdminRole, n as AdminRoleChange, o as AdminRoleField, p as AdminRoleTarget, q as AdminRoleView, r as AdminRoles, s as AdminSso, t as AdminSwitcher, u as AdminViewAccess, v as AfterChangeHook, w as AfterDeleteHook, x as AfterReadHook, y as ApiKeyContext, z as ApiKeyGlobalOperation, B as ApiKeyOperation, C as ApiKeyPermissions, D as ArrayField, F as AuditChange, G as AuditConfig, H as AuditEntry, J as AuditLog, K as AuditPage, L as AuditVerification, M as Auth, N as AuthConfig, O as AuthProvider, Q as AuthProviderProfile, R as AuthProviderRequest, S as AuthUser, T as BackupsConfig, U as BeforeChangeHook, V as BeforeDeleteHook, W as BeforeValidateHook, X as Block, Y as BlocksField, Z as BooleanField, _ as BuiltinApiKeysCollection, $ as BuiltinMediaCollection, a0 as BuiltinMediaFoldersCollection, a1 as BuiltinUsersCollection, a2 as BundleHints, a3 as CliCommand, a4 as CollectionAccess, a5 as CollectionAdmin, a6 as CollectionConfig, a7 as CollectionDocument, a8 as CollectionHooks, a9 as CollectionListAdmin, aa as CollectionSlug, ab as Config, ac as ConfigError, ad as ConfigIssue, ae as ContainerAdmin, af as CreateEasyCMSOptions, ag as CreateInput, ah as CreateMigrationResult, ai as CursorDocs, aj as CustomField, ak as CustomFieldTypes, al as DashboardWidget, am as Database, an as DatabaseAdapter, ao as DatabaseInitArgs, ap as DatabaseTransfer, aq as DateField, ar as DepthOptions, as as DirectUpload, at as DiskStorageOptions, au as DocumentOf, av as EasyCMS, aw as EasyCMSError, ax as EmailAdapter, ay as EmailField, az as EmailMessage, aA as Endpoint, aB as EndpointRequest, aC as ErrorCode, aD as FIELD_TYPES, aE as Field, aF as FieldAccess, aG as FieldAccessFn, aH as FieldAdmin, aI as FieldError, aJ as FieldRule, aK as FieldType, aL as FieldTypeBase, aM as FieldTypeDefinition, aN as FieldTypeValidateContext, aO as FieldValidate, aP as FieldValidateContext, aQ as FieldValue, aR as FieldsInput, aS as FieldsValue, aT as FilterOptions, aU as FilterOptionsArgs, aV as FindAfterArgs, aW as FindArgs, aX as FindOptions, aY as FolderLevel, aZ as FolderPermissions, a_ as ForbiddenError, a$ as GlobalAccess, b0 as GlobalConfig, b1 as GlobalDocument, b2 as GlobalHooks, b3 as GlobalInput, b4 as GlobalSlug, b5 as GroupField, b6 as ImageSize, b7 as IncrementOptions, b8 as InferCollection, b9 as InferGlobal, ba as JobConfig, bb as JsonField, bc as KeysetPage, bd as Label, be as LayoutNode, bf as LivePreview, bg as LocaleOf, bh as LocalizationConfig, bi as LogDetails, bj as Logger, bk as LoginArgs, bl as LogsConfig, bm as MediaDocument, bn as MediaSize, bo as MembersConfig, bp as MembersSignup, bq as MigrationInfo, br as NavGroup, bs as NotFoundError, bt as NumberField, bu as OnRequest, bv as OnRequestArgs, bw as Operation, bx as PLUGIN_API_VERSION, by as PasswordEmail, bz as PasswordEmailArgs, bA as PasswordEmailFn, bB as PasswordLinkOptions, bC as PayloadTooLargeError, bD as Plugin, bE as PluginInfo, bF as PluginTypes, bG as PreviewTarget, bH as PreviewURL, bI as QueryError, bJ as ROLE_OPERATIONS, bK as RawDocument, bL as ReadOptions, bM as RelationshipField, bN as RequestContext, bO as ResolvedConfig, bP as RichTextDocument, bQ as RichTextField, bR as Role, bS as RoleOperation, bT as RolePermissions, bU as Roles, bV as RoutesConfig, bW as ScheduledPublish, bX as SchemaError, bY as SchemaMode, bZ as SelectField, b_ as SelectOption, b$ as Session, c0 as SidebarPanel, c1 as SignupArgs, c2 as SignupResult, c3 as SingleSignOn, c4 as SlugField, c5 as SlugOf, c6 as SsoOutcome, c7 as SsoProviderRef, c8 as StorageAdapter, c9 as StoredFile, ca as TextField, cb as TextareaField, cc as TooManyRequestsError, cd as TypedPlugin, ce as UnauthorizedError, cf as UncountedDocs, cg as UpdateInput, ch as UpdateOptions, ci as UploadConfig, cj as UploadField, ck as UploadFromURLConfig, cl as UserIdentity, cm as ValidationError, cn as Version, co as VersionSummary, cp as VersionsConfig, cq as WEBHOOK_EVENTS, cr as WebhookConfig, cs as WebhookEvent, ct as WebhookPayload, cu as Where, cv as WhereOperators, cw as anyone, cx as consoleEmail, cy as consoleLogger, cz as createEasyCMS, cA as defineConfig, cB as defineFieldType, cC as definePlugin, cD as diskStorage, cE as hasRows, cF as isAdmin, cG as isHasMany, cH as isSignedIn, cI as isStaff, cJ as isSystemAdmin, cK as jsonLogger, cL as mimeAllowedBy, cM as rowFields, cN as silentLogger, cO as uniqueWithinOf } from './config-
|
|
3
|
-
export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-
|
|
4
|
-
export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler
|
|
1
|
+
import { P as PaginatedDocs, I as ID, E as EmailSetting } from './config-n7PtGl4V.js';
|
|
2
|
+
export { A as ADAPTER_API_VERSION, a as ADMIN_ICONS, b as Access, c as AccessArgs, d as AccessOptions, e as AdminBrand, f as AdminCommand, g as AdminComponent, h as AdminConfig, i as AdminFieldArgs, j as AdminIcon, k as AdminLocale, l as AdminPage, m as AdminRole, n as AdminRoleChange, o as AdminRoleField, p as AdminRoleTarget, q as AdminRoleView, r as AdminRoles, s as AdminSso, t as AdminSwitcher, u as AdminViewAccess, v as AfterChangeHook, w as AfterDeleteHook, x as AfterReadHook, y as ApiKeyContext, z as ApiKeyGlobalOperation, B as ApiKeyOperation, C as ApiKeyPermissions, D as ArrayField, F as AuditChange, G as AuditConfig, H as AuditEntry, J as AuditLog, K as AuditPage, L as AuditVerification, M as Auth, N as AuthConfig, O as AuthProvider, Q as AuthProviderProfile, R as AuthProviderRequest, S as AuthUser, T as BackupsConfig, U as BeforeChangeHook, V as BeforeDeleteHook, W as BeforeValidateHook, X as Block, Y as BlocksField, Z as BooleanField, _ as BuiltinApiKeysCollection, $ as BuiltinMediaCollection, a0 as BuiltinMediaFoldersCollection, a1 as BuiltinUsersCollection, a2 as BundleHints, a3 as CliCommand, a4 as CollectionAccess, a5 as CollectionAdmin, a6 as CollectionConfig, a7 as CollectionDocument, a8 as CollectionHooks, a9 as CollectionListAdmin, aa as CollectionSlug, ab as Config, ac as ConfigError, ad as ConfigIssue, ae as ContainerAdmin, af as CreateEasyCMSOptions, ag as CreateInput, ah as CreateMigrationResult, ai as CursorDocs, aj as CustomField, ak as CustomFieldTypes, al as DashboardWidget, am as Database, an as DatabaseAdapter, ao as DatabaseInitArgs, ap as DatabaseTransfer, aq as DateField, ar as DepthOptions, as as DirectUpload, at as DiskStorageOptions, au as DocumentOf, av as EasyCMS, aw as EasyCMSError, ax as EmailAdapter, ay as EmailField, az as EmailMessage, aA as Endpoint, aB as EndpointRequest, aC as ErrorCode, aD as FIELD_TYPES, aE as Field, aF as FieldAccess, aG as FieldAccessFn, aH as FieldAdmin, aI as FieldError, aJ as FieldRule, aK as FieldType, aL as FieldTypeBase, aM as FieldTypeDefinition, aN as FieldTypeValidateContext, aO as FieldValidate, aP as FieldValidateContext, aQ as FieldValue, aR as FieldsInput, aS as FieldsValue, aT as FilterOptions, aU as FilterOptionsArgs, aV as FindAfterArgs, aW as FindArgs, aX as FindOptions, aY as FolderLevel, aZ as FolderPermissions, a_ as ForbiddenError, a$ as GlobalAccess, b0 as GlobalConfig, b1 as GlobalDocument, b2 as GlobalHooks, b3 as GlobalInput, b4 as GlobalSlug, b5 as GroupField, b6 as ImageSize, b7 as IncrementOptions, b8 as InferCollection, b9 as InferGlobal, ba as JobConfig, bb as JsonField, bc as KeysetPage, bd as Label, be as LayoutNode, bf as LivePreview, bg as LocaleOf, bh as LocalizationConfig, bi as LogDetails, bj as Logger, bk as LoginArgs, bl as LogsConfig, bm as MediaDocument, bn as MediaSize, bo as MembersConfig, bp as MembersSignup, bq as MigrationInfo, br as NavGroup, bs as NotFoundError, bt as NumberField, bu as OnRequest, bv as OnRequestArgs, bw as Operation, bx as PLUGIN_API_VERSION, by as PasswordEmail, bz as PasswordEmailArgs, bA as PasswordEmailFn, bB as PasswordLinkOptions, bC as PayloadTooLargeError, bD as Plugin, bE as PluginInfo, bF as PluginTypes, bG as PreviewTarget, bH as PreviewURL, bI as QueryError, bJ as ROLE_OPERATIONS, bK as RawDocument, bL as ReadOptions, bM as RelationshipField, bN as RequestContext, bO as ResolvedConfig, bP as RichTextDocument, bQ as RichTextField, bR as Role, bS as RoleOperation, bT as RolePermissions, bU as Roles, bV as RoutesConfig, bW as ScheduledPublish, bX as SchemaError, bY as SchemaMode, bZ as SelectField, b_ as SelectOption, b$ as Session, c0 as SidebarPanel, c1 as SignupArgs, c2 as SignupResult, c3 as SingleSignOn, c4 as SlugField, c5 as SlugOf, c6 as SsoOutcome, c7 as SsoProviderRef, c8 as StorageAdapter, c9 as StoredFile, ca as TextField, cb as TextareaField, cc as TooManyRequestsError, cd as TypedPlugin, ce as UnauthorizedError, cf as UncountedDocs, cg as UpdateInput, ch as UpdateOptions, ci as UploadConfig, cj as UploadField, ck as UploadFromURLConfig, cl as UserIdentity, cm as ValidationError, cn as Version, co as VersionSummary, cp as VersionsConfig, cq as WEBHOOK_EVENTS, cr as WebhookConfig, cs as WebhookEvent, ct as WebhookPayload, cu as Where, cv as WhereOperators, cw as anyone, cx as consoleEmail, cy as consoleLogger, cz as createEasyCMS, cA as defineConfig, cB as defineFieldType, cC as definePlugin, cD as diskStorage, cE as hasRows, cF as isAdmin, cG as isHasMany, cH as isSignedIn, cI as isStaff, cJ as isSystemAdmin, cK as jsonLogger, cL as mimeAllowedBy, cM as rowFields, cN as silentLogger, cO as uniqueWithinOf } from './config-n7PtGl4V.js';
|
|
3
|
+
export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-C_vknKa2.js';
|
|
4
|
+
export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler-DV-1ICVz.js';
|
|
5
5
|
export { FieldCondition, matchesCondition } from './conditions.js';
|
|
6
6
|
|
|
7
7
|
type DeliveryKind = 'webhook' | 'email';
|
|
@@ -218,8 +218,19 @@ interface AdminStatus {
|
|
|
218
218
|
attention: AdminAttention[];
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* The cache tags public reads carry and `httpCache.purge` receives: `ecms` for all content,
|
|
223
|
+
* `ecms:posts` for a collection's lists, `ecms:posts:42` for a document, `ecms:global:site` for
|
|
224
|
+
* a global. Use them to tag your own fetches, e.g. Next's `fetch(url, { next: { tags } })`.
|
|
225
|
+
*/
|
|
226
|
+
declare const cacheTags: {
|
|
227
|
+
collection: (slug: string) => string[];
|
|
228
|
+
document: (slug: string, id: unknown) => string[];
|
|
229
|
+
global: (slug: string) => string[];
|
|
230
|
+
};
|
|
231
|
+
|
|
221
232
|
/** The version of `@easy-cms/core`, set when the package is built. */
|
|
222
233
|
declare const VERSION: string;
|
|
223
234
|
|
|
224
|
-
export { EmailSetting, ID, PaginatedDocs, VERSION };
|
|
235
|
+
export { EmailSetting, ID, PaginatedDocs, VERSION, cacheTags };
|
|
225
236
|
export type { AdminAttention, AdminDeliveries, AdminDelivery, AdminEmail, AdminEmailDelivery, AdminJob, AdminJobs, AdminScheduledJob, AdminStatus, AdminWebhookDelivery, BuiltInJob, DeliveryKind, DeliveryState, EmailCheck, SearchHit };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
VERSION,
|
|
9
9
|
WEBHOOK_EVENTS,
|
|
10
10
|
anyone,
|
|
11
|
+
cacheTags,
|
|
11
12
|
consoleEmail,
|
|
12
13
|
consoleLogger,
|
|
13
14
|
createApiHandler,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
sharedEasyCMS,
|
|
25
26
|
silentLogger,
|
|
26
27
|
slugify
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-TMO4JTGJ.js";
|
|
28
29
|
import {
|
|
29
30
|
matchesCondition
|
|
30
31
|
} from "./chunk-U266LV4M.js";
|
|
@@ -74,6 +75,7 @@ export {
|
|
|
74
75
|
ValidationError,
|
|
75
76
|
WEBHOOK_EVENTS,
|
|
76
77
|
anyone,
|
|
78
|
+
cacheTags,
|
|
77
79
|
consoleEmail,
|
|
78
80
|
consoleLogger,
|
|
79
81
|
createApiHandler,
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Database, EasyCMS, NavGroup, CollectionConfig, ID, RawDocument, Field, ResolvedConfig, ConfigIssue } from './index.js';
|
|
2
|
-
export { cP as API_KEYS, cQ as API_KEY_GLOBAL_OPERATIONS, cR as API_KEY_OPERATIONS, cS as DEFAULT_MAX_VERSIONS, cT as DEFAULT_PASSWORD_EMAILS, cU as FIELD_TYPE_BASES, cV as FOLDER_LEVELS, cW as MediaFolders, cX as SSO_COOKIE, cY as codeOfStatus, cE as hasRows, cG as isHasMany, cZ as isJsonLogger, c_ as keyAllows, c$ as logFormat, cL as mimeAllowedBy, cM as rowFields, cO as uniqueWithinOf } from './config-
|
|
3
|
-
export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as decryptBackup, q as fillMissing, t as findConfigFile, u as forwardedClientIp, v as generateSlugs, w as importConfig, x as mergeForUpdate, y as parseId, z as platformClientIp, E as readCookie, F as validateFields, G as writeBackupFile } from './handler
|
|
2
|
+
export { cP as API_KEYS, cQ as API_KEY_GLOBAL_OPERATIONS, cR as API_KEY_OPERATIONS, cS as DEFAULT_MAX_VERSIONS, cT as DEFAULT_PASSWORD_EMAILS, cU as FIELD_TYPE_BASES, cV as FOLDER_LEVELS, cW as MediaFolders, cX as SSO_COOKIE, cY as codeOfStatus, cE as hasRows, cG as isHasMany, cZ as isJsonLogger, c_ as keyAllows, c$ as logFormat, cL as mimeAllowedBy, cM as rowFields, cO as uniqueWithinOf } from './config-n7PtGl4V.js';
|
|
3
|
+
export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as decryptBackup, q as fillMissing, t as findConfigFile, u as forwardedClientIp, v as generateSlugs, w as importConfig, x as mergeForUpdate, y as parseId, z as platformClientIp, E as readCookie, F as validateFields, G as writeBackupFile } from './handler-DV-1ICVz.js';
|
|
4
4
|
export { conditionIssues } from './conditions.js';
|
|
5
5
|
|
|
6
6
|
/** The session cookie the REST API sets at login. */
|
package/dist/internal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bd as Label, aE as Field, I as ID, k as AdminLocale, t as AdminSwitcher, c7 as SsoProviderRef } from './config-
|
|
1
|
+
import { bd as Label, aE as Field, I as ID, k as AdminLocale, t as AdminSwitcher, c7 as SsoProviderRef } from './config-n7PtGl4V.js';
|
|
2
2
|
import { FieldCondition } from './conditions.js';
|
|
3
3
|
|
|
4
4
|
/** A Web Component from an admin module, with its `props` (plain JSON). */
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as ADMIN_ICONS, g as AdminComponent, j as AdminIcon, S as AuthUser, a3 as CliCommand, a4 as CollectionAccess, a6 as CollectionConfig, ab as Config, ac as ConfigError, al as DashboardWidget, aw as EasyCMSError, aA as Endpoint, aB as EndpointRequest, aC as ErrorCode, aE as Field, aF as FieldAccess, aI as FieldError, aL as FieldTypeBase, aM as FieldTypeDefinition, aN as FieldTypeValidateContext, a_ as ForbiddenError, b0 as GlobalConfig, I as ID, ba as JobConfig, bd as Label, br as NavGroup, bs as NotFoundError, bu as OnRequest, bv as OnRequestArgs, bx as PLUGIN_API_VERSION, bC as PayloadTooLargeError, bD as Plugin, bE as PluginInfo, bF as PluginTypes, bI as QueryError, bN as RequestContext, cc as TooManyRequestsError, cd as TypedPlugin, ce as UnauthorizedError, cm as ValidationError, cu as Where, cB as defineFieldType, cC as definePlugin } from './config-
|
|
2
|
-
export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-
|
|
1
|
+
export { a as ADMIN_ICONS, g as AdminComponent, j as AdminIcon, S as AuthUser, a3 as CliCommand, a4 as CollectionAccess, a6 as CollectionConfig, ab as Config, ac as ConfigError, al as DashboardWidget, aw as EasyCMSError, aA as Endpoint, aB as EndpointRequest, aC as ErrorCode, aE as Field, aF as FieldAccess, aI as FieldError, aL as FieldTypeBase, aM as FieldTypeDefinition, aN as FieldTypeValidateContext, a_ as ForbiddenError, b0 as GlobalConfig, I as ID, ba as JobConfig, bd as Label, br as NavGroup, bs as NotFoundError, bu as OnRequest, bv as OnRequestArgs, bx as PLUGIN_API_VERSION, bC as PayloadTooLargeError, bD as Plugin, bE as PluginInfo, bF as PluginTypes, bI as QueryError, bN as RequestContext, cc as TooManyRequestsError, cd as TypedPlugin, ce as UnauthorizedError, cm as ValidationError, cu as Where, cB as defineFieldType, cC as definePlugin } from './config-n7PtGl4V.js';
|
|
2
|
+
export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-C_vknKa2.js';
|
|
3
3
|
import './conditions.js';
|