@vercel/sandbox 0.0.5 → 0.0.6

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 (59) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/CHANGELOG.md +8 -0
  4. package/README.md +1 -0
  5. package/dist/{client/client.d.ts → api-client/api-client.d.ts} +30 -17
  6. package/dist/{client/client.js → api-client/api-client.js} +49 -44
  7. package/dist/{client → api-client}/base-client.d.ts +1 -1
  8. package/dist/{client → api-client}/base-client.js +3 -3
  9. package/dist/api-client/index.d.ts +1 -0
  10. package/dist/api-client/index.js +5 -0
  11. package/dist/{client → api-client}/validators.d.ts +20 -1
  12. package/dist/{client → api-client}/validators.js +9 -2
  13. package/dist/command.d.ts +127 -0
  14. package/dist/command.js +137 -0
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.js +6 -5
  17. package/dist/sandbox.d.ts +201 -0
  18. package/dist/sandbox.js +174 -0
  19. package/dist/utils/decode-base64-url.d.ts +7 -0
  20. package/dist/utils/decode-base64-url.js +12 -0
  21. package/dist/utils/get-credentials.d.ts +26 -0
  22. package/dist/utils/get-credentials.js +84 -0
  23. package/dist/utils/get-vercel-oidc-token.d.ts +6 -0
  24. package/dist/utils/get-vercel-oidc-token.js +21 -0
  25. package/dist/version.d.ts +1 -1
  26. package/dist/version.js +1 -1
  27. package/package.json +10 -3
  28. package/src/api-client/api-client.ts +225 -0
  29. package/src/{client → api-client}/base-client.ts +1 -1
  30. package/src/api-client/index.ts +1 -0
  31. package/src/{client → api-client}/validators.ts +9 -1
  32. package/src/command.test.ts +51 -0
  33. package/src/command.ts +176 -0
  34. package/src/index.ts +2 -1
  35. package/src/sandbox.ts +309 -0
  36. package/src/utils/decode-base64-url.ts +14 -0
  37. package/src/utils/get-credentials.ts +113 -0
  38. package/src/utils/get-vercel-oidc-token.ts +31 -0
  39. package/src/version.ts +1 -1
  40. package/tsconfig.json +2 -1
  41. package/typedoc.json +7 -1
  42. package/vitest.config.ts +8 -0
  43. package/vitest.setup.ts +4 -0
  44. package/dist/create-sandbox.d.ts +0 -219
  45. package/dist/create-sandbox.js +0 -231
  46. package/dist/utils/deferred-generator.d.ts +0 -5
  47. package/dist/utils/deferred-generator.js +0 -32
  48. package/dist/utils/deferred.d.ts +0 -6
  49. package/dist/utils/deferred.js +0 -12
  50. package/src/client/client.ts +0 -188
  51. package/src/create-sandbox.ts +0 -330
  52. package/src/utils/deferred-generator.ts +0 -38
  53. package/src/utils/deferred.ts +0 -12
  54. /package/dist/{client → api-client}/api-error.d.ts +0 -0
  55. /package/dist/{client → api-client}/api-error.js +0 -0
  56. /package/dist/{client → api-client}/with-retry.d.ts +0 -0
  57. /package/dist/{client → api-client}/with-retry.js +0 -0
  58. /package/src/{client → api-client}/api-error.ts +0 -0
  59. /package/src/{client → api-client}/with-retry.ts +0 -0
