pdf-master-landing 0.0.6 → 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/README.md +82 -82
- package/bin/deploy.mjs +164 -164
- package/dist/_diag.html +159 -159
- package/dist/app/.last_build_id +1 -1
- package/dist/app/README.md +49 -49
- package/dist/app/assets/AssetManifest.bin +1 -1
- package/dist/app/assets/AssetManifest.bin.json +1 -1
- package/dist/app/assets/FontManifest.json +1 -1
- package/dist/app/assets/NOTICES +235 -104
- package/dist/app/assets/assets/fonts/MiSans-Medium.ttf +0 -0
- package/dist/app/assets/assets/fonts/MiSans-Regular.ttf +0 -0
- package/dist/app/assets/assets/fonts/MiSans-Semibold.ttf +0 -0
- package/dist/app/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w100.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w200.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w300.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w400.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w500.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/build_font/LucideVariable-w600.ttf +0 -0
- package/dist/app/assets/packages/lucide_icons_flutter/assets/lucide.ttf +0 -0
- package/dist/app/assets/packages/pdfrx/assets/pdfium_client.js +65 -65
- package/dist/app/assets/packages/pdfrx/assets/pdfium_worker.js +5327 -5206
- package/dist/app/canvaskit/canvaskit.wasm +0 -0
- package/dist/app/canvaskit/chromium/canvaskit.wasm +0 -0
- package/dist/app/canvaskit/experimental_webparagraph/canvaskit.wasm +0 -0
- package/dist/app/canvaskit/skwasm.wasm +0 -0
- package/dist/app/canvaskit/skwasm_heavy.wasm +0 -0
- package/dist/app/canvaskit/wimp.wasm +0 -0
- package/dist/app/drift_worker.dart.js +13271 -13271
- package/dist/app/flutter_bootstrap.js +2 -2
- package/dist/app/flutter_service_worker.js +31 -31
- package/dist/app/index.html +59 -59
- package/dist/app/main.dart.js +104160 -93754
- package/dist/app/main.dart.mjs +496 -494
- package/dist/app/main.dart.wasm +0 -0
- package/dist/app/manifest.json +34 -34
- package/dist/app/version.json +1 -1
- package/dist/index.html +21 -21
- package/dist/privacy.html +18 -18
- package/package.json +41 -41
package/README.md
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
# PDF Master Landing
|
|
2
|
-
|
|
3
|
-
PDF Master 的产品介绍页。Vite + React + TypeScript。
|
|
4
|
-
|
|
5
|
-
## 与 Flutter Web 的关系
|
|
6
|
-
|
|
7
|
-
落地页是站点根;Flutter Web 应用部署在 `/app/` 子路径下。
|
|
8
|
-
|
|
9
|
-
集成方式:
|
|
10
|
-
|
|
11
|
-
- **构建产物源**:`flutter build web --base-href /app/ --wasm --release` → `<repo>/build/web/`。
|
|
12
|
-
- **同步点**:`landing/public/app/`。vite 把 `public/` 在 dev 直接 serve、在 build 拷到 `dist/`,所以一处同步两处生效。
|
|
13
|
-
- **同步脚本**:`scripts/sync-flutter-web.mjs`,挂在 `predev` / `prebuild` 钩子上,自动执行。
|
|
14
|
-
|
|
15
|
-
`landing/public/app/` 是构建产物,已 gitignore。
|
|
16
|
-
|
|
17
|
-
## 开发
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
cd landing
|
|
21
|
-
npm install
|
|
22
|
-
|
|
23
|
-
# 第一次跑:先准备 Flutter 产物(一次构建即可,后续不用重复)
|
|
24
|
-
npm run sync:app
|
|
25
|
-
|
|
26
|
-
# 启动 dev server
|
|
27
|
-
npm run dev # http://localhost:5180
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
`npm run dev` 会先跑 `predev`,把现有的 `build/web/` 同步到 `public/app/`(不重新构建 Flutter)。
|
|
31
|
-
如果 Flutter 代码有改动,重新跑 `npm run sync:app`。
|
|
32
|
-
|
|
33
|
-
### 用 flutter run 热重载联调
|
|
34
|
-
|
|
35
|
-
不想反复 `flutter build web`,可以让 Flutter 自己跑独立 dev server:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# 终端 A
|
|
39
|
-
cd ..
|
|
40
|
-
flutter run -d chrome --web-port 5181
|
|
41
|
-
|
|
42
|
-
# 终端 B:跳过同步、走 VITE_APP_BASE 切换
|
|
43
|
-
echo "VITE_APP_BASE=http://localhost:5181/" > landing/.env.local
|
|
44
|
-
SKIP_FLUTTER=1 npm run dev
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## 生产构建
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm run build # → landing/dist/,包含 dist/app/
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
`prebuild` 钩子会先跑 `flutter build web` + 同步到 `public/app/`,然后 vite build 把整个 `public/` 拷进 `dist/`。
|
|
54
|
-
|
|
55
|
-
## npm 发布与 1Panel 部署
|
|
56
|
-
|
|
57
|
-
这个项目可以作为 npm 包发布,包内只暴露静态产物 `dist/` 和部署脚本。
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
cd landing
|
|
61
|
-
npm publish
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
服务器上先把包安装到 1Panel 站点目录,再用包内 bin 把公开目录切成软链接:
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
cd /opt/1panel/www/sites/pdfmaster.top/index
|
|
68
|
-
npm install pdf-master-landing@latest
|
|
69
|
-
npx pdfmaster-deploy --target .
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
执行后,`/opt/1panel/www/sites/pdfmaster.top/index/dist` 会指向
|
|
73
|
-
`node_modules/pdf-master-landing/dist`。OpenResty 当前 root 仍然是
|
|
74
|
-
`/www/sites/pdfmaster.top/index/dist`,不用改 1Panel 站点配置。
|
|
75
|
-
|
|
76
|
-
## 同步脚本参数
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
npm run sync:app # 构建 + 同步(默认)
|
|
80
|
-
npm run sync:app:no-build # 只同步现有 build/web/,不跑 flutter
|
|
81
|
-
SKIP_FLUTTER=1 ... # 完全跳过(前端纯 UI 联调时用)
|
|
82
|
-
```
|
|
1
|
+
# PDF Master Landing
|
|
2
|
+
|
|
3
|
+
PDF Master 的产品介绍页。Vite + React + TypeScript。
|
|
4
|
+
|
|
5
|
+
## 与 Flutter Web 的关系
|
|
6
|
+
|
|
7
|
+
落地页是站点根;Flutter Web 应用部署在 `/app/` 子路径下。
|
|
8
|
+
|
|
9
|
+
集成方式:
|
|
10
|
+
|
|
11
|
+
- **构建产物源**:`flutter build web --base-href /app/ --wasm --release` → `<repo>/build/web/`。
|
|
12
|
+
- **同步点**:`landing/public/app/`。vite 把 `public/` 在 dev 直接 serve、在 build 拷到 `dist/`,所以一处同步两处生效。
|
|
13
|
+
- **同步脚本**:`scripts/sync-flutter-web.mjs`,挂在 `predev` / `prebuild` 钩子上,自动执行。
|
|
14
|
+
|
|
15
|
+
`landing/public/app/` 是构建产物,已 gitignore。
|
|
16
|
+
|
|
17
|
+
## 开发
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd landing
|
|
21
|
+
npm install
|
|
22
|
+
|
|
23
|
+
# 第一次跑:先准备 Flutter 产物(一次构建即可,后续不用重复)
|
|
24
|
+
npm run sync:app
|
|
25
|
+
|
|
26
|
+
# 启动 dev server
|
|
27
|
+
npm run dev # http://localhost:5180
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`npm run dev` 会先跑 `predev`,把现有的 `build/web/` 同步到 `public/app/`(不重新构建 Flutter)。
|
|
31
|
+
如果 Flutter 代码有改动,重新跑 `npm run sync:app`。
|
|
32
|
+
|
|
33
|
+
### 用 flutter run 热重载联调
|
|
34
|
+
|
|
35
|
+
不想反复 `flutter build web`,可以让 Flutter 自己跑独立 dev server:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 终端 A
|
|
39
|
+
cd ..
|
|
40
|
+
flutter run -d chrome --web-port 5181
|
|
41
|
+
|
|
42
|
+
# 终端 B:跳过同步、走 VITE_APP_BASE 切换
|
|
43
|
+
echo "VITE_APP_BASE=http://localhost:5181/" > landing/.env.local
|
|
44
|
+
SKIP_FLUTTER=1 npm run dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 生产构建
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm run build # → landing/dist/,包含 dist/app/
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`prebuild` 钩子会先跑 `flutter build web` + 同步到 `public/app/`,然后 vite build 把整个 `public/` 拷进 `dist/`。
|
|
54
|
+
|
|
55
|
+
## npm 发布与 1Panel 部署
|
|
56
|
+
|
|
57
|
+
这个项目可以作为 npm 包发布,包内只暴露静态产物 `dist/` 和部署脚本。
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd landing
|
|
61
|
+
npm publish
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
服务器上先把包安装到 1Panel 站点目录,再用包内 bin 把公开目录切成软链接:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd /opt/1panel/www/sites/pdfmaster.top/index
|
|
68
|
+
npm install pdf-master-landing@latest
|
|
69
|
+
npx pdfmaster-deploy --target .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
执行后,`/opt/1panel/www/sites/pdfmaster.top/index/dist` 会指向
|
|
73
|
+
`node_modules/pdf-master-landing/dist`。OpenResty 当前 root 仍然是
|
|
74
|
+
`/www/sites/pdfmaster.top/index/dist`,不用改 1Panel 站点配置。
|
|
75
|
+
|
|
76
|
+
## 同步脚本参数
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm run sync:app # 构建 + 同步(默认)
|
|
80
|
+
npm run sync:app:no-build # 只同步现有 build/web/,不跑 flutter
|
|
81
|
+
SKIP_FLUTTER=1 ... # 完全跳过(前端纯 UI 联调时用)
|
|
82
|
+
```
|
package/bin/deploy.mjs
CHANGED
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'node:fs/promises';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
|
|
7
|
-
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
|
-
|
|
9
|
-
function printHelp() {
|
|
10
|
-
console.log(`PDF Master landing deploy
|
|
11
|
-
|
|
12
|
-
Usage:
|
|
13
|
-
pdfmaster-deploy --target <site-index-dir>
|
|
14
|
-
pdf-master-landing deploy --target <site-index-dir>
|
|
15
|
-
|
|
16
|
-
Options:
|
|
17
|
-
-t, --target <dir> Directory that owns the public dist symlink.
|
|
18
|
-
--link-name <name> Symlink name inside target. Defaults to dist.
|
|
19
|
-
--dry-run Print the planned link change without writing files.
|
|
20
|
-
-h, --help Show this help.
|
|
21
|
-
`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function parseArgs(argv) {
|
|
25
|
-
const args = argv[0] === 'deploy' ? argv.slice(1) : argv;
|
|
26
|
-
const options = {
|
|
27
|
-
linkName: 'dist',
|
|
28
|
-
dryRun: false,
|
|
29
|
-
target: undefined,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
33
|
-
const arg = args[index];
|
|
34
|
-
const next = args[index + 1];
|
|
35
|
-
|
|
36
|
-
if (arg === '-h' || arg === '--help') {
|
|
37
|
-
options.help = true;
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (arg === '--dry-run') {
|
|
42
|
-
options.dryRun = true;
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (arg === '-t' || arg === '--target') {
|
|
47
|
-
if (!next) {
|
|
48
|
-
throw new Error(`${arg} requires a directory.`);
|
|
49
|
-
}
|
|
50
|
-
options.target = next;
|
|
51
|
-
index += 1;
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (arg === '--link-name') {
|
|
56
|
-
if (!next) {
|
|
57
|
-
throw new Error('--link-name requires a name.');
|
|
58
|
-
}
|
|
59
|
-
options.linkName = next;
|
|
60
|
-
index += 1;
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
throw new Error(`Unknown argument: ${arg}`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return options;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function pathExists(value) {
|
|
71
|
-
try {
|
|
72
|
-
await fs.lstat(value);
|
|
73
|
-
return true;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
if (error?.code === 'ENOENT') {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
throw error;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function assertSafeLinkName(linkName) {
|
|
83
|
-
if (!linkName || linkName.includes('/') || linkName.includes('\\') || linkName === '.' || linkName === '..') {
|
|
84
|
-
throw new Error('--link-name must be a plain file name inside the target directory.');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function assertPackageInsideTarget(sourceDist, targetDir) {
|
|
89
|
-
const relative = path.relative(targetDir, sourceDist);
|
|
90
|
-
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
91
|
-
throw new Error(`The package dist directory is outside the deploy target.
|
|
92
|
-
|
|
93
|
-
Install the npm package inside the 1Panel site directory first, then run the local bin:
|
|
94
|
-
|
|
95
|
-
cd ${targetDir}
|
|
96
|
-
npm install pdf-master-landing@latest
|
|
97
|
-
npx pdfmaster-deploy --target .
|
|
98
|
-
|
|
99
|
-
Package dist:
|
|
100
|
-
${sourceDist}
|
|
101
|
-
Deploy target:
|
|
102
|
-
${targetDir}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function deploy(options) {
|
|
107
|
-
if (!options.target) {
|
|
108
|
-
throw new Error('--target is required.');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
assertSafeLinkName(options.linkName);
|
|
112
|
-
|
|
113
|
-
const rawSourceDist = path.join(packageRoot, 'dist');
|
|
114
|
-
const sourceIndex = path.join(rawSourceDist, 'index.html');
|
|
115
|
-
const rawTargetDir = path.resolve(options.target);
|
|
116
|
-
|
|
117
|
-
if (!(await pathExists(sourceIndex))) {
|
|
118
|
-
throw new Error(`Cannot find built landing files at ${rawSourceDist}. Run npm run build before packing or publishing.`);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (!(await pathExists(rawTargetDir))) {
|
|
122
|
-
throw new Error(`Deploy target does not exist: ${rawTargetDir}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const sourceDist = await fs.realpath(rawSourceDist);
|
|
126
|
-
const targetDir = await fs.realpath(rawTargetDir);
|
|
127
|
-
const linkPath = path.join(targetDir, options.linkName);
|
|
128
|
-
const tempLinkPath = path.join(targetDir, `.${options.linkName}.next-${process.pid}-${Date.now()}`);
|
|
129
|
-
const relativeSource = path.relative(path.dirname(linkPath), sourceDist);
|
|
130
|
-
const symlinkType = process.platform === 'win32' ? 'junction' : 'dir';
|
|
131
|
-
|
|
132
|
-
assertPackageInsideTarget(sourceDist, targetDir);
|
|
133
|
-
|
|
134
|
-
console.log(`PDF Master landing deploy
|
|
135
|
-
Target: ${targetDir}
|
|
136
|
-
Source: ${sourceDist}
|
|
137
|
-
Link: ${linkPath} -> ${relativeSource}`);
|
|
138
|
-
|
|
139
|
-
if (options.dryRun) {
|
|
140
|
-
console.log('Dry run complete. No files were changed.');
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
await fs.rm(tempLinkPath, { force: true, recursive: true });
|
|
145
|
-
await fs.symlink(relativeSource, tempLinkPath, symlinkType);
|
|
146
|
-
await fs.rm(linkPath, { force: true, recursive: true });
|
|
147
|
-
await fs.rename(tempLinkPath, linkPath);
|
|
148
|
-
|
|
149
|
-
console.log('Deploy complete.');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const options = parseArgs(process.argv.slice(2));
|
|
154
|
-
|
|
155
|
-
if (options.help) {
|
|
156
|
-
printHelp();
|
|
157
|
-
} else {
|
|
158
|
-
await deploy(options);
|
|
159
|
-
}
|
|
160
|
-
} catch (error) {
|
|
161
|
-
console.error(error instanceof Error ? error.message : error);
|
|
162
|
-
console.error('Run pdfmaster-deploy --help for usage.');
|
|
163
|
-
process.exitCode = 1;
|
|
164
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
|
+
|
|
9
|
+
function printHelp() {
|
|
10
|
+
console.log(`PDF Master landing deploy
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
pdfmaster-deploy --target <site-index-dir>
|
|
14
|
+
pdf-master-landing deploy --target <site-index-dir>
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
-t, --target <dir> Directory that owns the public dist symlink.
|
|
18
|
+
--link-name <name> Symlink name inside target. Defaults to dist.
|
|
19
|
+
--dry-run Print the planned link change without writing files.
|
|
20
|
+
-h, --help Show this help.
|
|
21
|
+
`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const args = argv[0] === 'deploy' ? argv.slice(1) : argv;
|
|
26
|
+
const options = {
|
|
27
|
+
linkName: 'dist',
|
|
28
|
+
dryRun: false,
|
|
29
|
+
target: undefined,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
33
|
+
const arg = args[index];
|
|
34
|
+
const next = args[index + 1];
|
|
35
|
+
|
|
36
|
+
if (arg === '-h' || arg === '--help') {
|
|
37
|
+
options.help = true;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (arg === '--dry-run') {
|
|
42
|
+
options.dryRun = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (arg === '-t' || arg === '--target') {
|
|
47
|
+
if (!next) {
|
|
48
|
+
throw new Error(`${arg} requires a directory.`);
|
|
49
|
+
}
|
|
50
|
+
options.target = next;
|
|
51
|
+
index += 1;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (arg === '--link-name') {
|
|
56
|
+
if (!next) {
|
|
57
|
+
throw new Error('--link-name requires a name.');
|
|
58
|
+
}
|
|
59
|
+
options.linkName = next;
|
|
60
|
+
index += 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return options;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function pathExists(value) {
|
|
71
|
+
try {
|
|
72
|
+
await fs.lstat(value);
|
|
73
|
+
return true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error?.code === 'ENOENT') {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function assertSafeLinkName(linkName) {
|
|
83
|
+
if (!linkName || linkName.includes('/') || linkName.includes('\\') || linkName === '.' || linkName === '..') {
|
|
84
|
+
throw new Error('--link-name must be a plain file name inside the target directory.');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function assertPackageInsideTarget(sourceDist, targetDir) {
|
|
89
|
+
const relative = path.relative(targetDir, sourceDist);
|
|
90
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
91
|
+
throw new Error(`The package dist directory is outside the deploy target.
|
|
92
|
+
|
|
93
|
+
Install the npm package inside the 1Panel site directory first, then run the local bin:
|
|
94
|
+
|
|
95
|
+
cd ${targetDir}
|
|
96
|
+
npm install pdf-master-landing@latest
|
|
97
|
+
npx pdfmaster-deploy --target .
|
|
98
|
+
|
|
99
|
+
Package dist:
|
|
100
|
+
${sourceDist}
|
|
101
|
+
Deploy target:
|
|
102
|
+
${targetDir}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function deploy(options) {
|
|
107
|
+
if (!options.target) {
|
|
108
|
+
throw new Error('--target is required.');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
assertSafeLinkName(options.linkName);
|
|
112
|
+
|
|
113
|
+
const rawSourceDist = path.join(packageRoot, 'dist');
|
|
114
|
+
const sourceIndex = path.join(rawSourceDist, 'index.html');
|
|
115
|
+
const rawTargetDir = path.resolve(options.target);
|
|
116
|
+
|
|
117
|
+
if (!(await pathExists(sourceIndex))) {
|
|
118
|
+
throw new Error(`Cannot find built landing files at ${rawSourceDist}. Run npm run build before packing or publishing.`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!(await pathExists(rawTargetDir))) {
|
|
122
|
+
throw new Error(`Deploy target does not exist: ${rawTargetDir}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const sourceDist = await fs.realpath(rawSourceDist);
|
|
126
|
+
const targetDir = await fs.realpath(rawTargetDir);
|
|
127
|
+
const linkPath = path.join(targetDir, options.linkName);
|
|
128
|
+
const tempLinkPath = path.join(targetDir, `.${options.linkName}.next-${process.pid}-${Date.now()}`);
|
|
129
|
+
const relativeSource = path.relative(path.dirname(linkPath), sourceDist);
|
|
130
|
+
const symlinkType = process.platform === 'win32' ? 'junction' : 'dir';
|
|
131
|
+
|
|
132
|
+
assertPackageInsideTarget(sourceDist, targetDir);
|
|
133
|
+
|
|
134
|
+
console.log(`PDF Master landing deploy
|
|
135
|
+
Target: ${targetDir}
|
|
136
|
+
Source: ${sourceDist}
|
|
137
|
+
Link: ${linkPath} -> ${relativeSource}`);
|
|
138
|
+
|
|
139
|
+
if (options.dryRun) {
|
|
140
|
+
console.log('Dry run complete. No files were changed.');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await fs.rm(tempLinkPath, { force: true, recursive: true });
|
|
145
|
+
await fs.symlink(relativeSource, tempLinkPath, symlinkType);
|
|
146
|
+
await fs.rm(linkPath, { force: true, recursive: true });
|
|
147
|
+
await fs.rename(tempLinkPath, linkPath);
|
|
148
|
+
|
|
149
|
+
console.log('Deploy complete.');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const options = parseArgs(process.argv.slice(2));
|
|
154
|
+
|
|
155
|
+
if (options.help) {
|
|
156
|
+
printHelp();
|
|
157
|
+
} else {
|
|
158
|
+
await deploy(options);
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.error(error instanceof Error ? error.message : error);
|
|
162
|
+
console.error('Run pdfmaster-deploy --help for usage.');
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
}
|