@clovnet/plugin-sdk 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clovnet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # @clovnet/plugin-sdk
2
+
3
+ The official SDK for building **CasinoWebEngine (CWE) plugins** — the complete, contract-only
4
+ surface a plugin may touch, plus a full in-memory test harness under `./testing`. You never see
5
+ (or need) the platform's core: no database, no message bus, no wallet internals.
6
+
7
+ ```bash
8
+ pnpm add @clovnet/plugin-sdk zod
9
+ ```
10
+
11
+ `zod` is a **peer dependency** — your plugin and the host share one instance.
12
+
13
+ ## Quickstart
14
+
15
+ ```ts
16
+ import { definePlugin, settingsField, type PluginManifest } from "@clovnet/plugin-sdk";
17
+ import { z } from "zod";
18
+
19
+ const manifest: PluginManifest = {
20
+ key: "my-plugin",
21
+ name: "My Plugin",
22
+ author: "me",
23
+ version: "0.1.0",
24
+ kind: "integration",
25
+ runtimeCompat: ">=0.1.0 <0.2.0",
26
+ permissions: {
27
+ commands: [], // command allowlist (fail-closed)
28
+ events: { subscribe: [], emit: ["plugin.my-plugin.something_happened"] },
29
+ },
30
+ settings: { fields: { greeting: settingsField.string({ label: "Greeting" }) } },
31
+ datasets: {
32
+ notes: { schema: z.object({ noteKey: z.string(), text: z.string() }), keyField: "noteKey" },
33
+ },
34
+ routes: [{ method: "GET", path: "/notes", surface: "player", handler: "list-notes" }],
35
+ };
36
+
37
+ export default definePlugin({
38
+ manifest,
39
+ handlers: {
40
+ routes: {
41
+ "list-notes": async (req, ctx) => {
42
+ const notes = ctx.datasets.collection("notes");
43
+ const page = await notes.query({ limit: 50 });
44
+ return { body: { notes: page.records, player: req.player!.id } };
45
+ },
46
+ },
47
+ },
48
+ });
49
+ ```
50
+
51
+ Everything a plugin can do flows through the `PluginContext` (`ctx`):
52
+
53
+ | Capability | Surface | Gate |
54
+ |---|---|---|
55
+ | change core state | `ctx.commands.execute` | manifest command allowlist |
56
+ | read core data | `ctx.data.query` | manifest `dataScopes` (PII is a separate grant) |
57
+ | own data | `ctx.datasets` | declared datasets; schema-validated, quota-capped |
58
+ | events out | `ctx.events.emit` | namespaced `plugin.<key>.*`, declared |
59
+ | events in | `ctx.events.on` | declared subscriptions |
60
+ | call external APIs | `ctx.http.fetch` | `network.allowedHosts`, HTTPS only, secrets injected host-side |
61
+ | background work | `ctx.tasks.start` | task handlers, checkpoint-resumable |
62
+ | config / credentials | `ctx.settings` / `ctx.secrets` | typed schema; secrets write-only, never logged |
63
+
64
+ Everything not declared in the manifest is denied — at runtime **and** in your tests.
65
+
66
+ ## Testing (`/testing`)
67
+
68
+ ```ts
69
+ import { createTestContext, validateManifest } from "@clovnet/plugin-sdk/testing";
70
+ import plugin from "./src/index.js";
71
+
72
+ const { ctx, harness } = createTestContext({
73
+ definition: plugin,
74
+ settings: { greeting: "hi" },
75
+ secrets: { apiKey: "test-key" },
76
+ commandResults: { "wallet.bet.place": { transactionId: "t1", legs: [] } },
77
+ httpMock: () => ({ status: 200, json: { ok: true } }),
78
+ });
79
+
80
+ await harness.invokeRoute("POST /notes", { player: { id: "p1" }, body: { text: "gg" } });
81
+ harness.commands; // every command the plugin dispatched
82
+ harness.events; // every event it emitted
83
+ harness.httpExchanges; // outbound calls — secret headers shown as <redacted:name>
84
+ await harness.runJob("cleanup");
85
+ await harness.runMigration("0.2.0");
86
+ validateManifest(plugin); // doctor-lite: handler refs, cron, datasets, surfaces
87
+ ```
88
+
89
+ The mock enforces exactly what the real host enforces (same error names/codes); the platform runs
90
+ a conformance suite against both on every change.
91
+
92
+ ## Versioning — the runtime contract
93
+
94
+ The SDK's **major.minor is the platform's `RUNTIME_API_VERSION`** (patch releases are free). Your
95
+ manifest's `runtimeCompat` range must include the SDK minor you compiled against:
96
+
97
+ ```
98
+ SDK 0.1.x → runtimeCompat: ">=0.1.0 <0.2.0"
99
+ ```
100
+
101
+ npm dist-tags mirror the platform's release channels: `latest` = stable, `next` = beta,
102
+ `dev` = dev.
103
+
104
+ ## Dev loop
105
+
106
+ Start from the **plugin template** (a working `player-favorites` example with tests), then:
107
+
108
+ ```bash
109
+ docker compose -f docker-compose.plugindev.yml up # local CWE runtime (from the platform repo)
110
+ npx @clovnet/plugin-cli dev # watch → build → hot-reload sideload
111
+ npx @clovnet/plugin-cli validate # full plugin doctor on the runtime
112
+ ```
113
+
114
+ MIT © CasinoWebEngine