@@ -1,219 +0,0 @@
1
- import { SandboxClient } from "./client/client";
2
- import { Readable } from "stream";
3
- /**
4
- * SDK for interacting with the Sandbox API. Provides methods to create and
5
- * manage sandboxes configured with specific source code and network ports.
6
- *
7
- * Example:
8
- * ```ts
9
- * const sdk = new SDK({
10
- * teamId: process.env.VERCEL_TEAM_ID!,
11
- * token: process.env.VERCEL_TOKEN!,
12
- * });
13
- * ```
14
- *
15
- * @see {@link SDK.createSandbox} to start a new sandbox.
16
- */
17
- export declare class SDK {
18
- /**
19
- * Internal API client for communicating with the sandbox backend.
20
- */
21
- private client;
22
- /**
23
- * Create a new instance of `SDK`.
24
- *
25
- * @param config - Configuration options for the SDK.
26
- * @param config.teamId - The Vercel team ID used to scope the Sandbox.
27
- * @param config.token - The API token used for authentication.
28
- */
29
- constructor({ teamId, token }: {
30
- teamId: string;
31
- token: string;
32
- });
33
- /**
34
- * Creates a new sandbox instance using the provided Git repository and exposed ports.
35
- *
36
- * The repository must be public. On start, the sandbox will clone the repository
37
- * and expose the specified ports for access.
38
- *
39
- * @param params - Configuration parameters for the sandbox.
40
- * @param params.source - The source of the sandbox, currently supports Git repositories only.
41
- * @param params.source.type - Type of source, must be `"git"`.
42
- * @param params.source.url - The URL of the public Git repository to clone.
43
- * @param params.projectId - The Vercel project ID used to link the Sandbox to.
44
- * @param params.ports - Array of port numbers to expose from the sandbox.
45
- * @param params.timeout - (Optional) Timeout in seconds before the sandbox auto-terminates.
46
- *
47
- * @returns A promise that resolves to a `Sandbox` instance.
48
- */
49
- createSandbox(params: {
50
- source: {
51
- type: "git";
52
- url: string;
53
- };
54
- projectId: string;
55
- ports?: number[];
56
- timeout?: number;
57
- }): Promise<Sandbox>;
58
- /** @hidden */
59
- getSandbox({ routes, sandboxId, }: {
60
- routes: {
61
- subdomain: string;
62
- port: number;
63
- }[];
64
- sandboxId: string;
65
- }): Promise<Sandbox>;
66
- }
67
- /** @inline */
68
- interface RunCommandParams {
69
- /** The command to execute */
70
- cmd: string;
71
- /** Arguments to pass to the command */
72
- args?: string[];
73
- /** Working directory to execute the command in */
74
- cwd?: string;
75
- /** Environment variables to set for this command */
76
- env?: Record<string, string>;
77
- }
78
- /**
79
- * A Sandbox is an isolated Linux MicroVM that you can your experiments on.
80
- *
81
- * @see {@link SDK.createSandbox} to construct a Sandbox.
82
- * @hideconstructor
83
- */
84
- export declare class Sandbox {
85
- private client;
86
- /** @hidden */
87
- routes: {
88
- subdomain: string;
89
- port: number;
90
- }[];
91
- /**
92
- * The ID of this sandbox.
93
- */
94
- sandboxId: string;
95
- constructor({ client, routes, sandboxId, }: {
96
- client: SandboxClient;
97
- routes: {
98
- subdomain: string;
99
- port: number;
100
- }[];
101
- sandboxId: string;
102
- });
103
- /**
104
- * Start executing a command in this sandbox.
105
- *
106
- * @param command - The command to execute.
107
- * @param args - Arguments to pass to the command.
108
- *
109
- * @returns A {@link Command} instance.
110
- */
111
- runCommand(command: string, args?: string[]): Promise<Command>;
112
- /**
113
- * Start executing a command in this sandbox.
114
- *
115
- * @param params - What should be executed.
116
- *
117
- * @returns A {@link Command} instance.
118
- */
119
- runCommand(params: RunCommandParams): Promise<Command>;
120
- _runCommand(params: RunCommandParams): Promise<Command>;
121
- /**
122
- * Write files to the filesystem of this sandbox.
123
- */
124
- writeFiles(files: {
125
- path: string;
126
- stream: Readable | Buffer;
127
- }[]): Promise<void>;
128
- /**
129
- * Get the public domain of a port of this sandbox.
130
- *
131
- * E.g. `2grza2l7imxe.vercel.run`
132
- */
133
- domain(p: number): string;
134
- }
135
- /**
136
- * A command executed in a Sandbox.
137
- *
138
- * You can {@link wait} on commands to access their {@link exitCode}, and
139
- * iterate over their output with {@link logs}.
140
- *
141
- * @see {@link Sandbox.runCommand} to start a command.
142
- *
143
- * @hideconstructor
144
- */
145
- export declare class Command {
146
- private client;
147
- private sandboxId;
148
- /**
149
- * ID of the command execution.
150
- */
151
- cmdId: string;
152
- /**
153
- * The exit code of the command, if available. This is set after
154
- * {@link wait} has returned.
155
- */
156
- exitCode: number | null;
157
- constructor({ client, sandboxId, cmdId, }: {
158
- client: SandboxClient;
159
- sandboxId: string;
160
- cmdId: string;
161
- });
162
- /**
163
- * Iterate over the output of this command.
164
- *
165
- * ```
166
- * for await (const log of cmd.logs()) {
167
- * if (log.stream === "stdout") {
168
- * process.stdout.write(log.data);
169
- * } else {
170
- * process.stderr.write(log.data);
171
- * }
172
- * }
173
- * ```
174
- *
175
- * @see {@link Command.stdout}, {@link Command.stderr}, and {@link Command.output}
176
- * to access output as a string.
177
- */
178
- logs(): AsyncGenerator<{
179
- data: string;
180
- stream: "stdout" | "stderr";
181
- }, void, void>;
182
- /**
183
- * Wait for a command to exit and populate it's exit code.
184
- *
185
- * ```
186
- * await cmd.wait()
187
- * if (cmd.exitCode != 0) {
188
- * console.error("Something went wrong...")
189
- * }
190
- * ````
191
- */
192
- wait(): Promise<this>;
193
- /**
194
- * Print command logs to stdout/stderr
195
- */
196
- printLogs(): Promise<void>;
197
- /**
198
- * Get the output of `stdout` or `stderr` as a string.
199
- *
200
- * NOTE: This may error with string conversion errors if the command does
201
- * not ouptut valid unicode.
202
- */
203
- output(stream?: "stdout" | "stderr" | "both"): Promise<string>;
204
- /**
205
- * Get the output of `stdout` as a string.
206
- *
207
- * NOTE: This may error with string conversion errors if the command does
208
- * not ouptut valid unicode.
209
- */
210
- stdout(): Promise<string>;
211
- /**
212
- * Get the output of `stderr` as a string.
213
- *
214
- * NOTE: This may error with string conversion errors if the command does
215
- * not ouptut valid unicode.
216
- */
217
- stderr(): Promise<string>;
218
- }
219
- export {};
@@ -1,231 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Command = exports.Sandbox = exports.SDK = void 0;
4
- const client_1 = require("./client/client");
5
- /**
6
- * SDK for interacting with the Sandbox API. Provides methods to create and
7
- * manage sandboxes configured with specific source code and network ports.
8
- *
9
- * Example:
10
- * ```ts
11
- * const sdk = new SDK({
12
- * teamId: process.env.VERCEL_TEAM_ID!,
13
- * token: process.env.VERCEL_TOKEN!,
14
- * });
15
- * ```
16
- *
17
- * @see {@link SDK.createSandbox} to start a new sandbox.
18
- */
19
- class SDK {
20
- /**
21
- * Create a new instance of `SDK`.
22
- *
23
- * @param config - Configuration options for the SDK.
24
- * @param config.teamId - The Vercel team ID used to scope the Sandbox.
25
- * @param config.token - The API token used for authentication.
26
- */
27
- constructor({ teamId, token }) {
28
- this.client = new client_1.SandboxClient({ teamId, token });
29
- }
30
- /**
31
- * Creates a new sandbox instance using the provided Git repository and exposed ports.
32
- *
33
- * The repository must be public. On start, the sandbox will clone the repository
34
- * and expose the specified ports for access.
35
- *
36
- * @param params - Configuration parameters for the sandbox.
37
- * @param params.source - The source of the sandbox, currently supports Git repositories only.
38
- * @param params.source.type - Type of source, must be `"git"`.
39
- * @param params.source.url - The URL of the public Git repository to clone.
40
- * @param params.projectId - The Vercel project ID used to link the Sandbox to.
41
- * @param params.ports - Array of port numbers to expose from the sandbox.
42
- * @param params.timeout - (Optional) Timeout in seconds before the sandbox auto-terminates.
43
- *
44
- * @returns A promise that resolves to a `Sandbox` instance.
45
- */
46
- async createSandbox(params) {
47
- const { client } = this;
48
- const sandbox = await client.createSandbox({
49
- source: params.source,
50
- projectId: params.projectId,
51
- ports: params.ports ?? [],
52
- timeout: params.timeout,
53
- });
54
- return new Sandbox({
55
- client,
56
- sandboxId: sandbox.json.sandboxId,
57
- routes: sandbox.json.routes,
58
- });
59
- }
60
- /** @hidden */
61
- async getSandbox({ routes, sandboxId, }) {
62
- return new Sandbox({
63
- client: this.client,
64
- sandboxId: sandboxId,
65
- routes: routes,
66
- });
67
- }
68
- }
69
- exports.SDK = SDK;
70
- /**
71
- * A Sandbox is an isolated Linux MicroVM that you can your experiments on.
72
- *
73
- * @see {@link SDK.createSandbox} to construct a Sandbox.
74
- * @hideconstructor
75
- */
76
- class Sandbox {
77
- constructor({ client, routes, sandboxId, }) {
78
- this.client = client;
79
- this.routes = routes;
80
- this.sandboxId = sandboxId;
81
- }
82
- async runCommand(commandOrParams, args) {
83
- return typeof commandOrParams === "string"
84
- ? this._runCommand({ cmd: commandOrParams, args })
85
- : this._runCommand(commandOrParams);
86
- }
87
- async _runCommand(params) {
88
- const commandResponse = await this.client.runCommand({
89
- sandboxId: this.sandboxId,
90
- command: params.cmd,
91
- args: params.args ?? [],
92
- cwd: params.cwd,
93
- env: params.env ?? {},
94
- });
95
- return new Command({
96
- client: this.client,
97
- sandboxId: this.sandboxId,
98
- cmdId: commandResponse.json.cmdId,
99
- });
100
- }
101
- /**
102
- * Write files to the filesystem of this sandbox.
103
- */
104
- async writeFiles(files) {
105
- return this.client.writeFiles({
106
- sandboxId: this.sandboxId,
107
- files: files,
108
- });
109
- }
110
- /**
111
- * Get the public domain of a port of this sandbox.
112
- *
113
- * E.g. `2grza2l7imxe.vercel.run`
114
- */
115
- domain(p) {
116
- const route = this.routes.find(({ port }) => port == p);
117
- if (route) {
118
- return `https://${route.subdomain}.vercel.run`;
119
- }
120
- else {
121
- throw new Error(`No route for port ${p}`);
122
- }
123
- }
124
- }
125
- exports.Sandbox = Sandbox;
126
- /**
127
- * A command executed in a Sandbox.
128
- *
129
- * You can {@link wait} on commands to access their {@link exitCode}, and
130
- * iterate over their output with {@link logs}.
131
- *
132
- * @see {@link Sandbox.runCommand} to start a command.
133
- *
134
- * @hideconstructor
135
- */
136
- class Command {
137
- constructor({ client, sandboxId, cmdId, }) {
138
- this.client = client;
139
- this.sandboxId = sandboxId;
140
- this.cmdId = cmdId;
141
- this.exitCode = null;
142
- }
143
- /**
144
- * Iterate over the output of this command.
145
- *
146
- * ```
147
- * for await (const log of cmd.logs()) {
148
- * if (log.stream === "stdout") {
149
- * process.stdout.write(log.data);
150
- * } else {
151
- * process.stderr.write(log.data);
152
- * }
153
- * }
154
- * ```
155
- *
156
- * @see {@link Command.stdout}, {@link Command.stderr}, and {@link Command.output}
157
- * to access output as a string.
158
- */
159
- logs() {
160
- return this.client.getLogs({
161
- sandboxId: this.sandboxId,
162
- cmdId: this.cmdId,
163
- });
164
- }
165
- /**
166
- * Wait for a command to exit and populate it's exit code.
167
- *
168
- * ```
169
- * await cmd.wait()
170
- * if (cmd.exitCode != 0) {
171
- * console.error("Something went wrong...")
172
- * }
173
- * ````
174
- */
175
- async wait() {
176
- const command = await this.client.getCommand({
177
- sandboxId: this.sandboxId,
178
- cmdId: this.cmdId,
179
- wait: true,
180
- });
181
- this.exitCode = command.json.exitCode;
182
- return this;
183
- }
184
- /**
185
- * Print command logs to stdout/stderr
186
- */
187
- async printLogs() {
188
- for await (const log of this.logs()) {
189
- if (log.stream === "stdout") {
190
- process.stdout.write(log.data);
191
- }
192
- else {
193
- process.stderr.write(log.data);
194
- }
195
- }
196
- }
197
- /**
198
- * Get the output of `stdout` or `stderr` as a string.
199
- *
200
- * NOTE: This may error with string conversion errors if the command does
201
- * not ouptut valid unicode.
202
- */
203
- async output(stream = "both") {
204
- let data = "";
205
- for await (const log of this.logs()) {
206
- if (log.stream === stream) {
207
- data += log.data;
208
- }
209
- }
210
- return data;
211
- }
212
- /**
213
- * Get the output of `stdout` as a string.
214
- *
215
- * NOTE: This may error with string conversion errors if the command does
216
- * not ouptut valid unicode.
217
- */
218
- async stdout() {
219
- return this.output("stdout");
220
- }
221
- /**
222
- * Get the output of `stderr` as a string.
223
- *
224
- * NOTE: This may error with string conversion errors if the command does
225
- * not ouptut valid unicode.
226
- */
227
- async stderr() {
228
- return this.output("stderr");
229
- }
230
- }
231
- exports.Command = Command;
@@ -1,5 +0,0 @@
1
- export interface DeferredGenerator<T, R> {
2
- generator(): AsyncGenerator<T, R, void>;
3
- next: (value: IteratorResult<T | Promise<T>>) => void;
4
- }
5
- export declare function createDeferredGenerator<T, R>(): DeferredGenerator<T, R>;
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createDeferredGenerator = createDeferredGenerator;
4
- const deferred_1 = require("./deferred");
5
- function createDeferredGenerator() {
6
- const deferreds = [new deferred_1.Deferred()];
7
- let currentIndex = 0;
8
- const next = (value) => {
9
- const currentDeferred = deferreds[currentIndex];
10
- if (!value.done) {
11
- deferreds.push(new deferred_1.Deferred());
12
- currentIndex++;
13
- }
14
- currentDeferred.resolve(value);
15
- };
16
- function generator() {
17
- let currentIndex = 0;
18
- return (async function* () {
19
- while (true) {
20
- const result = await deferreds[currentIndex].promise;
21
- if (result.done)
22
- return result.value;
23
- yield result.value;
24
- currentIndex++;
25
- }
26
- })();
27
- }
28
- return {
29
- generator,
30
- next,
31
- };
32
- }
@@ -1,6 +0,0 @@
1
- export declare class Deferred<T> {
2
- promise: Promise<T>;
3
- resolve: (value: T | PromiseLike<T>) => void;
4
- reject: (reason?: any) => void;
5
- constructor();
6
- }
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Deferred = void 0;
4
- class Deferred {
5
- constructor() {
6
- this.promise = new Promise((res, rej) => {
7
- this.resolve = res;
8
- this.reject = rej;
9
- });
10
- }
11
- }
12
- exports.Deferred = Deferred;
@@ -1,188 +0,0 @@
1
- import FormData from "form-data";
2
- import { APIClient, parseOrThrow, type RequestParams } from "./base-client";
3
- import {
4
- Command,
5
- CreatedCommand,
6
- CreatedSandbox,
7
- LogLine,
8
- WrittenFile,
9
- } from "./validators";
10
- import { Readable } from "stream";
11
- import { APIError } from "./api-error";
12
- import { createDeferredGenerator } from "../utils/deferred-generator";
13
- import { VERSION } from "../version";
14
- import { z } from "zod";
15
- import jsonlines from "jsonlines";
16
- import os from "os";
17
-
18
- export class SandboxClient extends APIClient {
19
- private teamId: string;
20
-
21
- constructor(params: { host?: string; teamId: string; token: string }) {
22
- super({
23
- host: params.host ?? "https://api.vercel.com",
24
- token: params.token,
25
- debug: false,
26
- });
27
-
28
- this.teamId = params.teamId;
29
- }
30
-
31
- protected async request(path: string, params?: RequestParams) {
32
- return super.request(path, {
33
- ...params,
34
- query: { teamId: this.teamId, ...params?.query },
35
- headers: {
36
- "content-type": "application/json",
37
- "user-agent": `vercel/sandbox/${VERSION} (Node.js/${process.version}; ${os.platform()}/${os.arch()})`,
38
- ...params?.headers,
39
- },
40
- });
41
- }
42
-
43
- async createSandbox(params: {
44
- ports: number[];
45
- projectId: string;
46
- source: { type: "git"; url: string };
47
- timeout?: number;
48
- }) {
49
- return parseOrThrow(
50
- CreatedSandbox,
51
- await this.request("/v1/sandboxes", {
52
- method: "POST",
53
- body: JSON.stringify({
54
- projectId: params.projectId,
55
- ports: params.ports,
56
- source: params.source,
57
- timeout: params.timeout,
58
- }),
59
- }),
60
- );
61
- }
62
-
63
- async runCommand(params: {
64
- sandboxId: string;
65
- cwd?: string;
66
- command: string;
67
- args: string[];
68
- env: Record<string, string>;
69
- }) {
70
- return parseOrThrow(
71
- CreatedCommand,
72
- await this.request(`/v1/sandboxes/${params.sandboxId}/cmd`, {
73
- method: "POST",
74
- body: JSON.stringify({
75
- command: params.command,
76
- args: params.args,
77
- cwd: params.cwd,
78
- env: params.env,
79
- }),
80
- }),
81
- );
82
- }
83
-
84
- async getCommand(params: {
85
- sandboxId: string;
86
- cmdId: string;
87
- wait?: boolean;
88
- }) {
89
- return parseOrThrow(
90
- Command,
91
- await this.request(
92
- `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`,
93
- { query: { wait: params.wait ? "true" : undefined } },
94
- ),
95
- );
96
- }
97
-
98
- async writeFiles(params: {
99
- sandboxId: string;
100
- files: { path: string; stream: Readable | Buffer }[];
101
- }) {
102
- const formData = new FormData();
103
-
104
- for (const file of params.files) {
105
- formData.append(file.path, file.stream, file.path);
106
- }
107
-
108
- await parseOrThrow(
109
- WrittenFile,
110
- await this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {
111
- method: "POST",
112
- headers: { ...formData.getHeaders() },
113
- body: formData,
114
- }),
115
- );
116
- }
117
-
118
- async readFile(params: {
119
- sandboxId: string;
120
- path: string;
121
- cwd?: string;
122
- }): Promise<NodeJS.ReadableStream | null> {
123
- const response = await this.request(
124
- `/v1/sandboxes/${params.sandboxId}/fs/read`,
125
- {
126
- method: "POST",
127
- body: JSON.stringify({ path: params.path, cwd: params.cwd }),
128
- },
129
- );
130
-
131
- if (response.status === 404) {
132
- return null;
133
- }
134
-
135
- return response.body;
136
- }
137
-
138
- getLogs(params: { sandboxId: string; cmdId: string }) {
139
- const deferred = createDeferredGenerator<z.infer<typeof LogLine>, void>();
140
-
141
- (async () => {
142
- const response = await this.request(
143
- `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}/logs`,
144
- { method: "GET" },
145
- );
146
-
147
- if (response.headers.get("content-type") !== "application/x-ndjson") {
148
- throw new APIError(response, {
149
- message: "Expected a stream of logs",
150
- });
151
- }
152
-
153
- const parser = jsonlines.parse();
154
- response.body.pipe(parser);
155
-
156
- parser.on("data", (data) => {
157
- const parsed = LogLine.safeParse(data);
158
- if (parsed.success) {
159
- deferred.next({
160
- value: parsed.data,
161
- done: false,
162
- });
163
- } else {
164
- deferred.next({
165
- value: Promise.reject(parsed.error),
166
- done: false,
167
- });
168
- }
169
- });
170
-
171
- parser.on("error", (err) => {
172
- deferred.next({
173
- value: Promise.reject(err),
174
- done: false,
175
- });
176
- });
177
-
178
- parser.on("end", () => {
179
- deferred.next({
180
- value: undefined,
181
- done: true,
182
- });
183
- });
184
- })();
185
-
186
- return deferred.generator();
187
- }
188
- }