@heyo-sh/heyo-cms 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +44 -2
- package/dist/access/index.d.ts +9 -0
- package/dist/access/index.d.ts.map +1 -0
- package/dist/access/permissions.d.ts +54 -0
- package/dist/access/permissions.d.ts.map +1 -0
- package/dist/adapters/astro.d.ts +45 -0
- package/dist/adapters/astro.d.ts.map +1 -0
- package/dist/adapters/astro.js +1 -0
- package/dist/adapters/deliver.d.ts +26 -0
- package/dist/adapters/deliver.d.ts.map +1 -0
- package/dist/adapters/next.d.ts +45 -0
- package/dist/adapters/next.d.ts.map +1 -0
- package/dist/adapters/next.js +1 -0
- package/dist/adapters/nuxt.d.ts +51 -0
- package/dist/adapters/nuxt.d.ts.map +1 -0
- package/dist/adapters/nuxt.js +1 -0
- package/dist/adapters/react-router.d.ts +36 -0
- package/dist/adapters/react-router.d.ts.map +1 -0
- package/dist/adapters/react-router.js +1 -0
- package/dist/adapters/sveltekit.d.ts +41 -0
- package/dist/adapters/sveltekit.d.ts.map +1 -0
- package/dist/adapters/sveltekit.js +1 -0
- package/dist/ai/assistant/context.d.ts +64 -0
- package/dist/ai/assistant/context.d.ts.map +1 -0
- package/dist/ai/assistant/limits.d.ts +10 -0
- package/dist/ai/assistant/limits.d.ts.map +1 -0
- package/dist/ai/assistant/plans.d.ts +83 -0
- package/dist/ai/assistant/plans.d.ts.map +1 -0
- package/dist/ai/assistant/prompt.d.ts +22 -0
- package/dist/ai/assistant/prompt.d.ts.map +1 -0
- package/dist/ai/assistant/run.d.ts +59 -0
- package/dist/ai/assistant/run.d.ts.map +1 -0
- package/dist/ai/assistant/runtime.d.ts +35 -0
- package/dist/ai/assistant/runtime.d.ts.map +1 -0
- package/dist/ai/assistant/schema.d.ts +66 -0
- package/dist/ai/assistant/schema.d.ts.map +1 -0
- package/dist/ai/assistant/tools.d.ts +41 -0
- package/dist/ai/assistant/tools.d.ts.map +1 -0
- package/dist/ai/assistant/values.d.ts +33 -0
- package/dist/ai/assistant/values.d.ts.map +1 -0
- package/dist/ai/crypto.d.ts +12 -0
- package/dist/ai/crypto.d.ts.map +1 -0
- package/dist/ai/index.d.ts +19 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/pi.d.ts +89 -0
- package/dist/ai/pi.d.ts.map +1 -0
- package/dist/ai/registry.d.ts +66 -0
- package/dist/ai/registry.d.ts.map +1 -0
- package/dist/ai/service.d.ts +31 -0
- package/dist/ai/service.d.ts.map +1 -0
- package/dist/ai/variant-translation.d.ts +6 -0
- package/dist/ai/variant-translation.d.ts.map +1 -0
- package/dist/ai.d.ts +12 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +1 -0
- package/dist/auth/config.d.ts +65 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/crypto.d.ts +44 -0
- package/dist/auth/crypto.d.ts.map +1 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/oauth.d.ts +93 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/service.d.ts +38 -0
- package/dist/auth/service.d.ts.map +1 -0
- package/dist/auth/totp.d.ts +34 -0
- package/dist/auth/totp.d.ts.map +1 -0
- package/dist/auth.d.ts +9 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +30 -0
- package/dist/client/index.d.ts +51 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/types.d.ts +363 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client.d.ts +46 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +1 -0
- package/dist/content/export.d.ts +28 -0
- package/dist/content/export.d.ts.map +1 -0
- package/dist/content/import.d.ts +65 -0
- package/dist/content/import.d.ts.map +1 -0
- package/dist/content/records.d.ts +73 -0
- package/dist/content/records.d.ts.map +1 -0
- package/dist/content.d.ts +12 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +1 -0
- package/dist/db/d1.d.ts +29 -0
- package/dist/db/d1.d.ts.map +1 -0
- package/dist/db/d1.js +1 -0
- package/dist/db/mongodb.d.ts +128 -0
- package/dist/db/mongodb.d.ts.map +1 -0
- package/dist/db/mongodb.js +2 -0
- package/dist/db/postgres.d.ts +37 -0
- package/dist/db/postgres.d.ts.map +1 -0
- package/dist/db/postgres.js +1 -0
- package/dist/db/sql/adapter.d.ts +57 -0
- package/dist/db/sql/adapter.d.ts.map +1 -0
- package/dist/db/sql/compile.d.ts +50 -0
- package/dist/db/sql/compile.d.ts.map +1 -0
- package/dist/db/sql/ddl.d.ts +34 -0
- package/dist/db/sql/ddl.d.ts.map +1 -0
- package/dist/db/sql/dialect.d.ts +37 -0
- package/dist/db/sql/dialect.d.ts.map +1 -0
- package/dist/db/sql/driver.d.ts +34 -0
- package/dist/db/sql/driver.d.ts.map +1 -0
- package/dist/db/sql/introspect.d.ts +15 -0
- package/dist/db/sql/introspect.d.ts.map +1 -0
- package/dist/db/sqlite.d.ts +50 -0
- package/dist/db/sqlite.d.ts.map +1 -0
- package/dist/db/sqlite.js +1 -0
- package/dist/defaults.d.ts +5 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/duration.d.ts +12 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/editor/builtin.d.ts +45 -0
- package/dist/editor/builtin.d.ts.map +1 -0
- package/dist/editor/index.d.ts +14 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/markdown.d.ts +19 -0
- package/dist/editor/markdown.d.ts.map +1 -0
- package/dist/editor/registry.d.ts +30 -0
- package/dist/editor/registry.d.ts.map +1 -0
- package/dist/editor/serialize.d.ts +41 -0
- package/dist/editor/serialize.d.ts.map +1 -0
- package/dist/editor.d.ts +10 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +1 -0
- package/dist/engine/access.d.ts +33 -0
- package/dist/engine/access.d.ts.map +1 -0
- package/dist/engine/activity.d.ts +16 -0
- package/dist/engine/activity.d.ts.map +1 -0
- package/dist/engine/cursor.d.ts +19 -0
- package/dist/engine/cursor.d.ts.map +1 -0
- package/dist/engine/documents.d.ts +81 -0
- package/dist/engine/documents.d.ts.map +1 -0
- package/dist/engine/engine.d.ts +295 -0
- package/dist/engine/engine.d.ts.map +1 -0
- package/dist/engine/field-access.d.ts +21 -0
- package/dist/engine/field-access.d.ts.map +1 -0
- package/dist/engine/hooks.d.ts +58 -0
- package/dist/engine/hooks.d.ts.map +1 -0
- package/dist/engine/index.d.ts +20 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/jobs.d.ts +63 -0
- package/dist/engine/jobs.d.ts.map +1 -0
- package/dist/engine/locales.d.ts +40 -0
- package/dist/engine/locales.d.ts.map +1 -0
- package/dist/engine/outbox.d.ts +81 -0
- package/dist/engine/outbox.d.ts.map +1 -0
- package/dist/engine/relations.d.ts +60 -0
- package/dist/engine/relations.d.ts.map +1 -0
- package/dist/engine/scoped-db.d.ts +13 -0
- package/dist/engine/scoped-db.d.ts.map +1 -0
- package/dist/engine/slugs.d.ts +124 -0
- package/dist/engine/slugs.d.ts.map +1 -0
- package/dist/engine/trash.d.ts +25 -0
- package/dist/engine/trash.d.ts.map +1 -0
- package/dist/errors.d.ts +42 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/fields/builtin.d.ts +169 -0
- package/dist/fields/builtin.d.ts.map +1 -0
- package/dist/fields/index.d.ts +3 -0
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/registry.d.ts +35 -0
- package/dist/fields/registry.d.ts.map +1 -0
- package/dist/fields.d.ts +9 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +1 -0
- package/dist/http/guard.d.ts +45 -0
- package/dist/http/guard.d.ts.map +1 -0
- package/dist/http/handler.d.ts +31 -0
- package/dist/http/handler.d.ts.map +1 -0
- package/dist/http/index.d.ts +13 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/openapi.d.ts +5 -0
- package/dist/http/openapi.d.ts.map +1 -0
- package/dist/http/params.d.ts +32 -0
- package/dist/http/params.d.ts.map +1 -0
- package/dist/http/request-db.d.ts +19 -0
- package/dist/http/request-db.d.ts.map +1 -0
- package/dist/http/respond.d.ts +48 -0
- package/dist/http/respond.d.ts.map +1 -0
- package/dist/http/rich-text.d.ts +41 -0
- package/dist/http/rich-text.d.ts.map +1 -0
- package/dist/http/router.d.ts +55 -0
- package/dist/http/router.d.ts.map +1 -0
- package/dist/http/routes/access.d.ts +13 -0
- package/dist/http/routes/access.d.ts.map +1 -0
- package/dist/http/routes/admin.d.ts +28 -0
- package/dist/http/routes/admin.d.ts.map +1 -0
- package/dist/http/routes/ai.d.ts +26 -0
- package/dist/http/routes/ai.d.ts.map +1 -0
- package/dist/http/routes/auth.d.ts +13 -0
- package/dist/http/routes/auth.d.ts.map +1 -0
- package/dist/http/routes/documents.d.ts +24 -0
- package/dist/http/routes/documents.d.ts.map +1 -0
- package/dist/http/routes/generate.d.ts +5 -0
- package/dist/http/routes/generate.d.ts.map +1 -0
- package/dist/http/routes/media.d.ts +58 -0
- package/dist/http/routes/media.d.ts.map +1 -0
- package/dist/http/routes/panel.d.ts +20 -0
- package/dist/http/routes/panel.d.ts.map +1 -0
- package/dist/http/routes/system.d.ts +25 -0
- package/dist/http/routes/system.d.ts.map +1 -0
- package/dist/http/routes/webhooks.d.ts +17 -0
- package/dist/http/routes/webhooks.d.ts.map +1 -0
- package/dist/http/spec.d.ts +28 -0
- package/dist/http/spec.d.ts.map +1 -0
- package/dist/http.d.ts +17 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +1 -0
- package/dist/i18n/index.d.ts +12 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/names.d.ts +25 -0
- package/dist/i18n/names.d.ts.map +1 -0
- package/dist/ids.d.ts +28 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/index-2ddk43me.js +2 -0
- package/dist/index-2prbs05k.js +2 -0
- package/dist/index-385ggnge.js +2 -0
- package/dist/index-466cwb0b.js +2 -0
- package/dist/index-4qrep5f0.js +26 -0
- package/dist/index-67e458ws.js +2 -0
- package/dist/index-6m1kjq9g.js +2 -0
- package/dist/index-6w10rch0.js +3 -0
- package/dist/index-761dec5z.js +2 -0
- package/dist/index-8nzmqy0f.js +2 -0
- package/dist/index-8x2em6c8.js +14 -0
- package/dist/index-91fa1gzf.js +2 -0
- package/dist/index-9g2n7xa6.js +2 -0
- package/dist/index-a8jcwqsf.js +2 -0
- package/dist/index-abfzb1ve.js +2 -0
- package/dist/index-cv0hpz3d.js +2 -0
- package/dist/index-ebtj6ebd.js +0 -0
- package/dist/index-g041kfa5.js +18 -0
- package/dist/index-g4crf47y.js +0 -0
- package/dist/index-hbx67b20.js +7 -0
- package/dist/index-hpast878.js +40 -0
- package/dist/index-kc1j3h6z.js +2 -0
- package/dist/index-p2cqsmvw.js +2 -0
- package/dist/index-rg9tpg3p.js +5 -0
- package/dist/index-rw0hze6x.js +2 -0
- package/dist/index-s9x07zb3.js +2 -0
- package/dist/index-sgdnp83t.js +2 -0
- package/dist/index-szaq03qq.js +2 -0
- package/dist/index-vkwzdfte.js +5 -0
- package/dist/index-vzhxn50e.js +2 -0
- package/dist/index-x72d1hzh.js +2 -0
- package/dist/index-y8kzzn94.js +2 -0
- package/dist/index-ypcmns0v.js +2 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/jobs/runner.d.ts +77 -0
- package/dist/jobs/runner.d.ts.map +1 -0
- package/dist/jobs.d.ts +11 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +1 -0
- package/dist/media/cloudflare.d.ts +58 -0
- package/dist/media/cloudflare.d.ts.map +1 -0
- package/dist/media/document.d.ts +29 -0
- package/dist/media/document.d.ts.map +1 -0
- package/dist/media/gc.d.ts +46 -0
- package/dist/media/gc.d.ts.map +1 -0
- package/dist/media/index.d.ts +20 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/pipeline.d.ts +55 -0
- package/dist/media/pipeline.d.ts.map +1 -0
- package/dist/media/probe.d.ts +6 -0
- package/dist/media/probe.d.ts.map +1 -0
- package/dist/media/service.d.ts +26 -0
- package/dist/media/service.d.ts.map +1 -0
- package/dist/media/sharp.d.ts +28 -0
- package/dist/media/sharp.d.ts.map +1 -0
- package/dist/media/strip.d.ts +16 -0
- package/dist/media/strip.d.ts.map +1 -0
- package/dist/media/urls.d.ts +77 -0
- package/dist/media/urls.d.ts.map +1 -0
- package/dist/media/usages.d.ts +77 -0
- package/dist/media/usages.d.ts.map +1 -0
- package/dist/media/variants.d.ts +61 -0
- package/dist/media/variants.d.ts.map +1 -0
- package/dist/migrations.d.ts +115 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +1 -0
- package/dist/panel.d.ts +31 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/plugins/indexnow.d.ts +82 -0
- package/dist/plugins/indexnow.d.ts.map +1 -0
- package/dist/plugins.d.ts +9 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +1 -0
- package/dist/query.d.ts +40 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +1 -0
- package/dist/run-bjge3v8e.js +6 -0
- package/dist/schema/describe.d.ts +19 -0
- package/dist/schema/describe.d.ts.map +1 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/plan.d.ts +20 -0
- package/dist/schema/plan.d.ts.map +1 -0
- package/dist/schema/snapshot.d.ts +24 -0
- package/dist/schema/snapshot.d.ts.map +1 -0
- package/dist/schema/system.d.ts +31 -0
- package/dist/schema/system.d.ts.map +1 -0
- package/dist/schema.d.ts +7 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +1 -0
- package/dist/slugify.d.ts +31 -0
- package/dist/slugify.d.ts.map +1 -0
- package/dist/storage/bytes.d.ts +17 -0
- package/dist/storage/bytes.d.ts.map +1 -0
- package/dist/storage/http.d.ts +43 -0
- package/dist/storage/http.d.ts.map +1 -0
- package/dist/storage/local.d.ts +31 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/providers.d.ts +95 -0
- package/dist/storage/providers.d.ts.map +1 -0
- package/dist/storage/sign.d.ts +53 -0
- package/dist/storage/sign.d.ts.map +1 -0
- package/dist/strings.d.ts +13 -0
- package/dist/strings.d.ts.map +1 -0
- package/dist/telemetry.d.ts +137 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +1 -0
- package/dist/types/activity.d.ts +68 -0
- package/dist/types/activity.d.ts.map +1 -0
- package/dist/types/actor.d.ts +26 -0
- package/dist/types/actor.d.ts.map +1 -0
- package/dist/types/ai.d.ts +357 -0
- package/dist/types/ai.d.ts.map +1 -0
- package/dist/types/api.d.ts +268 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/auth.d.ts +310 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/config.d.ts +647 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/database.d.ts +75 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/editor.d.ts +166 -0
- package/dist/types/editor.d.ts.map +1 -0
- package/dist/types/events.d.ts +72 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/fields.d.ts +142 -0
- package/dist/types/fields.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +142 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/instance.d.ts +263 -0
- package/dist/types/instance.d.ts.map +1 -0
- package/dist/types/jobs.d.ts +78 -0
- package/dist/types/jobs.d.ts.map +1 -0
- package/dist/types/json.d.ts +24 -0
- package/dist/types/json.d.ts.map +1 -0
- package/dist/types/locales.d.ts +30 -0
- package/dist/types/locales.d.ts.map +1 -0
- package/dist/types/media.d.ts +342 -0
- package/dist/types/media.d.ts.map +1 -0
- package/dist/types/panel.d.ts +249 -0
- package/dist/types/panel.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +194 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/query.d.ts +101 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/schema.d.ts +203 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/storage.d.ts +61 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/telemetry.d.ts +14 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/trash.d.ts +42 -0
- package/dist/types/trash.d.ts.map +1 -0
- package/dist/types/webhooks.d.ts +133 -0
- package/dist/types/webhooks.d.ts.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/uploads.d.ts +22 -0
- package/dist/uploads.d.ts.map +1 -0
- package/dist/uploads.js +9 -0
- package/dist/webhooks/index.d.ts +10 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/job.d.ts +17 -0
- package/dist/webhooks/job.d.ts.map +1 -0
- package/dist/webhooks/service.d.ts +53 -0
- package/dist/webhooks/service.d.ts.map +1 -0
- package/dist/webhooks/sign.d.ts +26 -0
- package/dist/webhooks/sign.d.ts.map +1 -0
- package/dist/webhooks.d.ts +10 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +1 -0
- package/package.json +187 -4
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import type { CollectionApi, GlobalApi } from "../types/api";
|
|
2
|
+
import type { ResolvedCmsConfig, ResolvedCollection } from "../types/config";
|
|
3
|
+
import type { DatabaseAdapter } from "../types/database";
|
|
4
|
+
import type { CmsInstance } from "../types/instance";
|
|
5
|
+
import type { JsonObject } from "../types/json";
|
|
6
|
+
import type { Tx } from "../types/query";
|
|
7
|
+
import type { CmsTrash } from "../types/trash";
|
|
8
|
+
import { JobRunner } from "./jobs";
|
|
9
|
+
import { type BufferedEvent, type EventDispatch, type OutboxEntryMeta } from "./outbox";
|
|
10
|
+
export interface EngineOptions {
|
|
11
|
+
config: ResolvedCmsConfig;
|
|
12
|
+
/** Resolved lazily: a D1 binding only exists inside a request. */
|
|
13
|
+
database: () => Promise<DatabaseAdapter>;
|
|
14
|
+
dispatch: EventDispatch;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* What one write means.
|
|
18
|
+
*
|
|
19
|
+
* `operation` in the hook contract is CRUD and stays CRUD (section 5); this
|
|
20
|
+
* is the finer question the engine has to answer anyway — which event to
|
|
21
|
+
* emit, what the activity log should say, whether the `delete` hooks have
|
|
22
|
+
* already run. Keeping the two apart is what lets the trash exist without
|
|
23
|
+
* adding a fourth hook family nobody asked for.
|
|
24
|
+
*/
|
|
25
|
+
export type WriteIntent = "create" | "update" | "trash" | "restore" | "purge" | "schedule" | "unschedule";
|
|
26
|
+
/**
|
|
27
|
+
* The engine: one read path, one write path.
|
|
28
|
+
*
|
|
29
|
+
* Every document write in the product — local API, REST, the panel, a job,
|
|
30
|
+
* the scheduler — goes through `runWrite`. That is a deliberate constraint
|
|
31
|
+
* rather than tidiness: hooks, the outbox, the activity log and the future
|
|
32
|
+
* versions plugin all attach at one point, and a second write path would be a
|
|
33
|
+
* second place for each of them to be forgotten (stage 3).
|
|
34
|
+
*/
|
|
35
|
+
export declare class CmsEngine {
|
|
36
|
+
private readonly options;
|
|
37
|
+
private cms;
|
|
38
|
+
private readonly pipelines;
|
|
39
|
+
/** Collections and globals by name, for relation targets. */
|
|
40
|
+
private readonly byName;
|
|
41
|
+
/** The same by storage slug: a stored row knows its slug, not its name. */
|
|
42
|
+
private readonly bySlug;
|
|
43
|
+
/**
|
|
44
|
+
* Which collections can point at a file at all.
|
|
45
|
+
*
|
|
46
|
+
* Answered once per collection, because the alternative is three extra
|
|
47
|
+
* queries on every write to a collection that has no images — which is most
|
|
48
|
+
* of them.
|
|
49
|
+
*/
|
|
50
|
+
private readonly media;
|
|
51
|
+
private outbox;
|
|
52
|
+
private delivery;
|
|
53
|
+
constructor(options: EngineOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Hands the engine the instance hooks receive as `ctx.cms`.
|
|
56
|
+
*
|
|
57
|
+
* Separate from the constructor because the two refer to each other: the
|
|
58
|
+
* instance exposes `api`, and `api` has to be able to call back into the
|
|
59
|
+
* instance with access control enforced.
|
|
60
|
+
*/
|
|
61
|
+
bind(cms: CmsInstance): void;
|
|
62
|
+
/** `cms.api`, built once: one entry per declared collection. */
|
|
63
|
+
buildApi(): Record<string, CollectionApi<JsonObject>>;
|
|
64
|
+
/** `cms.globals`: the same machinery, one row, no `find` and no `create`. */
|
|
65
|
+
buildGlobals(): Record<string, GlobalApi<JsonObject>>;
|
|
66
|
+
/** `cms.trash`: deleted documents across every collection at once. */
|
|
67
|
+
buildTrash(): CmsTrash;
|
|
68
|
+
/** `cms.jobs`: the sweeps. Returned concrete so media can register its own. */
|
|
69
|
+
buildJobs(): JobRunner;
|
|
70
|
+
/**
|
|
71
|
+
* Delivers everything the outbox owes.
|
|
72
|
+
*
|
|
73
|
+
* A commit already schedules a delivery in the background; this is how a
|
|
74
|
+
* caller waits for it — a test, a CLI, or a serverless runtime that is
|
|
75
|
+
* about to freeze the process. Returns what this call delivered, which may
|
|
76
|
+
* be zero because the background pass got there first.
|
|
77
|
+
*/
|
|
78
|
+
drainEvents(limit?: number): Promise<number>;
|
|
79
|
+
/** Waits for in-flight deliveries. Called by `cms.close()`. */
|
|
80
|
+
settle(): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Writes events for an operation that is not a document write.
|
|
83
|
+
*
|
|
84
|
+
* Auth is the first caller: an invitation or a role change has to reach a
|
|
85
|
+
* webhook the same way a document change does — inside the transaction that
|
|
86
|
+
* caused it, delivered after the commit — and giving it a second mechanism
|
|
87
|
+
* would give it a second set of failure modes (section 5).
|
|
88
|
+
*/
|
|
89
|
+
appendEvents(tx: Tx, events: BufferedEvent[], meta: OutboxEntryMeta): Promise<void>;
|
|
90
|
+
/** Delivers what the last committed transaction queued, in the background. */
|
|
91
|
+
deliverSoon(): void;
|
|
92
|
+
private collectionApi;
|
|
93
|
+
/**
|
|
94
|
+
* The slug field a slug operation is about: the one named, or the
|
|
95
|
+
* collection's first — with `history`, when the operation needs one.
|
|
96
|
+
*/
|
|
97
|
+
private slugField;
|
|
98
|
+
private resolveSlug;
|
|
99
|
+
private previousSlugs;
|
|
100
|
+
/**
|
|
101
|
+
* Adds or removes one previous address, under the rules of an update to
|
|
102
|
+
* the slug field: the actor must be allowed to update the document and to
|
|
103
|
+
* write that field.
|
|
104
|
+
*/
|
|
105
|
+
private changePreviousSlug;
|
|
106
|
+
private find;
|
|
107
|
+
private findOne;
|
|
108
|
+
private findById;
|
|
109
|
+
private count;
|
|
110
|
+
private create;
|
|
111
|
+
private update;
|
|
112
|
+
/**
|
|
113
|
+
* The delete an editor performs.
|
|
114
|
+
*
|
|
115
|
+
* With the trash on it is a soft delete and the row keeps serving every
|
|
116
|
+
* query that asks for `includeTrashed`; with it off, or with
|
|
117
|
+
* `permanent: true`, the row goes. Either way the `delete` hooks run here
|
|
118
|
+
* and only here: the document is leaving the live set, which is the moment
|
|
119
|
+
* a hook was written for. A later purge does not run them again, because a
|
|
120
|
+
* hook that decrements a counter must not decrement it twice for one
|
|
121
|
+
* document.
|
|
122
|
+
*/
|
|
123
|
+
private remove;
|
|
124
|
+
private restore;
|
|
125
|
+
/**
|
|
126
|
+
* The permanent delete.
|
|
127
|
+
*
|
|
128
|
+
* Also the only operation that cleans up what pointed at the document:
|
|
129
|
+
* media usages survive the trash on purpose — an image used by a document
|
|
130
|
+
* an editor may still restore is not unused — so this is where they stop
|
|
131
|
+
* (section 6).
|
|
132
|
+
*/
|
|
133
|
+
private purge;
|
|
134
|
+
/**
|
|
135
|
+
* Records a change to apply later.
|
|
136
|
+
*
|
|
137
|
+
* The patch is checked now — access, field-level write access, validation —
|
|
138
|
+
* and applied later as an ordinary update, so the question "may this person
|
|
139
|
+
* schedule a publication" is answered by the same rules that answer "may
|
|
140
|
+
* this person publish". The alternative, checking only at apply time, would
|
|
141
|
+
* accept a schedule in the panel and fail silently on a Friday night.
|
|
142
|
+
*/
|
|
143
|
+
private schedule;
|
|
144
|
+
private unschedule;
|
|
145
|
+
private globalApi;
|
|
146
|
+
/**
|
|
147
|
+
* A global that nobody has saved yet reads as its defaults.
|
|
148
|
+
*
|
|
149
|
+
* No row is written: a read that writes cannot run on a replica, cannot run
|
|
150
|
+
* in a Worker that only has a read binding, and turns an anonymous page view
|
|
151
|
+
* into a database mutation.
|
|
152
|
+
*/
|
|
153
|
+
private globalGet;
|
|
154
|
+
/**
|
|
155
|
+
* Makes sure the singleton has a row, and reports its id.
|
|
156
|
+
*
|
|
157
|
+
* The id is derived from the slug rather than generated, which is what makes
|
|
158
|
+
* this safe to call concurrently: two first saves race to insert the same
|
|
159
|
+
* primary key, one of them loses, and losing means the row it wanted is
|
|
160
|
+
* already there.
|
|
161
|
+
*/
|
|
162
|
+
private ensureGlobalRow;
|
|
163
|
+
/**
|
|
164
|
+
* The defaults row: what a global is before anybody saves it.
|
|
165
|
+
*
|
|
166
|
+
* `created` is `null` for the copy `get()` invents and a date for the copy
|
|
167
|
+
* that is actually inserted. A global nobody has saved has no creation time,
|
|
168
|
+
* and inventing one would make "has this ever been configured" unanswerable.
|
|
169
|
+
*/
|
|
170
|
+
private emptyGlobalRow;
|
|
171
|
+
/**
|
|
172
|
+
* Applies one due scheduled change, as an ordinary update.
|
|
173
|
+
*
|
|
174
|
+
* Claim first, then write. The claim is a conditional update — the same
|
|
175
|
+
* portable trick the outbox uses — so two overlapping cron invocations
|
|
176
|
+
* cannot both apply the same patch, on any of the three engines and without
|
|
177
|
+
* a lock.
|
|
178
|
+
*/
|
|
179
|
+
private applyScheduled;
|
|
180
|
+
/** Purges one expired trash entry, as the system rather than as a person. */
|
|
181
|
+
private purgeExpired;
|
|
182
|
+
private clearSchedule;
|
|
183
|
+
/**
|
|
184
|
+
* Records a failed job item and tells the world about it.
|
|
185
|
+
*
|
|
186
|
+
* In the `jobs` table rather than only in a log: `job.failed` is in the
|
|
187
|
+
* event catalogue (section 7) because an operator has to be able to be
|
|
188
|
+
* paged for it, and a payload that only exists in stdout cannot be retried.
|
|
189
|
+
*/
|
|
190
|
+
private recordFailure;
|
|
191
|
+
/**
|
|
192
|
+
* The one place a document is written.
|
|
193
|
+
*
|
|
194
|
+
* Transaction, hooks, events, activity — in that order, every time. The
|
|
195
|
+
* operation-specific part is the `step` callback and nothing else, which is
|
|
196
|
+
* what makes the later versions plugin a single attachment point rather
|
|
197
|
+
* than three (stage 3, section 4).
|
|
198
|
+
*/
|
|
199
|
+
private runWrite;
|
|
200
|
+
/**
|
|
201
|
+
* The answer a repeated write already has.
|
|
202
|
+
*
|
|
203
|
+
* Only consulted when the caller supplied a key, so an ordinary save pays
|
|
204
|
+
* nothing for it. The stored document is returned verbatim: re-reading the
|
|
205
|
+
* row would describe the world now rather than what this call did, and a
|
|
206
|
+
* retry that reports somebody else's later edit as its own result is worse
|
|
207
|
+
* than no idempotency at all.
|
|
208
|
+
*/
|
|
209
|
+
private replay;
|
|
210
|
+
private recordIdempotency;
|
|
211
|
+
private runAfter;
|
|
212
|
+
/**
|
|
213
|
+
* The events the engine itself owes, in the order a consumer expects them.
|
|
214
|
+
*
|
|
215
|
+
* `document.field.changed` is one event per field that actually changed,
|
|
216
|
+
* which is what makes "tell me when `status` becomes `published`" a
|
|
217
|
+
* subscription rather than a diff the consumer has to compute (section 7).
|
|
218
|
+
*/
|
|
219
|
+
private emitDocumentEvents;
|
|
220
|
+
/**
|
|
221
|
+
* Keeps `media_usages` in step with what the document now contains.
|
|
222
|
+
*
|
|
223
|
+
* This is the whole of the media lifecycle's accounting. Nothing counts
|
|
224
|
+
* references at read time or at delete time; the count is maintained here,
|
|
225
|
+
* once, and `media-gc` only ever acts on what it says.
|
|
226
|
+
*/
|
|
227
|
+
private syncMedia;
|
|
228
|
+
/**
|
|
229
|
+
* Keeps `slug_history` in step with the write, in its transaction: a
|
|
230
|
+
* rolled back rename must not leave its old address behind as a redirect.
|
|
231
|
+
*/
|
|
232
|
+
private syncSlugs;
|
|
233
|
+
private keepsSlugHistory;
|
|
234
|
+
private referencesMedia;
|
|
235
|
+
/**
|
|
236
|
+
* The activity log, written by the engine inside the transaction.
|
|
237
|
+
*
|
|
238
|
+
* Built in rather than a plugin (section 11): an audit trail that can be
|
|
239
|
+
* switched off, or that commits separately from the change it describes, is
|
|
240
|
+
* not an audit trail.
|
|
241
|
+
*/
|
|
242
|
+
private writeActivity;
|
|
243
|
+
/** Collection, trash and access filters, combined the only legal way. */
|
|
244
|
+
private scope;
|
|
245
|
+
private load;
|
|
246
|
+
/**
|
|
247
|
+
* Writes system columns on one row and reports the row as it now stands.
|
|
248
|
+
*
|
|
249
|
+
* Also the one place `revision` moves. Every write that reaches here changed
|
|
250
|
+
* the row, so every write bumps it — there is no "minor" update that a
|
|
251
|
+
* concurrent editor would not want to know about, and a token that only
|
|
252
|
+
* sometimes advances is a token nobody can rely on.
|
|
253
|
+
*
|
|
254
|
+
* `expected` turns the write into a compare-and-set. The comparison is in
|
|
255
|
+
* the `WHERE` clause rather than in a read before it: two requests that both
|
|
256
|
+
* read revision 17 must not both find it acceptable, and only the database
|
|
257
|
+
* can decide which of them wins.
|
|
258
|
+
*/
|
|
259
|
+
private patch;
|
|
260
|
+
private assertAllowed;
|
|
261
|
+
private requireCollection;
|
|
262
|
+
/** When a document deleted now should be purged, or `null` if never. */
|
|
263
|
+
private purgeAt;
|
|
264
|
+
private expand;
|
|
265
|
+
/**
|
|
266
|
+
* Drops the fields this actor may not read.
|
|
267
|
+
*
|
|
268
|
+
* Skipped entirely when the collection declares no field rules, which is
|
|
269
|
+
* the overwhelmingly common case and the difference between a check and a
|
|
270
|
+
* cost.
|
|
271
|
+
*/
|
|
272
|
+
private redact;
|
|
273
|
+
private pipeline;
|
|
274
|
+
private outboxMeta;
|
|
275
|
+
private outboxWorker;
|
|
276
|
+
/**
|
|
277
|
+
* Delivery after the commit, never during it.
|
|
278
|
+
*
|
|
279
|
+
* Chained rather than fired in parallel so events keep their order, and
|
|
280
|
+
* swallowed because a failed delivery is the outbox's problem — it is
|
|
281
|
+
* recorded, retried, and must not turn a successful write into a thrown
|
|
282
|
+
* error (section 5).
|
|
283
|
+
*/
|
|
284
|
+
private scheduleDelivery;
|
|
285
|
+
private instance;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* A singleton's row id, derived from its slug.
|
|
289
|
+
*
|
|
290
|
+
* Deterministic because it has to be: the row is created on first save, and a
|
|
291
|
+
* generated id would let two concurrent saves produce two rows for a document
|
|
292
|
+
* the configuration says there is exactly one of.
|
|
293
|
+
*/
|
|
294
|
+
export declare function globalRowId(global: ResolvedCollection): string;
|
|
295
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Actor } from "../types/actor";
|
|
2
|
+
import type { ResolvedCollection } from "../types/config";
|
|
3
|
+
import type { JsonObject } from "../types/json";
|
|
4
|
+
export declare function hasFieldAccessRules(collection: ResolvedCollection): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Removes the fields this actor may not read, in place.
|
|
7
|
+
*
|
|
8
|
+
* In place because the caller owns the document: it was just built from a
|
|
9
|
+
* row, and copying every document of every page to delete a key from one of
|
|
10
|
+
* them would be the wrong trade.
|
|
11
|
+
*/
|
|
12
|
+
export declare function applyFieldReadAccess(document: JsonObject, collection: ResolvedCollection, actor: Actor | null, locale: string | null): JsonObject;
|
|
13
|
+
/**
|
|
14
|
+
* Refuses a write that touches a field the actor may not write.
|
|
15
|
+
*
|
|
16
|
+
* Refuses rather than drops: silently ignoring half a form is how an editor
|
|
17
|
+
* ends up believing they published something. The error names the fields, so
|
|
18
|
+
* a panel can mark them.
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertFieldWriteAccess(collection: ResolvedCollection, input: JsonObject, actor: Actor | null, locale: string | null, record?: JsonObject): void;
|
|
21
|
+
//# sourceMappingURL=field-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-access.d.ts","sourceRoot":"","sources":["../../src/engine/field-access.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAiDhD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAG3E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,UAAU,CAuBZ;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,CAAC,EAAE,UAAU,GAClB,IAAI,CAmBN"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ResolvedCmsConfig } from "../types/config";
|
|
2
|
+
import type { CreateHookInput, HookContext, HookResult, MaybePromise, UpdateHookInput, UpdateHookOutput } from "../types/hooks";
|
|
3
|
+
import type { HookPipelineEntry } from "../types/instance";
|
|
4
|
+
import type { JsonObject } from "../types/json";
|
|
5
|
+
/** Where a hook came from and when it runs, carried so `inspect()` can say. */
|
|
6
|
+
interface Registered {
|
|
7
|
+
source: string;
|
|
8
|
+
priority: number;
|
|
9
|
+
}
|
|
10
|
+
export interface BeforeEntry<TInput> extends Registered {
|
|
11
|
+
run: (input: TInput, context: HookContext) => MaybePromise<HookResult<JsonObject>>;
|
|
12
|
+
}
|
|
13
|
+
export interface AfterEntry<TOutput> extends Registered {
|
|
14
|
+
run: (output: TOutput, context: HookContext) => MaybePromise<void>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Every hook that can run on one collection, already in execution order.
|
|
18
|
+
*
|
|
19
|
+
* Built once per collection at start-up rather than looked up per write: the
|
|
20
|
+
* order is a property of the configuration, so computing it on every request
|
|
21
|
+
* would be work that cannot change its own answer.
|
|
22
|
+
*/
|
|
23
|
+
export interface CollectionHookPipeline {
|
|
24
|
+
createBefore: BeforeEntry<CreateHookInput<JsonObject>>[];
|
|
25
|
+
createAfter: AfterEntry<JsonObject>[];
|
|
26
|
+
updateBefore: BeforeEntry<UpdateHookInput<JsonObject>>[];
|
|
27
|
+
updateAfter: AfterEntry<UpdateHookOutput<JsonObject>>[];
|
|
28
|
+
deleteBefore: BeforeEntry<JsonObject>[];
|
|
29
|
+
deleteAfter: AfterEntry<JsonObject>[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Assembles the pipeline for one collection.
|
|
33
|
+
*
|
|
34
|
+
* Plugin hooks run first in `priority` order, the configuration's own hooks
|
|
35
|
+
* always run last. A user who installed a plugin can therefore always have
|
|
36
|
+
* the final word over it, without the plugin having to anticipate that
|
|
37
|
+
* (section 5).
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildHookPipeline(config: ResolvedCmsConfig, collection: string): CollectionHookPipeline;
|
|
40
|
+
/**
|
|
41
|
+
* Runs the `before` chain and reports what the operation should do next.
|
|
42
|
+
*
|
|
43
|
+
* One return contract for every hook, which is the part Payload gets wrong:
|
|
44
|
+
* `undefined` continue, `{ data }` continue with a replacement, `false` stop
|
|
45
|
+
* silently, `throw` stop with a status. `apply` is how a replacement folds
|
|
46
|
+
* back into an operation-shaped input.
|
|
47
|
+
*/
|
|
48
|
+
export declare function runBeforeHooks<TInput>(entries: BeforeEntry<TInput>[], input: TInput, context: HookContext, apply: (input: TInput, data: JsonObject) => TInput): Promise<TInput | false>;
|
|
49
|
+
export declare function runAfterHooks<TOutput>(entries: AfterEntry<TOutput>[], output: TOutput, context: HookContext): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* The pipeline as `cms.inspect()` prints it.
|
|
52
|
+
*
|
|
53
|
+
* Derived from the same builder the engine runs, so the printed order cannot
|
|
54
|
+
* drift from the executed one — which is the entire value of printing it.
|
|
55
|
+
*/
|
|
56
|
+
export declare function hookPipelineEntries(config: ResolvedCmsConfig): HookPipelineEntry[];
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/engine/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAEV,eAAe,EACf,WAAW,EAEX,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,+EAA+E;AAC/E,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW,CAAC,MAAM,CAAE,SAAQ,UAAU;IACrD,GAAG,EAAE,CACH,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,KACjB,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,UAAU,CAAC,OAAO,CAAE,SAAQ,UAAU;IACrD,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CACpE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IACzD,WAAW,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;IACtC,YAAY,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IACzD,WAAW,EAAE,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IACxD,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;IACxC,WAAW,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,MAAM,GACjB,sBAAsB,CA0ExB;AAyCD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,MAAM,EACzC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,EAC9B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,MAAM,GACjD,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAUzB;AAED,wBAAsB,aAAa,CAAC,OAAO,EACzC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,EAC9B,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,GACxB,iBAAiB,EAAE,CAkCrB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine: the local API, the hook pipeline and the transactional outbox.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here is HTTP-aware. The router in stage 7 calls exactly the same
|
|
5
|
+
* functions the local API does, which is the only way `cms.api.posts.find()`
|
|
6
|
+
* and `GET /api/heyo-cms/posts` can be guaranteed to behave identically
|
|
7
|
+
* (section 10).
|
|
8
|
+
*/
|
|
9
|
+
export { CmsEngine, globalRowId, type EngineOptions, type WriteIntent, } from "./engine";
|
|
10
|
+
export { JobRunner, type JobDefinition, type JobHost } from "./jobs";
|
|
11
|
+
export { listTrashed, type ListTrashedOptions } from "./trash";
|
|
12
|
+
export { EventBuffer, Outbox, type EventDispatch } from "./outbox";
|
|
13
|
+
export { buildHookPipeline, hookPipelineEntries, runAfterHooks, runBeforeHooks, type CollectionHookPipeline, } from "./hooks";
|
|
14
|
+
export { localeContext, resolveLocalized, type LocaleContext } from "./locales";
|
|
15
|
+
export { rowToDocument, scheduledPatch, toStoredData, validateFields, type ScheduledPatch, } from "./documents";
|
|
16
|
+
export { applyFieldReadAccess, assertFieldWriteAccess, hasFieldAccessRules, } from "./field-access";
|
|
17
|
+
export { RelationLoader, relationTarget } from "./relations";
|
|
18
|
+
export { scopedDb } from "./scoped-db";
|
|
19
|
+
export { cursorWhere, encodeCursor } from "./cursor";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,KAAK,sBAAsB,GAC5B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,cAAc,EACd,KAAK,cAAc,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ResolvedCmsConfig } from "../types/config";
|
|
2
|
+
import type { DatabaseAdapter } from "../types/database";
|
|
3
|
+
import type { CmsJobs, JobFailure, JobFailureArgs, JobRunArgs, JobRunReport } from "../types/jobs";
|
|
4
|
+
import type { JsonObject } from "../types/json";
|
|
5
|
+
import type { Row } from "../types/query";
|
|
6
|
+
/**
|
|
7
|
+
* What a sweep needs from the engine.
|
|
8
|
+
*
|
|
9
|
+
* Narrow on purpose: a job may ask which rows are due and may ask the engine
|
|
10
|
+
* to act on one of them, and it may not write a document itself. Every write
|
|
11
|
+
* in the product goes through one function (stage 3), and a background worker
|
|
12
|
+
* is exactly the kind of caller that would quietly grow a second one.
|
|
13
|
+
*/
|
|
14
|
+
export interface JobHost {
|
|
15
|
+
config: ResolvedCmsConfig;
|
|
16
|
+
database(): Promise<DatabaseAdapter>;
|
|
17
|
+
applyScheduled(row: Row): Promise<void>;
|
|
18
|
+
purgeExpired(row: Row): Promise<void>;
|
|
19
|
+
recordFailure(type: string, payload: JsonObject, error: unknown): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One sweep.
|
|
23
|
+
*
|
|
24
|
+
* Split into "what is due" and "act on one of them" so the runner owns the
|
|
25
|
+
* batching, the counting and the failure record, and a job only has to know
|
|
26
|
+
* its own question. Exported because `media-gc` is registered through it, and
|
|
27
|
+
* a plugin will eventually register its own the same way.
|
|
28
|
+
*/
|
|
29
|
+
export interface JobDefinition {
|
|
30
|
+
name: string;
|
|
31
|
+
/** Rows this job would act on, oldest obligation first. */
|
|
32
|
+
due(host: JobHost, now: Date, limit: number): Promise<Row[]>;
|
|
33
|
+
run(host: JobHost, row: Row, now: Date): Promise<void>;
|
|
34
|
+
/** What a failure is recorded as in the `jobs` table. */
|
|
35
|
+
failureType: string;
|
|
36
|
+
failurePayload(row: Row): JsonObject;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* `cms.jobs`.
|
|
40
|
+
*
|
|
41
|
+
* A registry rather than hard-coded calls: `media-gc` joins the two below only
|
|
42
|
+
* when the configuration has an `uploads` section, a plugin will eventually
|
|
43
|
+
* add its own, and `cms.inspect().jobs` has to print what will actually run
|
|
44
|
+
* rather than what the package happens to contain.
|
|
45
|
+
*/
|
|
46
|
+
export declare class JobRunner implements CmsJobs {
|
|
47
|
+
private readonly host;
|
|
48
|
+
private readonly jobs;
|
|
49
|
+
constructor(host: JobHost);
|
|
50
|
+
list(): string[];
|
|
51
|
+
/** Adds a sweep. Used by the media lifecycle, and later by plugins. */
|
|
52
|
+
register(job: JobDefinition): void;
|
|
53
|
+
/**
|
|
54
|
+
* One pass over everything that is due.
|
|
55
|
+
*
|
|
56
|
+
* A failing item never stops the sweep: one document whose scheduled change
|
|
57
|
+
* no longer validates must not keep every other publication waiting. Each
|
|
58
|
+
* failure is recorded with its payload and emitted as `job.failed`.
|
|
59
|
+
*/
|
|
60
|
+
run(args?: JobRunArgs): Promise<JobRunReport>;
|
|
61
|
+
failures(args?: JobFailureArgs): Promise<JobFailure[]>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../src/engine/jobs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,cAAc,EAEd,UAAU,EACV,YAAY,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAM1C;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IACrC,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7D,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAAC;CACtC;AAgFD;;;;;;;GAOG;AACH,qBAAa,SAAU,YAAW,OAAO;IAG3B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmD;IAExE,YAA6B,IAAI,EAAE,OAAO,EAAI;IAE9C,IAAI,IAAI,MAAM,EAAE,CAEf;IAED,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAEjC;IAED;;;;;;OAMG;IACG,GAAG,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CA2CtD;IAEK,QAAQ,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAsB/D;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { LocaleArgs } from "../types/api";
|
|
2
|
+
import type { ResolvedCmsConfig } from "../types/config";
|
|
3
|
+
import type { JsonObject, JsonValue } from "../types/json";
|
|
4
|
+
/**
|
|
5
|
+
* Everything a read needs to know about language, resolved once per call.
|
|
6
|
+
*
|
|
7
|
+
* Fallback is decided here and nowhere else: a field that resolves one way in
|
|
8
|
+
* the REST layer and another way in a hook would make `_fallback` a claim
|
|
9
|
+
* nobody could rely on.
|
|
10
|
+
*/
|
|
11
|
+
export interface LocaleContext {
|
|
12
|
+
/** The locale the caller asked for. */
|
|
13
|
+
locale: string;
|
|
14
|
+
/** The order values are looked up in, starting with `locale` itself. */
|
|
15
|
+
chain: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One rule, not a configuration section: a field with no value in the
|
|
19
|
+
* requested language is answered from `i18n.defaultLocale`, and the response
|
|
20
|
+
* says which fields those were. A caller that wants the gaps instead of the
|
|
21
|
+
* substitution passes `fallbackLocale: false` for that one call — which is
|
|
22
|
+
* exactly what the panel does while somebody is filling translations in.
|
|
23
|
+
*/
|
|
24
|
+
export declare function localeContext(config: ResolvedCmsConfig, args?: LocaleArgs): LocaleContext;
|
|
25
|
+
export interface ResolvedValue {
|
|
26
|
+
value: JsonValue;
|
|
27
|
+
/** The locale the value actually came from, `null` when nothing matched. */
|
|
28
|
+
from: string | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Picks one locale's value out of a stored `{ [locale]: value }` map.
|
|
32
|
+
*
|
|
33
|
+
* Fallback is per field, not per document: partial translations are the norm,
|
|
34
|
+
* so a document with a translated title and an untranslated body has to be
|
|
35
|
+
* expressible (section 9).
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveLocalized(stored: JsonValue | undefined, locale: LocaleContext): ResolvedValue;
|
|
38
|
+
/** Writes one locale into a stored map, leaving the other languages alone. */
|
|
39
|
+
export declare function writeLocalized(stored: JsonValue | undefined, locale: string, value: JsonValue): JsonObject;
|
|
40
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../src/engine/locales.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,iBAAiB,EACzB,IAAI,GAAE,UAAe,GACpB,aAAa,CAGf;AAmBD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,EAC7B,MAAM,EAAE,aAAa,GACpB,aAAa,CAOf;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,GAAG,SAAS,EAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,GACf,UAAU,CAIZ"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Actor } from "../types/actor";
|
|
2
|
+
import type { DatabaseAdapter } from "../types/database";
|
|
3
|
+
import type { AnyEventType, CmsEvent, HookEventEmitter } from "../types/events";
|
|
4
|
+
import type { JsonObject } from "../types/json";
|
|
5
|
+
import type { Tx } from "../types/query";
|
|
6
|
+
export declare const outboxTable = "outbox";
|
|
7
|
+
export interface BufferedEvent {
|
|
8
|
+
type: AnyEventType;
|
|
9
|
+
data: JsonObject;
|
|
10
|
+
previous: JsonObject | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* `ctx.events`: the only way a hook causes a side effect.
|
|
14
|
+
*
|
|
15
|
+
* Emitting queues; it never sends. A mail or a webhook fired inside the
|
|
16
|
+
* transaction would go out even when the write is rolled back, and a mail
|
|
17
|
+
* fired after the commit without a record would be lost when the process
|
|
18
|
+
* dies between the two. The queue is drained into the outbox table by the
|
|
19
|
+
* engine, inside the same transaction as the write (section 5).
|
|
20
|
+
*/
|
|
21
|
+
export declare class EventBuffer implements HookEventEmitter {
|
|
22
|
+
private readonly queued;
|
|
23
|
+
emit(type: AnyEventType, data: JsonObject, previous?: JsonObject | null): void;
|
|
24
|
+
/** Empties the queue; the caller is now responsible for the events. */
|
|
25
|
+
take(): BufferedEvent[];
|
|
26
|
+
}
|
|
27
|
+
export interface OutboxEntryMeta {
|
|
28
|
+
actor: Actor | null;
|
|
29
|
+
collection?: string;
|
|
30
|
+
documentId?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface OutboxOptions {
|
|
33
|
+
/** Section 7: five attempts, then the delivery is dead. */
|
|
34
|
+
maxAttempts?: number;
|
|
35
|
+
/** Exponential by default: 1s, 2s, 4s, 8s. */
|
|
36
|
+
backoff?: (attempt: number) => number;
|
|
37
|
+
/** Abandoned deliveries become claimable again. Subscribers must deduplicate event.id. */
|
|
38
|
+
leaseMs?: number;
|
|
39
|
+
now?: () => Date;
|
|
40
|
+
}
|
|
41
|
+
export type EventDispatch = (event: CmsEvent) => Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* The transactional outbox.
|
|
44
|
+
*
|
|
45
|
+
* Rows are written inside the transaction that produced them and delivered
|
|
46
|
+
* afterwards. That is the whole mechanism behind two promises the plan makes:
|
|
47
|
+
* a rolled back write sends nothing, and a committed one sends even if the
|
|
48
|
+
* process dies one line later (sections 5 and 7). It also means an engine
|
|
49
|
+
* without real transactions still has a defined behaviour — the row lands in
|
|
50
|
+
* the same operation sequence as the document, and the worker is idempotent
|
|
51
|
+
* because it claims a row before delivering it.
|
|
52
|
+
*/
|
|
53
|
+
export declare class Outbox {
|
|
54
|
+
private readonly adapter;
|
|
55
|
+
private readonly dispatch;
|
|
56
|
+
private readonly maxAttempts;
|
|
57
|
+
private readonly backoff;
|
|
58
|
+
private readonly leaseMs;
|
|
59
|
+
private readonly now;
|
|
60
|
+
constructor(adapter: DatabaseAdapter, dispatch: EventDispatch, options?: OutboxOptions);
|
|
61
|
+
append(tx: Tx, events: BufferedEvent[], meta: OutboxEntryMeta): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Delivers what is due and reports how much it delivered.
|
|
64
|
+
*
|
|
65
|
+
* Claim, deliver, settle — three short transactions rather than one long
|
|
66
|
+
* one, because a delivery is an HTTP call and holding a row lock across it
|
|
67
|
+
* is how an outbox turns into an outage.
|
|
68
|
+
*/
|
|
69
|
+
drain(limit?: number): Promise<number>;
|
|
70
|
+
/**
|
|
71
|
+
* Takes ownership of a row, or finds out somebody else already has.
|
|
72
|
+
*
|
|
73
|
+
* A conditional update is the portable claim: it works on all three
|
|
74
|
+
* engines, needs no row locking and makes a second worker — or a retried
|
|
75
|
+
* request on serverless — harmless.
|
|
76
|
+
*/
|
|
77
|
+
private hasPredecessor;
|
|
78
|
+
private claim;
|
|
79
|
+
private settle;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=outbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../src/engine/outbox.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAO,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAG9C,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAY,YAAW,gBAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAE9C,IAAI,CACF,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,UAAU,EAChB,QAAQ,GAAE,UAAU,GAAG,IAAW,GACjC,IAAI,CAEN;IAED,uEAAuE;IACvE,IAAI,IAAI,aAAa,EAAE,CAEtB;CACF;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/D;;;;;;;;;;GAUG;AACH,qBAAa,MAAM;IAOf,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IAEjC,YACmB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa,EACxC,OAAO,GAAE,aAAkB,EAM5B;IAEK,MAAM,CACV,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,aAAa,EAAE,EACvB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CA2Bf;IAED;;;;;;OAMG;IACG,KAAK,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCvC;IAED;;;;;;OAMG;YACW,cAAc;YAoBd,KAAK;YAuBL,MAAM;CAmCrB"}
|