pinme 2.0.0-beta.3 → 2.0.0-beta.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/dist/index.js CHANGED
@@ -1523,7 +1523,7 @@ var import_chalk21 = __toESM(require("chalk"));
1523
1523
  var import_figlet5 = __toESM(require("figlet"));
1524
1524
 
1525
1525
  // package.json
1526
- var version = "2.0.0-beta.3";
1526
+ var version = "2.0.0-beta.4";
1527
1527
 
1528
1528
  // bin/upload.ts
1529
1529
  var import_path7 = __toESM(require("path"));
@@ -7113,6 +7113,7 @@ var import_child_process2 = require("child_process");
7113
7113
  var TEMPLATE_DIR = import_path11.default.join(__dirname, "../template");
7114
7114
  var PROJECT_DIR = process.cwd();
7115
7115
  var API_BASE = "https://pinme.dev/api/v4";
7116
+ var TEMPLATE_REPO = "https://github.com/glitternetwork/pinme-worker-template.git";
7116
7117
  async function createCmd(options) {
7117
7118
  var _a, _b, _c, _d, _e, _f;
7118
7119
  try {
@@ -7188,9 +7189,20 @@ Directory "${projectName}" already exists.`));
7188
7189
  const errorMsg = ((_d = (_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.data) == null ? void 0 : _d.error) || ((_f = (_e = error.response) == null ? void 0 : _e.data) == null ? void 0 : _f.msg) || error.message || "Failed to create worker";
7189
7190
  throw new Error(errorMsg);
7190
7191
  }
7191
- console.log(import_chalk16.default.blue("\n2. Copying template files..."));
7192
- import_fs_extra6.default.copySync(TEMPLATE_DIR, targetDir);
7193
- console.log(import_chalk16.default.green(` Template copied to: ${targetDir}`));
7192
+ console.log(import_chalk16.default.blue("\n2. Cloning template from repository..."));
7193
+ try {
7194
+ (0, import_child_process2.execSync)(`git clone --depth 1 ${TEMPLATE_REPO} ${targetDir}`, {
7195
+ stdio: "inherit"
7196
+ });
7197
+ console.log(import_chalk16.default.green(` Template cloned to: ${targetDir}`));
7198
+ const gitDir = import_path11.default.join(targetDir, ".git");
7199
+ if (import_fs_extra6.default.existsSync(gitDir)) {
7200
+ import_fs_extra6.default.removeSync(gitDir);
7201
+ console.log(import_chalk16.default.gray(" .git directory removed"));
7202
+ }
7203
+ } catch (error) {
7204
+ throw new Error(`Failed to clone template: ${error.message}`);
7205
+ }
7194
7206
  console.log(import_chalk16.default.blue("\n3. Updating configuration..."));
7195
7207
  const configPath = import_path11.default.join(targetDir, "pinme.toml");
7196
7208
  const config = import_fs_extra6.default.readFileSync(configPath, "utf-8");
@@ -7386,7 +7398,7 @@ function getBuiltWorker() {
7386
7398
  return { workerJsPath, modulePaths };
7387
7399
  }
7388
7400
  function getSqlFiles() {
7389
- const sqlDir = import_path12.default.join(PROJECT_DIR2, "backend", "schema");
7401
+ const sqlDir = import_path12.default.join(PROJECT_DIR2, "db");
7390
7402
  if (!import_fs_extra7.default.existsSync(sqlDir)) {
7391
7403
  return [];
7392
7404
  }
@@ -7540,13 +7552,13 @@ function loadConfig2() {
7540
7552
  };
7541
7553
  }
7542
7554
  function getSqlFiles2() {
7543
- const sqlDir = import_path13.default.join(PROJECT_DIR3, "backend", "schema");
7555
+ const sqlDir = import_path13.default.join(PROJECT_DIR3, "db");
7544
7556
  if (!import_fs_extra8.default.existsSync(sqlDir)) {
7545
- throw new Error("SQL directory not found: backend/schema");
7557
+ throw new Error("SQL directory not found: db");
7546
7558
  }
7547
7559
  const files = import_fs_extra8.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
7548
7560
  if (files.length === 0) {
7549
- throw new Error("No SQL files found in backend/schema");
7561
+ throw new Error("No SQL files found in db");
7550
7562
  }
7551
7563
  return files.map((f) => import_path13.default.join(sqlDir, f));
7552
7564
  }
@@ -7627,7 +7639,7 @@ async function updateDbCmd(options) {
7627
7639
  }
7628
7640
  console.log(import_chalk18.default.gray(`Project: ${projectName}`));
7629
7641
  const sqlFiles = getSqlFiles2();
7630
- console.log(import_chalk18.default.gray(`Found ${sqlFiles.length} SQL file(s) in backend/schema`));
7642
+ console.log(import_chalk18.default.gray(`Found ${sqlFiles.length} SQL file(s) in db`));
7631
7643
  await updateDb(sqlFiles, projectName);
7632
7644
  console.log(import_chalk18.default.green("\n\u2705 Database update complete!"));
7633
7645
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinme",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -15,8 +15,7 @@
15
15
  "pinme": "./dist/index.js"
16
16
  },
17
17
  "files": [
18
- "dist",
19
- "template"
18
+ "dist"
20
19
  ],
21
20
  "keywords": [
22
21
  "ipfs",
@@ -1,177 +0,0 @@
1
- # Pinme Template
2
-
3
- Pinme 官方模板 - 前后端分离架构,使用 Vite + React 前端和 Cloudflare Workers 后端。
4
-
5
- ## 项目结构(Monorepo)
6
-
7
- ```
8
- .
9
- ├── pinme.toml # Pinme 配置
10
- ├── package.json # 根配置
11
- ├── frontend/ # 前端应用(React + Vite)
12
- │ ├── src/
13
- │ └── package.json
14
- ├── backend/ # 后端 Worker
15
- │ ├── src/
16
- │ │ └── worker.ts # ← 用户编辑这个文件
17
- │ ├── wrangler.toml # Wrangler 配置
18
- │ └── metadata.json # Worker 元数据(API 返回)
19
- ├── save-worker.ts # 构建并保存 Worker 脚本
20
- └── README.md
21
- ```
22
-
23
- ## 快速开始
24
-
25
- ### 1. 创建项目
26
-
27
- ```bash
28
- pinme create <project-name>
29
- ```
30
-
31
- ### 2. 安装依赖
32
-
33
- ```bash
34
- cd <project-name>
35
- npm install
36
- ```
37
-
38
- ### 3. 开发
39
-
40
- ```bash
41
- # 前端开发
42
- npm run dev:frontend
43
-
44
- # 后端开发
45
- # 直接编辑 backend/src/worker.ts
46
- npm run dev # 本地预览
47
- ```
48
-
49
- ### 4. 保存到平台
50
-
51
- ```bash
52
- npm run save
53
- ```
54
-
55
- ---
56
-
57
- ## 使用说明
58
-
59
- ### 创建项目
60
-
61
- ```bash
62
- pinme create my-app
63
- ```
64
-
65
- 会调用 `create_worker` API,返回:
66
- - `backend/metadata.json` - Worker 元数据
67
- - `backend/src/worker.ts` - Worker 源代码
68
-
69
- ### 开发后端
70
-
71
- 编辑 `backend/src/worker.ts`:
72
-
73
- ```typescript
74
- export default {
75
- async fetch(request: Request, env: any) {
76
- const url = new URL(request.url);
77
-
78
- if (url.pathname === '/api/hello') {
79
- return new Response('Hello World!');
80
- }
81
-
82
- return new Response('Not Found', { status: 404 });
83
- }
84
- };
85
- ```
86
-
87
- 本地预览:
88
- ```bash
89
- npm run dev
90
- ```
91
-
92
- ### 保存部署
93
-
94
- ```bash
95
- npm run save
96
- ```
97
-
98
- 流程:
99
- 1. `wrangler deploy --dry-run --outdir` - 构建 `backend/src/worker.ts` → `dist-worker/`
100
- 2. 上传 `dist-worker/*.js` + `backend/metadata.json` 到平台 API
101
-
102
- ### 前端开发
103
-
104
- ```bash
105
- npm run dev:frontend
106
- ```
107
-
108
- 访问 `http://localhost:5173`
109
-
110
- ---
111
-
112
- ## 命令
113
-
114
- | 命令 | 说明 |
115
- |------|------|
116
- | `npm run dev` | 本地预览后端 Worker |
117
- | `npm run dev:frontend` | 启动前端开发服务器 |
118
- | `npm run build` | 构建前端 + 后端 |
119
- | `npm run build:worker` | 构建后端 Worker |
120
- | `npm run build:frontend` | 构建前端 |
121
- | `npm run save` | **一键部署**(构建 + 部署前端到 IPFS + 保存 Worker 到平台) |
122
-
123
- ---
124
-
125
- ## 配置
126
-
127
- 编辑 `pinme.toml`:
128
-
129
- ```toml
130
- project_name = "my-app"
131
-
132
- [vars]
133
- VITE_WORKER_URL = ""
134
-
135
- [d1]
136
- migrations_dir = "backend/schema"
137
- # database_id = "xxx"
138
- ```
139
-
140
- 编辑 `backend/wrangler.toml` 配置 D1 等:
141
-
142
- ```toml
143
- name = "my-app"
144
- compatibility_date = "2026-03-01"
145
- main = "src/worker.ts"
146
-
147
- [[d1_databases]]
148
- binding = "DB"
149
- database_name = "my-app-db"
150
- database_id = "xxx"
151
- ```
152
-
153
- ---
154
-
155
- ## 文件说明
156
-
157
- | 文件 | 说明 |
158
- |------|------|
159
- | `backend/src/worker.ts` | 用户编辑的 Worker 源代码 |
160
- | `backend/metadata.json` | Worker 元数据(包含 bindings 等) |
161
- | `backend/wrangler.toml` | Wrangler 配置 |
162
- | `pinme.toml` | 项目配置 |
163
-
164
- ---
165
-
166
- ## 技术栈
167
-
168
- - **前端**: Vite + React + TypeScript + React Router
169
- - **后端**: Cloudflare Workers (TypeScript)
170
- - **数据库**: Cloudflare D1 (SQLite)
171
- - **部署**: Pinme 平台 API
172
-
173
- ---
174
-
175
- ## License
176
-
177
- MIT
@@ -1,12 +0,0 @@
1
- {
2
- "name": "backend",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "wrangler dev",
7
- "deploy": "wrangler deploy"
8
- },
9
- "devDependencies": {
10
- "wrangler": "^3.0.0"
11
- }
12
- }
@@ -1,35 +0,0 @@
1
- CREATE TABLE IF NOT EXISTS messages (
2
- id INTEGER PRIMARY KEY AUTOINCREMENT,
3
- content TEXT NOT NULL,
4
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
5
- );
6
-
7
- CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at);
8
-
9
- -- 项目表(D1 数据库关联)
10
- CREATE TABLE IF NOT EXISTS projects (
11
- id INTEGER PRIMARY KEY AUTOINCREMENT,
12
- project_name TEXT NOT NULL UNIQUE,
13
- db_uuid TEXT NOT NULL,
14
- db_name TEXT NOT NULL,
15
- created_at TEXT NOT NULL,
16
- region TEXT,
17
- created_by TEXT,
18
- created_at_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
19
- );
20
-
21
- CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(project_name);
22
-
23
- -- Worker 部署记录表
24
- CREATE TABLE IF NOT EXISTS workers (
25
- id INTEGER PRIMARY KEY AUTOINCREMENT,
26
- user_id TEXT NOT NULL,
27
- project_name TEXT NOT NULL,
28
- worker_name TEXT NOT NULL,
29
- url TEXT NOT NULL,
30
- deployed_at TEXT NOT NULL,
31
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
32
- UNIQUE(user_id, project_name)
33
- );
34
-
35
- CREATE INDEX IF NOT EXISTS idx_workers_user_project ON workers(user_id, project_name);
@@ -1,108 +0,0 @@
1
- // ============ 类型定义 ============
2
-
3
- export interface Env {
4
- DB: any;
5
- }
6
-
7
- // ============ 工具函数 ============
8
-
9
- const CORS_HEADERS = {
10
- 'Access-Control-Allow-Origin': '*',
11
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
12
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
13
- };
14
-
15
- function json(data: unknown, status = 200): Response {
16
- return Response.json(data, { status, headers: CORS_HEADERS });
17
- }
18
-
19
- function handleOptions(): Response {
20
- return new Response(null, { status: 204, headers: CORS_HEADERS });
21
- }
22
-
23
- // 内存存储(开发阶段使用,上线后换 D1)
24
- const messages: { id: number; content: string; created_at: string }[] = [];
25
- let messageId = 0;
26
-
27
- // ============ 路由处理器 ============
28
-
29
- async function handleHello(env: Env): Promise<Response> {
30
- // 如果有 D1 数据库,使用数据库
31
- if (env.DB) {
32
- const { results } = await env.DB
33
- .prepare('SELECT * FROM messages ORDER BY created_at DESC LIMIT 10')
34
- .all();
35
- return json({ message: 'Hello from Worker!', data: results, source: 'd1' });
36
- }
37
- // 否则使用内存存储
38
- return json({
39
- message: 'Hello from Worker!',
40
- data: messages.slice(-10).reverse(),
41
- source: 'memory'
42
- });
43
- }
44
-
45
- async function handleAddMessage(request: Request, env: Env): Promise<Response> {
46
- const body = await request.json() as { message?: string };
47
- const message = (body.message ?? '').trim().slice(0, 500);
48
- if (!message) return json({ error: 'message is required' }, 400);
49
-
50
- // 如果有 D1 数据库,使用数据库
51
- if (env.DB) {
52
- const result = await env.DB
53
- .prepare('INSERT INTO messages (content) VALUES (?) RETURNING *')
54
- .bind(message)
55
- .first();
56
- return json(result, 201);
57
- }
58
-
59
- // 否则使用内存存储
60
- const newMessage = {
61
- id: ++messageId,
62
- content: message,
63
- created_at: new Date().toISOString(),
64
- };
65
- messages.push(newMessage);
66
- return json(newMessage, 201);
67
- }
68
-
69
- // ============ 示例 Demo API ============
70
-
71
- async function handleGetRootDomain(): Promise<Response> {
72
- try {
73
- const response = await fetch('https://pinme.dev/api/v4/root_domain', {
74
- method: 'GET',
75
- headers: {
76
- 'Content-Type': 'application/json',
77
- },
78
- });
79
- const data = await response.json();
80
- return json(data);
81
- } catch (error) {
82
- return json({ error: 'Failed to fetch root domain' }, 500);
83
- }
84
- }
85
-
86
- // ============ 主入口 ============
87
-
88
- export default {
89
- async fetch(request: Request, env: Env): Promise<Response> {
90
- const { pathname } = new URL(request.url);
91
- const method = request.method;
92
-
93
- // 处理 CORS 预检请求
94
- if (method === 'OPTIONS') {
95
- return handleOptions();
96
- }
97
-
98
- try {
99
- if (pathname === '/api/hello' && method === 'GET') return handleHello(env);
100
- if (pathname === '/api/messages' && method === 'POST') return handleAddMessage(request, env);
101
- if (pathname === '/api/root-domain' && method === 'GET') return handleGetRootDomain();
102
-
103
- return json({ error: 'Not found' }, 404);
104
- } catch {
105
- return json({ error: 'Internal server error' }, 500);
106
- }
107
- },
108
- };
@@ -1,11 +0,0 @@
1
- name = "pinme-template"
2
- compatibility_date = "2026-03-01"
3
- main = "src/worker.ts"
4
-
5
- [[d1_databases]]
6
- binding = "pinme_template_db"
7
- database_name = "pinme-template-db"
8
- database_id = "e75f6af9-73a1-490c-80b1-4cd77895b2b9"
9
-
10
- [vars]
11
- VITE_WORKER_URL = "https://vite-react-ts-{hash}.pinme.pro"
@@ -1,4 +0,0 @@
1
- # Pinme Root Domain
2
- # 创建项目时会自动生成,无需手动配置
3
-
4
- VITE_API_URL="";
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="zh">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Pinme App</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/src/main.tsx"></script>
11
- </body>
12
- </html>
@@ -1,25 +0,0 @@
1
- {
2
- "name": "pinme-template-frontend",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite",
8
- "build": "tsc && vite build",
9
- "preview": "vite preview",
10
- "deploy": "tsc && vite build && pinme upload ./dist"
11
- },
12
- "dependencies": {
13
- "react": "^18.3.1",
14
- "react-dom": "^18.3.1",
15
- "react-router-dom": "^6.22.0"
16
- },
17
- "devDependencies": {
18
- "@types/node": "^22.10.5",
19
- "@types/react": "^18.3.1",
20
- "@types/react-dom": "^18.3.1",
21
- "@vitejs/plugin-react": "^4.3.1",
22
- "typescript": "^5.5.3",
23
- "vite": "^5.4.1"
24
- }
25
- }