create-rainynest-ext 0.0.0-stage → 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/index.js ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ // create-rainynest-ext — RainyNest 扩展脚手架
3
+ // 用法:
4
+ // npm create rainynest-ext my-plugin (生成插件工程)
5
+ // npm create rainynest-ext my-theme --theme (生成主题工程)
6
+ const fs = require('node:fs');
7
+ const path = require('node:path');
8
+
9
+ const args = process.argv.slice(2);
10
+ const themeFlag = args.includes('--theme');
11
+ const positional = args.find((a) => !a.startsWith('-'));
12
+ const kind = themeFlag ? 'theme' : 'plugin';
13
+ const name = positional || (themeFlag ? 'my-theme' : 'my-plugin');
14
+
15
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {
16
+ console.error(`[create] 无效名称 "${name}":只允许小写字母/数字/连字符`);
17
+ process.exit(1);
18
+ }
19
+
20
+ const dest = path.join(process.cwd(), name);
21
+ if (fs.existsSync(dest)) {
22
+ console.error(`[create] 目录已存在: ${dest}`);
23
+ process.exit(1);
24
+ }
25
+
26
+ const tplDir = path.join(__dirname, 'templates', kind);
27
+
28
+ function copyTpl(src, d) {
29
+ fs.mkdirSync(d, { recursive: true });
30
+ for (const item of fs.readdirSync(src)) {
31
+ const s = path.join(src, item);
32
+ const t = path.join(d, item);
33
+ if (fs.statSync(s).isDirectory()) {
34
+ copyTpl(s, t);
35
+ continue;
36
+ }
37
+ const content = fs.readFileSync(s, 'utf-8').replace(/__SLUG__/g, name);
38
+ fs.writeFileSync(t, content);
39
+ }
40
+ }
41
+
42
+ copyTpl(tplDir, dest);
43
+
44
+ console.log(`[create] ✓ 已生成${kind === 'plugin' ? '插件' : '主题'}工程: ${dest}`);
45
+ console.log(' 下一步:');
46
+ console.log(` cd ${name}`);
47
+ console.log(' npm install');
48
+ console.log(' npm run dev # 联调热更新(需要 RainyNest 站点的 EXT_DEV_TOKEN)');
49
+ console.log(' npm run pack # 产出发布包,到后台「系统 → 插件/主题」上传安装');
package/package.json CHANGED
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "name": "create-rainynest-ext",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "RainyNest 扩展脚手架:npm create rainynest-ext my-plugin 生成插件/主题模板工程",
5
+ "bin": {
6
+ "create-rainynest-ext": "index.js"
7
+ },
8
+ "files": [
9
+ "index.js",
10
+ "templates/"
11
+ ],
12
+ "keywords": [
13
+ "rainynest",
14
+ "plugin",
15
+ "theme",
16
+ "scaffold"
17
+ ],
18
+ "license": "MIT"
19
+ }
@@ -0,0 +1,17 @@
1
+ # __SLUG__
2
+
3
+ RainyNest 插件。
4
+
5
+ ## 开发
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev # 联调热更新,需要 RainyNest 主项目 .env 里的 EXT_DEV_TOKEN
10
+ ```
11
+
12
+ ## 发布
13
+
14
+ ```bash
15
+ npm run pack
16
+ # 产出 dist/__SLUG__.zip.rainy-plugin,到 RainyNest 后台「系统 → 插件」上传安装
17
+ ```
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "__SLUG__",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "RainyNest 插件 __SLUG__",
6
+ "scripts": {
7
+ "dev": "ext dev . --site http://localhost:3000",
8
+ "build": "ext build . -o dist",
9
+ "pack": "ext build . -o dist && ext pack dist"
10
+ },
11
+ "devDependencies": {
12
+ "@rainynest/ext": "^0.1.0",
13
+ "@rainynest/plugin-types": "^0.1.0",
14
+ "@types/react": "^19.1.0",
15
+ "typescript": "^5.8.0"
16
+ }
17
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "slug": "__SLUG__",
3
+ "name": "__SLUG__",
4
+ "version": "0.1.0",
5
+ "description": "插件描述",
6
+ "author": "",
7
+ "specVersion": "1.0",
8
+ "requiresCore": ">=1.0.0",
9
+ "entry": "index.ts",
10
+ "permissions": [],
11
+ "roleTemplates": [],
12
+ "database": { "enabled": false },
13
+ "configSchema": {
14
+ "basic": {
15
+ "label": "基础",
16
+ "fields": {
17
+ "enabled": { "type": "switch", "label": "启用", "default": true }
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,11 @@
1
+ // src/admin.tsx — 可选后台页面(customAdminRoutes 引用)
2
+ import React from 'react';
3
+
4
+ export default function AdminPage() {
5
+ return (
6
+ <div className="space-y-6">
7
+ <h1 className="text-2xl font-bold">__SLUG__</h1>
8
+ <p className="text-sm text-gray-500">插件管理页</p>
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,12 @@
1
+ // src/index.ts — __SLUG__ 插件入口
2
+ import type { PluginContext, ExtensionHandlers } from '@rainynest/plugin-types';
3
+
4
+ export default function createPlugin(ctx: PluginContext): ExtensionHandlers {
5
+ ctx.logger.info('__SLUG__ 已加载,版本', ctx.version);
6
+
7
+ return {
8
+ // 在这里实现扩展点,例如:
9
+ // onMount(ctx) {},
10
+ // injectFooter() { return []; },
11
+ };
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "target": "ES2022",
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "jsx": "react-jsx",
8
+ "noEmit": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["src"]
12
+ }
@@ -0,0 +1,17 @@
1
+ # __SLUG__
2
+
3
+ RainyNest 主题。
4
+
5
+ ## 开发
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev # 联调热更新,需要 RainyNest 主项目 .env 里的 EXT_DEV_TOKEN
10
+ ```
11
+
12
+ ## 发布
13
+
14
+ ```bash
15
+ npm run pack
16
+ # 产出 dist/__SLUG__.gz.rainy-theme,到 RainyNest 后台「系统 → 主题」上传安装
17
+ ```
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "__SLUG__",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "RainyNest 主题 __SLUG__",
6
+ "scripts": {
7
+ "dev": "ext dev . --site http://localhost:3000",
8
+ "build": "ext build . -o dist",
9
+ "pack": "ext build . -o dist && ext pack dist"
10
+ },
11
+ "devDependencies": {
12
+ "@rainynest/ext": "^0.1.0",
13
+ "@rainynest/plugin-types": "^0.1.0",
14
+ "typescript": "^5.8.0"
15
+ }
16
+ }
@@ -0,0 +1,8 @@
1
+ // src/theme.ts — 配置值 → CSS 变量
2
+ export function configToCssVariables(config: Record<string, any>): Record<string, string> {
3
+ const vars: Record<string, string> = {};
4
+ if (config?.basic?.accentColor) {
5
+ vars['--color-primary'] = config.basic.accentColor;
6
+ }
7
+ return vars;
8
+ }
@@ -0,0 +1 @@
1
+ /* theme.css — __SLUG__ 主题样式 */
@@ -0,0 +1,26 @@
1
+ {
2
+ "slug": "__SLUG__",
3
+ "name": "__SLUG__",
4
+ "version": "0.1.0",
5
+ "description": "主题描述",
6
+ "author": "",
7
+ "specVersion": "1.0",
8
+ "minRainyNestVersion": ">=1.0.0",
9
+ "preview": "preview.png",
10
+ "supports": ["posts", "pages", "moments", "gallery", "links"],
11
+ "configSchema": {
12
+ "basic": {
13
+ "label": "基础",
14
+ "fields": {
15
+ "accentColor": { "type": "color", "label": "强调色", "default": "#3b82f6" }
16
+ }
17
+ },
18
+ "advanced": {
19
+ "label": "高级",
20
+ "fields": {
21
+ "customCss": { "type": "textarea", "label": "自定义 CSS", "default": "" },
22
+ "customJs": { "type": "textarea", "label": "自定义 JS", "default": "" }
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "target": "ES2022",
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "noEmit": true,
8
+ "skipLibCheck": true
9
+ },
10
+ "include": ["src"]
11
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.