@prenta/core 8.9.1 → 8.10.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/CHANGELOG.md +102 -0
- package/dist/actions.d.ts +31 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +59 -4
- package/dist/actions.js.map +1 -1
- package/dist/ai/batch-links.d.ts +105 -0
- package/dist/ai/batch-links.d.ts.map +1 -0
- package/dist/ai/batch-links.js +667 -0
- package/dist/ai/batch-links.js.map +1 -0
- package/dist/ai/batch-list.d.ts +127 -4
- package/dist/ai/batch-list.d.ts.map +1 -1
- package/dist/ai/batch-list.js +250 -14
- package/dist/ai/batch-list.js.map +1 -1
- package/dist/ai/providers/http.d.ts +4 -0
- package/dist/ai/providers/http.d.ts.map +1 -1
- package/dist/ai/providers/http.js +9 -8
- package/dist/ai/providers/http.js.map +1 -1
- package/dist/ai/tasks/editor-text.d.ts +39 -0
- package/dist/ai/tasks/editor-text.d.ts.map +1 -0
- package/dist/ai/tasks/editor-text.js +45 -0
- package/dist/ai/tasks/editor-text.js.map +1 -0
- package/dist/ai/tasks/link-embeddings.d.ts +22 -0
- package/dist/ai/tasks/link-embeddings.d.ts.map +1 -1
- package/dist/ai/tasks/link-embeddings.js +24 -10
- package/dist/ai/tasks/link-embeddings.js.map +1 -1
- package/dist/ai/usage.d.ts +7 -0
- package/dist/ai/usage.d.ts.map +1 -1
- package/dist/ai/usage.js +11 -0
- package/dist/ai/usage.js.map +1 -1
- package/dist/api/guarded-db.d.ts +6 -0
- package/dist/api/guarded-db.d.ts.map +1 -1
- package/dist/api/guarded-db.js +13 -1
- package/dist/api/guarded-db.js.map +1 -1
- package/dist/api/handlers.d.ts.map +1 -1
- package/dist/api/handlers.js +2 -0
- package/dist/api/handlers.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +47 -0
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/route-helpers/forms.d.ts.map +1 -1
- package/dist/api/route-helpers/forms.js +7 -1
- package/dist/api/route-helpers/forms.js.map +1 -1
- package/dist/api/routes/ai-authoring.d.ts.map +1 -1
- package/dist/api/routes/ai-authoring.js +1 -0
- package/dist/api/routes/ai-authoring.js.map +1 -1
- package/dist/api/routes/ai-seo.d.ts.map +1 -1
- package/dist/api/routes/ai-seo.js +20 -18
- package/dist/api/routes/ai-seo.js.map +1 -1
- package/dist/api/routes/documents.d.ts.map +1 -1
- package/dist/api/routes/documents.js +20 -0
- package/dist/api/routes/documents.js.map +1 -1
- package/dist/api/routes/media.d.ts.map +1 -1
- package/dist/api/routes/media.js +3 -1
- package/dist/api/routes/media.js.map +1 -1
- package/dist/api/routes/scheduling.d.ts.map +1 -1
- package/dist/api/routes/scheduling.js +33 -2
- package/dist/api/routes/scheduling.js.map +1 -1
- package/dist/appearance/color.d.ts +17 -0
- package/dist/appearance/color.d.ts.map +1 -1
- package/dist/appearance/color.js +162 -1
- package/dist/appearance/color.js.map +1 -1
- package/dist/appearance/index.d.ts +3 -3
- package/dist/appearance/index.d.ts.map +1 -1
- package/dist/appearance/index.js +2 -2
- package/dist/appearance/index.js.map +1 -1
- package/dist/appearance/resolve.d.ts.map +1 -1
- package/dist/appearance/resolve.js +4 -2
- package/dist/appearance/resolve.js.map +1 -1
- package/dist/appearance/theme-tokens.d.ts +60 -11
- package/dist/appearance/theme-tokens.d.ts.map +1 -1
- package/dist/appearance/theme-tokens.js +184 -175
- package/dist/appearance/theme-tokens.js.map +1 -1
- package/dist/appearance/types.d.ts +16 -2
- package/dist/appearance/types.d.ts.map +1 -1
- package/dist/astro-site.d.ts +1 -11
- package/dist/astro-site.d.ts.map +1 -1
- package/dist/astro-site.js +4 -0
- package/dist/astro-site.js.map +1 -1
- package/dist/auth/team.d.ts +1 -0
- package/dist/auth/team.d.ts.map +1 -1
- package/dist/auth/team.js +1 -1
- package/dist/auth/team.js.map +1 -1
- package/dist/cache/http.d.ts +20 -0
- package/dist/cache/http.d.ts.map +1 -1
- package/dist/cache/http.js +42 -0
- package/dist/cache/http.js.map +1 -1
- package/dist/chrome/announcement.d.ts +30 -0
- package/dist/chrome/announcement.d.ts.map +1 -0
- package/dist/chrome/announcement.js +190 -0
- package/dist/chrome/announcement.js.map +1 -0
- package/dist/chrome/codegen.d.ts +17 -0
- package/dist/chrome/codegen.d.ts.map +1 -0
- package/dist/chrome/codegen.js +96 -0
- package/dist/chrome/codegen.js.map +1 -0
- package/dist/chrome/contract.d.ts +142 -0
- package/dist/chrome/contract.d.ts.map +1 -0
- package/dist/chrome/contract.js +2 -0
- package/dist/chrome/contract.js.map +1 -0
- package/dist/chrome/memory-store.d.ts +15 -0
- package/dist/chrome/memory-store.d.ts.map +1 -0
- package/dist/chrome/memory-store.js +54 -0
- package/dist/chrome/memory-store.js.map +1 -0
- package/dist/chrome/parse.d.ts +36 -0
- package/dist/chrome/parse.d.ts.map +1 -0
- package/dist/chrome/parse.js +277 -0
- package/dist/chrome/parse.js.map +1 -0
- package/dist/chrome/prisma-store.d.ts +11 -0
- package/dist/chrome/prisma-store.d.ts.map +1 -0
- package/dist/chrome/prisma-store.js +48 -0
- package/dist/chrome/prisma-store.js.map +1 -0
- package/dist/chrome/public.d.ts +22 -0
- package/dist/chrome/public.d.ts.map +1 -0
- package/dist/chrome/public.js +181 -0
- package/dist/chrome/public.js.map +1 -0
- package/dist/chrome/resolve.d.ts +36 -0
- package/dist/chrome/resolve.d.ts.map +1 -0
- package/dist/chrome/resolve.js +165 -0
- package/dist/chrome/resolve.js.map +1 -0
- package/dist/chrome/revalidate.d.ts +9 -0
- package/dist/chrome/revalidate.d.ts.map +1 -0
- package/dist/chrome/revalidate.js +51 -0
- package/dist/chrome/revalidate.js.map +1 -0
- package/dist/chrome/routes.d.ts +14 -0
- package/dist/chrome/routes.d.ts.map +1 -0
- package/dist/chrome/routes.js +306 -0
- package/dist/chrome/routes.js.map +1 -0
- package/dist/chrome/schema.d.ts +231 -0
- package/dist/chrome/schema.d.ts.map +1 -0
- package/dist/chrome/schema.js +73 -0
- package/dist/chrome/schema.js.map +1 -0
- package/dist/chrome/service.d.ts +76 -0
- package/dist/chrome/service.d.ts.map +1 -0
- package/dist/chrome/service.js +286 -0
- package/dist/chrome/service.js.map +1 -0
- package/dist/chrome/settings.d.ts +14 -0
- package/dist/chrome/settings.d.ts.map +1 -0
- package/dist/chrome/settings.js +142 -0
- package/dist/chrome/settings.js.map +1 -0
- package/dist/chrome/store.d.ts +48 -0
- package/dist/chrome/store.d.ts.map +1 -0
- package/dist/chrome/store.js +26 -0
- package/dist/chrome/store.js.map +1 -0
- package/dist/chrome/values.d.ts +98 -0
- package/dist/chrome/values.d.ts.map +1 -0
- package/dist/chrome/values.js +491 -0
- package/dist/chrome/values.js.map +1 -0
- package/dist/config/define.d.ts +2 -0
- package/dist/config/define.d.ts.map +1 -1
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/db/model-types.d.ts +62 -0
- package/dist/db/model-types.d.ts.map +1 -1
- package/dist/forms/attribution-settings.d.ts +23 -0
- package/dist/forms/attribution-settings.d.ts.map +1 -0
- package/dist/forms/attribution-settings.js +42 -0
- package/dist/forms/attribution-settings.js.map +1 -0
- package/dist/forms/attribution.d.ts +5 -1
- package/dist/forms/attribution.d.ts.map +1 -1
- package/dist/forms/attribution.js +6 -4
- package/dist/forms/attribution.js.map +1 -1
- package/dist/forms/client-validation.d.ts.map +1 -1
- package/dist/forms/client-validation.js +3 -0
- package/dist/forms/client-validation.js.map +1 -1
- package/dist/forms/form-model.d.ts +109 -0
- package/dist/forms/form-model.d.ts.map +1 -0
- package/dist/forms/form-model.js +192 -0
- package/dist/forms/form-model.js.map +1 -0
- package/dist/forms/index.d.ts +2 -2
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/service.d.ts +19 -1
- package/dist/forms/service.d.ts.map +1 -1
- package/dist/forms/service.js +152 -0
- package/dist/forms/service.js.map +1 -1
- package/dist/forms/spam.d.ts +0 -12
- package/dist/forms/spam.d.ts.map +1 -1
- package/dist/forms/spam.js +30 -0
- package/dist/forms/spam.js.map +1 -1
- package/dist/forms/submission.d.ts +7 -0
- package/dist/forms/submission.d.ts.map +1 -1
- package/dist/forms/submission.js +33 -0
- package/dist/forms/submission.js.map +1 -1
- package/dist/forms/types.d.ts +26 -1
- package/dist/forms/types.d.ts.map +1 -1
- package/dist/forms/types.js +9 -1
- package/dist/forms/types.js.map +1 -1
- package/dist/generated/browser.d.ts +35 -3
- package/dist/generated/client.d.ts +35 -3
- package/dist/generated/internal/class.d.ts +44 -0
- package/dist/generated/internal/class.js +4 -4
- package/dist/generated/internal/prismaNamespace.d.ts +403 -1
- package/dist/generated/internal/prismaNamespace.js +95 -1
- package/dist/generated/internal/prismaNamespaceBrowser.d.ts +102 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +95 -1
- package/dist/generated/models/ChromeRegion.d.ts +1203 -0
- package/dist/generated/models/ChromeRegion.js +1 -0
- package/dist/generated/models/Job.d.ts +732 -5
- package/dist/generated/models/JobEvent.d.ts +1339 -0
- package/dist/generated/models/JobEvent.js +1 -0
- package/dist/generated/models/JobReviewItem.d.ts +1470 -0
- package/dist/generated/models/JobReviewItem.js +1 -0
- package/dist/generated/models/SystemSetting.d.ts +952 -0
- package/dist/generated/models/SystemSetting.js +1 -0
- package/dist/generated/models.d.ts +4 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/jobs/batch-ai.d.ts +53 -0
- package/dist/jobs/batch-ai.d.ts.map +1 -0
- package/dist/jobs/batch-ai.js +314 -0
- package/dist/jobs/batch-ai.js.map +1 -0
- package/dist/jobs/contract.d.ts +186 -0
- package/dist/jobs/contract.d.ts.map +1 -0
- package/dist/jobs/contract.js +2 -0
- package/dist/jobs/contract.js.map +1 -0
- package/dist/jobs/error-text.d.ts +23 -0
- package/dist/jobs/error-text.d.ts.map +1 -0
- package/dist/jobs/error-text.js +110 -0
- package/dist/jobs/error-text.js.map +1 -0
- package/dist/jobs/handlers.d.ts.map +1 -1
- package/dist/jobs/handlers.js +48 -7
- package/dist/jobs/handlers.js.map +1 -1
- package/dist/jobs/memory-store.d.ts +26 -2
- package/dist/jobs/memory-store.d.ts.map +1 -1
- package/dist/jobs/memory-store.js +157 -3
- package/dist/jobs/memory-store.js.map +1 -1
- package/dist/jobs/outcomes.d.ts +46 -0
- package/dist/jobs/outcomes.d.ts.map +1 -0
- package/dist/jobs/outcomes.js +251 -0
- package/dist/jobs/outcomes.js.map +1 -0
- package/dist/jobs/prisma-store.d.ts +14 -2
- package/dist/jobs/prisma-store.d.ts.map +1 -1
- package/dist/jobs/prisma-store.js +257 -15
- package/dist/jobs/prisma-store.js.map +1 -1
- package/dist/jobs/queue.d.ts +62 -2
- package/dist/jobs/queue.d.ts.map +1 -1
- package/dist/jobs/queue.js +412 -36
- package/dist/jobs/queue.js.map +1 -1
- package/dist/jobs/retention.d.ts +11 -0
- package/dist/jobs/retention.d.ts.map +1 -0
- package/dist/jobs/retention.js +18 -0
- package/dist/jobs/retention.js.map +1 -0
- package/dist/jobs/review.d.ts +111 -0
- package/dist/jobs/review.d.ts.map +1 -0
- package/dist/jobs/review.js +461 -0
- package/dist/jobs/review.js.map +1 -0
- package/dist/jobs/routes.d.ts.map +1 -1
- package/dist/jobs/routes.js +491 -16
- package/dist/jobs/routes.js.map +1 -1
- package/dist/jobs/serialize.d.ts +40 -0
- package/dist/jobs/serialize.d.ts.map +1 -0
- package/dist/jobs/serialize.js +270 -0
- package/dist/jobs/serialize.js.map +1 -0
- package/dist/jobs/types.d.ts +141 -2
- package/dist/jobs/types.d.ts.map +1 -1
- package/dist/jobs/worker-status.d.ts +27 -0
- package/dist/jobs/worker-status.d.ts.map +1 -0
- package/dist/jobs/worker-status.js +66 -0
- package/dist/jobs/worker-status.js.map +1 -0
- package/dist/media/optimize.d.ts.map +1 -1
- package/dist/media/optimize.js +4 -2
- package/dist/media/optimize.js.map +1 -1
- package/dist/next-site.d.ts +1 -0
- package/dist/next-site.d.ts.map +1 -1
- package/dist/next-site.js +3 -0
- package/dist/next-site.js.map +1 -1
- package/dist/seo/audit-runner.d.ts.map +1 -1
- package/dist/seo/audit-runner.js +23 -2
- package/dist/seo/audit-runner.js.map +1 -1
- package/dist/seo/issue-fix-link-insert.d.ts +11 -0
- package/dist/seo/issue-fix-link-insert.d.ts.map +1 -1
- package/dist/seo/issue-fix-link-insert.js +122 -8
- package/dist/seo/issue-fix-link-insert.js.map +1 -1
- package/dist/server-site.d.ts.map +1 -1
- package/dist/server-site.js +15 -0
- package/dist/server-site.js.map +1 -1
- package/dist/site.d.ts +8 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +6 -0
- package/dist/site.js.map +1 -1
- package/dist/webhooks/index.d.ts +3 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js.map +1 -1
- package/package.json +6 -1
- package/prisma/migrations/0025_job_cancel_review/down.sql +60 -0
- package/prisma/migrations/0025_job_cancel_review/migration.sql +56 -0
- package/prisma/migrations/0026_job_creator_system_settings/down.sql +30 -0
- package/prisma/migrations/0026_job_creator_system_settings/migration.sql +14 -0
- package/prisma/migrations/0027_chrome_regions/down.sql +24 -0
- package/prisma/migrations/0027_chrome_regions/migration.sql +16 -0
- package/prisma/schema.prisma +105 -15
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PrentaCMSConfig } from '../config/types.js';
|
|
2
|
+
import type { PrentaDB } from '../db/client-types.js';
|
|
3
|
+
import type { PublicChrome } from './contract.js';
|
|
4
|
+
import { type ChromeStore } from './store.js';
|
|
5
|
+
/** `/x/y/` → `/x/y`. Null for anything that isn't a site path. */
|
|
6
|
+
export declare function normalizeChromePath(value: string | null | undefined): string | null;
|
|
7
|
+
/**
|
|
8
|
+
* Cache tags for `/public/chrome?path=`: the shared chrome set, plus the
|
|
9
|
+
* collection of every page whose override it reads. An ancestor can live in
|
|
10
|
+
* another collection than the page (`/blog` in pages, `/blog/hello` in posts).
|
|
11
|
+
*/
|
|
12
|
+
export declare function chromeReadTags(config: Pick<PrentaCMSConfig, 'collections'> | null, path: string): string[];
|
|
13
|
+
export interface LoadPublicChromeOptions {
|
|
14
|
+
db: PrentaDB;
|
|
15
|
+
store: ChromeStore;
|
|
16
|
+
config: Pick<PrentaCMSConfig, 'collections'> | null;
|
|
17
|
+
path: string;
|
|
18
|
+
now: Date;
|
|
19
|
+
}
|
|
20
|
+
/** Everything the site gets for one path. */
|
|
21
|
+
export declare function loadPublicChrome(options: LoadPublicChromeOptions): Promise<PublicChrome>;
|
|
22
|
+
//# sourceMappingURL=public.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/chrome/public.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAIrD,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,eAAe,CAAA;AAUtB,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAG/D,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAMnF;AAyCD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,EACnD,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAKV;AA6FD,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,QAAQ,CAAA;IACZ,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,CAAA;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,IAAI,CAAA;CACV;AAED,6CAA6C;AAC7C,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqD9F"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { chromeCacheTags, chromePagePaths } from '../cache/http.js';
|
|
2
|
+
import { matchPathToCollection } from '../seo/resolve-path.js';
|
|
3
|
+
import { coercePublicNavItems } from '../site.js';
|
|
4
|
+
import { readAnnouncement, toPublicAnnouncement } from './announcement.js';
|
|
5
|
+
import { effectiveRegion, menuSlugs, publicRegion, readRegionOverride, withEtag, } from './resolve.js';
|
|
6
|
+
import { CHROME_REGIONS } from './schema.js';
|
|
7
|
+
import { ANNOUNCEMENT_ROW } from './store.js';
|
|
8
|
+
import { fromStoredSchema, isRecord } from './values.js';
|
|
9
|
+
/** `/x/y/` → `/x/y`. Null for anything that isn't a site path. */
|
|
10
|
+
export function normalizeChromePath(value) {
|
|
11
|
+
if (typeof value !== 'string')
|
|
12
|
+
return null;
|
|
13
|
+
const trimmed = value.trim();
|
|
14
|
+
if (!trimmed.startsWith('/') || trimmed.startsWith('//') || trimmed.length > 2048)
|
|
15
|
+
return null;
|
|
16
|
+
if (/[\s?#]/.test(trimmed))
|
|
17
|
+
return null;
|
|
18
|
+
return trimmed.replace(/\/+$/, '') || '/';
|
|
19
|
+
}
|
|
20
|
+
function overridesOf(data) {
|
|
21
|
+
const layout = isRecord(data) && isRecord(data._layout) ? data._layout : {};
|
|
22
|
+
const out = {};
|
|
23
|
+
for (const region of CHROME_REGIONS) {
|
|
24
|
+
const override = readRegionOverride(layout[region]);
|
|
25
|
+
if (override !== undefined)
|
|
26
|
+
out[region] = override;
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function pageRef(config, path) {
|
|
31
|
+
const match = matchPathToCollection(config, path);
|
|
32
|
+
if (!match)
|
|
33
|
+
return null;
|
|
34
|
+
return { collection: match.collection, slugs: match.isRoot ? ['home', 'index'] : [match.slug] };
|
|
35
|
+
}
|
|
36
|
+
/** The page first, then its ancestors nearest first, so the first override found wins. */
|
|
37
|
+
function pageRefs(config, path) {
|
|
38
|
+
const refs = [];
|
|
39
|
+
for (const [index, pagePath] of chromePagePaths(path).entries()) {
|
|
40
|
+
const ref = pageRef(config, pagePath);
|
|
41
|
+
if (ref)
|
|
42
|
+
refs.push({ ref, isPage: index === 0 });
|
|
43
|
+
}
|
|
44
|
+
return refs;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Cache tags for `/public/chrome?path=`: the shared chrome set, plus the
|
|
48
|
+
* collection of every page whose override it reads. An ancestor can live in
|
|
49
|
+
* another collection than the page (`/blog` in pages, `/blog/hello` in posts).
|
|
50
|
+
*/
|
|
51
|
+
export function chromeReadTags(config, path) {
|
|
52
|
+
return chromeCacheTags(path, pageRefs(config, path).map(({ ref }) => ref.collection));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The page's own overrides and, per region, the nearest ancestor's. The root
|
|
56
|
+
* page is nobody's ancestor: the site default covers every page already.
|
|
57
|
+
*/
|
|
58
|
+
async function loadPageOverrides(db, config, path) {
|
|
59
|
+
const refs = pageRefs(config, path);
|
|
60
|
+
if (refs.length === 0)
|
|
61
|
+
return { page: {}, ancestor: {} };
|
|
62
|
+
const docs = (await db.document.findMany({
|
|
63
|
+
where: {
|
|
64
|
+
deletedAt: null,
|
|
65
|
+
status: 'PUBLISHED',
|
|
66
|
+
OR: refs.map(({ ref }) => ({
|
|
67
|
+
collection: ref.collection,
|
|
68
|
+
OR: [
|
|
69
|
+
{ slug: { in: ref.slugs } },
|
|
70
|
+
...ref.slugs.map((slug) => ({ data: { path: ['slug'], equals: slug } })),
|
|
71
|
+
],
|
|
72
|
+
})),
|
|
73
|
+
},
|
|
74
|
+
select: { collection: true, slug: true, data: true },
|
|
75
|
+
}));
|
|
76
|
+
const find = (ref) => docs.find((doc) => doc.collection === ref.collection && ref.slugs.includes(doc.slug ?? '')) ??
|
|
77
|
+
docs.find((doc) => doc.collection === ref.collection &&
|
|
78
|
+
isRecord(doc.data) &&
|
|
79
|
+
typeof doc.data.slug === 'string' &&
|
|
80
|
+
ref.slugs.includes(doc.data.slug));
|
|
81
|
+
let page = {};
|
|
82
|
+
const ancestor = {};
|
|
83
|
+
for (const { ref, isPage } of refs) {
|
|
84
|
+
const doc = find(ref);
|
|
85
|
+
if (!doc)
|
|
86
|
+
continue;
|
|
87
|
+
const overrides = overridesOf(doc.data);
|
|
88
|
+
if (isPage) {
|
|
89
|
+
page = overrides;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
for (const region of CHROME_REGIONS) {
|
|
93
|
+
if (ancestor[region] === undefined && overrides[region] !== undefined) {
|
|
94
|
+
ancestor[region] = overrides[region];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { page, ancestor };
|
|
99
|
+
}
|
|
100
|
+
/** Menus by slug, with the rules `/public/navigations/:slug` uses: any status but ARCHIVED. */
|
|
101
|
+
async function loadMenus(db, slugs) {
|
|
102
|
+
const menus = new Map();
|
|
103
|
+
if (slugs.length === 0)
|
|
104
|
+
return menus;
|
|
105
|
+
const docs = (await db.document.findMany({
|
|
106
|
+
where: {
|
|
107
|
+
collection: 'navigations',
|
|
108
|
+
deletedAt: null,
|
|
109
|
+
status: { not: 'ARCHIVED' },
|
|
110
|
+
OR: [
|
|
111
|
+
{ slug: { in: slugs } },
|
|
112
|
+
...slugs.map((slug) => ({ data: { path: ['slug'], equals: slug } })),
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
orderBy: { updatedAt: 'desc' },
|
|
116
|
+
}));
|
|
117
|
+
for (const doc of docs) {
|
|
118
|
+
const data = isRecord(doc.data) ? doc.data : {};
|
|
119
|
+
const slug = typeof data.slug === 'string' && data.slug ? data.slug : doc.slug;
|
|
120
|
+
if (!slug || !slugs.includes(slug) || menus.has(slug))
|
|
121
|
+
continue;
|
|
122
|
+
menus.set(slug, {
|
|
123
|
+
id: slug,
|
|
124
|
+
name: typeof data.name === 'string' ? data.name : (doc.title ?? ''),
|
|
125
|
+
items: coercePublicNavItems(data.items),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return menus;
|
|
129
|
+
}
|
|
130
|
+
async function loadBrand(db) {
|
|
131
|
+
const { resolveBrand } = await import('../appearance/index.js');
|
|
132
|
+
const brand = await resolveBrand(db, null);
|
|
133
|
+
return { logo: brand.public.primary, name: brand.siteTitle ?? '' };
|
|
134
|
+
}
|
|
135
|
+
/** Everything the site gets for one path. */
|
|
136
|
+
export async function loadPublicChrome(options) {
|
|
137
|
+
const { db, store, config, path, now } = options;
|
|
138
|
+
const rows = await store.list();
|
|
139
|
+
const byRegion = new Map(rows.map((row) => [row.region, row]));
|
|
140
|
+
const schemas = new Map();
|
|
141
|
+
for (const region of CHROME_REGIONS) {
|
|
142
|
+
const schema = fromStoredSchema(region, byRegion.get(region)?.schema);
|
|
143
|
+
if (schema)
|
|
144
|
+
schemas.set(region, schema);
|
|
145
|
+
}
|
|
146
|
+
const resolved = new Map();
|
|
147
|
+
if (schemas.size > 0) {
|
|
148
|
+
const { page, ancestor } = await loadPageOverrides(db, config, path);
|
|
149
|
+
for (const [region, schema] of schemas) {
|
|
150
|
+
const row = byRegion.get(region);
|
|
151
|
+
resolved.set(region, effectiveRegion(schema, { variant: row?.variant ?? null, values: row?.values ?? {} }, [
|
|
152
|
+
ancestor[region],
|
|
153
|
+
page[region],
|
|
154
|
+
]));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const slugs = new Set();
|
|
158
|
+
let needsBrand = false;
|
|
159
|
+
for (const [region, effective] of resolved) {
|
|
160
|
+
if (!effective)
|
|
161
|
+
continue;
|
|
162
|
+
const schema = schemas.get(region);
|
|
163
|
+
for (const slug of menuSlugs(schema, effective.values))
|
|
164
|
+
slugs.add(slug);
|
|
165
|
+
if (Object.values(schema.fields).some((def) => def.type === 'brand'))
|
|
166
|
+
needsBrand = true;
|
|
167
|
+
}
|
|
168
|
+
const [menus, brand] = await Promise.all([
|
|
169
|
+
loadMenus(db, [...slugs]),
|
|
170
|
+
needsBrand ? loadBrand(db) : Promise.resolve({ logo: null, name: '' }),
|
|
171
|
+
]);
|
|
172
|
+
const body = { announcement: null };
|
|
173
|
+
for (const [region, effective] of resolved) {
|
|
174
|
+
body[region] = effective
|
|
175
|
+
? publicRegion(schemas.get(region), effective, { menus, brand, now })
|
|
176
|
+
: null;
|
|
177
|
+
}
|
|
178
|
+
body.announcement = toPublicAnnouncement(readAnnouncement(byRegion.get(ANNOUNCEMENT_ROW)?.values), now);
|
|
179
|
+
return withEtag(body);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=public.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/chrome/public.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ResolvedLogo } from '../appearance/types.js';
|
|
2
|
+
import type { ChromeRegionOverride, PublicAnnouncement, PublicChrome, PublicChromeRegion, RegionSchema } from './contract.js';
|
|
3
|
+
import type { ChromeMenu } from './schema.js';
|
|
4
|
+
/** A region's variant and stored-format values after overrides. */
|
|
5
|
+
export interface EffectiveRegion {
|
|
6
|
+
variant: string;
|
|
7
|
+
values: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/** Read one region's override from a page's `_layout`. Strings are legacy variant-document ids, not overrides. */
|
|
10
|
+
export declare function readRegionOverride(value: unknown): ChromeRegionOverride | null | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Apply the overrides in order (nearest ancestor, then the page) over the
|
|
13
|
+
* site default. `undefined` means "no override at this level".
|
|
14
|
+
*/
|
|
15
|
+
export declare function effectiveRegion(schema: Pick<RegionSchema, 'variants' | 'fields'>, site: {
|
|
16
|
+
variant: string | null;
|
|
17
|
+
values: Record<string, unknown>;
|
|
18
|
+
}, overrides: Array<ChromeRegionOverride | null | undefined>): EffectiveRegion | null;
|
|
19
|
+
/** The menu slugs a region's values point at, defaults included. */
|
|
20
|
+
export declare function menuSlugs(schema: Pick<RegionSchema, 'fields'>, values: Record<string, unknown>): string[];
|
|
21
|
+
export interface PublicFieldContext {
|
|
22
|
+
menus: ReadonlyMap<string, ChromeMenu>;
|
|
23
|
+
brand: {
|
|
24
|
+
logo: ResolvedLogo | null;
|
|
25
|
+
name: string;
|
|
26
|
+
};
|
|
27
|
+
now: Date;
|
|
28
|
+
}
|
|
29
|
+
/** A region as the site receives it, every field filled in, in schema order. */
|
|
30
|
+
export declare function publicRegion(schema: Pick<RegionSchema, 'fields'>, region: EffectiveRegion, ctx: PublicFieldContext): PublicChromeRegion;
|
|
31
|
+
export declare function withEtag(body: {
|
|
32
|
+
header?: PublicChromeRegion | null;
|
|
33
|
+
footer?: PublicChromeRegion | null;
|
|
34
|
+
announcement: PublicAnnouncement | null;
|
|
35
|
+
}): PublicChrome;
|
|
36
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/chrome/resolve.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACb,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,aAAa,CAAA;AAUvD,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAO1F;AAqBD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,QAAQ,CAAC,EACjD,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACjE,SAAS,EAAE,KAAK,CAAC,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAAC,GACxD,eAAe,GAAG,IAAI,CAsBxB;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CACvB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,EAAE,CAkBV;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACtC,KAAK,EAAE;QAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClD,GAAG,EAAE,IAAI,CAAA;CACV;AA2DD,gFAAgF;AAChF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACpC,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,kBAAkB,GACtB,kBAAkB,CAMpB;AAQD,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAClC,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAClC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAA;CACxC,GAAG,YAAY,CAEf"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `/public/chrome` sends for a path. A region resolves in three steps,
|
|
3
|
+
* each over the last: the site default, the nearest ancestor page's override,
|
|
4
|
+
* then the page's own. An override of `null` hides the region; a later
|
|
5
|
+
* override that isn't null shows it again.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import { cleanFieldValue, effectiveVariant, hasVariant, isRecord, ownField, ownValue, } from './values.js';
|
|
9
|
+
/** Read one region's override from a page's `_layout`. Strings are legacy variant-document ids, not overrides. */
|
|
10
|
+
export function readRegionOverride(value) {
|
|
11
|
+
if (value === null)
|
|
12
|
+
return null;
|
|
13
|
+
if (!isRecord(value))
|
|
14
|
+
return undefined;
|
|
15
|
+
const out = {};
|
|
16
|
+
if (typeof value.variant === 'string')
|
|
17
|
+
out.variant = value.variant;
|
|
18
|
+
if (isRecord(value.fields))
|
|
19
|
+
out.fields = value.fields;
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Keep the values that fit their field and pass a save's checks; the rest are
|
|
24
|
+
* ignored. Page overrides come from `_layout`, which no chrome save checked,
|
|
25
|
+
* so a `javascript:` link or an over-long text there never reaches the site.
|
|
26
|
+
*/
|
|
27
|
+
function fittingValues(schema, values) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [key, value] of Object.entries(values ?? {})) {
|
|
30
|
+
const def = ownField(schema, key);
|
|
31
|
+
if (!def)
|
|
32
|
+
continue;
|
|
33
|
+
const fit = cleanFieldValue(def, value);
|
|
34
|
+
if (fit.ok)
|
|
35
|
+
out[key] = fit.value;
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Apply the overrides in order (nearest ancestor, then the page) over the
|
|
41
|
+
* site default. `undefined` means "no override at this level".
|
|
42
|
+
*/
|
|
43
|
+
export function effectiveRegion(schema, site, overrides) {
|
|
44
|
+
const base = {
|
|
45
|
+
variant: effectiveVariant(schema, site.variant),
|
|
46
|
+
values: fittingValues(schema, site.values),
|
|
47
|
+
};
|
|
48
|
+
let current = base;
|
|
49
|
+
for (const override of overrides) {
|
|
50
|
+
if (override === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
if (override === null) {
|
|
53
|
+
current = null;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const from = current ?? base;
|
|
57
|
+
current = {
|
|
58
|
+
variant: override.variant !== undefined && hasVariant(schema, override.variant)
|
|
59
|
+
? override.variant
|
|
60
|
+
: from.variant,
|
|
61
|
+
values: { ...from.values, ...fittingValues(schema, override.fields) },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return current;
|
|
65
|
+
}
|
|
66
|
+
/** The menu slugs a region's values point at, defaults included. */
|
|
67
|
+
export function menuSlugs(schema, values) {
|
|
68
|
+
const slugs = new Set();
|
|
69
|
+
for (const [key, def] of Object.entries(schema.fields)) {
|
|
70
|
+
if (def.type !== 'menu')
|
|
71
|
+
continue;
|
|
72
|
+
const value = ownValue(values, key);
|
|
73
|
+
if (def.list) {
|
|
74
|
+
const list = Array.isArray(value) ? value : def.default ? [def.default] : [];
|
|
75
|
+
for (const slug of list)
|
|
76
|
+
if (typeof slug === 'string' && slug)
|
|
77
|
+
slugs.add(slug);
|
|
78
|
+
}
|
|
79
|
+
else if (def.optional) {
|
|
80
|
+
if (isRecord(value) && value.on === true && typeof value.value === 'string' && value.value) {
|
|
81
|
+
slugs.add(value.value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const slug = typeof value === 'string' && value ? value : def.default;
|
|
86
|
+
if (slug)
|
|
87
|
+
slugs.add(slug);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return [...slugs];
|
|
91
|
+
}
|
|
92
|
+
/** Fill the placeholders the CMS owns. `{year}` is the current UTC year. */
|
|
93
|
+
function fillTokens(text, def, now) {
|
|
94
|
+
if (!def.tokens?.includes('{year}'))
|
|
95
|
+
return text;
|
|
96
|
+
return text.split('{year}').join(String(now.getUTCFullYear()));
|
|
97
|
+
}
|
|
98
|
+
function toggleOn(value) {
|
|
99
|
+
return isRecord(value) && value.on === true;
|
|
100
|
+
}
|
|
101
|
+
/** One field as the site receives it. */
|
|
102
|
+
function publicField(def, value, ctx) {
|
|
103
|
+
switch (def.type) {
|
|
104
|
+
case 'brand':
|
|
105
|
+
return def.key === 'logo' ? ctx.brand.logo : ctx.brand.name;
|
|
106
|
+
case 'menu': {
|
|
107
|
+
if (def.list) {
|
|
108
|
+
const list = Array.isArray(value) ? value : def.default ? [def.default] : [];
|
|
109
|
+
return list
|
|
110
|
+
.map((slug) => (typeof slug === 'string' ? ctx.menus.get(slug) : undefined))
|
|
111
|
+
.filter((menu) => menu !== undefined);
|
|
112
|
+
}
|
|
113
|
+
const slug = def.optional
|
|
114
|
+
? toggleOn(value) && typeof value.value === 'string'
|
|
115
|
+
? value.value
|
|
116
|
+
: null
|
|
117
|
+
: typeof value === 'string' && value
|
|
118
|
+
? value
|
|
119
|
+
: (def.default ?? null);
|
|
120
|
+
return slug ? (ctx.menus.get(slug) ?? null) : null;
|
|
121
|
+
}
|
|
122
|
+
case 'link': {
|
|
123
|
+
if (def.optional && !toggleOn(value))
|
|
124
|
+
return null;
|
|
125
|
+
if (!isRecord(value) || typeof value.url !== 'string' || value.url === '')
|
|
126
|
+
return null;
|
|
127
|
+
return { label: typeof value.label === 'string' ? value.label : '', url: value.url };
|
|
128
|
+
}
|
|
129
|
+
case 'text': {
|
|
130
|
+
if (def.optional) {
|
|
131
|
+
return toggleOn(value) && typeof value.value === 'string'
|
|
132
|
+
? fillTokens(value.value, def, ctx.now)
|
|
133
|
+
: null;
|
|
134
|
+
}
|
|
135
|
+
return fillTokens(typeof value === 'string' ? value : '', def, ctx.now);
|
|
136
|
+
}
|
|
137
|
+
case 'textarea':
|
|
138
|
+
return typeof value === 'string' ? value : '';
|
|
139
|
+
case 'select':
|
|
140
|
+
return typeof value === 'string' ? value : (def.default ?? def.options[0] ?? '');
|
|
141
|
+
case 'boolean':
|
|
142
|
+
return typeof value === 'boolean' ? value : (def.default ?? false);
|
|
143
|
+
case 'social':
|
|
144
|
+
return Array.isArray(value) ? value : [];
|
|
145
|
+
default:
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** A region as the site receives it, every field filled in, in schema order. */
|
|
150
|
+
export function publicRegion(schema, region, ctx) {
|
|
151
|
+
const fields = {};
|
|
152
|
+
for (const [key, def] of Object.entries(schema.fields)) {
|
|
153
|
+
fields[key] = publicField(def, ownValue(region.values, key), ctx);
|
|
154
|
+
}
|
|
155
|
+
return { variant: region.variant, fields };
|
|
156
|
+
}
|
|
157
|
+
/** Weak ETag over the response body, so an unchanged chrome answers 304. */
|
|
158
|
+
function chromeEtag(body) {
|
|
159
|
+
const hash = createHash('sha256').update(JSON.stringify(body)).digest('hex').slice(0, 20);
|
|
160
|
+
return `W/"chrome-${hash}"`;
|
|
161
|
+
}
|
|
162
|
+
export function withEtag(body) {
|
|
163
|
+
return { ...body, etag: chromeEtag(body) };
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/chrome/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tell the site its chrome changed, after the write has committed: the signed
|
|
3
|
+
* `chrome.updated` webhook (to the Developer tab's revalidate URL and any other
|
|
4
|
+
* endpoint subscribed to it) and the `prenta:chrome` cache tag. Chrome is on
|
|
5
|
+
* every page, so the wholesale `prenta` tag goes too, as for a global write.
|
|
6
|
+
* Never throws: the write already succeeded.
|
|
7
|
+
*/
|
|
8
|
+
export declare function revalidateChrome(region: string): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=revalidate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revalidate.d.ts","sourceRoot":"","sources":["../../src/chrome/revalidate.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCpE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PRENTA_CHROME_TAG, PRENTA_TAG_ROOT } from '../cache/http.js';
|
|
2
|
+
import { getPrentaConfig } from '../config/runtime.js';
|
|
3
|
+
import { createLogger } from '../diagnostics/logger.js';
|
|
4
|
+
const logger = createLogger('chrome');
|
|
5
|
+
/**
|
|
6
|
+
* Tell the site its chrome changed, after the write has committed: the signed
|
|
7
|
+
* `chrome.updated` webhook (to the Developer tab's revalidate URL and any other
|
|
8
|
+
* endpoint subscribed to it) and the `prenta:chrome` cache tag. Chrome is on
|
|
9
|
+
* every page, so the wholesale `prenta` tag goes too, as for a global write.
|
|
10
|
+
* Never throws: the write already succeeded.
|
|
11
|
+
*/
|
|
12
|
+
export async function revalidateChrome(region) {
|
|
13
|
+
const tags = [PRENTA_TAG_ROOT, PRENTA_CHROME_TAG];
|
|
14
|
+
const config = getPrentaConfig();
|
|
15
|
+
const adapter = config?.platform?.cache;
|
|
16
|
+
await Promise.all([
|
|
17
|
+
...tags.map(async (tag) => {
|
|
18
|
+
try {
|
|
19
|
+
await adapter?.invalidateTag(tag);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
logger.error('platform.cache invalidateTag failed, chrome may be stale until TTL', {
|
|
23
|
+
error: err instanceof Error ? err.message : String(err),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}),
|
|
27
|
+
(async () => {
|
|
28
|
+
try {
|
|
29
|
+
await config?.cache?.onInvalidate?.(tags);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.error('cache.onInvalidate failed, chrome may be stale until TTL', {
|
|
33
|
+
error: err instanceof Error ? err.message : String(err),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
})(),
|
|
37
|
+
(async () => {
|
|
38
|
+
try {
|
|
39
|
+
const { dispatch } = await import('../webhooks/index.js');
|
|
40
|
+
await dispatch('chrome.updated', { region });
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
logger.error('chrome.updated webhook dispatch failed', {
|
|
44
|
+
region,
|
|
45
|
+
error: err instanceof Error ? err.message : String(err),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
})(),
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=revalidate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revalidate.js","sourceRoot":"","sources":["../../src/chrome/revalidate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAc;IACnD,MAAM,IAAI,GAAG,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;IAChC,MAAM,OAAO,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAA;IACvC,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACxB,IAAI,CAAC;gBACH,MAAM,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,oEAAoE,EAAE;oBACjF,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC;QACF,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,IAAI,CAAC,CAAA;YAC3C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,0DAA0D,EAAE;oBACvE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,EAAE;QACJ,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAA;gBACzD,MAAM,QAAQ,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE;oBACrD,MAAM;oBACN,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,EAAE;KACL,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site chrome endpoints (DATA_CONTRACTS §2). Admin endpoints live at
|
|
3
|
+
* `/chrome/*`; the site reads `/public/chrome?path=`.
|
|
4
|
+
*
|
|
5
|
+
* Access: anyone signed in may read; saving values, the announcement or
|
|
6
|
+
* "Remove now" needs a role that can publish (a save goes live at once);
|
|
7
|
+
* pushing the schema and the Developer tab's settings need an admin. API keys
|
|
8
|
+
* also need the `chrome` global scope (or admin scope), and for a write the
|
|
9
|
+
* action it takes (`update` or `create`; `delete` for "Remove now"), so a
|
|
10
|
+
* read-only key can't save.
|
|
11
|
+
*/
|
|
12
|
+
import type { ApiRouter } from '../api/router.js';
|
|
13
|
+
export declare function registerChromeRoutes(router: ApiRouter): void;
|
|
14
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/chrome/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AA8GjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgO5D"}
|