@phpsandbox/sdk 0.1.4 → 0.1.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.
package/README.md CHANGED
@@ -111,6 +111,7 @@ Each `NotebookInstance` exposes service clients:
111
111
  - `notebook.container` (`Container`)
112
112
  - `notebook.composer` (`Composer`)
113
113
  - `notebook.git` (`Git`)
114
+ - `notebook.integrations` (`SandboxIntegrationApi`)
114
115
  - `notebook.lsp` (`Lsp`)
115
116
  - `notebook.repl` (`Repl`)
116
117
  - `notebook.auth` (`Auth`)
@@ -119,6 +120,7 @@ Each `NotebookInstance` exposes service clients:
119
120
  - `notebook.metrics` (`Metrics`)
120
121
  - `notebook.services` (`Services`)
121
122
  - `notebook.mail` (`NotebookMail`)
123
+ - `notebook.feedback` (`Feedback`)
122
124
 
123
125
  Notes:
124
126
 
@@ -242,18 +244,19 @@ console.log(installed.map((pkg) => pkg.name));
242
244
  ```ts
243
245
  await notebook.git.checkpoint('Jane Doe <jane@example.com>', 'Initial checkpoint');
244
246
 
245
- await notebook.secrets.set('GITHUB_TOKEN', {
246
- value: process.env.GITHUB_TOKEN!,
247
- type: 'credential',
247
+ const github = await client.integrations.link({
248
+ provider: 'github',
249
+ authorization: { type: 'token', token: process.env.GITHUB_TOKEN! },
248
250
  });
251
+ await notebook.integrations.attach({ integration: github });
249
252
 
250
- await notebook.git.sync({
253
+ const target = await notebook.git.targets.create({
251
254
  provider: 'github',
252
255
  repository: 'acme/my-repo',
253
- author: 'Jane Doe <jane@example.com>',
256
+ author: { name: 'Jane Doe', email: 'jane@example.com' },
254
257
  branch: 'main',
255
- credential: { secret: 'GITHUB_TOKEN' },
256
258
  });
259
+ await target.sync();
257
260
 
258
261
  const history = await notebook.git.log('main');
259
262
  console.log(history[0]);
@@ -306,6 +309,28 @@ await notebook.mail.delete(mail.hash);
306
309
  await notebook.mail.disable();
307
310
  ```
308
311
 
312
+ ### Feedback
313
+
314
+ ```ts
315
+ await sandbox.feedback.configure({
316
+ widget: {
317
+ targets: ['preview', 'publication'],
318
+ types: ['bug', 'suggestion', 'question'],
319
+ },
320
+ });
321
+
322
+ const feedback = await sandbox.feedback.submit({
323
+ type: 'bug',
324
+ message: 'Saving the profile failed.',
325
+ author: { externalId: 'customer-42', email: 'ada@example.com' },
326
+ context: { url: 'https://app.example.com/profile', path: '/profile' },
327
+ });
328
+
329
+ await sandbox.feedback.update(feedback.id, { status: 'resolved' });
330
+ ```
331
+
332
+ The server-side SDK uses the same PHPSandbox API token as the rest of the sandbox. Set `widget: null` to remove the optional popout without disabling API ingestion.
333
+
309
334
  ### Events
310
335
 
