@aglyn/aglyn 1.0.0-beta.143
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 +201 -0
- package/README.md +11 -0
- package/package.json +66 -0
- package/src/index.d.ts +25 -0
- package/src/index.js +26 -0
- package/src/index.js.map +1 -0
- package/src/lib/aglyn.d.ts +31 -0
- package/src/lib/aglyn.js +114 -0
- package/src/lib/aglyn.js.map +1 -0
- package/src/lib/app-utils/abuse-report.d.ts +193 -0
- package/src/lib/app-utils/abuse-report.js +321 -0
- package/src/lib/app-utils/abuse-report.js.map +1 -0
- package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
- package/src/lib/app-utils/accept-negotiation.js +266 -0
- package/src/lib/app-utils/accept-negotiation.js.map +1 -0
- package/src/lib/app-utils/account-emails.d.ts +263 -0
- package/src/lib/app-utils/account-emails.js +264 -0
- package/src/lib/app-utils/account-emails.js.map +1 -0
- package/src/lib/app-utils/actions.d.ts +717 -0
- package/src/lib/app-utils/actions.js +1031 -0
- package/src/lib/app-utils/actions.js.map +1 -0
- package/src/lib/app-utils/activity-presenter.d.ts +152 -0
- package/src/lib/app-utils/activity-presenter.js +326 -0
- package/src/lib/app-utils/activity-presenter.js.map +1 -0
- package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
- package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
- package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
- package/src/lib/app-utils/advertising-tags.d.ts +307 -0
- package/src/lib/app-utils/advertising-tags.js +525 -0
- package/src/lib/app-utils/advertising-tags.js.map +1 -0
- package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
- package/src/lib/app-utils/agent-api-catalog.js +106 -0
- package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
- package/src/lib/app-utils/agent-openapi.d.ts +103 -0
- package/src/lib/app-utils/agent-openapi.js +1128 -0
- package/src/lib/app-utils/agent-openapi.js.map +1 -0
- package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
- package/src/lib/app-utils/analytics-beacon.js +152 -0
- package/src/lib/app-utils/analytics-beacon.js.map +1 -0
- package/src/lib/app-utils/analytics-environment.d.ts +133 -0
- package/src/lib/app-utils/analytics-environment.js +152 -0
- package/src/lib/app-utils/analytics-environment.js.map +1 -0
- package/src/lib/app-utils/analytics-events.d.ts +744 -0
- package/src/lib/app-utils/analytics-events.js +650 -0
- package/src/lib/app-utils/analytics-events.js.map +1 -0
- package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
- package/src/lib/app-utils/analytics-link-clicks.js +267 -0
- package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
- package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
- package/src/lib/app-utils/analytics-path-key.js +46 -0
- package/src/lib/app-utils/analytics-path-key.js.map +1 -0
- package/src/lib/app-utils/api-adapter.d.ts +47 -0
- package/src/lib/app-utils/api-adapter.js +367 -0
- package/src/lib/app-utils/api-adapter.js.map +1 -0
- package/src/lib/app-utils/api-idempotency.d.ts +169 -0
- package/src/lib/app-utils/api-idempotency.js +213 -0
- package/src/lib/app-utils/api-idempotency.js.map +1 -0
- package/src/lib/app-utils/api-plugins.d.ts +210 -0
- package/src/lib/app-utils/api-plugins.js +221 -0
- package/src/lib/app-utils/api-plugins.js.map +1 -0
- package/src/lib/app-utils/assist-credits.d.ts +482 -0
- package/src/lib/app-utils/assist-credits.js +509 -0
- package/src/lib/app-utils/assist-credits.js.map +1 -0
- package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
- package/src/lib/app-utils/attribution-attribute.js +34 -0
- package/src/lib/app-utils/attribution-attribute.js.map +1 -0
- package/src/lib/app-utils/attribution-guard.d.ts +130 -0
- package/src/lib/app-utils/attribution-guard.js +410 -0
- package/src/lib/app-utils/attribution-guard.js.map +1 -0
- package/src/lib/app-utils/author-css.d.ts +123 -0
- package/src/lib/app-utils/author-css.js +275 -0
- package/src/lib/app-utils/author-css.js.map +1 -0
- package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
- package/src/lib/app-utils/author-html-markdown.js +497 -0
- package/src/lib/app-utils/author-html-markdown.js.map +1 -0
- package/src/lib/app-utils/author-html.d.ts +135 -0
- package/src/lib/app-utils/author-html.js +1037 -0
- package/src/lib/app-utils/author-html.js.map +1 -0
- package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
- package/src/lib/app-utils/automation-placeholders.js +207 -0
- package/src/lib/app-utils/automation-placeholders.js.map +1 -0
- package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
- package/src/lib/app-utils/bandwidth-cap.js +193 -0
- package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
- package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
- package/src/lib/app-utils/binding-token-catalog.js +293 -0
- package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
- package/src/lib/app-utils/binding-tokens.d.ts +157 -0
- package/src/lib/app-utils/binding-tokens.js +251 -0
- package/src/lib/app-utils/binding-tokens.js.map +1 -0
- package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
- package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
- package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
- package/src/lib/app-utils/campaign-attribution.js +162 -0
- package/src/lib/app-utils/campaign-attribution.js.map +1 -0
- package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
- package/src/lib/app-utils/campaign-forwarding.js +332 -0
- package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
- package/src/lib/app-utils/campaign-membership.d.ts +109 -0
- package/src/lib/app-utils/campaign-membership.js +176 -0
- package/src/lib/app-utils/campaign-membership.js.map +1 -0
- package/src/lib/app-utils/campaign-touch.d.ts +206 -0
- package/src/lib/app-utils/campaign-touch.js +326 -0
- package/src/lib/app-utils/campaign-touch.js.map +1 -0
- package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
- package/src/lib/app-utils/child-contract-compose.js +140 -0
- package/src/lib/app-utils/child-contract-compose.js.map +1 -0
- package/src/lib/app-utils/child-contract.d.ts +129 -0
- package/src/lib/app-utils/child-contract.js +153 -0
- package/src/lib/app-utils/child-contract.js.map +1 -0
- package/src/lib/app-utils/collection-delete.d.ts +113 -0
- package/src/lib/app-utils/collection-delete.js +120 -0
- package/src/lib/app-utils/collection-delete.js.map +1 -0
- package/src/lib/app-utils/collection-entries.d.ts +833 -0
- package/src/lib/app-utils/collection-entries.js +1285 -0
- package/src/lib/app-utils/collection-entries.js.map +1 -0
- package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
- package/src/lib/app-utils/collection-entry-date.js +183 -0
- package/src/lib/app-utils/collection-entry-date.js.map +1 -0
- package/src/lib/app-utils/collection-kind.d.ts +55 -0
- package/src/lib/app-utils/collection-kind.js +69 -0
- package/src/lib/app-utils/collection-kind.js.map +1 -0
- package/src/lib/app-utils/collection-slug.d.ts +79 -0
- package/src/lib/app-utils/collection-slug.js +70 -0
- package/src/lib/app-utils/collection-slug.js.map +1 -0
- package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
- package/src/lib/app-utils/compose-layout-nodes.js +261 -0
- package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
- package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
- package/src/lib/app-utils/compose-layout-props.js +61 -0
- package/src/lib/app-utils/compose-layout-props.js.map +1 -0
- package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
- package/src/lib/app-utils/compose-reusable-components.js +1366 -0
- package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
- package/src/lib/app-utils/compress.d.ts +35 -0
- package/src/lib/app-utils/compress.js +38 -0
- package/src/lib/app-utils/compress.js.map +1 -0
- package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
- package/src/lib/app-utils/consent-banner-ui.js +583 -0
- package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
- package/src/lib/app-utils/consent-groups.d.ts +189 -0
- package/src/lib/app-utils/consent-groups.js +219 -0
- package/src/lib/app-utils/consent-groups.js.map +1 -0
- package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
- package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
- package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
- package/src/lib/app-utils/console-record-links.d.ts +163 -0
- package/src/lib/app-utils/console-record-links.js +178 -0
- package/src/lib/app-utils/console-record-links.js.map +1 -0
- package/src/lib/app-utils/console-routes.d.ts +658 -0
- package/src/lib/app-utils/console-routes.js +489 -0
- package/src/lib/app-utils/console-routes.js.map +1 -0
- package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
- package/src/lib/app-utils/console-widget-slot-context.js +23 -0
- package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
- package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
- package/src/lib/app-utils/contact-custom-fields.js +349 -0
- package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
- package/src/lib/app-utils/contact-holder.d.ts +52 -0
- package/src/lib/app-utils/contact-holder.js +98 -0
- package/src/lib/app-utils/contact-holder.js.map +1 -0
- package/src/lib/app-utils/contact-merge.d.ts +136 -0
- package/src/lib/app-utils/contact-merge.js +379 -0
- package/src/lib/app-utils/contact-merge.js.map +1 -0
- package/src/lib/app-utils/contacts.d.ts +554 -0
- package/src/lib/app-utils/contacts.js +401 -0
- package/src/lib/app-utils/contacts.js.map +1 -0
- package/src/lib/app-utils/content-author-profile.d.ts +68 -0
- package/src/lib/app-utils/content-author-profile.js +118 -0
- package/src/lib/app-utils/content-author-profile.js.map +1 -0
- package/src/lib/app-utils/content-authors.d.ts +662 -0
- package/src/lib/app-utils/content-authors.js +771 -0
- package/src/lib/app-utils/content-authors.js.map +1 -0
- package/src/lib/app-utils/content-schema-type.d.ts +81 -0
- package/src/lib/app-utils/content-schema-type.js +87 -0
- package/src/lib/app-utils/content-schema-type.js.map +1 -0
- package/src/lib/app-utils/contexts.d.ts +35 -0
- package/src/lib/app-utils/contexts.js +35 -0
- package/src/lib/app-utils/contexts.js.map +1 -0
- package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
- package/src/lib/app-utils/create-resource-uid.js +23 -0
- package/src/lib/app-utils/create-resource-uid.js.map +1 -0
- package/src/lib/app-utils/crm-booking.d.ts +75 -0
- package/src/lib/app-utils/crm-booking.js +133 -0
- package/src/lib/app-utils/crm-booking.js.map +1 -0
- package/src/lib/app-utils/crm-csv.d.ts +232 -0
- package/src/lib/app-utils/crm-csv.js +432 -0
- package/src/lib/app-utils/crm-csv.js.map +1 -0
- package/src/lib/app-utils/crm-digest.d.ts +179 -0
- package/src/lib/app-utils/crm-digest.js +271 -0
- package/src/lib/app-utils/crm-digest.js.map +1 -0
- package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
- package/src/lib/app-utils/crm-email-templates.js +382 -0
- package/src/lib/app-utils/crm-email-templates.js.map +1 -0
- package/src/lib/app-utils/crm-inbound.d.ts +245 -0
- package/src/lib/app-utils/crm-inbound.js +407 -0
- package/src/lib/app-utils/crm-inbound.js.map +1 -0
- package/src/lib/app-utils/crm-kinds.d.ts +73 -0
- package/src/lib/app-utils/crm-kinds.js +92 -0
- package/src/lib/app-utils/crm-kinds.js.map +1 -0
- package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
- package/src/lib/app-utils/crm-next-activity.js +140 -0
- package/src/lib/app-utils/crm-next-activity.js.map +1 -0
- package/src/lib/app-utils/crm-reports.d.ts +479 -0
- package/src/lib/app-utils/crm-reports.js +680 -0
- package/src/lib/app-utils/crm-reports.js.map +1 -0
- package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
- package/src/lib/app-utils/crm-task-reminders.js +139 -0
- package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
- package/src/lib/app-utils/crm.d.ts +1546 -0
- package/src/lib/app-utils/crm.js +1814 -0
- package/src/lib/app-utils/crm.js.map +1 -0
- package/src/lib/app-utils/csp-report.d.ts +84 -0
- package/src/lib/app-utils/csp-report.js +177 -0
- package/src/lib/app-utils/csp-report.js.map +1 -0
- package/src/lib/app-utils/csv-import.d.ts +192 -0
- package/src/lib/app-utils/csv-import.js +279 -0
- package/src/lib/app-utils/csv-import.js.map +1 -0
- package/src/lib/app-utils/dataset-csv.d.ts +109 -0
- package/src/lib/app-utils/dataset-csv.js +235 -0
- package/src/lib/app-utils/dataset-csv.js.map +1 -0
- package/src/lib/app-utils/dataset-models.d.ts +194 -0
- package/src/lib/app-utils/dataset-models.js +409 -0
- package/src/lib/app-utils/dataset-models.js.map +1 -0
- package/src/lib/app-utils/dataset-query.d.ts +57 -0
- package/src/lib/app-utils/dataset-query.js +126 -0
- package/src/lib/app-utils/dataset-query.js.map +1 -0
- package/src/lib/app-utils/datasets.d.ts +136 -0
- package/src/lib/app-utils/datasets.js +177 -0
- package/src/lib/app-utils/datasets.js.map +1 -0
- package/src/lib/app-utils/decompress.d.ts +36 -0
- package/src/lib/app-utils/decompress.js +32 -0
- package/src/lib/app-utils/decompress.js.map +1 -0
- package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
- package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
- package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
- package/src/lib/app-utils/deferred-image.d.ts +86 -0
- package/src/lib/app-utils/deferred-image.js +83 -0
- package/src/lib/app-utils/deferred-image.js.map +1 -0
- package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
- package/src/lib/app-utils/definition-canvas-tree.js +126 -0
- package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
- package/src/lib/app-utils/deployment-shape.d.ts +167 -0
- package/src/lib/app-utils/deployment-shape.js +238 -0
- package/src/lib/app-utils/deployment-shape.js.map +1 -0
- package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
- package/src/lib/app-utils/detect-template-placeholders.js +53 -0
- package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
- package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
- package/src/lib/app-utils/dmca-counter-notice.js +277 -0
- package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
- package/src/lib/app-utils/docs-deflection.d.ts +156 -0
- package/src/lib/app-utils/docs-deflection.js +547 -0
- package/src/lib/app-utils/docs-deflection.js.map +1 -0
- package/src/lib/app-utils/docs-help.d.ts +57 -0
- package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
- package/src/lib/app-utils/docs-help.generated.js +867 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -0
- package/src/lib/app-utils/docs-help.js +46 -0
- package/src/lib/app-utils/docs-help.js.map +1 -0
- package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
- package/src/lib/app-utils/docs-index.generated.js +8388 -0
- package/src/lib/app-utils/docs-index.generated.js.map +1 -0
- package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
- package/src/lib/app-utils/docs-retrieval.js +188 -0
- package/src/lib/app-utils/docs-retrieval.js.map +1 -0
- package/src/lib/app-utils/document-landmark.d.ts +50 -0
- package/src/lib/app-utils/document-landmark.js +100 -0
- package/src/lib/app-utils/document-landmark.js.map +1 -0
- package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
- package/src/lib/app-utils/duplicate-resource.js +206 -0
- package/src/lib/app-utils/duplicate-resource.js.map +1 -0
- package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
- package/src/lib/app-utils/dynamic-list-rule.js +914 -0
- package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
- package/src/lib/app-utils/element-animation.d.ts +200 -0
- package/src/lib/app-utils/element-animation.js +233 -0
- package/src/lib/app-utils/element-animation.js.map +1 -0
- package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
- package/src/lib/app-utils/element-hidden-style.js +48 -0
- package/src/lib/app-utils/element-hidden-style.js.map +1 -0
- package/src/lib/app-utils/element-ui.d.ts +243 -0
- package/src/lib/app-utils/element-ui.js +459 -0
- package/src/lib/app-utils/element-ui.js.map +1 -0
- package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
- package/src/lib/app-utils/email-starter-policy.js +327 -0
- package/src/lib/app-utils/email-starter-policy.js.map +1 -0
- package/src/lib/app-utils/email-topics.d.ts +310 -0
- package/src/lib/app-utils/email-topics.js +336 -0
- package/src/lib/app-utils/email-topics.js.map +1 -0
- package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
- package/src/lib/app-utils/enabled-plugins-context.js +113 -0
- package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
- package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
- package/src/lib/app-utils/ensure-canvas-root.js +61 -0
- package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
- package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
- package/src/lib/app-utils/entity-picker-context.js +93 -0
- package/src/lib/app-utils/entity-picker-context.js.map +1 -0
- package/src/lib/app-utils/error-beacon.d.ts +107 -0
- package/src/lib/app-utils/error-beacon.js +296 -0
- package/src/lib/app-utils/error-beacon.js.map +1 -0
- package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
- package/src/lib/app-utils/expand-repeatables.js +299 -0
- package/src/lib/app-utils/expand-repeatables.js.map +1 -0
- package/src/lib/app-utils/foreign-script.d.ts +82 -0
- package/src/lib/app-utils/foreign-script.js +102 -0
- package/src/lib/app-utils/foreign-script.js.map +1 -0
- package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
- package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
- package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
- package/src/lib/app-utils/form-contract.d.ts +198 -0
- package/src/lib/app-utils/form-contract.js +282 -0
- package/src/lib/app-utils/form-contract.js.map +1 -0
- package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
- package/src/lib/app-utils/form-dataset-binding.js +74 -0
- package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
- package/src/lib/app-utils/forms.d.ts +727 -0
- package/src/lib/app-utils/forms.js +777 -0
- package/src/lib/app-utils/forms.js.map +1 -0
- package/src/lib/app-utils/functions.d.ts +188 -0
- package/src/lib/app-utils/functions.js +529 -0
- package/src/lib/app-utils/functions.js.map +1 -0
- package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
- package/src/lib/app-utils/guarded-version-save.js +131 -0
- package/src/lib/app-utils/guarded-version-save.js.map +1 -0
- package/src/lib/app-utils/health-report.d.ts +1766 -0
- package/src/lib/app-utils/health-report.js +2072 -0
- package/src/lib/app-utils/health-report.js.map +1 -0
- package/src/lib/app-utils/host-naming.d.ts +135 -0
- package/src/lib/app-utils/host-naming.js +188 -0
- package/src/lib/app-utils/host-naming.js.map +1 -0
- package/src/lib/app-utils/host-permissions.d.ts +76 -0
- package/src/lib/app-utils/host-permissions.js +119 -0
- package/src/lib/app-utils/host-permissions.js.map +1 -0
- package/src/lib/app-utils/host-tokens.d.ts +228 -0
- package/src/lib/app-utils/host-tokens.js +304 -0
- package/src/lib/app-utils/host-tokens.js.map +1 -0
- package/src/lib/app-utils/idp-profile.d.ts +83 -0
- package/src/lib/app-utils/idp-profile.js +268 -0
- package/src/lib/app-utils/idp-profile.js.map +1 -0
- package/src/lib/app-utils/image-upload-types.d.ts +49 -0
- package/src/lib/app-utils/image-upload-types.js +86 -0
- package/src/lib/app-utils/image-upload-types.js.map +1 -0
- package/src/lib/app-utils/index.d.ts +18 -0
- package/src/lib/app-utils/index.js +23 -0
- package/src/lib/app-utils/index.js.map +1 -0
- package/src/lib/app-utils/internal-traffic.d.ts +197 -0
- package/src/lib/app-utils/internal-traffic.js +288 -0
- package/src/lib/app-utils/internal-traffic.js.map +1 -0
- package/src/lib/app-utils/lineal-order.d.ts +62 -0
- package/src/lib/app-utils/lineal-order.js +65 -0
- package/src/lib/app-utils/lineal-order.js.map +1 -0
- package/src/lib/app-utils/link-references.d.ts +36 -0
- package/src/lib/app-utils/link-references.js +89 -0
- package/src/lib/app-utils/link-references.js.map +1 -0
- package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
- package/src/lib/app-utils/link-target-search-context.js +221 -0
- package/src/lib/app-utils/link-target-search-context.js.map +1 -0
- package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
- package/src/lib/app-utils/list-assignment-policy.js +170 -0
- package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
- package/src/lib/app-utils/list-import.d.ts +158 -0
- package/src/lib/app-utils/list-import.js +332 -0
- package/src/lib/app-utils/list-import.js.map +1 -0
- package/src/lib/app-utils/llms-txt.d.ts +104 -0
- package/src/lib/app-utils/llms-txt.js +144 -0
- package/src/lib/app-utils/llms-txt.js.map +1 -0
- package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
- package/src/lib/app-utils/local-storage-budget.js +153 -0
- package/src/lib/app-utils/local-storage-budget.js.map +1 -0
- package/src/lib/app-utils/lockdown.d.ts +698 -0
- package/src/lib/app-utils/lockdown.js +929 -0
- package/src/lib/app-utils/lockdown.js.map +1 -0
- package/src/lib/app-utils/margin-utilization.d.ts +267 -0
- package/src/lib/app-utils/margin-utilization.js +351 -0
- package/src/lib/app-utils/margin-utilization.js.map +1 -0
- package/src/lib/app-utils/markdown-lite.d.ts +297 -0
- package/src/lib/app-utils/markdown-lite.js +705 -0
- package/src/lib/app-utils/markdown-lite.js.map +1 -0
- package/src/lib/app-utils/marketing-consent.d.ts +704 -0
- package/src/lib/app-utils/marketing-consent.js +783 -0
- package/src/lib/app-utils/marketing-consent.js.map +1 -0
- package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
- package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
- package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
- package/src/lib/app-utils/marketplace-overrides.js +462 -0
- package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
- package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
- package/src/lib/app-utils/marketplace-provenance.js +136 -0
- package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
- package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
- package/src/lib/app-utils/marketplace-theme.js +525 -0
- package/src/lib/app-utils/marketplace-theme.js.map +1 -0
- package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
- package/src/lib/app-utils/marketplace-update-state.js +132 -0
- package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
- package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
- package/src/lib/app-utils/marketplace-verification.js +81 -0
- package/src/lib/app-utils/marketplace-verification.js.map +1 -0
- package/src/lib/app-utils/measure-node-map.d.ts +76 -0
- package/src/lib/app-utils/measure-node-map.js +111 -0
- package/src/lib/app-utils/measure-node-map.js.map +1 -0
- package/src/lib/app-utils/media-alt.d.ts +55 -0
- package/src/lib/app-utils/media-alt.js +58 -0
- package/src/lib/app-utils/media-alt.js.map +1 -0
- package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
- package/src/lib/app-utils/media-asset-facts.js +467 -0
- package/src/lib/app-utils/media-asset-facts.js.map +1 -0
- package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
- package/src/lib/app-utils/media-cdn-scope.js +75 -0
- package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
- package/src/lib/app-utils/media-folders.d.ts +161 -0
- package/src/lib/app-utils/media-folders.js +230 -0
- package/src/lib/app-utils/media-folders.js.map +1 -0
- package/src/lib/app-utils/media-metadata.d.ts +277 -0
- package/src/lib/app-utils/media-metadata.js +388 -0
- package/src/lib/app-utils/media-metadata.js.map +1 -0
- package/src/lib/app-utils/media-picker-context.d.ts +93 -0
- package/src/lib/app-utils/media-picker-context.js +26 -0
- package/src/lib/app-utils/media-picker-context.js.map +1 -0
- package/src/lib/app-utils/media-quarantine.d.ts +247 -0
- package/src/lib/app-utils/media-quarantine.js +323 -0
- package/src/lib/app-utils/media-quarantine.js.map +1 -0
- package/src/lib/app-utils/media-ref.d.ts +661 -0
- package/src/lib/app-utils/media-ref.js +1055 -0
- package/src/lib/app-utils/media-ref.js.map +1 -0
- package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
- package/src/lib/app-utils/media-takedown-reach.js +143 -0
- package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
- package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
- package/src/lib/app-utils/member-email-aliases.js +217 -0
- package/src/lib/app-utils/member-email-aliases.js.map +1 -0
- package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
- package/src/lib/app-utils/merge-node-sx.js +123 -0
- package/src/lib/app-utils/merge-node-sx.js.map +1 -0
- package/src/lib/app-utils/name-match.d.ts +155 -0
- package/src/lib/app-utils/name-match.js +175 -0
- package/src/lib/app-utils/name-match.js.map +1 -0
- package/src/lib/app-utils/name-search.d.ts +117 -0
- package/src/lib/app-utils/name-search.js +145 -0
- package/src/lib/app-utils/name-search.js.map +1 -0
- package/src/lib/app-utils/node-capabilities.d.ts +85 -0
- package/src/lib/app-utils/node-capabilities.js +88 -0
- package/src/lib/app-utils/node-capabilities.js.map +1 -0
- package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
- package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
- package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
- package/src/lib/app-utils/node-identity.d.ts +47 -0
- package/src/lib/app-utils/node-identity.js +50 -0
- package/src/lib/app-utils/node-identity.js.map +1 -0
- package/src/lib/app-utils/node-interactions.d.ts +102 -0
- package/src/lib/app-utils/node-interactions.js +192 -0
- package/src/lib/app-utils/node-interactions.js.map +1 -0
- package/src/lib/app-utils/node-url-policy.d.ts +54 -0
- package/src/lib/app-utils/node-url-policy.js +72 -0
- package/src/lib/app-utils/node-url-policy.js.map +1 -0
- package/src/lib/app-utils/notifications.d.ts +71 -0
- package/src/lib/app-utils/notifications.js +101 -0
- package/src/lib/app-utils/notifications.js.map +1 -0
- package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
- package/src/lib/app-utils/onboarding-deep-link.js +142 -0
- package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
- package/src/lib/app-utils/operator-identity.d.ts +207 -0
- package/src/lib/app-utils/operator-identity.js +186 -0
- package/src/lib/app-utils/operator-identity.js.map +1 -0
- package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
- package/src/lib/app-utils/org-billing-doc.js +238 -0
- package/src/lib/app-utils/org-billing-doc.js.map +1 -0
- package/src/lib/app-utils/org-override-reason.d.ts +100 -0
- package/src/lib/app-utils/org-override-reason.js +116 -0
- package/src/lib/app-utils/org-override-reason.js.map +1 -0
- package/src/lib/app-utils/org-permissions.d.ts +194 -0
- package/src/lib/app-utils/org-permissions.js +357 -0
- package/src/lib/app-utils/org-permissions.js.map +1 -0
- package/src/lib/app-utils/org-roles.d.ts +72 -0
- package/src/lib/app-utils/org-roles.js +131 -0
- package/src/lib/app-utils/org-roles.js.map +1 -0
- package/src/lib/app-utils/organizations.d.ts +407 -0
- package/src/lib/app-utils/organizations.js +511 -0
- package/src/lib/app-utils/organizations.js.map +1 -0
- package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
- package/src/lib/app-utils/page-header-actions-context.js +58 -0
- package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
- package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
- package/src/lib/app-utils/page-header-record-context.js +64 -0
- package/src/lib/app-utils/page-header-record-context.js.map +1 -0
- package/src/lib/app-utils/page-markdown.d.ts +103 -0
- package/src/lib/app-utils/page-markdown.js +385 -0
- package/src/lib/app-utils/page-markdown.js.map +1 -0
- package/src/lib/app-utils/paid-media-source.d.ts +90 -0
- package/src/lib/app-utils/paid-media-source.js +184 -0
- package/src/lib/app-utils/paid-media-source.js.map +1 -0
- package/src/lib/app-utils/palette-sx.d.ts +34 -0
- package/src/lib/app-utils/palette-sx.js +150 -0
- package/src/lib/app-utils/palette-sx.js.map +1 -0
- package/src/lib/app-utils/password-policy.d.ts +47 -0
- package/src/lib/app-utils/password-policy.js +46 -0
- package/src/lib/app-utils/password-policy.js.map +1 -0
- package/src/lib/app-utils/payments-configured.d.ts +84 -0
- package/src/lib/app-utils/payments-configured.js +88 -0
- package/src/lib/app-utils/payments-configured.js.map +1 -0
- package/src/lib/app-utils/person-erasure.d.ts +126 -0
- package/src/lib/app-utils/person-erasure.js +121 -0
- package/src/lib/app-utils/person-erasure.js.map +1 -0
- package/src/lib/app-utils/person-key.d.ts +32 -0
- package/src/lib/app-utils/person-key.js +62 -0
- package/src/lib/app-utils/person-key.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
- package/src/lib/app-utils/plan-entitlements.js +4085 -0
- package/src/lib/app-utils/plan-entitlements.js.map +1 -0
- package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
- package/src/lib/app-utils/platform-ad-conversions.js +174 -0
- package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
- package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
- package/src/lib/app-utils/platform-advertising-tags.js +203 -0
- package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
- package/src/lib/app-utils/platform-brand.d.ts +151 -0
- package/src/lib/app-utils/platform-brand.js +175 -0
- package/src/lib/app-utils/platform-brand.js.map +1 -0
- package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
- package/src/lib/app-utils/platform-consent-default.js +295 -0
- package/src/lib/app-utils/platform-consent-default.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
- package/src/lib/app-utils/platform-marketing-consent.js +182 -0
- package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
- package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
- package/src/lib/app-utils/platform-marketing-host.js +97 -0
- package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
- package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
- package/src/lib/app-utils/platform-visitor-consent.js +533 -0
- package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
- package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
- package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
- package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
- package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
- package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
- package/src/lib/app-utils/plugin-artifact-path.js +33 -0
- package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
- package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
- package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
- package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
- package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
- package/src/lib/app-utils/plugin-manifest.js +687 -0
- package/src/lib/app-utils/plugin-manifest.js.map +1 -0
- package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
- package/src/lib/app-utils/published-legal-pages.js +90 -0
- package/src/lib/app-utils/published-legal-pages.js.map +1 -0
- package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
- package/src/lib/app-utils/publisher-agreement.js +274 -0
- package/src/lib/app-utils/publisher-agreement.js.map +1 -0
- package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
- package/src/lib/app-utils/publisher-attestation.js +158 -0
- package/src/lib/app-utils/publisher-attestation.js.map +1 -0
- package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
- package/src/lib/app-utils/recipient-email-render.js +221 -0
- package/src/lib/app-utils/recipient-email-render.js.map +1 -0
- package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
- package/src/lib/app-utils/redispatch-caught-error.js +46 -0
- package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
- package/src/lib/app-utils/registering-plugin.d.ts +19 -0
- package/src/lib/app-utils/registering-plugin.js +38 -0
- package/src/lib/app-utils/registering-plugin.js.map +1 -0
- package/src/lib/app-utils/release-flags.d.ts +283 -0
- package/src/lib/app-utils/release-flags.js +518 -0
- package/src/lib/app-utils/release-flags.js.map +1 -0
- package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
- package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
- package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
- package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
- package/src/lib/app-utils/repeat-infringer.js +188 -0
- package/src/lib/app-utils/repeat-infringer.js.map +1 -0
- package/src/lib/app-utils/repeat-sources.d.ts +115 -0
- package/src/lib/app-utils/repeat-sources.js +86 -0
- package/src/lib/app-utils/repeat-sources.js.map +1 -0
- package/src/lib/app-utils/request-geo.d.ts +114 -0
- package/src/lib/app-utils/request-geo.js +247 -0
- package/src/lib/app-utils/request-geo.js.map +1 -0
- package/src/lib/app-utils/request-ip.d.ts +213 -0
- package/src/lib/app-utils/request-ip.js +344 -0
- package/src/lib/app-utils/request-ip.js.map +1 -0
- package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
- package/src/lib/app-utils/resolve-named-tokens.js +59 -0
- package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
- package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
- package/src/lib/app-utils/responsive-typography-sx.js +122 -0
- package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
- package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
- package/src/lib/app-utils/reusable-component-keys.js +140 -0
- package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
- package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
- package/src/lib/app-utils/reusable-prop-values.js +494 -0
- package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
- package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
- package/src/lib/app-utils/safe-json-ld.js +37 -0
- package/src/lib/app-utils/safe-json-ld.js.map +1 -0
- package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
- package/src/lib/app-utils/sanitize-svg.js +460 -0
- package/src/lib/app-utils/sanitize-svg.js.map +1 -0
- package/src/lib/app-utils/scheme-sx.d.ts +84 -0
- package/src/lib/app-utils/scheme-sx.js +148 -0
- package/src/lib/app-utils/scheme-sx.js.map +1 -0
- package/src/lib/app-utils/scope-tokens.d.ts +249 -0
- package/src/lib/app-utils/scope-tokens.js +331 -0
- package/src/lib/app-utils/scope-tokens.js.map +1 -0
- package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
- package/src/lib/app-utils/screen-link-context-value.js +43 -0
- package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
- package/src/lib/app-utils/screen-link-context.d.ts +185 -0
- package/src/lib/app-utils/screen-link-context.js +304 -0
- package/src/lib/app-utils/screen-link-context.js.map +1 -0
- package/src/lib/app-utils/screen-link-value.d.ts +269 -0
- package/src/lib/app-utils/screen-link-value.js +384 -0
- package/src/lib/app-utils/screen-link-value.js.map +1 -0
- package/src/lib/app-utils/screen-route.d.ts +669 -0
- package/src/lib/app-utils/screen-route.js +751 -0
- package/src/lib/app-utils/screen-route.js.map +1 -0
- package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
- package/src/lib/app-utils/screen-seo-fields.js +42 -0
- package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
- package/src/lib/app-utils/search-indexing.d.ts +162 -0
- package/src/lib/app-utils/search-indexing.js +207 -0
- package/src/lib/app-utils/search-indexing.js.map +1 -0
- package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
- package/src/lib/app-utils/seo-listing-fields.js +75 -0
- package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
- package/src/lib/app-utils/seo-locale.d.ts +119 -0
- package/src/lib/app-utils/seo-locale.js +133 -0
- package/src/lib/app-utils/seo-locale.js.map +1 -0
- package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
- package/src/lib/app-utils/seo-title-variables.js +190 -0
- package/src/lib/app-utils/seo-title-variables.js.map +1 -0
- package/src/lib/app-utils/seo-title.d.ts +70 -0
- package/src/lib/app-utils/seo-title.js +117 -0
- package/src/lib/app-utils/seo-title.js.map +1 -0
- package/src/lib/app-utils/server.d.ts +174 -0
- package/src/lib/app-utils/server.js +314 -0
- package/src/lib/app-utils/server.js.map +1 -0
- package/src/lib/app-utils/site-context.d.ts +106 -0
- package/src/lib/app-utils/site-context.js +100 -0
- package/src/lib/app-utils/site-context.js.map +1 -0
- package/src/lib/app-utils/sitemap.d.ts +117 -0
- package/src/lib/app-utils/sitemap.js +183 -0
- package/src/lib/app-utils/sitemap.js.map +1 -0
- package/src/lib/app-utils/social-image.d.ts +112 -0
- package/src/lib/app-utils/social-image.js +191 -0
- package/src/lib/app-utils/social-image.js.map +1 -0
- package/src/lib/app-utils/starter-templates.d.ts +99 -0
- package/src/lib/app-utils/starter-templates.js +579 -0
- package/src/lib/app-utils/starter-templates.js.map +1 -0
- package/src/lib/app-utils/stored-nodes.d.ts +120 -0
- package/src/lib/app-utils/stored-nodes.js +174 -0
- package/src/lib/app-utils/stored-nodes.js.map +1 -0
- package/src/lib/app-utils/strip-undefined.d.ts +59 -0
- package/src/lib/app-utils/strip-undefined.js +95 -0
- package/src/lib/app-utils/strip-undefined.js.map +1 -0
- package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
- package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
- package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
- package/src/lib/app-utils/support-tiers.d.ts +108 -0
- package/src/lib/app-utils/support-tiers.js +201 -0
- package/src/lib/app-utils/support-tiers.js.map +1 -0
- package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
- package/src/lib/app-utils/timezone-geo-hint.js +180 -0
- package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
- package/src/lib/app-utils/upload-cors.d.ts +155 -0
- package/src/lib/app-utils/upload-cors.js +254 -0
- package/src/lib/app-utils/upload-cors.js.map +1 -0
- package/src/lib/app-utils/upload-inspection.d.ts +159 -0
- package/src/lib/app-utils/upload-inspection.js +539 -0
- package/src/lib/app-utils/upload-inspection.js.map +1 -0
- package/src/lib/app-utils/url-slug.d.ts +40 -0
- package/src/lib/app-utils/url-slug.js +42 -0
- package/src/lib/app-utils/url-slug.js.map +1 -0
- package/src/lib/app-utils/usage-budget.d.ts +429 -0
- package/src/lib/app-utils/usage-budget.js +421 -0
- package/src/lib/app-utils/usage-budget.js.map +1 -0
- package/src/lib/app-utils/variables.d.ts +96 -0
- package/src/lib/app-utils/variables.js +233 -0
- package/src/lib/app-utils/variables.js.map +1 -0
- package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
- package/src/lib/app-utils/video-asset-facts.js +70 -0
- package/src/lib/app-utils/video-asset-facts.js.map +1 -0
- package/src/lib/app-utils/video-object.d.ts +89 -0
- package/src/lib/app-utils/video-object.js +245 -0
- package/src/lib/app-utils/video-object.js.map +1 -0
- package/src/lib/app-utils/visitor-consent.d.ts +757 -0
- package/src/lib/app-utils/visitor-consent.js +981 -0
- package/src/lib/app-utils/visitor-consent.js.map +1 -0
- package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
- package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
- package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
- package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
- package/src/lib/app-utils/web-vitals-rum.js +278 -0
- package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
- package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
- package/src/lib/app-utils/webhook-delivery.js +413 -0
- package/src/lib/app-utils/webhook-delivery.js.map +1 -0
- package/src/lib/app-utils/where-used.d.ts +57 -0
- package/src/lib/app-utils/where-used.js +59 -0
- package/src/lib/app-utils/where-used.js.map +1 -0
- package/src/lib/app-utils/wistia-embed.d.ts +86 -0
- package/src/lib/app-utils/wistia-embed.js +119 -0
- package/src/lib/app-utils/wistia-embed.js.map +1 -0
- package/src/lib/app-utils/workflows.d.ts +136 -0
- package/src/lib/app-utils/workflows.js +346 -0
- package/src/lib/app-utils/workflows.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
- package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
- package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
- package/src/lib/canvas-manager/canvas-manager.js +1311 -0
- package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
- package/src/lib/canvas-manager/index.d.ts +20 -0
- package/src/lib/canvas-manager/index.js +21 -0
- package/src/lib/canvas-manager/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/index.d.ts +17 -0
- package/src/lib/canvas-manager/stores/index.js +18 -0
- package/src/lib/canvas-manager/stores/index.js.map +1 -0
- package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
- package/src/lib/canvas-manager/stores/node.store.js +45 -0
- package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
- package/src/lib/components-manager/components-manager.d.ts +56 -0
- package/src/lib/components-manager/components-manager.js +191 -0
- package/src/lib/components-manager/components-manager.js.map +1 -0
- package/src/lib/components-manager/index.d.ts +18 -0
- package/src/lib/components-manager/index.js +19 -0
- package/src/lib/components-manager/index.js.map +1 -0
- package/src/lib/emit-manager/emit-manager.d.ts +56 -0
- package/src/lib/emit-manager/emit-manager.js +60 -0
- package/src/lib/emit-manager/emit-manager.js.map +1 -0
- package/src/lib/emit-manager/index.d.ts +18 -0
- package/src/lib/emit-manager/index.js +19 -0
- package/src/lib/emit-manager/index.js.map +1 -0
- package/src/lib/foundation/constants/_internal.d.ts +18 -0
- package/src/lib/foundation/constants/_internal.js +62 -0
- package/src/lib/foundation/constants/_internal.js.map +1 -0
- package/src/lib/foundation/constants/app.d.ts +23 -0
- package/src/lib/foundation/constants/app.js +25 -0
- package/src/lib/foundation/constants/app.js.map +1 -0
- package/src/lib/foundation/constants/canvas.d.ts +18 -0
- package/src/lib/foundation/constants/canvas.js +18 -0
- package/src/lib/foundation/constants/canvas.js.map +1 -0
- package/src/lib/foundation/constants/components.d.ts +54 -0
- package/src/lib/foundation/constants/components.js +61 -0
- package/src/lib/foundation/constants/components.js.map +1 -0
- package/src/lib/foundation/constants/shared.d.ts +50 -0
- package/src/lib/foundation/constants/shared.js +49 -0
- package/src/lib/foundation/constants/shared.js.map +1 -0
- package/src/lib/foundation/constants/symbol.d.ts +63 -0
- package/src/lib/foundation/constants/symbol.js +75 -0
- package/src/lib/foundation/constants/symbol.js.map +1 -0
- package/src/lib/foundation/definitions/components.types.d.ts +372 -0
- package/src/lib/foundation/definitions/components.types.js +180 -0
- package/src/lib/foundation/definitions/components.types.js.map +1 -0
- package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
- package/src/lib/foundation/definitions/contact.types.js +107 -0
- package/src/lib/foundation/definitions/contact.types.js.map +1 -0
- package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
- package/src/lib/foundation/definitions/host-content-collections.js +219 -0
- package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
- package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
- package/src/lib/foundation/definitions/org-billing.types.js +77 -0
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
- package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
- package/src/lib/foundation/definitions/organization.types.js +42 -0
- package/src/lib/foundation/definitions/organization.types.js.map +1 -0
- package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
- package/src/lib/foundation/definitions/platform.types.js +124 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -0
- package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
- package/src/lib/foundation/definitions/property-kinds.js +565 -0
- package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
- package/src/lib/foundation/definitions/shared.d.ts +23 -0
- package/src/lib/foundation/definitions/shared.js +18 -0
- package/src/lib/foundation/definitions/shared.js.map +1 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
- package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
- package/src/lib/foundation/index.d.ts +32 -0
- package/src/lib/foundation/index.js +67 -0
- package/src/lib/foundation/index.js.map +1 -0
- package/src/lib/lifecycle.d.ts +24 -0
- package/src/lib/lifecycle.js +39 -0
- package/src/lib/lifecycle.js.map +1 -0
- package/src/lib/mst/common.d.ts +17 -0
- package/src/lib/mst/common.js +23 -0
- package/src/lib/mst/common.js.map +1 -0
- package/src/lib/mst/index.d.ts +19 -0
- package/src/lib/mst/index.js +20 -0
- package/src/lib/mst/index.js.map +1 -0
- package/src/lib/mst/json.d.ts +22 -0
- package/src/lib/mst/json.js +23 -0
- package/src/lib/mst/json.js.map +1 -0
- package/src/lib/mst/types.d.ts +20 -0
- package/src/lib/mst/types.js +18 -0
- package/src/lib/mst/types.js.map +1 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
- package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
- package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
- package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
- package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
- package/src/lib/plugin-manager/custom-fields.js +39 -0
- package/src/lib/plugin-manager/custom-fields.js.map +1 -0
- package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
- package/src/lib/plugin-manager/editor-sessions.js +137 -0
- package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
- package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
- package/src/lib/plugin-manager/enabled-plugins.js +403 -0
- package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
- package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
- package/src/lib/plugin-manager/feature-plugins.js +609 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
- package/src/lib/plugin-manager/index.d.ts +42 -0
- package/src/lib/plugin-manager/index.js +46 -0
- package/src/lib/plugin-manager/index.js.map +1 -0
- package/src/lib/plugin-manager/install-presets.d.ts +93 -0
- package/src/lib/plugin-manager/install-presets.js +86 -0
- package/src/lib/plugin-manager/install-presets.js.map +1 -0
- package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
- package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
- package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
- package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
- package/src/lib/plugin-manager/order-fulfilment.js +104 -0
- package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
- package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
- package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
- package/src/lib/plugin-manager/plugin-bridge.js +154 -0
- package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
- package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
- package/src/lib/plugin-manager/plugin-config.js +228 -0
- package/src/lib/plugin-manager/plugin-config.js.map +1 -0
- package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
- package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
- package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
- package/src/lib/plugin-manager/plugin-contributions.js +283 -0
- package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
- package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
- package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
- package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-events.js +79 -0
- package/src/lib/plugin-manager/plugin-events.js.map +1 -0
- package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
- package/src/lib/plugin-manager/plugin-figures.js +252 -0
- package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
- package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
- package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
- package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
- package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
- package/src/lib/plugin-manager/plugin-jobs.js +182 -0
- package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
- package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
- package/src/lib/plugin-manager/plugin-loader.js +223 -0
- package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
- package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
- package/src/lib/plugin-manager/plugin-manager.js +343 -0
- package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
- package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
- package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
- package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
- package/src/lib/plugin-manager/plugin-permissions.js +77 -0
- package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
- package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
- package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
- package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
- package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
- package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
- package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
- package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
- package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
- package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
- package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
- package/src/lib/plugin-manager/plugin-services.js +153 -0
- package/src/lib/plugin-manager/plugin-services.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
- package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
- package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
- package/src/lib/plugin-manager/plugin-styles.js +186 -0
- package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
- package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
- package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
- package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
- package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
- package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
- package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
- package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
- package/src/lib/plugin-manager/plugin-zones.js +74 -0
- package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
- package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
- package/src/lib/plugin-manager/realm-plugins.js +196 -0
- package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
- package/src/lib/plugin-manager/realm-server.d.ts +54 -0
- package/src/lib/plugin-manager/realm-server.js +88 -0
- package/src/lib/plugin-manager/realm-server.js.map +1 -0
- package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
- package/src/lib/plugin-manager/record-zone-props.js +31 -0
- package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
- package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
- package/src/lib/plugin-manager/site-page-hooks.js +114 -0
- package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
- package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
- package/src/lib/plugin-manager/site-runtime.js +25 -0
- package/src/lib/plugin-manager/site-runtime.js.map +1 -0
- package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
- package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
- package/src/lib/types/ast.d.ts +199 -0
- package/src/lib/types/ast.js +20 -0
- package/src/lib/types/ast.js.map +1 -0
- package/src/lib/types/index.d.ts +20 -0
- package/src/lib/types/index.js +21 -0
- package/src/lib/types/index.js.map +1 -0
- package/src/lib/types/nodes.d.ts +608 -0
- package/src/lib/types/nodes.js +28 -0
- package/src/lib/types/nodes.js.map +1 -0
- package/src/lib/types/routing.d.ts +17 -0
- package/src/lib/types/routing.js +18 -0
- package/src/lib/types/routing.js.map +1 -0
- package/src/lib/types/screen.d.ts +23 -0
- package/src/lib/types/screen.js +18 -0
- package/src/lib/types/screen.js.map +1 -0
- package/src/lib/utils.d.ts +25 -0
- package/src/lib/utils.js +42 -0
- package/src/lib/utils.js.map +1 -0
- package/src/server.d.ts +37 -0
- package/src/server.js +55 -0
- package/src/server.js.map +1 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The atomic attempt claim (AGL-1691, promoted here by AGL-1697).
|
|
19
|
+
*
|
|
20
|
+
* Nine call sites in this repo create a Stripe Checkout session and eight of
|
|
21
|
+
* them sent no `Idempotency-Key`, so a retry, a double-click or a client
|
|
22
|
+
* timeout minted a second session on a live account. Closing them one at a time
|
|
23
|
+
* with one local copy each is how a codebase ends up with nine subtly different
|
|
24
|
+
* answers to the same question, so the POS implementation moves here whole
|
|
25
|
+
* rather than being reimplemented per caller.
|
|
26
|
+
*
|
|
27
|
+
* Exported ONLY from `@aglyn/aglyn/server` (never the client barrel): it needs
|
|
28
|
+
* `node:crypto`, which is the same reason `realm-server` lives behind that
|
|
29
|
+
* entry point.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* The minimum Firestore surface the claim needs, declared structurally.
|
|
33
|
+
*
|
|
34
|
+
* A `FirebaseFirestore.Firestore` satisfies it, but stating it this way keeps
|
|
35
|
+
* `@aglyn/aglyn` free of a firebase-admin dependency — and it is the reason a
|
|
36
|
+
* spec can hand this an in-memory map and count what actually landed.
|
|
37
|
+
*/
|
|
38
|
+
export interface IdempotencyDocRef {
|
|
39
|
+
create(data: Record<string, unknown>): Promise<unknown>;
|
|
40
|
+
get(): Promise<{
|
|
41
|
+
get(field: string): unknown;
|
|
42
|
+
}>;
|
|
43
|
+
set(data: Record<string, unknown>, options: {
|
|
44
|
+
merge: boolean;
|
|
45
|
+
}): Promise<unknown>;
|
|
46
|
+
delete(): Promise<unknown>;
|
|
47
|
+
}
|
|
48
|
+
export interface IdempotencyStore {
|
|
49
|
+
collection(name: string): {
|
|
50
|
+
doc(id: string): IdempotencyDocRef;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** A claim on one attempt. */
|
|
54
|
+
export interface AttemptClaim {
|
|
55
|
+
/**
|
|
56
|
+
* The digest to hand Stripe as `Idempotency-Key`, or null when the client
|
|
57
|
+
* sent no key.
|
|
58
|
+
*/
|
|
59
|
+
stripeKey: string | null;
|
|
60
|
+
/** Record the response so a repeat of this attempt replays it. */
|
|
61
|
+
record: (status: number, body: unknown) => Promise<void>;
|
|
62
|
+
/** Give the key back, so a failed attempt can be retried with it. */
|
|
63
|
+
release: () => Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export type AttemptClaimResult = {
|
|
66
|
+
claim: AttemptClaim;
|
|
67
|
+
} | {
|
|
68
|
+
replay: {
|
|
69
|
+
status: number;
|
|
70
|
+
body: unknown;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
export interface AttemptScope {
|
|
74
|
+
/**
|
|
75
|
+
* What kind of attempt this is (`pos`, `marketplace-checkout`, …). Part of
|
|
76
|
+
* the digest, so two features cannot collide on one client-minted key.
|
|
77
|
+
*/
|
|
78
|
+
kind: string;
|
|
79
|
+
/**
|
|
80
|
+
* What the attempt is scoped to — a host id, or a `listingId:buyerUid` pair.
|
|
81
|
+
* Also part of the digest.
|
|
82
|
+
*/
|
|
83
|
+
scopeId: string;
|
|
84
|
+
/**
|
|
85
|
+
* The org whose data this is, so `eraseOrgIdempotencyKeys` sweeps the claim
|
|
86
|
+
* on org erasure (AGL-1448). Empty is written as explicit `null` — Firestore
|
|
87
|
+
* rejects `undefined`.
|
|
88
|
+
*/
|
|
89
|
+
orgId: string;
|
|
90
|
+
/** The client-minted attempt key. Empty means "the client sent none". */
|
|
91
|
+
key: string;
|
|
92
|
+
/** What to answer a caller whose identical attempt is still in flight. */
|
|
93
|
+
busyMessage: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* How long a replay key is remembered (AGL-1978).
|
|
97
|
+
*
|
|
98
|
+
* This was unbounded, and the reason that matters is not document count. A
|
|
99
|
+
* settled claim stores the ORIGINAL RESPONSE BODY, and for the REST API that
|
|
100
|
+
* body is the created record's `values` — the customer's own data. So the
|
|
101
|
+
* collection was a second, permanent copy of every record ever created
|
|
102
|
+
* through the API, and `conventions.md` advertises the consequence in terms:
|
|
103
|
+
* a replay "keeps working after the record has been edited or deleted". A
|
|
104
|
+
* customer who deleted a record left our copy of it behind, forever, in a
|
|
105
|
+
* collection nobody thought of as content.
|
|
106
|
+
*
|
|
107
|
+
* 30 days, chosen against real retry behaviour rather than against the
|
|
108
|
+
* feeling that shorter is safer:
|
|
109
|
+
*
|
|
110
|
+
* - Stripe's own idempotency window is 24 hours, and it serves the whole
|
|
111
|
+
* payments industry. 30 days is thirty times that.
|
|
112
|
+
* - It covers every retry pattern an integration actually has: the immediate
|
|
113
|
+
* retry, the retry after a timeout, and the nightly job that fails and
|
|
114
|
+
* re-runs the next morning. A human re-importing last quarter's data is
|
|
115
|
+
* not retrying — that is a new operation, and it should mint a new key.
|
|
116
|
+
* - It turns an unbounded archive into a working set without touching the
|
|
117
|
+
* in-flight semantics the `409` protects.
|
|
118
|
+
*
|
|
119
|
+
* ⚠️ This CHANGES a documented promise. `apps/docs/api/conventions.md` said
|
|
120
|
+
* keys "never expire — a key really is single-use forever"; it now states
|
|
121
|
+
* the window. The doc moved in the same commit, because a retention change
|
|
122
|
+
* that leaves the published contract behind is the AGL-1496 shape.
|
|
123
|
+
*/
|
|
124
|
+
export declare const API_IDEMPOTENCY_RETENTION_DAYS = 30;
|
|
125
|
+
/**
|
|
126
|
+
* When a claim taken at `now` expires. A `Date`, never an epoch number: a
|
|
127
|
+
* TTL policy keys on a Firestore Timestamp and silently governs nothing when
|
|
128
|
+
* the field is a number. Note the existing `createdAtMs`/`settledAtMs`
|
|
129
|
+
* fields are numbers and could not have been used — which is why AGL-1978
|
|
130
|
+
* called for a new field rather than a policy on an existing one.
|
|
131
|
+
*/
|
|
132
|
+
export declare function apiIdempotencyExpiry(now?: Date): Date;
|
|
133
|
+
/**
|
|
134
|
+
* One Stripe idempotency key per OBJECT an attempt creates (AGL-1714).
|
|
135
|
+
*
|
|
136
|
+
* Stripe's idempotency layer is account-scoped, not endpoint-scoped: it
|
|
137
|
+
* "compares incoming parameters to those of the original request and errors if
|
|
138
|
+
* they're not the same". Sending one claim digest unchanged to two endpoints —
|
|
139
|
+
* a coupon and then the session, a price and then the subscription — therefore
|
|
140
|
+
* makes the SECOND call fail outright. An attempt that creates more than one
|
|
141
|
+
* Stripe object derives a key per object from the one digest instead.
|
|
142
|
+
*
|
|
143
|
+
* Null-propagating so a keyless attempt (older cached client bundle) sends no
|
|
144
|
+
* header at all rather than the string `"null:session"`.
|
|
145
|
+
*/
|
|
146
|
+
export declare function deriveStripeObjectKey(digest: string | null, object: string): string | null;
|
|
147
|
+
/**
|
|
148
|
+
* Take an exclusive claim on one attempt, so a retry cannot mint a second
|
|
149
|
+
* order, a second purchase or a second Checkout session.
|
|
150
|
+
*
|
|
151
|
+
* The key is supplied by the CLIENT, once per attempt, and is deliberately NOT
|
|
152
|
+
* derived from the content. A cashier ringing the same coffee twice in a minute
|
|
153
|
+
* is a real second sale, and a buyer re-buying a component after a refund is a
|
|
154
|
+
* real second purchase; a content hash would silently swallow both, which is a
|
|
155
|
+
* worse bug than the one this closes. So the client mints a key when something
|
|
156
|
+
* first becomes an attempt and retires it when that attempt is over — stable
|
|
157
|
+
* across a retry of THAT attempt, distinct for a legitimately identical next
|
|
158
|
+
* one. Callers that need "you cannot have two of these at all" want a business
|
|
159
|
+
* rule as well, not a longer-lived key.
|
|
160
|
+
*
|
|
161
|
+
* The claim is `create()`. Firestore rejects a create on an existing document,
|
|
162
|
+
* and that rejection is the whole dedupe primitive — a read-then-write would
|
|
163
|
+
* race exactly the double-submit it exists to stop.
|
|
164
|
+
*
|
|
165
|
+
* Storage reuses the REST API's collection and its `orgId` field rather than
|
|
166
|
+
* inventing a second replay store, so `eraseOrgIdempotencyKeys` already sweeps
|
|
167
|
+
* these on org erasure (AGL-1448) with no change there.
|
|
168
|
+
*/
|
|
169
|
+
export declare function claimAttempt(store: IdempotencyStore, scope: AttemptScope): Promise<AttemptClaimResult>;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { createHash } from "node:crypto";
|
|
17
|
+
/** Where the REST API already keeps replay keys (AGL-618). */ const COLLECTION = 'apiIdempotency';
|
|
18
|
+
/**
|
|
19
|
+
* How long a replay key is remembered (AGL-1978).
|
|
20
|
+
*
|
|
21
|
+
* This was unbounded, and the reason that matters is not document count. A
|
|
22
|
+
* settled claim stores the ORIGINAL RESPONSE BODY, and for the REST API that
|
|
23
|
+
* body is the created record's `values` — the customer's own data. So the
|
|
24
|
+
* collection was a second, permanent copy of every record ever created
|
|
25
|
+
* through the API, and `conventions.md` advertises the consequence in terms:
|
|
26
|
+
* a replay "keeps working after the record has been edited or deleted". A
|
|
27
|
+
* customer who deleted a record left our copy of it behind, forever, in a
|
|
28
|
+
* collection nobody thought of as content.
|
|
29
|
+
*
|
|
30
|
+
* 30 days, chosen against real retry behaviour rather than against the
|
|
31
|
+
* feeling that shorter is safer:
|
|
32
|
+
*
|
|
33
|
+
* - Stripe's own idempotency window is 24 hours, and it serves the whole
|
|
34
|
+
* payments industry. 30 days is thirty times that.
|
|
35
|
+
* - It covers every retry pattern an integration actually has: the immediate
|
|
36
|
+
* retry, the retry after a timeout, and the nightly job that fails and
|
|
37
|
+
* re-runs the next morning. A human re-importing last quarter's data is
|
|
38
|
+
* not retrying — that is a new operation, and it should mint a new key.
|
|
39
|
+
* - It turns an unbounded archive into a working set without touching the
|
|
40
|
+
* in-flight semantics the `409` protects.
|
|
41
|
+
*
|
|
42
|
+
* ⚠️ This CHANGES a documented promise. `apps/docs/api/conventions.md` said
|
|
43
|
+
* keys "never expire — a key really is single-use forever"; it now states
|
|
44
|
+
* the window. The doc moved in the same commit, because a retention change
|
|
45
|
+
* that leaves the published contract behind is the AGL-1496 shape.
|
|
46
|
+
*/ export const API_IDEMPOTENCY_RETENTION_DAYS = 30;
|
|
47
|
+
/**
|
|
48
|
+
* When a claim taken at `now` expires. A `Date`, never an epoch number: a
|
|
49
|
+
* TTL policy keys on a Firestore Timestamp and silently governs nothing when
|
|
50
|
+
* the field is a number. Note the existing `createdAtMs`/`settledAtMs`
|
|
51
|
+
* fields are numbers and could not have been used — which is why AGL-1978
|
|
52
|
+
* called for a new field rather than a policy on an existing one.
|
|
53
|
+
*/ export function apiIdempotencyExpiry(now = new Date()) {
|
|
54
|
+
return new Date(now.getTime() + API_IDEMPOTENCY_RETENTION_DAYS * 24 * 60 * 60 * 1000);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* One Stripe idempotency key per OBJECT an attempt creates (AGL-1714).
|
|
58
|
+
*
|
|
59
|
+
* Stripe's idempotency layer is account-scoped, not endpoint-scoped: it
|
|
60
|
+
* "compares incoming parameters to those of the original request and errors if
|
|
61
|
+
* they're not the same". Sending one claim digest unchanged to two endpoints —
|
|
62
|
+
* a coupon and then the session, a price and then the subscription — therefore
|
|
63
|
+
* makes the SECOND call fail outright. An attempt that creates more than one
|
|
64
|
+
* Stripe object derives a key per object from the one digest instead.
|
|
65
|
+
*
|
|
66
|
+
* Null-propagating so a keyless attempt (older cached client bundle) sends no
|
|
67
|
+
* header at all rather than the string `"null:session"`.
|
|
68
|
+
*/ export function deriveStripeObjectKey(digest, object) {
|
|
69
|
+
return digest ? `${digest}:${object}` : null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Take an exclusive claim on one attempt, so a retry cannot mint a second
|
|
73
|
+
* order, a second purchase or a second Checkout session.
|
|
74
|
+
*
|
|
75
|
+
* The key is supplied by the CLIENT, once per attempt, and is deliberately NOT
|
|
76
|
+
* derived from the content. A cashier ringing the same coffee twice in a minute
|
|
77
|
+
* is a real second sale, and a buyer re-buying a component after a refund is a
|
|
78
|
+
* real second purchase; a content hash would silently swallow both, which is a
|
|
79
|
+
* worse bug than the one this closes. So the client mints a key when something
|
|
80
|
+
* first becomes an attempt and retires it when that attempt is over — stable
|
|
81
|
+
* across a retry of THAT attempt, distinct for a legitimately identical next
|
|
82
|
+
* one. Callers that need "you cannot have two of these at all" want a business
|
|
83
|
+
* rule as well, not a longer-lived key.
|
|
84
|
+
*
|
|
85
|
+
* The claim is `create()`. Firestore rejects a create on an existing document,
|
|
86
|
+
* and that rejection is the whole dedupe primitive — a read-then-write would
|
|
87
|
+
* race exactly the double-submit it exists to stop.
|
|
88
|
+
*
|
|
89
|
+
* Storage reuses the REST API's collection and its `orgId` field rather than
|
|
90
|
+
* inventing a second replay store, so `eraseOrgIdempotencyKeys` already sweeps
|
|
91
|
+
* these on org erasure (AGL-1448) with no change there.
|
|
92
|
+
*/ export async function claimAttempt(store, scope) {
|
|
93
|
+
// No key: transact as before. These are public API routes and an older
|
|
94
|
+
// cached client bundle must keep working rather than start failing.
|
|
95
|
+
//
|
|
96
|
+
// ⚠️ THIS IS A NO-OP CLAIM, AND IT IS A REAL HOLE — deliberately left open,
|
|
97
|
+
// now made LOUD (AGL-2163). `stripeKey: null` propagates through
|
|
98
|
+
// `deriveStripeObjectKey` to the Stripe call (see
|
|
99
|
+
// `marketplace/checkout.ts`), so a caller that sends no Idempotency-Key
|
|
100
|
+
// header gets neither our claim nor Stripe's own 24-hour window: the
|
|
101
|
+
// concurrent-double-charge race this module exists to close is fully back
|
|
102
|
+
// for that request.
|
|
103
|
+
//
|
|
104
|
+
// THE POLICY IS NOT CHANGED HERE, ON PURPOSE. The obvious "fix" — synthesise
|
|
105
|
+
// a key from the request body — would redefine what "the same attempt"
|
|
106
|
+
// means: a cashier ringing the same coffee twice and a buyer re-purchasing
|
|
107
|
+
// the same listing after a refund would both read as replays and be
|
|
108
|
+
// silently swallowed, which is a worse bug than the one it closes (see the
|
|
109
|
+
// paragraph above on why the key is client-minted). Requiring the header
|
|
110
|
+
// instead would break every older cached client bundle mid-checkout.
|
|
111
|
+
// Choosing between those two is a product call, not a bug fix.
|
|
112
|
+
//
|
|
113
|
+
// What IS wrong is that it was SILENT. An unprotected money call left no
|
|
114
|
+
// trace anywhere, so nobody could tell whether this path was taken once a
|
|
115
|
+
// year or on a third of all checkouts — which is exactly the number the
|
|
116
|
+
// policy decision needs. `console.warn` rather than a counter because it
|
|
117
|
+
// rides the platform's existing log pipeline and this path is low-volume by
|
|
118
|
+
// construction (one line per money attempt, not per request).
|
|
119
|
+
if (!scope.key) {
|
|
120
|
+
var _scope_orgId;
|
|
121
|
+
console.warn('api-idempotency: UNPROTECTED money call — no Idempotency-Key header, ' + 'so neither the attempt claim nor Stripe idempotency applies', {
|
|
122
|
+
kind: scope.kind,
|
|
123
|
+
scopeId: scope.scopeId,
|
|
124
|
+
orgId: (_scope_orgId = scope.orgId) != null ? _scope_orgId : null
|
|
125
|
+
});
|
|
126
|
+
return {
|
|
127
|
+
claim: {
|
|
128
|
+
stripeKey: null,
|
|
129
|
+
record: async ()=>undefined,
|
|
130
|
+
release: async ()=>undefined
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const digest = createHash('sha256').update(`${scope.kind}:${scope.scopeId}:${scope.key}`).digest('hex');
|
|
135
|
+
const ref = store.collection(COLLECTION).doc(digest);
|
|
136
|
+
try {
|
|
137
|
+
await ref.create({
|
|
138
|
+
orgId: scope.orgId || null,
|
|
139
|
+
scopeId: scope.scopeId,
|
|
140
|
+
kind: scope.kind,
|
|
141
|
+
status: 'pending',
|
|
142
|
+
createdAtMs: Date.now(),
|
|
143
|
+
// Stamped at CLAIM, not at settlement, so a claim stranded by a killed
|
|
144
|
+
// process is reaped on the same schedule as one that completed. Those
|
|
145
|
+
// are the documents that would otherwise sit forever holding a key
|
|
146
|
+
// hostage — the failure mode `release()` exists to avoid and cannot
|
|
147
|
+
// cover when the process is gone.
|
|
148
|
+
expiresAt: apiIdempotencyExpiry()
|
|
149
|
+
});
|
|
150
|
+
} catch (unused) {
|
|
151
|
+
// Already claimed: either the attempt finished and we replay its result,
|
|
152
|
+
// or it is still in flight.
|
|
153
|
+
const prior = await ref.get();
|
|
154
|
+
const priorResponse = prior.get('response');
|
|
155
|
+
if (priorResponse) {
|
|
156
|
+
var _prior_get;
|
|
157
|
+
return {
|
|
158
|
+
replay: {
|
|
159
|
+
status: Number((_prior_get = prior.get('responseStatus')) != null ? _prior_get : 200),
|
|
160
|
+
body: priorResponse
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
// In flight. Fail CLOSED — the money direction. Letting the second caller
|
|
165
|
+
// through IS the duplicate charge. A process killed between the claim and
|
|
166
|
+
// the record leaves a key stuck here; the customer starts a fresh attempt
|
|
167
|
+
// with a fresh key, which is the correct failure direction even though it
|
|
168
|
+
// is not a pleasant one.
|
|
169
|
+
return {
|
|
170
|
+
replay: {
|
|
171
|
+
status: 409,
|
|
172
|
+
body: {
|
|
173
|
+
error: scope.busyMessage
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
claim: {
|
|
180
|
+
// The same digest goes to Stripe, so even if our claim is lost after the
|
|
181
|
+
// call, Stripe replays its own session rather than opening a second one.
|
|
182
|
+
// Scoped by kind and attempt, so it cannot collide.
|
|
183
|
+
stripeKey: digest,
|
|
184
|
+
// Both swallow their own failure. A claim that cannot be recorded or
|
|
185
|
+
// released must not turn a completed purchase into a 500 — the money has
|
|
186
|
+
// already moved by then, and the worst case here is a key that replays
|
|
187
|
+
// nothing or one that goes unused.
|
|
188
|
+
record: async (status, body)=>{
|
|
189
|
+
try {
|
|
190
|
+
await ref.set({
|
|
191
|
+
status: 'done',
|
|
192
|
+
responseStatus: status,
|
|
193
|
+
response: body,
|
|
194
|
+
settledAtMs: Date.now()
|
|
195
|
+
}, {
|
|
196
|
+
merge: true
|
|
197
|
+
});
|
|
198
|
+
} catch (unused) {
|
|
199
|
+
/* best effort */ }
|
|
200
|
+
},
|
|
201
|
+
// A rejected or failed attempt must not burn the key: the customer fixes
|
|
202
|
+
// the cause and presses the same button.
|
|
203
|
+
release: async ()=>{
|
|
204
|
+
try {
|
|
205
|
+
await ref.delete();
|
|
206
|
+
} catch (unused) {
|
|
207
|
+
/* best effort */ }
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//# sourceMappingURL=api-idempotency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/api-idempotency.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createHash } from 'node:crypto'\n\n/**\n * The atomic attempt claim (AGL-1691, promoted here by AGL-1697).\n *\n * Nine call sites in this repo create a Stripe Checkout session and eight of\n * them sent no `Idempotency-Key`, so a retry, a double-click or a client\n * timeout minted a second session on a live account. Closing them one at a time\n * with one local copy each is how a codebase ends up with nine subtly different\n * answers to the same question, so the POS implementation moves here whole\n * rather than being reimplemented per caller.\n *\n * Exported ONLY from `@aglyn/aglyn/server` (never the client barrel): it needs\n * `node:crypto`, which is the same reason `realm-server` lives behind that\n * entry point.\n */\n\n/**\n * The minimum Firestore surface the claim needs, declared structurally.\n *\n * A `FirebaseFirestore.Firestore` satisfies it, but stating it this way keeps\n * `@aglyn/aglyn` free of a firebase-admin dependency — and it is the reason a\n * spec can hand this an in-memory map and count what actually landed.\n */\nexport interface IdempotencyDocRef {\n create(data: Record<string, unknown>): Promise<unknown>\n get(): Promise<{ get(field: string): unknown }>\n set(data: Record<string, unknown>, options: { merge: boolean }): Promise<unknown>\n delete(): Promise<unknown>\n}\n\nexport interface IdempotencyStore {\n collection(name: string): { doc(id: string): IdempotencyDocRef }\n}\n\n/** A claim on one attempt. */\nexport interface AttemptClaim {\n /**\n * The digest to hand Stripe as `Idempotency-Key`, or null when the client\n * sent no key.\n */\n stripeKey: string | null\n /** Record the response so a repeat of this attempt replays it. */\n record: (status: number, body: unknown) => Promise<void>\n /** Give the key back, so a failed attempt can be retried with it. */\n release: () => Promise<void>\n}\n\nexport type AttemptClaimResult =\n | { claim: AttemptClaim }\n | { replay: { status: number; body: unknown } }\n\nexport interface AttemptScope {\n /**\n * What kind of attempt this is (`pos`, `marketplace-checkout`, …). Part of\n * the digest, so two features cannot collide on one client-minted key.\n */\n kind: string\n /**\n * What the attempt is scoped to — a host id, or a `listingId:buyerUid` pair.\n * Also part of the digest.\n */\n scopeId: string\n /**\n * The org whose data this is, so `eraseOrgIdempotencyKeys` sweeps the claim\n * on org erasure (AGL-1448). Empty is written as explicit `null` — Firestore\n * rejects `undefined`.\n */\n orgId: string\n /** The client-minted attempt key. Empty means \"the client sent none\". */\n key: string\n /** What to answer a caller whose identical attempt is still in flight. */\n busyMessage: string\n}\n\n/** Where the REST API already keeps replay keys (AGL-618). */\nconst COLLECTION = 'apiIdempotency'\n\n/**\n * How long a replay key is remembered (AGL-1978).\n *\n * This was unbounded, and the reason that matters is not document count. A\n * settled claim stores the ORIGINAL RESPONSE BODY, and for the REST API that\n * body is the created record's `values` — the customer's own data. So the\n * collection was a second, permanent copy of every record ever created\n * through the API, and `conventions.md` advertises the consequence in terms:\n * a replay \"keeps working after the record has been edited or deleted\". A\n * customer who deleted a record left our copy of it behind, forever, in a\n * collection nobody thought of as content.\n *\n * 30 days, chosen against real retry behaviour rather than against the\n * feeling that shorter is safer:\n *\n * - Stripe's own idempotency window is 24 hours, and it serves the whole\n * payments industry. 30 days is thirty times that.\n * - It covers every retry pattern an integration actually has: the immediate\n * retry, the retry after a timeout, and the nightly job that fails and\n * re-runs the next morning. A human re-importing last quarter's data is\n * not retrying — that is a new operation, and it should mint a new key.\n * - It turns an unbounded archive into a working set without touching the\n * in-flight semantics the `409` protects.\n *\n * ⚠️ This CHANGES a documented promise. `apps/docs/api/conventions.md` said\n * keys \"never expire — a key really is single-use forever\"; it now states\n * the window. The doc moved in the same commit, because a retention change\n * that leaves the published contract behind is the AGL-1496 shape.\n */\nexport const API_IDEMPOTENCY_RETENTION_DAYS = 30\n\n/**\n * When a claim taken at `now` expires. A `Date`, never an epoch number: a\n * TTL policy keys on a Firestore Timestamp and silently governs nothing when\n * the field is a number. Note the existing `createdAtMs`/`settledAtMs`\n * fields are numbers and could not have been used — which is why AGL-1978\n * called for a new field rather than a policy on an existing one.\n */\nexport function apiIdempotencyExpiry(now = new Date()): Date {\n return new Date(\n now.getTime() + API_IDEMPOTENCY_RETENTION_DAYS * 24 * 60 * 60 * 1000,\n )\n}\n\n/**\n * One Stripe idempotency key per OBJECT an attempt creates (AGL-1714).\n *\n * Stripe's idempotency layer is account-scoped, not endpoint-scoped: it\n * \"compares incoming parameters to those of the original request and errors if\n * they're not the same\". Sending one claim digest unchanged to two endpoints —\n * a coupon and then the session, a price and then the subscription — therefore\n * makes the SECOND call fail outright. An attempt that creates more than one\n * Stripe object derives a key per object from the one digest instead.\n *\n * Null-propagating so a keyless attempt (older cached client bundle) sends no\n * header at all rather than the string `\"null:session\"`.\n */\nexport function deriveStripeObjectKey(\n digest: string | null,\n object: string,\n): string | null {\n return digest ? `${digest}:${object}` : null\n}\n\n/**\n * Take an exclusive claim on one attempt, so a retry cannot mint a second\n * order, a second purchase or a second Checkout session.\n *\n * The key is supplied by the CLIENT, once per attempt, and is deliberately NOT\n * derived from the content. A cashier ringing the same coffee twice in a minute\n * is a real second sale, and a buyer re-buying a component after a refund is a\n * real second purchase; a content hash would silently swallow both, which is a\n * worse bug than the one this closes. So the client mints a key when something\n * first becomes an attempt and retires it when that attempt is over — stable\n * across a retry of THAT attempt, distinct for a legitimately identical next\n * one. Callers that need \"you cannot have two of these at all\" want a business\n * rule as well, not a longer-lived key.\n *\n * The claim is `create()`. Firestore rejects a create on an existing document,\n * and that rejection is the whole dedupe primitive — a read-then-write would\n * race exactly the double-submit it exists to stop.\n *\n * Storage reuses the REST API's collection and its `orgId` field rather than\n * inventing a second replay store, so `eraseOrgIdempotencyKeys` already sweeps\n * these on org erasure (AGL-1448) with no change there.\n */\nexport async function claimAttempt(\n store: IdempotencyStore,\n scope: AttemptScope,\n): Promise<AttemptClaimResult> {\n // No key: transact as before. These are public API routes and an older\n // cached client bundle must keep working rather than start failing.\n //\n // ⚠️ THIS IS A NO-OP CLAIM, AND IT IS A REAL HOLE — deliberately left open,\n // now made LOUD (AGL-2163). `stripeKey: null` propagates through\n // `deriveStripeObjectKey` to the Stripe call (see\n // `marketplace/checkout.ts`), so a caller that sends no Idempotency-Key\n // header gets neither our claim nor Stripe's own 24-hour window: the\n // concurrent-double-charge race this module exists to close is fully back\n // for that request.\n //\n // THE POLICY IS NOT CHANGED HERE, ON PURPOSE. The obvious \"fix\" — synthesise\n // a key from the request body — would redefine what \"the same attempt\"\n // means: a cashier ringing the same coffee twice and a buyer re-purchasing\n // the same listing after a refund would both read as replays and be\n // silently swallowed, which is a worse bug than the one it closes (see the\n // paragraph above on why the key is client-minted). Requiring the header\n // instead would break every older cached client bundle mid-checkout.\n // Choosing between those two is a product call, not a bug fix.\n //\n // What IS wrong is that it was SILENT. An unprotected money call left no\n // trace anywhere, so nobody could tell whether this path was taken once a\n // year or on a third of all checkouts — which is exactly the number the\n // policy decision needs. `console.warn` rather than a counter because it\n // rides the platform's existing log pipeline and this path is low-volume by\n // construction (one line per money attempt, not per request).\n if (!scope.key) {\n console.warn(\n 'api-idempotency: UNPROTECTED money call — no Idempotency-Key header, ' +\n 'so neither the attempt claim nor Stripe idempotency applies',\n { kind: scope.kind, scopeId: scope.scopeId, orgId: scope.orgId ?? null },\n )\n return {\n claim: {\n stripeKey: null,\n record: async () => undefined,\n release: async () => undefined,\n },\n }\n }\n const digest = createHash('sha256')\n .update(`${scope.kind}:${scope.scopeId}:${scope.key}`)\n .digest('hex')\n const ref = store.collection(COLLECTION).doc(digest)\n try {\n await ref.create({\n orgId: scope.orgId || null,\n scopeId: scope.scopeId,\n kind: scope.kind,\n status: 'pending',\n createdAtMs: Date.now(),\n // Stamped at CLAIM, not at settlement, so a claim stranded by a killed\n // process is reaped on the same schedule as one that completed. Those\n // are the documents that would otherwise sit forever holding a key\n // hostage — the failure mode `release()` exists to avoid and cannot\n // cover when the process is gone.\n expiresAt: apiIdempotencyExpiry(),\n })\n } catch {\n // Already claimed: either the attempt finished and we replay its result,\n // or it is still in flight.\n const prior = await ref.get()\n const priorResponse = prior.get('response')\n if (priorResponse) {\n return {\n replay: {\n status: Number(prior.get('responseStatus') ?? 200),\n body: priorResponse,\n },\n }\n }\n // In flight. Fail CLOSED — the money direction. Letting the second caller\n // through IS the duplicate charge. A process killed between the claim and\n // the record leaves a key stuck here; the customer starts a fresh attempt\n // with a fresh key, which is the correct failure direction even though it\n // is not a pleasant one.\n return { replay: { status: 409, body: { error: scope.busyMessage } } }\n }\n return {\n claim: {\n // The same digest goes to Stripe, so even if our claim is lost after the\n // call, Stripe replays its own session rather than opening a second one.\n // Scoped by kind and attempt, so it cannot collide.\n stripeKey: digest,\n // Both swallow their own failure. A claim that cannot be recorded or\n // released must not turn a completed purchase into a 500 — the money has\n // already moved by then, and the worst case here is a key that replays\n // nothing or one that goes unused.\n record: async (status: number, body: unknown): Promise<void> => {\n try {\n await ref.set(\n {\n status: 'done',\n responseStatus: status,\n response: body,\n settledAtMs: Date.now(),\n },\n { merge: true },\n )\n } catch {\n /* best effort */\n }\n },\n // A rejected or failed attempt must not burn the key: the customer fixes\n // the cause and presses the same button.\n release: async (): Promise<void> => {\n try {\n await ref.delete()\n } catch {\n /* best effort */\n }\n },\n },\n }\n}\n"],"names":["createHash","COLLECTION","API_IDEMPOTENCY_RETENTION_DAYS","apiIdempotencyExpiry","now","Date","getTime","deriveStripeObjectKey","digest","object","claimAttempt","store","scope","key","console","warn","kind","scopeId","orgId","claim","stripeKey","record","undefined","release","update","ref","collection","doc","create","status","createdAtMs","expiresAt","prior","get","priorResponse","replay","Number","body","error","busyMessage","set","responseStatus","response","settledAtMs","merge","delete"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,UAAU,QAAQ,cAAa;AA2ExC,4DAA4D,GAC5D,MAAMC,aAAa;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC,GACD,OAAO,MAAMC,iCAAiC,GAAE;AAEhD;;;;;;CAMC,GACD,OAAO,SAASC,qBAAqBC,MAAM,IAAIC,MAAM;IACnD,OAAO,IAAIA,KACTD,IAAIE,OAAO,KAAKJ,iCAAiC,KAAK,KAAK,KAAK;AAEpE;AAEA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASK,sBACdC,MAAqB,EACrBC,MAAc;IAEd,OAAOD,SAAS,GAAGA,OAAO,CAAC,EAAEC,QAAQ,GAAG;AAC1C;AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,eAAeC,aACpBC,KAAuB,EACvBC,KAAmB;IAEnB,uEAAuE;IACvE,oEAAoE;IACpE,EAAE;IACF,4EAA4E;IAC5E,iEAAiE;IACjE,kDAAkD;IAClD,wEAAwE;IACxE,qEAAqE;IACrE,0EAA0E;IAC1E,oBAAoB;IACpB,EAAE;IACF,6EAA6E;IAC7E,uEAAuE;IACvE,2EAA2E;IAC3E,oEAAoE;IACpE,2EAA2E;IAC3E,yEAAyE;IACzE,qEAAqE;IACrE,+DAA+D;IAC/D,EAAE;IACF,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,yEAAyE;IACzE,4EAA4E;IAC5E,8DAA8D;IAC9D,IAAI,CAACA,MAAMC,GAAG,EAAE;YAIuCD;QAHrDE,QAAQC,IAAI,CACV,0EACE,+DACF;YAAEC,MAAMJ,MAAMI,IAAI;YAAEC,SAASL,MAAMK,OAAO;YAAEC,KAAK,GAAEN,eAAAA,MAAMM,KAAK,YAAXN,eAAe;QAAK;QAEzE,OAAO;YACLO,OAAO;gBACLC,WAAW;gBACXC,QAAQ,UAAYC;gBACpBC,SAAS,UAAYD;YACvB;QACF;IACF;IACA,MAAMd,SAASR,WAAW,UACvBwB,MAAM,CAAC,GAAGZ,MAAMI,IAAI,CAAC,CAAC,EAAEJ,MAAMK,OAAO,CAAC,CAAC,EAAEL,MAAMC,GAAG,EAAE,EACpDL,MAAM,CAAC;IACV,MAAMiB,MAAMd,MAAMe,UAAU,CAACzB,YAAY0B,GAAG,CAACnB;IAC7C,IAAI;QACF,MAAMiB,IAAIG,MAAM,CAAC;YACfV,OAAON,MAAMM,KAAK,IAAI;YACtBD,SAASL,MAAMK,OAAO;YACtBD,MAAMJ,MAAMI,IAAI;YAChBa,QAAQ;YACRC,aAAazB,KAAKD,GAAG;YACrB,uEAAuE;YACvE,sEAAsE;YACtE,mEAAmE;YACnE,oEAAoE;YACpE,kCAAkC;YAClC2B,WAAW5B;QACb;IACF,EAAE,eAAM;QACN,yEAAyE;QACzE,4BAA4B;QAC5B,MAAM6B,QAAQ,MAAMP,IAAIQ,GAAG;QAC3B,MAAMC,gBAAgBF,MAAMC,GAAG,CAAC;QAChC,IAAIC,eAAe;gBAGEF;YAFnB,OAAO;gBACLG,QAAQ;oBACNN,QAAQO,QAAOJ,aAAAA,MAAMC,GAAG,CAAC,6BAAVD,aAA+B;oBAC9CK,MAAMH;gBACR;YACF;QACF;QACA,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,yBAAyB;QACzB,OAAO;YAAEC,QAAQ;gBAAEN,QAAQ;gBAAKQ,MAAM;oBAAEC,OAAO1B,MAAM2B,WAAW;gBAAC;YAAE;QAAE;IACvE;IACA,OAAO;QACLpB,OAAO;YACL,yEAAyE;YACzE,yEAAyE;YACzE,oDAAoD;YACpDC,WAAWZ;YACX,qEAAqE;YACrE,yEAAyE;YACzE,uEAAuE;YACvE,mCAAmC;YACnCa,QAAQ,OAAOQ,QAAgBQ;gBAC7B,IAAI;oBACF,MAAMZ,IAAIe,GAAG,CACX;wBACEX,QAAQ;wBACRY,gBAAgBZ;wBAChBa,UAAUL;wBACVM,aAAatC,KAAKD,GAAG;oBACvB,GACA;wBAAEwC,OAAO;oBAAK;gBAElB,EAAE,eAAM;gBACN,eAAe,GACjB;YACF;YACA,yEAAyE;YACzE,yCAAyC;YACzCrB,SAAS;gBACP,IAAI;oBACF,MAAME,IAAIoB,MAAM;gBAClB,EAAE,eAAM;gBACN,eAAe,GACjB;YACF;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Server half of the plugin pattern (AGL-396): the API-route registry, the
|
|
19
|
+
* server counterpart to the ConsoleExtension registry. A feature plugin
|
|
20
|
+
* registers request handlers here from its `/server` entry point (never its
|
|
21
|
+
* client barrel, so firebase-admin and other server-only deps stay out of
|
|
22
|
+
* the browser bundle). The app ships one catch-all dispatcher route per
|
|
23
|
+
* Next app that resolves a request path to a registered handler — so moving
|
|
24
|
+
* a feature's API into its plugin needs no new app route and keeps the same
|
|
25
|
+
* URL. Reference implementation: events-calendar `events/list` (AGL-396).
|
|
26
|
+
*
|
|
27
|
+
* The request/response shapes are structural (not `next` types) so plugins
|
|
28
|
+
* stay framework-light; `NextApiRequest`/`NextApiResponse` satisfy them, so
|
|
29
|
+
* the dispatcher passes Next's objects straight through.
|
|
30
|
+
*/
|
|
31
|
+
export interface PluginApiRequest {
|
|
32
|
+
method?: string;
|
|
33
|
+
query: Partial<Record<string, string | string[]>>;
|
|
34
|
+
body: any;
|
|
35
|
+
/**
|
|
36
|
+
* The unparsed request text, for handlers that verify signatures over the
|
|
37
|
+
* exact payload (Stripe/Svix webhooks registered as plugin API paths).
|
|
38
|
+
* UTF-8 re-encoding of the text is byte-identical for valid UTF-8 JSON.
|
|
39
|
+
*/
|
|
40
|
+
rawBody?: string;
|
|
41
|
+
headers: Partial<Record<string, string | string[]>>;
|
|
42
|
+
cookies: Partial<Record<string, string>>;
|
|
43
|
+
/**
|
|
44
|
+
* Node socket — the client-address fallback (`remoteAddress`).
|
|
45
|
+
*
|
|
46
|
+
* On the console's Pages Router this is the real transport peer. Behind the
|
|
47
|
+
* App Router adapter there is no socket, and `api-adapter.ts` fills it from
|
|
48
|
+
* the shared client-address reader so a handler falling back to it gets the
|
|
49
|
+
* same trusted hop rather than a caller-supplied one.
|
|
50
|
+
*/
|
|
51
|
+
socket: {
|
|
52
|
+
remoteAddress?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export interface PluginApiResponse {
|
|
56
|
+
status(code: number): PluginApiResponse;
|
|
57
|
+
json(body: unknown): void;
|
|
58
|
+
send(body: unknown): void;
|
|
59
|
+
setHeader(name: string, value: string | number | readonly string[]): void;
|
|
60
|
+
redirect(url: string): void;
|
|
61
|
+
redirect(status: number, url: string): void;
|
|
62
|
+
end(): void;
|
|
63
|
+
}
|
|
64
|
+
export type PluginApiHandler = (req: PluginApiRequest, res: PluginApiResponse) => void | Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* A handler in the Web shape (AGL-2939): the dispatcher's own `Request`
|
|
67
|
+
* in, a `Response` out — with a streamed body when the door streams, as
|
|
68
|
+
* the assistant's chat and a job's event feed do. `params` carries the
|
|
69
|
+
* dispatcher's path segments and any `:name` segment the registered path
|
|
70
|
+
* declared.
|
|
71
|
+
*/
|
|
72
|
+
export type PluginWebApiHandler = (request: Request, context: {
|
|
73
|
+
params: Record<string, string | string[]>;
|
|
74
|
+
}) => Response | Promise<Response>;
|
|
75
|
+
/** What a route registers: the (req, res) shape, or a Web handler. */
|
|
76
|
+
export type PluginApiRoute = PluginApiHandler | {
|
|
77
|
+
web: PluginWebApiHandler;
|
|
78
|
+
};
|
|
79
|
+
/** A registered route matched to a request path, with its `:name` segments filled. */
|
|
80
|
+
export interface PluginApiMatch {
|
|
81
|
+
route: PluginApiRoute;
|
|
82
|
+
params: Record<string, string>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Who a request is FOR, as far as the dispatchers' release gate is concerned
|
|
86
|
+
* (AGL-2978).
|
|
87
|
+
*
|
|
88
|
+
* The gate buckets a rollout and reads per-org overrides on an org id, and a
|
|
89
|
+
* dispatcher learns that id from the site a request names (`hostId`). Two
|
|
90
|
+
* kinds of request name no site and still belong to one organization:
|
|
91
|
+
*
|
|
92
|
+
* - a request to an ORGANIZATION-level surface (`ConsoleExtension.orgNavItems`,
|
|
93
|
+
* AGL-2974), which names its org rather than a site;
|
|
94
|
+
* - a request that arrives with no bearer token by design — a provider's
|
|
95
|
+
* OAuth redirect back to the platform, which carries only what the platform
|
|
96
|
+
* signed into it.
|
|
97
|
+
*
|
|
98
|
+
* Without a subject the gate treats both as anonymous, so a plugin released to
|
|
99
|
+
* one organization by override refused that organization's own requests, and
|
|
100
|
+
* a staff member previewing a dark plugin could not complete a redirect their
|
|
101
|
+
* own session had started.
|
|
102
|
+
*/
|
|
103
|
+
export interface PluginApiRequestSubject {
|
|
104
|
+
/** The organization: the rollout bucket and the override key. */
|
|
105
|
+
orgId: string | null;
|
|
106
|
+
/**
|
|
107
|
+
* The account the request acts for, read ONLY when the request carries no
|
|
108
|
+
* bearer token — a token speaks for itself. A route may name one only when
|
|
109
|
+
* it verified a signature binding the uid to the request, because the gate
|
|
110
|
+
* lets a staff account named here preview a released-off plugin.
|
|
111
|
+
*/
|
|
112
|
+
uid?: string | null;
|
|
113
|
+
}
|
|
114
|
+
/** Reads a request's subject; answers `null` when the request names none. */
|
|
115
|
+
export type PluginApiSubjectResolver = (request: Request) => PluginApiRequestSubject | null | Promise<PluginApiRequestSubject | null>;
|
|
116
|
+
/** What a registration may say about its route beyond the handler. */
|
|
117
|
+
export interface PluginApiRouteOptions {
|
|
118
|
+
/**
|
|
119
|
+
* How a request to this route names its subject when it names no site.
|
|
120
|
+
* Consulted by both dispatchers before their release gate, and only for a
|
|
121
|
+
* request with no `hostId`: a named site always decides the org.
|
|
122
|
+
*/
|
|
123
|
+
subject?: PluginApiSubjectResolver;
|
|
124
|
+
/**
|
|
125
|
+
* The route answers a link the platform MAILED to somebody — an
|
|
126
|
+
* unsubscribe in a message's `List-Unsubscribe` header — rather than a door
|
|
127
|
+
* a member uses (AGL-2981).
|
|
128
|
+
*
|
|
129
|
+
* Such a link has to keep working whether or not its plugin is released,
|
|
130
|
+
* or switched on, for the workspace NOW. A recipient's way out does not
|
|
131
|
+
* close when a rollout is paused or a workspace turns the plugin off:
|
|
132
|
+
* CAN-SPAM holds an opt-out open for thirty days after the send, and an
|
|
133
|
+
* unsubscribe that 404s the day a kill switch is flipped is one nobody can
|
|
134
|
+
* use. So both dispatchers skip their per-site enablement and release
|
|
135
|
+
* gates for it — and nothing else: lockdown and the rate limit still
|
|
136
|
+
* apply. The flag says nothing about who may act, so the route
|
|
137
|
+
* authenticates the link itself, by a signature it verifies.
|
|
138
|
+
*/
|
|
139
|
+
recipientLink?: boolean;
|
|
140
|
+
}
|
|
141
|
+
export { setRegisteringPluginId, getRegisteringPluginId, } from './registering-plugin';
|
|
142
|
+
/**
|
|
143
|
+
* Registers a plugin API handler at a host-relative path (e.g.
|
|
144
|
+
* 'events/list'), served by the app dispatcher at `/api/events/list`.
|
|
145
|
+
*
|
|
146
|
+
* Idempotent by path FOR ITS OWNER — re-registration by the plugin that
|
|
147
|
+
* holds the path replaces the previous handler, which is what a hot reload,
|
|
148
|
+
* a second surface, and a repeated init all depend on.
|
|
149
|
+
*
|
|
150
|
+
* A different plugin is REFUSED (AGL-2484). This map is process-global and
|
|
151
|
+
* was last-writer-wins on the path alone, while Aglyn's own commission-taking
|
|
152
|
+
* handlers sit at `marketplace/checkout` and `commerce/checkout` — and the
|
|
153
|
+
* tenant dispatcher calls `ensureRemoteServerBundles()` after the first-party
|
|
154
|
+
* loader has run, so a remote bundle registering either path was simply the
|
|
155
|
+
* later writer. Getting there needs `PLUGIN_REMOTE_SERVER=enabled` (off by
|
|
156
|
+
* default), realm trust and a valid signature, so this is the last of several
|
|
157
|
+
* doors rather than the only one; it is also the one the registry could close
|
|
158
|
+
* by itself, because it already recorded who registered what.
|
|
159
|
+
*
|
|
160
|
+
* Anonymous registration — no loader marker — is an IDENTITY here, not a
|
|
161
|
+
* wildcard: it may replace itself and nothing else may take it.
|
|
162
|
+
*/
|
|
163
|
+
export declare function registerPluginApiRoute(path: string, handler: PluginApiRoute, options?: PluginApiRouteOptions): void;
|
|
164
|
+
/** The plugin that registered a path, for per-org enablement gating. */
|
|
165
|
+
export declare function pluginIdForRegisteredApiPath(path: string): string | undefined;
|
|
166
|
+
export declare function unregisterPluginApiRoute(path: string): void;
|
|
167
|
+
/**
|
|
168
|
+
* The route for a request path, or undefined when nothing is registered.
|
|
169
|
+
*
|
|
170
|
+
* An exact registration wins; otherwise a registration whose path carries
|
|
171
|
+
* `:name` segments matches segment for segment (`ai/jobs/:jobId/cancel`
|
|
172
|
+
* answers `ai/jobs/abc/cancel`), and the named segments come back as
|
|
173
|
+
* `params`. Patterns are tried in registration order and a static segment
|
|
174
|
+
* beats a named one only by being registered exactly.
|
|
175
|
+
*/
|
|
176
|
+
export declare function resolvePluginApiMatch(path: string): PluginApiMatch | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* Whether a request path resolves to a route registered as a
|
|
179
|
+
* {@link PluginApiRouteOptions.recipientLink} — what both dispatchers ask
|
|
180
|
+
* before their enablement and release gates (AGL-2981).
|
|
181
|
+
*/
|
|
182
|
+
export declare function isPluginRecipientLinkRoute(path: string): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* The subject a request to a registered route names, or `null` (AGL-2978).
|
|
185
|
+
*
|
|
186
|
+
* `null` when the route declared no resolver, when the resolver answered
|
|
187
|
+
* nothing, and when it THREW: a resolver that cannot read its request has
|
|
188
|
+
* named no subject, and the gate then treats the request as anonymous — the
|
|
189
|
+
* conservative direction. The resolver reads a clone, so the handler still
|
|
190
|
+
* receives the untouched body. Ids are held to a plain path segment, so a
|
|
191
|
+
* resolver cannot hand the gate a path to read overrides from.
|
|
192
|
+
*/
|
|
193
|
+
export declare function resolvePluginApiRequestSubject(path: string, request: Request): Promise<PluginApiRequestSubject | null>;
|
|
194
|
+
/**
|
|
195
|
+
* The legacy (node-style) handler at a request path, or undefined when
|
|
196
|
+
* nothing is registered there or the route is a web handler — a web route
|
|
197
|
+
* is reached through `resolvePluginApiMatch` and `runPluginApiMatch`, since
|
|
198
|
+
* it takes the `Request` and the filled `:name` segments, not a `req`/`res`
|
|
199
|
+
* pair.
|
|
200
|
+
*/
|
|
201
|
+
export declare function resolvePluginApiRoute(path: string): PluginApiHandler | undefined;
|
|
202
|
+
/**
|
|
203
|
+
* Runs a matched route against the dispatcher's request: a Web handler is
|
|
204
|
+
* called as it is, and a (req, res) handler goes through the adapter the
|
|
205
|
+
* caller supplies — the adapter lives on the `/server` entry, which this
|
|
206
|
+
* module may not import.
|
|
207
|
+
*/
|
|
208
|
+
export declare function runPluginApiMatch(match: PluginApiMatch, request: Request, params: Record<string, string | string[]>, runLegacy: (handler: PluginApiHandler, request: Request, params: Record<string, string | string[]>) => Promise<Response>): Promise<Response>;
|
|
209
|
+
/** Registered paths, for diagnostics. */
|
|
210
|
+
export declare function listPluginApiRoutes(): string[];
|