@seayoo-web/finder 2.0.12 → 2.0.13

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/dist/index.cjs +0 -354
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seayoo-web/finder",
3
- "version": "2.0.12",
3
+ "version": "2.0.13",
4
4
  "description": "agent for web finder",
5
5
  "type": "module",
6
6
  "source": "index.ts",
package/dist/index.cjs DELETED
@@ -1,354 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const fs = require("fs");
4
- const path = require("path");
5
- const open = require("open");
6
- require("colors");
7
- const compressing = require("compressing");
8
- const os = require("os");
9
- const presetIgnores = ["node_modules/", ".git/", ".vscode/", "__MACOSX/", ".DS_Store", ".gitkeep"];
10
- function compressToBuffer(sourceDir, ignoreFiles, debug) {
11
- const ignoreFileList = [...presetIgnores, ...ignoreFiles || []];
12
- const filesToCompress = getAllFiles(sourceDir, ignoreFileList);
13
- const zipStream = new compressing.zip.Stream();
14
- filesToCompress.forEach((file) => {
15
- zipStream.addEntry(file, { relativePath: path.relative(sourceDir, file) });
16
- });
17
- if (debug) {
18
- console.log({
19
- method: "compressToBuffer",
20
- sourceDir,
21
- ignores: ignoreFileList,
22
- filesCount: filesToCompress.length
23
- });
24
- }
25
- const chunks = [];
26
- return new Promise(function(resolve, reject) {
27
- zipStream.on("data", (chunk) => chunks.push(chunk)).on("end", () => resolve(Buffer.concat(chunks))).on("error", reject);
28
- });
29
- }
30
- function getAllFiles(dir, ignores = []) {
31
- const list = [];
32
- fs.readdirSync(dir).forEach((file) => {
33
- const filePath = path.join(dir, file);
34
- const stats = fs.lstatSync(filePath);
35
- if (stats.isDirectory()) {
36
- list.push(...getAllFiles(filePath, ignores));
37
- } else if (!isIgnoreFile(filePath, ignores)) {
38
- list.push(filePath);
39
- }
40
- });
41
- return list;
42
- }
43
- function isIgnoreFile(filePath, ignores) {
44
- const filename = path.basename(filePath);
45
- const dirs = path.normalize(filePath).split(path.sep);
46
- return ignores.some((name) => {
47
- if (name.endsWith("/") && name !== "/") {
48
- return dirs.includes(name.slice(0, -1));
49
- }
50
- return filename === name;
51
- });
52
- }
53
- function pure(url) {
54
- return url.replace(/(?:^https?:\/\/|\/*$)/gi, "");
55
- }
56
- function getSystemTempDir() {
57
- const dir = path.resolve(os.tmpdir(), "webfinder");
58
- if (!fs.existsSync(dir)) {
59
- fs.mkdirSync(dir, { recursive: true });
60
- }
61
- return dir;
62
- }
63
- const nodeVersion = +process.version.replace(/\..+/, "").slice(1);
64
- if (nodeVersion < 20) {
65
- process.emitWarning = function() {
66
- };
67
- }
68
- async function request({
69
- url,
70
- method,
71
- headers,
72
- data
73
- }) {
74
- const hasFileUpload = method === "POST" && data && Object.values(data).some((value) => typeof value === "object" && "buffer" in value);
75
- const reqHeaders = new Headers();
76
- if (headers) {
77
- Object.entries(headers).forEach(([key, value]) => {
78
- reqHeaders.set(key, value);
79
- });
80
- }
81
- const requestInit = { method, headers: reqHeaders };
82
- try {
83
- if (data) {
84
- if (hasFileUpload) {
85
- const formData = new FormData();
86
- Object.entries(data).forEach(([key, value]) => {
87
- if (typeof value === "object" && "buffer" in value) {
88
- const { buffer, filename, contentType: contentType2 } = value;
89
- const blob = new Blob([new Uint8Array(buffer)], { type: contentType2 });
90
- formData.append(key, blob, filename);
91
- } else {
92
- formData.append(key, String(value));
93
- }
94
- });
95
- requestInit.headers = reqHeaders;
96
- requestInit.body = formData;
97
- } else {
98
- reqHeaders.set("content-type", reqHeaders.get("content-type") || "application/json");
99
- requestInit.headers = reqHeaders;
100
- requestInit.body = JSON.stringify(data);
101
- }
102
- }
103
- const response = await fetch(url, requestInit);
104
- let responseData;
105
- const contentType = response.headers.get("content-type");
106
- if (contentType == null ? void 0 : contentType.includes("application/json")) {
107
- responseData = await response.json();
108
- } else {
109
- responseData = await response.text();
110
- }
111
- return {
112
- status: response.status,
113
- message: response.statusText,
114
- data: responseData
115
- };
116
- } catch (err) {
117
- return {
118
- status: 500,
119
- message: err instanceof Error ? err.message : String(err),
120
- data: null
121
- };
122
- }
123
- }
124
- const FinderServers = {
125
- "finder.seayoo.io": [],
126
- "finder.seayoo.com": [],
127
- "finder.seayoo.internal": [],
128
- "finder.dev.seayoo.com": [],
129
- "finder.dev.seayoo.io": []
130
- };
131
- const FinderApiPaths = {
132
- deploy: "/service/deploy",
133
- inspect: "/inspect/supported/projects",
134
- upload: "/service/upload"
135
- };
136
- async function deploy(option) {
137
- const { debug, target, buffer, user, key, payload } = option;
138
- const targetServer = await findTargetServer(target, debug);
139
- if (!targetServer) {
140
- throw `finder不支持该域名部署,请检查 ${target}`.bgRed;
141
- }
142
- if (!user || !key) {
143
- throw `部署缺少认证信息(user & key)`.bgRed;
144
- }
145
- const zipMockName = `${Date.now()}${Math.random().toString(16).slice(-3)}.zip`;
146
- const { status, data } = await request({
147
- url: `${getFinderServerFullPath(targetServer)}${FinderApiPaths.deploy}?target=${encodeURIComponent(pure(target))}`,
148
- method: "POST",
149
- headers: { user, key },
150
- data: {
151
- path: zipMockName,
152
- file: { buffer, filename: zipMockName, contentType: "application/octet-stream" },
153
- payload: payload ? JSON.stringify(payload) : ""
154
- }
155
- });
156
- if (status !== 200) {
157
- throw `部署接口错误(status ${status})`.red;
158
- }
159
- if (!data || typeof data !== "object" || "err" in data && data.err || !("data" in data) || typeof data.data !== "string") {
160
- throw `部署接口响应错误。 ${JSON.stringify(data)}`.red;
161
- }
162
- const url = data.data;
163
- if (debug) {
164
- console.log("部署完毕,接口返回内容", data);
165
- }
166
- return {
167
- previewUrl: url.endsWith("/") ? url.replace(/\/*$/, "/") + "index.html?" + Math.random().toString(16).slice(2) : url.startsWith("http") ? url : ""
168
- };
169
- }
170
- async function upload(option) {
171
- const { debug, target, buffer, user, key } = option;
172
- const targetServer = await findTargetServer(target, debug);
173
- if (!targetServer) {
174
- throw `finder不支持该域名部署,请检查 ${target}`.bgRed;
175
- }
176
- if (!user || !key) {
177
- throw `部署缺少认证信息(user & key)`.bgRed;
178
- }
179
- const filename = path.basename(target);
180
- const deployTarget = path.dirname(pure(target));
181
- const { status, data } = await request({
182
- url: `${getFinderServerFullPath(targetServer)}${FinderApiPaths.upload}?target=${encodeURIComponent(deployTarget)}`,
183
- method: "POST",
184
- headers: { user, key },
185
- data: {
186
- path: filename,
187
- file: { buffer, filename, contentType: "application/octet-stream" }
188
- }
189
- });
190
- if (status !== 200) {
191
- throw `上传接口错误(status ${status})`.red;
192
- }
193
- if (!data || typeof data !== "object" || "err" in data && data.err || !("data" in data) || typeof data.data !== "string") {
194
- throw `上传接口响应错误。 ${JSON.stringify(data)}`.red;
195
- }
196
- return { previewUrl: `https://${pure(target)}` };
197
- }
198
- const getFinderServerFullPath = function(domain) {
199
- return (domain.endsWith("internal") ? "http://" : "https://") + domain;
200
- };
201
- async function findTargetServer(target, debug) {
202
- const t = pure(target);
203
- await updateSupportedProjects(false, debug);
204
- for (const domain in FinderServers) {
205
- if (FinderServers[domain].find((url) => t.startsWith(url))) {
206
- return domain;
207
- }
208
- }
209
- await updateSupportedProjects(true, debug);
210
- for (const domain in FinderServers) {
211
- if (FinderServers[domain].find((url) => t.startsWith(url))) {
212
- return domain;
213
- }
214
- }
215
- return null;
216
- }
217
- async function updateSupportedProjects(force = false, debug) {
218
- const domains = Object.keys(FinderServers);
219
- for (const domain of domains) {
220
- FinderServers[domain] = await getServerSupportedProjects(domain, force, debug) || [];
221
- }
222
- }
223
- async function getServerSupportedProjects(serverDomain, ignoreCache = false, debug) {
224
- const cacheFile = path.resolve(getSystemTempDir(), `${serverDomain}.json`);
225
- if (fs.existsSync(cacheFile) && !ignoreCache) {
226
- try {
227
- const cache = JSON.parse(fs.readFileSync(cacheFile).toString());
228
- if (Array.isArray(cache) && cache.every((d) => typeof d === "string")) {
229
- if (debug) {
230
- console.log({ method: "getServerSupportedProjects", serverDomain, cache });
231
- }
232
- return cache;
233
- }
234
- } catch (e) {
235
- console.error("ReadFinderCacheError", e);
236
- }
237
- }
238
- const inspectURL = `${getFinderServerFullPath(serverDomain)}${FinderApiPaths.inspect}`;
239
- const { status, message, data } = await request({
240
- url: inspectURL,
241
- method: "GET",
242
- headers: { "user-agent": `web finder agent v2` }
243
- });
244
- if (status !== 200) {
245
- if (debug) {
246
- console.error(`服务器 ${inspectURL} 检查接口错误`.bgRed, (message || "").red);
247
- }
248
- return [];
249
- }
250
- if (!Array.isArray(data) || !data.every((d) => typeof d === "string")) {
251
- console.error(`服务器 ${inspectURL} 接口返回内容错误`.bgRed, JSON.stringify(data).red);
252
- return [];
253
- }
254
- if (debug) {
255
- console.log({ method: "getServerSupportedProjects", serverDomain, list: data });
256
- }
257
- const pureList = data.map(pure);
258
- fs.writeFileSync(cacheFile, JSON.stringify(pureList));
259
- return pureList;
260
- }
261
- async function finderDeploy(option) {
262
- const { dist, ignoreFiles, deployTo, user, key, debug, preview, commitLogs } = option;
263
- if (!dist) {
264
- throw "部署参数 dist 缺失".bgRed;
265
- }
266
- if (!fs.existsSync(path.resolve(dist)) || !fs.lstatSync(path.resolve(dist)).isDirectory()) {
267
- throw "部署参数错误,dist 需要是一个存在的文件目录".bgRed + " " + dist.red;
268
- }
269
- const payload = commitLogs ? { 更新内容: commitLogs } : void 0;
270
- if (debug) {
271
- console.log({
272
- method: "finderDeploy",
273
- dist,
274
- deployTo,
275
- ignoreFiles,
276
- payload,
277
- user,
278
- preview
279
- });
280
- }
281
- const buffer = await compressToBuffer(dist, ignoreFiles, debug).catch((e) => {
282
- throw "部署预处理之压缩代码失败".bgRed + " " + (e instanceof Error ? e.message : String(e));
283
- });
284
- if (Array.isArray(deployTo)) {
285
- const results = await Promise.all(
286
- deployTo.map((target) => {
287
- return deploy({ debug, target, buffer, user, key, payload });
288
- })
289
- );
290
- const lastDeployResult = results[results.length - 1];
291
- if (preview && lastDeployResult && lastDeployResult.previewUrl) {
292
- open(lastDeployResult.previewUrl);
293
- }
294
- return lastDeployResult.previewUrl || "";
295
- }
296
- const deployResult = await deploy({ debug, target: deployTo, buffer, user, key, payload });
297
- if (preview && deployResult && deployResult.previewUrl) {
298
- open(deployResult.previewUrl);
299
- }
300
- return deployResult.previewUrl || "";
301
- }
302
- async function finderUpload(option) {
303
- const { filePath, deployTo, user, key, preview, debug } = option;
304
- if (!filePath) {
305
- throw `部署缺少参数 filePath(文件全路径)`.bgRed;
306
- }
307
- if (filePath && !fs.existsSync(filePath)) {
308
- throw `部署文件不存在(请确保传入完整文件路径)`.bgRed + " " + filePath;
309
- }
310
- if (!deployTo) {
311
- throw `部署缺少参数 deployTo(部署目标)`.bgRed;
312
- }
313
- const fileExtension = path.extname(filePath);
314
- const filename = path.basename(filePath);
315
- const target = !deployTo.endsWith(fileExtension) ? `${pure(deployTo)}/${filename}` : pure(deployTo);
316
- const resp = await upload({ debug, target, buffer: Buffer.from(fs.readFileSync(filePath)), user, key });
317
- if (preview && resp.previewUrl) {
318
- open(resp.previewUrl);
319
- }
320
- }
321
- function viteDeployPlugin(option) {
322
- let distDir = null;
323
- return {
324
- name: "finerDeployAgent",
325
- generateBundle({ dir }) {
326
- distDir = process.cwd();
327
- if (dir) {
328
- distDir = path.resolve(distDir, dir);
329
- }
330
- },
331
- async closeBundle() {
332
- var _a, _b;
333
- if (!distDir) {
334
- console.error("没有找到部署资源,请尝试检查 build 是否生成了正确的资源".bgRed);
335
- return;
336
- }
337
- const result = await finderDeploy({
338
- preview: true,
339
- ...option,
340
- dist: distDir
341
- }).catch((e) => e instanceof Error ? e : typeof e === "string" ? new Error(e) : new Error(e + ""));
342
- if (result instanceof Error) {
343
- (_a = option.onError) == null ? void 0 : _a.call(option);
344
- console.log("部署失败".bgRed, result.message);
345
- } else {
346
- (_b = option.onFinished) == null ? void 0 : _b.call(option);
347
- console.log("部署成功".bgGreen, (result || "").green);
348
- }
349
- }
350
- };
351
- }
352
- exports.finderDeploy = finderDeploy;
353
- exports.finderUpload = finderUpload;
354
- exports.viteDeployPlugin = viteDeployPlugin;