311
336
  ```ts
@@ -401,7 +401,7 @@ var Filesystem = class {
401
401
  return this.okra.invoke("fs.textSearch", { query, options: { ...defaultOptions, ...options } }).finally(() => disposable.dispose());
402
402
  }
403
403
  tail(path, options = {}) {
404
- return this.okra.invoke("fs.tail", { path, lines: options.lines ?? 10 }).catch((e) => this.handleError(e));
404
+ return this.okra.invoke("fs.tail", { path, lines: options.lines ?? 10 }).then(({ content }) => content).catch((e) => this.handleError(e));
405
405
  }
406
406
  stat(path) {
407
407
  return this.okra.invoke("fs.stat", { path }).catch((e) => this.handleError(e));
@@ -4166,6 +4166,7 @@ var Git = class {
4166
4166
  constructor(okra, client) {
4167
4167
  this.okra = okra;
4168
4168
  this.client = client;
4169
+ this.targets = new GitTargetApi(okra.data.id, client);
4169
4170
  }
4170
4171
  checkpoint(author, message, branch = "main", allowEmpty = false) {
4171
4172
  return this.okra.invoke("git.checkpoint", { author, message, branch, allowEmpty });
@@ -4173,17 +4174,6 @@ var Git = class {
4173
4174
  checkout(branch, create = true) {
4174
4175
  return this.okra.invoke("git.checkout", { branch, create });
4175
4176
  }
4176
- async sync(input) {
4177
- const response = await this.client.post(
4178
- `/notebook/${this.okra.data.id}/git/sync-targets`,
4179
- this.omitUndefined({ ...input })
4180
- );
4181
- return response.data;
4182
- }
4183
- async syncTargets() {
4184
- const response = await this.client.get(`/notebook/${this.okra.data.id}/git/sync-targets`);
4185
- return response.data;
4186
- }
4187
4177
  log(ref = "main") {
4188
4178
  return this.okra.invoke("git.log", { ref });
4189
4179
  }
@@ -4252,10 +4242,56 @@ var Git = class {
4252
4242
  url2.hash = "";
4253
4243
  return url2.toString();
4254
4244
  }
4255
- omitUndefined(input) {
4256
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
4245
+ };
4246
+ var GitTargetApi = class {
4247
+ constructor(notebookId, client) {
4248
+ this.notebookId = notebookId;
4249
+ this.client = client;
4250
+ }
4251
+ async create(input) {
4252
+ const response = await this.client.post(
4253
+ `/notebook/${this.notebookId}/git/targets`,
4254
+ omitUndefined({ ...input })
4255
+ );
4256
+ return new GitTarget(response.data, this.notebookId, this.client);
4257
+ }
4258
+ async list() {
4259
+ const response = await this.client.get(`/notebook/${this.notebookId}/git/targets`);
4260
+ return response.data.map((target) => new GitTarget(target, this.notebookId, this.client));
4261
+ }
4262
+ async get(target) {
4263
+ const response = await this.client.get(
4264
+ `/notebook/${this.notebookId}/git/targets/${encodeURIComponent(gitTargetId(target))}`
4265
+ );
4266
+ return new GitTarget(response.data, this.notebookId, this.client);
4267
+ }
4268
+ async sync(target, input = {}) {
4269
+ const response = await this.client.post(
4270
+ `/notebook/${this.notebookId}/git/targets/${encodeURIComponent(gitTargetId(target))}/sync`,
4271
+ omitUndefined({ ...input })
4272
+ );
4273
+ return new GitTarget(response.data, this.notebookId, this.client);
4274
+ }
4275
+ };
4276
+ var GitTarget = class {
4277
+ constructor(data, notebookId, client) {
4278
+ this.data = data;
4279
+ this.notebookId = notebookId;
4280
+ this.client = client;
4281
+ }
4282
+ get id() {
4283
+ return this.data.id;
4284
+ }
4285
+ sync(input = {}) {
4286
+ return new GitTargetApi(this.notebookId, this.client).sync(this, input);
4257
4287
  }
4258
4288
  };
4289
+ function gitTargetId(target) {
4290
+ return typeof target === "string" ? target : target.id;
4291
+ }
4292
+ function omitUndefined(input) {
4293
+ return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
4294
+ }
4259
4295
 
4260
4296
  // node_modules/zod/v4/classic/external.js
4261
4297
  var external_exports = {};
@@ -18824,11 +18860,15 @@ var PublicationDomainDnsRecordTypeSchema = external_exports.enum(["CNAME", "ALIA
18824
18860
  var PublicationProtectionModeSchema = external_exports.enum(["none", "password"]);
18825
18861
  var PublicationLogStreamSchema = external_exports.enum(["build", "runtime"]);
18826
18862
  var PublishStreamLogStreamSchema = external_exports.enum(["build", "publish", "runtime"]);
18863
+ var PublicationEventPayloadSchema = external_exports.preprocess(
18864
+ (payload) => Array.isArray(payload) && payload.length === 0 ? {} : payload,
18865
+ external_exports.record(external_exports.string(), external_exports.unknown())
18866
+ );
18827
18867
  var PublicationEventDataSchema = external_exports.object({
18828
18868
  id: external_exports.union([external_exports.number(), external_exports.string()]).optional(),
18829
18869
  sequence: external_exports.number(),
18830
18870
  type: external_exports.string(),
18831
- payload: external_exports.record(external_exports.string(), external_exports.unknown()),
18871
+ payload: PublicationEventPayloadSchema,
18832
18872
  createdAt: external_exports.string().nullable()
18833
18873
  }).passthrough();
18834
18874
  var PublicationLogChunkDataSchema = external_exports.object({
@@ -18849,6 +18889,7 @@ var PublishStreamLogSchema = external_exports.object({
18849
18889
  var PublishStreamResultSchema = external_exports.object({
18850
18890
  success: external_exports.boolean(),
18851
18891
  publicationId: external_exports.string(),
18892
+ url: external_exports.string().url(),
18852
18893
  buildId: external_exports.string(),
18853
18894
  releaseId: external_exports.string(),
18854
18895
  status: PublicationStatusSchema
@@ -18960,10 +19001,6 @@ var PublicationApi = class {
18960
19001
  const response = await this.client.delete(`/publications/${id}/protection`);
18961
19002
  return new PublicationInstance(response.data, this.client);
18962
19003
  }
18963
- async setFeedback(id, input) {
18964
- const response = await this.client.put(`/publications/${id}/feedback`, input);
18965
- return new PublicationInstance(response.data, this.client);
18966
- }
18967
19004
  async listDomains(id) {
18968
19005
  const response = await this.client.get(
18969
19006
  `/publications/${id}/domains`
@@ -19073,7 +19110,7 @@ var PublicationRun = class {
19073
19110
  if (event.type === "result") {
19074
19111
  const { type: _, ...result } = event;
19075
19112
  this.finalResult = result;
19076
- this.resolveResult?.(result);
19113
+ this.resolveResult?.(this.finalResult);
19077
19114
  }
19078
19115
  }
19079
19116
  if (!this.finalResult) {
@@ -19164,9 +19201,6 @@ var PublicationInstance = class _PublicationInstance {
19164
19201
  disableProtection() {
19165
19202
  return this.client.publications.disableProtection(this.data.id);
19166
19203
  }
19167
- setFeedback(input) {
19168
- return this.client.publications.setFeedback(this.data.id, input);
19169
- }
19170
19204
  domains() {
19171
19205
  return this.client.publications.listDomains(this.data.id);
19172
19206
  }
@@ -19419,18 +19453,13 @@ var restActionRoutes = {
19419
19453
  "container.stats": { method: "GET", path: "/runtime/container/stats" },
19420
19454
  "terminal.list": { method: "GET", path: "/runtime/terminals" },
19421
19455
  "shell.exec": { method: "POST", path: "/runtime/executions" },
19422
- "fs.info": { method: "POST", path: "/runtime/files/info" },
19423
19456
  "fs.readFile": { method: "GET", path: "/runtime/files/content" },
19424
19457
  "fs.writeFile": { method: "PUT", path: "/runtime/files/content" },
19425
- "fs.write": { method: "PUT", path: "/runtime/files/text" },
19426
- "fs.mkdir": { method: "POST", path: "/runtime/directories" },
19427
19458
  "fs.createDirectory": { method: "PUT", path: "/runtime/directories" },
19428
19459
  "fs.readDirectory": { method: "POST", path: "/runtime/directories/read" },
19429
19460
  "fs.stat": { method: "POST", path: "/runtime/files/stat" },
19430
- "fs.move": { method: "POST", path: "/runtime/files/move" },
19431
19461
  "fs.rename": { method: "POST", path: "/runtime/files/rename" },
19432
19462
  "fs.copy": { method: "POST", path: "/runtime/files/copy" },
19433
- "fs.remove": { method: "POST", path: "/runtime/files/remove" },
19434
19463
  "fs.delete": { method: "DELETE", path: "/runtime/files" },
19435
19464
  "fs.tail": { method: "POST", path: "/runtime/files/tail" },
19436
19465
  "fs.find": { method: "POST", path: "/runtime/files/find" },
@@ -19625,6 +19654,164 @@ function runtimeAbort(options) {
19625
19654
  };
19626
19655
  }
19627
19656
 
19657
+ // src/feedback.ts
19658
+ var Feedback = class {
19659
+ constructor(client, notebookId) {
19660
+ this.client = client;
19661
+ this.notebookId = notebookId;
19662
+ }
19663
+ async configure(input) {
19664
+ const response = await this.client.put(this.path("/configuration"), input);
19665
+ return response.data;
19666
+ }
19667
+ async configuration() {
19668
+ const response = await this.client.get(this.path("/configuration"));
19669
+ return response.data;
19670
+ }
19671
+ async submit(input) {
19672
+ const response = await this.client.post(this.path(), input);
19673
+ return response.data;
19674
+ }
19675
+ async list(options = {}) {
19676
+ const query = new URLSearchParams();
19677
+ for (const [name, value] of Object.entries(options)) {
19678
+ if (value !== void 0) query.set(name, String(value));
19679
+ }
19680
+ const response = await this.client.get(
19681
+ `${this.path()}${query.size === 0 ? "" : `?${query.toString()}`}`
19682
+ );
19683
+ return response.data;
19684
+ }
19685
+ async get(id) {
19686
+ const response = await this.client.get(this.path(`/${encodeURIComponent(id)}`));
19687
+ return response.data;
19688
+ }
19689
+ async update(id, input) {
19690
+ const response = await this.client.patch(this.path(`/${encodeURIComponent(id)}`), input);
19691
+ return response.data;
19692
+ }
19693
+ path(suffix = "") {
19694
+ return `/notebook/${this.notebookId}/feedback${suffix}`;
19695
+ }
19696
+ };
19697
+
19698
+ // src/integrations.ts
19699
+ var IntegrationApi = class {
19700
+ constructor(client) {
19701
+ this.client = client;
19702
+ }
19703
+ async link(input) {
19704
+ const response = await this.client.post("/integrations", input);
19705
+ return new Integration(response.data, this.client);
19706
+ }
19707
+ async list() {
19708
+ const response = await this.client.get("/integrations");
19709
+ return response.data.map((integration) => new Integration(integration, this.client));
19710
+ }
19711
+ async get(integration) {
19712
+ const response = await this.client.get(`/integrations/${encodeURIComponent(integrationId(integration))}`);
19713
+ return new Integration(response.data, this.client);
19714
+ }
19715
+ async update(integration, input) {
19716
+ const response = await this.client.patch(
19717
+ `/integrations/${encodeURIComponent(integrationId(integration))}`,
19718
+ input
19719
+ );
19720
+ return new Integration(response.data, this.client);
19721
+ }
19722
+ async unlink(integration) {
19723
+ await this.client.delete(`/integrations/${encodeURIComponent(integrationId(integration))}`);
19724
+ }
19725
+ };
19726
+ var Integration = class {
19727
+ constructor(data, client) {
19728
+ this.data = data;
19729
+ this.client = client;
19730
+ }
19731
+ get id() {
19732
+ return this.data.id;
19733
+ }
19734
+ get provider() {
19735
+ return this.data.provider;
19736
+ }
19737
+ get label() {
19738
+ return this.data.label;
19739
+ }
19740
+ update(input) {
19741
+ return new IntegrationApi(this.client).update(this, input);
19742
+ }
19743
+ unlink() {
19744
+ return new IntegrationApi(this.client).unlink(this);
19745
+ }
19746
+ };
19747
+ function integrationId(integration) {
19748
+ return typeof integration === "string" ? integration : integration.id;
19749
+ }
19750
+
19751
+ // src/sandbox-integrations.ts
19752
+ var SandboxIntegrationApi = class {
19753
+ constructor(notebookId, client) {
19754
+ this.notebookId = notebookId;
19755
+ this.client = client;
19756
+ }
19757
+ async attach(input) {
19758
+ const response = await this.client.post(this.path(), {
19759
+ ...input,
19760
+ integration: integrationId(input.integration)
19761
+ });
19762
+ return new SandboxIntegration(response.data, this.notebookId, this.client);
19763
+ }
19764
+ async list() {
19765
+ const response = await this.client.get(this.path());
19766
+ return response.data.map((integration) => new SandboxIntegration(integration, this.notebookId, this.client));
19767
+ }
19768
+ async get(integration) {
19769
+ const response = await this.client.get(this.bindingPath(integration));
19770
+ return new SandboxIntegration(response.data, this.notebookId, this.client);
19771
+ }
19772
+ async update(integration, input) {
19773
+ const response = await this.client.patch(this.bindingPath(integration), {
19774
+ ...input,
19775
+ integration: input.integration === void 0 ? void 0 : integrationId(input.integration)
19776
+ });
19777
+ return new SandboxIntegration(response.data, this.notebookId, this.client);
19778
+ }
19779
+ async detach(integration) {
19780
+ await this.client.delete(this.bindingPath(integration));
19781
+ }
19782
+ path() {
19783
+ return `/notebook/${this.notebookId}/integrations`;
19784
+ }
19785
+ bindingPath(integration) {
19786
+ return `${this.path()}/${encodeURIComponent(sandboxIntegrationId(integration))}`;
19787
+ }
19788
+ };
19789
+ var SandboxIntegration = class {
19790
+ constructor(data, notebookId, client) {
19791
+ this.data = data;
19792
+ this.notebookId = notebookId;
19793
+ this.client = client;
19794
+ }
19795
+ get id() {
19796
+ return this.data.id;
19797
+ }
19798
+ get integration() {
19799
+ return new Integration(this.data.integration, this.client);
19800
+ }
19801
+ get effects() {
19802
+ return this.data.effects;
19803
+ }
19804
+ update(input) {
19805
+ return new SandboxIntegrationApi(this.notebookId, this.client).update(this, input);
19806
+ }
19807
+ detach() {
19808
+ return new SandboxIntegrationApi(this.notebookId, this.client).detach(this);
19809
+ }
19810
+ };
19811
+ function sandboxIntegrationId(integration) {
19812
+ return typeof integration === "string" ? integration : integration.id;
19813
+ }
19814
+
19628
19815
  // src/index.ts
19629
19816
  function normalizeNotebookSecretInputs(input) {
19630
19817
  if (Array.isArray(input)) {
@@ -19733,6 +19920,7 @@ var Client = class {
19733
19920
  this.publications = new PublicationApi(this);
19734
19921
  this.notebook = new NotebookApi(this);
19735
19922
  this.servers = new ServerApi(this);
19923
+ this.integrations = new IntegrationApi(this);
19736
19924
  this.options = Object.assign({ startClosed: true }, options);
19737
19925
  this.baseUrl = normalizeApiBaseUrl(url2);
19738
19926
  if (options.fetch) {
@@ -19759,6 +19947,9 @@ var Client = class {
19759
19947
  put(path, body) {
19760
19948
  return this.makeRequest("PUT", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
19761
19949
  }
19950
+ patch(path, body) {
19951
+ return this.makeRequest("PATCH", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
19952
+ }
19762
19953
  async stream(path) {
19763
19954
  const response = await this.fetch(
19764
19955
  new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
@@ -19972,8 +20163,10 @@ var NotebookInstance = class {
19972
20163
  this.services = new Services(this);
19973
20164
  this.config = new Config(this);
19974
20165
  this.secrets = new NotebookSecrets(client, this.data.id);
20166
+ this.integrations = new SandboxIntegrationApi(this.data.id, client);
19975
20167
  this.preview = new NotebookPreview(client, this.data.id);
19976
20168
  this.mail = new NotebookMail(client, this.data.id);
20169
+ this.feedback = new Feedback(client, this.data.id);
19977
20170
  }
19978
20171
  get runtimeTransport() {
19979
20172
  return this.client.runtimeTransport;
@@ -20286,12 +20479,17 @@ export {
20286
20479
  CommandError,
20287
20480
  ComposerCredentials,
20288
20481
  ErrorEvent,
20482
+ Feedback,
20289
20483
  FileChangeFilter,
20290
20484
  FileChangeType,
20291
20485
  FileType,
20292
20486
  Filesystem,
20293
20487
  FilesystemError,
20294
20488
  FilesystemErrorType,
20489
+ GitTarget,
20490
+ GitTargetApi,
20491
+ Integration,
20492
+ IntegrationApi,
20295
20493
  LspConnection,
20296
20494
  NotebookApi,
20297
20495
  NotebookComposerCredentialApi,
@@ -20344,14 +20542,18 @@ export {
20344
20542
  PublishStreamSseResultEventSchema,
20345
20543
  RateLimitError,
20346
20544
  RuntimeTelemetry,
20545
+ SandboxIntegration,
20546
+ SandboxIntegrationApi,
20347
20547
  SendTimeoutError,
20348
20548
  ServerApi,
20349
20549
  ServerInstance,
20350
20550
  ShellProcess,
20351
20551
  UnsupportedRuntimeTransportError,
20552
+ integrationId,
20352
20553
  notebookBuiltinServices,
20353
20554
  notebookKnownServices,
20354
20555
  once,
20556
+ sandboxIntegrationId,
20355
20557
  timeout,
20356
20558
  watchRuntimeTelemetry
20357
20559
  };