@chatu-ai/builder-sdk 0.1.0 → 0.1.1

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/client.d.ts CHANGED
@@ -89,6 +89,16 @@ export interface BuilderClient {
89
89
  }): Promise<string>;
90
90
  downloadUrl(conversationId: string): string;
91
91
  };
92
+ export: {
93
+ /**
94
+ * 导出应用源码 ZIP(含 Dockerfile/DEPLOY.md)。沙箱未运行时服务端返回 409 SANDBOX_NOT_RUNNING —— 调用方先 sandbox.wake()。
95
+ * 返回 Blob 与建议文件名(取自 Content-Disposition)
96
+ */
97
+ zip(conversationId: string): Promise<{
98
+ blob: Blob;
99
+ fileName: string;
100
+ }>;
101
+ };
92
102
  }
93
103
  export declare function createBuilderClient(options: BuilderClientOptions): BuilderClient;
94
104
  export declare class BuilderApiError extends Error {
package/dist/client.js CHANGED
@@ -76,6 +76,17 @@ export function createBuilderClient(options) {
76
76
  read: (id, path, opts) => req(`/${id}/files/read?${qs({ path, ...opts })}`),
77
77
  downloadUrl: id => `${restBase}/${id}/files/download`,
78
78
  },
79
+ export: {
80
+ zip: async (id) => {
81
+ const res = await doFetch(`${restBase}/${id}/export/zip`, auth.apply({}));
82
+ if (!res.ok)
83
+ throw new BuilderApiError(res.status, await res.text().catch(() => ''));
84
+ const cd = res.headers.get('content-disposition') ?? '';
85
+ const m = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i.exec(cd);
86
+ const fileName = m?.[1] ? decodeURIComponent(m[1]) : 'app.zip';
87
+ return { blob: await res.blob(), fileName };
88
+ },
89
+ },
79
90
  };
80
91
  }
81
92
  /**
@@ -60,3 +60,28 @@ describe('client req envelope unwrap', () => {
60
60
  await expect(c.sandbox.status('c1')).rejects.toThrow('会话不存在');
61
61
  });
62
62
  });
63
+ describe('client export.zip', () => {
64
+ it('returns blob and filename from content-disposition', async () => {
65
+ const c = createBuilderClient({
66
+ restBase: 'https://api.test/web/Builder',
67
+ auth: new CookieAuth(),
68
+ transport: { stream: async function* () { }, resubscribe: async function* () { }, cancel: async () => { } },
69
+ fetchImpl: (async () => new Response(new Uint8Array([0x50, 0x4b]), {
70
+ status: 200,
71
+ headers: { 'content-type': 'application/zip', 'content-disposition': 'attachment; filename="my-app.zip"' },
72
+ })),
73
+ });
74
+ const r = await c.export.zip('c1');
75
+ expect(r.fileName).toBe('my-app.zip');
76
+ expect(r.blob.size).toBe(2);
77
+ });
78
+ it('throws BuilderApiError 409 when sandbox not running', async () => {
79
+ const c = createBuilderClient({
80
+ restBase: 'https://api.test/web/Builder',
81
+ auth: new CookieAuth(),
82
+ transport: { stream: async function* () { }, resubscribe: async function* () { }, cancel: async () => { } },
83
+ fetchImpl: (async () => new Response('{"error":"SANDBOX_NOT_RUNNING"}', { status: 409 })),
84
+ });
85
+ await expect(c.export.zip('c1')).rejects.toMatchObject({ status: 409 });
86
+ });
87
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatu-ai/builder-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "ChatU Builder client SDK core: REST + streaming client, zod event schemas, seq resume",
5
5
  "license": "MIT",
6
6
  "type": "module",