emdash 0.9.0 → 0.10.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/dist/{adapters-DoNJiveC.d.mts → adapters-BktHA7EO.d.mts} +1 -1
- package/dist/{adapters-DoNJiveC.d.mts.map → adapters-BktHA7EO.d.mts.map} +1 -1
- package/dist/{apply-BzltprvY.mjs → apply-UsrFuO7l.mjs} +156 -254
- package/dist/apply-UsrFuO7l.mjs.map +1 -0
- package/dist/astro/index.d.mts +6 -6
- package/dist/astro/index.mjs +10 -2
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/auth.mjs +5 -5
- package/dist/astro/middleware/redirect.mjs +5 -5
- package/dist/astro/middleware/request-context.mjs +4 -4
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.mjs +35 -34
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +8 -9
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{base64-BRICGH2l.mjs → base64-MBPo9ozB.mjs} +1 -1
- package/dist/{base64-BRICGH2l.mjs.map → base64-MBPo9ozB.mjs.map} +1 -1
- package/dist/{byline-BSaNL1w7.mjs → byline-C3vnhIpU.mjs} +4 -4
- package/dist/{byline-BSaNL1w7.mjs.map → byline-C3vnhIpU.mjs.map} +1 -1
- package/dist/{bylines-CvJ3PYz2.mjs → bylines-esI7ioa9.mjs} +5 -5
- package/dist/{bylines-CvJ3PYz2.mjs.map → bylines-esI7ioa9.mjs.map} +1 -1
- package/dist/{cache-C6N_hhN7.mjs → cache-fTzxgMFJ.mjs} +3 -3
- package/dist/{cache-C6N_hhN7.mjs.map → cache-fTzxgMFJ.mjs.map} +1 -1
- package/dist/{chunks-NBQVDOci.mjs → chunks-Da2-b-oA.mjs} +2 -2
- package/dist/{chunks-NBQVDOci.mjs.map → chunks-Da2-b-oA.mjs.map} +1 -1
- package/dist/cli/index.mjs +251 -79
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/{config-BI0V3ICQ.mjs → config-CVssduLe.mjs} +1 -1
- package/dist/{config-BI0V3ICQ.mjs.map → config-CVssduLe.mjs.map} +1 -1
- package/dist/{content-8lOYF0pr.mjs → content-C7G4QXkK.mjs} +14 -3
- package/dist/content-C7G4QXkK.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-WRezodiz.mjs → db-errors-B7P2pSCn.mjs} +1 -1
- package/dist/{db-errors-WRezodiz.mjs.map → db-errors-B7P2pSCn.mjs.map} +1 -1
- package/dist/{default-D8ksjWhO.mjs → default-pHuz9WF6.mjs} +1 -1
- package/dist/{default-D8ksjWhO.mjs.map → default-pHuz9WF6.mjs.map} +1 -1
- package/dist/{error-D_-tqP-I.mjs → error-DqnRMM5z.mjs} +1 -1
- package/dist/{error-D_-tqP-I.mjs.map → error-DqnRMM5z.mjs.map} +1 -1
- package/dist/{index-BFRaVcD6.d.mts → index-DjPMOfO0.d.mts} +82 -67
- package/dist/index-DjPMOfO0.d.mts.map +1 -0
- package/dist/index.d.mts +10 -10
- package/dist/index.mjs +28 -27
- package/dist/{load-DDqMMvZL.mjs → load-sXRuM7Us.mjs} +2 -2
- package/dist/{load-DDqMMvZL.mjs.map → load-sXRuM7Us.mjs.map} +1 -1
- package/dist/{loader-CKLbBnhK.mjs → loader-Bx2_9-5e.mjs} +31 -6
- package/dist/loader-Bx2_9-5e.mjs.map +1 -0
- package/dist/{manifest-schema-DqWNC3lM.mjs → manifest-schema-CXAbd1vH.mjs} +1 -1
- package/dist/{manifest-schema-DqWNC3lM.mjs.map → manifest-schema-CXAbd1vH.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +3 -3
- package/dist/{media-BW32b4gi.mjs → media-D8FbNsl0.mjs} +2 -2
- package/dist/{media-BW32b4gi.mjs.map → media-D8FbNsl0.mjs.map} +1 -1
- package/dist/{mode-ier8jbBk.mjs → mode-YhqNVef_.mjs} +1 -1
- package/dist/{mode-ier8jbBk.mjs.map → mode-YhqNVef_.mjs.map} +1 -1
- package/dist/{options-BVp3UsTS.mjs → options-nPxWnrya.mjs} +1 -1
- package/dist/{options-BVp3UsTS.mjs.map → options-nPxWnrya.mjs.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{patterns-CrCYkMBb.mjs → patterns-DsUZ4uxI.mjs} +1 -1
- package/dist/{patterns-CrCYkMBb.mjs.map → patterns-DsUZ4uxI.mjs.map} +1 -1
- package/dist/{placeholder-BE4o_2dc.d.mts → placeholder-CDPtkelt.d.mts} +1 -1
- package/dist/{placeholder-BE4o_2dc.d.mts.map → placeholder-CDPtkelt.d.mts.map} +1 -1
- package/dist/{placeholder-CIJejMlK.mjs → placeholder-Ci0RLeCk.mjs} +1 -1
- package/dist/{placeholder-CIJejMlK.mjs.map → placeholder-Ci0RLeCk.mjs.map} +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{public-url-DByxYjUw.mjs → public-url-B1AxbbbQ.mjs} +1 -1
- package/dist/{public-url-DByxYjUw.mjs.map → public-url-B1AxbbbQ.mjs.map} +1 -1
- package/dist/{query-Cg9ZKRQ0.mjs → query-Bo-msrmu.mjs} +13 -13
- package/dist/{query-Cg9ZKRQ0.mjs.map → query-Bo-msrmu.mjs.map} +1 -1
- package/dist/{redirect-BhUBKRc1.mjs → redirect-C5H7VGIX.mjs} +3 -3
- package/dist/{redirect-BhUBKRc1.mjs.map → redirect-C5H7VGIX.mjs.map} +1 -1
- package/dist/{registry-Dw70ChxB.mjs → registry-Beb7wxFc.mjs} +5 -5
- package/dist/{registry-Dw70ChxB.mjs.map → registry-Beb7wxFc.mjs.map} +1 -1
- package/dist/{request-cache-B-bmkipQ.mjs → request-cache-C-tIpYIw.mjs} +1 -1
- package/dist/{request-cache-B-bmkipQ.mjs.map → request-cache-C-tIpYIw.mjs.map} +1 -1
- package/dist/{runner-Bnoj7vjK.d.mts → runner-Clwe4Mme.d.mts} +2 -2
- package/dist/{runner-Bnoj7vjK.d.mts.map → runner-Clwe4Mme.d.mts.map} +1 -1
- package/dist/{runner-C7ADox5q.mjs → runner-DMnlIkh4.mjs} +433 -138
- package/dist/runner-DMnlIkh4.mjs.map +1 -0
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +3 -3
- package/dist/{search-dOGEccMa.mjs → search-DkN-BqsS.mjs} +164 -92
- package/dist/search-DkN-BqsS.mjs.map +1 -0
- package/dist/{secrets-CW3reAnU.mjs → secrets-CZ8rxLX3.mjs} +3 -3
- package/dist/{secrets-CW3reAnU.mjs.map → secrets-CZ8rxLX3.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +15 -14
- package/dist/seo/index.d.mts +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/taxonomies-CTtewrSQ.mjs +407 -0
- package/dist/taxonomies-CTtewrSQ.mjs.map +1 -0
- package/dist/taxonomy-DSxx2K2L.mjs +218 -0
- package/dist/taxonomy-DSxx2K2L.mjs.map +1 -0
- package/dist/{tokens-D7zMmWi2.mjs → tokens-CyRDPVW2.mjs} +2 -2
- package/dist/{tokens-D7zMmWi2.mjs.map → tokens-CyRDPVW2.mjs.map} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs → transaction-D44LBXvU.mjs} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs.map → transaction-D44LBXvU.mjs.map} +1 -1
- package/dist/{transport-DNEfeMaU.d.mts → transport-DX_5rpsq.d.mts} +1 -1
- package/dist/{transport-DNEfeMaU.d.mts.map → transport-DX_5rpsq.d.mts.map} +1 -1
- package/dist/{transport-BeMCmin1.mjs → transport-xpzIjCIB.mjs} +1 -1
- package/dist/{transport-BeMCmin1.mjs.map → transport-xpzIjCIB.mjs.map} +1 -1
- package/dist/{types-CRxNbK-Z.mjs → types-BIgulNsW.mjs} +2 -2
- package/dist/{types-CRxNbK-Z.mjs.map → types-BIgulNsW.mjs.map} +1 -1
- package/dist/{types-CJsYGpco.d.mts → types-B_CXXnzh.d.mts} +1 -1
- package/dist/{types-CJsYGpco.d.mts.map → types-B_CXXnzh.d.mts.map} +1 -1
- package/dist/{types-M78DQ1lx.d.mts → types-C-aFbqmA.d.mts} +1 -1
- package/dist/{types-M78DQ1lx.d.mts.map → types-C-aFbqmA.d.mts.map} +1 -1
- package/dist/{types-4fVtCIm0.mjs → types-CoO6mpV3.mjs} +1 -1
- package/dist/{types-4fVtCIm0.mjs.map → types-CoO6mpV3.mjs.map} +1 -1
- package/dist/{types-BuBIptGk.d.mts → types-D19uBYWn.d.mts} +149 -4
- package/dist/types-D19uBYWn.d.mts.map +1 -0
- package/dist/{types-BSyXeCFW.d.mts → types-Dl1fgFjn.d.mts} +1 -1
- package/dist/{types-BSyXeCFW.d.mts.map → types-Dl1fgFjn.d.mts.map} +1 -1
- package/dist/{types-CrtWgIvl.d.mts → types-Dtx1mSMX.d.mts} +9 -1
- package/dist/types-Dtx1mSMX.d.mts.map +1 -0
- package/dist/{types-CIOg5AR8.mjs → types-Eg829jj9.mjs} +1 -1
- package/dist/{types-CIOg5AR8.mjs.map → types-Eg829jj9.mjs.map} +1 -1
- package/dist/{types-CDbKp7ND.mjs → types-K-EkEQCI.mjs} +1 -1
- package/dist/{types-CDbKp7ND.mjs.map → types-K-EkEQCI.mjs.map} +1 -1
- package/dist/{validate-Baqf0slj.mjs → validate-CBIbxM3L.mjs} +14 -10
- package/dist/validate-CBIbxM3L.mjs.map +1 -0
- package/dist/{validate-BfQh_C_y.d.mts → validate-DHGwADqO.d.mts} +18 -5
- package/dist/validate-DHGwADqO.d.mts.map +1 -0
- package/dist/{validation-BfEI7tNe.mjs → validation-B1NYiEos.mjs} +5 -5
- package/dist/{validation-BfEI7tNe.mjs.map → validation-B1NYiEos.mjs.map} +1 -1
- package/dist/version-CMD42IRC.mjs +7 -0
- package/dist/{version-DoxrVdYf.mjs.map → version-CMD42IRC.mjs.map} +1 -1
- package/dist/{zod-generator-CC0xNe_K.mjs → zod-generator-BNJDQBSZ.mjs} +8 -3
- package/dist/zod-generator-BNJDQBSZ.mjs.map +1 -0
- package/package.json +6 -6
- package/src/api/handlers/content.ts +11 -0
- package/src/api/handlers/dashboard.ts +29 -36
- package/src/api/handlers/menus.ts +256 -75
- package/src/api/handlers/taxonomies.ts +273 -97
- package/src/api/schemas/common.ts +7 -0
- package/src/api/schemas/menus.ts +23 -0
- package/src/api/schemas/taxonomies.ts +39 -0
- package/src/astro/integration/routes.ts +10 -0
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +1 -1
- package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +196 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +9 -177
- package/src/astro/routes/api/menus/[name]/items.ts +16 -6
- package/src/astro/routes/api/menus/[name]/reorder.ts +8 -3
- package/src/astro/routes/api/menus/[name]/translations.ts +82 -0
- package/src/astro/routes/api/menus/[name].ts +19 -10
- package/src/astro/routes/api/menus/index.ts +9 -6
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +89 -0
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +22 -22
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +11 -14
- package/src/astro/routes/api/taxonomies/index.ts +9 -6
- package/src/cli/commands/export-seed.ts +82 -21
- package/src/cli/commands/plugin-init.ts +216 -90
- package/src/database/migrations/036_i18n_menus_and_taxonomies.ts +477 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/content.ts +11 -0
- package/src/database/repositories/taxonomy.ts +193 -89
- package/src/database/types.ts +10 -2
- package/src/i18n/resolve.ts +37 -0
- package/src/loader.ts +49 -2
- package/src/mcp/server.ts +77 -18
- package/src/menus/index.ts +143 -124
- package/src/menus/types.ts +15 -1
- package/src/schema/zod-generator.ts +12 -2
- package/src/seed/apply.ts +140 -54
- package/src/seed/types.ts +14 -1
- package/src/seed/validate.ts +27 -13
- package/src/taxonomies/index.ts +230 -213
- package/src/taxonomies/types.ts +10 -0
- package/dist/apply-BzltprvY.mjs.map +0 -1
- package/dist/content-8lOYF0pr.mjs.map +0 -1
- package/dist/index-BFRaVcD6.d.mts.map +0 -1
- package/dist/loader-CKLbBnhK.mjs.map +0 -1
- package/dist/runner-C7ADox5q.mjs.map +0 -1
- package/dist/search-dOGEccMa.mjs.map +0 -1
- package/dist/taxonomies-ZlRtD6AG.mjs +0 -315
- package/dist/taxonomies-ZlRtD6AG.mjs.map +0 -1
- package/dist/types-BuBIptGk.d.mts.map +0 -1
- package/dist/types-CrtWgIvl.d.mts.map +0 -1
- package/dist/validate-Baqf0slj.mjs.map +0 -1
- package/dist/validate-BfQh_C_y.d.mts.map +0 -1
- package/dist/version-DoxrVdYf.mjs +0 -7
- package/dist/zod-generator-CC0xNe_K.mjs.map +0 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* emdash plugin init
|
|
3
3
|
*
|
|
4
|
-
* Scaffold a new EmDash plugin. Generates the
|
|
4
|
+
* Scaffold a new EmDash plugin. Generates the sandboxed-format boilerplate:
|
|
5
5
|
* src/index.ts -- descriptor factory
|
|
6
6
|
* src/sandbox-entry.ts -- definePlugin({ hooks, routes })
|
|
7
7
|
* package.json
|
|
8
8
|
* tsconfig.json
|
|
9
9
|
*
|
|
10
|
-
* Use --native to generate native-format boilerplate
|
|
10
|
+
* Use --format=native (or --native) to generate native-format boilerplate
|
|
11
|
+
* instead (createPlugin + React admin). When neither is passed and stdout
|
|
12
|
+
* is a TTY, the user is prompted to choose.
|
|
11
13
|
*
|
|
12
14
|
*/
|
|
13
15
|
|
|
@@ -22,6 +24,8 @@ import { fileExists } from "./bundle-utils.js";
|
|
|
22
24
|
const SLUG_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
23
25
|
const SCOPE_RE = /^@[^/]+\//;
|
|
24
26
|
|
|
27
|
+
type PluginFormat = "standard" | "native";
|
|
28
|
+
|
|
25
29
|
export const pluginInitCommand = defineCommand({
|
|
26
30
|
meta: {
|
|
27
31
|
name: "init",
|
|
@@ -37,15 +41,27 @@ export const pluginInitCommand = defineCommand({
|
|
|
37
41
|
type: "string",
|
|
38
42
|
description: "Plugin name/id (e.g. my-plugin or @org/my-plugin)",
|
|
39
43
|
},
|
|
44
|
+
format: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description:
|
|
47
|
+
"Plugin format: sandboxed or native. Prompts when running interactively if not set.",
|
|
48
|
+
valueHint: "sandboxed|native",
|
|
49
|
+
},
|
|
40
50
|
native: {
|
|
41
51
|
type: "boolean",
|
|
42
|
-
description: "
|
|
52
|
+
description: "Shortcut for --format=native",
|
|
43
53
|
default: false,
|
|
44
54
|
},
|
|
45
55
|
},
|
|
46
56
|
async run({ args }) {
|
|
47
57
|
const targetDir = resolve(args.dir);
|
|
48
|
-
|
|
58
|
+
|
|
59
|
+
const format = await resolveFormat(args.format, args.native);
|
|
60
|
+
if (!format) {
|
|
61
|
+
consola.info("Cancelled");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const isNative = format === "native";
|
|
49
65
|
|
|
50
66
|
// Derive plugin name from --name or directory name
|
|
51
67
|
let pluginName = args.name || basename(targetDir);
|
|
@@ -71,7 +87,7 @@ export const pluginInitCommand = defineCommand({
|
|
|
71
87
|
process.exit(1);
|
|
72
88
|
}
|
|
73
89
|
|
|
74
|
-
consola.start(`Scaffolding ${isNative ? "native" : "
|
|
90
|
+
consola.start(`Scaffolding ${isNative ? "native" : "sandboxed"} plugin: ${pluginName}`);
|
|
75
91
|
|
|
76
92
|
await mkdir(srcDir, { recursive: true });
|
|
77
93
|
|
|
@@ -83,22 +99,99 @@ export const pluginInitCommand = defineCommand({
|
|
|
83
99
|
|
|
84
100
|
consola.success(`Plugin scaffolded in ${targetDir}`);
|
|
85
101
|
consola.info("Next steps:");
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
const steps: string[] = [];
|
|
103
|
+
if (args.dir !== ".") steps.push(`cd ${args.dir}`);
|
|
104
|
+
steps.push("pnpm install");
|
|
105
|
+
steps.push(
|
|
106
|
+
isNative
|
|
107
|
+
? "Edit src/index.ts to add hooks and routes"
|
|
108
|
+
: "Edit src/sandbox-entry.ts to add hooks and routes",
|
|
109
|
+
);
|
|
110
|
+
steps.push("pnpm build");
|
|
111
|
+
if (!isNative) steps.push("emdash plugin validate --dir .");
|
|
112
|
+
steps.forEach((step, i) => consola.info(` ${i + 1}. ${step}`));
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
async function resolveFormat(
|
|
117
|
+
formatArg: string | undefined,
|
|
118
|
+
nativeFlag: boolean,
|
|
119
|
+
): Promise<PluginFormat | null> {
|
|
120
|
+
if (formatArg) {
|
|
121
|
+
const normalized = formatArg.toLowerCase();
|
|
122
|
+
let parsed: PluginFormat;
|
|
123
|
+
if (normalized === "native") {
|
|
124
|
+
parsed = "native";
|
|
125
|
+
} else if (normalized === "sandboxed" || normalized === "standard") {
|
|
126
|
+
parsed = "standard";
|
|
92
127
|
} else {
|
|
93
|
-
consola.
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
consola.error(`Invalid --format "${formatArg}". Use "sandboxed" or "native".`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
if (nativeFlag && parsed !== "native") {
|
|
132
|
+
consola.error(`Conflicting flags: --native and --format=${formatArg}. Pass only one.`);
|
|
133
|
+
process.exit(1);
|
|
96
134
|
}
|
|
97
|
-
|
|
135
|
+
return parsed;
|
|
136
|
+
}
|
|
137
|
+
if (nativeFlag) return "native";
|
|
138
|
+
|
|
139
|
+
if (!process.stdout.isTTY) return "standard";
|
|
140
|
+
|
|
141
|
+
const choice = await consola.prompt("Which plugin format?", {
|
|
142
|
+
type: "select",
|
|
143
|
+
initial: "standard",
|
|
144
|
+
options: [
|
|
145
|
+
{
|
|
146
|
+
label: "Sandboxed",
|
|
147
|
+
value: "standard",
|
|
148
|
+
hint: "runs in an isolated sandbox; safe to install from the marketplace",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
label: "Native",
|
|
152
|
+
value: "native",
|
|
153
|
+
hint: "full runtime access; install from npm",
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
cancel: "null",
|
|
157
|
+
});
|
|
158
|
+
if (choice === null) return null;
|
|
159
|
+
return choice as PluginFormat;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function camelCase(slug: string): string {
|
|
163
|
+
return slug
|
|
164
|
+
.split("-")
|
|
165
|
+
.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))
|
|
166
|
+
.join("");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function pascalCase(slug: string): string {
|
|
170
|
+
return slug
|
|
171
|
+
.split("-")
|
|
172
|
+
.map((s) => s[0].toUpperCase() + s.slice(1))
|
|
173
|
+
.join("");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const TSCONFIG = {
|
|
177
|
+
compilerOptions: {
|
|
178
|
+
target: "ES2022",
|
|
179
|
+
module: "preserve",
|
|
180
|
+
moduleResolution: "bundler",
|
|
181
|
+
strict: true,
|
|
182
|
+
esModuleInterop: true,
|
|
183
|
+
declaration: true,
|
|
184
|
+
outDir: "./dist",
|
|
185
|
+
rootDir: "./src",
|
|
98
186
|
},
|
|
99
|
-
|
|
187
|
+
include: ["src/**/*"],
|
|
188
|
+
exclude: ["node_modules", "dist"],
|
|
189
|
+
} as const;
|
|
190
|
+
|
|
191
|
+
const TSDOWN_VERSION = "^0.20.0";
|
|
192
|
+
const TYPESCRIPT_VERSION = "^5.9.0";
|
|
100
193
|
|
|
101
|
-
// ──
|
|
194
|
+
// ── Sandboxed format scaffolding ─────────────────────────────────
|
|
102
195
|
|
|
103
196
|
async function scaffoldStandard(
|
|
104
197
|
targetDir: string,
|
|
@@ -106,13 +199,8 @@ async function scaffoldStandard(
|
|
|
106
199
|
pluginName: string,
|
|
107
200
|
slug: string,
|
|
108
201
|
): Promise<void> {
|
|
109
|
-
|
|
110
|
-
const fnName = slug
|
|
111
|
-
.split("-")
|
|
112
|
-
.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))
|
|
113
|
-
.join("");
|
|
202
|
+
const fnName = camelCase(slug);
|
|
114
203
|
|
|
115
|
-
// package.json
|
|
116
204
|
await writeFile(
|
|
117
205
|
join(targetDir, "package.json"),
|
|
118
206
|
JSON.stringify(
|
|
@@ -120,74 +208,98 @@ async function scaffoldStandard(
|
|
|
120
208
|
name: pluginName,
|
|
121
209
|
version: "0.1.0",
|
|
122
210
|
type: "module",
|
|
211
|
+
main: "./dist/index.mjs",
|
|
123
212
|
exports: {
|
|
124
|
-
".":
|
|
125
|
-
|
|
213
|
+
".": {
|
|
214
|
+
types: "./dist/index.d.mts",
|
|
215
|
+
import: "./dist/index.mjs",
|
|
216
|
+
},
|
|
217
|
+
"./sandbox": {
|
|
218
|
+
types: "./dist/sandbox-entry.d.mts",
|
|
219
|
+
import: "./dist/sandbox-entry.mjs",
|
|
220
|
+
},
|
|
126
221
|
},
|
|
127
|
-
files: ["
|
|
222
|
+
files: ["dist"],
|
|
223
|
+
scripts: {
|
|
224
|
+
build: "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean",
|
|
225
|
+
dev: "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --watch",
|
|
226
|
+
typecheck: "tsc --noEmit",
|
|
227
|
+
},
|
|
228
|
+
keywords: ["emdash", "emdash-plugin"],
|
|
229
|
+
license: "MIT",
|
|
128
230
|
peerDependencies: {
|
|
129
231
|
emdash: "*",
|
|
130
232
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
// tsconfig.json
|
|
138
|
-
await writeFile(
|
|
139
|
-
join(targetDir, "tsconfig.json"),
|
|
140
|
-
JSON.stringify(
|
|
141
|
-
{
|
|
142
|
-
compilerOptions: {
|
|
143
|
-
target: "ES2022",
|
|
144
|
-
module: "preserve",
|
|
145
|
-
moduleResolution: "bundler",
|
|
146
|
-
strict: true,
|
|
147
|
-
esModuleInterop: true,
|
|
148
|
-
declaration: true,
|
|
149
|
-
outDir: "./dist",
|
|
150
|
-
rootDir: "./src",
|
|
233
|
+
devDependencies: {
|
|
234
|
+
emdash: "*",
|
|
235
|
+
tsdown: TSDOWN_VERSION,
|
|
236
|
+
typescript: TYPESCRIPT_VERSION,
|
|
151
237
|
},
|
|
152
|
-
include: ["src/**/*"],
|
|
153
|
-
exclude: ["node_modules", "dist"],
|
|
154
238
|
},
|
|
155
239
|
null,
|
|
156
240
|
"\t",
|
|
157
241
|
) + "\n",
|
|
158
242
|
);
|
|
159
243
|
|
|
160
|
-
|
|
244
|
+
await writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(TSCONFIG, null, "\t") + "\n");
|
|
245
|
+
|
|
161
246
|
await writeFile(
|
|
162
247
|
join(srcDir, "index.ts"),
|
|
163
248
|
`import type { PluginDescriptor } from "emdash";
|
|
164
249
|
|
|
165
250
|
export function ${fnName}Plugin(): PluginDescriptor {
|
|
166
251
|
\treturn {
|
|
167
|
-
\t\tid: "${
|
|
252
|
+
\t\tid: "${slug}",
|
|
168
253
|
\t\tversion: "0.1.0",
|
|
169
254
|
\t\tformat: "standard",
|
|
170
255
|
\t\tentrypoint: "${pluginName}/sandbox",
|
|
171
|
-
|
|
256
|
+
|
|
257
|
+
\t\tcapabilities: ["content:read"],
|
|
258
|
+
\t\tstorage: {
|
|
259
|
+
\t\t\tevents: { indexes: ["timestamp"] },
|
|
260
|
+
\t\t},
|
|
172
261
|
\t};
|
|
173
262
|
}
|
|
174
263
|
`,
|
|
175
264
|
);
|
|
176
265
|
|
|
177
|
-
// src/sandbox-entry.ts -- plugin definition
|
|
178
266
|
await writeFile(
|
|
179
267
|
join(srcDir, "sandbox-entry.ts"),
|
|
180
268
|
`import { definePlugin } from "emdash";
|
|
181
269
|
import type { PluginContext } from "emdash";
|
|
182
270
|
|
|
271
|
+
interface ContentSaveEvent {
|
|
272
|
+
\tcollection: string;
|
|
273
|
+
\tcontent: { id: string };
|
|
274
|
+
\tisNew: boolean;
|
|
275
|
+
}
|
|
276
|
+
|
|
183
277
|
export default definePlugin({
|
|
184
278
|
\thooks: {
|
|
185
279
|
\t\t"content:afterSave": {
|
|
186
|
-
\t\t\thandler: async (event:
|
|
280
|
+
\t\t\thandler: async (event: ContentSaveEvent, ctx: PluginContext) => {
|
|
187
281
|
\t\t\t\tctx.log.info("Content saved", {
|
|
188
282
|
\t\t\t\t\tcollection: event.collection,
|
|
189
283
|
\t\t\t\t\tid: event.content.id,
|
|
190
284
|
\t\t\t\t});
|
|
285
|
+
|
|
286
|
+
\t\t\t\tawait ctx.storage.events.put(\`save-\${Date.now()}\`, {
|
|
287
|
+
\t\t\t\t\ttimestamp: new Date().toISOString(),
|
|
288
|
+
\t\t\t\t\tcollection: event.collection,
|
|
289
|
+
\t\t\t\t\tcontentId: event.content.id,
|
|
290
|
+
\t\t\t\t});
|
|
291
|
+
\t\t\t},
|
|
292
|
+
\t\t},
|
|
293
|
+
\t},
|
|
294
|
+
|
|
295
|
+
\troutes: {
|
|
296
|
+
\t\trecent: {
|
|
297
|
+
\t\t\thandler: async (_routeCtx, ctx: PluginContext) => {
|
|
298
|
+
\t\t\t\tconst result = await ctx.storage.events.query({
|
|
299
|
+
\t\t\t\t\torderBy: { timestamp: "desc" },
|
|
300
|
+
\t\t\t\t\tlimit: 10,
|
|
301
|
+
\t\t\t\t});
|
|
302
|
+
\t\t\t\treturn { events: result.items };
|
|
191
303
|
\t\t\t},
|
|
192
304
|
\t\t},
|
|
193
305
|
\t},
|
|
@@ -204,12 +316,9 @@ async function scaffoldNative(
|
|
|
204
316
|
pluginName: string,
|
|
205
317
|
slug: string,
|
|
206
318
|
): Promise<void> {
|
|
207
|
-
const fnName = slug
|
|
208
|
-
|
|
209
|
-
.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))
|
|
210
|
-
.join("");
|
|
319
|
+
const fnName = camelCase(slug);
|
|
320
|
+
const typeName = pascalCase(slug);
|
|
211
321
|
|
|
212
|
-
// package.json
|
|
213
322
|
await writeFile(
|
|
214
323
|
join(targetDir, "package.json"),
|
|
215
324
|
JSON.stringify(
|
|
@@ -217,71 +326,88 @@ async function scaffoldNative(
|
|
|
217
326
|
name: pluginName,
|
|
218
327
|
version: "0.1.0",
|
|
219
328
|
type: "module",
|
|
329
|
+
main: "./dist/index.mjs",
|
|
220
330
|
exports: {
|
|
221
|
-
".":
|
|
331
|
+
".": {
|
|
332
|
+
types: "./dist/index.d.mts",
|
|
333
|
+
import: "./dist/index.mjs",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
files: ["dist"],
|
|
337
|
+
scripts: {
|
|
338
|
+
build: "tsdown src/index.ts --format esm --dts --clean",
|
|
339
|
+
dev: "tsdown src/index.ts --format esm --dts --watch",
|
|
340
|
+
typecheck: "tsc --noEmit",
|
|
222
341
|
},
|
|
223
|
-
|
|
342
|
+
keywords: ["emdash", "emdash-plugin"],
|
|
343
|
+
license: "MIT",
|
|
224
344
|
peerDependencies: {
|
|
225
345
|
emdash: "*",
|
|
226
346
|
},
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
// tsconfig.json
|
|
234
|
-
await writeFile(
|
|
235
|
-
join(targetDir, "tsconfig.json"),
|
|
236
|
-
JSON.stringify(
|
|
237
|
-
{
|
|
238
|
-
compilerOptions: {
|
|
239
|
-
target: "ES2022",
|
|
240
|
-
module: "preserve",
|
|
241
|
-
moduleResolution: "bundler",
|
|
242
|
-
strict: true,
|
|
243
|
-
esModuleInterop: true,
|
|
244
|
-
declaration: true,
|
|
245
|
-
outDir: "./dist",
|
|
246
|
-
rootDir: "./src",
|
|
347
|
+
devDependencies: {
|
|
348
|
+
emdash: "*",
|
|
349
|
+
tsdown: TSDOWN_VERSION,
|
|
350
|
+
typescript: TYPESCRIPT_VERSION,
|
|
247
351
|
},
|
|
248
|
-
include: ["src/**/*"],
|
|
249
|
-
exclude: ["node_modules", "dist"],
|
|
250
352
|
},
|
|
251
353
|
null,
|
|
252
354
|
"\t",
|
|
253
355
|
) + "\n",
|
|
254
356
|
);
|
|
255
357
|
|
|
256
|
-
|
|
358
|
+
await writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(TSCONFIG, null, "\t") + "\n");
|
|
359
|
+
|
|
257
360
|
await writeFile(
|
|
258
361
|
join(srcDir, "index.ts"),
|
|
259
362
|
`import { definePlugin } from "emdash";
|
|
260
363
|
import type { PluginDescriptor } from "emdash";
|
|
261
364
|
|
|
262
|
-
export
|
|
365
|
+
export interface ${typeName}Options {
|
|
366
|
+
\tenabled?: boolean;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export function ${fnName}Plugin(options: ${typeName}Options = {}): PluginDescriptor<${typeName}Options> {
|
|
263
370
|
\treturn {
|
|
264
|
-
\t\tid: "${
|
|
371
|
+
\t\tid: "${slug}",
|
|
265
372
|
\t\tversion: "0.1.0",
|
|
266
373
|
\t\tformat: "native",
|
|
267
374
|
\t\tentrypoint: "${pluginName}",
|
|
268
|
-
\t\toptions
|
|
375
|
+
\t\toptions,
|
|
269
376
|
\t};
|
|
270
377
|
}
|
|
271
378
|
|
|
272
|
-
export function createPlugin() {
|
|
379
|
+
export function createPlugin(options: ${typeName}Options = {}) {
|
|
273
380
|
\treturn definePlugin({
|
|
274
|
-
\t\tid: "${
|
|
381
|
+
\t\tid: "${slug}",
|
|
275
382
|
\t\tversion: "0.1.0",
|
|
276
383
|
|
|
384
|
+
\t\tcapabilities: ["content:read"],
|
|
385
|
+
\t\tstorage: {
|
|
386
|
+
\t\t\tevents: { indexes: ["createdAt"] },
|
|
387
|
+
\t\t},
|
|
388
|
+
|
|
277
389
|
\t\thooks: {
|
|
278
390
|
\t\t\t"content:afterSave": async (event, ctx) => {
|
|
279
|
-
\t\t\t\
|
|
391
|
+
\t\t\t\tif (options.enabled === false) return;
|
|
392
|
+
\t\t\t\tawait ctx.storage.events.put(\`evt_\${Date.now()}\`, {
|
|
280
393
|
\t\t\t\t\tcollection: event.collection,
|
|
281
|
-
\t\t\t\t\
|
|
394
|
+
\t\t\t\t\tcontentId: event.content.id,
|
|
395
|
+
\t\t\t\t\tcreatedAt: new Date().toISOString(),
|
|
282
396
|
\t\t\t\t});
|
|
283
397
|
\t\t\t},
|
|
284
398
|
\t\t},
|
|
399
|
+
|
|
400
|
+
\t\troutes: {
|
|
401
|
+
\t\t\trecent: {
|
|
402
|
+
\t\t\t\thandler: async (ctx) => {
|
|
403
|
+
\t\t\t\t\tconst result = await ctx.storage.events.query({
|
|
404
|
+
\t\t\t\t\t\torderBy: { createdAt: "desc" },
|
|
405
|
+
\t\t\t\t\t\tlimit: 10,
|
|
406
|
+
\t\t\t\t\t});
|
|
407
|
+
\t\t\t\t\treturn { events: result.items };
|
|
408
|
+
\t\t\t\t},
|
|
409
|
+
\t\t\t},
|
|
410
|
+
\t\t},
|
|
285
411
|
\t});
|
|
286
412
|
}
|
|
287
413
|
|