feat: add module contracts and discovery
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Ekklesia module template
|
||||
|
||||
This is the smallest supported backend-only Ekklesia module. It proves the manifest, package,
|
||||
Module SDK, discovery, capability, permission, and logical storage-bucket contracts without
|
||||
pretending that the later runtime, API, or Drizzle registration layers already exist.
|
||||
|
||||
To create a module inside this repository:
|
||||
|
||||
1. Copy this directory to `modules/<module-id>`.
|
||||
2. Rename the package in `package.json` and remove `private` when it is ready for publication.
|
||||
3. Update the ID, name, version, namespaces, compatibility ranges, and bucket requests in
|
||||
`ekklesia.module.json`.
|
||||
4. Replace the example server entrypoint with backend behavior only.
|
||||
5. Run `pnpm install`, `pnpm modules:validate`, and `pnpm verify` from the repository root.
|
||||
|
||||
Do not add UI components, styles, renderers, navigation, or layouts. Those belong to surfaces.
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"manifestVersion": 1,
|
||||
"id": "example",
|
||||
"name": "Example Module",
|
||||
"description": "A minimal backend-only Ekklesia module template.",
|
||||
"version": "0.1.0",
|
||||
"compatibility": {
|
||||
"platform": "^0.1.0",
|
||||
"moduleSdk": "^0.1.0"
|
||||
},
|
||||
"capabilities": ["example.records"],
|
||||
"permissions": ["example.records.read"],
|
||||
"storage": {
|
||||
"buckets": [
|
||||
{
|
||||
"id": "records",
|
||||
"description": "Private objects owned by this example module."
|
||||
}
|
||||
]
|
||||
},
|
||||
"entrypoints": {
|
||||
"server": "./src/server/index.ts"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@ekklesia/module-template",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"ekklesia.module.json"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/server/index.d.ts",
|
||||
"import": "./dist/server/index.js"
|
||||
},
|
||||
"./server": {
|
||||
"types": "./dist/server/index.d.ts",
|
||||
"import": "./dist/server/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --project tsconfig.build.json",
|
||||
"lint": "biome lint .",
|
||||
"prepack": "pnpm --workspace-root exec turbo run build --filter=@ekklesia/module-template",
|
||||
"test": "vitest run",
|
||||
"typecheck": "tsc --noEmit --project tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ekklesia/module-sdk": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.5.3",
|
||||
"@types/node": "24.13.3",
|
||||
"@ekklesia/typescript-config": "workspace:*",
|
||||
"typescript": "7.0.2",
|
||||
"vitest": "4.1.10"
|
||||
},
|
||||
"ekklesia": {
|
||||
"layer": "module"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface ExampleModuleServer {
|
||||
readonly id: "example";
|
||||
}
|
||||
|
||||
export const exampleModuleServer: ExampleModuleServer = {
|
||||
id: "example",
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { defineModule, type ModuleManifestInput } from "@ekklesia/module-sdk";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("module template", () => {
|
||||
it("ships a valid backend-only manifest", async () => {
|
||||
const manifestUrl = new URL("../ekklesia.module.json", import.meta.url);
|
||||
const manifestInput = JSON.parse(await readFile(manifestUrl, "utf8")) as ModuleManifestInput;
|
||||
const manifest = defineModule(manifestInput);
|
||||
|
||||
expect(manifest.id).toBe("example");
|
||||
expect(manifest.storage.buckets.map((bucket) => bucket.id)).toEqual(["records"]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"noEmit": false,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/**/*.test.ts", "tests"]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@ekklesia/typescript-config/node.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"types": ["node", "vitest/globals"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "tests/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user