@airdraft/plugin-schema-editor 0.1.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 +5 -0
- package/dist/FileSchemaAdapter.d.ts +12 -0
- package/dist/FileSchemaAdapter.d.ts.map +1 -0
- package/dist/FileSchemaAdapter.js +24 -0
- package/dist/FileSchemaAdapter.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/withSchemaEditor.d.ts +16 -0
- package/dist/withSchemaEditor.d.ts.map +1 -0
- package/dist/withSchemaEditor.js +213 -0
- package/dist/withSchemaEditor.js.map +1 -0
- package/package.json +40 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SchemaAdapter, CollectionMap } from '@airdraft/core';
|
|
2
|
+
/**
|
|
3
|
+
* Reads and writes collections from/to an `airdraft.schema.json` file on disk.
|
|
4
|
+
* All mutations are written immediately — no in-memory buffering.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FileSchemaAdapter implements SchemaAdapter {
|
|
7
|
+
private readonly absPath;
|
|
8
|
+
constructor(schemaPath: string);
|
|
9
|
+
read(): Promise<CollectionMap>;
|
|
10
|
+
write(collections: CollectionMap): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=FileSchemaAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSchemaAdapter.d.ts","sourceRoot":"","sources":["../src/FileSchemaAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AASlE;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;gBAEpB,UAAU,EAAE,MAAM;IAIxB,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IAM9B,KAAK,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAMvD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Reads and writes collections from/to an `airdraft.schema.json` file on disk.
|
|
5
|
+
* All mutations are written immediately — no in-memory buffering.
|
|
6
|
+
*/
|
|
7
|
+
export class FileSchemaAdapter {
|
|
8
|
+
absPath;
|
|
9
|
+
constructor(schemaPath) {
|
|
10
|
+
this.absPath = resolve(process.cwd(), schemaPath);
|
|
11
|
+
}
|
|
12
|
+
async read() {
|
|
13
|
+
const raw = await readFile(this.absPath, 'utf-8');
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
return parsed.collections ?? {};
|
|
16
|
+
}
|
|
17
|
+
async write(collections) {
|
|
18
|
+
const raw = await readFile(this.absPath, 'utf-8');
|
|
19
|
+
const current = JSON.parse(raw);
|
|
20
|
+
const updated = { ...current, collections };
|
|
21
|
+
await writeFile(this.absPath, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=FileSchemaAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSchemaAdapter.js","sourceRoot":"","sources":["../src/FileSchemaAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAU9B;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACX,OAAO,CAAQ;IAEhC,YAAY,UAAkB;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;QAC5C,OAAO,MAAM,CAAC,WAAW,IAAI,EAAE,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAA0B;QACpC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;QAC7C,MAAM,OAAO,GAAe,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAA;QACvD,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;IACjF,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Plugin, SchemaAdapter } from '@airdraft/core';
|
|
2
|
+
export interface WithSchemaEditorOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Admin key required for all schema mutation routes.
|
|
5
|
+
* When omitted and `NODE_ENV === 'development'`, routes are open without auth.
|
|
6
|
+
* In any other environment an adminKey is required.
|
|
7
|
+
*/
|
|
8
|
+
adminKey?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Override the schema adapter. Defaults to `FileSchemaAdapter` using
|
|
11
|
+
* `config.schemaPath` from the CmsConfig at request time.
|
|
12
|
+
*/
|
|
13
|
+
adapter?: SchemaAdapter;
|
|
14
|
+
}
|
|
15
|
+
export declare function withSchemaEditor(options?: WithSchemaEditorOptions): Plugin;
|
|
16
|
+
//# sourceMappingURL=withSchemaEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withSchemaEditor.d.ts","sourceRoot":"","sources":["../src/withSchemaEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EAId,MAAM,gBAAgB,CAAA;AAqBvB,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAwOD,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CAS9E"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { FileSchemaAdapter } from './FileSchemaAdapter.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Constants
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
/** Collection names that cannot be used — they conflict with built-in API routes. */
|
|
6
|
+
const RESERVED_SLUGS = new Set([
|
|
7
|
+
'schema',
|
|
8
|
+
'media',
|
|
9
|
+
'openapi',
|
|
10
|
+
'health',
|
|
11
|
+
'apply',
|
|
12
|
+
'collections',
|
|
13
|
+
]);
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
function json(data, status = 200) {
|
|
18
|
+
return new Response(JSON.stringify(data), {
|
|
19
|
+
status,
|
|
20
|
+
headers: { 'Content-Type': 'application/json' },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function checkAdminKey(req, adminKey) {
|
|
24
|
+
if (process.env.NODE_ENV === 'development' && adminKey === undefined)
|
|
25
|
+
return true;
|
|
26
|
+
if (!adminKey)
|
|
27
|
+
return false;
|
|
28
|
+
const provided = req.headers.get('x-admin-key');
|
|
29
|
+
return provided === adminKey;
|
|
30
|
+
}
|
|
31
|
+
/** Extract the last path segment after /schema/collections/ */
|
|
32
|
+
function extractCollectionName(url) {
|
|
33
|
+
// e.g. /api/cms/schema/collections/posts → 'posts'
|
|
34
|
+
const parts = url.pathname.split('/');
|
|
35
|
+
const collectionsIdx = parts.lastIndexOf('collections');
|
|
36
|
+
if (collectionsIdx === -1 || collectionsIdx === parts.length - 1)
|
|
37
|
+
return null;
|
|
38
|
+
return parts[collectionsIdx + 1] ?? null;
|
|
39
|
+
}
|
|
40
|
+
function resolveAdapter(pluginAdapter, config) {
|
|
41
|
+
if (pluginAdapter)
|
|
42
|
+
return pluginAdapter;
|
|
43
|
+
if (!config.schemaPath) {
|
|
44
|
+
throw new Error('[plugin-schema-editor] No schemaPath in CmsConfig and no adapter provided to withSchemaEditor().');
|
|
45
|
+
}
|
|
46
|
+
return new FileSchemaAdapter(config.schemaPath);
|
|
47
|
+
}
|
|
48
|
+
function makeRoutes(pluginAdapterRef, adminKey) {
|
|
49
|
+
async function requireAuth(req) {
|
|
50
|
+
if (!checkAdminKey(req, adminKey)) {
|
|
51
|
+
return json({ error: { code: 'UNAUTHORIZED', message: 'X-Admin-Key required.' } }, 401);
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
// ------------------------------------------------------------------
|
|
57
|
+
// GET /schema/collections — list all collections
|
|
58
|
+
// ------------------------------------------------------------------
|
|
59
|
+
'/schema/collections': async (req, ctx) => {
|
|
60
|
+
if (req.method !== 'GET') {
|
|
61
|
+
if (req.method === 'POST')
|
|
62
|
+
return handleCreateCollection(req, ctx);
|
|
63
|
+
return json({ error: { code: 'METHOD_NOT_ALLOWED', message: 'Method not allowed.' } }, 405);
|
|
64
|
+
}
|
|
65
|
+
const adapter = resolveAdapter(pluginAdapterRef.current, ctx.config);
|
|
66
|
+
const collections = await adapter.read();
|
|
67
|
+
return json({ data: collections });
|
|
68
|
+
},
|
|
69
|
+
// ------------------------------------------------------------------
|
|
70
|
+
// GET /schema/collections/:name — single collection
|
|
71
|
+
// PUT /schema/collections/:name — update
|
|
72
|
+
// DELETE /schema/collections/:name — delete
|
|
73
|
+
// ------------------------------------------------------------------
|
|
74
|
+
'/schema/collections/:name': async (req, ctx) => {
|
|
75
|
+
const url = new URL(req.url);
|
|
76
|
+
const name = extractCollectionName(url);
|
|
77
|
+
if (!name) {
|
|
78
|
+
return json({ error: { code: 'BAD_REQUEST', message: 'Collection name required.' } }, 400);
|
|
79
|
+
}
|
|
80
|
+
const adapter = resolveAdapter(pluginAdapterRef.current, ctx.config);
|
|
81
|
+
if (req.method === 'GET') {
|
|
82
|
+
const collections = await adapter.read();
|
|
83
|
+
const col = collections[name];
|
|
84
|
+
if (!col)
|
|
85
|
+
return json({ error: { code: 'NOT_FOUND', message: `Collection '${name}' not found.` } }, 404);
|
|
86
|
+
return json({ data: col });
|
|
87
|
+
}
|
|
88
|
+
if (req.method === 'PUT') {
|
|
89
|
+
const authErr = await requireAuth(req);
|
|
90
|
+
if (authErr)
|
|
91
|
+
return authErr;
|
|
92
|
+
return handleUpdateCollection(req, ctx, name, adapter);
|
|
93
|
+
}
|
|
94
|
+
if (req.method === 'DELETE') {
|
|
95
|
+
const authErr = await requireAuth(req);
|
|
96
|
+
if (authErr)
|
|
97
|
+
return authErr;
|
|
98
|
+
return handleDeleteCollection(req, ctx, name, adapter);
|
|
99
|
+
}
|
|
100
|
+
return json({ error: { code: 'METHOD_NOT_ALLOWED', message: 'Method not allowed.' } }, 405);
|
|
101
|
+
},
|
|
102
|
+
// ------------------------------------------------------------------
|
|
103
|
+
// POST /schema/apply — flush schema to disk (no-op for FileSchemaAdapter,
|
|
104
|
+
// meaningful for CloudSchemaAdapter)
|
|
105
|
+
// ------------------------------------------------------------------
|
|
106
|
+
'/schema/apply': async (req, ctx) => {
|
|
107
|
+
if (req.method !== 'POST') {
|
|
108
|
+
return json({ error: { code: 'METHOD_NOT_ALLOWED', message: 'Method not allowed.' } }, 405);
|
|
109
|
+
}
|
|
110
|
+
const authErr = await requireAuth(req);
|
|
111
|
+
if (authErr)
|
|
112
|
+
return authErr;
|
|
113
|
+
const adapter = resolveAdapter(pluginAdapterRef.current, ctx.config);
|
|
114
|
+
const collections = await adapter.read();
|
|
115
|
+
await adapter.write(collections);
|
|
116
|
+
return json({ data: { ok: true } });
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
// ---- sub-handlers --------------------------------------------------------
|
|
120
|
+
async function handleCreateCollection(req, ctx) {
|
|
121
|
+
const authErr = await requireAuth(req);
|
|
122
|
+
if (authErr)
|
|
123
|
+
return authErr;
|
|
124
|
+
let body;
|
|
125
|
+
try {
|
|
126
|
+
body = await req.json();
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return json({ error: { code: 'BAD_REQUEST', message: 'Invalid JSON body.' } }, 400);
|
|
130
|
+
}
|
|
131
|
+
const { name, config: colConfig } = body;
|
|
132
|
+
if (!name || typeof name !== 'string') {
|
|
133
|
+
return json({ error: { code: 'BAD_REQUEST', message: '"name" is required.' } }, 400);
|
|
134
|
+
}
|
|
135
|
+
const slug = name.trim().toLowerCase();
|
|
136
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(slug)) {
|
|
137
|
+
return json({
|
|
138
|
+
error: { code: 'BAD_REQUEST', message: 'Collection name must start with a letter and contain only a-z, 0-9, _, -.' },
|
|
139
|
+
}, 400);
|
|
140
|
+
}
|
|
141
|
+
if (RESERVED_SLUGS.has(slug)) {
|
|
142
|
+
return json({
|
|
143
|
+
error: { code: 'CONFLICT', message: `'${slug}' is a reserved name and cannot be used.` },
|
|
144
|
+
}, 409);
|
|
145
|
+
}
|
|
146
|
+
const adapter = resolveAdapter(pluginAdapterRef.current, ctx.config);
|
|
147
|
+
const collections = await adapter.read();
|
|
148
|
+
if (collections[slug]) {
|
|
149
|
+
return json({ error: { code: 'CONFLICT', message: `Collection '${slug}' already exists.` } }, 409);
|
|
150
|
+
}
|
|
151
|
+
collections[slug] = colConfig;
|
|
152
|
+
await adapter.write(collections);
|
|
153
|
+
return json({ data: { name: slug, config: colConfig } }, 201);
|
|
154
|
+
}
|
|
155
|
+
async function handleUpdateCollection(req, _ctx, name, adapter) {
|
|
156
|
+
let body;
|
|
157
|
+
try {
|
|
158
|
+
body = await req.json();
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return json({ error: { code: 'BAD_REQUEST', message: 'Invalid JSON body.' } }, 400);
|
|
162
|
+
}
|
|
163
|
+
const collections = await adapter.read();
|
|
164
|
+
if (!collections[name]) {
|
|
165
|
+
return json({ error: { code: 'NOT_FOUND', message: `Collection '${name}' not found.` } }, 404);
|
|
166
|
+
}
|
|
167
|
+
// Merge — path and format are locked if content exists (warning only in v1)
|
|
168
|
+
const updated = { ...collections[name], ...body };
|
|
169
|
+
collections[name] = updated;
|
|
170
|
+
await adapter.write(collections);
|
|
171
|
+
return json({ data: { name, config: updated } });
|
|
172
|
+
}
|
|
173
|
+
async function handleDeleteCollection(req, ctx, name, adapter) {
|
|
174
|
+
const url = new URL(req.url);
|
|
175
|
+
// Two-step deletion: requires ?confirm=<collection-name> to purge schema entry
|
|
176
|
+
const confirm = url.searchParams.get('confirm');
|
|
177
|
+
if (confirm !== name) {
|
|
178
|
+
return json({
|
|
179
|
+
error: {
|
|
180
|
+
code: 'CONFIRMATION_REQUIRED',
|
|
181
|
+
message: `Pass ?confirm=${name} to confirm deletion of collection '${name}'.`,
|
|
182
|
+
},
|
|
183
|
+
}, 409);
|
|
184
|
+
}
|
|
185
|
+
const collections = await adapter.read();
|
|
186
|
+
if (!collections[name]) {
|
|
187
|
+
return json({ error: { code: 'NOT_FOUND', message: `Collection '${name}' not found.` } }, 404);
|
|
188
|
+
}
|
|
189
|
+
// Check for existing content entries
|
|
190
|
+
const col = collections[name];
|
|
191
|
+
const glob = col.path.replace('{slug}', '*');
|
|
192
|
+
const existingFiles = await ctx.adapter.list(glob);
|
|
193
|
+
if (existingFiles.length > 0) {
|
|
194
|
+
// Schema removed; content files retained. GUI should warn separately.
|
|
195
|
+
}
|
|
196
|
+
delete collections[name];
|
|
197
|
+
await adapter.write(collections);
|
|
198
|
+
return new Response(null, { status: 204 });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Plugin factory
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
export function withSchemaEditor(options = {}) {
|
|
205
|
+
const pluginAdapterRef = {
|
|
206
|
+
current: options.adapter ?? null,
|
|
207
|
+
};
|
|
208
|
+
return {
|
|
209
|
+
name: 'schema-editor',
|
|
210
|
+
routes: makeRoutes(pluginAdapterRef, options.adminKey),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=withSchemaEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withSchemaEditor.js","sourceRoot":"","sources":["../src/withSchemaEditor.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@airdraft/plugin-schema-editor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Airdraft schema editor plugin — API routes and file adapter for GUI-driven collection management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md", "CHANGELOG.md"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"release": "standard-version",
|
|
24
|
+
"release:patch": "standard-version --release-as patch",
|
|
25
|
+
"release:minor": "standard-version --release-as minor",
|
|
26
|
+
"release:major": "standard-version --release-as major"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": { "access": "public" },
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.0.0",
|
|
32
|
+
"standard-version": "^9.5.0",
|
|
33
|
+
"typescript": "^5.4.0",
|
|
34
|
+
"vitest": "^1.5.0"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@airdraft/core": "*"
|
|
38
|
+
},
|
|
39
|
+
"engines": { "node": ">=18.0.0" }
|
|
40
|
+
}
|