@aphexcms/cms-core 9.5.2 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/documents.d.ts +28 -0
- package/dist/api/documents.d.ts.map +1 -1
- package/dist/api/documents.js +18 -0
- package/dist/api/schemas/documents.d.ts +19 -0
- package/dist/api/schemas/documents.d.ts.map +1 -1
- package/dist/api/schemas/documents.js +18 -0
- package/dist/client/api.d.ts +2 -0
- package/dist/client/api.d.ts.map +1 -0
- package/dist/client/api.js +11 -0
- package/dist/client/ui.d.ts +25 -0
- package/dist/client/ui.d.ts.map +1 -0
- package/dist/client/ui.js +53 -0
- package/dist/components/admin/ActivityView.svelte +227 -0
- package/dist/components/admin/ActivityView.svelte.d.ts +4 -0
- package/dist/components/admin/ActivityView.svelte.d.ts.map +1 -0
- package/dist/components/admin/DocumentEditor.svelte +197 -11
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/ScheduleDialog.svelte +174 -0
- package/dist/components/admin/ScheduleDialog.svelte.d.ts +20 -0
- package/dist/components/admin/ScheduleDialog.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ArrayField.svelte +10 -2
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/layout/OrganizationSwitcher.svelte +3 -3
- package/dist/components/layout/sidebar/NavUser.svelte +5 -5
- package/dist/db/interfaces/events.d.ts +55 -0
- package/dist/db/interfaces/events.d.ts.map +1 -0
- package/dist/db/interfaces/events.js +1 -0
- package/dist/db/interfaces/index.d.ts +10 -2
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/plugin-storage.d.ts +39 -0
- package/dist/db/interfaces/plugin-storage.d.ts.map +1 -0
- package/dist/db/interfaces/plugin-storage.js +1 -0
- package/dist/events/catalog.d.ts +8 -0
- package/dist/events/catalog.d.ts.map +1 -0
- package/dist/events/catalog.js +11 -0
- package/dist/events/consumer.d.ts +79 -0
- package/dist/events/consumer.d.ts.map +1 -0
- package/dist/events/consumer.js +76 -0
- package/dist/events/define-event.d.ts +17 -0
- package/dist/events/define-event.d.ts.map +1 -0
- package/dist/events/define-event.js +7 -0
- package/dist/events/emit.d.ts +11 -0
- package/dist/events/emit.d.ts.map +1 -0
- package/dist/events/emit.js +20 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +3 -0
- package/dist/field-validation/rule.d.ts.map +1 -1
- package/dist/field-validation/rule.js +15 -0
- package/dist/field-validation/utils.d.ts.map +1 -1
- package/dist/field-validation/utils.js +7 -1
- package/dist/forms/define-form.d.ts +25 -0
- package/dist/forms/define-form.d.ts.map +1 -0
- package/dist/forms/define-form.js +22 -0
- package/dist/forms/index.d.ts +4 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +5 -0
- package/dist/forms/types.d.ts +49 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/types.js +1 -0
- package/dist/forms/validate.d.ts +9 -0
- package/dist/forms/validate.d.ts.map +1 -0
- package/dist/forms/validate.js +18 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/jobs/document-jobs.d.ts +27 -0
- package/dist/jobs/document-jobs.d.ts.map +1 -0
- package/dist/jobs/document-jobs.js +42 -0
- package/dist/jobs/embedded-runner.d.ts +25 -0
- package/dist/jobs/embedded-runner.d.ts.map +1 -0
- package/dist/jobs/embedded-runner.js +46 -0
- package/dist/jobs/index.d.ts +7 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +8 -0
- package/dist/jobs/relay.d.ts +27 -0
- package/dist/jobs/relay.d.ts.map +1 -0
- package/dist/jobs/relay.js +60 -0
- package/dist/jobs/run-batch.d.ts +52 -0
- package/dist/jobs/run-batch.d.ts.map +1 -0
- package/dist/jobs/run-batch.js +61 -0
- package/dist/jobs/run-due-jobs.d.ts +30 -0
- package/dist/jobs/run-due-jobs.d.ts.map +1 -0
- package/dist/jobs/run-due-jobs.js +69 -0
- package/dist/jobs/types.d.ts +18 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +1 -0
- package/dist/lib/api/documents.d.ts +28 -0
- package/dist/lib/api/documents.d.ts.map +1 -1
- package/dist/lib/api/documents.js +18 -0
- package/dist/lib/api/documents.js.map +1 -1
- package/dist/lib/api/schemas/documents.d.ts +19 -0
- package/dist/lib/api/schemas/documents.d.ts.map +1 -1
- package/dist/lib/api/schemas/documents.js +18 -0
- package/dist/lib/api/schemas/documents.js.map +1 -1
- package/dist/lib/client/api.d.ts +2 -0
- package/dist/lib/client/api.d.ts.map +1 -0
- package/dist/lib/client/api.js +12 -0
- package/dist/lib/client/api.js.map +1 -0
- package/dist/lib/client/ui.d.ts +25 -0
- package/dist/lib/client/ui.d.ts.map +1 -0
- package/dist/lib/client/ui.js +54 -0
- package/dist/lib/client/ui.js.map +1 -0
- package/dist/lib/db/interfaces/events.d.ts +55 -0
- package/dist/lib/db/interfaces/events.d.ts.map +1 -0
- package/dist/lib/db/interfaces/events.js +2 -0
- package/dist/lib/db/interfaces/events.js.map +1 -0
- package/dist/lib/db/interfaces/index.d.ts +10 -2
- package/dist/lib/db/interfaces/index.d.ts.map +1 -1
- package/dist/lib/db/interfaces/plugin-storage.d.ts +39 -0
- package/dist/lib/db/interfaces/plugin-storage.d.ts.map +1 -0
- package/dist/lib/db/interfaces/plugin-storage.js +2 -0
- package/dist/lib/db/interfaces/plugin-storage.js.map +1 -0
- package/dist/lib/events/catalog.d.ts +8 -0
- package/dist/lib/events/catalog.d.ts.map +1 -0
- package/dist/lib/events/catalog.js +12 -0
- package/dist/lib/events/catalog.js.map +1 -0
- package/dist/lib/events/consumer.d.ts +79 -0
- package/dist/lib/events/consumer.d.ts.map +1 -0
- package/dist/lib/events/consumer.js +77 -0
- package/dist/lib/events/consumer.js.map +1 -0
- package/dist/lib/events/define-event.d.ts +17 -0
- package/dist/lib/events/define-event.d.ts.map +1 -0
- package/dist/lib/events/define-event.js +8 -0
- package/dist/lib/events/define-event.js.map +1 -0
- package/dist/lib/events/emit.d.ts +11 -0
- package/dist/lib/events/emit.d.ts.map +1 -0
- package/dist/lib/events/emit.js +21 -0
- package/dist/lib/events/emit.js.map +1 -0
- package/dist/lib/events/index.d.ts +4 -0
- package/dist/lib/events/index.d.ts.map +1 -0
- package/dist/lib/events/index.js +4 -0
- package/dist/lib/events/index.js.map +1 -0
- package/dist/lib/field-validation/rule.d.ts.map +1 -1
- package/dist/lib/field-validation/rule.js +15 -0
- package/dist/lib/field-validation/rule.js.map +1 -1
- package/dist/lib/field-validation/utils.d.ts.map +1 -1
- package/dist/lib/field-validation/utils.js +7 -1
- package/dist/lib/field-validation/utils.js.map +1 -1
- package/dist/lib/forms/define-form.d.ts +25 -0
- package/dist/lib/forms/define-form.d.ts.map +1 -0
- package/dist/lib/forms/define-form.js +23 -0
- package/dist/lib/forms/define-form.js.map +1 -0
- package/dist/lib/forms/index.d.ts +4 -0
- package/dist/lib/forms/index.d.ts.map +1 -0
- package/dist/lib/forms/index.js +6 -0
- package/dist/lib/forms/index.js.map +1 -0
- package/dist/lib/forms/types.d.ts +49 -0
- package/dist/lib/forms/types.d.ts.map +1 -0
- package/dist/lib/forms/types.js +2 -0
- package/dist/lib/forms/types.js.map +1 -0
- package/dist/lib/forms/validate.d.ts +9 -0
- package/dist/lib/forms/validate.d.ts.map +1 -0
- package/dist/lib/forms/validate.js +19 -0
- package/dist/lib/forms/validate.js.map +1 -0
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +15 -0
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +6 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/jobs/document-jobs.d.ts +27 -0
- package/dist/lib/jobs/document-jobs.d.ts.map +1 -0
- package/dist/lib/jobs/document-jobs.js +43 -0
- package/dist/lib/jobs/document-jobs.js.map +1 -0
- package/dist/lib/jobs/embedded-runner.d.ts +25 -0
- package/dist/lib/jobs/embedded-runner.d.ts.map +1 -0
- package/dist/lib/jobs/embedded-runner.js +47 -0
- package/dist/lib/jobs/embedded-runner.js.map +1 -0
- package/dist/lib/jobs/index.d.ts +7 -0
- package/dist/lib/jobs/index.d.ts.map +1 -0
- package/dist/lib/jobs/index.js +9 -0
- package/dist/lib/jobs/index.js.map +1 -0
- package/dist/lib/jobs/relay.d.ts +27 -0
- package/dist/lib/jobs/relay.d.ts.map +1 -0
- package/dist/lib/jobs/relay.js +61 -0
- package/dist/lib/jobs/relay.js.map +1 -0
- package/dist/lib/jobs/run-batch.d.ts +52 -0
- package/dist/lib/jobs/run-batch.d.ts.map +1 -0
- package/dist/lib/jobs/run-batch.js +62 -0
- package/dist/lib/jobs/run-batch.js.map +1 -0
- package/dist/lib/jobs/run-due-jobs.d.ts +30 -0
- package/dist/lib/jobs/run-due-jobs.d.ts.map +1 -0
- package/dist/lib/jobs/run-due-jobs.js +70 -0
- package/dist/lib/jobs/run-due-jobs.js.map +1 -0
- package/dist/lib/jobs/types.d.ts +18 -0
- package/dist/lib/jobs/types.d.ts.map +1 -0
- package/dist/lib/jobs/types.js +2 -0
- package/dist/lib/jobs/types.js.map +1 -0
- package/dist/lib/local-api/collection-api.d.ts +42 -0
- package/dist/lib/local-api/collection-api.d.ts.map +1 -1
- package/dist/lib/local-api/collection-api.js +200 -25
- package/dist/lib/local-api/collection-api.js.map +1 -1
- package/dist/lib/local-api/hooks.d.ts +7 -0
- package/dist/lib/local-api/hooks.d.ts.map +1 -0
- package/dist/lib/local-api/hooks.js +20 -0
- package/dist/lib/local-api/hooks.js.map +1 -0
- package/dist/lib/mcp/tools.js +1 -1
- package/dist/lib/mcp/tools.js.map +1 -1
- package/dist/lib/plugins/resolver.d.ts +12 -1
- package/dist/lib/plugins/resolver.d.ts.map +1 -1
- package/dist/lib/plugins/resolver.js +4 -1
- package/dist/lib/plugins/resolver.js.map +1 -1
- package/dist/lib/plugins/types.d.ts +47 -2
- package/dist/lib/plugins/types.d.ts.map +1 -1
- package/dist/lib/plugins/types.js.map +1 -1
- package/dist/lib/schema-utils/define-type.d.ts +32 -0
- package/dist/lib/schema-utils/define-type.d.ts.map +1 -0
- package/dist/lib/schema-utils/define-type.js +41 -0
- package/dist/lib/schema-utils/define-type.js.map +1 -0
- package/dist/lib/schema-utils/index.d.ts +1 -0
- package/dist/lib/schema-utils/index.d.ts.map +1 -1
- package/dist/lib/schema-utils/index.js +1 -0
- package/dist/lib/schema-utils/index.js.map +1 -1
- package/dist/lib/server/api/index.d.ts.map +1 -1
- package/dist/lib/server/api/index.js +8 -0
- package/dist/lib/server/api/index.js.map +1 -1
- package/dist/lib/server/api/routes/documents-publish.d.ts.map +1 -1
- package/dist/lib/server/api/routes/documents-publish.js +110 -0
- package/dist/lib/server/api/routes/documents-publish.js.map +1 -1
- package/dist/lib/server/api/routes/jobs.d.ts +4 -0
- package/dist/lib/server/api/routes/jobs.d.ts.map +1 -0
- package/dist/lib/server/api/routes/jobs.js +93 -0
- package/dist/lib/server/api/routes/jobs.js.map +1 -0
- package/dist/lib/server/api/routes/workers-run.d.ts +4 -0
- package/dist/lib/server/api/routes/workers-run.d.ts.map +1 -0
- package/dist/lib/server/api/routes/workers-run.js +41 -0
- package/dist/lib/server/api/routes/workers-run.js.map +1 -0
- package/dist/lib/server/index.d.ts +1 -0
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/services/version-service.d.ts +16 -0
- package/dist/lib/services/version-service.d.ts.map +1 -1
- package/dist/lib/services/version-service.js +72 -48
- package/dist/lib/services/version-service.js.map +1 -1
- package/dist/lib/types/config.d.ts +43 -0
- package/dist/lib/types/config.d.ts.map +1 -1
- package/dist/lib/types/events.d.ts +134 -0
- package/dist/lib/types/events.d.ts.map +1 -0
- package/dist/lib/types/events.js +4 -0
- package/dist/lib/types/events.js.map +1 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/index.js +1 -0
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/types/schemas.d.ts +71 -0
- package/dist/lib/types/schemas.d.ts.map +1 -1
- package/dist/lib/utils/index.d.ts +1 -1
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/local-api/collection-api.d.ts +42 -0
- package/dist/local-api/collection-api.d.ts.map +1 -1
- package/dist/local-api/collection-api.js +200 -25
- package/dist/local-api/hooks.d.ts +7 -0
- package/dist/local-api/hooks.d.ts.map +1 -0
- package/dist/local-api/hooks.js +19 -0
- package/dist/mcp/tools.js +1 -1
- package/dist/plugins/resolver.d.ts +12 -1
- package/dist/plugins/resolver.d.ts.map +1 -1
- package/dist/plugins/resolver.js +4 -1
- package/dist/plugins/types.d.ts +47 -2
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/schema-utils/define-type.d.ts +32 -0
- package/dist/schema-utils/define-type.d.ts.map +1 -0
- package/dist/schema-utils/define-type.js +40 -0
- package/dist/schema-utils/index.d.ts +1 -0
- package/dist/schema-utils/index.d.ts.map +1 -1
- package/dist/schema-utils/index.js +1 -0
- package/dist/server/api/index.d.ts.map +1 -1
- package/dist/server/api/index.js +8 -0
- package/dist/server/api/routes/documents-publish.d.ts.map +1 -1
- package/dist/server/api/routes/documents-publish.js +110 -0
- package/dist/server/api/routes/jobs.d.ts +4 -0
- package/dist/server/api/routes/jobs.d.ts.map +1 -0
- package/dist/server/api/routes/jobs.js +92 -0
- package/dist/server/api/routes/workers-run.d.ts +4 -0
- package/dist/server/api/routes/workers-run.d.ts.map +1 -0
- package/dist/server/api/routes/workers-run.js +40 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/services/version-service.d.ts +16 -0
- package/dist/services/version-service.d.ts.map +1 -1
- package/dist/services/version-service.js +72 -48
- package/dist/types/config.d.ts +43 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/events.d.ts +134 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +3 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/schemas.d.ts +71 -0
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* `config.plugins` and exposed on the engine so both server and admin consult the
|
|
6
6
|
* same resolved model. Validates duplicate part ids up front — no silent overrides.
|
|
7
7
|
*/
|
|
8
|
-
import type { AdminToolPart, CMSPlugin, DocumentActionPart, FieldComponentPart, PartKind, PluginPart, ServerRoutePart, SettingsPart } from './types.js';
|
|
8
|
+
import type { AdminToolPart, CMSPlugin, DocumentActionPart, EventConsumerPart, FieldComponentPart, PartKind, PluginPart, ServerRoutePart, SettingsPart } from './types.js';
|
|
9
9
|
import type { SchemaType } from '../types/schemas.js';
|
|
10
|
+
import type { JobHandlerMap } from '../jobs/types.js';
|
|
10
11
|
import { type CapabilityDefinition } from '../types/capabilities.js';
|
|
11
12
|
type PartOf<K extends PartKind> = Extract<PluginPart, {
|
|
12
13
|
implements: K;
|
|
@@ -43,6 +44,16 @@ export interface PartResolver {
|
|
|
43
44
|
settingsDeclarations(): SettingsPart[];
|
|
44
45
|
/** The settings declaration for a given plugin id, if any. */
|
|
45
46
|
settingsDeclaration(pluginId: string): SettingsPart | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* All plugin-contributed job handlers, merged into one map (later parts win on a
|
|
49
|
+
* type collision). The runner layers this between core built-ins and the app's
|
|
50
|
+
* `config.jobs.handlers`.
|
|
51
|
+
*/
|
|
52
|
+
jobHandlers(): JobHandlerMap;
|
|
53
|
+
/** All registered event consumers, in registration order. The runner turns these into delivery job handlers. */
|
|
54
|
+
eventConsumers(): EventConsumerPart[];
|
|
55
|
+
/** Event consumers subscribed to a given event type — the relay's fan-out list. */
|
|
56
|
+
consumersForEvent(eventType: string): EventConsumerPart[];
|
|
46
57
|
}
|
|
47
58
|
export declare function createPartResolver(plugins?: CMSPlugin[]): PartResolver;
|
|
48
59
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,YAAY,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,yEAAyE;IACzE,WAAW,IAAI,UAAU,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;IAC3D,gDAAgD;IAChD,YAAY,IAAI,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB;oEACgE;IAChE,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,sFAAsF;IACtF,eAAe,CAAC,IAAI,EAAE;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,kBAAkB,EAAE,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,EAAE,CAAC;IAC1F,sEAAsE;IACtE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC9D,+DAA+D;IAC/D,oBAAoB,IAAI,YAAY,EAAE,CAAC;IACvC,8DAA8D;IAC9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,YAAY,EACZ,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,yEAAyE;IACzE,WAAW,IAAI,UAAU,EAAE,CAAC;IAC5B,6EAA6E;IAC7E,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC;IAC3D,gDAAgD;IAChD,YAAY,IAAI,eAAe,EAAE,CAAC;IAClC,8DAA8D;IAC9D,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB;oEACgE;IAChE,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,sFAAsF;IACtF,eAAe,CAAC,IAAI,EAAE;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,kBAAkB,EAAE,CAAC;IACzB,mDAAmD;IACnD,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,aAAa,EAAE,CAAC;IAC1F,sEAAsE;IACtE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC9D,+DAA+D;IAC/D,oBAAoB,IAAI,YAAY,EAAE,CAAC;IACvC,8DAA8D;IAC9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAChE;;;;OAIG;IACH,WAAW,IAAI,aAAa,CAAC;IAC7B,gHAAgH;IAChH,cAAc,IAAI,iBAAiB,EAAE,CAAC;IACtC,mFAAmF;IACnF,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;CAC1D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,SAAS,EAAO,GAAG,YAAY,CAwF1E"}
|
package/dist/plugins/resolver.js
CHANGED
|
@@ -60,6 +60,9 @@ export function createPartResolver(plugins = []) {
|
|
|
60
60
|
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0)),
|
|
61
61
|
fieldComponent: (input) => getParts('aphex/field/component').find((f) => f.input === input),
|
|
62
62
|
settingsDeclarations: () => getParts('aphex/settings'),
|
|
63
|
-
settingsDeclaration: (pluginId) => getParts('aphex/settings').find((s) => s.pluginId === pluginId)
|
|
63
|
+
settingsDeclaration: (pluginId) => getParts('aphex/settings').find((s) => s.pluginId === pluginId),
|
|
64
|
+
jobHandlers: () => getParts('aphex/job/handler').reduce((acc, part) => ({ ...acc, ...part.handlers }), {}),
|
|
65
|
+
eventConsumers: () => getParts('aphex/event/consumer'),
|
|
66
|
+
consumersForEvent: (eventType) => getParts('aphex/event/consumer').filter((c) => c.events.includes(eventType))
|
|
64
67
|
};
|
|
65
68
|
}
|
package/dist/plugins/types.d.ts
CHANGED
|
@@ -18,8 +18,10 @@ import type { AphexEnv } from '../server/api/index.js';
|
|
|
18
18
|
import type { Field, SettingsField, SchemaType } from '../types/schemas.js';
|
|
19
19
|
import type { AdminArea } from '../admin/types.js';
|
|
20
20
|
import type { CapabilityDefinition } from '../types/capabilities.js';
|
|
21
|
+
import type { JobHandlerMap } from '../jobs/types.js';
|
|
22
|
+
import type { EventConsumerHandler } from '../events/consumer.js';
|
|
21
23
|
/** Known extension points. Plugins may also register custom string kinds. */
|
|
22
|
-
export type PartKind = 'aphex/schema' | 'aphex/schema/transform' | 'aphex/server/route' | 'aphex/capabilities' | 'aphex/settings' | 'aphex/document/action' | 'aphex/admin/tool' | 'aphex/field/component';
|
|
24
|
+
export type PartKind = 'aphex/schema' | 'aphex/schema/transform' | 'aphex/server/route' | 'aphex/capabilities' | 'aphex/settings' | 'aphex/job/handler' | 'aphex/event/consumer' | 'aphex/document/action' | 'aphex/admin/tool' | 'aphex/field/component';
|
|
23
25
|
/** Contributes content schemas, merged into the app's `schemaTypes`. */
|
|
24
26
|
export interface SchemaPart {
|
|
25
27
|
implements: 'aphex/schema';
|
|
@@ -118,6 +120,49 @@ export interface SettingsPart {
|
|
|
118
120
|
*/
|
|
119
121
|
requiredCapabilities?: string[];
|
|
120
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Registers job handlers on the durable queue — the *execution* half of the spine
|
|
125
|
+
* (a `aphex/server/route` webhook receiver, or any code, does the *enqueue* half via
|
|
126
|
+
* `c.var.aphexCMS.databaseAdapter.scheduleJob`). A plugin that both enqueues and
|
|
127
|
+
* handles a job type (e.g. a Shopify sync) is thus fully self-contained: no handler
|
|
128
|
+
* wiring in the app's `aphex.config.ts`.
|
|
129
|
+
*
|
|
130
|
+
* The runner assembles its map as: core built-ins → plugin handlers → the app's
|
|
131
|
+
* `config.jobs.handlers` — so the app always wins and can override a plugin's handler,
|
|
132
|
+
* and a plugin can override a core built-in. Two plugins claiming the same job `type`
|
|
133
|
+
* is last-wins by registration order; keep type strings package-namespaced
|
|
134
|
+
* (`shopify.product.sync`) to avoid collisions.
|
|
135
|
+
*/
|
|
136
|
+
export interface JobHandlerPart {
|
|
137
|
+
implements: 'aphex/job/handler';
|
|
138
|
+
handlers: JobHandlerMap;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Subscribes to domain events — the *react* half of the spine (`hooks` transform, events
|
|
142
|
+
* react; a consumer is where "react" lives). When any of `events` fires, the relay enqueues
|
|
143
|
+
* a durable delivery job and the runner invokes `handler`. So a consumer is decoupled from
|
|
144
|
+
* the emit site (a failing email never fails the publish) and inherits retries/backoff/
|
|
145
|
+
* dead-lettering from the job queue.
|
|
146
|
+
*
|
|
147
|
+
* A plugin that emits an event (e.g. a webhook receiver `appendEvent`) and consumes it here
|
|
148
|
+
* is fully self-contained — no wiring in the app's `aphex.config.ts`. This is the primitive
|
|
149
|
+
* behind webhook-on-publish, cache invalidation, notifications, and automation.
|
|
150
|
+
*/
|
|
151
|
+
export interface EventConsumerPart {
|
|
152
|
+
implements: 'aphex/event/consumer';
|
|
153
|
+
/**
|
|
154
|
+
* Unique across all plugins — it names the delivery job type (`aphex/consumer:<id>`) and
|
|
155
|
+
* scopes the per-event idempotency key, so two consumers never share a delivery. Namespace
|
|
156
|
+
* it by package (`shopify.publish-sync`) to avoid collisions.
|
|
157
|
+
*/
|
|
158
|
+
id: string;
|
|
159
|
+
/** Event types this reacts to, matched exactly (e.g. `['document.published']`). */
|
|
160
|
+
events: string[];
|
|
161
|
+
/** Runs when a subscribed event fires. Must be idempotent (at-least-once); throw to retry. */
|
|
162
|
+
handler: EventConsumerHandler;
|
|
163
|
+
/** Retry budget for this consumer's delivery jobs before dead-lettering. Defaults to the queue default (5). */
|
|
164
|
+
maxAttempts?: number;
|
|
165
|
+
}
|
|
121
166
|
/**
|
|
122
167
|
* A minimal, stable context handed to a document-action component. Deliberately
|
|
123
168
|
* decoupled from editor internals — actions get exactly this and nothing more, so
|
|
@@ -214,7 +259,7 @@ export interface FieldComponentPart {
|
|
|
214
259
|
input: string;
|
|
215
260
|
component: Component<FieldComponentProps>;
|
|
216
261
|
}
|
|
217
|
-
export type PluginPart = SchemaPart | SchemaTransformPart | ServerRoutePart | CapabilitiesPart | SettingsPart | DocumentActionPart | AdminToolPart | FieldComponentPart;
|
|
262
|
+
export type PluginPart = SchemaPart | SchemaTransformPart | ServerRoutePart | CapabilitiesPart | SettingsPart | JobHandlerPart | EventConsumerPart | DocumentActionPart | AdminToolPart | FieldComponentPart;
|
|
218
263
|
/** A plugin manifest. Returned by `definePlugin`. */
|
|
219
264
|
export interface CMSPlugin {
|
|
220
265
|
/** Package-style name, e.g. `@acme/aphex-plugin-seo`. Used in error messages. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Field, SchemaType, SchemaHooks, InferFields } from '../types/schemas.js';
|
|
2
|
+
/**
|
|
3
|
+
* Define a schema with hooks typed from its own fields.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* export default defineType({
|
|
8
|
+
* type: 'document',
|
|
9
|
+
* name: 'contactSubmission',
|
|
10
|
+
* title: 'Contact Submission',
|
|
11
|
+
* fields: [
|
|
12
|
+
* { name: 'email', type: 'string', title: 'Email' },
|
|
13
|
+
* { name: 'subscribed', type: 'boolean', title: 'Subscribed' }
|
|
14
|
+
* ],
|
|
15
|
+
* hooks: {
|
|
16
|
+
* beforeValidate: [
|
|
17
|
+
* // `data.email` is `string | undefined`, `data.subscribed` is `boolean | undefined`
|
|
18
|
+
* ({ data }) => ({ ...data, email: data.email?.trim().toLowerCase() })
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The `const` type parameter preserves the field literals; `hooks` uses the
|
|
25
|
+
* inferred type through a mapped type (a non-inferential position), so `fields`
|
|
26
|
+
* is the sole inference site and `data` is contextually typed from it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function defineType<const F extends readonly Field[]>(schema: Omit<SchemaType, 'fields' | 'hooks'> & {
|
|
29
|
+
fields: F;
|
|
30
|
+
hooks?: SchemaHooks<InferFields<F>>;
|
|
31
|
+
}): SchemaType;
|
|
32
|
+
//# sourceMappingURL=define-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-type.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/define-type.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,KAAK,EAAE,EAC1D,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG;IAC9C,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACpC,GACC,UAAU,CAIZ"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// schema-utils/define-type.ts
|
|
2
|
+
//
|
|
3
|
+
// Optional authoring helper. Wrapping a schema in `defineType({ ... })` instead
|
|
4
|
+
// of annotating `const x: SchemaType = { ... }` lets TypeScript capture the exact
|
|
5
|
+
// `fields` tuple and infer the document shape — so `beforeValidate` hooks receive
|
|
6
|
+
// a typed `data` with no codegen and no casts in your schema.
|
|
7
|
+
//
|
|
8
|
+
// Backwards compatible: plain `SchemaType` object literals keep working exactly
|
|
9
|
+
// as before. This is opt-in, only for the typed-hook ergonomics.
|
|
10
|
+
/**
|
|
11
|
+
* Define a schema with hooks typed from its own fields.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* export default defineType({
|
|
16
|
+
* type: 'document',
|
|
17
|
+
* name: 'contactSubmission',
|
|
18
|
+
* title: 'Contact Submission',
|
|
19
|
+
* fields: [
|
|
20
|
+
* { name: 'email', type: 'string', title: 'Email' },
|
|
21
|
+
* { name: 'subscribed', type: 'boolean', title: 'Subscribed' }
|
|
22
|
+
* ],
|
|
23
|
+
* hooks: {
|
|
24
|
+
* beforeValidate: [
|
|
25
|
+
* // `data.email` is `string | undefined`, `data.subscribed` is `boolean | undefined`
|
|
26
|
+
* ({ data }) => ({ ...data, email: data.email?.trim().toLowerCase() })
|
|
27
|
+
* ]
|
|
28
|
+
* }
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* The `const` type parameter preserves the field literals; `hooks` uses the
|
|
33
|
+
* inferred type through a mapped type (a non-inferential position), so `fields`
|
|
34
|
+
* is the sole inference site and `data` is contextually typed from it.
|
|
35
|
+
*/
|
|
36
|
+
export function defineType(schema) {
|
|
37
|
+
// One controlled widening: the registry stores the loose `SchemaType` (fields
|
|
38
|
+
// as a mutable array, hooks with the erased generic). Runtime is unaffected.
|
|
39
|
+
return schema;
|
|
40
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAuB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QA6DrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
|
package/dist/server/api/index.js
CHANGED
|
@@ -19,6 +19,8 @@ import { rolesRouter } from './routes/roles.js';
|
|
|
19
19
|
import { pluginSettingsRouter } from './routes/plugin-settings.js';
|
|
20
20
|
import { userPreferencesRouter } from './routes/user-preferences.js';
|
|
21
21
|
import { userRouter } from './routes/user.js';
|
|
22
|
+
import { workersRunRouter } from './routes/workers-run.js';
|
|
23
|
+
import { jobsRouter } from './routes/jobs.js';
|
|
22
24
|
/**
|
|
23
25
|
* Build the Aphex API Hono app shell.
|
|
24
26
|
*
|
|
@@ -86,6 +88,12 @@ export function mountAphexBuiltins(app) {
|
|
|
86
88
|
// Hono would try to match them under the wrong handler chain.
|
|
87
89
|
app.route('/user', userPreferencesRouter);
|
|
88
90
|
app.route('/user', userRouter);
|
|
91
|
+
// Internal worker endpoint — machine-to-machine, secret-gated (404 unless
|
|
92
|
+
// jobs.workerSecret is set). Under /internal so it reads as clearly non-public.
|
|
93
|
+
// → POST /api/internal/workers/run
|
|
94
|
+
app.route('/internal/workers', workersRunRouter);
|
|
95
|
+
// Read-only job/event history (observability). → GET /api/jobs, GET /api/events
|
|
96
|
+
app.route('/', jobsRouter);
|
|
89
97
|
// Health check — unauthenticated, used by load balancers and uptime monitors.
|
|
90
98
|
app.get('/aphex-health', async (c) => {
|
|
91
99
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-publish.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"documents-publish.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/documents-publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,QAAQ,CAoR/C,CAAC"}
|
|
@@ -2,7 +2,117 @@ import { Hono } from 'hono';
|
|
|
2
2
|
import { authToContext } from '../../../local-api/auth-helpers.js';
|
|
3
3
|
import { PermissionError } from '../../../local-api/permissions.js';
|
|
4
4
|
import { cmsLogger } from '../../../utils/logger.js';
|
|
5
|
+
import { scheduleDocumentRequest } from '../../../api/schemas/documents.js';
|
|
5
6
|
export const documentsPublishRouter = new Hono()
|
|
7
|
+
.post('/:id/schedule', async (c) => {
|
|
8
|
+
try {
|
|
9
|
+
const { localAPI } = c.var.aphexCMS;
|
|
10
|
+
const context = authToContext(c.var.auth);
|
|
11
|
+
const id = c.req.param('id');
|
|
12
|
+
if (!id) {
|
|
13
|
+
return c.json({ success: false, error: 'Missing document ID' }, 400);
|
|
14
|
+
}
|
|
15
|
+
const parsed = scheduleDocumentRequest.safeParse(await c.req.json().catch(() => null));
|
|
16
|
+
if (!parsed.success) {
|
|
17
|
+
return c.json({ success: false, error: 'Invalid request', issues: parsed.error.issues }, 400);
|
|
18
|
+
}
|
|
19
|
+
const { action, runAt } = parsed.data;
|
|
20
|
+
const found = await localAPI.findDocumentById(context, id);
|
|
21
|
+
if (!found) {
|
|
22
|
+
return c.json({ success: false, error: 'Document not found' }, 404);
|
|
23
|
+
}
|
|
24
|
+
const collection = localAPI.getCollection(found.type);
|
|
25
|
+
if (!collection) {
|
|
26
|
+
return c.json({
|
|
27
|
+
success: false,
|
|
28
|
+
error: 'Invalid document type',
|
|
29
|
+
message: `Collection '${found.type}' not found`
|
|
30
|
+
}, 400);
|
|
31
|
+
}
|
|
32
|
+
const when = new Date(runAt);
|
|
33
|
+
const job = action === 'publish'
|
|
34
|
+
? await collection.schedulePublish(context, id, when)
|
|
35
|
+
: await collection.scheduleUnpublish(context, id, when);
|
|
36
|
+
return c.json({
|
|
37
|
+
success: true,
|
|
38
|
+
data: { jobId: job.id, type: job.type, runAt: job.runAt.toISOString(), status: job.status },
|
|
39
|
+
message: `Document ${action} scheduled for ${job.runAt.toISOString()}`
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
cmsLogger.error('Failed to schedule document action:', error);
|
|
44
|
+
if (error instanceof PermissionError) {
|
|
45
|
+
return c.json({ success: false, error: 'Forbidden', message: error.message }, 403);
|
|
46
|
+
}
|
|
47
|
+
return c.json({
|
|
48
|
+
success: false,
|
|
49
|
+
error: 'Failed to schedule document action',
|
|
50
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
51
|
+
}, 500);
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.get('/:id/schedule', async (c) => {
|
|
55
|
+
// Pending scheduled publish/unpublish for this document — powers the editor's
|
|
56
|
+
// "scheduled for …" indicator. Read-gated inside the collection.
|
|
57
|
+
try {
|
|
58
|
+
const { localAPI } = c.var.aphexCMS;
|
|
59
|
+
const context = authToContext(c.var.auth);
|
|
60
|
+
const id = c.req.param('id');
|
|
61
|
+
if (!id)
|
|
62
|
+
return c.json({ success: false, error: 'Missing document ID' }, 400);
|
|
63
|
+
const found = await localAPI.findDocumentById(context, id);
|
|
64
|
+
if (!found)
|
|
65
|
+
return c.json({ success: false, error: 'Document not found' }, 404);
|
|
66
|
+
const collection = localAPI.getCollection(found.type);
|
|
67
|
+
if (!collection) {
|
|
68
|
+
return c.json({ success: false, error: 'Invalid document type' }, 400);
|
|
69
|
+
}
|
|
70
|
+
const jobs = await collection.getScheduled(context, id);
|
|
71
|
+
return c.json({
|
|
72
|
+
success: true,
|
|
73
|
+
data: jobs.map((j) => ({
|
|
74
|
+
jobId: j.id,
|
|
75
|
+
type: j.type,
|
|
76
|
+
runAt: j.runAt.toISOString(),
|
|
77
|
+
status: j.status,
|
|
78
|
+
createdAt: j.createdAt.toISOString()
|
|
79
|
+
}))
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
cmsLogger.error('Failed to read document schedule:', error);
|
|
84
|
+
if (error instanceof PermissionError) {
|
|
85
|
+
return c.json({ success: false, error: 'Forbidden', message: error.message }, 403);
|
|
86
|
+
}
|
|
87
|
+
return c.json({ success: false, error: 'Failed to read document schedule' }, 500);
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
.delete('/:id/schedule', async (c) => {
|
|
91
|
+
// Cancel the pending schedule for this document.
|
|
92
|
+
try {
|
|
93
|
+
const { localAPI } = c.var.aphexCMS;
|
|
94
|
+
const context = authToContext(c.var.auth);
|
|
95
|
+
const id = c.req.param('id');
|
|
96
|
+
if (!id)
|
|
97
|
+
return c.json({ success: false, error: 'Missing document ID' }, 400);
|
|
98
|
+
const found = await localAPI.findDocumentById(context, id);
|
|
99
|
+
if (!found)
|
|
100
|
+
return c.json({ success: false, error: 'Document not found' }, 404);
|
|
101
|
+
const collection = localAPI.getCollection(found.type);
|
|
102
|
+
if (!collection) {
|
|
103
|
+
return c.json({ success: false, error: 'Invalid document type' }, 400);
|
|
104
|
+
}
|
|
105
|
+
const cancelled = await collection.cancelScheduled(context, id);
|
|
106
|
+
return c.json({ success: true, data: { cancelled } });
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
cmsLogger.error('Failed to cancel document schedule:', error);
|
|
110
|
+
if (error instanceof PermissionError) {
|
|
111
|
+
return c.json({ success: false, error: 'Forbidden', message: error.message }, 403);
|
|
112
|
+
}
|
|
113
|
+
return c.json({ success: false, error: 'Failed to cancel document schedule' }, 500);
|
|
114
|
+
}
|
|
115
|
+
})
|
|
6
116
|
.post('/:id/publish', async (c) => {
|
|
7
117
|
try {
|
|
8
118
|
const { localAPI } = c.var.aphexCMS;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/jobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AA4CzC,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,QAAQ,CAiDnC,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { authToContext } from '../../../local-api/auth-helpers.js';
|
|
4
|
+
import { hasCapability } from '../../../types/capabilities.js';
|
|
5
|
+
import { cmsLogger } from '../../../utils/logger.js';
|
|
6
|
+
// Read-only history / observability for the durable spine. Gated on `document.read`:
|
|
7
|
+
// the operational log of publish work is visible to anyone who can read content.
|
|
8
|
+
// Mirrors JobStatus (types/events) as a zod enum — the API contract's source of truth.
|
|
9
|
+
const jobStatus = z.enum(['pending', 'leased', 'completed', 'failed', 'cancelled']);
|
|
10
|
+
const listJobsQuery = z.object({
|
|
11
|
+
status: jobStatus.optional(),
|
|
12
|
+
type: z.string().optional(),
|
|
13
|
+
limit: z.coerce.number().int().min(1).max(200).optional(),
|
|
14
|
+
offset: z.coerce.number().int().min(0).optional()
|
|
15
|
+
});
|
|
16
|
+
const listEventsQuery = z.object({
|
|
17
|
+
type: z.string().optional(),
|
|
18
|
+
limit: z.coerce.number().int().min(1).max(200).optional(),
|
|
19
|
+
offset: z.coerce.number().int().min(0).optional()
|
|
20
|
+
});
|
|
21
|
+
/** Map an adapter Page into the ApiResponse `pagination` shape the client expects. */
|
|
22
|
+
function toPagination(page) {
|
|
23
|
+
const pageSize = page.limit || 1;
|
|
24
|
+
return {
|
|
25
|
+
total: page.total,
|
|
26
|
+
page: Math.floor(page.offset / pageSize) + 1,
|
|
27
|
+
pageSize,
|
|
28
|
+
totalPages: Math.max(1, Math.ceil(page.total / pageSize)),
|
|
29
|
+
hasNextPage: page.offset + page.limit < page.total,
|
|
30
|
+
hasPrevPage: page.offset > 0
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function requireHistoryAccess(c) {
|
|
34
|
+
const auth = c.var.auth;
|
|
35
|
+
if (!auth || auth.type === 'partial_session') {
|
|
36
|
+
return { error: c.json({ success: false, error: 'Authentication required' }, 401) };
|
|
37
|
+
}
|
|
38
|
+
if (!hasCapability(auth, 'document.read')) {
|
|
39
|
+
return { error: c.json({ success: false, error: 'Insufficient permissions' }, 403) };
|
|
40
|
+
}
|
|
41
|
+
return { organizationId: authToContext(auth).organizationId };
|
|
42
|
+
}
|
|
43
|
+
export const jobsRouter = new Hono()
|
|
44
|
+
.get('/jobs', async (c) => {
|
|
45
|
+
try {
|
|
46
|
+
const gate = requireHistoryAccess(c);
|
|
47
|
+
if ('error' in gate)
|
|
48
|
+
return gate.error;
|
|
49
|
+
const parsed = listJobsQuery.safeParse(c.req.query());
|
|
50
|
+
if (!parsed.success) {
|
|
51
|
+
return c.json({ success: false, error: 'Invalid query', issues: parsed.error.issues }, 400);
|
|
52
|
+
}
|
|
53
|
+
const { status, type, limit, offset } = parsed.data;
|
|
54
|
+
const { databaseAdapter } = c.var.aphexCMS;
|
|
55
|
+
const page = await databaseAdapter.listJobs({
|
|
56
|
+
organizationId: gate.organizationId,
|
|
57
|
+
status,
|
|
58
|
+
type,
|
|
59
|
+
limit,
|
|
60
|
+
offset
|
|
61
|
+
});
|
|
62
|
+
return c.json({ success: true, data: page.items, pagination: toPagination(page) });
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
cmsLogger.error('Failed to list jobs:', error);
|
|
66
|
+
return c.json({ success: false, error: 'Failed to list jobs' }, 500);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
.get('/events', async (c) => {
|
|
70
|
+
try {
|
|
71
|
+
const gate = requireHistoryAccess(c);
|
|
72
|
+
if ('error' in gate)
|
|
73
|
+
return gate.error;
|
|
74
|
+
const parsed = listEventsQuery.safeParse(c.req.query());
|
|
75
|
+
if (!parsed.success) {
|
|
76
|
+
return c.json({ success: false, error: 'Invalid query', issues: parsed.error.issues }, 400);
|
|
77
|
+
}
|
|
78
|
+
const { type, limit, offset } = parsed.data;
|
|
79
|
+
const { databaseAdapter } = c.var.aphexCMS;
|
|
80
|
+
const page = await databaseAdapter.listEvents({
|
|
81
|
+
organizationId: gate.organizationId,
|
|
82
|
+
type,
|
|
83
|
+
limit,
|
|
84
|
+
offset
|
|
85
|
+
});
|
|
86
|
+
return c.json({ success: true, data: page.items, pagination: toPagination(page) });
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
cmsLogger.error('Failed to list events:', error);
|
|
90
|
+
return c.json({ success: false, error: 'Failed to list events' }, 500);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workers-run.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/workers-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAezC,eAAO,MAAM,gBAAgB,uDAAuB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { randomUUID, timingSafeEqual } from 'node:crypto';
|
|
3
|
+
import { runJobsBatch } from '../../../jobs/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Constant-time compare of the presented bearer token against the configured secret.
|
|
6
|
+
* Length is compared first (and short-circuits), which leaks only the secret's length —
|
|
7
|
+
* acceptable, and unavoidable without hashing both sides.
|
|
8
|
+
*/
|
|
9
|
+
function secretMatches(presented, expected) {
|
|
10
|
+
const a = Buffer.from(presented);
|
|
11
|
+
const b = Buffer.from(expected);
|
|
12
|
+
if (a.length !== b.length)
|
|
13
|
+
return false;
|
|
14
|
+
return timingSafeEqual(a, b);
|
|
15
|
+
}
|
|
16
|
+
export const workersRunRouter = new Hono();
|
|
17
|
+
/**
|
|
18
|
+
* POST /api/internal/workers/run — drive one bounded batch of due jobs and return counts.
|
|
19
|
+
*
|
|
20
|
+
* Machine-to-machine: authorized by a shared secret (`Authorization: Bearer <secret>`),
|
|
21
|
+
* NOT the user capability system — platform cron (hosted) or a self-hosted worker loop
|
|
22
|
+
* calls it on a cadence. Disabled (404) unless `jobs.workerSecret` is configured, so it
|
|
23
|
+
* never exists as an unauthenticated surface by default. Bounded per call (batchSize), so
|
|
24
|
+
* a single invocation can't run unboundedly; the caller's cadence sets throughput.
|
|
25
|
+
*/
|
|
26
|
+
workersRunRouter.post('/run', async (c) => {
|
|
27
|
+
const secret = c.var.aphexCMS.config.jobs?.workerSecret;
|
|
28
|
+
// Not configured → the endpoint doesn't exist. Don't advertise it or hint at auth.
|
|
29
|
+
if (!secret)
|
|
30
|
+
return c.json({ success: false, error: 'Not found' }, 404);
|
|
31
|
+
const header = c.req.header('authorization') ?? '';
|
|
32
|
+
const presented = header.startsWith('Bearer ') ? header.slice('Bearer '.length) : '';
|
|
33
|
+
if (!presented || !secretMatches(presented, secret)) {
|
|
34
|
+
return c.json({ success: false, error: 'Unauthorized' }, 401);
|
|
35
|
+
}
|
|
36
|
+
// Shared seam: builds the handler map (built-in + app-registered) and runs one batch.
|
|
37
|
+
// The embedded poll loop calls the same helper, so the two modes can't drift.
|
|
38
|
+
const result = await runJobsBatch(c.var.aphexCMS, { workerId: `endpoint-${randomUUID()}` });
|
|
39
|
+
return c.json({ success: true, result });
|
|
40
|
+
});
|
package/dist/server/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export { AssetService } from '../services/asset-service.js';
|
|
|
16
16
|
export { RolesService } from '../services/roles-service.js';
|
|
17
17
|
export { GET as serveAssetCDN } from '../routes/assets-cdn.js';
|
|
18
18
|
export { createAphexApi, mountAphexBuiltins, toHonoHandler, type AphexEnv } from './api/index.js';
|
|
19
|
+
export * from '../jobs/index.js';
|
|
19
20
|
export * from '../schema-utils/index.js';
|
|
20
21
|
export { createHashForPublishing } from '../utils/content-hash.js';
|
|
21
22
|
export { getPreviewPerspective, type PreviewPerspective } from '../preview/perspective.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/F,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGxF,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACN,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/server/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAE/B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxF,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI5D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/F,cAAc,eAAe,CAAC;AAG9B,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGxF,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACN,QAAQ,EACR,cAAc,EACd,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACN,iBAAiB,EACjB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAC"}
|
package/dist/server/index.js
CHANGED
|
@@ -32,6 +32,8 @@ export { GET as serveAssetCDN } from '../routes/assets-cdn.js';
|
|
|
32
32
|
// Hono API app — exposed so user apps (and tests) can construct or extend
|
|
33
33
|
// the same router the SK catch-all forwards to.
|
|
34
34
|
export { createAphexApi, mountAphexBuiltins, toHonoHandler } from './api/index.js';
|
|
35
|
+
// Job execution — the DB-backed job runner (claim → run handler → complete/retry/fail).
|
|
36
|
+
export * from '../jobs/index.js';
|
|
35
37
|
// Schema utilities
|
|
36
38
|
export * from '../schema-utils/index.js';
|
|
37
39
|
// Content hash utilities (server-side)
|
|
@@ -17,6 +17,22 @@ export declare class VersionService {
|
|
|
17
17
|
* Create a version snapshot and enforce rolling retention.
|
|
18
18
|
*/
|
|
19
19
|
createVersion(db: DatabaseAdapter, organizationId: string, documentId: string, eventType: 'draft' | 'publish', data: any, userId?: string | null): Promise<DocumentVersion | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Write a version snapshot on an already-transactional adapter. The caller owns
|
|
22
|
+
* the transaction boundary and retention (call `enforceRetentionFor` post-commit).
|
|
23
|
+
* No-op when the adapter has no versioning support.
|
|
24
|
+
*/
|
|
25
|
+
snapshotTx(tx: DatabaseAdapter, organizationId: string, documentId: string, eventType: 'draft' | 'publish', data: any, userId?: string | null): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Publish + snapshot on an already-transactional adapter. Caller owns the tx
|
|
28
|
+
* and retention. Returns the published document (or null if publish was a no-op).
|
|
29
|
+
*/
|
|
30
|
+
publishTx(tx: DatabaseAdapter, organizationId: string, documentId: string): Promise<Document | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Public retention trigger for callers that manage their own transaction and
|
|
33
|
+
* therefore can't rely on `saveWithVersion`/`publishWithVersion` to run it.
|
|
34
|
+
*/
|
|
35
|
+
enforceRetentionFor(db: DatabaseAdapter, organizationId: string, documentId: string): Promise<void>;
|
|
20
36
|
/**
|
|
21
37
|
* Save draft and create version atomically using adapter transaction.
|
|
22
38
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/version-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"version-service.d.ts","sourceRoot":"","sources":["../../src/lib/services/version-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG7E;;;;;;GAMG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAI9C;;OAEG;IACG,aAAa,CAClB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAelC;;;;OAIG;IACG,UAAU,CACf,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACG,SAAS,CACd,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAoB3B;;;OAGG;IACG,mBAAmB,CACxB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAIhB;;OAEG;IACG,eAAe,CACpB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAgB3B;;OAEG;IACG,kBAAkB,CACvB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAiB3B;;OAEG;IACG,cAAc,CACnB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA0BrB,YAAY,CACjB,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,mBAAmB,CAAC;IAKzB,UAAU,CACf,EAAE,EAAE,eAAe,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAKpB,gBAAgB;CAuB9B"}
|