@phpsandbox/sdk 0.0.57 → 0.0.59
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/README.md +12 -7
- package/dist/browser/phpsandbox-sdk.esm.js +15552 -527
- package/dist/browser/phpsandbox-sdk.esm.min.js +70 -3
- package/dist/browser/phpsandbox-sdk.iife.js +15552 -527
- package/dist/browser/phpsandbox-sdk.iife.min.js +70 -3
- package/dist/deployments.d.ts +167 -107
- package/dist/deployments.js +283 -23
- package/dist/git.d.ts +36 -2
- package/dist/git.js +12 -3
- package/dist/index.d.ts +15 -5
- package/dist/index.js +26 -4
- package/dist/schemas/deployments.d.ts +417 -0
- package/dist/schemas/deployments.js +133 -0
- package/dist/servers.d.ts +42 -0
- package/dist/servers.js +48 -0
- package/docs/api-summary.md +1 -1
- package/examples/README.md +28 -0
- package/examples/deploy-cloudflare-container.ts +49 -0
- package/examples/deploy-laravel-cloud.ts +111 -0
- package/examples/deploy-ssh-agent.ts +211 -0
- package/examples/get.ts +2 -5
- package/package.json +4 -3
package/dist/deployments.js
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
+
import { ApiError } from './index.js';
|
|
2
|
+
import { DeploymentEventDataSchema, DeploymentLogChunkDataSchema, DeployStreamSseEventNameSchema, DeployStreamSseEventSchema, } from './schemas/deployments.js';
|
|
3
|
+
export * from './schemas/deployments.js';
|
|
1
4
|
export class NotebookDeploymentApi {
|
|
2
5
|
constructor(client) {
|
|
3
6
|
this.client = client;
|
|
4
7
|
}
|
|
5
|
-
async
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
async current(notebookId) {
|
|
9
|
+
try {
|
|
10
|
+
const response = await this.client.get(`/notebook/${notebookId}/deployment`);
|
|
11
|
+
return new DeploymentInstance(response.data, this.client, notebookId);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (error instanceof ApiError && error.status === 404) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
8
19
|
}
|
|
9
|
-
async
|
|
10
|
-
const response = await this.client.
|
|
11
|
-
|
|
20
|
+
async publish(notebookId, input) {
|
|
21
|
+
const response = await this.client.post(`/notebook/${notebookId}/deployment/publish`, input);
|
|
22
|
+
const run = new DeploymentRun(new DeploymentInstance(response.data, this.client, notebookId), this.client);
|
|
23
|
+
run.start();
|
|
24
|
+
return run;
|
|
12
25
|
}
|
|
13
26
|
async slugAvailability(id, slug) {
|
|
14
27
|
const query = new URLSearchParams({ slug }).toString();
|
|
15
|
-
const response = await this.client.get(`/notebook/${id}/
|
|
28
|
+
const response = await this.client.get(`/notebook/${id}/deployment/slug-availability?${query}`);
|
|
16
29
|
return response.data;
|
|
17
30
|
}
|
|
18
31
|
}
|
|
@@ -24,10 +37,6 @@ export class DeploymentApi {
|
|
|
24
37
|
const response = await this.client.get(`/deployments/${id}`);
|
|
25
38
|
return new DeploymentInstance(response.data, this.client);
|
|
26
39
|
}
|
|
27
|
-
async redeploy(id, input = {}) {
|
|
28
|
-
const response = await this.client.post(`/deployments/${id}/redeploy`, input);
|
|
29
|
-
return new DeploymentInstance(response.data, this.client);
|
|
30
|
-
}
|
|
31
40
|
async delete(id) {
|
|
32
41
|
await this.client.delete(`/deployments/${id}`);
|
|
33
42
|
}
|
|
@@ -67,25 +76,140 @@ export class DeploymentApi {
|
|
|
67
76
|
await this.client.delete(`/deployments/${id}/domains/${domainId}`);
|
|
68
77
|
}
|
|
69
78
|
async events(id) {
|
|
70
|
-
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/events/stream`));
|
|
79
|
+
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/events/stream`), DeploymentEventDataSchema);
|
|
71
80
|
}
|
|
72
81
|
async buildLogs(id, buildId) {
|
|
73
|
-
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/builds/${buildId}/logs/stream`));
|
|
82
|
+
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/builds/${buildId}/logs/stream`), DeploymentLogChunkDataSchema);
|
|
74
83
|
}
|
|
75
84
|
async logs(id) {
|
|
76
|
-
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/logs/stream`));
|
|
85
|
+
return parseNdjsonStream(await this.client.stream(`/deployments/${id}/logs/stream`), DeploymentLogChunkDataSchema);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export class DeploymentRun {
|
|
89
|
+
constructor(initial, client) {
|
|
90
|
+
this.initial = initial;
|
|
91
|
+
this.client = client;
|
|
92
|
+
this.started = false;
|
|
93
|
+
this.completed = false;
|
|
94
|
+
this.finalError = null;
|
|
95
|
+
this.finalResult = null;
|
|
96
|
+
this.resultPromise = null;
|
|
97
|
+
this.resolveResult = null;
|
|
98
|
+
this.rejectResult = null;
|
|
99
|
+
this.bufferedEvents = [];
|
|
100
|
+
this.subscribers = new Set();
|
|
101
|
+
}
|
|
102
|
+
async *events() {
|
|
103
|
+
this.start();
|
|
104
|
+
const queue = this.subscribe();
|
|
105
|
+
try {
|
|
106
|
+
for await (const event of queue) {
|
|
107
|
+
yield event;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
this.subscribers.delete(queue);
|
|
112
|
+
queue.close();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
result() {
|
|
116
|
+
this.start();
|
|
117
|
+
return this.resultPromise;
|
|
118
|
+
}
|
|
119
|
+
async deployment() {
|
|
120
|
+
await this.result();
|
|
121
|
+
return this.initial.refresh();
|
|
122
|
+
}
|
|
123
|
+
start() {
|
|
124
|
+
if (this.started) {
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
if (!this.initial.data.okraUrl) {
|
|
128
|
+
throw new Error(`Deployment ${this.initial.data.id} has no okraUrl for SSE streaming`);
|
|
129
|
+
}
|
|
130
|
+
this.started = true;
|
|
131
|
+
this.resultPromise = new Promise((resolve, reject) => {
|
|
132
|
+
this.resolveResult = resolve;
|
|
133
|
+
this.rejectResult = reject;
|
|
134
|
+
});
|
|
135
|
+
this.resultPromise.catch(() => undefined);
|
|
136
|
+
void this.consumeStream(this.initial.data.okraUrl);
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
subscribe() {
|
|
140
|
+
const queue = new AsyncDeployEventQueue();
|
|
141
|
+
for (const event of this.bufferedEvents) {
|
|
142
|
+
queue.push(event);
|
|
143
|
+
}
|
|
144
|
+
if (this.finalError) {
|
|
145
|
+
queue.fail(this.finalError);
|
|
146
|
+
}
|
|
147
|
+
else if (this.completed) {
|
|
148
|
+
queue.close();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.subscribers.add(queue);
|
|
152
|
+
}
|
|
153
|
+
return queue;
|
|
154
|
+
}
|
|
155
|
+
async consumeStream(okraUrl) {
|
|
156
|
+
try {
|
|
157
|
+
const stream = await this.client.sse(okraUrl);
|
|
158
|
+
for await (const event of readDeployStreamEvents(stream)) {
|
|
159
|
+
this.publish(event);
|
|
160
|
+
if (event.type === 'result') {
|
|
161
|
+
const { type: _, ...result } = event;
|
|
162
|
+
this.finalResult = result;
|
|
163
|
+
this.resolveResult?.(result);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (!this.finalResult) {
|
|
167
|
+
throw new Error('Deploy stream ended without result');
|
|
168
|
+
}
|
|
169
|
+
this.closeSubscribers();
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
this.fail(err instanceof Error ? err : new Error(String(err)));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
publish(event) {
|
|
176
|
+
this.bufferedEvents.push(event);
|
|
177
|
+
for (const subscriber of this.subscribers) {
|
|
178
|
+
subscriber.push(event);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
closeSubscribers() {
|
|
182
|
+
this.completed = true;
|
|
183
|
+
for (const subscriber of this.subscribers) {
|
|
184
|
+
subscriber.close();
|
|
185
|
+
}
|
|
186
|
+
this.subscribers.clear();
|
|
187
|
+
}
|
|
188
|
+
fail(error) {
|
|
189
|
+
this.finalError = error;
|
|
190
|
+
this.completed = true;
|
|
191
|
+
this.rejectResult?.(error);
|
|
192
|
+
for (const subscriber of this.subscribers) {
|
|
193
|
+
subscriber.fail(error);
|
|
194
|
+
}
|
|
195
|
+
this.subscribers.clear();
|
|
77
196
|
}
|
|
78
197
|
}
|
|
79
198
|
export class DeploymentInstance {
|
|
80
|
-
constructor(data, client) {
|
|
199
|
+
constructor(data, client, notebookId) {
|
|
81
200
|
this.data = data;
|
|
82
201
|
this.client = client;
|
|
202
|
+
this.notebookId = notebookId;
|
|
83
203
|
}
|
|
84
|
-
refresh() {
|
|
85
|
-
|
|
204
|
+
async refresh() {
|
|
205
|
+
const response = await this.client.get(`/deployments/${this.data.id}`);
|
|
206
|
+
return new DeploymentInstance(response.data, this.client, this.notebookId);
|
|
86
207
|
}
|
|
87
|
-
|
|
88
|
-
|
|
208
|
+
publish() {
|
|
209
|
+
if (!this.notebookId) {
|
|
210
|
+
return Promise.reject(new Error('Deployment publish requires a notebook-scoped deployment instance.'));
|
|
211
|
+
}
|
|
212
|
+
return this.client.notebook.deployment.publish(this.notebookId);
|
|
89
213
|
}
|
|
90
214
|
delete() {
|
|
91
215
|
return this.client.deployments.delete(this.data.id);
|
|
@@ -107,7 +231,7 @@ export class DeploymentInstance {
|
|
|
107
231
|
events() {
|
|
108
232
|
return this.client.deployments.events(this.data.id);
|
|
109
233
|
}
|
|
110
|
-
buildLogs(buildId = this.data.
|
|
234
|
+
buildLogs(buildId = this.data.latestBuild?.id ?? '') {
|
|
111
235
|
if (buildId === '') {
|
|
112
236
|
return Promise.reject(new Error('Deployment has no latest build id'));
|
|
113
237
|
}
|
|
@@ -156,7 +280,143 @@ function unwrapDeploymentDomainCollection(input) {
|
|
|
156
280
|
}
|
|
157
281
|
return Array.isArray(input.data) ? input.data : [];
|
|
158
282
|
}
|
|
159
|
-
|
|
283
|
+
class AsyncDeployEventQueue {
|
|
284
|
+
constructor() {
|
|
285
|
+
this.values = [];
|
|
286
|
+
this.pending = [];
|
|
287
|
+
this.closed = false;
|
|
288
|
+
this.error = null;
|
|
289
|
+
}
|
|
290
|
+
push(value) {
|
|
291
|
+
if (this.closed) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const next = this.pending.shift();
|
|
295
|
+
if (next) {
|
|
296
|
+
next.resolve({ done: false, value });
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
this.values.push(value);
|
|
300
|
+
}
|
|
301
|
+
close() {
|
|
302
|
+
if (this.closed) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
this.closed = true;
|
|
306
|
+
for (const next of this.pending.splice(0)) {
|
|
307
|
+
next.resolve({ done: true, value: undefined });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
fail(error) {
|
|
311
|
+
if (this.closed) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
this.error = error;
|
|
315
|
+
this.closed = true;
|
|
316
|
+
for (const next of this.pending.splice(0)) {
|
|
317
|
+
next.reject(error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async *[Symbol.asyncIterator]() {
|
|
321
|
+
while (true) {
|
|
322
|
+
const next = await this.next();
|
|
323
|
+
if (next.done) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
yield next.value;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
next() {
|
|
330
|
+
const value = this.values.shift();
|
|
331
|
+
if (value) {
|
|
332
|
+
return Promise.resolve({ done: false, value });
|
|
333
|
+
}
|
|
334
|
+
if (this.error) {
|
|
335
|
+
return Promise.reject(this.error);
|
|
336
|
+
}
|
|
337
|
+
if (this.closed) {
|
|
338
|
+
return Promise.resolve({ done: true, value: undefined });
|
|
339
|
+
}
|
|
340
|
+
return new Promise((resolve, reject) => {
|
|
341
|
+
this.pending.push({ resolve, reject });
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async function* readDeployStreamEvents(stream) {
|
|
346
|
+
const reader = parseSSEStream(stream).getReader();
|
|
347
|
+
try {
|
|
348
|
+
while (true) {
|
|
349
|
+
const { done, value } = await reader.read();
|
|
350
|
+
if (done) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const event = parseDeployStreamEvent(value);
|
|
354
|
+
if (event) {
|
|
355
|
+
yield event;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
reader.releaseLock();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function parseDeployStreamEvent(event) {
|
|
364
|
+
if (!DeployStreamSseEventNameSchema.safeParse(event.event).success) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
return DeployStreamSseEventSchema.parse(event);
|
|
368
|
+
}
|
|
369
|
+
function parseSSEStream(input) {
|
|
370
|
+
const decoder = new TextDecoder();
|
|
371
|
+
let buffer = '';
|
|
372
|
+
return input.pipeThrough(new TransformStream({
|
|
373
|
+
transform(chunk, controller) {
|
|
374
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
375
|
+
const blocks = buffer.split('\n\n');
|
|
376
|
+
buffer = blocks.pop() ?? '';
|
|
377
|
+
for (const block of blocks) {
|
|
378
|
+
const event = parseSSEBlock(block);
|
|
379
|
+
if (event) {
|
|
380
|
+
controller.enqueue(event);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
flush(controller) {
|
|
385
|
+
buffer += decoder.decode();
|
|
386
|
+
if (buffer.trim() !== '') {
|
|
387
|
+
const event = parseSSEBlock(buffer);
|
|
388
|
+
if (event) {
|
|
389
|
+
controller.enqueue(event);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
}));
|
|
394
|
+
}
|
|
395
|
+
function parseSSEBlock(block) {
|
|
396
|
+
let eventType = 'message';
|
|
397
|
+
let data = '';
|
|
398
|
+
for (const line of block.split('\n')) {
|
|
399
|
+
if (line.startsWith('event: ')) {
|
|
400
|
+
eventType = line.slice(7).trim();
|
|
401
|
+
}
|
|
402
|
+
else if (line.startsWith('data: ')) {
|
|
403
|
+
data += line.slice(6);
|
|
404
|
+
}
|
|
405
|
+
else if (line.startsWith('data:')) {
|
|
406
|
+
data += line.slice(5);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (data === '') {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
return { event: eventType, data: JSON.parse(data) };
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
return { event: eventType, data };
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function parseNdjsonStream(input, schema) {
|
|
160
420
|
const decoder = new TextDecoder();
|
|
161
421
|
let buffer = '';
|
|
162
422
|
return input.pipeThrough(new TransformStream({
|
|
@@ -167,7 +427,7 @@ function parseNdjsonStream(input) {
|
|
|
167
427
|
for (const line of lines) {
|
|
168
428
|
const trimmed = line.trim();
|
|
169
429
|
if (trimmed !== '') {
|
|
170
|
-
controller.enqueue(JSON.parse(trimmed));
|
|
430
|
+
controller.enqueue(schema.parse(JSON.parse(trimmed)));
|
|
171
431
|
}
|
|
172
432
|
}
|
|
173
433
|
},
|
|
@@ -175,7 +435,7 @@ function parseNdjsonStream(input) {
|
|
|
175
435
|
buffer += decoder.decode();
|
|
176
436
|
const trimmed = buffer.trim();
|
|
177
437
|
if (trimmed !== '') {
|
|
178
|
-
controller.enqueue(JSON.parse(trimmed));
|
|
438
|
+
controller.enqueue(schema.parse(JSON.parse(trimmed)));
|
|
179
439
|
}
|
|
180
440
|
},
|
|
181
441
|
}));
|
package/dist/git.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Client, SecretRef } from './index.js';
|
|
1
2
|
import { Action, NotebookInstance } from './index.js';
|
|
2
3
|
export interface GitLog {
|
|
3
4
|
hash: string;
|
|
@@ -48,6 +49,36 @@ export interface GitCredentials {
|
|
|
48
49
|
abilities: string[];
|
|
49
50
|
expiresAt: string;
|
|
50
51
|
}
|
|
52
|
+
export type GitProvider = 'github' | (string & {});
|
|
53
|
+
export type GitRepositoryVisibility = 'private' | 'public';
|
|
54
|
+
export type GitSyncDirection = 'pull' | 'push' | 'both';
|
|
55
|
+
export interface GitSyncAuthor {
|
|
56
|
+
name: string;
|
|
57
|
+
email: string;
|
|
58
|
+
}
|
|
59
|
+
export interface GitSyncTargetInput {
|
|
60
|
+
provider: GitProvider;
|
|
61
|
+
repository: string;
|
|
62
|
+
author: GitSyncAuthor;
|
|
63
|
+
branch?: string;
|
|
64
|
+
credential: SecretRef;
|
|
65
|
+
direction?: GitSyncDirection;
|
|
66
|
+
visibility?: GitRepositoryVisibility;
|
|
67
|
+
setDefault?: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface GitSyncTargetData {
|
|
70
|
+
id: string;
|
|
71
|
+
provider: GitProvider;
|
|
72
|
+
repository: string;
|
|
73
|
+
url: string | null;
|
|
74
|
+
branch: string;
|
|
75
|
+
credentialConfigured: boolean;
|
|
76
|
+
default: boolean;
|
|
77
|
+
lastCommitSha: string | null;
|
|
78
|
+
lastSyncedAt: string | null;
|
|
79
|
+
createdAt: string | null;
|
|
80
|
+
updatedAt: string | null;
|
|
81
|
+
}
|
|
51
82
|
export interface GitCheckoutResult extends GitRef {
|
|
52
83
|
branch: string;
|
|
53
84
|
created: boolean;
|
|
@@ -180,10 +211,12 @@ export interface GitActions {
|
|
|
180
211
|
}
|
|
181
212
|
export default class Git {
|
|
182
213
|
protected okra: NotebookInstance;
|
|
183
|
-
|
|
214
|
+
private readonly client;
|
|
215
|
+
constructor(okra: NotebookInstance, client: Client);
|
|
184
216
|
checkpoint(author: string, message: string, branch?: string, allowEmpty?: boolean): Promise<GitRef>;
|
|
185
217
|
checkout(branch: string, create?: boolean): Promise<GitCheckoutResult>;
|
|
186
|
-
sync(
|
|
218
|
+
sync(input: GitSyncTargetInput): Promise<GitSyncTargetData>;
|
|
219
|
+
syncTargets(): Promise<GitSyncTargetData[]>;
|
|
187
220
|
log(ref?: string): Promise<GitLog[]>;
|
|
188
221
|
diff(input: GitDiffInput): Promise<GitDiffPreview>;
|
|
189
222
|
merge(input: GitMergeInput): Promise<GitMergeResult>;
|
|
@@ -199,5 +232,6 @@ export default class Git {
|
|
|
199
232
|
status(): Promise<GitStatus>;
|
|
200
233
|
private normalizeRemoteInput;
|
|
201
234
|
private gitUrlForNotebook;
|
|
235
|
+
private omitUndefined;
|
|
202
236
|
}
|
|
203
237
|
export {};
|
package/dist/git.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default class Git {
|
|
2
|
-
constructor(okra) {
|
|
2
|
+
constructor(okra, client) {
|
|
3
3
|
this.okra = okra;
|
|
4
|
+
this.client = client;
|
|
4
5
|
}
|
|
5
6
|
checkpoint(author, message, branch = 'main', allowEmpty = false) {
|
|
6
7
|
return this.okra.invoke('git.checkpoint', { author, message, branch, allowEmpty });
|
|
@@ -8,8 +9,13 @@ export default class Git {
|
|
|
8
9
|
checkout(branch, create = true) {
|
|
9
10
|
return this.okra.invoke('git.checkout', { branch, create });
|
|
10
11
|
}
|
|
11
|
-
sync(
|
|
12
|
-
|
|
12
|
+
async sync(input) {
|
|
13
|
+
const response = await this.client.post(`/notebook/${this.okra.data.id}/git/sync-targets`, this.omitUndefined({ ...input }));
|
|
14
|
+
return response.data;
|
|
15
|
+
}
|
|
16
|
+
async syncTargets() {
|
|
17
|
+
const response = await this.client.get(`/notebook/${this.okra.data.id}/git/sync-targets`);
|
|
18
|
+
return response.data;
|
|
13
19
|
}
|
|
14
20
|
log(ref = 'main') {
|
|
15
21
|
return this.okra.invoke('git.log', { ref });
|
|
@@ -79,4 +85,7 @@ export default class Git {
|
|
|
79
85
|
url.hash = '';
|
|
80
86
|
return url.toString();
|
|
81
87
|
}
|
|
88
|
+
omitUndefined(input) {
|
|
89
|
+
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
90
|
+
}
|
|
82
91
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ import Git, { GitActions, GitCredentials, GitEvents } from './git.js';
|
|
|
15
15
|
import { Disposable } from './types.js';
|
|
16
16
|
import { Beacon, BeaconOptions } from './beacon/index.js';
|
|
17
17
|
import { NotebookUnavailableError } from './errors/index.js';
|
|
18
|
-
import { DeploymentApi, NotebookDeploymentApi, type
|
|
18
|
+
import { DeploymentApi, NotebookDeploymentApi, type DeploymentInstance, type DeploymentRun, type PublishInput } from './deployments.js';
|
|
19
|
+
import { ServerApi } from './servers.js';
|
|
19
20
|
export * from './types.js';
|
|
20
21
|
export { Transport } from './socket/index.js';
|
|
21
22
|
export * from './lsp.js';
|
|
@@ -30,6 +31,7 @@ export * from './utils/promise.js';
|
|
|
30
31
|
export * from './beacon/index.js';
|
|
31
32
|
export * from './errors/index.js';
|
|
32
33
|
export * from './deployments.js';
|
|
34
|
+
export * from './servers.js';
|
|
33
35
|
interface Result<TType extends 'success' | 'error' | 'running', TData extends object> {
|
|
34
36
|
type: TType;
|
|
35
37
|
message: string;
|
|
@@ -125,10 +127,15 @@ export interface NotebookPolicyData {
|
|
|
125
127
|
prune_after_at: string | null;
|
|
126
128
|
}
|
|
127
129
|
export type SecretEnvironment = 'development' | 'production';
|
|
130
|
+
export type SecretType = 'environment_variable' | 'credential';
|
|
131
|
+
export interface SecretRef {
|
|
132
|
+
secret: string;
|
|
133
|
+
environment?: SecretEnvironment;
|
|
134
|
+
}
|
|
128
135
|
export interface NotebookSecretData {
|
|
129
136
|
uuid: string;
|
|
130
137
|
name: string;
|
|
131
|
-
type:
|
|
138
|
+
type: SecretType;
|
|
132
139
|
environment: SecretEnvironment;
|
|
133
140
|
createdAt: string | null;
|
|
134
141
|
updatedAt: string | null;
|
|
@@ -138,7 +145,7 @@ export interface NotebookSecretListOptions {
|
|
|
138
145
|
}
|
|
139
146
|
export interface UpsertNotebookSecretInput {
|
|
140
147
|
value: string;
|
|
141
|
-
type?:
|
|
148
|
+
type?: SecretType;
|
|
142
149
|
environment?: SecretEnvironment;
|
|
143
150
|
}
|
|
144
151
|
export interface UpsertNotebookSecretItemInput extends UpsertNotebookSecretInput {
|
|
@@ -223,7 +230,7 @@ export declare class NotebookApi {
|
|
|
223
230
|
readonly secrets: NotebookSecretApi;
|
|
224
231
|
readonly preview: NotebookPreviewApi;
|
|
225
232
|
readonly mail: NotebookMailApi;
|
|
226
|
-
readonly
|
|
233
|
+
readonly deployment: NotebookDeploymentApi;
|
|
227
234
|
constructor(client: Client);
|
|
228
235
|
create(template: string, input?: Partial<CreateNotebookInput>, init?: boolean): Promise<NotebookInstance>;
|
|
229
236
|
get(id: string): Promise<NotebookInstance>;
|
|
@@ -245,6 +252,7 @@ export interface PHPSandboxClientOptions {
|
|
|
245
252
|
export declare class Client {
|
|
246
253
|
readonly notebook: NotebookApi;
|
|
247
254
|
readonly deployments: DeploymentApi;
|
|
255
|
+
readonly servers: ServerApi;
|
|
248
256
|
readonly options: PHPSandboxClientOptions;
|
|
249
257
|
private readonly fetch;
|
|
250
258
|
private readonly baseUrl;
|
|
@@ -263,6 +271,7 @@ export declare class Client {
|
|
|
263
271
|
data: T;
|
|
264
272
|
}>;
|
|
265
273
|
stream(path: string): Promise<ReadableStream<Uint8Array>>;
|
|
274
|
+
sse(url: string): Promise<ReadableStream<Uint8Array>>;
|
|
266
275
|
private makeRequest;
|
|
267
276
|
}
|
|
268
277
|
export declare class PHPSandbox extends Client {
|
|
@@ -331,7 +340,8 @@ export declare class NotebookInstance {
|
|
|
331
340
|
constructor(data: NotebookData, client: Client);
|
|
332
341
|
ready(): Promise<NotebookInitSuccessResult>;
|
|
333
342
|
fork(input?: Partial<ForkNotebookInput>): Promise<NotebookInstance>;
|
|
334
|
-
|
|
343
|
+
deployment(): Promise<DeploymentInstance | null>;
|
|
344
|
+
publish(input?: PublishInput): Promise<DeploymentRun>;
|
|
335
345
|
gitCredentials(): Promise<GitCredentials>;
|
|
336
346
|
delete(): Promise<void>;
|
|
337
347
|
stop(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -28,6 +28,7 @@ import Git from './git.js';
|
|
|
28
28
|
import { createBeacon } from './beacon/index.js';
|
|
29
29
|
import { NotebookUnavailableError } from './errors/index.js';
|
|
30
30
|
import { DeploymentApi, NotebookDeploymentApi } from './deployments.js';
|
|
31
|
+
import { ServerApi } from './servers.js';
|
|
31
32
|
export * from './types.js';
|
|
32
33
|
export { Transport } from './socket/index.js';
|
|
33
34
|
export * from './lsp.js';
|
|
@@ -42,6 +43,7 @@ export * from './utils/promise.js';
|
|
|
42
43
|
export * from './beacon/index.js';
|
|
43
44
|
export * from './errors/index.js';
|
|
44
45
|
export * from './deployments.js';
|
|
46
|
+
export * from './servers.js';
|
|
45
47
|
function normalizeNotebookSecretInputs(input) {
|
|
46
48
|
if (Array.isArray(input)) {
|
|
47
49
|
return input;
|
|
@@ -97,7 +99,7 @@ export class NotebookApi {
|
|
|
97
99
|
this.secrets = new NotebookSecretApi(client);
|
|
98
100
|
this.preview = new NotebookPreviewApi(client);
|
|
99
101
|
this.mail = new NotebookMailApi(client);
|
|
100
|
-
this.
|
|
102
|
+
this.deployment = new NotebookDeploymentApi(client);
|
|
101
103
|
}
|
|
102
104
|
async create(template, input = {}, init = true) {
|
|
103
105
|
const response = await this.client.post('/notebook', { template, ...input });
|
|
@@ -151,6 +153,7 @@ export class Client {
|
|
|
151
153
|
this.fetch = globalThis.fetch;
|
|
152
154
|
this.deployments = new DeploymentApi(this);
|
|
153
155
|
this.notebook = new NotebookApi(this);
|
|
156
|
+
this.servers = new ServerApi(this);
|
|
154
157
|
this.options = Object.assign({ startClosed: true }, options);
|
|
155
158
|
this.baseUrl = normalizeApiBaseUrl(url);
|
|
156
159
|
if (options.fetch) {
|
|
@@ -187,6 +190,22 @@ export class Client {
|
|
|
187
190
|
}
|
|
188
191
|
return response.body;
|
|
189
192
|
}
|
|
193
|
+
async sse(url) {
|
|
194
|
+
const response = await this.fetch(new Request(url, {
|
|
195
|
+
method: 'GET',
|
|
196
|
+
headers: {
|
|
197
|
+
...this.headers,
|
|
198
|
+
'Accept': 'text/event-stream',
|
|
199
|
+
},
|
|
200
|
+
}));
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
throw new ApiError(response, await response.text());
|
|
203
|
+
}
|
|
204
|
+
if (!response.body) {
|
|
205
|
+
throw new Error('PHPSandbox API Error: SSE response body is not readable');
|
|
206
|
+
}
|
|
207
|
+
return response.body;
|
|
208
|
+
}
|
|
190
209
|
async makeRequest(method, path, init) {
|
|
191
210
|
const response = await this.fetch(new Request(new URL(path.replace(/^\//, ''), this.baseUrl), {
|
|
192
211
|
method,
|
|
@@ -313,7 +332,7 @@ export class NotebookInstance {
|
|
|
313
332
|
this.container = new Container(this);
|
|
314
333
|
this.laravel = new Laravel(this);
|
|
315
334
|
this.shell = new Shell(this);
|
|
316
|
-
this.git = new Git(this);
|
|
335
|
+
this.git = new Git(this, client);
|
|
317
336
|
this.services = new Services(this);
|
|
318
337
|
this.config = new Config(this);
|
|
319
338
|
this.secrets = new NotebookSecrets(client, this.data.id);
|
|
@@ -342,8 +361,11 @@ export class NotebookInstance {
|
|
|
342
361
|
fork(input = {}) {
|
|
343
362
|
return this.client.notebook.fork(this.data.id, input);
|
|
344
363
|
}
|
|
345
|
-
|
|
346
|
-
return this.client.notebook.
|
|
364
|
+
deployment() {
|
|
365
|
+
return this.client.notebook.deployment.current(this.data.id);
|
|
366
|
+
}
|
|
367
|
+
publish(input) {
|
|
368
|
+
return this.client.notebook.deployment.publish(this.data.id, input);
|
|
347
369
|
}
|
|
348
370
|
gitCredentials() {
|
|
349
371
|
return this.client.notebook.gitCredentials(this.data.id);
|