@zhin.js/adapter-weixin-ilink 0.1.0 → 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @zhin.js/adapter-weixin-ilink
2
+
3
+ ## 1.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [65f4b0a]
8
+ - Updated dependencies [e62c23a]
9
+ - @zhin.js/core@1.2.0
10
+ - @zhin.js/agent@0.2.0
11
+ - @zhin.js/host-api@1.0.0
12
+ - zhin.js@2.0.0
13
+ - @zhin.js/host-router@1.0.0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cdn-upload.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-upload.test.d.ts","sourceRoot":"","sources":["../src/cdn-upload.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,150 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ vi.mock("../util/logger.js", () => ({
3
+ logger: {
4
+ info: vi.fn(),
5
+ debug: vi.fn(),
6
+ warn: vi.fn(),
7
+ error: vi.fn(),
8
+ },
9
+ }));
10
+ const { mockFetch } = vi.hoisted(() => ({
11
+ mockFetch: vi.fn(),
12
+ }));
13
+ vi.stubGlobal("fetch", mockFetch);
14
+ import { encryptAesEcb, aesEcbPaddedSize } from "./aes-ecb.js";
15
+ import { uploadBufferToCdn } from "./cdn-upload.js";
16
+ import crypto from "node:crypto";
17
+ beforeEach(() => {
18
+ vi.clearAllMocks();
19
+ });
20
+ describe("aesEcbPaddedSize", () => {
21
+ it("pads to 16-byte boundary", () => {
22
+ expect(aesEcbPaddedSize(0)).toBe(16);
23
+ expect(aesEcbPaddedSize(1)).toBe(16);
24
+ expect(aesEcbPaddedSize(15)).toBe(16);
25
+ expect(aesEcbPaddedSize(16)).toBe(32);
26
+ expect(aesEcbPaddedSize(31)).toBe(32);
27
+ expect(aesEcbPaddedSize(32)).toBe(48);
28
+ });
29
+ });
30
+ describe("encryptAesEcb", () => {
31
+ it("encrypts and produces correct ciphertext length", () => {
32
+ const key = crypto.randomBytes(16);
33
+ const plaintext = Buffer.from("hello world 1234");
34
+ const ct = encryptAesEcb(plaintext, key);
35
+ // 16 bytes plaintext + PKCS7 padding = 32 bytes ciphertext
36
+ expect(ct.length).toBe(32);
37
+ });
38
+ });
39
+ describe("uploadBufferToCdn", () => {
40
+ const aeskey = crypto.randomBytes(16);
41
+ it("uploads successfully and returns downloadParam", async () => {
42
+ mockFetch.mockResolvedValueOnce({
43
+ ok: true,
44
+ status: 200,
45
+ headers: new Headers({ "x-encrypted-param": "dl-param" }),
46
+ });
47
+ const result = await uploadBufferToCdn({
48
+ buf: Buffer.from("data"),
49
+ uploadParam: "up",
50
+ filekey: "fk",
51
+ cdnBaseUrl: "https://cdn.com",
52
+ label: "test",
53
+ aeskey,
54
+ });
55
+ expect(result.downloadParam).toBe("dl-param");
56
+ });
57
+ it("POSTs to uploadFullUrl when provided", async () => {
58
+ mockFetch.mockResolvedValueOnce({
59
+ ok: true,
60
+ status: 200,
61
+ headers: new Headers({ "x-encrypted-param": "dl-full" }),
62
+ });
63
+ const fullUrl = "http://host/c2c/upload?q=1";
64
+ const result = await uploadBufferToCdn({
65
+ buf: Buffer.from("data"),
66
+ uploadFullUrl: fullUrl,
67
+ filekey: "fk",
68
+ cdnBaseUrl: "https://unused.example",
69
+ label: "test",
70
+ aeskey,
71
+ });
72
+ expect(result.downloadParam).toBe("dl-full");
73
+ expect(mockFetch).toHaveBeenCalledWith(fullUrl, expect.objectContaining({ method: "POST" }));
74
+ });
75
+ it("retries on server error then succeeds", async () => {
76
+ mockFetch
77
+ .mockResolvedValueOnce({
78
+ ok: false,
79
+ status: 500,
80
+ headers: new Headers({ "x-error-message": "busy" }),
81
+ text: () => Promise.resolve("busy"),
82
+ })
83
+ .mockResolvedValueOnce({
84
+ ok: true,
85
+ status: 200,
86
+ headers: new Headers({ "x-encrypted-param": "dl" }),
87
+ });
88
+ const result = await uploadBufferToCdn({
89
+ buf: Buffer.from("data"),
90
+ uploadParam: "up",
91
+ filekey: "fk",
92
+ cdnBaseUrl: "https://cdn.com",
93
+ label: "test",
94
+ aeskey,
95
+ });
96
+ expect(result.downloadParam).toBe("dl");
97
+ expect(mockFetch).toHaveBeenCalledTimes(2);
98
+ });
99
+ it("throws immediately on 4xx client error", async () => {
100
+ mockFetch.mockResolvedValueOnce({
101
+ ok: false,
102
+ status: 403,
103
+ headers: new Headers({}),
104
+ text: () => Promise.resolve("forbidden"),
105
+ });
106
+ await expect(uploadBufferToCdn({
107
+ buf: Buffer.from("data"),
108
+ uploadParam: "up",
109
+ filekey: "fk",
110
+ cdnBaseUrl: "https://cdn.com",
111
+ label: "test",
112
+ aeskey,
113
+ })).rejects.toThrow("client error");
114
+ expect(mockFetch).toHaveBeenCalledTimes(1);
115
+ });
116
+ it("throws when x-encrypted-param header is missing after all retries", async () => {
117
+ for (let i = 0; i < 3; i++) {
118
+ mockFetch.mockResolvedValueOnce({
119
+ ok: true,
120
+ status: 200,
121
+ headers: new Headers({}),
122
+ });
123
+ }
124
+ await expect(uploadBufferToCdn({
125
+ buf: Buffer.from("data"),
126
+ uploadParam: "up",
127
+ filekey: "fk",
128
+ cdnBaseUrl: "https://cdn.com",
129
+ label: "test",
130
+ aeskey,
131
+ })).rejects.toThrow("x-encrypted-param");
132
+ });
133
+ it("uses x-error-message header for 4xx when available", async () => {
134
+ mockFetch.mockResolvedValueOnce({
135
+ ok: false,
136
+ status: 400,
137
+ headers: new Headers({ "x-error-message": "bad request detail" }),
138
+ text: () => Promise.resolve("fallback text"),
139
+ });
140
+ await expect(uploadBufferToCdn({
141
+ buf: Buffer.from("data"),
142
+ uploadParam: "up",
143
+ filekey: "fk",
144
+ cdnBaseUrl: "https://cdn.com",
145
+ label: "test",
146
+ aeskey,
147
+ })).rejects.toThrow("bad request detail");
148
+ });
149
+ });
150
+ //# sourceMappingURL=cdn-upload.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-upload.test.js","sourceRoot":"","sources":["../src/cdn-upload.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mime.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mime.test.d.ts","sourceRoot":"","sources":["../src/mime.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { getMimeFromFilename, getExtensionFromMime, getExtensionFromContentTypeOrUrl } from "./mime.js";
3
+ describe("getMimeFromFilename", () => {
4
+ it("returns correct MIME for known extensions", () => {
5
+ expect(getMimeFromFilename("photo.png")).toBe("image/png");
6
+ expect(getMimeFromFilename("doc.pdf")).toBe("application/pdf");
7
+ expect(getMimeFromFilename("video.mp4")).toBe("video/mp4");
8
+ expect(getMimeFromFilename("audio.mp3")).toBe("audio/mpeg");
9
+ expect(getMimeFromFilename("image.jpg")).toBe("image/jpeg");
10
+ expect(getMimeFromFilename("image.jpeg")).toBe("image/jpeg");
11
+ expect(getMimeFromFilename("data.csv")).toBe("text/csv");
12
+ });
13
+ it("is case-insensitive", () => {
14
+ expect(getMimeFromFilename("PHOTO.PNG")).toBe("image/png");
15
+ expect(getMimeFromFilename("file.PDF")).toBe("application/pdf");
16
+ });
17
+ it("returns application/octet-stream for unknown extensions", () => {
18
+ expect(getMimeFromFilename("file.xyz")).toBe("application/octet-stream");
19
+ expect(getMimeFromFilename("noext")).toBe("application/octet-stream");
20
+ });
21
+ it("handles paths with directories", () => {
22
+ expect(getMimeFromFilename("/path/to/photo.png")).toBe("image/png");
23
+ });
24
+ });
25
+ describe("getExtensionFromMime", () => {
26
+ it("returns correct extension for known MIME types", () => {
27
+ expect(getExtensionFromMime("image/jpeg")).toBe(".jpg");
28
+ expect(getExtensionFromMime("image/png")).toBe(".png");
29
+ expect(getExtensionFromMime("video/mp4")).toBe(".mp4");
30
+ expect(getExtensionFromMime("application/pdf")).toBe(".pdf");
31
+ });
32
+ it("handles MIME with parameters", () => {
33
+ expect(getExtensionFromMime("image/jpeg; charset=utf-8")).toBe(".jpg");
34
+ expect(getExtensionFromMime("text/plain; boundary=something")).toBe(".txt");
35
+ });
36
+ it("returns .bin for unknown MIME types", () => {
37
+ expect(getExtensionFromMime("application/unknown")).toBe(".bin");
38
+ expect(getExtensionFromMime("x-custom/type")).toBe(".bin");
39
+ });
40
+ it("handles image/jpg alias", () => {
41
+ expect(getExtensionFromMime("image/jpg")).toBe(".jpg");
42
+ });
43
+ });
44
+ describe("getExtensionFromContentTypeOrUrl", () => {
45
+ it("prefers Content-Type when it resolves to a known extension", () => {
46
+ expect(getExtensionFromContentTypeOrUrl("image/png", "https://example.com/file.jpg")).toBe(".png");
47
+ });
48
+ it("falls back to URL extension when Content-Type is unknown", () => {
49
+ expect(getExtensionFromContentTypeOrUrl("application/unknown", "https://example.com/file.jpg")).toBe(".jpg");
50
+ });
51
+ it("falls back to URL extension when Content-Type is null", () => {
52
+ expect(getExtensionFromContentTypeOrUrl(null, "https://example.com/file.mp4")).toBe(".mp4");
53
+ });
54
+ it("returns .bin when neither Content-Type nor URL has a known extension", () => {
55
+ expect(getExtensionFromContentTypeOrUrl(null, "https://example.com/file")).toBe(".bin");
56
+ expect(getExtensionFromContentTypeOrUrl("application/unknown", "https://example.com/file.xyz")).toBe(".bin");
57
+ });
58
+ it("handles URL with query parameters", () => {
59
+ expect(getExtensionFromContentTypeOrUrl(null, "https://example.com/file.png?token=abc")).toBe(".png");
60
+ });
61
+ });
62
+ //# sourceMappingURL=mime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mime.test.js","sourceRoot":"","sources":["../src/mime.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=silk-transcode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"silk-transcode.test.d.ts","sourceRoot":"","sources":["../src/silk-transcode.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ vi.mock("../util/logger.js", () => ({
3
+ logger: {
4
+ info: vi.fn(),
5
+ debug: vi.fn(),
6
+ warn: vi.fn(),
7
+ error: vi.fn(),
8
+ },
9
+ }));
10
+ describe("silkToWav", () => {
11
+ beforeEach(() => {
12
+ vi.resetModules();
13
+ });
14
+ it("returns null when silk-wasm is unavailable", async () => {
15
+ vi.doMock("silk-wasm", () => {
16
+ throw new Error("Cannot find module 'silk-wasm'");
17
+ });
18
+ const { silkToWav } = await import("./silk-transcode.js");
19
+ const result = await silkToWav(Buffer.from("fake-silk"));
20
+ expect(result).toBeNull();
21
+ });
22
+ it("transcodes silk to WAV successfully", async () => {
23
+ const fakePcm = new Uint8Array(480); // 10ms at 24kHz mono 16-bit
24
+ vi.doMock("silk-wasm", () => ({
25
+ decode: vi.fn().mockResolvedValue({
26
+ data: fakePcm,
27
+ duration: 10,
28
+ }),
29
+ }));
30
+ const { silkToWav } = await import("./silk-transcode.js");
31
+ const result = await silkToWav(Buffer.from("fake-silk"));
32
+ expect(result).not.toBeNull();
33
+ expect(result.length).toBe(44 + fakePcm.byteLength); // WAV header + PCM data
34
+ // Verify WAV header
35
+ expect(result.toString("ascii", 0, 4)).toBe("RIFF");
36
+ expect(result.toString("ascii", 8, 12)).toBe("WAVE");
37
+ expect(result.toString("ascii", 12, 16)).toBe("fmt ");
38
+ expect(result.readUInt16LE(20)).toBe(1); // PCM format
39
+ expect(result.readUInt16LE(22)).toBe(1); // mono
40
+ expect(result.readUInt32LE(24)).toBe(24000); // sample rate
41
+ expect(result.readUInt16LE(34)).toBe(16); // bits per sample
42
+ expect(result.toString("ascii", 36, 40)).toBe("data");
43
+ });
44
+ it("returns null when decode fails", async () => {
45
+ vi.doMock("silk-wasm", () => ({
46
+ decode: vi.fn().mockRejectedValue(new Error("decode error")),
47
+ }));
48
+ const { silkToWav } = await import("./silk-transcode.js");
49
+ const result = await silkToWav(Buffer.from("bad-silk"));
50
+ expect(result).toBeNull();
51
+ });
52
+ });
53
+ //# sourceMappingURL=silk-transcode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"silk-transcode.test.js","sourceRoot":"","sources":["../src/silk-transcode.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upload.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.test.d.ts","sourceRoot":"","sources":["../src/upload.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,250 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import fs from "node:fs/promises";
3
+ import fsSync from "node:fs";
4
+ import path from "node:path";
5
+ import os from "node:os";
6
+ vi.mock("./ilink-logger.js", () => ({
7
+ logger: {
8
+ info: vi.fn(),
9
+ debug: vi.fn(),
10
+ warn: vi.fn(),
11
+ error: vi.fn(),
12
+ },
13
+ }));
14
+ const { mockGetUploadUrl } = vi.hoisted(() => ({
15
+ mockGetUploadUrl: vi.fn(),
16
+ }));
17
+ vi.mock("./ilink-api.js", async (importOriginal) => {
18
+ const actual = await importOriginal();
19
+ return {
20
+ ...actual,
21
+ getUploadUrl: mockGetUploadUrl,
22
+ };
23
+ });
24
+ const { mockFetch } = vi.hoisted(() => ({
25
+ mockFetch: vi.fn(),
26
+ }));
27
+ vi.stubGlobal("fetch", mockFetch);
28
+ function mockCdnResponse(params) {
29
+ const headers = new Headers(params.headers ?? {});
30
+ return {
31
+ ok: params.ok ?? true,
32
+ status: params.status ?? 200,
33
+ headers,
34
+ text: () => Promise.resolve(params.body ?? ""),
35
+ };
36
+ }
37
+ import { downloadRemoteImageToTemp, uploadFileToWeixin, uploadVideoToWeixin, uploadFileAttachmentToWeixin } from "./upload.js";
38
+ beforeEach(() => {
39
+ vi.clearAllMocks();
40
+ });
41
+ describe("downloadRemoteImageToTemp", () => {
42
+ it("downloads and saves file to temp dir", async () => {
43
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-test-"));
44
+ try {
45
+ const imageBytes = Buffer.from("fake-image-data");
46
+ mockFetch.mockResolvedValueOnce({
47
+ ok: true,
48
+ status: 200,
49
+ arrayBuffer: () => Promise.resolve(imageBytes.buffer.slice(imageBytes.byteOffset, imageBytes.byteOffset + imageBytes.byteLength)),
50
+ headers: new Headers({ "content-type": "image/png" }),
51
+ });
52
+ const filePath = await downloadRemoteImageToTemp("https://example.com/photo.png", tmpDir);
53
+ expect(filePath).toContain(tmpDir);
54
+ expect(filePath).toMatch(/\.png$/);
55
+ const content = await fs.readFile(filePath);
56
+ expect(content.toString()).toBe("fake-image-data");
57
+ }
58
+ finally {
59
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
60
+ }
61
+ });
62
+ it("throws on non-ok response", async () => {
63
+ mockFetch.mockResolvedValueOnce({
64
+ ok: false,
65
+ status: 404,
66
+ statusText: "Not Found",
67
+ });
68
+ await expect(downloadRemoteImageToTemp("https://example.com/missing.png", "/tmp/test")).rejects.toThrow("remote media download failed");
69
+ });
70
+ });
71
+ describe("uploadFileToWeixin", () => {
72
+ it("uploads image file and returns info", async () => {
73
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-img-test-"));
74
+ try {
75
+ const filePath = path.join(tmpDir, "test.png");
76
+ await fs.writeFile(filePath, "fake-image-data");
77
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up-param" });
78
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: { "x-encrypted-param": "dl-param" } }));
79
+ const result = await uploadFileToWeixin({
80
+ filePath,
81
+ toUserId: "user1",
82
+ opts: { baseUrl: "https://api.com", token: "tok" },
83
+ cdnBaseUrl: "https://cdn.com",
84
+ });
85
+ expect(result.filekey).toBeDefined();
86
+ expect(result.downloadEncryptedQueryParam).toBe("dl-param");
87
+ expect(result.fileSize).toBe(15);
88
+ expect(result.fileSizeCiphertext).toBe(16);
89
+ }
90
+ finally {
91
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
92
+ }
93
+ });
94
+ it("uploads via upload_full_url when upload_param is absent", async () => {
95
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-fullurl-test-"));
96
+ try {
97
+ const filePath = path.join(tmpDir, "test.png");
98
+ await fs.writeFile(filePath, "fake-image-data");
99
+ const fullUrl = "http://cdn.example/c2c/upload?encrypted_query_param=x&filekey=y";
100
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_full_url: fullUrl });
101
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: { "x-encrypted-param": "dl-full" } }));
102
+ const result = await uploadFileToWeixin({
103
+ filePath,
104
+ toUserId: "user1",
105
+ opts: { baseUrl: "https://api.com", token: "tok" },
106
+ cdnBaseUrl: "https://ignored-cdn.com",
107
+ });
108
+ expect(result.downloadEncryptedQueryParam).toBe("dl-full");
109
+ expect(mockFetch).toHaveBeenCalledTimes(1);
110
+ const [calledUrl] = mockFetch.mock.calls[0];
111
+ expect(calledUrl).toBe(fullUrl);
112
+ }
113
+ finally {
114
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
115
+ }
116
+ });
117
+ it("throws when getUploadUrl returns neither upload_full_url nor upload_param", async () => {
118
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-fail-test-"));
119
+ try {
120
+ const filePath = path.join(tmpDir, "test.txt");
121
+ await fs.writeFile(filePath, "data");
122
+ mockGetUploadUrl.mockResolvedValueOnce({});
123
+ await expect(uploadFileToWeixin({
124
+ filePath,
125
+ toUserId: "user1",
126
+ opts: { baseUrl: "https://api.com" },
127
+ cdnBaseUrl: "https://cdn.com",
128
+ })).rejects.toThrow("no upload URL");
129
+ }
130
+ finally {
131
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
132
+ }
133
+ });
134
+ it("retries CDN upload on server error then succeeds", async () => {
135
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-retry-test-"));
136
+ try {
137
+ const filePath = path.join(tmpDir, "data.bin");
138
+ await fs.writeFile(filePath, "some data for upload");
139
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up" });
140
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({
141
+ ok: false,
142
+ status: 500,
143
+ headers: { "x-error-message": "server busy" },
144
+ body: "server busy",
145
+ }));
146
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: { "x-encrypted-param": "dl-retry" } }));
147
+ const result = await uploadFileToWeixin({
148
+ filePath,
149
+ toUserId: "user1",
150
+ opts: { baseUrl: "https://api.com" },
151
+ cdnBaseUrl: "https://cdn.com",
152
+ });
153
+ expect(result.downloadEncryptedQueryParam).toBe("dl-retry");
154
+ expect(mockFetch).toHaveBeenCalledTimes(2);
155
+ }
156
+ finally {
157
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
158
+ }
159
+ });
160
+ it("throws immediately on CDN client error (4xx)", async () => {
161
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-4xx-test-"));
162
+ try {
163
+ const filePath = path.join(tmpDir, "data.bin");
164
+ await fs.writeFile(filePath, "data");
165
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up" });
166
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({
167
+ ok: false,
168
+ status: 403,
169
+ headers: { "x-error-message": "forbidden" },
170
+ body: "forbidden",
171
+ }));
172
+ await expect(uploadFileToWeixin({
173
+ filePath,
174
+ toUserId: "user1",
175
+ opts: { baseUrl: "https://api.com" },
176
+ cdnBaseUrl: "https://cdn.com",
177
+ })).rejects.toThrow("client error");
178
+ expect(mockFetch).toHaveBeenCalledTimes(1);
179
+ }
180
+ finally {
181
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
182
+ }
183
+ });
184
+ it("throws when CDN returns no x-encrypted-param after all retries", async () => {
185
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-no-param-test-"));
186
+ try {
187
+ const filePath = path.join(tmpDir, "data.bin");
188
+ await fs.writeFile(filePath, "data");
189
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up" });
190
+ for (let i = 0; i < 3; i++) {
191
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: {} }));
192
+ }
193
+ await expect(uploadFileToWeixin({
194
+ filePath,
195
+ toUserId: "user1",
196
+ opts: { baseUrl: "https://api.com" },
197
+ cdnBaseUrl: "https://cdn.com",
198
+ })).rejects.toThrow("x-encrypted-param");
199
+ }
200
+ finally {
201
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
202
+ }
203
+ });
204
+ });
205
+ describe("uploadVideoToWeixin", () => {
206
+ it("uploads video file", async () => {
207
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-vid-test-"));
208
+ try {
209
+ const filePath = path.join(tmpDir, "clip.mp4");
210
+ await fs.writeFile(filePath, "fake-video-content");
211
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up-vid" });
212
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: { "x-encrypted-param": "dl-vid" } }));
213
+ const result = await uploadVideoToWeixin({
214
+ filePath,
215
+ toUserId: "user1",
216
+ opts: { baseUrl: "https://api.com" },
217
+ cdnBaseUrl: "https://cdn.com",
218
+ });
219
+ expect(result.filekey).toBeDefined();
220
+ expect(result.downloadEncryptedQueryParam).toBe("dl-vid");
221
+ }
222
+ finally {
223
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
224
+ }
225
+ });
226
+ });
227
+ describe("uploadFileAttachmentToWeixin", () => {
228
+ it("uploads file attachment", async () => {
229
+ const tmpDir = fsSync.mkdtempSync(path.join(os.tmpdir(), "upload-att-test-"));
230
+ try {
231
+ const filePath = path.join(tmpDir, "doc.pdf");
232
+ await fs.writeFile(filePath, "pdf-content");
233
+ mockGetUploadUrl.mockResolvedValueOnce({ upload_param: "up" });
234
+ mockFetch.mockResolvedValueOnce(mockCdnResponse({ headers: { "x-encrypted-param": "dl" } }));
235
+ const result = await uploadFileAttachmentToWeixin({
236
+ filePath,
237
+ fileName: "doc.pdf",
238
+ toUserId: "user1",
239
+ opts: { baseUrl: "https://api.com" },
240
+ cdnBaseUrl: "https://cdn.com",
241
+ });
242
+ expect(result.filekey).toBeDefined();
243
+ expect(result.downloadEncryptedQueryParam).toBe("dl");
244
+ }
245
+ finally {
246
+ fsSync.rmSync(tmpDir, { recursive: true, force: true });
247
+ }
248
+ });
249
+ });
250
+ //# sourceMappingURL=upload.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.test.js","sourceRoot":"","sources":["../src/upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,MAAM,EAAE;QACN,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACf;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE;CAC1B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IACjD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAmC,CAAC;IACvE,OAAO;QACL,GAAG,MAAM;QACT,YAAY,EAAE,gBAAgB;KAC/B,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;CACnB,CAAC,CAAC,CAAC;AACJ,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAElC,SAAS,eAAe,CAAC,MAKxB;IACC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,IAAI;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,GAAG;QAC5B,OAAO;QACP,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAE/H,UAAU,CAAC,GAAG,EAAE;IACd,EAAE,CAAC,aAAa,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAClD,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,GAAG;gBACX,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;gBACjI,OAAO,EAAE,IAAI,OAAO,CAAC,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;aACtD,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAC;YAC1F,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,SAAS,CAAC,qBAAqB,CAAC;YAC9B,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,GAAG;YACX,UAAU,EAAE,WAAW;SACxB,CAAC,CAAC;QACH,MAAM,MAAM,CACV,yBAAyB,CAAC,iCAAiC,EAAE,WAAW,CAAC,CAC1E,CAAC,OAAO,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YAEhD,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YACrE,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,UAAU,EAAE,EAAE,CAAC,CAClE,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE;gBAClD,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAClF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YAEhD,MAAM,OAAO,GAAG,iEAAiE,CAAC;YAClF,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,CAAC,CACjE,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE;gBAClD,UAAU,EAAE,yBAAyB;aACtC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAA0B,CAAC;YACrE,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAErC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;YAE3C,MAAM,MAAM,CACV,kBAAkB,CAAC;gBACjB,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACrC,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;YAErD,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/D,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC;gBACd,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,iBAAiB,EAAE,aAAa,EAAE;gBAC7C,IAAI,EAAE,aAAa;aACpB,CAAC,CACH,CAAC;YACF,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,UAAU,EAAE,EAAE,CAAC,CAClE,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5D,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAErC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC;gBACd,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE;gBAC3C,IAAI,EAAE,WAAW;aAClB,CAAC,CACH,CAAC;YAEF,MAAM,MAAM,CACV,kBAAkB,CAAC;gBACjB,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAErC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,SAAS,CAAC,qBAAqB,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YACpE,CAAC;YAED,MAAM,MAAM,CACV,kBAAkB,CAAC;gBACjB,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACzC,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;YAEnD,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;YACnE,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,QAAQ,EAAE,EAAE,CAAC,CAChE,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;gBACvC,QAAQ;gBACR,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YAE5C,gBAAgB,CAAC,qBAAqB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,SAAS,CAAC,qBAAqB,CAC7B,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAAE,CAAC,CAC5D,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC;gBAChD,QAAQ;gBACR,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE;gBACpC,UAAU,EAAE,iBAAiB;aAC9B,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-weixin-ilink",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "description": "Zhin.js adapter for WeChat personal account via Tencent iLink Bot API (ClawBot)",
6
6
  "main": "./lib/index.js",
@@ -55,18 +55,18 @@
55
55
  "radix-ui": "^1.4.3",
56
56
  "typescript": "^6.0.3",
57
57
  "@zhin.js/cli": "1.0.88",
58
- "@zhin.js/host-api": "0.0.4",
59
58
  "@zhin.js/contract": "1.0.1",
60
- "zhin.js": "1.0.92"
59
+ "zhin.js": "2.0.0",
60
+ "@zhin.js/host-api": "1.0.0"
61
61
  },
62
62
  "peerDependencies": {
63
- "@zhin.js/agent": "0.1.31",
64
- "@zhin.js/contract": "1.0.1",
63
+ "@zhin.js/agent": "0.2.0",
65
64
  "@zhin.js/client": "2.0.2",
66
- "@zhin.js/core": "1.1.33",
67
- "@zhin.js/host-api": "0.0.4",
68
- "zhin.js": "1.0.92",
69
- "@zhin.js/host-router": "0.0.3"
65
+ "@zhin.js/host-api": "1.0.0",
66
+ "@zhin.js/host-router": "1.0.0",
67
+ "zhin.js": "2.0.0",
68
+ "@zhin.js/contract": "1.0.1",
69
+ "@zhin.js/core": "1.2.0"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "@zhin.js/agent": {