@seayoo-web/finder 1.1.0 → 1.2.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/dist/core.js +1 -1
- package/index.d.ts +6 -6
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const compressing=require("compressing"),pkg=require("../package.json"),needle=require("needle"),crypto=require("crypto"),fsp=require("fs/promises"),open=require("open"),path=require("path"),fs=require("fs"),os=require("os");require("colors");const finderServers={"finder.seayoo.io":[],"finder.seayoo.com":[],"finder.seayoo.internal":[],"finder.dev.seayoo.com":[]},paths={deploy:"/service/deploy",inspect:"/inspect/supported/projects",upload:"/service/upload"};let isDebugMode=!1;async function finderDeploy({dist:e,zip:r,archive:t,deployTo:i,user:n,key:o,debug:s,preview:a}){if(isDebugMode=!!s,!e&&!r)throw"部署参数 dist(文件目录) 或者 zip(打包文件) 需要二选一".bgBrightRed;if(r&&!/.+\.zip$/i.test(r))throw`部署参数 zip 需要指定一个zip文件 ${r}`;if(r&&!fs.existsSync(r))throw"部署参数 zip 指定的文件不存在(请确保传入完整文件路径)".bgBrightRed+" "+r;if(!(r||fs.existsSync(path.resolve(e))&&fs.lstatSync(path.resolve(e)).isDirectory()))throw"部署参数错误,dist(文件目录) 需要是一个存在的文件目录".bgBrightRed+" "+e;if(!i&&!t)throw"部署参数 archive(打包归档) 和 deployTo(部署文件) 至少需要二选一".bgBrightRed;const
|
|
1
|
+
const compressing=require("compressing"),pkg=require("../package.json"),needle=require("needle"),crypto=require("crypto"),fsp=require("fs/promises"),open=require("open"),path=require("path"),fs=require("fs"),os=require("os");require("colors");const finderServers={"finder.seayoo.io":[],"finder.seayoo.com":[],"finder.seayoo.internal":[],"finder.dev.seayoo.com":[]},paths={deploy:"/service/deploy",inspect:"/inspect/supported/projects",upload:"/service/upload"};let isDebugMode=!1;async function finderDeploy({dist:e,zip:r,archive:t,deployTo:i,user:n,key:o,debug:s,preview:a}){if(isDebugMode=!!s,!e&&!r)throw"部署参数 dist(文件目录) 或者 zip(打包文件) 需要二选一".bgBrightRed;if(r&&!/.+\.zip$/i.test(r))throw`部署参数 zip 需要指定一个zip文件 ${r}`;if(r&&!fs.existsSync(r))throw"部署参数 zip 指定的文件不存在(请确保传入完整文件路径)".bgBrightRed+" "+r;if(!(r||fs.existsSync(path.resolve(e))&&fs.lstatSync(path.resolve(e)).isDirectory()))throw"部署参数错误,dist(文件目录) 需要是一个存在的文件目录".bgBrightRed+" "+e;if(!i&&!t)throw"部署参数 archive(打包归档) 和 deployTo(部署文件) 至少需要二选一".bgBrightRed;const p=r||await async function(){const r=path.resolve(getTempDir(),getRandomZipFileName());try{await compressing.zip.compressDir(e,r,{ignoreBase:!0})}catch(e){throw"部署预处理之压缩文件目录失败".bgBrightRed+" "+e.toString()}return r}(),d=Buffer.from(fs.readFileSync(p));if(null!==t&&await archiveFile(p,t,r!==p),!i)return;if(Array.isArray(i)){let e;for(const r of i)e=await deploy({target:r,buffer:d,user:n,key:o});return a&&e&&e.previewUrl&&open(e.previewUrl),e}const c=await deploy({target:i,buffer:d,user:n,key:o});return a&&c&&c.previewUrl&&open(c.previewUrl),c}async function finderUpload({file:e,deployTo:r,user:t,key:i,preview:n}){if(!e)throw"部署缺少参数 file(文件全路径)".bgBrightRed;if(e&&!fs.existsSync(e))throw"部署file参数指定的文件不存在(请确保传入完整文件路径)".bgBrightRed+" "+e;if(!r)throw"部署缺少参数 deployTo(部署目标)".bgBrightRed;const o=path.extname(e);r.endsWith(o)||(r=r.replace(/\/*$/,"")+"/"+md5(await fsp.readFile(e)));const s=await upload({target:r,buffer:Buffer.from(fs.readFileSync(e)),user:t,key:i});n&&s&&s.previewUrl&&open(s.previewUrl)}const getFinderServerFullPath=function(e){return(e.endsWith("internal")?"http://":"https://")+e};function getTempDir(){const e=path.resolve(os.tmpdir(),"webfinder");return fs.existsSync(e)||fs.mkdirSync(e,{recursive:!0}),e}function md5(e){return crypto.createHash("md5").update(e).digest("hex").toLowerCase()}function pure(e){return e.replace(/^https?:\/\//i,"")}function getRandomZipFileName(){return Date.now()+Math.random().toString(16).slice(2)+".zip"}function getDefaultArchiveFileName(){const e=new Date,r=e=>("0"+e).slice(-2);return[e.getFullYear(),r(e.getMonth()+1),r(e.getDate()),r(e.getHours()),r(e.getMinutes())].join("")+".zip"}async function archiveFile(e,r,t){if(!r)return;const i=/\.zip$/i.test(r)?path.resolve(r):path.resolve(r,getDefaultArchiveFileName());await fsp.mkdir(path.dirname(i),{recursive:!0}).catch((e=>{throw"检查归档目录失败 ".brightRed+" "+e.toString()})),await fsp.copyFile(e,i).catch((()=>{console.error("归档文件失败".brightRed)})),t&&await fsp.unlink(e).catch((()=>{console.error(`删除zip文件失败 ${e}`.brightRed)}))}async function deploy({target:e,buffer:r,user:t,key:i}){const n=await findTargetServer(e);if(!n)throw`finder不支持该域名部署,请检查 ${e}`.bgBrightRed;if(!t||!i)throw"部署缺少认证信息(user & key)".bgBrightRed;return new Promise(((o,s)=>{const a=getRandomZipFileName();needle.post(`${getFinderServerFullPath(n)}${paths.deploy}?target=${encodeURIComponent(pure(e))}`,{path:a,file:{buffer:r,filename:a,content_type:"application/octet-stream"}},{headers:{user:t,key:i},multipart:!0},(function(e,r){if(e)return s("部署接口错误".bgBrightRed+" "+JSON.stringify(e));const t=r.body;return t.err?s(t.desc):t.data&&"string"==typeof t.data?void o({previewUrl:t.data.endsWith("/")?t.data.replace(/\/*$/,"/")+"index.html?"+Math.random().toString(16).slice(2):t.data}):s("部署接口数据错误".bgBrightRed+" "+(r.body.message||JSON.stringify(r.body)))}))}))}async function upload({target:e,buffer:r,user:t,key:i}){const n=await findTargetServer(e);if(!n)throw`finder不支持该域名部署,请检查 ${e}`.bgBrightRed;if(!t||!i)throw"部署缺少认证信息(user & key)".bgBrightRed;return new Promise(((o,s)=>{const a=path.basename(e),p=path.dirname(pure(e));needle.post(`${getFinderServerFullPath(n)}${paths.upload}?target=${encodeURIComponent(p)}`,{path:a,file:{buffer:r,filename:a,content_type:"application/octet-stream"}},{headers:{user:t,key:i},multipart:!0},(function(r,t){if(r)return s("上传接口错误".bgBrightRed+" "+JSON.stringify(r));const i=t.body;return i.err?s(i.desc):i.data&&"string"==typeof i.data?void o({previewUrl:"https://"+pure(e)}):s("上传接口数据错误".bgBrightRed+" "+JSON.stringify(t.body))}))}))}async function findTargetServer(e){const r=pure(e);await updateSupportedProjects();for(const e in finderServers)if(finderServers[e].find((e=>r.startsWith(e))))return e;await updateSupportedProjects(!0);for(const e in finderServers)if(finderServers[e].find((e=>r.startsWith(e))))return e;return null}async function updateSupportedProjects(e){const r=Object.keys(finderServers);for(const t of r)finderServers[t]=await getServerSupportedProjects(t,e)||[]}async function getServerSupportedProjects(e,r){const t=path.resolve(getTempDir(),e+".json");if(fs.existsSync(t)&&!r){const e=fs.readFileSync(t).toString();try{const r=JSON.parse(e);if(Array.isArray(r))return r}catch(e){isDebugMode&&console.error("cache file form error".brightRed,e)}}return await new Promise(((r,i)=>{const n=`${getFinderServerFullPath(e)}${paths.inspect}`;needle.get(n,{user_agent:`web finder agent v${pkg.version}`},(function(i,o){if(i)return isDebugMode&&console.error(`服务器 ${n} 检查接口错误`.brightRed+" "+i.toString()),r([]);const s=o.body;if(!Array.isArray(s))return isDebugMode&&console.warn(`服务器 ${n} 接口返回内容错误`.brightRed+" "+JSON.stringify(s)),r([]);isDebugMode&&console.log(`${e} 支持服务器列表`,s);const a=s.map((e=>pure(e,!0)));fsp.writeFile(t,JSON.stringify(a)).then((()=>{r(a)}),(e=>{isDebugMode&&console.error("write cache error".brightRed,e),r(a)}))}))}))}exports.finderDeploy=finderDeploy,exports.finderUpload=finderUpload;
|
package/index.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ interface IDeployCoreOptions {
|
|
|
3
3
|
dist?: string;
|
|
4
4
|
/** 如果不指定目录,可以指定一个zip文件,指定zip后,dist无效 */
|
|
5
5
|
zip?: string,
|
|
6
|
-
/** 归档备份的文件名,如果不指定文件名,则按照时间戳命名zip
|
|
7
|
-
archive?: string,
|
|
6
|
+
/** 归档备份的文件名,如果不指定文件名,则按照时间戳命名zip文件,设置为 null 则不归档文件 */
|
|
7
|
+
archive?: string | null,
|
|
8
8
|
/** 部署目标地址 */
|
|
9
|
-
deployTo: string,
|
|
9
|
+
deployTo: string | string[],
|
|
10
10
|
/** 部署授权用户名 */
|
|
11
11
|
user: string,
|
|
12
12
|
/** 部署授权key */
|
|
@@ -65,12 +65,12 @@ export declare const deployPlugin: {
|
|
|
65
65
|
vite: (options: {
|
|
66
66
|
/** 如果不指定目录,可以指定一个zip文件,指定zip后,dist无效 */
|
|
67
67
|
zip?: string,
|
|
68
|
-
/** 归档备份的文件名,如果不指定文件名,则按照时间戳命名zip
|
|
69
|
-
archive?: string,
|
|
68
|
+
/** 归档备份的文件名,如果不指定文件名,则按照时间戳命名zip文件,设置为 null 则不保留归档文档 */
|
|
69
|
+
archive?: string | null,
|
|
70
70
|
/** 是否调试输出更多信息 */
|
|
71
71
|
debug?: boolean,
|
|
72
72
|
/** 部署目标地址 */
|
|
73
|
-
deployTo: string,
|
|
73
|
+
deployTo: string | string[],
|
|
74
74
|
/** 部署授权用户名 */
|
|
75
75
|
user: string,
|
|
76
76
|
/** 部署授权key */
|