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 +21 -9
- package/package.json +2 -3
- package/template/README.md +0 -177
- package/template/backend/package.json +0 -12
- package/template/backend/schema/001_init.sql +0 -35
- package/template/backend/src/worker.ts +0 -108
- package/template/backend/wrangler.toml +0 -11
- package/template/frontend/.env.example +0 -4
- package/template/frontend/index.html +0 -12
- package/template/frontend/package.json +0 -25
- package/template/frontend/pnpm-lock.yaml +0 -1119
- package/template/frontend/src/App.css +0 -389
- package/template/frontend/src/App.tsx +0 -38
- package/template/frontend/src/components/Header.tsx +0 -29
- package/template/frontend/src/main.tsx +0 -21
- package/template/frontend/src/pages/About/index.tsx +0 -39
- package/template/frontend/src/pages/Demo/index.tsx +0 -87
- package/template/frontend/src/pages/Home/index.tsx +0 -94
- package/template/frontend/src/utils/api.ts +0 -6
- package/template/frontend/src/vite-env.d.ts +0 -1
- package/template/frontend/tsconfig.json +0 -22
- package/template/frontend/tsconfig.node.json +0 -11
- package/template/frontend/vite.config.ts +0 -27
- package/template/package.json +0 -16
- package/template/pinme.toml +0 -18
- package/template/pnpm-workspace.yaml +0 -3
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.
|
|
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.
|
|
7192
|
-
|
|
7193
|
-
|
|
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, "
|
|
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, "
|
|
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:
|
|
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
|
|
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
|
|
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
|
+
"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",
|
package/template/README.md
DELETED
|
@@ -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,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,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
|
-
}
|