feat: standalone module-build readiness for the public @ekklesia packages (ADR 0053)
CI / verify (pull_request) Successful in 1m2s
CI / infrastructure-smoke (pull_request) Successful in 28s
CI / migration-smoke (pull_request) Successful in 1m52s
CI / standalone-module (pull_request) Successful in 26s
CI / image-build (pull_request) Successful in 30s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m42s

Makes the public module-development package set usable from a module
repository outside the monorepo. Nothing is published.

- Curated @ekklesia/module-sdk: an explicit author API, no contracts
  barrel, no identity/authorization internals, no Drizzle and no legacy
  ModuleDatabase type. defineModuleRuntime returns the SDK's own named
  interfaces so a module's emitted declarations never reach into
  @ekklesia/contracts. defineModuleSchema is gone; createModuleTable and
  defineModuleSchemaMetadata live in @ekklesia/module-database.
- Drizzle: no longer a dependency of module-sdk or contracts. Core keeps
  the legacy Drizzle schema validator (moved to core/src/modules) and
  its legacy runtime support; drizzle-orm is an optional peer only.
- React is a peer (plus devDependency) of @ekklesia/ui; the boundary
  checker allows exactly that consumer-selected peer.
- @ekklesia/typescript-config is publishable; module-ui-host is private.
  Every public package carries "ekklesia.distribution":
  "module-development" and no monorepo-root prepack.
- module-pack reads the Node.js range from the module's own engines.node
  and recognizes Ekklesia packages by name plus that marker, so
  registry-installed packages are incorporated, SDK-compatibility
  checked, and never credited as third-party.
- scripts/pack-public-packages.ts (pnpm packages:pack) rebuilds, packs
  and inspects the nine public tarballs; scripts/test-standalone-module.sh
  (pnpm test:standalone-module, new CI job) installs them into a fixture
  module outside the repository and proves it typechecks, builds,
  packages, and verifies.
- Public-package boundary tests and module-development docs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ekklesia
2026-10-08 07:28:54 -05:00
co-authored by Claude Opus 5.5
parent 9426c83109
commit 89d5d0f2da
63 changed files with 2320 additions and 237 deletions
+102 -3
View File
@@ -1,3 +1,102 @@
export * from "@ekklesia/contracts";
export * from "./define-module-runtime.js";
export * from "./define-module-schema.js";
/**
* `@ekklesia/module-sdk`: the supported module-author API (ADR 0053).
*
* Every export is chosen. The platform's internal contracts (identity parsing, authorization,
* lifecycle, manifest internals beyond what a module validates about itself) are not re-exported,
* and neither is the legacy Drizzle database facade. A module that uses a database declares
* `database: { abi: 1 }` and gets its database types and helpers from `@ekklesia/module-database`.
* Nothing here loads or requires Drizzle.
*/
export type {
Awaitable,
CapabilityId,
CapabilityRegistrar,
CapabilityResolver,
ModuleId,
RegisteredCapability,
} from "@ekklesia/contracts";
// HTTP routes (ADR 0015, ADR 0042).
// Who is calling (ADR 0013, ADR 0036): only what a route handler receives and branches on.
// Configuration (ADR 0029).
// Object storage (ADR 0030, ADR 0031).
// Realtime (ADR 0032).
// The module's own static artifacts, for a module's tests to validate them the way Core does.
export {
ANONYMOUS_PRINCIPAL,
type EkklesiaAnonymousPrincipal,
type EkklesiaAuthenticatedPrincipal,
type EkklesiaDeviceId,
type EkklesiaDevicePrincipal,
type EkklesiaPrincipal,
type EkklesiaUserId,
EMPTY_MODULE_CONFIGURATION,
EMPTY_MODULE_STORAGE,
isAnonymousPrincipal,
isAuthenticatedPrincipal,
isDevicePrincipal,
isModuleHttpMethod,
isModuleRouteBodyMode,
isValidModuleStorageKey,
isValidModuleStorageReadUrlFilename,
MODULE_HTTP_BODY_MODES,
MODULE_HTTP_METHODS,
MODULE_REALTIME_CHANNEL_MAX_LENGTH,
MODULE_REALTIME_ERROR_CODES,
MODULE_REALTIME_MAX_CHANNELS_PER_MODULE,
MODULE_REALTIME_MAX_PAYLOAD_BYTES,
MODULE_REALTIME_MAX_SUBSCRIBERS_PER_CHANNEL,
MODULE_ROUTE_ABSOLUTE_MAX_BODY_BYTES,
MODULE_ROUTE_MAX_BODY_BYTES_CEILING,
MODULE_ROUTE_STREAMED_MAX_BODY_BYTES_CEILING,
MODULE_STORAGE_ERROR_CODES,
MODULE_STORAGE_KEY_MAX_BYTES,
MODULE_STORAGE_READ_URL_DEFAULT_SECONDS,
MODULE_STORAGE_READ_URL_FILENAME_MAX_LENGTH,
MODULE_STORAGE_READ_URL_MAX_SECONDS,
MODULE_STORAGE_READ_URL_MIN_SECONDS,
type ModuleConfiguration,
type ModuleConfigurationValue,
type ModuleHttpMethod,
type ModuleManifest,
type ModuleRealtimeChannel,
type ModuleRealtimeChannelDefinitionInput,
type ModuleRealtimeChannelRegistrar,
ModuleRealtimeError,
type ModuleRealtimeErrorCode,
type ModuleRealtimeJsonPrimitive,
type ModuleRealtimeJsonValue,
type ModuleRealtimePublisher,
type ModuleRouteBodyMode,
type ModuleRoutePath,
type ModuleStorage,
type ModuleStorageBody,
type ModuleStorageBucket,
ModuleStorageError,
type ModuleStorageErrorCode,
type ModuleStorageListing,
type ModuleStorageListOptions,
type ModuleStorageObject,
type ModuleStorageObjectMetadata,
type ModuleStoragePutOptions,
type ModuleStorageReadUrl,
type ModuleStorageReadUrlOptions,
parseDrizzleMigrationJournal,
parseModuleManifest,
parseModuleMigrationPolicy,
} from "@ekklesia/contracts";
export {
defineModuleRuntime,
type ModuleRegistrationContext,
type ModuleRuntimeContext,
type ModuleRuntimeDefinition,
type ModuleRuntimeDefinitionWithDatabase,
type ModuleRuntimeDefinitionWithoutDatabase,
type ModuleRuntimeServices,
} from "./define-module-runtime.js";
export type {
ModuleHttpRouteRegistrar,
ModuleRouteDefinitionInput,
ModuleRouteHandler,
ModuleRouteHandlerContext,
} from "./http.js";