@crowi/plugin-api 0.1.0-alpha.2 → 1.0.0-alpha.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/README.md +117 -0
- package/dist/index.d.mts +427 -90
- package/dist/index.d.ts +427 -90
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -3
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# @crowi/plugin-api
|
|
2
|
+
|
|
3
|
+
Type-only contract for Crowi 2.0 plugins. A Crowi plugin is an ordinary
|
|
4
|
+
npm package that default-exports an object satisfying the `CrowiPlugin`
|
|
5
|
+
type from this package; the runtime loads it via `await
|
|
6
|
+
import('<plugin-name>')` at boot and calls each `register*` callback it
|
|
7
|
+
implements. See
|
|
8
|
+
[RFC-0001](https://github.com/crowi/crowi/blob/main/docs/rfcs/0001-plugin-architecture.md)
|
|
9
|
+
for the full design and the
|
|
10
|
+
[plugin development guide](https://crowi.wiki/docs/plugins/developing)
|
|
11
|
+
for a walkthrough.
|
|
12
|
+
|
|
13
|
+
> **Alpha notice**: Crowi v2 is under active alpha development and this
|
|
14
|
+
> package is at `0.x`. The API stability guarantee (working across every
|
|
15
|
+
> v2 minor) takes effect once it reaches `2.x`; the contract may still
|
|
16
|
+
> change during the alpha period.
|
|
17
|
+
|
|
18
|
+
## Minimal plugin
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import type { CrowiPlugin } from '@crowi/plugin-api';
|
|
22
|
+
|
|
23
|
+
const myPlugin: CrowiPlugin = {
|
|
24
|
+
name: '@example/crowi-plugin-mystorage',
|
|
25
|
+
version: '0.1.0',
|
|
26
|
+
|
|
27
|
+
registerStorage: (registry, ctx) => {
|
|
28
|
+
registry.register('mystorage', {
|
|
29
|
+
put: async (key, body, meta) => ({ key }),
|
|
30
|
+
get: async (key) => { throw new Error('not implemented'); },
|
|
31
|
+
delete: async (key) => {},
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default myPlugin;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`name` must match the npm package name — it doubles as the namespace
|
|
40
|
+
prefix for this plugin's config rows (`plugin:<name>:*`) and per-page
|
|
41
|
+
metadata (`page.metadata['<name>']`).
|
|
42
|
+
|
|
43
|
+
## Authoring a config schema
|
|
44
|
+
|
|
45
|
+
A plugin declares its configurable values with `configSchema`, a Zod
|
|
46
|
+
object schema. The admin UI at `/admin/plugins` walks this schema to
|
|
47
|
+
auto-generate a config form, encrypt `@sensitive`-marked fields at
|
|
48
|
+
rest, and render `@action`-marked fields with a button.
|
|
49
|
+
|
|
50
|
+
This package's `peerDependencies` declares `zod: "^4"` — that is the
|
|
51
|
+
correct **npm package** to install, because the zod v4 package is the
|
|
52
|
+
one that ships a `zod/v3` compat subpath. What `peerDependencies`
|
|
53
|
+
cannot express is *which entry point* to import from, and that part
|
|
54
|
+
matters:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
// Correct — the v3 compat shim that the v4 package ships.
|
|
58
|
+
import { z } from 'zod/v3';
|
|
59
|
+
|
|
60
|
+
// Wrong — compiles and type-checks, but fails at plugin boot.
|
|
61
|
+
import { z } from 'zod';
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`CrowiPlugin.configSchema` is typed against `zod/v3`'s `z.ZodObject`,
|
|
65
|
+
and every runtime helper that reads a plugin's config schema
|
|
66
|
+
(`@sensitive` / `@action` marker detection, the admin form field
|
|
67
|
+
serializer, `listSensitiveKeys()`) introspects the `zod/v3` internal
|
|
68
|
+
shape (`_def.typeName`, `_def.values`, `.description`, …). A schema
|
|
69
|
+
built from the top-level `zod` (v4) API has a different internal shape
|
|
70
|
+
and none of that introspection can see through it — most importantly,
|
|
71
|
+
`@sensitive` fields stop being detected, and the value they guard would
|
|
72
|
+
be written to and read from storage as plaintext.
|
|
73
|
+
|
|
74
|
+
To turn that silent failure mode into a loud one, `PluginManager`
|
|
75
|
+
validates every plugin's `configSchema` at boot and throws if it wasn't
|
|
76
|
+
built from `zod/v3`:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Plugin '<name>' declares configSchema built with the top-level 'zod' (v4) API.
|
|
80
|
+
Import from 'zod/v3' instead — @crowi/plugin-api's config-schema introspection
|
|
81
|
+
requires the zod v3 compat shape (see @crowi/plugin-api README).
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If you hit this error, the fix is always the same: change the `zod`
|
|
85
|
+
import for the file that builds `configSchema` (and `pageMetadataSchema`,
|
|
86
|
+
if you use it) to `import { z } from 'zod/v3'`. No other code needs to
|
|
87
|
+
change — `zod/v3`'s `z.object()` / `z.string()` / etc. API surface is
|
|
88
|
+
what every first-party Crowi plugin already uses.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { z } from 'zod/v3';
|
|
92
|
+
import type { CrowiPlugin } from '@crowi/plugin-api';
|
|
93
|
+
|
|
94
|
+
const myPlugin: CrowiPlugin = {
|
|
95
|
+
name: '@example/crowi-plugin-mystorage',
|
|
96
|
+
version: '0.1.0',
|
|
97
|
+
|
|
98
|
+
configSchema: z.object({
|
|
99
|
+
endpoint: z.string().url().describe('Storage endpoint URL'),
|
|
100
|
+
accessKey: z.string().describe('@sensitive Access key'),
|
|
101
|
+
}),
|
|
102
|
+
|
|
103
|
+
registerStorage: (registry, ctx) => {
|
|
104
|
+
const config = ctx.config<{ endpoint: string; accessKey: string }>();
|
|
105
|
+
// ... build the driver using config
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export default myPlugin;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## See also
|
|
113
|
+
|
|
114
|
+
- [Plugin development guide](https://crowi.wiki/docs/plugins/developing) —
|
|
115
|
+
the full walkthrough (markers, `adminPlacement`, `configI18n`,
|
|
116
|
+
`PluginContext`, dependency plugins, renderer plugins).
|
|
117
|
+
- [RFC-0001: Plugin architecture](https://github.com/crowi/crowi/blob/main/docs/rfcs/0001-plugin-architecture.md)
|