@aphexcms/cms-core 9.3.0 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/block-previews.svelte.d.ts +46 -0
- package/dist/admin/block-previews.svelte.d.ts.map +1 -0
- package/dist/admin/block-previews.svelte.js +26 -0
- package/dist/admin/field-components.svelte.d.ts +16 -0
- package/dist/admin/field-components.svelte.d.ts.map +1 -0
- package/dist/admin/field-components.svelte.js +18 -0
- package/dist/admin/nav.svelte.d.ts +34 -0
- package/dist/admin/nav.svelte.d.ts.map +1 -0
- package/dist/admin/nav.svelte.js +78 -0
- package/dist/admin/slots.svelte.d.ts +50 -0
- package/dist/admin/slots.svelte.d.ts.map +1 -0
- package/dist/admin/slots.svelte.js +67 -0
- package/dist/admin/types.d.ts +7 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +1 -0
- package/dist/api/schemas/api-keys.d.ts +4 -37
- package/dist/api/schemas/api-keys.d.ts.map +1 -1
- package/dist/api/schemas/api-keys.js +5 -2
- package/dist/api/schemas/assets.d.ts +4 -0
- package/dist/api/schemas/assets.d.ts.map +1 -1
- package/dist/api/schemas/assets.js +3 -0
- package/dist/api/schemas/plugin-settings.d.ts +6 -0
- package/dist/api/schemas/plugin-settings.d.ts.map +1 -0
- package/dist/api/schemas/plugin-settings.js +8 -0
- package/dist/api/schemas/roles.d.ts +7 -56
- package/dist/api/schemas/roles.d.ts.map +1 -1
- package/dist/api/schemas/roles.js +11 -6
- package/dist/api/schemas/user.d.ts +2 -1
- package/dist/api/schemas/user.d.ts.map +1 -1
- package/dist/api/schemas/user.js +7 -2
- package/dist/app-augment.d.ts +11 -0
- package/dist/app-augment.d.ts.map +1 -1
- package/dist/app.d.ts +2 -0
- package/dist/auth/provider.d.ts +3 -0
- package/dist/auth/provider.d.ts.map +1 -1
- package/dist/cli/generate-types.d.ts +10 -5
- package/dist/cli/generate-types.d.ts.map +1 -1
- package/dist/cli/generate-types.js +117 -77
- package/dist/cli/generate-types.js.map +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/migrate.d.ts +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +27 -2
- package/dist/cli/migrate.js.map +1 -1
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +9 -0
- package/dist/components/AdminApp.svelte +271 -113
- package/dist/components/AdminApp.svelte.d.ts +18 -2
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/AdminSlot.svelte +18 -0
- package/dist/components/admin/AdminSlot.svelte.d.ts +12 -0
- package/dist/components/admin/AdminSlot.svelte.d.ts.map +1 -0
- package/dist/components/admin/DocumentEditor.svelte +646 -385
- package/dist/components/admin/DocumentEditor.svelte.d.ts +13 -0
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/MediaBrowser.svelte +13 -3
- package/dist/components/admin/MediaBrowser.svelte.d.ts.map +1 -1
- package/dist/components/admin/PluginSettingsPanel.svelte +231 -0
- package/dist/components/admin/PluginSettingsPanel.svelte.d.ts +8 -0
- package/dist/components/admin/PluginSettingsPanel.svelte.d.ts.map +1 -0
- package/dist/components/admin/SchemaField.svelte +76 -95
- package/dist/components/admin/SchemaField.svelte.d.ts +7 -0
- package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +24 -2
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/FieldInput.svelte +109 -0
- package/dist/components/admin/fields/FieldInput.svelte.d.ts +17 -0
- package/dist/components/admin/fields/FieldInput.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/richtext/PortableTextImageView.svelte +5 -12
- package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts +2 -9
- package/dist/components/admin/fields/richtext/PortableTextImageView.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte +18 -17
- package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts +2 -9
- package/dist/components/admin/fields/richtext/PortableTextObjectView.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/richtext/RichtextField.svelte +55 -2
- package/dist/components/admin/fields/richtext/RichtextField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
- package/dist/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
- package/dist/components/admin/fields/richtext/portable-text-object-node.js +4 -2
- package/dist/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
- package/dist/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
- package/dist/components/admin/fields/richtext/svelte-node-view.js +20 -1
- package/dist/components/layout/OrganizationSwitcher.svelte +31 -10
- package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +1 -1
- package/dist/components/layout/Sidebar.svelte +49 -11
- package/dist/components/layout/Sidebar.svelte.d.ts +5 -1
- package/dist/components/layout/Sidebar.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/AppSidebar.svelte +66 -3
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +5 -0
- package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/NavMain.svelte +3 -2
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts +4 -3
- package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +1 -1
- package/dist/components/layout/sidebar/NavUser.svelte +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/db/interfaces/asset.d.ts +1 -0
- package/dist/db/interfaces/asset.d.ts.map +1 -1
- package/dist/db/interfaces/index.d.ts +3 -1
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/plugin-settings.d.ts +23 -0
- package/dist/db/interfaces/plugin-settings.d.ts.map +1 -0
- package/dist/db/interfaces/plugin-settings.js +13 -0
- package/dist/db/interfaces/role.d.ts +14 -5
- package/dist/db/interfaces/role.d.ts.map +1 -1
- package/dist/engine.d.ts +28 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +44 -0
- package/dist/field-validation/utils.d.ts +15 -0
- package/dist/field-validation/utils.d.ts.map +1 -1
- package/dist/field-validation/utils.js +74 -0
- package/dist/graphql/resolvers.d.ts.map +1 -1
- package/dist/graphql/resolvers.js +9 -10
- package/dist/graphql/schema.d.ts.map +1 -1
- package/dist/graphql/schema.js +18 -19
- package/dist/hooks.d.ts +6 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +59 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/lib/admin/block-previews.svelte.d.ts +46 -0
- package/dist/lib/admin/block-previews.svelte.d.ts.map +1 -0
- package/dist/lib/admin/block-previews.svelte.js +27 -0
- package/dist/lib/admin/block-previews.svelte.js.map +1 -0
- package/dist/lib/admin/field-components.svelte.d.ts +16 -0
- package/dist/lib/admin/field-components.svelte.d.ts.map +1 -0
- package/dist/lib/admin/field-components.svelte.js +19 -0
- package/dist/lib/admin/field-components.svelte.js.map +1 -0
- package/dist/lib/admin/nav.svelte.d.ts +34 -0
- package/dist/lib/admin/nav.svelte.d.ts.map +1 -0
- package/dist/lib/admin/nav.svelte.js +79 -0
- package/dist/lib/admin/nav.svelte.js.map +1 -0
- package/dist/lib/admin/slots.svelte.d.ts +50 -0
- package/dist/lib/admin/slots.svelte.d.ts.map +1 -0
- package/dist/lib/admin/slots.svelte.js +68 -0
- package/dist/lib/admin/slots.svelte.js.map +1 -0
- package/dist/lib/admin/types.d.ts +7 -0
- package/dist/lib/admin/types.d.ts.map +1 -0
- package/dist/lib/admin/types.js +2 -0
- package/dist/lib/admin/types.js.map +1 -0
- package/dist/lib/api/schemas/api-keys.d.ts +4 -37
- package/dist/lib/api/schemas/api-keys.d.ts.map +1 -1
- package/dist/lib/api/schemas/api-keys.js +5 -2
- package/dist/lib/api/schemas/api-keys.js.map +1 -1
- package/dist/lib/api/schemas/assets.d.ts +4 -0
- package/dist/lib/api/schemas/assets.d.ts.map +1 -1
- package/dist/lib/api/schemas/assets.js +3 -0
- package/dist/lib/api/schemas/assets.js.map +1 -1
- package/dist/lib/api/schemas/plugin-settings.d.ts +6 -0
- package/dist/lib/api/schemas/plugin-settings.d.ts.map +1 -0
- package/dist/lib/api/schemas/plugin-settings.js +9 -0
- package/dist/lib/api/schemas/plugin-settings.js.map +1 -0
- package/dist/lib/api/schemas/roles.d.ts +7 -56
- package/dist/lib/api/schemas/roles.d.ts.map +1 -1
- package/dist/lib/api/schemas/roles.js +11 -6
- package/dist/lib/api/schemas/roles.js.map +1 -1
- package/dist/lib/api/schemas/user.d.ts +2 -1
- package/dist/lib/api/schemas/user.d.ts.map +1 -1
- package/dist/lib/api/schemas/user.js +7 -2
- package/dist/lib/api/schemas/user.js.map +1 -1
- package/dist/lib/app-augment.d.ts +11 -0
- package/dist/lib/app-augment.d.ts.map +1 -1
- package/dist/lib/auth/provider.d.ts +3 -0
- package/dist/lib/auth/provider.d.ts.map +1 -1
- package/dist/lib/client/index.d.ts +6 -0
- package/dist/lib/client/index.d.ts.map +1 -1
- package/dist/lib/client/index.js +9 -0
- package/dist/lib/client/index.js.map +1 -1
- package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts +7 -0
- package/dist/lib/components/admin/fields/richtext/portable-text-object-node.d.ts.map +1 -1
- package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js +4 -2
- package/dist/lib/components/admin/fields/richtext/portable-text-object-node.js.map +1 -1
- package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts +16 -1
- package/dist/lib/components/admin/fields/richtext/svelte-node-view.d.ts.map +1 -1
- package/dist/lib/components/admin/fields/richtext/svelte-node-view.js +20 -1
- package/dist/lib/components/admin/fields/richtext/svelte-node-view.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +11 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/db/interfaces/asset.d.ts +1 -0
- package/dist/lib/db/interfaces/asset.d.ts.map +1 -1
- package/dist/lib/db/interfaces/index.d.ts +3 -1
- package/dist/lib/db/interfaces/index.d.ts.map +1 -1
- package/dist/lib/db/interfaces/plugin-settings.d.ts +23 -0
- package/dist/lib/db/interfaces/plugin-settings.d.ts.map +1 -0
- package/dist/lib/db/interfaces/plugin-settings.js +14 -0
- package/dist/lib/db/interfaces/plugin-settings.js.map +1 -0
- package/dist/lib/db/interfaces/role.d.ts +14 -5
- package/dist/lib/db/interfaces/role.d.ts.map +1 -1
- package/dist/lib/engine.d.ts +28 -0
- package/dist/lib/engine.d.ts.map +1 -1
- package/dist/lib/engine.js +44 -0
- package/dist/lib/engine.js.map +1 -1
- package/dist/lib/field-validation/utils.d.ts +15 -0
- package/dist/lib/field-validation/utils.d.ts.map +1 -1
- package/dist/lib/field-validation/utils.js +74 -0
- package/dist/lib/field-validation/utils.js.map +1 -1
- package/dist/lib/graphql/resolvers.d.ts.map +1 -1
- package/dist/lib/graphql/resolvers.js +9 -10
- package/dist/lib/graphql/resolvers.js.map +1 -1
- package/dist/lib/graphql/schema.d.ts.map +1 -1
- package/dist/lib/graphql/schema.js +18 -19
- package/dist/lib/graphql/schema.js.map +1 -1
- package/dist/lib/hooks.d.ts +6 -0
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +59 -2
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +5 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/local-api/collection-api.d.ts.map +1 -1
- package/dist/lib/local-api/collection-api.js +4 -2
- package/dist/lib/local-api/collection-api.js.map +1 -1
- package/dist/lib/local-api/types.d.ts +8 -0
- package/dist/lib/local-api/types.d.ts.map +1 -1
- package/dist/lib/mcp/tools.d.ts.map +1 -1
- package/dist/lib/mcp/tools.js +110 -1
- package/dist/lib/mcp/tools.js.map +1 -1
- package/dist/lib/permissions-context.svelte.d.ts +7 -4
- package/dist/lib/permissions-context.svelte.d.ts.map +1 -1
- package/dist/lib/permissions-context.svelte.js.map +1 -1
- package/dist/lib/plugins/index.d.ts +3 -0
- package/dist/lib/plugins/index.d.ts.map +1 -0
- package/dist/lib/plugins/index.js +3 -0
- package/dist/lib/plugins/index.js.map +1 -0
- package/dist/lib/plugins/resolver.d.ts +49 -0
- package/dist/lib/plugins/resolver.d.ts.map +1 -0
- package/dist/lib/plugins/resolver.js +66 -0
- package/dist/lib/plugins/resolver.js.map +1 -0
- package/dist/lib/plugins/types.d.ts +233 -0
- package/dist/lib/plugins/types.d.ts.map +1 -0
- package/dist/lib/plugins/types.js +9 -0
- package/dist/lib/plugins/types.js.map +1 -0
- package/dist/lib/schema-utils/desugar.d.ts +27 -0
- package/dist/lib/schema-utils/desugar.d.ts.map +1 -0
- package/dist/lib/schema-utils/desugar.js +102 -0
- package/dist/lib/schema-utils/desugar.js.map +1 -0
- package/dist/lib/schema-utils/index.d.ts +2 -0
- package/dist/lib/schema-utils/index.d.ts.map +1 -1
- package/dist/lib/schema-utils/index.js +2 -0
- package/dist/lib/schema-utils/index.js.map +1 -1
- package/dist/lib/schema-utils/settings.d.ts +17 -0
- package/dist/lib/schema-utils/settings.d.ts.map +1 -0
- package/dist/lib/schema-utils/settings.js +23 -0
- package/dist/lib/schema-utils/settings.js.map +1 -0
- package/dist/lib/schema-utils/validator.d.ts.map +1 -1
- package/dist/lib/schema-utils/validator.js +11 -0
- package/dist/lib/schema-utils/validator.js.map +1 -1
- package/dist/lib/security/secret-crypto.d.ts +18 -0
- package/dist/lib/security/secret-crypto.d.ts.map +1 -0
- package/dist/lib/security/secret-crypto.js +71 -0
- package/dist/lib/security/secret-crypto.js.map +1 -0
- package/dist/lib/server/api/index.d.ts.map +1 -1
- package/dist/lib/server/api/index.js +3 -0
- package/dist/lib/server/api/index.js.map +1 -1
- package/dist/lib/server/api/routes/assets.d.ts.map +1 -1
- package/dist/lib/server/api/routes/assets.js +8 -2
- package/dist/lib/server/api/routes/assets.js.map +1 -1
- package/dist/lib/server/api/routes/organizations.d.ts.map +1 -1
- package/dist/lib/server/api/routes/organizations.js +4 -1
- package/dist/lib/server/api/routes/organizations.js.map +1 -1
- package/dist/lib/server/api/routes/plugin-settings.d.ts +4 -0
- package/dist/lib/server/api/routes/plugin-settings.d.ts.map +1 -0
- package/dist/lib/server/api/routes/plugin-settings.js +109 -0
- package/dist/lib/server/api/routes/plugin-settings.js.map +1 -0
- package/dist/lib/server/api/routes/roles.d.ts.map +1 -1
- package/dist/lib/server/api/routes/roles.js +37 -0
- package/dist/lib/server/api/routes/roles.js.map +1 -1
- package/dist/lib/server/api/routes/user.d.ts.map +1 -1
- package/dist/lib/server/api/routes/user.js +14 -3
- package/dist/lib/server/api/routes/user.js.map +1 -1
- package/dist/lib/services/asset-service.d.ts +1 -0
- package/dist/lib/services/asset-service.d.ts.map +1 -1
- package/dist/lib/services/asset-service.js.map +1 -1
- package/dist/lib/services/index.d.ts +2 -0
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +1 -0
- package/dist/lib/services/index.js.map +1 -1
- package/dist/lib/services/plugin-settings-service.d.ts +76 -0
- package/dist/lib/services/plugin-settings-service.d.ts.map +1 -0
- package/dist/lib/services/plugin-settings-service.js +236 -0
- package/dist/lib/services/plugin-settings-service.js.map +1 -0
- package/dist/lib/services/roles-service.d.ts +2 -2
- package/dist/lib/services/roles-service.d.ts.map +1 -1
- package/dist/lib/services/roles-service.js.map +1 -1
- package/dist/lib/theme/css.d.ts +30 -0
- package/dist/lib/theme/css.d.ts.map +1 -0
- package/dist/lib/theme/css.js +54 -0
- package/dist/lib/theme/css.js.map +1 -0
- package/dist/lib/theme/derive.d.ts +27 -0
- package/dist/lib/theme/derive.d.ts.map +1 -0
- package/dist/lib/theme/derive.js +108 -0
- package/dist/lib/theme/derive.js.map +1 -0
- package/dist/lib/theme/index.d.ts +5 -0
- package/dist/lib/theme/index.d.ts.map +1 -0
- package/dist/lib/theme/index.js +5 -0
- package/dist/lib/theme/index.js.map +1 -0
- package/dist/lib/theme/schemes.d.ts +60 -0
- package/dist/lib/theme/schemes.d.ts.map +1 -0
- package/dist/lib/theme/schemes.js +150 -0
- package/dist/lib/theme/schemes.js.map +1 -0
- package/dist/lib/theme/tokens.d.ts +57 -0
- package/dist/lib/theme/tokens.d.ts.map +1 -0
- package/dist/lib/theme/tokens.js +11 -0
- package/dist/lib/theme/tokens.js.map +1 -0
- package/dist/lib/types/auth.d.ts +10 -10
- package/dist/lib/types/auth.d.ts.map +1 -1
- package/dist/lib/types/capabilities.d.ts +50 -9
- package/dist/lib/types/capabilities.d.ts.map +1 -1
- package/dist/lib/types/capabilities.js +147 -5
- package/dist/lib/types/capabilities.js.map +1 -1
- package/dist/lib/types/config.d.ts +30 -1
- package/dist/lib/types/config.d.ts.map +1 -1
- package/dist/lib/types/schemas.d.ts +90 -2
- package/dist/lib/types/schemas.d.ts.map +1 -1
- package/dist/lib/types/schemas.js.map +1 -1
- package/dist/lib/types/sidebar.d.ts +3 -1
- package/dist/lib/types/sidebar.d.ts.map +1 -1
- package/dist/lib/utils/index.d.ts +1 -0
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js +1 -0
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/preview.d.ts +16 -5
- package/dist/lib/utils/preview.d.ts.map +1 -1
- package/dist/lib/utils/preview.js +7 -2
- package/dist/lib/utils/preview.js.map +1 -1
- package/dist/lib/utils/string-case.d.ts +21 -0
- package/dist/lib/utils/string-case.d.ts.map +1 -0
- package/dist/lib/utils/string-case.js +26 -0
- package/dist/lib/utils/string-case.js.map +1 -0
- package/dist/lib/vite/index.d.ts +7 -0
- package/dist/lib/vite/index.d.ts.map +1 -1
- package/dist/lib/vite/index.js +37 -6
- package/dist/lib/vite/index.js.map +1 -1
- package/dist/local-api/collection-api.d.ts.map +1 -1
- package/dist/local-api/collection-api.js +4 -2
- package/dist/local-api/types.d.ts +8 -0
- package/dist/local-api/types.d.ts.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +110 -1
- package/dist/permissions-context.svelte.d.ts +7 -4
- package/dist/permissions-context.svelte.d.ts.map +1 -1
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +2 -0
- package/dist/plugins/resolver.d.ts +49 -0
- package/dist/plugins/resolver.d.ts.map +1 -0
- package/dist/plugins/resolver.js +65 -0
- package/dist/plugins/types.d.ts +233 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +8 -0
- package/dist/schema-utils/desugar.d.ts +27 -0
- package/dist/schema-utils/desugar.d.ts.map +1 -0
- package/dist/schema-utils/desugar.js +101 -0
- package/dist/schema-utils/index.d.ts +2 -0
- package/dist/schema-utils/index.d.ts.map +1 -1
- package/dist/schema-utils/index.js +2 -0
- package/dist/schema-utils/settings.d.ts +17 -0
- package/dist/schema-utils/settings.d.ts.map +1 -0
- package/dist/schema-utils/settings.js +22 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +11 -0
- package/dist/security/secret-crypto.d.ts +18 -0
- package/dist/security/secret-crypto.d.ts.map +1 -0
- package/dist/security/secret-crypto.js +70 -0
- package/dist/server/api/index.d.ts.map +1 -1
- package/dist/server/api/index.js +3 -0
- package/dist/server/api/routes/assets.d.ts.map +1 -1
- package/dist/server/api/routes/assets.js +8 -2
- package/dist/server/api/routes/organizations.d.ts.map +1 -1
- package/dist/server/api/routes/organizations.js +4 -1
- package/dist/server/api/routes/plugin-settings.d.ts +4 -0
- package/dist/server/api/routes/plugin-settings.d.ts.map +1 -0
- package/dist/server/api/routes/plugin-settings.js +108 -0
- package/dist/server/api/routes/roles.d.ts.map +1 -1
- package/dist/server/api/routes/roles.js +37 -0
- package/dist/server/api/routes/user.d.ts.map +1 -1
- package/dist/server/api/routes/user.js +14 -3
- package/dist/services/asset-service.d.ts +1 -0
- package/dist/services/asset-service.d.ts.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -0
- package/dist/services/plugin-settings-service.d.ts +76 -0
- package/dist/services/plugin-settings-service.d.ts.map +1 -0
- package/dist/services/plugin-settings-service.js +235 -0
- package/dist/services/roles-service.d.ts +2 -2
- package/dist/services/roles-service.d.ts.map +1 -1
- package/dist/theme/css.d.ts +30 -0
- package/dist/theme/css.d.ts.map +1 -0
- package/dist/theme/css.js +53 -0
- package/dist/theme/derive.d.ts +27 -0
- package/dist/theme/derive.d.ts.map +1 -0
- package/dist/theme/derive.js +107 -0
- package/dist/theme/index.d.ts +5 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +4 -0
- package/dist/theme/schemes.d.ts +60 -0
- package/dist/theme/schemes.d.ts.map +1 -0
- package/dist/theme/schemes.js +149 -0
- package/dist/theme/tokens.d.ts +57 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +10 -0
- package/dist/types/auth.d.ts +10 -10
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/capabilities.d.ts +50 -9
- package/dist/types/capabilities.d.ts.map +1 -1
- package/dist/types/capabilities.js +147 -5
- package/dist/types/config.d.ts +30 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/schemas.d.ts +90 -2
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/sidebar.d.ts +3 -1
- package/dist/types/sidebar.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/preview.d.ts +16 -5
- package/dist/utils/preview.d.ts.map +1 -1
- package/dist/utils/preview.js +7 -2
- package/dist/utils/string-case.d.ts +21 -0
- package/dist/utils/string-case.d.ts.map +1 -0
- package/dist/utils/string-case.js +25 -0
- package/dist/vite/index.d.ts +7 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +37 -6
- package/package.json +6 -4
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin type system — the public authoring surface.
|
|
3
|
+
*
|
|
4
|
+
* A plugin is a manifest of typed "parts", each implementing a named extension
|
|
5
|
+
* point. The kinds are split into two planes (see PLUGIN_SYSTEM_PLAN.md §Constraint):
|
|
6
|
+
*
|
|
7
|
+
* - SERVER / serializable plane — schemas, server routes, capabilities. Collected
|
|
8
|
+
* by the engine at boot; safe to reason about without loading any component.
|
|
9
|
+
* - COMPONENT plane — document actions, admin tools, field components. These carry
|
|
10
|
+
* Svelte components and are only ever imported into admin module code, never
|
|
11
|
+
* passed through SvelteKit `load` (load data must stay serializable).
|
|
12
|
+
*
|
|
13
|
+
* All imports here are type-only, so this module is safe on both planes.
|
|
14
|
+
*/
|
|
15
|
+
import type { Component } from 'svelte';
|
|
16
|
+
import type { Context, Hono } from 'hono';
|
|
17
|
+
import type { AphexEnv } from '../server/api/index.js';
|
|
18
|
+
import type { Field, SettingsField, SchemaType } from '../types/schemas.js';
|
|
19
|
+
import type { AdminArea } from '../admin/types.js';
|
|
20
|
+
import type { CapabilityDefinition } from '../types/capabilities.js';
|
|
21
|
+
/** Known extension points. Plugins may also register custom string kinds. */
|
|
22
|
+
export type PartKind = 'aphex/schema' | 'aphex/schema/transform' | 'aphex/server/route' | 'aphex/capabilities' | 'aphex/settings' | 'aphex/document/action' | 'aphex/admin/tool' | 'aphex/field/component';
|
|
23
|
+
/** Contributes content schemas, merged into the app's `schemaTypes`. */
|
|
24
|
+
export interface SchemaPart {
|
|
25
|
+
implements: 'aphex/schema';
|
|
26
|
+
schemas: SchemaType[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Transforms the resolved schema list — decorate existing types, not just add new
|
|
30
|
+
* ones (e.g. inject an SEO field group into a set of collections). Runs after all
|
|
31
|
+
* `aphex/schema` parts merge, on both the server engine and the admin, so the
|
|
32
|
+
* transform must be pure and deterministic. This is what lets a plugin "enable"
|
|
33
|
+
* itself on chosen document types the way Payload's `collections: [...]` does.
|
|
34
|
+
*/
|
|
35
|
+
export interface SchemaTransformPart {
|
|
36
|
+
implements: 'aphex/schema/transform';
|
|
37
|
+
transform: (schemas: SchemaType[]) => SchemaType[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Contributes an HTTP endpoint under `/api`. `path: '/bookings'` + `method: 'POST'`
|
|
41
|
+
* becomes `POST /api/bookings`. The handler gets the same Hono context as built-ins
|
|
42
|
+
* (`c.var.aphexCMS`, `c.var.auth`).
|
|
43
|
+
*/
|
|
44
|
+
export interface ServerRoutePart {
|
|
45
|
+
implements: 'aphex/server/route';
|
|
46
|
+
/** Unique across all plugins — collisions are a startup error. */
|
|
47
|
+
id: string;
|
|
48
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
49
|
+
path: string;
|
|
50
|
+
handler: (c: Context<AphexEnv>) => Response | Promise<Response>;
|
|
51
|
+
/**
|
|
52
|
+
* Who may call this route. Mandatory and with no default: a plugin route is an
|
|
53
|
+
* ordinary internet-facing endpoint, and "I forgot" must not be spellable as
|
|
54
|
+
* "anyone may call this". Say which of the three you mean:
|
|
55
|
+
*
|
|
56
|
+
* - `['forms.export']` — must be authenticated AND hold every listed capability.
|
|
57
|
+
* The usual answer. The CMS gates the route before the handler runs (401 with no
|
|
58
|
+
* session/api-key, 403 when capabilities are missing), so the check can't be
|
|
59
|
+
* forgotten in the handler.
|
|
60
|
+
* - `[]` — must be authenticated, but any role will do. Use when membership of the
|
|
61
|
+
* organization is itself the authorization.
|
|
62
|
+
* - `'public'` — no gate; anyone on the internet can call it. For webhook receivers
|
|
63
|
+
* and the like, where the handler does its own verification (a signature, a shared
|
|
64
|
+
* secret). Opting out is deliberate and greppable.
|
|
65
|
+
*/
|
|
66
|
+
requiredCapabilities: string[] | 'public';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Declares custom capabilities this plugin introduces — surfaced (and assignable) in
|
|
70
|
+
* the roles UI. Pass `defineCapability(id, { title, description, group })` for full
|
|
71
|
+
* metadata, or a bare id string (labelled from its last segment). Merged with the
|
|
72
|
+
* built-in catalog by the part resolver (`capabilityCatalog()`); a plugin can't
|
|
73
|
+
* redefine a core capability.
|
|
74
|
+
*/
|
|
75
|
+
export interface CapabilitiesPart {
|
|
76
|
+
implements: 'aphex/capabilities';
|
|
77
|
+
capabilities: (string | CapabilityDefinition)[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Declares a plugin's **settings surface** — configuration a user edits in the
|
|
81
|
+
* admin UI (connection details, toggles, and — in phase 2 — secrets), stored
|
|
82
|
+
* per-`(organization, plugin)` and injected back into the plugin's server code.
|
|
83
|
+
*
|
|
84
|
+
* This is CONFIG, not content: settings are deliberately NOT content schema types.
|
|
85
|
+
* They never enter document lists, draft/published perspectives, versioning, the
|
|
86
|
+
* content REST/GraphQL API, MCP tools, or generated types. Only the field *renderer*
|
|
87
|
+
* is reused (the same UI that draws a document field), never the type registry,
|
|
88
|
+
* content storage, or content API. See references/plugin-settings-and-secrets-scope.md.
|
|
89
|
+
*
|
|
90
|
+
* Declaration only, like every other serializable part — the host owns rendering,
|
|
91
|
+
* storage, encryption, gating, and injection. A plugin only says what its settings
|
|
92
|
+
* look like.
|
|
93
|
+
*/
|
|
94
|
+
export interface SettingsPart {
|
|
95
|
+
implements: 'aphex/settings';
|
|
96
|
+
/**
|
|
97
|
+
* Which plugin these settings belong to — the storage key alongside the org.
|
|
98
|
+
* Use the plugin's package name (e.g. `@aphexcms/forms`) so it's stable and unique.
|
|
99
|
+
*/
|
|
100
|
+
pluginId: string;
|
|
101
|
+
/** Human label for the settings section in the admin UI. */
|
|
102
|
+
title: string;
|
|
103
|
+
/** Optional one-line description shown under the title. */
|
|
104
|
+
description?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The settings fields. `SettingsField` is a deliberately narrow subset — `string`,
|
|
107
|
+
* `text`, `number`, `boolean`, plus the settings-only `secret` (write-only,
|
|
108
|
+
* encrypted at rest) — so every declared field is one the panel really renders and
|
|
109
|
+
* the service really validates. No content-schema features (references, portable
|
|
110
|
+
* text, assets) and no custom `input` widgets. Values are type-checked against
|
|
111
|
+
* these declarations on save.
|
|
112
|
+
*/
|
|
113
|
+
fields: SettingsField[];
|
|
114
|
+
/**
|
|
115
|
+
* Capabilities required to view/edit this settings section. Defaults to the
|
|
116
|
+
* built-in `plugin.settings.manage` when omitted — set a narrower capability to
|
|
117
|
+
* gate a specific plugin's settings more tightly.
|
|
118
|
+
*/
|
|
119
|
+
requiredCapabilities?: string[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A minimal, stable context handed to a document-action component. Deliberately
|
|
123
|
+
* decoupled from editor internals — actions get exactly this and nothing more, so
|
|
124
|
+
* the editor can be refactored without breaking plugins.
|
|
125
|
+
*/
|
|
126
|
+
export interface DocumentActionProps {
|
|
127
|
+
/** Null while the document is new and unsaved. */
|
|
128
|
+
documentId: string | null;
|
|
129
|
+
schema: SchemaType;
|
|
130
|
+
/** The live edited draft data. */
|
|
131
|
+
data: Record<string, unknown>;
|
|
132
|
+
status: 'new' | 'draft' | 'published' | 'unpublished';
|
|
133
|
+
/** Shallow-merge a patch into the document's data. */
|
|
134
|
+
updateData: (patch: Record<string, unknown>) => void;
|
|
135
|
+
save: () => Promise<void>;
|
|
136
|
+
publish: () => Promise<void>;
|
|
137
|
+
}
|
|
138
|
+
/** Adds a button/action to the document editor toolbar. */
|
|
139
|
+
export interface DocumentActionPart {
|
|
140
|
+
implements: 'aphex/document/action';
|
|
141
|
+
/** Unique across all plugins. */
|
|
142
|
+
id: string;
|
|
143
|
+
title: string;
|
|
144
|
+
icon?: Component;
|
|
145
|
+
component: Component<{
|
|
146
|
+
action: DocumentActionProps;
|
|
147
|
+
}>;
|
|
148
|
+
/** Document type names this applies to. Omit for all types. */
|
|
149
|
+
appliesTo?: string[];
|
|
150
|
+
requiredCapabilities?: string[];
|
|
151
|
+
order?: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The stable context handed to an admin-tool component — enough to read the
|
|
155
|
+
* environment, gate on capabilities, and navigate, without touching AdminApp
|
|
156
|
+
* internals. For document data, tools use the REST client (session-authenticated).
|
|
157
|
+
*/
|
|
158
|
+
export interface AdminToolProps {
|
|
159
|
+
organizationId: string | null;
|
|
160
|
+
capabilities: readonly string[];
|
|
161
|
+
role: string | null;
|
|
162
|
+
/** True if the session has the capability (privileged roles bypass). */
|
|
163
|
+
can: (capability: string) => boolean;
|
|
164
|
+
/** All content schemas (read-only), for listing document types etc. */
|
|
165
|
+
schemas: SchemaType[];
|
|
166
|
+
/** Switch the active admin area/tab (e.g. back to `'structure'`). */
|
|
167
|
+
navigate: (area: AdminArea) => void;
|
|
168
|
+
/** Open a document in the editor. */
|
|
169
|
+
openDocument: (documentType: string, documentId: string) => void;
|
|
170
|
+
}
|
|
171
|
+
/** Adds a top-level admin section (its own tool). */
|
|
172
|
+
export interface AdminToolPart {
|
|
173
|
+
implements: 'aphex/admin/tool';
|
|
174
|
+
/** Unique across all plugins; also the tool's route key. */
|
|
175
|
+
id: string;
|
|
176
|
+
title: string;
|
|
177
|
+
icon?: Component;
|
|
178
|
+
component: Component<{
|
|
179
|
+
tool: AdminToolProps;
|
|
180
|
+
}>;
|
|
181
|
+
requiredCapabilities?: string[];
|
|
182
|
+
order?: number;
|
|
183
|
+
/**
|
|
184
|
+
* Where the tool's trigger renders. `'tab'` (default) puts it in the top tab
|
|
185
|
+
* strip alongside Content/Media/Vision; `'sidebar'` puts it in the left sidebar
|
|
186
|
+
* nav instead — better once several plugins are installed and the tab strip
|
|
187
|
+
* would overflow. Either way the tool opens the same `plugin:<id>` area.
|
|
188
|
+
*/
|
|
189
|
+
placement?: 'tab' | 'sidebar';
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The stable props a field-input widget receives — the same shape the built-in
|
|
193
|
+
* field renderers use, so a plugin widget is a drop-in replacement.
|
|
194
|
+
*/
|
|
195
|
+
export interface FieldComponentProps {
|
|
196
|
+
field: Field;
|
|
197
|
+
value: unknown;
|
|
198
|
+
onUpdate: (value: unknown) => void;
|
|
199
|
+
readonly?: boolean;
|
|
200
|
+
/** Validation-state CSS classes to spread onto the control (optional). */
|
|
201
|
+
validationClasses?: string;
|
|
202
|
+
/** The whole document's data — for widgets that read sibling fields (e.g. an SEO preview). */
|
|
203
|
+
documentData?: Record<string, unknown>;
|
|
204
|
+
/** The document's type name (e.g. `'author'`) — for widgets that vary by type. */
|
|
205
|
+
schemaType?: string;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Provides a custom input widget, selected by a field's `input` key in the schema
|
|
209
|
+
* (e.g. `{ type: 'string', input: 'color' }`).
|
|
210
|
+
*/
|
|
211
|
+
export interface FieldComponentPart {
|
|
212
|
+
implements: 'aphex/field/component';
|
|
213
|
+
/** Matched against a field's `input` property. */
|
|
214
|
+
input: string;
|
|
215
|
+
component: Component<FieldComponentProps>;
|
|
216
|
+
}
|
|
217
|
+
export type PluginPart = SchemaPart | SchemaTransformPart | ServerRoutePart | CapabilitiesPart | SettingsPart | DocumentActionPart | AdminToolPart | FieldComponentPart;
|
|
218
|
+
/** A plugin manifest. Returned by `definePlugin`. */
|
|
219
|
+
export interface CMSPlugin {
|
|
220
|
+
/** Package-style name, e.g. `@acme/aphex-plugin-seo`. Used in error messages. */
|
|
221
|
+
name: string;
|
|
222
|
+
version?: string;
|
|
223
|
+
parts?: PluginPart[];
|
|
224
|
+
}
|
|
225
|
+
/** Registration hook available to server-route parts (kept for the api-mount seam). */
|
|
226
|
+
export type RegisterRoutes = (app: Hono<AphexEnv>) => void;
|
|
227
|
+
/**
|
|
228
|
+
* Identity helper that pins the `CMSPlugin` type for authoring. Kept a pure
|
|
229
|
+
* pass-through so bundlers can tree-shake unused plugins; validation (duplicate
|
|
230
|
+
* ids/names) happens in the part resolver at boot, where it can see all plugins.
|
|
231
|
+
*/
|
|
232
|
+
export declare function definePlugin(plugin: CMSPlugin): CMSPlugin;
|
|
233
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/plugins/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity helper that pins the `CMSPlugin` type for authoring. Kept a pure
|
|
3
|
+
* pass-through so bundlers can tree-shake unused plugins; validation (duplicate
|
|
4
|
+
* ids/names) happens in the part resolver at boot, where it can see all plugins.
|
|
5
|
+
*/
|
|
6
|
+
export function definePlugin(plugin) {
|
|
7
|
+
return plugin;
|
|
8
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Field, SchemaType } from '../types/schemas.js';
|
|
2
|
+
export interface DesugarOptions {
|
|
3
|
+
/** The authored `type` keyword to replace, e.g. `'color'`. */
|
|
4
|
+
type: string;
|
|
5
|
+
/**
|
|
6
|
+
* Build the replacement from the authored field. Own the *shape* only — `type`,
|
|
7
|
+
* `fields`, and the default `input`/`inputOptions`. Anything you copy off the
|
|
8
|
+
* authored field here is redundant: it is layered back on afterwards.
|
|
9
|
+
*/
|
|
10
|
+
build: (authored: Field) => Field;
|
|
11
|
+
/**
|
|
12
|
+
* Keys that exist only on the sugar type and must not survive onto the expanded
|
|
13
|
+
* field (e.g. color's `alpha`, which becomes `inputOptions.alpha`). Everything
|
|
14
|
+
* else the author wrote is preserved.
|
|
15
|
+
*/
|
|
16
|
+
sugarKeys?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Desugar every `{ type: <options.type> }` field across a schema list, recursing into
|
|
20
|
+
* nested objects and array members, preserving everything the author declared.
|
|
21
|
+
*
|
|
22
|
+
* Intended as the body of an `aphex/schema/transform` part, so it runs identically in
|
|
23
|
+
* the engine, the admin, and the type generator — nothing downstream ever sees the
|
|
24
|
+
* sugar keyword.
|
|
25
|
+
*/
|
|
26
|
+
export declare function desugarFieldType(schemas: SchemaType[], options: DesugarOptions): SchemaType[];
|
|
27
|
+
//# sourceMappingURL=desugar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desugar.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/desugar.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC9B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,KAAK,KAAK,CAAC;IAClC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AA6ED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,EAAE,CAM7F"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// schema-utils/desugar.ts
|
|
2
|
+
//
|
|
3
|
+
// Shared machinery for `aphex/schema/transform` parts that desugar a custom field
|
|
4
|
+
// keyword into a real field — e.g. `{ type: 'color' }` → the color `object`, or
|
|
5
|
+
// `{ type: 'seo' }` → the SEO `object`.
|
|
6
|
+
//
|
|
7
|
+
// Every such transform has the same two jobs, and the second is easy to get wrong:
|
|
8
|
+
//
|
|
9
|
+
// 1. Walk the whole schema list — fields, nested object fields, and array members.
|
|
10
|
+
// 2. Replace the sugar field WITHOUT losing what the author wrote on it.
|
|
11
|
+
//
|
|
12
|
+
// Hand-rolled transforms tended to rebuild the field from a hand-picked subset
|
|
13
|
+
// (`name`/`title`/`description`/`group`), which silently dropped `access` — turning a
|
|
14
|
+
// restricted field unrestricted — along with `validation` and every group after the
|
|
15
|
+
// first. Preservation is the default here so a plugin author can't forget it: the
|
|
16
|
+
// builder supplies only the shape, and the authored field is layered back on top.
|
|
17
|
+
/**
|
|
18
|
+
* Layer the authored field back over the built one.
|
|
19
|
+
*
|
|
20
|
+
* The builder owns structure (`type`, `fields`); the author owns intent (`group`,
|
|
21
|
+
* `validation`, `access`, and any property added to BaseField later — hence a
|
|
22
|
+
* spread rather than an allowlist, which would silently go stale).
|
|
23
|
+
*/
|
|
24
|
+
function preserveAuthored(authored, built, sugarKeys) {
|
|
25
|
+
const rest = { ...authored };
|
|
26
|
+
delete rest.type;
|
|
27
|
+
for (const key of sugarKeys)
|
|
28
|
+
delete rest[key];
|
|
29
|
+
const builtRecord = built;
|
|
30
|
+
const merged = {
|
|
31
|
+
...builtRecord,
|
|
32
|
+
...rest,
|
|
33
|
+
// Re-assert what the desugaring defines: the author wrote `type: 'color'`,
|
|
34
|
+
// not the object it expands to.
|
|
35
|
+
type: builtRecord.type,
|
|
36
|
+
// An author who explicitly asked for a different widget still wins; otherwise
|
|
37
|
+
// the builder's widget is the whole point of the field type.
|
|
38
|
+
input: rest.input ?? builtRecord.input,
|
|
39
|
+
// Merged, not replaced: the builder derives options from the sugar keys
|
|
40
|
+
// (color's `alpha` → `inputOptions.alpha`), so letting an authored
|
|
41
|
+
// `inputOptions` win wholesale would silently drop them. Authored keys still
|
|
42
|
+
// win individually.
|
|
43
|
+
inputOptions: mergeInputOptions(builtRecord.inputOptions, rest.inputOptions)
|
|
44
|
+
};
|
|
45
|
+
if ('fields' in builtRecord)
|
|
46
|
+
merged.fields = builtRecord.fields;
|
|
47
|
+
return merged;
|
|
48
|
+
}
|
|
49
|
+
/** Combine the builder's derived widget options with any the author declared. */
|
|
50
|
+
function mergeInputOptions(built, authored) {
|
|
51
|
+
const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
52
|
+
if (!isRecord(built))
|
|
53
|
+
return isRecord(authored) ? authored : undefined;
|
|
54
|
+
if (!isRecord(authored))
|
|
55
|
+
return built;
|
|
56
|
+
return { ...built, ...authored };
|
|
57
|
+
}
|
|
58
|
+
function expandFields(fields, options) {
|
|
59
|
+
const sugarKeys = options.sugarKeys ?? [];
|
|
60
|
+
return fields.map((field) => {
|
|
61
|
+
if (field.type === options.type) {
|
|
62
|
+
return preserveAuthored(field, options.build(field), sugarKeys);
|
|
63
|
+
}
|
|
64
|
+
if (field.type === 'object' && Array.isArray(field.fields)) {
|
|
65
|
+
return { ...field, fields: expandFields(field.fields, options) };
|
|
66
|
+
}
|
|
67
|
+
if (field.type === 'array' && Array.isArray(field.of)) {
|
|
68
|
+
return { ...field, of: field.of.map((member) => expandMember(member, options)) };
|
|
69
|
+
}
|
|
70
|
+
return field;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Array `of` members are `TypeReference`s, not `Field`s — expand them the same way. */
|
|
74
|
+
function expandMember(member, options) {
|
|
75
|
+
if (member.type === options.type) {
|
|
76
|
+
// A member names a *type*, so `name` is often absent — but builders take a
|
|
77
|
+
// named field. Fall back to the sugar keyword so the expansion keeps its
|
|
78
|
+
// identity (`{ of: [{ type: 'color' }] }` stays a recognisable color member
|
|
79
|
+
// instead of becoming an anonymous object).
|
|
80
|
+
const authored = { ...member, name: member.name ?? options.type };
|
|
81
|
+
const built = options.build(authored);
|
|
82
|
+
return preserveAuthored(authored, built, options.sugarKeys ?? []);
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(member.fields)) {
|
|
85
|
+
return { ...member, fields: expandFields(member.fields, options) };
|
|
86
|
+
}
|
|
87
|
+
return member;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Desugar every `{ type: <options.type> }` field across a schema list, recursing into
|
|
91
|
+
* nested objects and array members, preserving everything the author declared.
|
|
92
|
+
*
|
|
93
|
+
* Intended as the body of an `aphex/schema/transform` part, so it runs identically in
|
|
94
|
+
* the engine, the admin, and the type generator — nothing downstream ever sees the
|
|
95
|
+
* sugar keyword.
|
|
96
|
+
*/
|
|
97
|
+
export function desugarFieldType(schemas, options) {
|
|
98
|
+
return schemas.map((schema) => 'fields' in schema && Array.isArray(schema.fields)
|
|
99
|
+
? { ...schema, fields: expandFields(schema.fields, options) }
|
|
100
|
+
: schema);
|
|
101
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SettingsField } from '../types/schemas.js';
|
|
2
|
+
/** A normalized select option: what the user sees, and what gets stored. */
|
|
3
|
+
export interface SettingsListItem {
|
|
4
|
+
title: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The select options for a settings field, normalized from `StringField.list`'s
|
|
9
|
+
* loose shape (bare strings, or `{title, value}` objects) — empty when the field
|
|
10
|
+
* isn't a select.
|
|
11
|
+
*
|
|
12
|
+
* A `DependentList` yields no options: its valid values are a function of another
|
|
13
|
+
* field's value, which settings doesn't resolve. The panel renders such a field as a
|
|
14
|
+
* free-text input, so the validator must not treat it as a closed set either.
|
|
15
|
+
*/
|
|
16
|
+
export declare function settingsListItems(field: SettingsField): SettingsListItem[];
|
|
17
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/settings.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,EAAE,CAK1E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Helpers for plugin settings declarations (`aphex/settings`).
|
|
2
|
+
//
|
|
3
|
+
// Shared by the settings panel (which renders the options) and PluginSettingsService
|
|
4
|
+
// (which validates a submitted value against them). They must agree: if they drift,
|
|
5
|
+
// the panel offers a choice the server rejects. So the normalization lives here once.
|
|
6
|
+
/**
|
|
7
|
+
* The select options for a settings field, normalized from `StringField.list`'s
|
|
8
|
+
* loose shape (bare strings, or `{title, value}` objects) — empty when the field
|
|
9
|
+
* isn't a select.
|
|
10
|
+
*
|
|
11
|
+
* A `DependentList` yields no options: its valid values are a function of another
|
|
12
|
+
* field's value, which settings doesn't resolve. The panel renders such a field as a
|
|
13
|
+
* free-text input, so the validator must not treat it as a closed set either.
|
|
14
|
+
*/
|
|
15
|
+
export function settingsListItems(field) {
|
|
16
|
+
if (field.type !== 'string')
|
|
17
|
+
return [];
|
|
18
|
+
const list = field.list;
|
|
19
|
+
if (!Array.isArray(list))
|
|
20
|
+
return [];
|
|
21
|
+
return list.map((item) => (typeof item === 'string' ? { title: item, value: item } : item));
|
|
22
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAmB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAyB,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAYzC,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAAkD,CAAC;AAEzF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAmOpE"}
|
|
@@ -44,6 +44,17 @@ export const VALID_FIELD_TYPES = [...PRIMITIVE_FIELD_TYPES, 'array', 'object'];
|
|
|
44
44
|
export function validateSchemaReferences(schemas) {
|
|
45
45
|
const schemaNames = new Set(schemas.map((schema) => schema.name));
|
|
46
46
|
const errors = [];
|
|
47
|
+
// Duplicate schema names are a hard error — no silent overrides. This matters
|
|
48
|
+
// most once plugins merge their schemas into the app's: a collision would
|
|
49
|
+
// otherwise let one type shadow another. Report every duplicate name once.
|
|
50
|
+
const nameCounts = new Map();
|
|
51
|
+
for (const schema of schemas)
|
|
52
|
+
nameCounts.set(schema.name, (nameCounts.get(schema.name) ?? 0) + 1);
|
|
53
|
+
for (const [name, count] of nameCounts) {
|
|
54
|
+
if (count > 1) {
|
|
55
|
+
errors.push(`Duplicate schema name "${name}" (defined ${count} times). Schema names must be unique across app and plugin schemas.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
47
58
|
// Field-type lists live at module scope (shared source of truth).
|
|
48
59
|
const primitiveTypes = PRIMITIVE_FIELD_TYPES;
|
|
49
60
|
const validFieldTypes = VALID_FIELD_TYPES;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypt a plaintext string into a self-describing envelope
|
|
3
|
+
* `v1:<iv>:<authTag>:<ciphertext>` (base64 segments). Safe to store as an ordinary
|
|
4
|
+
* string in the settings blob.
|
|
5
|
+
*/
|
|
6
|
+
export declare function encryptSecret(plaintext: string, secret: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Decrypt an envelope produced by {@link encryptSecret}. Throws if the envelope is
|
|
9
|
+
* malformed, the version is unknown, or authentication fails (wrong key / tampering).
|
|
10
|
+
*/
|
|
11
|
+
export declare function decryptSecret(envelope: string, secret: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Whether a stored value looks like one of our encryption envelopes. Lets the service
|
|
14
|
+
* tell "already-encrypted ciphertext" from "a value that still needs encrypting"
|
|
15
|
+
* without trying to decrypt.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isEncryptedSecret(value: unknown): value is string;
|
|
18
|
+
//# sourceMappingURL=secret-crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-crypto.d.ts","sourceRoot":"","sources":["../../src/lib/security/secret-crypto.ts"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CActE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEjE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// security/secret-crypto.ts
|
|
2
|
+
//
|
|
3
|
+
// Authenticated symmetric encryption for plugin secrets (the one genuinely-new
|
|
4
|
+
// brick of the settings/secrets feature — see references/plugin-settings-and-secrets-scope.md).
|
|
5
|
+
//
|
|
6
|
+
// SERVER ONLY: imports `node:crypto`. Never import this from client/admin code — a
|
|
7
|
+
// decrypted secret must never reach the browser. It's kept out of the cms-core client
|
|
8
|
+
// barrel deliberately.
|
|
9
|
+
//
|
|
10
|
+
// Design (mirrors the good ideas from Better Auth's `symmetricEncrypt`, without the
|
|
11
|
+
// dependency — cms-core stays auth-provider-agnostic):
|
|
12
|
+
// - AES-256-GCM: authenticated (AEAD), so tampering is detected on decrypt.
|
|
13
|
+
// - Random 96-bit IV per encryption (never reused).
|
|
14
|
+
// - Versioned envelope `v1:<iv>:<tag>:<ciphertext>` (all base64). The version prefix
|
|
15
|
+
// is what makes key rotation possible later: add `v2`, decrypt either, re-encrypt
|
|
16
|
+
// on next write — no data migration.
|
|
17
|
+
// - Key derived via SHA-256 so any-length configured secret becomes a valid 32-byte key.
|
|
18
|
+
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto';
|
|
19
|
+
const VERSION = 'v1';
|
|
20
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
21
|
+
const IV_BYTES = 12; // 96-bit nonce, the GCM standard.
|
|
22
|
+
/** Derive a 32-byte AES key from an arbitrary-length configured secret. */
|
|
23
|
+
function deriveKey(secret) {
|
|
24
|
+
return createHash('sha256').update(secret, 'utf8').digest();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Encrypt a plaintext string into a self-describing envelope
|
|
28
|
+
* `v1:<iv>:<authTag>:<ciphertext>` (base64 segments). Safe to store as an ordinary
|
|
29
|
+
* string in the settings blob.
|
|
30
|
+
*/
|
|
31
|
+
export function encryptSecret(plaintext, secret) {
|
|
32
|
+
const key = deriveKey(secret);
|
|
33
|
+
const iv = randomBytes(IV_BYTES);
|
|
34
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
35
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
36
|
+
const authTag = cipher.getAuthTag();
|
|
37
|
+
return [
|
|
38
|
+
VERSION,
|
|
39
|
+
iv.toString('base64'),
|
|
40
|
+
authTag.toString('base64'),
|
|
41
|
+
ciphertext.toString('base64')
|
|
42
|
+
].join(':');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Decrypt an envelope produced by {@link encryptSecret}. Throws if the envelope is
|
|
46
|
+
* malformed, the version is unknown, or authentication fails (wrong key / tampering).
|
|
47
|
+
*/
|
|
48
|
+
export function decryptSecret(envelope, secret) {
|
|
49
|
+
const parts = envelope.split(':');
|
|
50
|
+
const [version, ivB64, tagB64, ctB64] = parts;
|
|
51
|
+
if (parts.length !== 4 || version !== VERSION || !ivB64 || !tagB64 || !ctB64) {
|
|
52
|
+
throw new Error('Malformed or unsupported secret envelope');
|
|
53
|
+
}
|
|
54
|
+
const key = deriveKey(secret);
|
|
55
|
+
const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(ivB64, 'base64'));
|
|
56
|
+
decipher.setAuthTag(Buffer.from(tagB64, 'base64'));
|
|
57
|
+
const plaintext = Buffer.concat([
|
|
58
|
+
decipher.update(Buffer.from(ctB64, 'base64')),
|
|
59
|
+
decipher.final()
|
|
60
|
+
]);
|
|
61
|
+
return plaintext.toString('utf8');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether a stored value looks like one of our encryption envelopes. Lets the service
|
|
65
|
+
* tell "already-encrypted ciphertext" from "a value that still needs encrypting"
|
|
66
|
+
* without trying to decrypt.
|
|
67
|
+
*/
|
|
68
|
+
export function isEncryptedSecret(value) {
|
|
69
|
+
return typeof value === 'string' && value.startsWith(`${VERSION}:`);
|
|
70
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/server/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAqB7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,SAAS,EAAE;QACV,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACT,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;KAClB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,kGAqB7B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAqDrD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,IACtE,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,uBAejD"}
|
package/dist/server/api/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { organizationsInvitationsRouter } from './routes/organizations-invitatio
|
|
|
16
16
|
import { organizationsMembersRouter } from './routes/organizations-members.js';
|
|
17
17
|
import { organizationsSwitchRouter } from './routes/organizations-switch.js';
|
|
18
18
|
import { rolesRouter } from './routes/roles.js';
|
|
19
|
+
import { pluginSettingsRouter } from './routes/plugin-settings.js';
|
|
19
20
|
import { userPreferencesRouter } from './routes/user-preferences.js';
|
|
20
21
|
import { userRouter } from './routes/user.js';
|
|
21
22
|
/**
|
|
@@ -77,6 +78,8 @@ export function mountAphexBuiltins(app) {
|
|
|
77
78
|
app.route('/organizations', organizationsRouter);
|
|
78
79
|
// Roles — combined router covers /, /:name, no precedence concern.
|
|
79
80
|
app.route('/roles', rolesRouter);
|
|
81
|
+
// Plugin settings — the config plane. `/`, `/:pluginId`, no precedence concern.
|
|
82
|
+
app.route('/plugin-settings', pluginSettingsRouter);
|
|
80
83
|
// User account routes — register specifics first.
|
|
81
84
|
// `/user/cms-preference`, `/user/request-password-reset`,
|
|
82
85
|
// `/user/reset-password` need to win over `/user` PATCH otherwise
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,QAAQ,CAoKrC,CAAC"}
|
|
@@ -25,6 +25,7 @@ export const assetsRouter = new Hono()
|
|
|
25
25
|
assetType: q.assetType,
|
|
26
26
|
mimeType: q.mimeType,
|
|
27
27
|
search: q.search,
|
|
28
|
+
includeSystem: q.includeSystem ?? false,
|
|
28
29
|
limit: q.limit ?? 20,
|
|
29
30
|
offset: q.offset ?? 0
|
|
30
31
|
};
|
|
@@ -34,7 +35,8 @@ export const assetsRouter = new Hono()
|
|
|
34
35
|
databaseAdapter.countAssets(auth.organizationId, {
|
|
35
36
|
assetType: filters.assetType,
|
|
36
37
|
mimeType: filters.mimeType,
|
|
37
|
-
search: filters.search
|
|
38
|
+
search: filters.search,
|
|
39
|
+
includeSystem: filters.includeSystem
|
|
38
40
|
})
|
|
39
41
|
]);
|
|
40
42
|
const pageSize = filters.limit || 20;
|
|
@@ -101,6 +103,8 @@ export const assetsRouter = new Hono()
|
|
|
101
103
|
const creditLine = formData.get('creditLine') || undefined;
|
|
102
104
|
const schemaType = formData.get('schemaType') || undefined;
|
|
103
105
|
const fieldPath = formData.get('fieldPath') || undefined;
|
|
106
|
+
const system = formData.get('system') === 'true' || undefined;
|
|
107
|
+
const usage = formData.get('usage') || undefined;
|
|
104
108
|
const targetOrganizationId = auth.organizationId;
|
|
105
109
|
const uploadData = {
|
|
106
110
|
organizationId: targetOrganizationId,
|
|
@@ -115,7 +119,9 @@ export const assetsRouter = new Hono()
|
|
|
115
119
|
createdBy: auth.type === 'session' ? auth.user.id : undefined,
|
|
116
120
|
metadata: {
|
|
117
121
|
schemaType,
|
|
118
|
-
fieldPath
|
|
122
|
+
fieldPath,
|
|
123
|
+
system,
|
|
124
|
+
usage
|
|
119
125
|
}
|
|
120
126
|
};
|
|
121
127
|
const asset = await assetService.uploadAsset(targetOrganizationId, uploadData);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/api/routes/organizations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CAoI7C,CAAC"}
|