@seayoo-web/finder 2.0.1 → 2.0.3

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.cjs CHANGED
@@ -78,7 +78,7 @@ async function request({
78
78
  Object.entries(data).forEach(([key, value]) => {
79
79
  if (typeof value === "object" && "buffer" in value) {
80
80
  const { buffer, filename, contentType: contentType2 } = value;
81
- const blob = new Blob([buffer], { type: contentType2 });
81
+ const blob = new Blob([new Uint8Array(buffer)], { type: contentType2 });
82
82
  formData.append(key, blob, filename);
83
83
  } else {
84
84
  formData.append(key, String(value));
@@ -241,7 +241,7 @@ async function getServerSupportedProjects(serverDomain, ignoreCache = false, deb
241
241
  headers: { UserAgent: `web finder agent v2` }
242
242
  });
243
243
  if (status !== 200) {
244
- if (!serverDomain.includes(".internal")) {
244
+ if (debug) {
245
245
  console.error(`服务器 ${inspectURL} 检查接口错误`.bgRed, (message || "").red);
246
246
  }
247
247
  return [];
package/dist/index.js CHANGED
@@ -76,7 +76,7 @@ async function request({
76
76
  Object.entries(data).forEach(([key, value]) => {
77
77
  if (typeof value === "object" && "buffer" in value) {
78
78
  const { buffer, filename, contentType: contentType2 } = value;
79
- const blob = new Blob([buffer], { type: contentType2 });
79
+ const blob = new Blob([new Uint8Array(buffer)], { type: contentType2 });
80
80
  formData.append(key, blob, filename);
81
81
  } else {
82
82
  formData.append(key, String(value));
@@ -239,7 +239,7 @@ async function getServerSupportedProjects(serverDomain, ignoreCache = false, deb
239
239
  headers: { UserAgent: `web finder agent v2` }
240
240
  });
241
241
  if (status !== 200) {
242
- if (!serverDomain.includes(".internal")) {
242
+ if (debug) {
243
243
  console.error(`服务器 ${inspectURL} 检查接口错误`.bgRed, (message || "").red);
244
244
  }
245
245
  return [];
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@seayoo-web/finder",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "agent for web finder",
5
5
  "type": "module",
6
6
  "source": "index.ts",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.js",
9
9
  "types": "./types/index.d.ts",
10
+ "files": [
11
+ "dist",
12
+ "types",
13
+ "README.md"
14
+ ],
10
15
  "exports": {
11
16
  ".": {
12
17
  "types": "./types/index.d.ts",
@@ -1,81 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- import { zip } from "compressing";
6
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
7
-
8
- import { compressToBuffer, getAllFiles, isIgnoreFile } from "../src/compress";
9
-
10
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
- const dirForCompress = path.resolve(__dirname, "./testCompress");
12
-
13
- describe("compressing utils", () => {
14
- beforeAll(async () => {
15
- await fs.mkdir(dirForCompress, { recursive: true });
16
- await fs.mkdir(path.join(dirForCompress, "skip"), { recursive: true });
17
- await fs.mkdir(path.join(dirForCompress, "nestDir"), { recursive: true });
18
- await fs.writeFile(path.join(dirForCompress, "a.js"), "console.log('a')");
19
- await fs.writeFile(path.join(dirForCompress, "b.css"), "body{}");
20
- await fs.writeFile(path.join(dirForCompress, "ignore.js"), "console.log('j')");
21
- await fs.writeFile(path.join(dirForCompress, "skip", "e.json"), "{}");
22
- await fs.writeFile(path.join(dirForCompress, "nestDir", "c.html"), "<body></body>");
23
- });
24
- afterAll(async () => {
25
- await fs.rm(dirForCompress, { recursive: true, force: true });
26
- });
27
-
28
- test("isIgnoreFile", () => {
29
- const ignores = ["skip/", "ignore.js"];
30
- expect(isIgnoreFile(["test", "skip", "test.json"].join(path.sep), ignores)).toBe(true);
31
- expect(isIgnoreFile(["test", "skip", "test.json"].join(path.sep), ["skip"])).toBe(false);
32
- expect(isIgnoreFile(["test", "Skip", "test.json"].join(path.sep), ["skip/"])).toBe(false);
33
- expect(isIgnoreFile(["test", "skip1", "test.json"].join(path.sep), ignores)).toBe(false);
34
- expect(isIgnoreFile(["test", "skip1", "ignore.js"].join(path.sep), ignores)).toBe(true);
35
- expect(isIgnoreFile(["test", "skip1", "ignore.json"].join(path.sep), ignores)).toBe(false);
36
- expect(isIgnoreFile(["test", "skip1", "iGnore.js"].join(path.sep), ignores)).toBe(false);
37
- });
38
-
39
- test("getAllFiles", () => {
40
- const files = getAllFiles(dirForCompress);
41
- expect(files.sort()).toEqual(
42
- [
43
- path.join(dirForCompress, "a.js"),
44
- path.join(dirForCompress, "b.css"),
45
- path.join(dirForCompress, "ignore.js"),
46
- path.join(dirForCompress, "skip", "e.json"),
47
- path.join(dirForCompress, "nestDir", "c.html"),
48
- ].sort(),
49
- );
50
- });
51
-
52
- test("compressToBuffer", async () => {
53
- const buf = await compressToBuffer(dirForCompress, ["skip/", "ignore.js"]);
54
- expect(Buffer.isBuffer(buf)).toBe(true);
55
-
56
- const tempUnzipDir = path.join(__dirname, "temp-unzip-dir");
57
- await fs.mkdir(tempUnzipDir, { recursive: true });
58
- try {
59
- await zip.uncompress(buf, tempUnzipDir);
60
- const files = getAllFiles(tempUnzipDir, []);
61
- expect(files.sort()).toEqual(
62
- [
63
- path.join(tempUnzipDir, "a.js"),
64
- path.join(tempUnzipDir, "b.css"),
65
- path.join(tempUnzipDir, "nestDir", "c.html"),
66
- ].sort(),
67
- );
68
-
69
- // 验证解压后的文件是否存在且内容正确
70
- const ajs = await fs.readFile(path.join(tempUnzipDir, "a.js"), "utf-8");
71
- const bcss = await fs.readFile(path.join(tempUnzipDir, "b.css"), "utf-8");
72
- const chtml = await fs.readFile(path.join(tempUnzipDir, "nestDir", "c.html"), "utf-8");
73
- expect(ajs).toBe("console.log('a')");
74
- expect(bcss).toBe("body{}");
75
- expect(chtml).toBe("<body></body>");
76
- } finally {
77
- // 清理解压目录
78
- await fs.rm(tempUnzipDir, { recursive: true, force: true });
79
- }
80
- });
81
- });
package/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from "./src/core";
2
- export * from "./src/plugin";
package/src/compress.ts DELETED
@@ -1,61 +0,0 @@
1
- import { readdirSync, lstatSync } from "fs";
2
- import { join, relative, normalize, basename, sep } from "path";
3
-
4
- import { zip } from "compressing";
5
-
6
- // 部署代码默认的忽略列表
7
- const presetIgnores = ["node_modules/", ".git/", ".vscode/", "__MACOSX/", ".DS_Store"];
8
-
9
- /** 代码压缩 */
10
- export function compressToBuffer(sourceDir: string, ignoreFiles?: string[], debug?: boolean): Promise<Buffer> {
11
- const ignoreFileList = [...presetIgnores, ...(ignoreFiles || [])];
12
- const filesToCompress = getAllFiles(sourceDir, ignoreFileList);
13
- const zipStream = new zip.Stream();
14
- // 计算文件在压缩包中的相对路径
15
- filesToCompress.forEach((file) => {
16
- zipStream.addEntry(file, { relativePath: relative(sourceDir, file) });
17
- });
18
- if (debug) {
19
- console.log({
20
- method: "compressToBuffer",
21
- sourceDir,
22
- ignores: ignoreFileList,
23
- filesCount: filesToCompress.length,
24
- });
25
- }
26
- // 将压缩流写入buffer
27
- const chunks: Buffer[] = [];
28
- return new Promise(function (resolve, reject) {
29
- zipStream
30
- .on("data", (chunk) => chunks.push(chunk as Buffer))
31
- .on("end", () => resolve(Buffer.concat(chunks)))
32
- .on("error", reject);
33
- });
34
- }
35
-
36
- export function getAllFiles(dir: string, ignores: string[] = []) {
37
- const list: string[] = [];
38
- readdirSync(dir).forEach((file) => {
39
- const filePath = join(dir, file);
40
- const stats = lstatSync(filePath);
41
- if (stats.isDirectory()) {
42
- // 如果是文件夹,递归处理
43
- list.push(...getAllFiles(filePath, ignores));
44
- // 如果是文件,检查是否符合过滤规则
45
- } else if (!isIgnoreFile(filePath, ignores)) {
46
- list.push(filePath);
47
- }
48
- });
49
- return list;
50
- }
51
-
52
- export function isIgnoreFile(filePath: string, ignores: string[]) {
53
- const filename = basename(filePath);
54
- const dirs = normalize(filePath).split(sep);
55
- return ignores.some((name) => {
56
- if (name.endsWith("/") && name !== "/") {
57
- return dirs.includes(name.slice(0, -1));
58
- }
59
- return filename === name;
60
- });
61
- }
package/src/core.ts DELETED
@@ -1,104 +0,0 @@
1
- import { existsSync, lstatSync, readFileSync } from "fs";
2
- import { basename, extname, resolve } from "path";
3
-
4
- import open from "open";
5
-
6
- import "colors";
7
- import { compressToBuffer } from "./compress";
8
- import { deploy, upload } from "./service";
9
- import { pure } from "./utils";
10
-
11
- /** 部署一个目录 */
12
- export async function finderDeploy(option: {
13
- /** 需要推送的代码目录 */
14
- dist: string;
15
- /** 忽略部署的文件,如果是目录则需要以 / 结尾。暂不支持模糊匹配 */
16
- ignoreFiles?: string[];
17
- /** 部署的目标地址 */
18
- deployTo: string | string[];
19
- /** 部署 user */
20
- user: string;
21
- /** 部署 key */
22
- key: string;
23
- /** 是否输出更多调试信息 */
24
- debug?: boolean;
25
- /** 是否部署完毕后打开目标文件(index.html) */
26
- preview?: boolean;
27
- /** 代码的 commit log 信息,换行用 \n */
28
- commitLogs?: string;
29
- }): Promise<string> {
30
- const { dist, ignoreFiles, deployTo, user, key, debug, preview, commitLogs } = option;
31
- if (!dist) {
32
- throw "部署参数 dist 缺失".bgRed;
33
- }
34
- if (!existsSync(resolve(dist)) || !lstatSync(resolve(dist)).isDirectory()) {
35
- throw "部署参数错误,dist 需要是一个存在的文件目录".bgRed + " " + dist.red;
36
- }
37
- const payload = commitLogs ? { 更新内容: commitLogs } : undefined;
38
- if (debug) {
39
- console.log({
40
- method: "finderDeploy",
41
- dist,
42
- deployTo,
43
- ignoreFiles,
44
- payload,
45
- user,
46
- preview,
47
- });
48
- }
49
- // 压缩代码准备上传
50
- const buffer = await compressToBuffer(dist, ignoreFiles, debug).catch((e) => {
51
- throw "部署预处理之压缩代码失败".bgRed + " " + (e instanceof Error ? e.message : String(e));
52
- });
53
- if (Array.isArray(deployTo)) {
54
- // 多次部署
55
- const results = await Promise.all(
56
- deployTo.map((target) => {
57
- return deploy({ debug, target, buffer, user, key, payload });
58
- }),
59
- );
60
- const lastDeployResult = results[results.length - 1];
61
- if (preview && lastDeployResult && lastDeployResult.previewUrl) {
62
- open(lastDeployResult.previewUrl);
63
- }
64
- return lastDeployResult.previewUrl || "";
65
- }
66
- // 单次部署
67
- const deployResult = await deploy({ debug, target: deployTo, buffer, user, key, payload });
68
- if (preview && deployResult && deployResult.previewUrl) {
69
- open(deployResult.previewUrl);
70
- }
71
- return deployResult.previewUrl || "";
72
- }
73
-
74
- /** 上传一个文件到 finder */
75
- export async function finderUpload(option: {
76
- /** 需要上传的文件全局路 */
77
- filePath: string;
78
- /** 部署目标全路径,需要包含文件名 */
79
- deployTo: string;
80
- user: string;
81
- key: string;
82
- debug?: boolean;
83
- preview?: boolean;
84
- }) {
85
- const { filePath, deployTo, user, key, preview, debug } = option;
86
-
87
- if (!filePath) {
88
- throw `部署缺少参数 filePath(文件全路径)`.bgRed;
89
- }
90
- if (filePath && !existsSync(filePath)) {
91
- throw `部署文件不存在(请确保传入完整文件路径)`.bgRed + " " + filePath;
92
- }
93
- if (!deployTo) {
94
- throw `部署缺少参数 deployTo(部署目标)`.bgRed;
95
- }
96
-
97
- const fileExtension = extname(filePath);
98
- const filename = basename(filePath);
99
- const target = !deployTo.endsWith(fileExtension) ? `${pure(deployTo)}/${filename}` : pure(deployTo);
100
- const resp = await upload({ debug, target, buffer: Buffer.from(readFileSync(filePath)), user, key });
101
- if (preview && resp.previewUrl) {
102
- open(resp.previewUrl);
103
- }
104
- }
package/src/plugin.ts DELETED
@@ -1,39 +0,0 @@
1
- import { resolve } from "path";
2
-
3
- import { finderDeploy } from "./core";
4
- import "colors";
5
-
6
- type FinderDeployVitePluginOption = Omit<Parameters<typeof finderDeploy>[0], "dist"> & {
7
- onFinished?: () => unknown;
8
- onError?: () => unknown;
9
- };
10
-
11
- export function viteDeployPlugin(option: FinderDeployVitePluginOption) {
12
- let distDir: string | null = null;
13
- return {
14
- name: "finerDeployAgent",
15
- generateBundle({ dir }: { dir: string }) {
16
- distDir = process.cwd();
17
- if (dir) {
18
- distDir = resolve(distDir, dir);
19
- }
20
- },
21
- async closeBundle() {
22
- if (!distDir) {
23
- console.error("没有找到部署资源,请尝试检查 build 是否生成了正确的资源".bgRed);
24
- return;
25
- }
26
- const result = await finderDeploy({
27
- preview: true,
28
- ...option,
29
- dist: distDir,
30
- }).catch(() => null);
31
- if (result === null) {
32
- option.onError?.();
33
- } else {
34
- option.onFinished?.();
35
- console.log("部署成功".bgGreen, (result || "").green);
36
- }
37
- },
38
- };
39
- }
package/src/service.ts DELETED
@@ -1,183 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync } from "fs";
2
- import { basename, dirname, resolve } from "path";
3
-
4
- import { getSystemTempDir, pure, request } from "./utils";
5
-
6
- /** finder 服务器列表以及所支持的域名 */
7
- const FinderServers: Record<string, string[]> = {
8
- "finder.seayoo.io": [],
9
- "finder.seayoo.com": [],
10
- "finder.seayoo.internal": [],
11
- "finder.dev.seayoo.com": [],
12
- "finder.dev.seayoo.io": [],
13
- };
14
-
15
- /** finder 的 api path */
16
- const FinderApiPaths = {
17
- deploy: "/service/deploy",
18
- inspect: "/inspect/supported/projects",
19
- upload: "/service/upload",
20
- } as const;
21
-
22
- /** 将指定的 zip buffer 部署到指定目录 */
23
- export async function deploy(option: {
24
- debug?: boolean;
25
- target: string;
26
- buffer: Buffer;
27
- user: string;
28
- key: string;
29
- payload?: Record<string, string>;
30
- }): Promise<{ previewUrl?: string }> {
31
- const { debug, target, buffer, user, key, payload } = option;
32
- const targetServer = await findTargetServer(target, debug);
33
- if (!targetServer) {
34
- throw `finder不支持该域名部署,请检查 ${target}`.bgRed;
35
- }
36
- if (!user || !key) {
37
- throw `部署缺少认证信息(user & key)`.bgRed;
38
- }
39
- const zipMockName = `${Date.now()}${Math.random().toString(16).slice(-3)}.zip`;
40
- const { status, message, data } = await request({
41
- url: `${getFinderServerFullPath(targetServer)}${FinderApiPaths.deploy}?target=${encodeURIComponent(pure(target))}`,
42
- method: "POST",
43
- headers: { user, key },
44
- data: {
45
- path: zipMockName,
46
- file: { buffer, filename: zipMockName, contentType: "application/octet-stream" },
47
- payload: JSON.stringify(payload || ""),
48
- },
49
- });
50
- if (status !== 200) {
51
- throw `${`部署接口错误(${status})`.bgRed} ${message || ""}.red`;
52
- }
53
- if (!data || typeof data !== "object") {
54
- throw `部署接口响应错误,请自行检查是否部署成功。`.bgRed + JSON.stringify(data).red;
55
- }
56
- if ("err" in data || !("data" in data) || typeof data.data !== "string") {
57
- throw `部署接口错误。`.bgRed + JSON.stringify(data).red;
58
- }
59
- // 返回预览页面地址
60
- const url = data.data;
61
- if (debug) {
62
- console.log("部署完毕,接口返回内容", data);
63
- }
64
- return {
65
- previewUrl: url.endsWith("/")
66
- ? url.replace(/\/*$/, "/") + "index.html?" + Math.random().toString(16).slice(2)
67
- : url.startsWith("http")
68
- ? url
69
- : "",
70
- };
71
- }
72
-
73
- /** 将文件上传到指定位置 */
74
- export async function upload(option: {
75
- debug?: boolean;
76
- target: string;
77
- buffer: Buffer;
78
- user: string;
79
- key: string;
80
- }): Promise<{ previewUrl?: string }> {
81
- const { debug, target, buffer, user, key } = option;
82
- const targetServer = await findTargetServer(target, debug);
83
- if (!targetServer) {
84
- throw `finder不支持该域名部署,请检查 ${target}`.bgRed;
85
- }
86
- if (!user || !key) {
87
- throw `部署缺少认证信息(user & key)`.bgRed;
88
- }
89
- const filename = basename(target);
90
- const deployTarget = dirname(pure(target));
91
- const { status, message, data } = await request({
92
- url: `${getFinderServerFullPath(targetServer)}${FinderApiPaths.upload}?target=${encodeURIComponent(deployTarget)}`,
93
- method: "POST",
94
- headers: { user, key },
95
- data: {
96
- path: filename,
97
- file: { buffer, filename, contentType: "application/octet-stream" },
98
- },
99
- });
100
- if (status !== 200) {
101
- throw `${`上传接口错误(${status})`.bgRed} ${message || ""}.red`;
102
- }
103
- if (!data || typeof data !== "object") {
104
- throw `上传接口响应错误,请自行检查是否上传成功。`.bgRed + JSON.stringify(data).red;
105
- }
106
- if ("err" in data || !("data" in data) || typeof data.data !== "string") {
107
- throw `上传接口错误。`.bgRed + JSON.stringify(data).red;
108
- }
109
- return { previewUrl: `https://${pure(target)}` };
110
- }
111
-
112
- const getFinderServerFullPath = function (domain: string) {
113
- return (domain.endsWith("internal") ? "http://" : "https://") + domain;
114
- };
115
-
116
- async function findTargetServer(target: string, debug?: boolean) {
117
- const t = pure(target);
118
- await updateSupportedProjects(false, debug);
119
- for (const domain in FinderServers) {
120
- if (FinderServers[domain].find((url) => t.startsWith(url))) {
121
- return domain;
122
- }
123
- }
124
- // 如果没有找到则强制查询后再来一次
125
- await updateSupportedProjects(true, debug);
126
- for (const domain in FinderServers) {
127
- if (FinderServers[domain].find((url) => t.startsWith(url))) {
128
- return domain;
129
- }
130
- }
131
- // 还是没有找到就返回
132
- return null;
133
- }
134
-
135
- async function updateSupportedProjects(force = false, debug?: boolean) {
136
- const domains = Object.keys(FinderServers);
137
- for (const domain of domains) {
138
- FinderServers[domain] = (await getServerSupportedProjects(domain, force, debug)) || [];
139
- }
140
- }
141
-
142
- async function getServerSupportedProjects(
143
- serverDomain: string,
144
- ignoreCache = false,
145
- debug?: boolean,
146
- ): Promise<string[]> {
147
- const cacheFile = resolve(getSystemTempDir(), `${serverDomain}.json`);
148
- if (existsSync(cacheFile) && !ignoreCache) {
149
- try {
150
- const cache = JSON.parse(readFileSync(cacheFile).toString());
151
- if (Array.isArray(cache) && cache.every((d) => typeof d === "string")) {
152
- if (debug) {
153
- console.log({ method: "getServerSupportedProjects", serverDomain, cache });
154
- }
155
- return cache;
156
- }
157
- } catch (e) {
158
- console.error("ReadFinderCacheError", e);
159
- }
160
- }
161
- const inspectURL = `${getFinderServerFullPath(serverDomain)}${FinderApiPaths.inspect}`;
162
- const { status, message, data } = await request({
163
- url: inspectURL,
164
- method: "GET",
165
- headers: { UserAgent: `web finder agent v2` },
166
- });
167
- if (status !== 200) {
168
- if (!serverDomain.includes(".internal")) {
169
- console.error(`服务器 ${inspectURL} 检查接口错误`.bgRed, (message || "").red);
170
- }
171
- return [];
172
- }
173
- if (!Array.isArray(data) || !data.every((d) => typeof d === "string")) {
174
- console.error(`服务器 ${inspectURL} 接口返回内容错误`.bgRed, JSON.stringify(data).red);
175
- return [];
176
- }
177
- if (debug) {
178
- console.log({ method: "getServerSupportedProjects", serverDomain, list: data });
179
- }
180
- const pureList = data.map(pure);
181
- writeFileSync(cacheFile, JSON.stringify(pureList));
182
- return pureList;
183
- }
package/src/utils.ts DELETED
@@ -1,97 +0,0 @@
1
- import fs from "fs";
2
- import os from "os";
3
- import path from "path";
4
-
5
- export function pure(url: string) {
6
- return url.replace(/(?:^https?:\/\/|\/*$)/gi, "");
7
- }
8
-
9
- export function getSystemTempDir() {
10
- const dir = path.resolve(os.tmpdir(), "webfinder");
11
- if (!fs.existsSync(dir)) {
12
- fs.mkdirSync(dir, { recursive: true });
13
- }
14
- return dir;
15
- }
16
-
17
- type RequestData = Record<string, string | number | { buffer: Buffer; contentType: string; filename: string }>;
18
-
19
- export async function request({
20
- url,
21
- method,
22
- headers,
23
- data,
24
- }: {
25
- url: string;
26
- method: "GET" | "POST";
27
- headers?: Record<string, string>;
28
- data?: RequestData;
29
- }): Promise<{ status: number; message?: string; data: unknown }> {
30
- // 检查是否有文件需要上传
31
- const hasFileUpload =
32
- method === "POST" && data && Object.values(data).some((value) => typeof value === "object" && "buffer" in value);
33
-
34
- // 准备请求配置
35
- const requestInit: RequestInit = {
36
- method,
37
- headers: { ...headers },
38
- };
39
-
40
- // 处理请求体
41
- try {
42
- if (data) {
43
- if (hasFileUpload) {
44
- // 使用 FormData 处理包含文件的请求
45
- const formData = new FormData();
46
-
47
- // 遍历数据,将普通字段和文件字段添加到 FormData
48
- Object.entries(data).forEach(([key, value]) => {
49
- if (typeof value === "object" && "buffer" in value) {
50
- // 处理文件字段
51
- const { buffer, filename, contentType } = value;
52
- const blob = new Blob([buffer], { type: contentType });
53
- formData.append(key, blob, filename);
54
- } else {
55
- // 处理普通字段
56
- formData.append(key, String(value));
57
- }
58
- });
59
-
60
- requestInit.body = formData;
61
- } else {
62
- // 普通 JSON 请求
63
- requestInit.headers = {
64
- "Content-Type": "application/json",
65
- ...headers,
66
- };
67
- requestInit.body = JSON.stringify(data);
68
- }
69
- }
70
-
71
- // 发送请求
72
- const response = await fetch(url, requestInit);
73
-
74
- // 尝试解析响应
75
- let responseData: unknown;
76
- const contentType = response.headers.get("content-type");
77
-
78
- if (contentType?.includes("application/json")) {
79
- responseData = await response.json();
80
- } else {
81
- responseData = await response.text();
82
- }
83
-
84
- // 返回统一的响应格式
85
- return {
86
- status: response.status,
87
- message: response.statusText,
88
- data: responseData,
89
- };
90
- } catch (err) {
91
- return {
92
- status: 500,
93
- message: err instanceof Error ? err.message : String(err),
94
- data: null,
95
- };
96
- }
97
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "@seayoo-web/tsconfig/node.json",
3
- "include": ["src/**/*.ts", "index.ts"],
4
- "compilerOptions": {
5
- "outDir": "dist",
6
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
7
- "declarationDir": "./types"
8
- }
9
- }
package/vite.config.ts DELETED
@@ -1,27 +0,0 @@
1
- import { builtinModules } from "module";
2
- import { join } from "node:path";
3
-
4
- import { defineConfig } from "vite";
5
-
6
- import pkg from "./package.json";
7
-
8
- export default defineConfig({
9
- build: {
10
- outDir: "dist",
11
- lib: {
12
- entry: join(process.cwd(), "index.ts"),
13
- formats: ["es", "cjs"],
14
- fileName: (format, entryName) => {
15
- return format === "es"
16
- ? `${entryName}.js`
17
- : format === "cjs"
18
- ? entryName + ".cjs"
19
- : `${entryName}.${format}.js`;
20
- },
21
- },
22
- minify: false,
23
- rollupOptions: {
24
- external: [...Object.keys(pkg.dependencies || {}), ...builtinModules, ...builtinModules.map((n) => `node:${n}`)],
25
- },
26
- },
27
- });