@plitzi/sdk-server 0.32.24 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +326 -162
- package/dist/adapters/authAdapters.d.ts +21 -0
- package/dist/adapters/authAdapters.js +12 -0
- package/dist/adapters/jsonAdapters.d.ts +15 -0
- package/dist/adapters/jsonAdapters.js +9 -4
- package/dist/core/auth/api.d.ts +148 -0
- package/dist/core/auth/api.js +286 -0
- package/dist/core/auth/authorize.d.ts +96 -0
- package/dist/core/auth/authorize.js +92 -0
- package/dist/core/auth/createAuth.d.ts +165 -0
- package/dist/core/auth/createAuth.js +105 -0
- package/dist/core/auth/credentials.d.ts +29 -0
- package/dist/core/auth/credentials.js +48 -0
- package/dist/core/auth/domains.d.ts +41 -0
- package/dist/core/auth/domains.js +78 -0
- package/dist/core/auth/identity.d.ts +108 -0
- package/dist/core/auth/identity.js +164 -0
- package/dist/core/auth/oauth/client.d.ts +5 -0
- package/dist/core/auth/oauth/client.js +47 -0
- package/dist/core/auth/oauth/index.d.ts +78 -0
- package/dist/core/auth/oauth/index.js +113 -0
- package/dist/core/auth/oauth/providers/github.d.ts +2 -0
- package/dist/core/auth/oauth/providers/github.js +48 -0
- package/dist/core/auth/oauth/providers/google.d.ts +2 -0
- package/dist/core/auth/oauth/providers/google.js +30 -0
- package/dist/core/auth/oauth/state.d.ts +23 -0
- package/dist/core/auth/oauth/state.js +55 -0
- package/dist/core/auth/oauth/types.d.ts +51 -0
- package/dist/core/auth/oauth/types.js +13 -0
- package/dist/core/auth/routes.d.ts +50 -0
- package/dist/core/auth/routes.js +129 -0
- package/dist/core/auth/session.d.ts +128 -0
- package/dist/core/auth/session.js +165 -0
- package/dist/core/auth/spaceTokens.d.ts +137 -0
- package/dist/core/auth/spaceTokens.js +212 -0
- package/dist/core/auth/tokens.d.ts +151 -0
- package/dist/core/auth/tokens.js +221 -0
- package/dist/core/createServer.d.ts +29 -0
- package/dist/core/createServer.js +28 -14
- package/dist/core/handlers/authMiddleware.d.ts +27 -0
- package/dist/core/handlers/authMiddleware.js +38 -0
- package/dist/core/handlers/authRouteHandlers.d.ts +46 -0
- package/dist/core/handlers/authRouteHandlers.js +75 -0
- package/dist/core/handlers/types.d.ts +37 -0
- package/dist/{src/core → core}/http/dispatcher.d.ts +2 -2
- package/dist/core/http/dispatcher.js +8 -6
- package/dist/core/http/navigation.d.ts +11 -0
- package/dist/core/http/navigation.js +16 -0
- package/dist/core/http/securityHeaders.js +6 -4
- package/dist/core/http/stages/authApi.d.ts +17 -0
- package/dist/core/http/stages/authApi.js +66 -0
- package/dist/core/http/stages/authRoutes.js +40 -11
- package/dist/core/http/stages/exchangeRoute.d.ts +15 -0
- package/dist/core/http/stages/exchangeRoute.js +67 -0
- package/dist/core/http/stages/health.d.ts +11 -0
- package/dist/core/http/stages/health.js +25 -3
- package/dist/core/http/stages/middlewares.d.ts +2 -0
- package/dist/core/http/stages/static.d.ts +13 -0
- package/dist/core/http/stages/static.js +21 -6
- package/dist/core/http/types.d.ts +35 -0
- package/dist/{modules/mcp/constants.js → core/previewToken.js} +1 -1
- package/dist/core/sdkAssets.d.ts +16 -0
- package/dist/core/sdkAssets.js +46 -0
- package/dist/core/server/baseServer.js +40 -5
- package/dist/core/server/pageServer.d.ts +7 -0
- package/dist/core/server/pageServer.js +13 -17
- package/dist/core/services/action.d.ts +9 -0
- package/dist/core/services/action.js +21 -0
- package/dist/core/services/registry.d.ts +3 -0
- package/dist/core/services/registry.js +9 -19
- package/dist/{src/core → core}/services/resolve.d.ts +1 -0
- package/dist/core/services/resolve.js +6 -4
- package/dist/core/services/rsc.js +3 -2
- package/dist/core/staticFiles.js +1 -1
- package/dist/{src/core → core}/transports.d.ts +3 -0
- package/dist/core/transports.js +7 -6
- package/dist/handlers.d.ts +58 -0
- package/dist/handlers.js +3 -0
- package/dist/{src/helpers → helpers}/buildResponseHelpers.d.ts +2 -1
- package/dist/helpers/buildResponseHelpers.js +13 -4
- package/dist/helpers/buildServerInfo.d.ts +3 -0
- package/dist/helpers/buildServerInfo.js +25 -3
- package/dist/{src/helpers → helpers}/cache/keys.d.ts +5 -1
- package/dist/helpers/cache/keys.js +1 -1
- package/dist/helpers/compress.d.ts +18 -0
- package/dist/helpers/compress.js +47 -11
- package/dist/helpers/offlineDataLoader.d.ts +11 -0
- package/dist/helpers/offlineDataLoader.js +15 -0
- package/dist/helpers/resolveDebugMode.d.ts +10 -0
- package/dist/helpers/resolveDebugMode.js +13 -0
- package/dist/index.d.ts +16 -2
- package/dist/index.js +9 -20
- package/dist/kernel.d.ts +41 -0
- package/dist/kernel.js +22 -0
- package/dist/middlewares/spaceDeployment.d.ts +2 -0
- package/dist/middlewares/spaceDeployment.js +2 -1
- package/dist/modules/actions/handler.d.ts +11 -0
- package/dist/modules/actions/handler.js +77 -0
- package/dist/modules/connectors/engine.d.ts +42 -0
- package/dist/modules/connectors/engine.js +221 -0
- package/dist/modules/connectors/getByPath.d.ts +8 -0
- package/dist/modules/connectors/getByPath.js +21 -0
- package/dist/modules/connectors/index.d.ts +7 -0
- package/dist/modules/connectors/projection.d.ts +18 -0
- package/dist/modules/connectors/projection.js +108 -0
- package/dist/modules/connectors/resolver.d.ts +18 -0
- package/dist/modules/connectors/resolver.js +68 -0
- package/dist/modules/connectors/types.d.ts +19 -0
- package/dist/{src/modules → modules}/rsc/handler.d.ts +2 -2
- package/dist/modules/rsc/handler.js +54 -2
- package/dist/modules/rsc/resolveRscData.d.ts +35 -0
- package/dist/modules/rsc/resolveRscData.js +74 -0
- package/dist/{src/modules → modules}/ssr/Component.d.ts +4 -1
- package/dist/modules/ssr/Component.js +10 -3
- package/dist/modules/ssr/buildBody.d.ts +9 -0
- package/dist/modules/ssr/handler.d.ts +4 -0
- package/dist/modules/ssr/handler.js +18 -1
- package/dist/{src/modules → modules}/ssr/loadPluginComponents.d.ts +5 -2
- package/dist/modules/ssr/loadPluginComponents.js +20 -2
- package/dist/{src/modules → modules}/ssr/prepareRender.d.ts +2 -2
- package/dist/modules/ssr/prepareRender.js +24 -7
- package/dist/modules/ssr/preview.d.ts +10 -0
- package/dist/modules/ssr/preview.js +5 -78
- package/dist/modules/ssr/registerExternalPlugins.js +1 -1
- package/dist/modules/ssr/streamBody.d.ts +5 -0
- package/dist/modules/ssr/streamBody.js +1 -1
- package/dist/modules/ssr/template.d.ts +2 -0
- package/dist/modules/ssr/template.js +1 -1
- package/dist/plugins/compile.js +1 -1
- package/dist/plugins/manager.js +12 -8
- package/dist/ssr.d.ts +15 -0
- package/dist/ssr.js +4 -0
- package/package.json +29 -25
- package/dist/.gitkeep +0 -0
- package/dist/core/server/mcpServer.js +0 -29
- package/dist/core/services/mcp.js +0 -27
- package/dist/core/services/oauth.js +0 -116
- package/dist/core/services/preview.js +0 -37
- package/dist/core/services/proxy.js +0 -12
- package/dist/mcp.d.ts +0 -2
- package/dist/mcp.js +0 -7
- package/dist/modules/ai/AIEngine.js +0 -120
- package/dist/modules/ai/toolkit.js +0 -59
- package/dist/modules/mcp/apps/example/view/index.tsx +0 -70
- package/dist/modules/mcp/apps/index.js +0 -16
- package/dist/modules/mcp/apps/render/index.js +0 -17
- package/dist/modules/mcp/apps/render/styles.js +0 -54
- package/dist/modules/mcp/apps/render/view/heldBatch.ts +0 -107
- package/dist/modules/mcp/apps/render/view/index.tsx +0 -314
- package/dist/modules/mcp/apps/render/view/streamProgress.ts +0 -137
- package/dist/modules/mcp/apps/shared/assets.js +0 -10
- package/dist/modules/mcp/apps/shared/bundle.js +0 -23
- package/dist/modules/mcp/apps/shared/page.js +0 -34
- package/dist/modules/mcp/apps/shared/registerApp.js +0 -43
- package/dist/modules/mcp/apps/shared/resolve.js +0 -5
- package/dist/modules/mcp/apps/shared/shell.ejs +0 -59
- package/dist/modules/mcp/apps/shared/zodEnglishOnly.js +0 -23
- package/dist/modules/mcp/catalogs/builtinCallbacks.js +0 -204
- package/dist/modules/mcp/catalogs/builtinComponents.js +0 -170
- package/dist/modules/mcp/catalogs/builtinElementCallbacks.js +0 -50
- package/dist/modules/mcp/catalogs/builtinTransformers.js +0 -148
- package/dist/modules/mcp/catalogs/builtinUtilities.js +0 -90
- package/dist/modules/mcp/catalogs/cssCatalog/border.js +0 -30
- package/dist/modules/mcp/catalogs/cssCatalog/box.js +0 -31
- package/dist/modules/mcp/catalogs/cssCatalog/helpers.js +0 -185
- package/dist/modules/mcp/catalogs/cssCatalog/index.js +0 -131
- package/dist/modules/mcp/catalogs/cssCatalog/layout.js +0 -98
- package/dist/modules/mcp/catalogs/cssCatalog/visual.js +0 -144
- package/dist/modules/mcp/catalogs/observed.js +0 -90
- package/dist/modules/mcp/catalogs/paramSpec.js +0 -69
- package/dist/modules/mcp/catalogs/registry.js +0 -89
- package/dist/modules/mcp/handler.js +0 -83
- package/dist/modules/mcp/helpers/agentPrompt.js +0 -104
- package/dist/modules/mcp/helpers/computeVersion.js +0 -16
- package/dist/modules/mcp/helpers/guide.js +0 -467
- package/dist/modules/mcp/helpers/interactions.js +0 -123
- package/dist/modules/mcp/helpers/log.js +0 -64
- package/dist/modules/mcp/helpers/opResult.js +0 -18
- package/dist/modules/mcp/helpers/space.js +0 -300
- package/dist/modules/mcp/helpers/uris.js +0 -44
- package/dist/modules/mcp/previewClient.js +0 -31
- package/dist/modules/mcp/proxy/config.js +0 -46
- package/dist/modules/mcp/proxy/fetch.js +0 -91
- package/dist/modules/mcp/proxy/grant.js +0 -65
- package/dist/modules/mcp/proxy/guard.js +0 -38
- package/dist/modules/mcp/proxy/handler.js +0 -68
- package/dist/modules/mcp/proxy/rewrite.js +0 -72
- package/dist/modules/mcp/proxy/sign.js +0 -15
- package/dist/modules/mcp/proxy/types.js +0 -9
- package/dist/modules/mcp/resources/canonical.js +0 -30
- package/dist/modules/mcp/resources/core.js +0 -18
- package/dist/modules/mcp/resources/envelope.js +0 -14
- package/dist/modules/mcp/resources/primer.js +0 -31
- package/dist/modules/mcp/resources/register.js +0 -190
- package/dist/modules/mcp/resources/renderGuide.js +0 -451
- package/dist/modules/mcp/resources/router.js +0 -37
- package/dist/modules/mcp/resources/schema.js +0 -43
- package/dist/modules/mcp/resources/style.js +0 -34
- package/dist/modules/mcp/screenshotClient.js +0 -47
- package/dist/modules/mcp/server.js +0 -113
- package/dist/modules/mcp/tools/apply/dispatch.js +0 -105
- package/dist/modules/mcp/tools/apply/index.js +0 -150
- package/dist/modules/mcp/tools/apply/writeResult.js +0 -37
- package/dist/modules/mcp/tools/index.js +0 -24
- package/dist/modules/mcp/tools/operations/index.js +0 -45
- package/dist/modules/mcp/tools/operations/schema/bindings/deleteBinding.js +0 -32
- package/dist/modules/mcp/tools/operations/schema/bindings/patchBinding.js +0 -36
- package/dist/modules/mcp/tools/operations/schema/bindings/upsertBinding.js +0 -47
- package/dist/modules/mcp/tools/operations/schema/elements/deleteElement.js +0 -29
- package/dist/modules/mcp/tools/operations/schema/elements/moveElement.js +0 -41
- package/dist/modules/mcp/tools/operations/schema/elements/patchElement.js +0 -58
- package/dist/modules/mcp/tools/operations/schema/elements/repeatElement.js +0 -148
- package/dist/modules/mcp/tools/operations/schema/elements/upsertElement.js +0 -65
- package/dist/modules/mcp/tools/operations/schema/folders/deleteFolder.js +0 -30
- package/dist/modules/mcp/tools/operations/schema/folders/upsertFolder.js +0 -49
- package/dist/modules/mcp/tools/operations/schema/interactions/deleteInteraction.js +0 -52
- package/dist/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.js +0 -47
- package/dist/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.js +0 -44
- package/dist/modules/mcp/tools/operations/schema/operations.js +0 -41
- package/dist/modules/mcp/tools/operations/schema/pages/deletePage.js +0 -25
- package/dist/modules/mcp/tools/operations/schema/pages/upsertPage.js +0 -75
- package/dist/modules/mcp/tools/operations/schema/settings/patchSettings.js +0 -45
- package/dist/modules/mcp/tools/operations/schema/shared.js +0 -122
- package/dist/modules/mcp/tools/operations/schema/translator.js +0 -215
- package/dist/modules/mcp/tools/operations/schema/variables/deleteVariable.js +0 -18
- package/dist/modules/mcp/tools/operations/schema/variables/upsertVariable.js +0 -42
- package/dist/modules/mcp/tools/operations/schema/write.js +0 -109
- package/dist/modules/mcp/tools/operations/schemaIds.js +0 -54
- package/dist/modules/mcp/tools/operations/style/definitions/deleteDefinition.js +0 -21
- package/dist/modules/mcp/tools/operations/style/definitions/patchDefinition.js +0 -28
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinition.js +0 -24
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinitions.js +0 -40
- package/dist/modules/mcp/tools/operations/style/globalStyles/deleteGlobalStyle.js +0 -21
- package/dist/modules/mcp/tools/operations/style/globalStyles/patchGlobalStyle.js +0 -28
- package/dist/modules/mcp/tools/operations/style/globalStyles/upsertGlobalStyle.js +0 -24
- package/dist/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.js +0 -21
- package/dist/modules/mcp/tools/operations/style/idStyles/patchIdStyle.js +0 -28
- package/dist/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.js +0 -24
- package/dist/modules/mcp/tools/operations/style/operations.js +0 -29
- package/dist/modules/mcp/tools/operations/style/shared.js +0 -59
- package/dist/modules/mcp/tools/operations/style/translator.js +0 -101
- package/dist/modules/mcp/tools/operations/style/variables/deleteStyleVariable.js +0 -21
- package/dist/modules/mcp/tools/operations/style/variables/upsertStyleVariable.js +0 -22
- package/dist/modules/mcp/tools/operations/style/write.js +0 -108
- package/dist/modules/mcp/tools/preview.js +0 -37
- package/dist/modules/mcp/tools/read.js +0 -51
- package/dist/modules/mcp/tools/render.js +0 -184
- package/dist/modules/mcp/tools/screenshot.js +0 -83
- package/dist/modules/mcp/tools/search.js +0 -115
- package/dist/modules/mcp/tools/shared/expandOperations.js +0 -44
- package/dist/modules/mcp/tools/shared/tool.js +0 -33
- package/dist/modules/mcp/tools/shared/validator/audit.js +0 -124
- package/dist/modules/mcp/tools/shared/validator/batch.js +0 -39
- package/dist/modules/mcp/tools/shared/validator/bindings.js +0 -70
- package/dist/modules/mcp/tools/shared/validator/context.js +0 -35
- package/dist/modules/mcp/tools/shared/validator/css.js +0 -39
- package/dist/modules/mcp/tools/shared/validator/elements.js +0 -68
- package/dist/modules/mcp/tools/shared/validator/index.js +0 -246
- package/dist/modules/mcp/tools/shared/validator/interactions.js +0 -103
- package/dist/modules/mcp/tools/shared/validator/refs.js +0 -28
- package/dist/modules/mcp/tools/validate.js +0 -47
- package/dist/modules/oauth/authorize.js +0 -177
- package/dist/modules/oauth/challenge.js +0 -33
- package/dist/modules/oauth/consentPage.js +0 -118
- package/dist/modules/oauth/metadata.js +0 -69
- package/dist/modules/oauth/params.js +0 -5
- package/dist/modules/oauth/pkce.js +0 -15
- package/dist/modules/oauth/records.js +0 -46
- package/dist/modules/oauth/register.js +0 -55
- package/dist/modules/oauth/respond.js +0 -44
- package/dist/modules/oauth/token.js +0 -100
- package/dist/public/.gitkeep +0 -0
- package/dist/src/adapters/jsonAdapters.d.ts +0 -7
- package/dist/src/core/createServer.d.ts +0 -14
- package/dist/src/core/http/stages/health.d.ts +0 -2
- package/dist/src/core/http/stages/middlewares.d.ts +0 -2
- package/dist/src/core/http/stages/static.d.ts +0 -5
- package/dist/src/core/http/types.d.ts +0 -22
- package/dist/src/core/server/mcpServer.d.ts +0 -2
- package/dist/src/core/server/pageServer.d.ts +0 -10
- package/dist/src/core/services/mcp.d.ts +0 -3
- package/dist/src/core/services/oauth.d.ts +0 -18
- package/dist/src/core/services/preview.d.ts +0 -2
- package/dist/src/core/services/proxy.d.ts +0 -2
- package/dist/src/core/services/registry.d.ts +0 -4
- package/dist/src/helpers/buildServerInfo.d.ts +0 -2
- package/dist/src/helpers/compress.d.ts +0 -3
- package/dist/src/index.d.ts +0 -15
- package/dist/src/mcp.d.ts +0 -14
- package/dist/src/middlewares/spaceDeployment.d.ts +0 -2
- package/dist/src/modules/ai/AIEngine.d.ts +0 -20
- package/dist/src/modules/ai/index.d.ts +0 -4
- package/dist/src/modules/ai/toolkit.d.ts +0 -17
- package/dist/src/modules/mcp/apps/example/index.d.ts +0 -8
- package/dist/src/modules/mcp/apps/index.d.ts +0 -11
- package/dist/src/modules/mcp/apps/render/index.d.ts +0 -4
- package/dist/src/modules/mcp/apps/render/styles.d.ts +0 -10
- package/dist/src/modules/mcp/apps/shared/assets.d.ts +0 -10
- package/dist/src/modules/mcp/apps/shared/bundle.d.ts +0 -4
- package/dist/src/modules/mcp/apps/shared/index.d.ts +0 -3
- package/dist/src/modules/mcp/apps/shared/page.d.ts +0 -2
- package/dist/src/modules/mcp/apps/shared/registerApp.d.ts +0 -5
- package/dist/src/modules/mcp/apps/shared/resolve.d.ts +0 -1
- package/dist/src/modules/mcp/apps/shared/zodEnglishOnly.d.ts +0 -4
- package/dist/src/modules/mcp/catalogs/builtinCallbacks.d.ts +0 -23
- package/dist/src/modules/mcp/catalogs/builtinComponents.d.ts +0 -4
- package/dist/src/modules/mcp/catalogs/builtinElementCallbacks.d.ts +0 -20
- package/dist/src/modules/mcp/catalogs/builtinTransformers.d.ts +0 -28
- package/dist/src/modules/mcp/catalogs/builtinUtilities.d.ts +0 -18
- package/dist/src/modules/mcp/catalogs/cssCatalog/border.d.ts +0 -4
- package/dist/src/modules/mcp/catalogs/cssCatalog/box.d.ts +0 -4
- package/dist/src/modules/mcp/catalogs/cssCatalog/helpers.d.ts +0 -34
- package/dist/src/modules/mcp/catalogs/cssCatalog/index.d.ts +0 -19
- package/dist/src/modules/mcp/catalogs/cssCatalog/layout.d.ts +0 -9
- package/dist/src/modules/mcp/catalogs/cssCatalog/visual.d.ts +0 -8
- package/dist/src/modules/mcp/catalogs/index.d.ts +0 -9
- package/dist/src/modules/mcp/catalogs/observed.d.ts +0 -48
- package/dist/src/modules/mcp/catalogs/paramSpec.d.ts +0 -42
- package/dist/src/modules/mcp/catalogs/registry.d.ts +0 -35
- package/dist/src/modules/mcp/e2e/index.d.ts +0 -6
- package/dist/src/modules/mcp/e2e/mcpEndpoint.d.ts +0 -27
- package/dist/src/modules/mcp/e2e/postMessageChannel.d.ts +0 -22
- package/dist/src/modules/mcp/e2e/renderingHost.d.ts +0 -34
- package/dist/src/modules/mcp/handler.d.ts +0 -22
- package/dist/src/modules/mcp/helpers/agentPrompt.d.ts +0 -4
- package/dist/src/modules/mcp/helpers/computeVersion.d.ts +0 -1
- package/dist/src/modules/mcp/helpers/guide.d.ts +0 -4
- package/dist/src/modules/mcp/helpers/index.d.ts +0 -8
- package/dist/src/modules/mcp/helpers/interactions.d.ts +0 -30
- package/dist/src/modules/mcp/helpers/log.d.ts +0 -8
- package/dist/src/modules/mcp/helpers/opResult.d.ts +0 -13
- package/dist/src/modules/mcp/helpers/space.d.ts +0 -115
- package/dist/src/modules/mcp/helpers/uris.d.ts +0 -28
- package/dist/src/modules/mcp/index.d.ts +0 -13
- package/dist/src/modules/mcp/previewClient.d.ts +0 -13
- package/dist/src/modules/mcp/proxy/config.d.ts +0 -17
- package/dist/src/modules/mcp/proxy/fetch.d.ts +0 -18
- package/dist/src/modules/mcp/proxy/grant.d.ts +0 -23
- package/dist/src/modules/mcp/proxy/guard.d.ts +0 -6
- package/dist/src/modules/mcp/proxy/handler.d.ts +0 -8
- package/dist/src/modules/mcp/proxy/index.d.ts +0 -7
- package/dist/src/modules/mcp/proxy/rewrite.d.ts +0 -13
- package/dist/src/modules/mcp/proxy/sign.d.ts +0 -6
- package/dist/src/modules/mcp/proxy/types.d.ts +0 -45
- package/dist/src/modules/mcp/resources/canonical.d.ts +0 -6
- package/dist/src/modules/mcp/resources/core.d.ts +0 -5
- package/dist/src/modules/mcp/resources/envelope.d.ts +0 -10
- package/dist/src/modules/mcp/resources/index.d.ts +0 -8
- package/dist/src/modules/mcp/resources/primer.d.ts +0 -7
- package/dist/src/modules/mcp/resources/register.d.ts +0 -10
- package/dist/src/modules/mcp/resources/renderGuide.d.ts +0 -10
- package/dist/src/modules/mcp/resources/router.d.ts +0 -10
- package/dist/src/modules/mcp/resources/schema.d.ts +0 -5
- package/dist/src/modules/mcp/resources/style.d.ts +0 -5
- package/dist/src/modules/mcp/screenshotClient.d.ts +0 -13
- package/dist/src/modules/mcp/server.d.ts +0 -31
- package/dist/src/modules/mcp/tests/helpers.d.ts +0 -13
- package/dist/src/modules/mcp/tools/apply/dispatch.d.ts +0 -6
- package/dist/src/modules/mcp/tools/apply/index.d.ts +0 -470
- package/dist/src/modules/mcp/tools/apply/writeResult.d.ts +0 -8
- package/dist/src/modules/mcp/tools/index.d.ts +0 -18
- package/dist/src/modules/mcp/tools/operations/index.d.ts +0 -928
- package/dist/src/modules/mcp/tools/operations/schema/bindings/deleteBinding.d.ts +0 -17
- package/dist/src/modules/mcp/tools/operations/schema/bindings/patchBinding.d.ts +0 -25
- package/dist/src/modules/mcp/tools/operations/schema/bindings/upsertBinding.d.ts +0 -27
- package/dist/src/modules/mcp/tools/operations/schema/elements/deleteElement.d.ts +0 -10
- package/dist/src/modules/mcp/tools/operations/schema/elements/moveElement.d.ts +0 -16
- package/dist/src/modules/mcp/tools/operations/schema/elements/patchElement.d.ts +0 -22
- package/dist/src/modules/mcp/tools/operations/schema/elements/repeatElement.d.ts +0 -55
- package/dist/src/modules/mcp/tools/operations/schema/elements/upsertElement.d.ts +0 -16
- package/dist/src/modules/mcp/tools/operations/schema/folders/deleteFolder.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/schema/folders/upsertFolder.d.ts +0 -12
- package/dist/src/modules/mcp/tools/operations/schema/index.d.ts +0 -21
- package/dist/src/modules/mcp/tools/operations/schema/interactions/deleteInteraction.d.ts +0 -12
- package/dist/src/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.d.ts +0 -18
- package/dist/src/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.d.ts +0 -27
- package/dist/src/modules/mcp/tools/operations/schema/operations.d.ts +0 -229
- package/dist/src/modules/mcp/tools/operations/schema/pages/deletePage.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/schema/pages/upsertPage.d.ts +0 -14
- package/dist/src/modules/mcp/tools/operations/schema/settings/patchSettings.d.ts +0 -34
- package/dist/src/modules/mcp/tools/operations/schema/shared.d.ts +0 -92
- package/dist/src/modules/mcp/tools/operations/schema/translator.d.ts +0 -12
- package/dist/src/modules/mcp/tools/operations/schema/variables/deleteVariable.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/schema/variables/upsertVariable.d.ts +0 -16
- package/dist/src/modules/mcp/tools/operations/schema/write.d.ts +0 -42
- package/dist/src/modules/mcp/tools/operations/schemaIds.d.ts +0 -6
- package/dist/src/modules/mcp/tools/operations/style/definitions/deleteDefinition.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/style/definitions/patchDefinition.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/definitions/upsertDefinition.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/definitions/upsertDefinitions.d.ts +0 -41
- package/dist/src/modules/mcp/tools/operations/style/globalStyles/deleteGlobalStyle.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/style/globalStyles/patchGlobalStyle.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/globalStyles/upsertGlobalStyle.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.d.ts +0 -9
- package/dist/src/modules/mcp/tools/operations/style/idStyles/patchIdStyle.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.d.ts +0 -37
- package/dist/src/modules/mcp/tools/operations/style/index.d.ts +0 -15
- package/dist/src/modules/mcp/tools/operations/style/operations.d.ts +0 -264
- package/dist/src/modules/mcp/tools/operations/style/shared.d.ts +0 -116
- package/dist/src/modules/mcp/tools/operations/style/translator.d.ts +0 -12
- package/dist/src/modules/mcp/tools/operations/style/variables/deleteStyleVariable.d.ts +0 -15
- package/dist/src/modules/mcp/tools/operations/style/variables/upsertStyleVariable.d.ts +0 -20
- package/dist/src/modules/mcp/tools/operations/style/write.d.ts +0 -12
- package/dist/src/modules/mcp/tools/preview.d.ts +0 -465
- package/dist/src/modules/mcp/tools/read.d.ts +0 -9
- package/dist/src/modules/mcp/tools/render.d.ts +0 -499
- package/dist/src/modules/mcp/tools/render.test.d.ts +0 -1
- package/dist/src/modules/mcp/tools/screenshot.d.ts +0 -470
- package/dist/src/modules/mcp/tools/search.d.ts +0 -15
- package/dist/src/modules/mcp/tools/shared/expandOperations.d.ts +0 -13
- package/dist/src/modules/mcp/tools/shared/tool.d.ts +0 -72
- package/dist/src/modules/mcp/tools/shared/validator/audit.d.ts +0 -4
- package/dist/src/modules/mcp/tools/shared/validator/batch.d.ts +0 -5
- package/dist/src/modules/mcp/tools/shared/validator/bindings.d.ts +0 -6
- package/dist/src/modules/mcp/tools/shared/validator/context.d.ts +0 -38
- package/dist/src/modules/mcp/tools/shared/validator/css.d.ts +0 -4
- package/dist/src/modules/mcp/tools/shared/validator/elements.d.ts +0 -7
- package/dist/src/modules/mcp/tools/shared/validator/index.d.ts +0 -8
- package/dist/src/modules/mcp/tools/shared/validator/interactions.d.ts +0 -3
- package/dist/src/modules/mcp/tools/shared/validator/refs.d.ts +0 -4
- package/dist/src/modules/mcp/tools/validate.d.ts +0 -467
- package/dist/src/modules/mcp/types/aiSchema.d.ts +0 -218
- package/dist/src/modules/mcp/types/appTypes.d.ts +0 -26
- package/dist/src/modules/mcp/types/index.d.ts +0 -5
- package/dist/src/modules/mcp/types/previewTypes.d.ts +0 -25
- package/dist/src/modules/mcp/types/screenshotTypes.d.ts +0 -29
- package/dist/src/modules/mcp/types/toolTypes.d.ts +0 -138
- package/dist/src/modules/oauth/authorize.d.ts +0 -7
- package/dist/src/modules/oauth/challenge.d.ts +0 -11
- package/dist/src/modules/oauth/consentPage.d.ts +0 -7
- package/dist/src/modules/oauth/metadata.d.ts +0 -40
- package/dist/src/modules/oauth/params.d.ts +0 -5
- package/dist/src/modules/oauth/pkce.d.ts +0 -6
- package/dist/src/modules/oauth/records.d.ts +0 -71
- package/dist/src/modules/oauth/register.d.ts +0 -5
- package/dist/src/modules/oauth/respond.d.ts +0 -13
- package/dist/src/modules/oauth/token.d.ts +0 -5
- package/dist/src/modules/ssr/buildBody.d.ts +0 -9
- package/dist/src/modules/ssr/handler.d.ts +0 -4
- package/dist/src/modules/ssr/preview.d.ts +0 -16
- package/dist/src/modules/ssr/streamBody.d.ts +0 -5
- package/dist/src/modules/ssr/template.d.ts +0 -6
- package/dist/src/standalone/alias-loader.d.mts +0 -2
- package/dist/src/standalone/plugins/ClientInfo.d.ts +0 -2
- package/dist/src/standalone/plugins/ServerInfo.d.ts +0 -2
- package/dist/src/standalone/plugins/SharedInfo.d.ts +0 -2
- package/dist/src/standalone/plugins/styles.d.ts +0 -5
- package/dist/src/standalone/register-alias.d.mts +0 -1
- package/dist/src/standalone/server.d.ts +0 -1
- package/dist/src/standalone/stubs/react-syntax-highlighter.d.mts +0 -31
- package/skills/plitzi-render/SKILL.md +0 -174
- /package/dist/{src/core/http/dispatcher.test.d.ts → core/auth/api.test.d.ts} +0 -0
- /package/dist/{src/core/server/mcpServer.test.d.ts → core/auth/authorize.test.d.ts} +0 -0
- /package/dist/{src/modules/ai/toolkit.test.d.ts → core/auth/createAuth.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/apps/apps.test.d.ts → core/auth/domains.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/apps/render/styles.test.d.ts → core/auth/identity.test.d.ts} +0 -0
- /package/dist/{src/modules → core/auth}/oauth/oauth.test.d.ts +0 -0
- /package/dist/{src/modules/mcp/catalogs/builtinTransformers.test.d.ts → core/auth/routes.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/catalogs/cssCatalog/cssCatalog.test.d.ts → core/auth/session.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/e2e/connector.test.d.ts → core/auth/spaceTokens.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/e2e/host.test.d.ts → core/auth/tokens.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/e2e/oauthConnector.test.d.ts → core/createServer.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/helpers/log.test.d.ts → core/handlers/handlers.test.d.ts} +0 -0
- /package/dist/{src/core → core}/health.d.ts +0 -0
- /package/dist/{src/modules/mcp/mcp.bench.d.ts → core/http/dispatcher.test.d.ts} +0 -0
- /package/dist/{src/core → core}/http/securityHeaders.d.ts +0 -0
- /package/dist/{src/core → core}/http/stages/authRoutes.d.ts +0 -0
- /package/dist/{src/core → core}/http/stages/pluginAssets.d.ts +0 -0
- /package/dist/{src/core → core}/mimeTypes.d.ts +0 -0
- /package/dist/{src/modules/mcp/constants.d.ts → core/previewToken.d.ts} +0 -0
- /package/dist/{src/core → core}/requestParser.d.ts +0 -0
- /package/dist/{src/core → core}/server/baseServer.d.ts +0 -0
- /package/dist/{src/modules/mcp/proxy/endpoint.test.d.ts → core/server/baseServer.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/proxy/proxy.test.d.ts → core/services/resolve.test.d.ts} +0 -0
- /package/dist/{src/core → core}/services/rsc.d.ts +0 -0
- /package/dist/{src/core → core}/services/ssr.d.ts +0 -0
- /package/dist/{src/core → core}/staticFiles.d.ts +0 -0
- /package/dist/{src/modules/mcp/proxy/wiring.test.d.ts → helpers/buildResponseHelpers.test.d.ts} +0 -0
- /package/dist/{src/helpers → helpers}/cache/TtlCache.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/cache/cacheManager.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/cache/defaults.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/cache/index.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/apply.test.d.ts → helpers/cache/keys.test.d.ts} +0 -0
- /package/dist/{src/helpers → helpers}/cache/serverCaches.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/bindings.test.d.ts → helpers/compress.test.d.ts} +0 -0
- /package/dist/{src/helpers → helpers}/escapeJson.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/metrics.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/normalizePlugins.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/css.test.d.ts → helpers/offlineDataLoader.test.d.ts} +0 -0
- /package/dist/{src/helpers → helpers}/readCookie.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/interactions.test.d.ts → helpers/resolveDebugMode.test.d.ts} +0 -0
- /package/dist/{src/helpers → helpers}/runMiddlewares.d.ts +0 -0
- /package/dist/{src/helpers → helpers}/serverLog.d.ts +0 -0
- /package/dist/{src/middlewares → middlewares}/auth.d.ts +0 -0
- /package/dist/{src/middlewares → middlewares}/basicAuth.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/pages.test.d.ts → middlewares/spaceDeployment.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/reads.test.d.ts → modules/actions/handler.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/schemaIds.test.d.ts → modules/connectors/engine.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/search.test.d.ts → modules/connectors/projection.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/skill.test.d.ts → modules/connectors/resolver.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/styles.test.d.ts → modules/rsc/resolveRscData.test.d.ts} +0 -0
- /package/dist/{src/modules → modules}/ssr/applySSRResult.d.ts +0 -0
- /package/dist/{src/modules/mcp/tests/tools.test.d.ts → modules/ssr/loadPluginComponents.test.d.ts} +0 -0
- /package/dist/{src/modules/mcp/tests/validation.test.d.ts → modules/ssr/metering.test.d.ts} +0 -0
- /package/dist/{src/modules → modules}/ssr/registerExternalPlugins.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/compile.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/copy.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/detect.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/manager.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/validate.d.ts +0 -0
- /package/dist/{src/plugins → plugins}/validate.test.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# @plitzi/sdk-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The page server for Plitzi spaces: server-side rendering, React Server Components, plugins, connectors and the
|
|
4
|
+
HTTP kernel they run on. Ships as an HTTP/2 server by default, with support for HTTP/1.1 and HTTP/3.
|
|
5
|
+
|
|
6
|
+
This package serves **pages**. The AI surface — the MCP server, its tool engine and the draft-preview
|
|
7
|
+
endpoint — lives in [`@plitzi/sdk-mcp`](../mcp/README.md), which builds on this one. A deployment that only
|
|
8
|
+
renders pages never installs it, and never loads it.
|
|
4
9
|
|
|
5
10
|
## Installation
|
|
6
11
|
|
|
@@ -11,29 +16,33 @@ yarn add @plitzi/sdk-server
|
|
|
11
16
|
## Usage
|
|
12
17
|
|
|
13
18
|
```ts
|
|
14
|
-
import {
|
|
15
|
-
import { createSSRServer } from '@plitzi/sdk-server';
|
|
19
|
+
import { createServer } from '@plitzi/sdk-server';
|
|
16
20
|
|
|
17
|
-
const server =
|
|
18
|
-
httpVersion: 2,
|
|
19
|
-
tls: {
|
|
20
|
-
key: readFileSync('./certs/server-key.pem'),
|
|
21
|
-
cert: readFileSync('./certs/server.pem')
|
|
22
|
-
},
|
|
23
|
-
adapters: {
|
|
24
|
-
getOfflineData,
|
|
25
|
-
getSpaceDeployment
|
|
26
|
-
}
|
|
27
|
-
});
|
|
21
|
+
const server = createServer({ adapters: { getOfflineData, getSpaceDeployment } });
|
|
28
22
|
|
|
29
23
|
server.listen(3001);
|
|
30
24
|
```
|
|
31
25
|
|
|
26
|
+
That is a whole page server: two adapters saying which space to render and where its content lives. The SDK bundle,
|
|
27
|
+
the transport and the rest have defaults the server can work out for itself — see
|
|
28
|
+
[What the server does without being asked](#what-the-server-does-without-being-asked).
|
|
29
|
+
|
|
30
|
+
Add TLS and it speaks HTTP/2:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { readFileSync } from 'node:fs';
|
|
34
|
+
|
|
35
|
+
createServer({
|
|
36
|
+
tls: { key: readFileSync('./certs/server-key.pem'), cert: readFileSync('./certs/server.pem') },
|
|
37
|
+
adapters: { getOfflineData, getSpaceDeployment }
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
32
41
|
## Configuration
|
|
33
42
|
|
|
34
43
|
| Option | Type | Default | Description |
|
|
35
44
|
|---|---|---|---|
|
|
36
|
-
| `httpVersion` | `1 \| 2 \| 3` | `2` | HTTP protocol version. Falls back to the nearest available lower version. |
|
|
45
|
+
| `httpVersion` | `1 \| 2 \| 3` | `2` with `tls`, else `1` | HTTP protocol version. Falls back to the nearest available lower version. |
|
|
37
46
|
| `tls` | `{ key, cert, minVersion? }` | — | TLS key and certificate. Required for versions 2 and 3; optional for version 1. |
|
|
38
47
|
| `devMode` | `boolean` | `NODE_ENV !== 'production'` | Enables development mode: appends `?dev` to esm.sh CDN URLs for React, and activates per-request timing metrics (see [Dev metrics](#dev-metrics)). |
|
|
39
48
|
| `assetVersion` | `string` | — | Cache-buster appended as `?v=<assetVersion>` to all default SDK asset URLs. Compute from file mtime or package version at startup. |
|
|
@@ -45,13 +54,16 @@ server.listen(3001);
|
|
|
45
54
|
| `pluginsCacheDir` | `string` | `.sdk-plugins` | Directory where compiled plugin files are stored. |
|
|
46
55
|
| `pluginsTtlMs` | `number` | `604800000` | TTL in milliseconds for compiled plugins (default: 1 week). |
|
|
47
56
|
| `autoLoadSchemaPlugins` | `boolean` | `true` | Auto-download and cache plugins declared in the schema's `offlineData.plugins` list. Set to `false` to manage plugin loading manually. |
|
|
48
|
-
| `publicDir` | `string` | — | Absolute path to a directory served at the root URL level (e.g. `robots.txt`, `favicon.png`). Files are checked
|
|
57
|
+
| `publicDir` | `string` | — | Absolute path to a directory served at the root URL level (e.g. `robots.txt`, `favicon.png`). Files are checked before `static` prefix routes. |
|
|
49
58
|
| `static` | `Record<string, string>` | — | URL prefix → filesystem path mappings for static file serving. |
|
|
50
59
|
| `ssrOnly` | `boolean` | `false` | Omit client-side JS from the rendered page. Useful for verifying SSR HTML without hydration. |
|
|
51
60
|
| `streaming` | `boolean` | `false` | Stream HTML to the browser incrementally to reduce TTFB. See [Streaming](#streaming). |
|
|
52
61
|
| `middlewares` | `SSRMiddleware[]` | — | Array of custom middleware functions executed before the SSR renderer on every request (see [Custom middlewares](#custom-middlewares)). |
|
|
53
62
|
| `rsc` | `SSRRscConfig` | — | React Server Components endpoint configuration (see [RSC](#react-server-components-rsc)). |
|
|
63
|
+
| `compression` | `SSRCompressionConfig \| false` | Brotli, then gzip | Response compression (see [Compression](#compression)). `false` never compresses. |
|
|
64
|
+
| `health` | `SSRHealthConfig` | identity payload | The `/health` endpoint. `check` adds live state per probe and turns it into a readiness probe (see [Health](#health)). |
|
|
54
65
|
| `adapters` | `SSRAdapters` | — | Required. Adapter callbacks for data fetching. |
|
|
66
|
+
| `onListenError` | `(error, { port, host, label }) => void` | exits non-zero | What to do when the server cannot take its port. By default it prints what went wrong and what to do about it, then exits — a process whose server never bound is not running. Supply this to keep it alive and decide yourself. |
|
|
55
67
|
|
|
56
68
|
### HTTP version behaviour
|
|
57
69
|
|
|
@@ -65,45 +77,37 @@ HTTP/3 requires Node.js ≥ 23 started with `--experimental-quic`. When unavaila
|
|
|
65
77
|
|
|
66
78
|
## Adapters
|
|
67
79
|
|
|
68
|
-
The `adapters` option is the integration point between the SSR server and your data layer.
|
|
80
|
+
The `adapters` option is the integration point between the SSR server and your data layer. For the auth ones, `createAuth` answers all three for you — see [User authentication](#user-authentication).
|
|
69
81
|
|
|
70
82
|
```ts
|
|
71
83
|
type SSRAdapters = {
|
|
72
84
|
getOfflineData: (spaceId: number, environment: string, revision?: number) => Promise<OfflineDataRaw | undefined>;
|
|
73
85
|
getSpaceDeployment: (req: SSRRequest) => Promise<SSRSpaceDeployment>;
|
|
74
86
|
getUser?: (req: SSRRequest) => Promise<SSRUser | undefined>;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
getRscData?: (
|
|
78
|
-
req: SSRRequest,
|
|
79
|
-
spaceId: number,
|
|
80
|
-
environment: Environment,
|
|
81
|
-
revision: number,
|
|
82
|
-
user: SSRUser | undefined,
|
|
83
|
-
ids?: string[] // present on partial refresh; absent for full fetch
|
|
84
|
-
) => Promise<SSRRscData>;
|
|
87
|
+
authenticate?: (credentials: Record<string, string>, req: SSRRequest) => Promise<SSRSession | undefined>;
|
|
88
|
+
endSession?: (req: SSRRequest) => Promise<void>;
|
|
89
|
+
getRscData?: (context: SSRRscContext) => Promise<SSRRscData>;
|
|
85
90
|
};
|
|
86
91
|
```
|
|
87
92
|
|
|
88
93
|
- **`getOfflineData`** — returns the space snapshot (schema, plugins, styles, segments, collections) for SSR.
|
|
89
94
|
- **`getSpaceDeployment`** — resolves which space and environment to render for a given inbound request. Return `{ error: { code, message } }` to abort with an HTTP error. Optionally include `templateProps` to override template variables, or `pluginNames` to activate plugins for the space (see [Plugins](#plugins) and [Template props](#template-props)).
|
|
90
|
-
- **`getUser`** *(optional)* — resolves the authenticated user from the inbound request (e.g. via a session cookie or `Authorization` header). Called in parallel with `getOfflineData` on every cache miss.
|
|
91
|
-
- **`
|
|
92
|
-
- **`
|
|
93
|
-
- **`getRscData`** *(optional)* — called by the RSC endpoint (`/_rsc`) to fetch server-side data for schema elements with `runtime: 'server'`.
|
|
95
|
+
- **`getUser`** *(optional)* — resolves the authenticated user from the inbound request (e.g. via a session cookie or `Authorization` header). Called in parallel with `getOfflineData` on every cache miss. Return `undefined` for unauthenticated requests. What it returns is inlined into the page — `authenticated`, `user.details`, the access token and its expiry — and that does two things: it decides page-level access for guest vs. registered users during the render, and it **saves the browser its first auth request**. The SDK adopts the inlined session on boot, stores it and schedules the renewal, rather than asking the same authority the same question a few milliseconds later. Implement this one adapter and every server-rendered page starts signed in with no round trip; `createAuth` answers it for you.
|
|
96
|
+
- **`authenticate`** *(optional)* — called when `POST {loginPath}` is received, with the credentials already parsed from the body (a posted form or JSON), whatever fields they are. Return a session to grant one, `undefined` to refuse — and never throw for a wrong password. **Identity only**: the cookies, their lifetimes and the readable hint are the server's, which is what keeps a session established here visible to the API side and the other way round. For a navigation (full-page form submit, `Sec-Fetch-Mode: navigate`) the server answers a `303` so the view re-renders via a GET; for a fetch it answers `200` with `{ success, access_token, expire_at }` or `401` with `{ error, reason }` — never a bodyless status, which leaves a caller holding nothing. This route knows a session and not the account behind it; `createServer({ auth })` serves the same path from the auth kernel instead, which answers the full grant.
|
|
97
|
+
- **`endSession`** *(optional)* — called when `POST {logoutPath}` is received. Revoke the session at the source; the server clears the cookies. Clearing them alone would leave the credential itself working for anyone who had already copied it. A navigation receives a `303` redirect; a fetch receives `204 No Content`.
|
|
98
|
+
- **`getRscData`** *(optional)* — called by the RSC endpoint (`/_rsc`), and once per page render, to fetch server-side data for schema elements with `runtime: 'server'`. Takes one `SSRRscContext`: the request, the space context, the resolved user so authenticated operations are safe, `ids` on a partial refresh (absent means every element), and `loadOfflineData`. That last one is the space itself, shared with the page render happening alongside — await it instead of fetching the schema again, and it is read once per request however many callers ask. Return `{}` when there is no server data for the current request (see [RSC](#react-server-components-rsc)).
|
|
94
99
|
|
|
95
100
|
## JSON adapters (offline mode)
|
|
96
101
|
|
|
97
|
-
`createJsonAdapters` provides a ready-made adapter set that reads
|
|
102
|
+
`createJsonAdapters` provides a ready-made adapter set that reads a space from local JSON files, useful for offline mode, integration tests, and static deployments.
|
|
98
103
|
|
|
99
104
|
```ts
|
|
100
|
-
import {
|
|
105
|
+
import { createServer, createJsonAdapters } from '@plitzi/sdk-server';
|
|
101
106
|
|
|
102
|
-
const server =
|
|
107
|
+
const server = createServer({
|
|
103
108
|
adapters: createJsonAdapters({
|
|
104
109
|
offlineData: '/exports/offline.json',
|
|
105
|
-
deployment: { spaceId: 1, environment: 'main', revision: 0 }
|
|
106
|
-
user: { id: 1, username: 'admin', email: 'admin@example.com', verified: true, permissions: [], roles: [] }
|
|
110
|
+
deployment: { spaceId: 1, environment: 'main', revision: 0 }
|
|
107
111
|
})
|
|
108
112
|
});
|
|
109
113
|
|
|
@@ -116,18 +120,83 @@ server.listen(3001);
|
|
|
116
120
|
|---|---|---|
|
|
117
121
|
| `offlineData` | `string` | Path to a single JSON file used for every request. |
|
|
118
122
|
| `offlineData` | `(spaceId, environment, revision?) => string` | Function returning the path for the requested space. |
|
|
123
|
+
| `offlineData` | `OfflineDataRaw` | The space itself, for a consumer that already holds it. Read-only: `saveOfflineData` is offered only for a path. |
|
|
119
124
|
| `deployment` | `string` | Path to a JSON file containing an `SSRSpaceDeployment` object. |
|
|
120
125
|
| `deployment` | `SSRSpaceDeployment` | Inline deployment object used for every request. |
|
|
121
126
|
| `deployment` | `Record<hostname, SSRSpaceDeployment>` | Per-hostname map. Use `'*'` as a catch-all. |
|
|
127
|
+
|
|
128
|
+
## Auth adapters
|
|
129
|
+
|
|
130
|
+
Where a space comes from and who is looking at it are two integrations, so they are two factories. `createAuthAdapters` answers the identity half, and the two compose with a spread:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { createAuthAdapters, createJsonAdapters, createServer } from '@plitzi/sdk-server';
|
|
134
|
+
|
|
135
|
+
createServer({
|
|
136
|
+
adapters: {
|
|
137
|
+
...createJsonAdapters({ offlineData: '/exports/offline.json' }),
|
|
138
|
+
...createAuthAdapters({ user: req => sessionsFor(req) })
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `AuthAdaptersConfig`
|
|
144
|
+
|
|
145
|
+
| Option | Type | Description |
|
|
146
|
+
|---|---|---|
|
|
122
147
|
| `user` | `SSRUser` | Fixed user returned for every request. Useful for testing authenticated flows. |
|
|
123
|
-
| `user` | `(req) => SSRUser \| undefined \| Promise<SSRUser \| undefined>` |
|
|
148
|
+
| `user` | `(req) => SSRUser \| undefined \| Promise<SSRUser \| undefined>` | Dynamic resolution per request. |
|
|
149
|
+
| `authenticate` | `(credentials, req) => Promise<SSRSession \| undefined>` | Verify credentials and mint a session for `POST {loginPath}`. |
|
|
150
|
+
| `endSession` | `(req) => Promise<void>` | Revoke this request's session for `POST {logoutPath}`. |
|
|
151
|
+
|
|
152
|
+
Anything left out is omitted rather than set to `undefined`, so composing these never unwires an adapter another factory supplied.
|
|
153
|
+
|
|
154
|
+
A deployment running the auth kernel needs none of this: `createServer({ auth })` fills the same three in from `createAuth(...).ssrAdapters`, and serves the full `/auth` surface instead of just login and logout.
|
|
155
|
+
|
|
156
|
+
## What the server does without being asked
|
|
157
|
+
|
|
158
|
+
Four things it used to make every deployment declare, each of which it can answer itself:
|
|
159
|
+
|
|
160
|
+
| | |
|
|
161
|
+
|---|---|
|
|
162
|
+
| **The SDK bundle** | The rendered page is told to fetch `/sdk-assets/plitzi-sdk.js`, so the server serves it, from its own copy of `@plitzi/plitzi-sdk`. Declaring `static: { '/sdk-assets': … }` still wins — a pinned build, a CDN mirror |
|
|
163
|
+
| **The transport** | `httpVersion` defaults to HTTP/2 with `tls` and HTTP/1.1 without. No browser speaks cleartext h2, so the old default of `2` meant every local run had to say otherwise |
|
|
164
|
+
| **The audience** | `tokens.audience` defaults to the issuer, which is right for a deployment that is its own audience |
|
|
165
|
+
| **The space** | `createJsonAdapters({ offlineData })` alone resolves to space 1, `main`, revision 0 |
|
|
166
|
+
|
|
167
|
+
A page server therefore needs `port`, `adapters`, and nothing else.
|
|
168
|
+
|
|
169
|
+
## Health
|
|
170
|
+
|
|
171
|
+
Every server answers `GET /health` with its identity — no wiring needed:
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{ "Server": "SDK Server", "Version": "v1.2.3", "role": "ssr" }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`check` adds what only the deployment can know, read on every probe. Returning `healthy: false` answers **503**,
|
|
178
|
+
which is what makes this a readiness probe rather than a liveness one: an orchestrator stops routing to a replica
|
|
179
|
+
whose database has gone, instead of sending it traffic it can only fail. A check that throws is itself an unhealthy
|
|
180
|
+
answer, reported as one rather than as a 500.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
createServer({
|
|
184
|
+
health: {
|
|
185
|
+
role: 'ssr',
|
|
186
|
+
name: 'Acme Renderer',
|
|
187
|
+
version: pkg.version,
|
|
188
|
+
check: () => ({ Databases: { mongo: mongo.status() }, healthy: mongo.healthy })
|
|
189
|
+
},
|
|
190
|
+
adapters
|
|
191
|
+
});
|
|
192
|
+
```
|
|
124
193
|
|
|
125
194
|
## Static files
|
|
126
195
|
|
|
127
196
|
Map URL prefixes to local directories:
|
|
128
197
|
|
|
129
198
|
```ts
|
|
130
|
-
|
|
199
|
+
createServer({
|
|
131
200
|
static: {
|
|
132
201
|
'/sdk-assets': './node_modules/@plitzi/plitzi-sdk/dist',
|
|
133
202
|
'/builder-assets': './node_modules/@plitzi/plitzi-builder/dist'
|
|
@@ -140,44 +209,61 @@ Static responses include `ETag`, `Last-Modified`, and `Cache-Control` headers. S
|
|
|
140
209
|
|
|
141
210
|
### Public directory
|
|
142
211
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Use `publicDir` to serve your own root-level files (e.g. `robots.txt`, `sitemap.xml`) without prefixes:
|
|
212
|
+
Use `publicDir` to serve your own root-level files (e.g. `robots.txt`, `sitemap.xml`, `favicon.png`) without prefixes:
|
|
146
213
|
|
|
147
214
|
```ts
|
|
148
|
-
|
|
215
|
+
createServer({
|
|
149
216
|
publicDir: path.resolve(process.cwd(), 'src/services/ssr/public'),
|
|
150
217
|
adapters: { ... }
|
|
151
218
|
});
|
|
152
219
|
```
|
|
153
220
|
|
|
154
|
-
The lookup order for a request is:
|
|
221
|
+
The lookup order for a request is: `publicDir` → `static` prefix routes → SSR renderer.
|
|
155
222
|
|
|
156
223
|
`/.well-known/` paths follow the same lookup order: served from `publicDir` if a matching file exists, otherwise `404 Not Found`. They are never handled by the SSR renderer.
|
|
157
224
|
|
|
158
225
|
## Compression
|
|
159
226
|
|
|
160
|
-
Responses are compressed
|
|
227
|
+
Responses are compressed based on the `Accept-Encoding` request header. By default the server offers Brotli, then
|
|
228
|
+
gzip, and leaves payloads under 1 KB alone — below that the compressed body plus its headers is no smaller.
|
|
161
229
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
230
|
+
`Content-Encoding` and `Vary: Accept-Encoding` are set on every compressed response. An encoding the client refused
|
|
231
|
+
with `q=0` is never used.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
createServer({
|
|
235
|
+
compression: { encodings: ['gzip'], threshold: 2048, gzipLevel: 9 },
|
|
236
|
+
adapters
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Nothing at all — for a CDN or proxy in front that already compresses.
|
|
240
|
+
createServer({ compression: false, adapters });
|
|
241
|
+
```
|
|
166
242
|
|
|
167
|
-
|
|
243
|
+
| Option | Type | Default | Description |
|
|
244
|
+
|---|---|---|---|
|
|
245
|
+
| `encodings` | `('br' \| 'gzip')[]` | `['br', 'gzip']` | What this server offers, most preferred first; the first one the client accepts wins. `[]` disables compression. |
|
|
246
|
+
| `threshold` | `number` | `1024` | Responses smaller than this many bytes go out uncompressed. |
|
|
247
|
+
| `brotliQuality` | `number` | `4` | Brotli quality, 0–11. Past 4 the CPU cost outgrows the bytes saved on HTML. |
|
|
248
|
+
| `gzipLevel` | `number` | `6` | Gzip level, 0–9. |
|
|
249
|
+
|
|
250
|
+
A response that sets `Cache-Control: no-transform` is never compressed, whatever the settings say — that header is
|
|
251
|
+
how a handler declares its body must reach the client byte for byte. The OAuth token endpoint in
|
|
252
|
+
[`@plitzi/sdk-mcp`](../mcp/README.md) relies on it: a credential travelling beside a caller-chosen value is the
|
|
253
|
+
shape a BREACH-style attack needs.
|
|
168
254
|
|
|
169
255
|
## Render cache
|
|
170
256
|
|
|
171
257
|
SSR output is cached in-memory per `(spaceId, environment, revision, hostname, path, search)`. The cache uses a 5-minute TTL by default. The `main` environment is always excluded from caching — it is the development environment and its schema changes frequently.
|
|
172
258
|
|
|
173
259
|
```ts
|
|
174
|
-
|
|
260
|
+
createServer({
|
|
175
261
|
cacheTtlMs: 60_000, // 1 minute
|
|
176
262
|
adapters: { ... }
|
|
177
263
|
});
|
|
178
264
|
|
|
179
265
|
// Disable caching entirely
|
|
180
|
-
|
|
266
|
+
createServer({
|
|
181
267
|
cacheTtlMs: 0,
|
|
182
268
|
adapters: { ... }
|
|
183
269
|
});
|
|
@@ -192,7 +278,7 @@ Responses include an `X-Cache: HIT` or `X-Cache: MISS` header for observability.
|
|
|
192
278
|
`server.cache` exposes programmatic cache control, useful when content changes and you need to invalidate entries without restarting the server.
|
|
193
279
|
|
|
194
280
|
```ts
|
|
195
|
-
const server =
|
|
281
|
+
const server = createServer({ cacheTtlMs: 300_000, adapters });
|
|
196
282
|
|
|
197
283
|
// Invalidate all entries for a specific space
|
|
198
284
|
server.cache?.invalidate({ spaceId: 42 });
|
|
@@ -229,7 +315,7 @@ Plugins are React component bundles that extend the Plitzi schema renderer. They
|
|
|
229
315
|
```ts
|
|
230
316
|
import type { SSRSpaceDeployment } from '@plitzi/sdk-server';
|
|
231
317
|
|
|
232
|
-
const server =
|
|
318
|
+
const server = createServer({
|
|
233
319
|
plugins: {
|
|
234
320
|
// From a source file — compiled to ESM with esbuild
|
|
235
321
|
'my-chart': {
|
|
@@ -310,7 +396,7 @@ Plugins listed in `pluginSources` are registered into the plugin manager on-the-
|
|
|
310
396
|
|
|
311
397
|
### Plugin versioning
|
|
312
398
|
|
|
313
|
-
Every plugin registered through `
|
|
399
|
+
Every plugin registered through `createServer` (or via `server.plugins.register`) is versioned. If you omit `version`, it defaults to `'1.0.0'`:
|
|
314
400
|
|
|
315
401
|
```ts
|
|
316
402
|
plugins: {
|
|
@@ -364,7 +450,7 @@ To force recompilation without waiting for TTL expiry, call `server.plugins.inva
|
|
|
364
450
|
Plugins can be registered after the server has started without restarting it. This is useful when plugins are loaded from a database or activated at runtime:
|
|
365
451
|
|
|
366
452
|
```ts
|
|
367
|
-
const server =
|
|
453
|
+
const server = createServer({ adapters });
|
|
368
454
|
server.listen(3001);
|
|
369
455
|
|
|
370
456
|
// Later — register a new plugin dynamically
|
|
@@ -426,18 +512,12 @@ Implement `getRscData` in your adapters to serve data from the `/_rsc` endpoint.
|
|
|
426
512
|
When `ids` is provided the client is performing a **partial refresh** — only return data for those element IDs. When `ids` is absent, return data for all elements (full fetch):
|
|
427
513
|
|
|
428
514
|
```ts
|
|
429
|
-
import type { SSRAdapters,
|
|
515
|
+
import type { SSRAdapters, SSRRscContext, SSRRscData } from '@plitzi/sdk-server';
|
|
430
516
|
|
|
431
|
-
const getRscData = async (
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
revision: number,
|
|
436
|
-
user: SSRUser | undefined,
|
|
437
|
-
ids?: string[]
|
|
438
|
-
): Promise<SSRRscData> => {
|
|
439
|
-
// Only serve data when the schema has RSC enabled
|
|
440
|
-
const offlineData = await getOfflineData(spaceId, environment, revision);
|
|
517
|
+
const getRscData = async ({ user, ids, loadOfflineData }: SSRRscContext): Promise<SSRRscData> => {
|
|
518
|
+
// Only serve data when the schema has RSC enabled. `loadOfflineData` joins the read the page render already
|
|
519
|
+
// started — it never costs a second trip to your database.
|
|
520
|
+
const offlineData = await loadOfflineData();
|
|
441
521
|
if (!offlineData?.schema.rsc?.enabled) {
|
|
442
522
|
return {};
|
|
443
523
|
}
|
|
@@ -502,7 +582,7 @@ The server automatically registers `GET /_rsc` when `adapters.getRscData` is pro
|
|
|
502
582
|
1. Reads `spaceId`, `environment`, and `revision` from the resolved `spaceDeployment` context.
|
|
503
583
|
2. Reads the authenticated user from `ctx.user`.
|
|
504
584
|
3. Reads optional `?ids=elem1,elem2` for partial refresh.
|
|
505
|
-
4. Calls `adapters.getRscData(req, spaceId, environment, revision, user, ids
|
|
585
|
+
4. Calls `adapters.getRscData({ req, spaceId, environment, revision, user, ids, loadOfflineData })`.
|
|
506
586
|
5. Returns a JSON payload:
|
|
507
587
|
|
|
508
588
|
```json
|
|
@@ -523,7 +603,7 @@ The endpoint returns `400` if `spaceId` is missing or invalid, `500` if `getRscD
|
|
|
523
603
|
### RSC configuration
|
|
524
604
|
|
|
525
605
|
```ts
|
|
526
|
-
|
|
606
|
+
createServer({
|
|
527
607
|
rsc: {
|
|
528
608
|
enabled: true, // default: true when getRscData is provided
|
|
529
609
|
path: '/_rsc' // default: '/_rsc'
|
|
@@ -565,46 +645,123 @@ The hook is backed by `RscProvider`, which fetches `/_rsc` once on mount and upd
|
|
|
565
645
|
|
|
566
646
|
## User authentication
|
|
567
647
|
|
|
568
|
-
|
|
648
|
+
Sessions, in one call. `createAuth` takes what only your deployment knows — the signing secret, what you call your
|
|
649
|
+
cookies, and the store your accounts live in — and returns the whole cycle wired together.
|
|
650
|
+
|
|
651
|
+
```ts
|
|
652
|
+
import { createServer } from '@plitzi/sdk-server';
|
|
653
|
+
import { createAuth } from '@plitzi/sdk-server/kernel';
|
|
654
|
+
|
|
655
|
+
const auth = createAuth({
|
|
656
|
+
tokens: { secret: process.env.AUTH_SECRET, issuer: 'https://acme.com', audience: ['https://acme.com'] },
|
|
657
|
+
cookie: { name: 'acme_session' },
|
|
658
|
+
adapters: accounts,
|
|
659
|
+
api: { verifyPassword }
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
createServer({ port: 443, adapters: { getOfflineData, getSpaceDeployment }, auth });
|
|
663
|
+
```
|
|
569
664
|
|
|
570
|
-
|
|
665
|
+
`auth` on the server is the whole of the wiring: it mounts the `/auth` flows, answers the identity adapters a page
|
|
666
|
+
server asks for, and carries the cookie naming with it — so there is no second place to keep in step. Everything is
|
|
667
|
+
still exported separately (`createTokens`, `createIdentity`, `createAuthApi`, `authRoutes`, …) for a deployment that
|
|
668
|
+
wants to assemble or replace one piece.
|
|
571
669
|
|
|
572
|
-
|
|
670
|
+
Nothing here assumes a web framework: a request is `{ headers, hostname, cookies?, query?, body? }` and a response is
|
|
671
|
+
anything that can carry `Set-Cookie`, both true of bare `node:http`.
|
|
672
|
+
|
|
673
|
+
### Serving the flows from your own server
|
|
674
|
+
|
|
675
|
+
A page server gets the `/auth` surface from `createServer({ auth })`. A deployment that serves its API elsewhere —
|
|
676
|
+
its own HTTP server, or one behind a router — gets the same flows as ready-made handlers from
|
|
677
|
+
`@plitzi/sdk-server/handlers`.
|
|
678
|
+
|
|
679
|
+
**That entry imports no framework and does not add one as a dependency.** The request, response and router are
|
|
680
|
+
described by the few properties the handlers touch, which an Express, Connect or Koa object already satisfies and a
|
|
681
|
+
`node:http` server satisfies with a few lines of its own.
|
|
573
682
|
|
|
574
683
|
```ts
|
|
575
|
-
import
|
|
684
|
+
import { createAuthMiddleware, mountAuthRoutes } from '@plitzi/sdk-server/handlers';
|
|
576
685
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
686
|
+
// Every request: resolves the credential against your policy and puts it on `req.user` / `req.grant`,
|
|
687
|
+
// or answers `{ error, reason }` with the right status.
|
|
688
|
+
app.use(createAuthMiddleware(auth.identity, policy));
|
|
580
689
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
690
|
+
// The twelve flows, on whatever has `get` and `post`.
|
|
691
|
+
const router = Router();
|
|
692
|
+
mountAuthRoutes(router, { api: auth.api, cookies: auth.cookies });
|
|
693
|
+
app.use('/auth', router);
|
|
694
|
+
```
|
|
584
695
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
return undefined;
|
|
588
|
-
}
|
|
696
|
+
Without a router, `createAuthRouteHandlers` returns the same flows as a list — `{ method, path, handle }` — and
|
|
697
|
+
dispatching them is yours:
|
|
589
698
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
email: user.email,
|
|
594
|
-
verified: user.isActive,
|
|
595
|
-
permissions: user.permissions,
|
|
596
|
-
roles: user.roles
|
|
597
|
-
};
|
|
598
|
-
};
|
|
699
|
+
```ts
|
|
700
|
+
import { createAuthRouteHandlers } from '@plitzi/sdk-server/handlers';
|
|
701
|
+
import { parseRequest } from '@plitzi/sdk-server/kernel';
|
|
599
702
|
|
|
600
|
-
|
|
703
|
+
const routes = createAuthRouteHandlers({ api: auth.api, cookies: auth.cookies });
|
|
704
|
+
const route = routes.find(r => r.method === req.method && `/auth${r.path}` === req.path);
|
|
705
|
+
await route?.handle(req, res);
|
|
601
706
|
```
|
|
602
707
|
|
|
708
|
+
What is *not* here is anything a deployment must decide: its accounts, its policy, its cookie naming. Those stay
|
|
709
|
+
`createAuth`'s. What is here is the part that was identical in every deployment that wrote it by hand — including
|
|
710
|
+
one real trap: `hostname` is a prototype getter on several frameworks, so building the carrier with a spread drops
|
|
711
|
+
it, and every cookie is then named for nowhere.
|
|
712
|
+
|
|
713
|
+
### What you implement
|
|
714
|
+
|
|
715
|
+
An account store. These are the only functions the server needs from it, and it never learns whether they read
|
|
716
|
+
Postgres, MySQL, Mongo or an identity service:
|
|
717
|
+
|
|
718
|
+
| Adapter | Needed for |
|
|
719
|
+
|---|---|
|
|
720
|
+
| `findAccountByToken(token)` | every request — the row **is** the revocation switch, so look accounts up *by token* |
|
|
721
|
+
| `saveSession(userId, session)` | signing in and renewing. Storing the new pair retires the previous one; that is rotation |
|
|
722
|
+
| `clearSession(target)` | signing out |
|
|
723
|
+
| `loadAccess(userId)` | the roles and permissions a grant answers with |
|
|
724
|
+
| `findByUsername(username)` | password sign-in |
|
|
725
|
+
| `findByRefreshToken(token)` | renewal. Answer with `refreshExpiresAt`, or every renewal is refused as expired |
|
|
726
|
+
| `findMembership(userId, spaceId)` | space-level permission checks (`auth.can`) |
|
|
727
|
+
| `createAccount`, `findByEmail`, `setResetToken`, `sendMail`, … | signup, password reset, verification |
|
|
728
|
+
|
|
729
|
+
**What is absent decides what the deployment offers.** No `createAccount`, no signup — and the route answers 404
|
|
730
|
+
rather than failing at runtime. Declining a flow is one act: do not implement it. `GET /auth/capabilities` publishes
|
|
731
|
+
the result, so a sign-in page renders what the backend actually answers instead of a button that dead-ends.
|
|
732
|
+
|
|
733
|
+
### What you get
|
|
734
|
+
|
|
735
|
+
`POST /auth/login`, `/auth/refresh`, `/auth/logout`, `/auth/sessions/revoke`, `/auth/exchange`, `GET /auth/session`,
|
|
736
|
+
`GET /auth/capabilities`, plus signup, password reset and verification where the adapters support them. Sign-in and
|
|
737
|
+
sign-out also answer a full-page form submission with a `303` so the view re-renders, which a `fetch` client does
|
|
738
|
+
not need and a `<form>` does.
|
|
739
|
+
|
|
740
|
+
Behaviour you do not have to get right yourself: the credential is renewed ahead of expiry and rotated when it is;
|
|
741
|
+
signing out revokes at the source rather than only clearing the browser's copy; a readable hint cookie rides beside
|
|
742
|
+
the session carrying nothing but expiry timestamps, so a page can tell that nobody is signed in without a request;
|
|
743
|
+
and every refusal names a machine-readable `reason`, so a client can tell "renew me" from "you are gone".
|
|
744
|
+
|
|
745
|
+
### Beyond the defaults
|
|
746
|
+
|
|
747
|
+
| Config | Effect |
|
|
748
|
+
|---|---|
|
|
749
|
+
| `cookie` | Name, domain, `SameSite`, `Secure`, the refresh path, the hint suffix. Defaults derive from the request host |
|
|
750
|
+
| `basePath` | Where the flows are mounted. The guard's rules follow it |
|
|
751
|
+
| `rules` / `fallback` | Extra authorization rules, applied before the derived ones, and what an unlisted path requires |
|
|
752
|
+
| `identity` | Your own hosts and origins — the floor for domain binding and framing |
|
|
753
|
+
| `tokens.lifetimes` | How long each credential lives |
|
|
754
|
+
|
|
755
|
+
A working example is [`examples/02-with-users`](../../examples/02-with-users).
|
|
756
|
+
|
|
603
757
|
### `SSRUser`
|
|
604
758
|
|
|
759
|
+
What a rendered page sees, so a schema can restrict pages to signed-in visitors — the SDK reads `authenticated` and
|
|
760
|
+
`user.details`.
|
|
761
|
+
|
|
605
762
|
| Field | Type | Description |
|
|
606
763
|
|---|---|---|
|
|
607
|
-
| `token` | `string` | Opaque token or JWT
|
|
764
|
+
| `token` | `string` | Opaque token or JWT. |
|
|
608
765
|
| `id` | `number` | Unique user identifier. |
|
|
609
766
|
| `username` | `string` | Display name. |
|
|
610
767
|
| `email` | `string` | Email address. |
|
|
@@ -612,59 +769,26 @@ createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser } });
|
|
|
612
769
|
| `permissions` | `string[]` | Permission keys for fine-grained access control. |
|
|
613
770
|
| `roles` | `string[]` | Role names. |
|
|
614
771
|
|
|
615
|
-
###
|
|
772
|
+
### Bringing your own identity entirely
|
|
616
773
|
|
|
617
|
-
|
|
774
|
+
Skip `createAuth` and implement three adapters directly — the server then knows only what you tell it:
|
|
618
775
|
|
|
619
776
|
```ts
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
The path is configurable via `loginPath`. Set it to `false` to disable the endpoint entirely:
|
|
633
|
-
|
|
634
|
-
```ts
|
|
635
|
-
createSSRServer({
|
|
636
|
-
loginPath: '/api/login', // custom path
|
|
637
|
-
// loginPath: false, // disable
|
|
638
|
-
adapters: { ... }
|
|
777
|
+
createServer({
|
|
778
|
+
adapters: {
|
|
779
|
+
getOfflineData,
|
|
780
|
+
getSpaceDeployment,
|
|
781
|
+
getUser: async req => /* … resolve the visitor, or undefined */,
|
|
782
|
+
authenticate: async (credentials, req) => /* … a session, or undefined to refuse */,
|
|
783
|
+
endSession: async req => /* … revoke it */
|
|
784
|
+
},
|
|
785
|
+
loginPath: '/api/login', // or false to serve no endpoint
|
|
786
|
+
logoutPath: false
|
|
639
787
|
});
|
|
640
788
|
```
|
|
641
789
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
The server exposes a built-in `POST /auth/logout` endpoint. When hit, it calls `adapters.onLogout(req, res)`. A navigation gets a `303` redirect so the view re-renders logged out; a fetch gets `204 No Content`. Implement `onLogout` to invalidate the session or cached user entry and clear the cookie:
|
|
645
|
-
|
|
646
|
-
```ts
|
|
647
|
-
const onLogout = async (req: SSRRequest, res: SSRResponseHelpers): Promise<void> => {
|
|
648
|
-
const token = parseCookies(req.headers['cookie'] ?? '')['my_session'];
|
|
649
|
-
if (token) {
|
|
650
|
-
await cache.delete(`user-${token}`);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
res.setHeader('Set-Cookie', 'my_session=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0');
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser, onLogout } });
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
The path is configurable via `logoutPath`. Set it to `false` to disable the endpoint entirely:
|
|
660
|
-
|
|
661
|
-
```ts
|
|
662
|
-
createSSRServer({
|
|
663
|
-
logoutPath: '/api/logout', // custom path
|
|
664
|
-
// logoutPath: false, // disable
|
|
665
|
-
adapters: { ... }
|
|
666
|
-
});
|
|
667
|
-
```
|
|
790
|
+
`authenticate` returns identity and nothing else: the cookies, their lifetimes and the readable hint are the
|
|
791
|
+
server's, which is what keeps a session established on the API side visible to the renderer and the other way round.
|
|
668
792
|
|
|
669
793
|
## Basic auth
|
|
670
794
|
|
|
@@ -694,7 +818,7 @@ const rateLimitMiddleware: SSRMiddleware = async (req, res, next) => {
|
|
|
694
818
|
return next();
|
|
695
819
|
};
|
|
696
820
|
|
|
697
|
-
|
|
821
|
+
createServer({
|
|
698
822
|
middlewares: [corsMiddleware, rateLimitMiddleware],
|
|
699
823
|
adapters: { ... }
|
|
700
824
|
});
|
|
@@ -702,12 +826,62 @@ createSSRServer({
|
|
|
702
826
|
|
|
703
827
|
Middlewares run after the built-in auth checks (Basic auth, `spaceDeployment` resolution, `getUser`) and before RSC and the SSR renderer.
|
|
704
828
|
|
|
829
|
+
## Extending the pipeline
|
|
830
|
+
|
|
831
|
+
A page server runs a fixed, ordered pipeline of stages. Order is an invariant — static assets first, then stages
|
|
832
|
+
that authenticate themselves, then the auth middleware chain, then the data services, then the renderer — so a
|
|
833
|
+
companion package does not hand over a list of stages. It hands them over by **slot**, and this package decides
|
|
834
|
+
where the slot lands:
|
|
835
|
+
|
|
836
|
+
```ts
|
|
837
|
+
import { createServer } from '@plitzi/sdk-server';
|
|
838
|
+
import { mcpExtensions } from '@plitzi/sdk-mcp';
|
|
839
|
+
|
|
840
|
+
const server = createServer({ adapters }, mcpExtensions());
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
| Slot | Runs | For |
|
|
844
|
+
|---|---|---|
|
|
845
|
+
| `preAuth` | after static assets, **before** the auth middleware chain | stages that gate themselves — on a shared secret, a bearer token, or nothing at all |
|
|
846
|
+
| `data` | after the auth chain, before the page render | stages serving data to an already-identified visitor |
|
|
847
|
+
|
|
848
|
+
Pass only the stages you want rather than the whole bundle:
|
|
849
|
+
|
|
850
|
+
```ts
|
|
851
|
+
import { previewStage } from '@plitzi/sdk-mcp';
|
|
852
|
+
|
|
853
|
+
// Draft-preview, but no MCP endpoint on this port.
|
|
854
|
+
const server = createServer({ adapters, preview: { enabled: true, secret } }, { preAuth: [previewStage] });
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
A stage receives the `SSRContext` — the request, the config, and the render singletons (`renderFn`,
|
|
858
|
+
`pluginManager`, `caches`) — and returns `true` when it has answered, `false` to fall through. Passing the stages
|
|
859
|
+
**is** the decision to mount them: there is no config flag mirroring it, and a server that never passes them
|
|
860
|
+
never loads them.
|
|
861
|
+
|
|
862
|
+
## Running it locally
|
|
863
|
+
|
|
864
|
+
The package ships a small harness in [`dev/`](./dev) — file-backed adapters over a sample space, three demo
|
|
865
|
+
plugins and a demo style document — so you can exercise SSR and RSC without standing up a platform:
|
|
866
|
+
|
|
867
|
+
```bash
|
|
868
|
+
yarn start # pages + RSC on :3002 against dev/sample
|
|
869
|
+
yarn start:dev # same, resolving every @plitzi/* workspace package from source
|
|
870
|
+
yarn start:watch # same as start, restarting on change
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
`SSR_ENABLED=0` and `RSC_ENABLED=0` switch the surfaces off individually; `LOG_REQUESTS=0` quiets the request log.
|
|
874
|
+
Writes land back in `dev/sample`, so `git restore dev/sample` resets a session.
|
|
875
|
+
|
|
876
|
+
`dev/` is not part of the published package and nothing in `src/` imports it — it consumes this package's public
|
|
877
|
+
API exactly as a consumer would.
|
|
878
|
+
|
|
705
879
|
## SSR-only mode
|
|
706
880
|
|
|
707
881
|
Set `ssrOnly: true` to serve raw server-rendered HTML without any client-side scripts. Useful for inspecting SSR output or building purely static pages:
|
|
708
882
|
|
|
709
883
|
```ts
|
|
710
|
-
|
|
884
|
+
createServer({
|
|
711
885
|
ssrOnly: true,
|
|
712
886
|
adapters: { ... }
|
|
713
887
|
});
|
|
@@ -724,7 +898,7 @@ import { statSync } from 'node:fs';
|
|
|
724
898
|
|
|
725
899
|
const assetVersion = String(statSync('./node_modules/@plitzi/plitzi-sdk/dist/plitzi-sdk.js').mtimeMs | 0);
|
|
726
900
|
|
|
727
|
-
|
|
901
|
+
createServer({
|
|
728
902
|
assetVersion,
|
|
729
903
|
adapters: { ... }
|
|
730
904
|
});
|
|
@@ -755,7 +929,7 @@ const templateFn: SSRTemplateFn = ({ html, offlineData, jsPath, cssPath, plugins
|
|
|
755
929
|
</html>
|
|
756
930
|
`;
|
|
757
931
|
|
|
758
|
-
|
|
932
|
+
createServer({ templateFn, adapters: { ... } });
|
|
759
933
|
```
|
|
760
934
|
|
|
761
935
|
The function is called once per render (cache misses only). The built-in `template.ejs` is used as fallback when `templateFn` is not set.
|
|
@@ -798,7 +972,7 @@ return {
|
|
|
798
972
|
Enable streaming to reduce TTFB by sending the `<head>` section to the browser before React finishes rendering:
|
|
799
973
|
|
|
800
974
|
```ts
|
|
801
|
-
|
|
975
|
+
createServer({
|
|
802
976
|
streaming: true,
|
|
803
977
|
adapters: { ... }
|
|
804
978
|
});
|
|
@@ -839,23 +1013,11 @@ When `devMode: true`, per-phase timing is instrumented on every render and repor
|
|
|
839
1013
|
|
|
840
1014
|
In production (`devMode: false`) timing instrumentation is skipped entirely — no `Server-Timing` header, no console output.
|
|
841
1015
|
|
|
842
|
-
##
|
|
843
|
-
|
|
844
|
-
This package ships an [Agent Skill](https://agentskills.io/) for `plitzi_render`, the MCP tool that renders a
|
|
845
|
-
self-contained UI widget from a batch of operations. The skill teaches an agent when to show a widget instead of
|
|
846
|
-
writing prose, the shape of a good call, the layout/theme traps that make a widget look wrong in a chat panel, and
|
|
847
|
-
how to iterate on a widget it already rendered.
|
|
848
|
-
|
|
849
|
-
It lives in [`skills/plitzi-render`](./skills/plitzi-render/SKILL.md) and is a plain `SKILL.md`, so it installs by
|
|
850
|
-
copying that folder into the skills directory of the agent you use (Claude Code, VS Code / Copilot, Codex, Gemini
|
|
851
|
-
CLI, Cline, Goose…):
|
|
852
|
-
|
|
853
|
-
```bash
|
|
854
|
-
cp -R node_modules/@plitzi/sdk-server/skills/plitzi-render ~/.claude/skills/
|
|
855
|
-
```
|
|
1016
|
+
## Examples
|
|
856
1017
|
|
|
857
|
-
|
|
858
|
-
|
|
1018
|
+
Runnable setups live in [`examples/`](../../examples): server-rendering a space, adding React Server Components,
|
|
1019
|
+
and mounting the MCP endpoint and draft preview alongside pages. Each one starts with `yarn start` and is a real
|
|
1020
|
+
package, not a snippet.
|
|
859
1021
|
|
|
860
1022
|
## Exported types
|
|
861
1023
|
|
|
@@ -885,6 +1047,8 @@ import type {
|
|
|
885
1047
|
PluginRegistry,
|
|
886
1048
|
CacheFilter,
|
|
887
1049
|
CacheManager,
|
|
888
|
-
JsonAdaptersConfig
|
|
1050
|
+
JsonAdaptersConfig,
|
|
1051
|
+
AuthAdapters,
|
|
1052
|
+
AuthAdaptersConfig
|
|
889
1053
|
} from '@plitzi/sdk-server';
|
|
890
1054
|
```
|