@phpsandbox/sdk 0.1.6 → 0.1.10

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/README.md +42 -50
  2. package/dist/beacon/index.d.ts +1 -7
  3. package/dist/beacon/index.js +14 -13
  4. package/dist/beacon/navigator.d.ts +8 -36
  5. package/dist/beacon/navigator.js +1 -62
  6. package/dist/browser/phpsandbox-sdk.esm.js +547 -691
  7. package/dist/browser/phpsandbox-sdk.esm.min.js +23 -23
  8. package/dist/browser/phpsandbox-sdk.iife.js +547 -691
  9. package/dist/browser/phpsandbox-sdk.iife.min.js +35 -35
  10. package/dist/composer.d.ts +10 -8
  11. package/dist/composer.js +18 -18
  12. package/dist/errors/index.d.ts +43 -8
  13. package/dist/errors/index.js +120 -14
  14. package/dist/feedback.js +1 -2
  15. package/dist/filesystem.d.ts +0 -17
  16. package/dist/filesystem.js +2 -21
  17. package/dist/git.d.ts +1 -5
  18. package/dist/git.js +6 -8
  19. package/dist/index.d.ts +66 -156
  20. package/dist/index.js +172 -289
  21. package/dist/integrations.d.ts +0 -2
  22. package/dist/integrations.js +5 -11
  23. package/dist/log.d.ts +0 -2
  24. package/dist/lsp.js +1 -1
  25. package/dist/metrics.d.ts +3 -3
  26. package/dist/ports.d.ts +1 -1
  27. package/dist/publications.d.ts +4 -54
  28. package/dist/publications.js +25 -103
  29. package/dist/runtime/rest.js +34 -17
  30. package/dist/runtime.d.ts +68 -0
  31. package/dist/runtime.js +46 -0
  32. package/dist/sandbox-integrations.d.ts +1 -2
  33. package/dist/sandbox-integrations.js +11 -14
  34. package/dist/schemas/publications.d.ts +0 -6
  35. package/dist/schemas/publications.js +0 -1
  36. package/dist/servers.d.ts +4 -2
  37. package/dist/servers.js +5 -8
  38. package/dist/shell.d.ts +2 -14
  39. package/dist/shell.js +1 -21
  40. package/dist/socket/index.d.ts +6 -7
  41. package/dist/socket/index.js +39 -25
  42. package/dist/types.d.ts +0 -12
  43. package/dist/types.js +1 -15
  44. package/docs/api-summary.md +28 -28
  45. package/docs/cdn-usage.md +43 -55
  46. package/docs/getting-started.md +43 -26
  47. package/examples/README.md +5 -35
  48. package/examples/basic.ts +9 -18
  49. package/examples/get.ts +2 -2
  50. package/examples/git-merge-smoke.ts +2 -3
  51. package/examples/laravel-load-test.ts +31 -36
  52. package/examples/notebook-readonly-smoke.ts +12 -26
  53. package/examples/publication-provider-label.ts +1 -1
  54. package/examples/publish-cloudflare-container.ts +2 -2
  55. package/examples/publish-laravel-cloud.ts +2 -2
  56. package/examples/publish-ssh-agent.ts +2 -2
  57. package/package.json +4 -3
  58. package/dist/container.d.ts +0 -65
  59. package/dist/container.js +0 -30
@@ -28,131 +28,147 @@ var PHPSandbox = (() => {
28
28
  // src/index.ts
29
29
  var index_exports = {};
30
30
  __export(index_exports, {
31
- ApiError: () => ApiError,
32
- Client: () => Client,
33
- CommandError: () => CommandError,
34
- ComposerCredentials: () => ComposerCredentials,
35
- ErrorEvent: () => ErrorEvent,
36
- Feedback: () => Feedback,
37
31
  FileChangeFilter: () => FileChangeFilter,
38
32
  FileChangeType: () => FileChangeType,
39
33
  FileType: () => FileType,
40
- Filesystem: () => Filesystem,
41
- FilesystemError: () => FilesystemError,
42
- FilesystemErrorType: () => FilesystemErrorType,
43
- GitTarget: () => GitTarget,
44
- GitTargetApi: () => GitTargetApi,
45
- Integration: () => Integration,
46
- IntegrationApi: () => IntegrationApi,
47
34
  LspConnection: () => LspConnection,
48
- NotebookApi: () => NotebookApi,
49
- NotebookComposerCredentialApi: () => NotebookComposerCredentialApi,
50
- NotebookInitError: () => NotebookInitError,
51
35
  NotebookInstance: () => NotebookInstance,
52
- NotebookMail: () => NotebookMail,
53
- NotebookMailApi: () => NotebookMailApi,
54
- NotebookPreview: () => NotebookPreview,
55
- NotebookPreviewApi: () => NotebookPreviewApi,
56
- NotebookPublicationApi: () => NotebookPublicationApi,
57
- NotebookSecretApi: () => NotebookSecretApi,
58
- NotebookSecrets: () => NotebookSecrets,
59
- NotebookState: () => NotebookState,
60
- NotebookUnavailableError: () => NotebookUnavailableError,
61
36
  PHPSandbox: () => PHPSandbox,
62
37
  PHPSandboxError: () => PHPSandboxError,
63
- ProcessReadable: () => ProcessReadable,
64
- ProcessResult: () => ProcessResult,
65
- PromiseTimeoutError: () => PromiseTimeoutError,
66
- PublicationApi: () => PublicationApi,
67
- PublicationBuildStatusSchema: () => PublicationBuildStatusSchema,
68
- PublicationDomainDnsRecordTypeSchema: () => PublicationDomainDnsRecordTypeSchema,
69
- PublicationEventDataSchema: () => PublicationEventDataSchema,
70
- PublicationInstance: () => PublicationInstance,
71
- PublicationJurisdictionSchema: () => PublicationJurisdictionSchema,
72
- PublicationLogChunkDataSchema: () => PublicationLogChunkDataSchema,
73
- PublicationLogStreamSchema: () => PublicationLogStreamSchema,
74
- PublicationProtectionModeSchema: () => PublicationProtectionModeSchema,
75
- PublicationProviderNameSchema: () => PublicationProviderNameSchema,
76
- PublicationRegionSchema: () => PublicationRegionSchema,
77
- PublicationReleaseStatusSchema: () => PublicationReleaseStatusSchema,
78
- PublicationRun: () => PublicationRun,
79
- PublicationSizeSchema: () => PublicationSizeSchema,
80
- PublicationStatusSchema: () => PublicationStatusSchema,
81
- PublishStreamErrorSchema: () => PublishStreamErrorSchema,
82
- PublishStreamEventSchema: () => PublishStreamEventSchema,
83
- PublishStreamLogEventSchema: () => PublishStreamLogEventSchema,
84
- PublishStreamLogSchema: () => PublishStreamLogSchema,
85
- PublishStreamLogStreamSchema: () => PublishStreamLogStreamSchema,
86
- PublishStreamPhaseEventSchema: () => PublishStreamPhaseEventSchema,
87
- PublishStreamPhaseSchema: () => PublishStreamPhaseSchema,
88
- PublishStreamResultEventSchema: () => PublishStreamResultEventSchema,
89
- PublishStreamResultSchema: () => PublishStreamResultSchema,
90
- PublishStreamSseDoneEventSchema: () => PublishStreamSseDoneEventSchema,
91
- PublishStreamSseErrorEventSchema: () => PublishStreamSseErrorEventSchema,
92
- PublishStreamSseEventNameSchema: () => PublishStreamSseEventNameSchema,
93
- PublishStreamSseEventSchema: () => PublishStreamSseEventSchema,
94
- PublishStreamSseLogEventSchema: () => PublishStreamSseLogEventSchema,
95
- PublishStreamSsePhaseEventSchema: () => PublishStreamSsePhaseEventSchema,
96
- PublishStreamSseResultEventSchema: () => PublishStreamSseResultEventSchema,
97
- RateLimitError: () => RateLimitError,
98
- RuntimeTelemetry: () => RuntimeTelemetry,
99
- SandboxIntegration: () => SandboxIntegration,
100
- SandboxIntegrationApi: () => SandboxIntegrationApi,
101
- SendTimeoutError: () => SendTimeoutError,
102
- ServerApi: () => ServerApi,
103
- ServerInstance: () => ServerInstance,
104
- ShellProcess: () => ShellProcess,
105
- UnsupportedRuntimeTransportError: () => UnsupportedRuntimeTransportError,
106
- integrationId: () => integrationId,
38
+ RemoteError: () => RemoteError,
39
+ TransportError: () => TransportError,
107
40
  notebookBuiltinServices: () => notebookBuiltinServices,
108
- notebookKnownServices: () => notebookKnownServices,
109
- once: () => once,
110
- sandboxIntegrationId: () => sandboxIntegrationId,
111
- timeout: () => timeout,
112
- watchRuntimeTelemetry: () => watchRuntimeTelemetry
41
+ notebookKnownServices: () => notebookKnownServices
113
42
  });
114
43
 
115
44
  // src/errors/index.ts
116
- var PromiseTimeoutError = class extends Error {
117
- constructor(message, time3) {
45
+ var remoteErrorCodes = [
46
+ "ActionNotFound",
47
+ "AuthenticationRequired",
48
+ "BadGateway",
49
+ "BadRequest",
50
+ "Conflict",
51
+ "FileAlreadyExists",
52
+ "FileIsDirectory",
53
+ "FileNotDirectory",
54
+ "FileNotFound",
55
+ "FilesystemUnavailable",
56
+ "InternalError",
57
+ "InvalidArgument",
58
+ "InvalidConfiguration",
59
+ "InvalidRequest",
60
+ "InvalidResponse",
61
+ "InvalidServiceCommand",
62
+ "MethodNotAllowed",
63
+ "NotebookInitializationFailed",
64
+ "NotebookUnavailable",
65
+ "NotFound",
66
+ "PayloadTooLarge",
67
+ "PermissionDenied",
68
+ "RateLimited",
69
+ "RequestFailed",
70
+ "RuntimeOperationFailed",
71
+ "ServiceNotFound",
72
+ "ServiceUnavailable",
73
+ "UnprocessableEntity",
74
+ "ValidationFailed",
75
+ "WorkspaceUnavailable"
76
+ ];
77
+ var PHPSandboxError = class extends Error {
78
+ constructor(message, cause) {
118
79
  super(message);
119
- this.time = time3;
80
+ this.name = new.target.name;
81
+ this.cause = cause;
120
82
  }
121
83
  };
122
- var SendTimeoutError = class _SendTimeoutError extends PromiseTimeoutError {
123
- static fromPromiseTimeoutError(error51) {
124
- return new _SendTimeoutError(error51.message, error51.time);
84
+ var RemoteError = class _RemoteError extends PHPSandboxError {
85
+ constructor(message, options) {
86
+ super(message, options.cause);
87
+ this.source = options.source;
88
+ this.status = options.status;
89
+ this.code = options.code;
90
+ this.details = options.details;
125
91
  }
126
- };
127
- var NotebookUnavailableError = class extends Error {
128
- constructor(message = "Notebook is no longer available", raw = {}) {
129
- super(message);
130
- this.raw = raw;
131
- this.name = "NotebookUnavailableError";
92
+ static is(error51, code) {
93
+ return error51 instanceof _RemoteError && (code === void 0 || error51.code === code);
132
94
  }
133
- };
134
- var UnsupportedRuntimeTransportError = class extends Error {
135
- constructor(message) {
136
- super(message);
137
- this.name = "UnsupportedRuntimeTransportError";
95
+ static isValidation(error51) {
96
+ return _RemoteError.is(error51, "ValidationFailed") && validationDetails(error51.details) !== void 0;
97
+ }
98
+ is(code) {
99
+ return this.code === code;
138
100
  }
139
101
  };
140
-
141
- // src/types.ts
142
- var ErrorEvent = class extends Error {
143
- constructor(code, message, raw = {}) {
144
- super(message);
102
+ var TransportError = class _TransportError extends PHPSandboxError {
103
+ constructor(message, code, cause) {
104
+ super(message, cause);
145
105
  this.code = code;
146
- this.message = message;
147
- this.raw = raw;
106
+ }
107
+ static is(error51, code) {
108
+ return error51 instanceof _TransportError && (code === void 0 || error51.code === code);
109
+ }
110
+ is(code) {
111
+ return this.code === code;
148
112
  }
149
113
  };
150
- var RateLimitError = class extends ErrorEvent {
151
- constructor(message, raw = {}) {
152
- super(429, message, raw);
114
+ function remoteError(source, payload, cause) {
115
+ const error51 = record(payload);
116
+ const status = positiveInteger(error51?.status);
117
+ const code = nonEmptyString(error51?.code);
118
+ const message = nonEmptyString(error51?.message);
119
+ if (status === void 0 || !isRemoteErrorCode(code) || message === void 0) {
120
+ throw new TransportError("PHPSandbox returned an invalid error response.", "InvalidResponse", cause ?? payload);
121
+ }
122
+ return new RemoteError(message, {
123
+ source,
124
+ status,
125
+ code,
126
+ details: error51?.details,
127
+ cause
128
+ });
129
+ }
130
+ function isRemoteErrorCode(value) {
131
+ return typeof value === "string" && remoteErrorCodes.includes(value);
132
+ }
133
+ function positiveInteger(value) {
134
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : void 0;
135
+ }
136
+ function nonEmptyString(value) {
137
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
138
+ }
139
+ function record(value) {
140
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
141
+ }
142
+ function stringArrayRecord(value) {
143
+ const candidate = record(value);
144
+ if (candidate === void 0) {
145
+ return void 0;
146
+ }
147
+ const entries = Object.entries(candidate);
148
+ if (!entries.every(([, messages]) => Array.isArray(messages) && messages.every((message) => typeof message === "string"))) {
149
+ return void 0;
150
+ }
151
+ return Object.fromEntries(entries);
152
+ }
153
+ function validationDetails(value) {
154
+ const details = record(value);
155
+ const errors = stringArrayRecord(details?.errors);
156
+ return errors === void 0 ? void 0 : { errors };
157
+ }
158
+ var PromiseTimeoutError = class extends Error {
159
+ constructor(message, time3) {
160
+ super(message);
161
+ this.time = time3;
153
162
  }
154
163
  };
155
- var PHPSandboxError = class extends ErrorEvent {
164
+ var SendTimeoutError = class _SendTimeoutError extends TransportError {
165
+ constructor(message, time3, cause) {
166
+ super(message, "SendTimeout", cause);
167
+ this.time = time3;
168
+ }
169
+ static fromPromiseTimeoutError(error51) {
170
+ return new _SendTimeoutError(error51.message, error51.time, error51);
171
+ }
156
172
  };
157
173
 
158
174
  // node_modules/nanoid/url-alphabet/index.js
@@ -188,21 +204,6 @@ var PHPSandbox = (() => {
188
204
  FileChangeType2[FileChangeType2["DELETED"] = 3] = "DELETED";
189
205
  return FileChangeType2;
190
206
  })(FileChangeType || {});
191
- var FilesystemErrorType = /* @__PURE__ */ ((FilesystemErrorType2) => {
192
- FilesystemErrorType2["Unavailable"] = "Unavailable";
193
- FilesystemErrorType2["NoPermissions"] = "NoPermissions";
194
- FilesystemErrorType2["FileExists"] = "FileExists";
195
- FilesystemErrorType2["FileNotFound"] = "FileNotFound";
196
- FilesystemErrorType2["FileIsADirectory"] = "FileIsADirectory";
197
- FilesystemErrorType2["FileNotADirectory"] = "FileNotADirectory";
198
- return FilesystemErrorType2;
199
- })(FilesystemErrorType || {});
200
- var FilesystemError = class extends ErrorEvent {
201
- constructor(inner, name) {
202
- super(inner.code, inner.message);
203
- this.name = name;
204
- }
205
- };
206
207
  var FilesystemSubscription = class {
207
208
  constructor(disposable, onDispose) {
208
209
  this.disposable = disposable;
@@ -356,7 +357,7 @@ var PHPSandbox = (() => {
356
357
  if (this.okra.runtimeTransport === "rest") {
357
358
  return new ReadableStream({
358
359
  start(controller) {
359
- controller.error(new UnsupportedRuntimeTransportError("Following files requires the realtime transport."));
360
+ controller.error(new PHPSandboxError("Following files requires the realtime transport."));
360
361
  }
361
362
  });
362
363
  }
@@ -576,9 +577,6 @@ var PHPSandbox = (() => {
576
577
  return this.okra.invoke("fs.tree", { path });
577
578
  }
578
579
  handleError(e) {
579
- if (e instanceof ErrorEvent && "name" in e.raw) {
580
- throw new FilesystemError(e, e.raw.name);
581
- }
582
580
  throw e;
583
581
  }
584
582
  };
@@ -783,38 +781,6 @@ var PHPSandbox = (() => {
783
781
  }
784
782
  };
785
783
 
786
- // src/container.ts
787
- var NotebookState = /* @__PURE__ */ ((NotebookState2) => {
788
- NotebookState2["RUNNING"] = "running";
789
- NotebookState2["STOPPED"] = "stopped";
790
- NotebookState2["STARTING"] = "starting";
791
- NotebookState2["STOPPING"] = "stopping";
792
- NotebookState2["KILLED"] = "killed";
793
- NotebookState2["ERROR"] = "error";
794
- NotebookState2["PROVISIONING"] = "provisioning";
795
- return NotebookState2;
796
- })(NotebookState || {});
797
- var Container = class {
798
- constructor(okra) {
799
- this.okra = okra;
800
- }
801
- start() {
802
- return this.okra.invoke("container.start");
803
- }
804
- restart() {
805
- return this.okra.invoke("container.restart");
806
- }
807
- stop() {
808
- return this.okra.invoke("container.stop");
809
- }
810
- state() {
811
- return this.okra.invoke("container.state");
812
- }
813
- setPhp(version2) {
814
- return this.okra.invoke("container.set-php", { version: version2 });
815
- }
816
- };
817
-
818
784
  // src/auth.ts
819
785
  var Auth = class {
820
786
  constructor(okra) {
@@ -862,7 +828,7 @@ var PHPSandbox = (() => {
862
828
  return LspConnection.create(id, this);
863
829
  }
864
830
  whenSocketConnected() {
865
- return this.okra.whenConnected();
831
+ return this.okra.connected();
866
832
  }
867
833
  };
868
834
  var LspConnection = class _LspConnection {
@@ -908,26 +874,6 @@ var PHPSandbox = (() => {
908
874
  opts: { tty: false, ...resolvedOpts }
909
875
  };
910
876
  }
911
- var CommandError = class extends Error {
912
- constructor(result) {
913
- super(result.output);
914
- this.result = result;
915
- }
916
- };
917
- var ProcessResult = class {
918
- constructor(output, stdout, stderr, exitCode) {
919
- this.output = output;
920
- this.stdout = stdout;
921
- this.stderr = stderr;
922
- this.exitCode = exitCode;
923
- }
924
- throw() {
925
- if (this.exitCode !== 0) {
926
- throw new CommandError(this);
927
- }
928
- return this;
929
- }
930
- };
931
877
  var ProcessReadable = class {
932
878
  constructor() {
933
879
  this.controller = null;
@@ -1015,7 +961,7 @@ var PHPSandbox = (() => {
1015
961
  { abortSignal }
1016
962
  ).then((result) => {
1017
963
  finish();
1018
- return new ProcessResult(result.output, result.stdout, result.stderr, result.exitCode);
964
+ return result;
1019
965
  }).catch((error51) => {
1020
966
  fail(error51);
1021
967
  throw error51;
@@ -1040,6 +986,24 @@ var PHPSandbox = (() => {
1040
986
  };
1041
987
 
1042
988
  // src/composer.ts
989
+ var ComposerCredentials = class {
990
+ constructor(client, notebookId) {
991
+ this.client = client;
992
+ this.notebookId = notebookId;
993
+ }
994
+ async set(input) {
995
+ const response = await this.client.put(
996
+ `/notebook/${this.notebookId}/composer/credentials`,
997
+ input
998
+ );
999
+ return response.data;
1000
+ }
1001
+ async remove(type, url2) {
1002
+ const params = new URLSearchParams({ type });
1003
+ if (url2) params.set("url", url2);
1004
+ await this.client.delete(`/notebook/${this.notebookId}/composer/credentials?${params.toString()}`);
1005
+ }
1006
+ };
1043
1007
  var ComposerProcess = class {
1044
1008
  constructor(id, okra, command, args, options) {
1045
1009
  this.id = id;
@@ -1077,7 +1041,7 @@ var PHPSandbox = (() => {
1077
1041
  };
1078
1042
  this.completion = this.okra.invoke("composer.invoke", { id, command, args, options }).then((result) => {
1079
1043
  finish();
1080
- return new ProcessResult(result.output, result.stdout, result.stderr, result.exitCode);
1044
+ return result;
1081
1045
  }).catch((error51) => {
1082
1046
  fail(error51);
1083
1047
  throw error51;
@@ -1098,21 +1062,6 @@ var PHPSandbox = (() => {
1098
1062
  run(command, args = {}, options = {}) {
1099
1063
  return new ComposerProcess(nanoid(), this.okra, command, args, options);
1100
1064
  }
1101
- dumpAutoload(options = {}) {
1102
- return this.run("dump-autoload", {}, options);
1103
- }
1104
- install(options = {}) {
1105
- return this.run("install", {}, options);
1106
- }
1107
- update(args, options = {}) {
1108
- return this.run("update", args, options);
1109
- }
1110
- require(packages, options = {}) {
1111
- return this.run("require", packages, options);
1112
- }
1113
- remove(args, options = {}) {
1114
- return this.run("remove", args, options);
1115
- }
1116
1065
  packages() {
1117
1066
  return this.okra.invoke("composer.packages");
1118
1067
  }
@@ -1272,6 +1221,50 @@ var PHPSandbox = (() => {
1272
1221
  }
1273
1222
  };
1274
1223
 
1224
+ // src/runtime.ts
1225
+ var RuntimeMetrics = class {
1226
+ constructor(metrics) {
1227
+ this.metrics = metrics;
1228
+ }
1229
+ current() {
1230
+ return this.metrics.current();
1231
+ }
1232
+ watch(options = {}) {
1233
+ return this.metrics.watch(options);
1234
+ }
1235
+ };
1236
+ var RuntimeLogs = class {
1237
+ constructor(logs) {
1238
+ this.logs = logs;
1239
+ }
1240
+ follow(options = {}) {
1241
+ return this.logs.follow(options);
1242
+ }
1243
+ };
1244
+ var RuntimePorts = class {
1245
+ constructor(ports) {
1246
+ this.ports = ports;
1247
+ }
1248
+ list() {
1249
+ return this.ports.list();
1250
+ }
1251
+ watch(options = {}) {
1252
+ return this.ports.watch(options);
1253
+ }
1254
+ };
1255
+ var Runtime = class {
1256
+ constructor(notebook) {
1257
+ this.notebook = notebook;
1258
+ const telemetry = new RuntimeTelemetry(notebook);
1259
+ this.metrics = new RuntimeMetrics(new Metrics(notebook, telemetry));
1260
+ this.logs = new RuntimeLogs(new Logs(notebook, telemetry));
1261
+ this.ports = new RuntimePorts(new Ports(notebook, telemetry));
1262
+ }
1263
+ setPhpVersion(version2) {
1264
+ return this.notebook.invoke("container.set-php", { version: version2 });
1265
+ }
1266
+ };
1267
+
1275
1268
  // src/repl.ts
1276
1269
  var Repl = class {
1277
1270
  constructor(okra) {
@@ -2159,24 +2152,24 @@ var PHPSandbox = (() => {
2159
2152
  }
2160
2153
  find(bytes, inputOffset, byteLength) {
2161
2154
  const records = this.caches[byteLength - 1];
2162
- FIND_CHUNK: for (const record2 of records) {
2163
- const recordBytes = record2.bytes;
2155
+ FIND_CHUNK: for (const record3 of records) {
2156
+ const recordBytes = record3.bytes;
2164
2157
  for (let j = 0; j < byteLength; j++) {
2165
2158
  if (recordBytes[j] !== bytes[inputOffset + j]) {
2166
2159
  continue FIND_CHUNK;
2167
2160
  }
2168
2161
  }
2169
- return record2.str;
2162
+ return record3.str;
2170
2163
  }
2171
2164
  return null;
2172
2165
  }
2173
2166
  store(bytes, value) {
2174
2167
  const records = this.caches[bytes.length - 1];
2175
- const record2 = { bytes, str: value };
2168
+ const record3 = { bytes, str: value };
2176
2169
  if (records.length >= this.maxLengthPerKey) {
2177
- records[Math.random() * records.length | 0] = record2;
2170
+ records[Math.random() * records.length | 0] = record3;
2178
2171
  } else {
2179
- records.push(record2);
2172
+ records.push(record3);
2180
2173
  }
2181
2174
  }
2182
2175
  decode(bytes, inputOffset, byteLength) {
@@ -2926,17 +2919,17 @@ var PHPSandbox = (() => {
2926
2919
  return Event2;
2927
2920
  })()
2928
2921
  );
2929
- var ErrorEvent2 = (
2922
+ var ErrorEvent = (
2930
2923
  /** @class */
2931
2924
  (function(_super) {
2932
- __extends(ErrorEvent3, _super);
2933
- function ErrorEvent3(error51, target) {
2925
+ __extends(ErrorEvent2, _super);
2926
+ function ErrorEvent2(error51, target) {
2934
2927
  var _this = _super.call(this, "error", target) || this;
2935
2928
  _this.message = error51.message;
2936
2929
  _this.error = error51;
2937
2930
  return _this;
2938
2931
  }
2939
- return ErrorEvent3;
2932
+ return ErrorEvent2;
2940
2933
  })(Event)
2941
2934
  );
2942
2935
  var CloseEvent = (
@@ -3361,7 +3354,7 @@ var PHPSandbox = (() => {
3361
3354
  };
3362
3355
  ReconnectingWebSocket3.prototype._handleTimeout = function() {
3363
3356
  this._debug("timeout event");
3364
- this._handleError(new ErrorEvent2(Error("TIMEOUT"), this));
3357
+ this._handleError(new ErrorEvent(Error("TIMEOUT"), this));
3365
3358
  };
3366
3359
  ReconnectingWebSocket3.prototype._disconnect = function(code, reason) {
3367
3360
  if (code === void 0) {
@@ -3448,12 +3441,12 @@ var PHPSandbox = (() => {
3448
3441
  if (!value || typeof value !== "object") {
3449
3442
  return void 0;
3450
3443
  }
3451
- const record2 = value;
3452
- const message = typeof record2.message === "string" && record2.message ? record2.message : typeof record2.reason === "string" && record2.reason ? record2.reason : void 0;
3444
+ const record3 = value;
3445
+ const message = typeof record3.message === "string" && record3.message ? record3.message : typeof record3.reason === "string" && record3.reason ? record3.reason : void 0;
3453
3446
  if (!message) {
3454
3447
  return void 0;
3455
3448
  }
3456
- const name = typeof record2.name === "string" && record2.name ? record2.name : void 0;
3449
+ const name = typeof record3.name === "string" && record3.name ? record3.name : void 0;
3457
3450
  return name ? `${name}: ${message}` : message;
3458
3451
  };
3459
3452
  var describeWebSocketEvent = (event) => {
@@ -3466,29 +3459,29 @@ var PHPSandbox = (() => {
3466
3459
  if (!event || typeof event !== "object") {
3467
3460
  return String(event);
3468
3461
  }
3469
- const record2 = event;
3462
+ const record3 = event;
3470
3463
  const parts = [];
3471
- const topLevelMessage = extractNestedErrorMessage(record2);
3464
+ const topLevelMessage = extractNestedErrorMessage(record3);
3472
3465
  if (topLevelMessage) {
3473
3466
  parts.push(topLevelMessage);
3474
3467
  }
3475
- const nestedErrorMessage = extractNestedErrorMessage(record2.error);
3468
+ const nestedErrorMessage = extractNestedErrorMessage(record3.error);
3476
3469
  if (nestedErrorMessage && nestedErrorMessage !== topLevelMessage) {
3477
3470
  parts.push(`error=${nestedErrorMessage}`);
3478
3471
  }
3479
- if (typeof record2.type === "string" && record2.type) {
3480
- parts.push(`type=${record2.type}`);
3472
+ if (typeof record3.type === "string" && record3.type) {
3473
+ parts.push(`type=${record3.type}`);
3481
3474
  }
3482
- if (typeof record2.code === "number") {
3483
- parts.push(`code=${record2.code}`);
3475
+ if (typeof record3.code === "number") {
3476
+ parts.push(`code=${record3.code}`);
3484
3477
  }
3485
- if (typeof record2.reason === "string" && record2.reason && record2.reason !== topLevelMessage) {
3486
- parts.push(`reason=${record2.reason}`);
3478
+ if (typeof record3.reason === "string" && record3.reason && record3.reason !== topLevelMessage) {
3479
+ parts.push(`reason=${record3.reason}`);
3487
3480
  }
3488
- if (typeof record2.wasClean === "boolean") {
3489
- parts.push(`wasClean=${record2.wasClean}`);
3481
+ if (typeof record3.wasClean === "boolean") {
3482
+ parts.push(`wasClean=${record3.wasClean}`);
3490
3483
  }
3491
- const target = record2.target ?? record2.currentTarget;
3484
+ const target = record3.target ?? record3.currentTarget;
3492
3485
  if (target && typeof target === "object") {
3493
3486
  if (typeof target.url === "string" && target.url) {
3494
3487
  parts.push(`url=${sanitizeWebSocketUrl(target.url)}`);
@@ -3538,25 +3531,36 @@ var PHPSandbox = (() => {
3538
3531
  };
3539
3532
 
3540
3533
  // src/socket/index.ts
3534
+ var SAFE_DEBUG_METADATA_KEYS = /* @__PURE__ */ new Set([
3535
+ "url",
3536
+ "action",
3537
+ "event",
3538
+ "responseEvent",
3539
+ "errorEvent",
3540
+ "hasData",
3541
+ "code",
3542
+ "attempt",
3543
+ "maxRetries",
3544
+ "timeout",
3545
+ "errorCount",
3546
+ "byteLength"
3547
+ ]);
3541
3548
  var ReconnectingWebSocket2 = reconnecting_websocket_mjs_default ?? reconnecting_websocket_mjs_exports;
3542
- var ConnectionTimeoutError = class extends Error {
3549
+ var ConnectionTimeoutError = class extends TransportError {
3543
3550
  constructor(message = "WebSocket connection timeout") {
3544
- super(message);
3545
- this.name = "ConnectionTimeoutError";
3551
+ super(message, "ConnectionTimeout");
3546
3552
  }
3547
3553
  };
3548
- var ConnectionFailedError = class extends Error {
3554
+ var ConnectionFailedError = class extends TransportError {
3549
3555
  constructor(message, originalError) {
3550
- super(message);
3556
+ super(message, "ConnectionFailed", originalError);
3551
3557
  this.originalError = originalError;
3552
- this.name = "ConnectionFailedError";
3553
3558
  }
3554
3559
  };
3555
- var InvalidMessageError = class extends Error {
3560
+ var InvalidMessageError = class extends TransportError {
3556
3561
  constructor(message, data) {
3557
- super(message);
3562
+ super(message, "InvalidResponse", data);
3558
3563
  this.data = data;
3559
- this.name = "InvalidMessageError";
3560
3564
  }
3561
3565
  };
3562
3566
  var InvalidConfigurationError = class extends Error {
@@ -3583,7 +3587,6 @@ var PHPSandbox = (() => {
3583
3587
  const urlProvider = typeof url2 === "string" ? this.url.toString() : async () => new URL(await url2()).toString();
3584
3588
  this.PING_INTERVAL = options.pingInterval ?? 3e4;
3585
3589
  this.CONNECT_WAIT_TIMEOUT = options.connectWaitTimeout ?? 3e4;
3586
- const startClosed = options.startClosed !== false;
3587
3590
  this.rws = new ReconnectingWebSocket2(urlProvider, [], {
3588
3591
  WebSocket: options.webSocket ?? globalThis.WebSocket ?? browser_default,
3589
3592
  connectionTimeout: options.connectionTimeout,
@@ -3591,7 +3594,7 @@ var PHPSandbox = (() => {
3591
3594
  minReconnectionDelay: 200,
3592
3595
  maxEnqueuedMessages: 0,
3593
3596
  maxRetries: options.maxRetries ?? 50,
3594
- startClosed
3597
+ startClosed: true
3595
3598
  });
3596
3599
  this.log("debug", "Transport initialized", {
3597
3600
  url: this.url === null ? "dynamic" : transportLogUrl(this.url),
@@ -3622,8 +3625,10 @@ var PHPSandbox = (() => {
3622
3625
  log(level, message, data) {
3623
3626
  if (this.options.debug) {
3624
3627
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3625
- const logData = data ? JSON.stringify(data, null, 2) : "";
3626
- console[level](`[Transport ${timestamp}] ${message}${logData ? "\n" + logData : ""}`);
3628
+ const metadata = safeDebugMetadata(data);
3629
+ const logData = metadata ? `
3630
+ ${JSON.stringify(metadata, null, 2)}` : "";
3631
+ console[level](`[Transport ${timestamp}] ${message}${logData}`);
3627
3632
  }
3628
3633
  }
3629
3634
  /**
@@ -3746,10 +3751,12 @@ var PHPSandbox = (() => {
3746
3751
  }
3747
3752
  if (event === "Events.BootError" /* BootError */) {
3748
3753
  const errorData = data;
3749
- const error51 = new NotebookUnavailableError(
3750
- errorData?.message || "Notebook is no longer available",
3751
- errorData || {}
3752
- );
3754
+ const error51 = new RemoteError(errorData?.message || "Notebook is no longer available", {
3755
+ source: "runtime",
3756
+ status: 503,
3757
+ code: "NotebookUnavailable",
3758
+ details: errorData || {}
3759
+ });
3753
3760
  this.log("error", "Boot error received", { data });
3754
3761
  this.terminate(error51, 4e3, error51.message);
3755
3762
  return;
@@ -3892,12 +3899,16 @@ var PHPSandbox = (() => {
3892
3899
  });
3893
3900
  this.listenOnce(errorEvent, (e) => {
3894
3901
  this.log("error", "Message error received", { action, error: e });
3895
- const error51 = e;
3896
- reject(new ErrorEvent(error51.code, error51.message, error51));
3902
+ reject(remoteError("runtime", e));
3897
3903
  });
3898
3904
  closeHandler = (_ev) => {
3899
3905
  if (_ev.code === 1008 && (_ev.reason || "").includes("rate limit")) {
3900
- reject(new RateLimitError(_ev.reason || "Rate limit exceeded", _ev));
3906
+ reject(new RemoteError(_ev.reason || "Rate limit exceeded", {
3907
+ source: "runtime",
3908
+ status: 429,
3909
+ code: "RateLimited",
3910
+ cause: _ev
3911
+ }));
3901
3912
  return;
3902
3913
  }
3903
3914
  const detail = describeWebSocketEvent(_ev);
@@ -3910,7 +3921,7 @@ var PHPSandbox = (() => {
3910
3921
  this.log("debug", "Message sent", { action, data });
3911
3922
  } catch (error51) {
3912
3923
  this.log("error", "Failed to send message", { action, error: error51 });
3913
- reject(error51);
3924
+ reject(new ConnectionFailedError(`Failed to send runtime action ${action}.`, error51));
3914
3925
  }
3915
3926
  };
3916
3927
  const send = async () => {
@@ -3963,7 +3974,7 @@ var PHPSandbox = (() => {
3963
3974
  try {
3964
3975
  return await sender();
3965
3976
  } catch (e) {
3966
- if (e instanceof ErrorEvent || e instanceof RateLimitError || e instanceof InvalidConfigurationError || e instanceof InvalidMessageError || e instanceof NotebookUnavailableError || e instanceof DOMException) {
3977
+ if (e instanceof RemoteError || e instanceof InvalidConfigurationError || e instanceof InvalidMessageError || e instanceof DOMException) {
3967
3978
  this.log("debug", "Non-retryable error, bailing", {
3968
3979
  error: e.message,
3969
3980
  attempt
@@ -4032,7 +4043,7 @@ var PHPSandbox = (() => {
4032
4043
  }
4033
4044
  terminate(error51, code = 4e3, reason = error51.message) {
4034
4045
  this.terminalError = error51;
4035
- if (error51 instanceof NotebookUnavailableError) {
4046
+ if (RemoteError.is(error51, "NotebookUnavailable")) {
4036
4047
  this.eventEmitter.emit("transport.boot_error", {
4037
4048
  error: error51,
4038
4049
  timestamp: Date.now()
@@ -4180,6 +4191,15 @@ var PHPSandbox = (() => {
4180
4191
  };
4181
4192
  });
4182
4193
  };
4194
+ function safeDebugMetadata(data) {
4195
+ if (data === null || typeof data !== "object") {
4196
+ return null;
4197
+ }
4198
+ const metadata = Object.entries(data).filter(
4199
+ ([key, value]) => SAFE_DEBUG_METADATA_KEYS.has(key) && ["string", "number", "boolean"].includes(typeof value)
4200
+ );
4201
+ return metadata.length > 0 ? Object.fromEntries(metadata) : null;
4202
+ }
4183
4203
  function transportLogUrl(url2) {
4184
4204
  const safeUrl = new URL(url2);
4185
4205
  safeUrl.search = "";
@@ -4304,8 +4324,9 @@ var PHPSandbox = (() => {
4304
4324
  revert(input) {
4305
4325
  return this.okra.invoke("git.revert", input);
4306
4326
  }
4307
- credentials() {
4308
- return this.okra.gitCredentials();
4327
+ async credentials() {
4328
+ const response = await this.client.post(`/notebook/${this.okra.data.id}/git/credentials`);
4329
+ return response.data;
4309
4330
  }
4310
4331
  restore(ref) {
4311
4332
  return this.okra.invoke("git.restore", { ref });
@@ -4365,15 +4386,8 @@ var PHPSandbox = (() => {
4365
4386
  );
4366
4387
  return new GitTarget(response.data, this.notebookId, this.client);
4367
4388
  }
4368
- async sync(target, input = {}) {
4369
- const response = await this.client.post(
4370
- `/notebook/${this.notebookId}/git/targets/${encodeURIComponent(gitTargetId(target))}/sync`,
4371
- omitUndefined({ ...input })
4372
- );
4373
- return new GitTarget(response.data, this.notebookId, this.client);
4374
- }
4375
4389
  };
4376
- var GitTarget = class {
4390
+ var GitTarget = class _GitTarget {
4377
4391
  constructor(data, notebookId, client) {
4378
4392
  this.data = data;
4379
4393
  this.notebookId = notebookId;
@@ -4382,8 +4396,12 @@ var PHPSandbox = (() => {
4382
4396
  get id() {
4383
4397
  return this.data.id;
4384
4398
  }
4385
- sync(input = {}) {
4386
- return new GitTargetApi(this.notebookId, this.client).sync(this, input);
4399
+ async sync(input = {}) {
4400
+ const response = await this.client.post(
4401
+ `/notebook/${this.notebookId}/git/targets/${encodeURIComponent(this.id)}/sync`,
4402
+ omitUndefined({ ...input })
4403
+ );
4404
+ return new _GitTarget(response.data, this.notebookId, this.client);
4387
4405
  }
4388
4406
  };
4389
4407
  function gitTargetId(target) {
@@ -4587,7 +4605,7 @@ var PHPSandbox = (() => {
4587
4605
  promise: () => promise,
4588
4606
  property: () => _property,
4589
4607
  readonly: () => readonly,
4590
- record: () => record,
4608
+ record: () => record2,
4591
4609
  refine: () => refine,
4592
4610
  regex: () => _regex,
4593
4611
  regexes: () => regexes_exports,
@@ -16925,7 +16943,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16925
16943
  preprocess: () => preprocess,
16926
16944
  promise: () => promise,
16927
16945
  readonly: () => readonly,
16928
- record: () => record,
16946
+ record: () => record2,
16929
16947
  refine: () => refine,
16930
16948
  set: () => set,
16931
16949
  strictObject: () => strictObject,
@@ -17894,7 +17912,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17894
17912
  inst.keyType = def.keyType;
17895
17913
  inst.valueType = def.valueType;
17896
17914
  });
17897
- function record(keyType, valueType, params) {
17915
+ function record2(keyType, valueType, params) {
17898
17916
  if (!valueType || !valueType._zod) {
17899
17917
  return new ZodRecord({
17900
17918
  type: "record",
@@ -18361,7 +18379,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18361
18379
  }, ...args);
18362
18380
  function json(params) {
18363
18381
  const jsonSchema = lazy(() => {
18364
- return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record(string2(), jsonSchema)]);
18382
+ return union([string2(params), number2(), boolean2(), _null3(), array(jsonSchema), record2(string2(), jsonSchema)]);
18365
18383
  });
18366
18384
  return jsonSchema;
18367
18385
  }
@@ -18956,7 +18974,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18956
18974
  "AFR"
18957
18975
  ]);
18958
18976
  var PublicationJurisdictionSchema = external_exports.enum(["eu", "fedramp"]);
18959
- var PublicationDomainDnsRecordTypeSchema = external_exports.enum(["CNAME", "ALIAS", "ANAME"]);
18960
18977
  var PublicationProtectionModeSchema = external_exports.enum(["none", "password"]);
18961
18978
  var PublicationLogStreamSchema = external_exports.enum(["build", "runtime"]);
18962
18979
  var PublishStreamLogStreamSchema = external_exports.enum(["build", "publish", "runtime"]);
@@ -19047,33 +19064,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19047
19064
  });
19048
19065
 
19049
19066
  // src/publications.ts
19050
- var NotebookPublicationApi = class {
19051
- constructor(client) {
19052
- this.client = client;
19053
- }
19054
- async current(notebookId) {
19055
- try {
19056
- const response = await this.client.get(
19057
- `/notebook/${notebookId}/publication`
19058
- );
19059
- return new PublicationInstance(response.data, this.client, notebookId);
19060
- } catch (error51) {
19061
- if (error51 instanceof ApiError && error51.status === 404) {
19062
- return null;
19063
- }
19064
- throw error51;
19065
- }
19066
- }
19067
- async publish(notebookId, input) {
19068
- const response = await this.client.post(
19069
- `/notebook/${notebookId}/publication`,
19070
- input
19071
- );
19072
- const run = new PublicationRun(new PublicationInstance(response.data, this.client, notebookId), this.client);
19073
- run.start();
19074
- return run;
19075
- }
19076
- };
19077
19067
  var PublicationApi = class {
19078
19068
  constructor(client) {
19079
19069
  this.client = client;
@@ -19082,60 +19072,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19082
19072
  const response = await this.client.get(`/publications/${id}`);
19083
19073
  return new PublicationInstance(response.data, this.client);
19084
19074
  }
19085
- async destroy(id) {
19086
- await this.client.delete(`/publications/${id}`);
19087
- }
19088
- async setProtection(id, input) {
19089
- const response = await this.client.put(`/publications/${id}/protection`, input);
19090
- return new PublicationInstance(response.data, this.client);
19091
- }
19092
- async protection(id) {
19093
- const response = await this.client.get(`/publications/${id}/protection`);
19094
- return response.data;
19095
- }
19096
- async createProtectionSession(id) {
19097
- const response = await this.client.post(`/publications/${id}/protection/session`);
19098
- return response.data;
19099
- }
19100
- async disableProtection(id) {
19101
- const response = await this.client.delete(`/publications/${id}/protection`);
19102
- return new PublicationInstance(response.data, this.client);
19103
- }
19104
- async listDomains(id) {
19105
- const response = await this.client.get(
19106
- `/publications/${id}/domains`
19107
- );
19108
- return unwrapPublicationDomainCollection(response.data);
19109
- }
19110
- async createDomain(id, input) {
19111
- const response = await this.client.post(`/publications/${id}/domains`, input);
19112
- return response.data;
19113
- }
19114
- async refreshDomain(id, domainId) {
19115
- const response = await this.client.post(`/publications/${id}/domains/${domainId}/refresh`);
19116
- return response.data;
19117
- }
19118
- async deleteDomain(id, domainId) {
19119
- await this.client.delete(`/publications/${id}/domains/${domainId}`);
19120
- }
19121
- async events(id) {
19122
- return parseNdjsonStream(
19123
- await this.client.stream(`/publications/${id}/events/stream`),
19124
- PublicationEventDataSchema
19125
- );
19126
- }
19127
- async buildLogs(id, buildId) {
19128
- return parseNdjsonStream(
19129
- await this.client.stream(`/publications/${id}/builds/${buildId}/logs/stream`),
19130
- PublicationLogChunkDataSchema
19131
- );
19132
- }
19133
- async logs(id) {
19134
- return parseNdjsonStream(
19135
- await this.client.stream(`/publications/${id}/logs/stream`),
19136
- PublicationLogChunkDataSchema
19137
- );
19138
- }
19139
19075
  };
19140
19076
  var PublicationRun = class {
19141
19077
  constructor(initial, client) {
@@ -19254,14 +19190,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19254
19190
  const response = await this.client.get(`/publications/${this.data.id}`);
19255
19191
  return new _PublicationInstance(response.data, this.client, this.notebookId);
19256
19192
  }
19257
- publish() {
19193
+ async publish() {
19258
19194
  if (!this.notebookId) {
19259
19195
  return Promise.reject(new Error("Publishing requires a notebook-scoped publication instance."));
19260
19196
  }
19261
- return this.client.notebook.publication.publish(this.notebookId);
19197
+ const response = await this.client.post(
19198
+ `/notebook/${this.notebookId}/publication`
19199
+ );
19200
+ const run = new PublicationRun(
19201
+ new _PublicationInstance(response.data, this.client, this.notebookId),
19202
+ this.client
19203
+ );
19204
+ run.start();
19205
+ return run;
19262
19206
  }
19263
- destroy() {
19264
- return this.client.publications.destroy(this.data.id);
19207
+ async destroy() {
19208
+ await this.client.delete(`/publications/${this.data.id}`);
19265
19209
  }
19266
19210
  async wait(options = {}) {
19267
19211
  const intervalMs = options.intervalMs ?? 1e3;
@@ -19277,41 +19221,44 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19277
19221
  }
19278
19222
  return current;
19279
19223
  }
19280
- events() {
19281
- return this.client.publications.events(this.data.id);
19224
+ async events() {
19225
+ return parseNdjsonStream(
19226
+ await this.client.stream(`/publications/${this.data.id}/events/stream`),
19227
+ PublicationEventDataSchema
19228
+ );
19282
19229
  }
19283
19230
  buildLogs(buildId = this.data.latestBuild?.id ?? "") {
19284
19231
  if (buildId === "") {
19285
19232
  return Promise.reject(new Error("Publication has no latest build id"));
19286
19233
  }
19287
- return this.client.publications.buildLogs(this.data.id, buildId);
19288
- }
19289
- logs() {
19290
- return this.client.publications.logs(this.data.id);
19234
+ return this.client.stream(`/publications/${this.data.id}/builds/${buildId}/logs/stream`).then((stream) => parseNdjsonStream(stream, PublicationLogChunkDataSchema));
19291
19235
  }
19292
- setProtection(input) {
19293
- return this.client.publications.setProtection(this.data.id, input);
19294
- }
19295
- protection() {
19296
- return this.client.publications.protection(this.data.id);
19297
- }
19298
- createProtectionSession() {
19299
- return this.client.publications.createProtectionSession(this.data.id);
19300
- }
19301
- disableProtection() {
19302
- return this.client.publications.disableProtection(this.data.id);
19236
+ async logs() {
19237
+ return parseNdjsonStream(
19238
+ await this.client.stream(`/publications/${this.data.id}/logs/stream`),
19239
+ PublicationLogChunkDataSchema
19240
+ );
19303
19241
  }
19304
- domains() {
19305
- return this.client.publications.listDomains(this.data.id);
19242
+ async setProtection(input) {
19243
+ const response = await this.client.put(
19244
+ `/publications/${this.data.id}/protection`,
19245
+ input
19246
+ );
19247
+ return new _PublicationInstance(response.data, this.client, this.notebookId);
19306
19248
  }
19307
- addDomain(input) {
19308
- return this.client.publications.createDomain(this.data.id, input);
19249
+ async protection() {
19250
+ const response = await this.client.get(`/publications/${this.data.id}/protection`);
19251
+ return response.data;
19309
19252
  }
19310
- refreshDomain(domainId) {
19311
- return this.client.publications.refreshDomain(this.data.id, domainId);
19253
+ async createProtectionSession() {
19254
+ const response = await this.client.post(
19255
+ `/publications/${this.data.id}/protection/session`
19256
+ );
19257
+ return response.data;
19312
19258
  }
19313
- deleteDomain(domainId) {
19314
- return this.client.publications.deleteDomain(this.data.id, domainId);
19259
+ async disableProtection() {
19260
+ const response = await this.client.delete(`/publications/${this.data.id}/protection`);
19261
+ return new _PublicationInstance(response.data, this.client, this.notebookId);
19315
19262
  }
19316
19263
  };
19317
19264
  function publicationStatusIsTerminal(status) {
@@ -19320,12 +19267,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19320
19267
  function delay(ms) {
19321
19268
  return new Promise((resolve) => setTimeout(resolve, ms));
19322
19269
  }
19323
- function unwrapPublicationDomainCollection(input) {
19324
- if (Array.isArray(input)) {
19325
- return input;
19326
- }
19327
- return Array.isArray(input.data) ? input.data : [];
19328
- }
19329
19270
  var AsyncPublishEventQueue = class {
19330
19271
  constructor() {
19331
19272
  this.values = [];
@@ -19492,9 +19433,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19492
19433
  constructor(client) {
19493
19434
  this.client = client;
19494
19435
  }
19495
- async list() {
19496
- const response = await this.client.get("/servers");
19497
- return response.data;
19436
+ async list(options = {}) {
19437
+ const query = options.page === void 0 ? "" : `?${new URLSearchParams({ page: String(options.page) }).toString()}`;
19438
+ return this.client.get(`/servers${query}`);
19498
19439
  }
19499
19440
  async create(input) {
19500
19441
  const response = await this.client.post("/servers", input);
@@ -19504,9 +19445,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19504
19445
  const response = await this.client.get(`/servers/${id}`);
19505
19446
  return new ServerInstance(response.data, this.client);
19506
19447
  }
19507
- async delete(id) {
19508
- await this.client.delete(`/servers/${id}`);
19509
- }
19510
19448
  };
19511
19449
  var ServerInstance = class {
19512
19450
  constructor(data, client) {
@@ -19516,8 +19454,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19516
19454
  refresh() {
19517
19455
  return this.client.servers.get(this.data.id);
19518
19456
  }
19519
- delete() {
19520
- return this.client.servers.delete(this.data.id);
19457
+ async delete() {
19458
+ await this.client.delete(`/servers/${this.data.id}`);
19521
19459
  }
19522
19460
  async waitReady(options) {
19523
19461
  const timeout2 = options?.timeout ?? 3e5;
@@ -19540,12 +19478,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19540
19478
  // src/runtime/rest.ts
19541
19479
  var restActionRoutes = {
19542
19480
  "runtime.ready": { method: "GET", path: "/runtime" },
19543
- ping: { method: "GET", path: "/runtime/ping" },
19544
19481
  "config.get": { method: "GET", path: "/runtime/config" },
19545
19482
  "config.update": { method: "PATCH", path: "/runtime/config" },
19546
19483
  "config.set-ports": { method: "PUT", path: "/runtime/config/ports" },
19547
- "container.state": { method: "GET", path: "/runtime/container" },
19548
- "container.start": { method: "POST", path: "/runtime/container/start" },
19549
19484
  "container.restart": { method: "POST", path: "/runtime/container/restart" },
19550
19485
  "container.stop": { method: "POST", path: "/runtime/container/stop" },
19551
19486
  "container.set-php": { method: "PUT", path: "/runtime/container/php" },
@@ -19598,10 +19533,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19598
19533
  const actionUrl = new URL(runtimeUrl);
19599
19534
  const ticket = actionUrl.searchParams.get("ticket") ?? "";
19600
19535
  if (ticket === "") {
19601
- throw new UnsupportedRuntimeTransportError("The notebook connection does not contain a runtime ticket.");
19536
+ throw new PHPSandboxError("The notebook connection does not contain a runtime ticket.");
19602
19537
  }
19603
19538
  this.ticket = ticket;
19604
- actionUrl.protocol = actionUrl.protocol === "wss:" ? "https:" : "http:";
19539
+ if (actionUrl.protocol === "wss:") {
19540
+ actionUrl.protocol = "https:";
19541
+ } else if (actionUrl.protocol === "ws:") {
19542
+ actionUrl.protocol = "http:";
19543
+ }
19605
19544
  actionUrl.pathname = `/api/v1/notebooks/${encodeURIComponent(this.notebookId)}`;
19606
19545
  actionUrl.searchParams.delete("ticket");
19607
19546
  actionUrl.hash = "";
@@ -19617,27 +19556,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19617
19556
  return this.invokeRaw(action, data ?? {}, options);
19618
19557
  }
19619
19558
  send() {
19620
- throw new UnsupportedRuntimeTransportError("Fire-and-forget actions require the realtime transport.");
19559
+ throw new PHPSandboxError("Fire-and-forget actions require the realtime transport.");
19621
19560
  }
19622
19561
  async invokeRaw(action, data, options) {
19623
19562
  const abort = runtimeAbort(options);
19624
19563
  try {
19625
19564
  for (let attempt = 0; attempt < 2; attempt += 1) {
19626
- const response = await this.fetch(this.request(action, data, abort.signal));
19565
+ const response = await runtimeFetch(this.fetch, this.request(action, data, abort.signal));
19627
19566
  if (response.status === 401 && attempt === 0 && this.refresh !== void 0) {
19628
19567
  await this.refreshAuthorization();
19629
19568
  continue;
19630
19569
  }
19631
19570
  const payload = await runtimeActionResponse(response);
19632
19571
  if (!response.ok || payload.error !== void 0) {
19633
- const error51 = payload.error ?? payload;
19634
- const message = typeof error51.message === "string" ? error51.message : `Runtime action ${action} failed.`;
19635
- const code = typeof error51.code === "number" ? error51.code : response.status;
19636
- throw new ErrorEvent(code, message, error51);
19572
+ throw remoteError("runtime", payload.error, response);
19637
19573
  }
19638
19574
  return payload.data;
19639
19575
  }
19640
- throw new ErrorEvent(401, `Runtime action ${action} could not be authorized.`, {});
19576
+ throw new RemoteError(`Runtime action ${action} could not be authorized.`, {
19577
+ source: "runtime",
19578
+ status: 401,
19579
+ code: "AuthenticationRequired"
19580
+ });
19641
19581
  } finally {
19642
19582
  abort.dispose();
19643
19583
  }
@@ -19645,7 +19585,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19645
19585
  request(action, data, signal) {
19646
19586
  const route = restActionRoutes[action];
19647
19587
  if (route === void 0) {
19648
- throw new UnsupportedRuntimeTransportError(`Runtime action ${action} requires the realtime transport.`);
19588
+ throw new PHPSandboxError(`Runtime action ${action} requires the realtime transport.`);
19649
19589
  }
19650
19590
  const url2 = new URL(this.actionUrl);
19651
19591
  url2.pathname += route.path;
@@ -19658,7 +19598,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19658
19598
  method: route.method,
19659
19599
  headers,
19660
19600
  body: route.method === "GET" ? void 0 : body,
19661
- signal
19601
+ signal,
19602
+ redirect: "error"
19662
19603
  });
19663
19604
  }
19664
19605
  async refreshAuthorization() {
@@ -19672,18 +19613,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19672
19613
  }
19673
19614
  }
19674
19615
  };
19616
+ async function runtimeFetch(fetch, request) {
19617
+ try {
19618
+ return await fetch(request);
19619
+ } catch (error51) {
19620
+ if (error51 instanceof DOMException && error51.name === "AbortError") {
19621
+ throw error51;
19622
+ }
19623
+ throw new TransportError("Unable to reach the PHPSandbox runtime.", "ConnectionFailed", error51);
19624
+ }
19625
+ }
19675
19626
  async function runtimeActionResponse(response) {
19676
19627
  if (response.ok && response.headers.get("content-type")?.toLowerCase().startsWith("application/octet-stream")) {
19677
19628
  return { data: new Uint8Array(await response.arrayBuffer()) };
19678
19629
  }
19679
19630
  const body = await response.text();
19680
19631
  if (body === "") {
19632
+ if (response.ok) {
19633
+ throw new TransportError("PHPSandbox runtime returned an empty response.", "InvalidResponse", response);
19634
+ }
19681
19635
  return {};
19682
19636
  }
19683
19637
  try {
19684
19638
  return JSON.parse(body);
19685
- } catch {
19686
- return { error: { code: response.status, message: body } };
19639
+ } catch (error51) {
19640
+ throw new TransportError("PHPSandbox runtime returned an invalid JSON response.", "InvalidResponse", error51);
19687
19641
  }
19688
19642
  }
19689
19643
  function runtimeActionRequestBody(action, data, url2, headers) {
@@ -19777,10 +19731,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19777
19731
  for (const [name, value] of Object.entries(options)) {
19778
19732
  if (value !== void 0) query.set(name, String(value));
19779
19733
  }
19780
- const response = await this.client.get(
19734
+ return this.client.get(
19781
19735
  `${this.path()}${query.size === 0 ? "" : `?${query.toString()}`}`
19782
19736
  );
19783
- return response.data;
19784
19737
  }
19785
19738
  async get(id) {
19786
19739
  const response = await this.client.get(this.path(`/${encodeURIComponent(id)}`));
@@ -19812,18 +19765,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19812
19765
  const response = await this.client.get(`/integrations/${encodeURIComponent(integrationId(integration))}`);
19813
19766
  return new Integration(response.data, this.client);
19814
19767
  }
19815
- async update(integration, input) {
19816
- const response = await this.client.patch(
19817
- `/integrations/${encodeURIComponent(integrationId(integration))}`,
19818
- input
19819
- );
19820
- return new Integration(response.data, this.client);
19821
- }
19822
- async unlink(integration) {
19823
- await this.client.delete(`/integrations/${encodeURIComponent(integrationId(integration))}`);
19824
- }
19825
19768
  };
19826
- var Integration = class {
19769
+ var Integration = class _Integration {
19827
19770
  constructor(data, client) {
19828
19771
  this.data = data;
19829
19772
  this.client = client;
@@ -19837,11 +19780,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19837
19780
  get label() {
19838
19781
  return this.data.label;
19839
19782
  }
19840
- update(input) {
19841
- return new IntegrationApi(this.client).update(this, input);
19783
+ async update(input) {
19784
+ const response = await this.client.patch(
19785
+ `/integrations/${encodeURIComponent(this.id)}`,
19786
+ input
19787
+ );
19788
+ return new _Integration(response.data, this.client);
19842
19789
  }
19843
- unlink() {
19844
- return new IntegrationApi(this.client).unlink(this);
19790
+ async unlink() {
19791
+ await this.client.delete(`/integrations/${encodeURIComponent(this.id)}`);
19845
19792
  }
19846
19793
  };
19847
19794
  function integrationId(integration) {
@@ -19869,16 +19816,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19869
19816
  const response = await this.client.get(this.bindingPath(integration));
19870
19817
  return new SandboxIntegration(response.data, this.notebookId, this.client);
19871
19818
  }
19872
- async update(integration, input) {
19873
- const response = await this.client.patch(this.bindingPath(integration), {
19874
- ...input,
19875
- integration: input.integration === void 0 ? void 0 : integrationId(input.integration)
19876
- });
19877
- return new SandboxIntegration(response.data, this.notebookId, this.client);
19878
- }
19879
- async detach(integration) {
19880
- await this.client.delete(this.bindingPath(integration));
19881
- }
19882
19819
  path() {
19883
19820
  return `/notebook/${this.notebookId}/integrations`;
19884
19821
  }
@@ -19886,7 +19823,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19886
19823
  return `${this.path()}/${encodeURIComponent(sandboxIntegrationId(integration))}`;
19887
19824
  }
19888
19825
  };
19889
- var SandboxIntegration = class {
19826
+ var SandboxIntegration = class _SandboxIntegration {
19890
19827
  constructor(data, notebookId, client) {
19891
19828
  this.data = data;
19892
19829
  this.notebookId = notebookId;
@@ -19901,11 +19838,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19901
19838
  get effects() {
19902
19839
  return this.data.effects;
19903
19840
  }
19904
- update(input) {
19905
- return new SandboxIntegrationApi(this.notebookId, this.client).update(this, input);
19841
+ async update(input) {
19842
+ const response = await this.client.patch(this.path(), {
19843
+ ...input,
19844
+ integration: input.integration === void 0 ? void 0 : integrationId(input.integration)
19845
+ });
19846
+ return new _SandboxIntegration(response.data, this.notebookId, this.client);
19906
19847
  }
19907
- detach() {
19908
- return new SandboxIntegrationApi(this.notebookId, this.client).detach(this);
19848
+ async detach() {
19849
+ await this.client.delete(this.path());
19850
+ }
19851
+ path() {
19852
+ return `/notebook/${this.notebookId}/integrations/${encodeURIComponent(this.id)}`;
19909
19853
  }
19910
19854
  };
19911
19855
  function sandboxIntegrationId(integration) {
@@ -19922,87 +19866,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19922
19866
  ...typeof value === "string" ? { value } : value
19923
19867
  }));
19924
19868
  }
19925
- var NotebookInitError = class extends Error {
19926
- constructor(message, data = {}) {
19927
- super(message);
19928
- this.message = message;
19929
- this.data = data;
19930
- this.name = "NotebookInitError";
19931
- }
19932
- };
19933
- var ApiError = class extends Error {
19934
- constructor(response, body) {
19935
- const data = parseApiErrorBody(body);
19936
- const apiMessage = apiErrorMessage(data, body);
19937
- super(`PHPSandbox API Error: ${response.status} ${response.statusText}${apiMessage === "" ? "" : ` - ${apiMessage}`}`);
19938
- this.response = response;
19939
- this.body = body;
19940
- this.status = response.status;
19941
- this.data = data;
19942
- this.apiMessage = apiMessage === "" ? void 0 : apiMessage;
19943
- }
19944
- };
19945
- function parseApiErrorBody(body) {
19946
- try {
19947
- return JSON.parse(body);
19948
- } catch {
19949
- return null;
19950
- }
19951
- }
19952
- function apiErrorMessage(data, fallback) {
19953
- if (data !== null && typeof data === "object") {
19954
- const record2 = data;
19955
- if (typeof record2.message === "string" && record2.message.trim() !== "") {
19956
- return record2.message.trim();
19957
- }
19958
- if (record2.error !== void 0) {
19959
- return typeof record2.error === "string" ? record2.error.trim() : JSON.stringify(record2.error);
19960
- }
19961
- }
19962
- return fallback.trim();
19963
- }
19964
19869
  var NotebookApi = class {
19965
19870
  constructor(client) {
19966
19871
  this.client = client;
19967
- this.secrets = new NotebookSecretApi(client);
19968
- this.composerCredentials = new NotebookComposerCredentialApi(client);
19969
- this.preview = new NotebookPreviewApi(client);
19970
- this.mail = new NotebookMailApi(client);
19971
- this.publication = new NotebookPublicationApi(client);
19972
19872
  }
19973
- async create(template, input = {}, init = true) {
19873
+ async create(template, input = {}) {
19974
19874
  const response = await this.client.post("/notebook", { template, ...input });
19975
- const instance = new NotebookInstance(response.data, this.client);
19976
- if (!init) {
19977
- return instance;
19978
- }
19979
- return this.init(instance);
19875
+ return new NotebookInstance(response.data, this.client);
19980
19876
  }
19981
19877
  async get(id) {
19982
19878
  const response = await this.client.get(`/notebook/${id}`);
19983
19879
  return new NotebookInstance(response.data, this.client);
19984
19880
  }
19985
- async update(id, input = {}) {
19986
- const response = await this.client.put(`/notebook/${id}`, input);
19987
- return new NotebookInstance(response.data, this.client);
19988
- }
19989
- async destroy(id) {
19990
- await this.client.delete(`/notebook/${id}`);
19991
- }
19992
- async fork(id, input = {}) {
19993
- const response = await this.client.post(`/notebook/${id}/fork`, input);
19994
- return new NotebookInstance(response.data, this.client);
19995
- }
19996
- async gitCredentials(id) {
19997
- const response = await this.client.post(`/notebook/${id}/git/credentials`);
19998
- return response.data;
19999
- }
20000
- openFromData(data) {
20001
- return this.init(new NotebookInstance(data, this.client));
20002
- }
20003
- async init(instance) {
20004
- await instance.ready();
20005
- return instance;
19881
+ open(data) {
19882
+ return new NotebookInstance(data, this.client);
20006
19883
  }
20007
19884
  };
20008
19885
  function normalizeApiBaseUrl(url2) {
@@ -20013,15 +19890,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20013
19890
  baseUrl.hash = "";
20014
19891
  return baseUrl.toString();
20015
19892
  }
20016
- var Client = class {
20017
- constructor(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20018
- this.runtimeTransportValue = "realtime";
19893
+ var ClientImplementation = class {
19894
+ constructor(token, url2 = "https://api.phpsandbox.io/v1", options = {}, runtimeTransport = "realtime") {
20019
19895
  this.fetch = globalThis.fetch;
20020
19896
  this.publications = new PublicationApi(this);
20021
19897
  this.notebook = new NotebookApi(this);
20022
19898
  this.servers = new ServerApi(this);
20023
19899
  this.integrations = new IntegrationApi(this);
20024
- this.options = Object.assign({ startClosed: true }, options);
19900
+ this.options = { ...options };
19901
+ this.runtimeTransportValue = runtimeTransport;
20025
19902
  this.baseUrl = normalizeApiBaseUrl(url2);
20026
19903
  if (options.fetch) {
20027
19904
  this.fetch = options.fetch;
@@ -20051,24 +19928,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20051
19928
  return this.makeRequest("PATCH", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
20052
19929
  }
20053
19930
  async stream(path) {
20054
- const response = await this.fetch(
19931
+ const response = await this.fetchResponse(
20055
19932
  new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
20056
19933
  method: "GET",
20057
- headers: this.headers
19934
+ headers: this.headers,
19935
+ redirect: "error"
20058
19936
  })
20059
19937
  );
20060
19938
  if (!response.ok) {
20061
- throw new ApiError(response, await response.text());
19939
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20062
19940
  }
20063
19941
  if (!response.body) {
20064
- throw new Error("PHPSandbox API Error: response body is not readable");
19942
+ throw new TransportError("PHPSandbox API response body is not readable.", "InvalidResponse", response);
20065
19943
  }
20066
19944
  return response.body;
20067
19945
  }
20068
19946
  async sse(url2) {
20069
- const response = await this.fetch(
19947
+ const response = await this.fetchResponse(
20070
19948
  new Request(url2, {
20071
19949
  method: "GET",
19950
+ redirect: "error",
20072
19951
  headers: {
20073
19952
  ...this.headers,
20074
19953
  "Accept": "text/event-stream"
@@ -20076,140 +19955,90 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20076
19955
  })
20077
19956
  );
20078
19957
  if (!response.ok) {
20079
- throw new ApiError(response, await response.text());
19958
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20080
19959
  }
20081
19960
  if (!response.body) {
20082
- throw new Error("PHPSandbox API Error: SSE response body is not readable");
19961
+ throw new TransportError("PHPSandbox API SSE response body is not readable.", "InvalidResponse", response);
20083
19962
  }
20084
19963
  return response.body;
20085
19964
  }
20086
19965
  async makeRequest(method, path, init) {
20087
- const response = await this.fetch(
19966
+ const response = await this.fetchResponse(
20088
19967
  new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
20089
19968
  method,
20090
19969
  ...init,
20091
- headers: this.headers
19970
+ headers: this.headers,
19971
+ redirect: "error"
20092
19972
  })
20093
19973
  );
20094
19974
  if (!response.ok) {
20095
- throw new ApiError(response, await response.text());
19975
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20096
19976
  }
20097
19977
  if (response.status === 204) {
20098
19978
  return { data: void 0 };
20099
19979
  }
20100
19980
  const body = await response.text();
20101
- return { data: body === "" ? void 0 : JSON.parse(body) };
20102
- }
20103
- };
20104
- var PHPSandbox = class _PHPSandbox extends Client {
20105
- static realtime(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20106
- return new _PHPSandbox(token, url2, options);
20107
- }
20108
- static rest(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20109
- const client = new _PHPSandbox(token, url2, options);
20110
- client.runtimeTransportValue = "rest";
20111
- return client;
20112
- }
20113
- };
20114
- var NotebookSecretApi = class {
20115
- constructor(client) {
20116
- this.client = client;
20117
- }
20118
- async list(id, options) {
20119
- const params = new URLSearchParams();
20120
- if (options?.environment) params.set("environment", options.environment);
20121
- const query = params.toString();
20122
- const response = await this.client.get(`/notebook/${id}/secrets${query ? `?${query}` : ""}`);
20123
- return response.data;
20124
- }
20125
- async set(id, name, input) {
20126
- const payload = typeof input === "string" ? { name, value: input } : { name, ...input };
20127
- const response = await this.client.put(`/notebook/${id}/secrets`, payload);
20128
- return response.data;
20129
- }
20130
- async setMany(id, input) {
20131
- const response = await this.client.put(`/notebook/${id}/secrets`, {
20132
- secrets: normalizeNotebookSecretInputs(input)
20133
- });
20134
- return response.data;
20135
- }
20136
- async delete(id, name, options) {
20137
- const params = new URLSearchParams();
20138
- if (options?.environment) params.set("environment", options.environment);
20139
- const query = params.toString();
20140
- await this.client.delete(`/notebook/${id}/secrets/${encodeURIComponent(name)}${query ? `?${query}` : ""}`);
20141
- }
20142
- };
20143
- var NotebookComposerCredentialApi = class {
20144
- constructor(client) {
20145
- this.client = client;
20146
- }
20147
- async set(id, input) {
20148
- const response = await this.client.put(`/notebook/${id}/composer/credentials`, input);
20149
- return response.data;
19981
+ if (body === "") {
19982
+ throw new TransportError("PHPSandbox API returned an empty response.", "InvalidResponse", response);
19983
+ }
19984
+ try {
19985
+ const payload = JSON.parse(body);
19986
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload) || !Object.prototype.hasOwnProperty.call(payload, "data")) {
19987
+ throw new TransportError("PHPSandbox API returned an invalid success response.", "InvalidResponse", response);
19988
+ }
19989
+ return payload;
19990
+ } catch (error51) {
19991
+ if (TransportError.is(error51)) {
19992
+ throw error51;
19993
+ }
19994
+ throw new TransportError("PHPSandbox API returned an invalid JSON response.", "InvalidResponse", error51);
19995
+ }
20150
19996
  }
20151
- async remove(id, type, url2) {
20152
- const params = new URLSearchParams({ type });
20153
- if (url2) params.set("url", url2);
20154
- await this.client.delete(`/notebook/${id}/composer/credentials?${params.toString()}`);
19997
+ async fetchResponse(request) {
19998
+ try {
19999
+ return await this.fetch(request);
20000
+ } catch (error51) {
20001
+ if (error51 instanceof DOMException && error51.name === "AbortError") {
20002
+ throw error51;
20003
+ }
20004
+ throw new TransportError("Unable to reach the PHPSandbox API.", "ConnectionFailed", error51);
20005
+ }
20155
20006
  }
20156
20007
  };
20157
- var NotebookPreviewApi = class {
20158
- constructor(client) {
20159
- this.client = client;
20160
- }
20161
- async get(id, url2) {
20162
- const query = url2 === void 0 ? "" : `?${new URLSearchParams({ url: url2 }).toString()}`;
20163
- const response = await this.client.get(`/notebook/${id}/preview${query}`);
20164
- return response.data;
20165
- }
20166
- async setPassword(id, input) {
20167
- const response = await this.client.put(`/notebook/${id}/preview`, input);
20168
- return response.data;
20169
- }
20170
- async disable(id) {
20171
- await this.client.delete(`/notebook/${id}/preview`);
20172
- }
20173
- async createSession(id, input) {
20174
- const response = await this.client.post(`/notebook/${id}/preview/session`, input);
20175
- return response.data;
20008
+ async function responsePayload(response) {
20009
+ const body = await response.text();
20010
+ if (body === "") {
20011
+ return void 0;
20176
20012
  }
20177
- async createHandoff(id, input) {
20178
- const response = await this.client.post(`/notebook/${id}/preview/handoff`, input);
20179
- return response.data;
20013
+ try {
20014
+ return JSON.parse(body);
20015
+ } catch (error51) {
20016
+ throw new TransportError("PHPSandbox API returned an invalid JSON response.", "InvalidResponse", error51);
20180
20017
  }
20181
- };
20182
- var NotebookMailApi = class {
20018
+ }
20019
+ function errorPayload(payload) {
20020
+ return payload !== null && typeof payload === "object" && !Array.isArray(payload) ? payload.error : void 0;
20021
+ }
20022
+ var PHPSandbox = class _PHPSandbox {
20183
20023
  constructor(client) {
20184
20024
  this.client = client;
20025
+ this.notebook = client.notebook;
20026
+ this.publications = client.publications;
20027
+ this.servers = client.servers;
20028
+ this.integrations = client.integrations;
20185
20029
  }
20186
- async status(id) {
20187
- const response = await this.client.get(`/notebook/${id}/mail`);
20188
- return response.data;
20189
- }
20190
- async enable(id) {
20191
- const response = await this.client.put(`/notebook/${id}/mail`);
20192
- return response.data;
20193
- }
20194
- async disable(id) {
20195
- await this.client.delete(`/notebook/${id}/mail`);
20196
- }
20197
- async list(id, options = {}) {
20198
- const response = await this.client.get(
20199
- `/notebook/${id}/mails${formatQueryString(options)}`
20200
- );
20201
- return response.data;
20030
+ get runtimeTransport() {
20031
+ return this.client.runtimeTransport;
20202
20032
  }
20203
- async get(id, hash2) {
20204
- const response = await this.client.get(`/notebook/${id}/mails/${encodeURIComponent(hash2)}`);
20205
- return response.data;
20033
+ static realtime(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20034
+ return new _PHPSandbox(new ClientImplementation(token, url2, options));
20206
20035
  }
20207
- async delete(id, hash2) {
20208
- await this.client.delete(`/notebook/${id}/mails/${encodeURIComponent(hash2)}`);
20036
+ static rest(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20037
+ return new _PHPSandbox(new ClientImplementation(token, url2, options, "rest"));
20209
20038
  }
20210
20039
  };
20211
20040
  var _initPromise, _NotebookInstance_instances, init_fn;
20212
- var NotebookInstance = class {
20041
+ var _NotebookInstance = class _NotebookInstance {
20213
20042
  constructor(data, client) {
20214
20043
  this.data = data;
20215
20044
  this.client = client;
@@ -20238,7 +20067,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20238
20067
  };
20239
20068
  this.socket = new Transport(connectionUrl, this.emitter, {
20240
20069
  debug: client.options.debug,
20241
- startClosed: client.options.startClosed,
20242
20070
  webSocket: client.options.webSocket
20243
20071
  });
20244
20072
  this.watchConnection();
@@ -20252,12 +20080,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20252
20080
  this.auth = new Auth(this);
20253
20081
  this.lsp = new Lsp(this);
20254
20082
  this.composer = new Composer(this, client);
20255
- const telemetry = new RuntimeTelemetry(this);
20256
- this.logs = new Logs(this, telemetry);
20257
- this.metrics = new Metrics(this, telemetry);
20258
- this.ports = new Ports(this, telemetry);
20083
+ this.runtime = new Runtime(this);
20259
20084
  this.repl = new Repl(this);
20260
- this.container = new Container(this);
20261
20085
  this.shell = new Shell(this);
20262
20086
  this.git = new Git(this, client);
20263
20087
  this.services = new Services(this);
@@ -20281,21 +20105,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20281
20105
  throw terminalError;
20282
20106
  }
20283
20107
  const ready = async () => {
20284
- if (this.client.options.startClosed && !socket.isConnected) {
20108
+ if (!socket.isConnected) {
20285
20109
  await socket.connect();
20286
20110
  }
20287
20111
  return __privateGet(this, _initPromise);
20288
20112
  };
20289
20113
  return ready();
20290
20114
  }
20291
- fork(input = {}) {
20292
- return this.client.notebook.fork(this.data.id, input);
20115
+ async fork(input = {}) {
20116
+ const response = await this.client.post(`/notebook/${this.data.id}/fork`, input);
20117
+ return new _NotebookInstance(response.data, this.client);
20293
20118
  }
20294
- publication() {
20295
- return this.client.notebook.publication.current(this.data.id);
20119
+ async publication() {
20120
+ try {
20121
+ const response = await this.client.get(`/notebook/${this.data.id}/publication`);
20122
+ return new PublicationInstance(response.data, this.client, this.data.id);
20123
+ } catch (error51) {
20124
+ if (RemoteError.is(error51) && error51.status === 404) {
20125
+ return null;
20126
+ }
20127
+ throw error51;
20128
+ }
20296
20129
  }
20297
- publish(input) {
20298
- return this.client.notebook.publication.publish(this.data.id, input);
20130
+ async publish(input) {
20131
+ const response = await this.client.post(`/notebook/${this.data.id}/publication`, input);
20132
+ const run = new PublicationRun(new PublicationInstance(response.data, this.client, this.data.id), this.client);
20133
+ run.start();
20134
+ return run;
20299
20135
  }
20300
20136
  run(command, argsOrOpts = [], opts) {
20301
20137
  if (Array.isArray(argsOrOpts)) {
@@ -20309,19 +20145,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20309
20145
  }
20310
20146
  return this.run(command, argsOrOpts).wait();
20311
20147
  }
20312
- gitCredentials() {
20313
- return this.client.notebook.gitCredentials(this.data.id);
20148
+ async destroy() {
20149
+ await this.client.delete(`/notebook/${this.data.id}`);
20150
+ this.socket?.terminate(new RemoteError("Notebook has been deleted.", {
20151
+ source: "runtime",
20152
+ status: 503,
20153
+ code: "NotebookUnavailable",
20154
+ details: { id: this.data.id }
20155
+ }));
20314
20156
  }
20315
- destroy() {
20316
- return this.client.notebook.destroy(this.data.id).then(() => {
20317
- this.socket?.terminate(new NotebookUnavailableError("Notebook has been deleted.", { id: this.data.id }));
20318
- });
20157
+ restart() {
20158
+ return this.invoke("container.restart");
20319
20159
  }
20320
20160
  stop() {
20321
- return this.container.stop();
20322
- }
20323
- restart() {
20324
- return this.container.restart();
20161
+ return this.invoke("container.stop");
20325
20162
  }
20326
20163
  invoke(action, data = {}, options = {}) {
20327
20164
  if (this.restInvoker !== null) {
@@ -20338,9 +20175,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20338
20175
  }
20339
20176
  return this.realtimeSocket().send(action, data || {});
20340
20177
  }
20341
- ping() {
20342
- return this.invoke("ping");
20343
- }
20344
20178
  listen(event, handler) {
20345
20179
  const disposable = this.emitter.listen(event, handler);
20346
20180
  this.disposables.push(disposable);
@@ -20355,9 +20189,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20355
20189
  connected() {
20356
20190
  return this.waitForSocketConnection({ rejectOnClose: true });
20357
20191
  }
20358
- whenConnected() {
20359
- return this.waitForSocketConnection({ rejectOnClose: false });
20360
- }
20361
20192
  waitForSocketConnection(options) {
20362
20193
  const socket = this.realtimeSocket();
20363
20194
  const terminalError = socket.getTerminalError();
@@ -20429,7 +20260,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20429
20260
  }
20430
20261
  restInitialization() {
20431
20262
  if (this.restInvoker === null) {
20432
- throw new UnsupportedRuntimeTransportError("This operation requires the REST transport.");
20263
+ throw new PHPSandboxError("This operation requires the REST transport.");
20433
20264
  }
20434
20265
  if (__privateGet(this, _initPromise) === null) {
20435
20266
  __privateSet(this, _initPromise, this.restInvoker.ready().then((result) => {
@@ -20442,15 +20273,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20442
20273
  }
20443
20274
  return __privateGet(this, _initPromise);
20444
20275
  }
20445
- update(input) {
20446
- return this.client.notebook.update(this.data.id, input);
20447
- }
20448
20276
  onDidInitialize(handler) {
20449
20277
  return this.listen("notebook.initialized", handler);
20450
20278
  }
20451
20279
  async reconnect() {
20452
20280
  const socket = this.realtimeSocket();
20453
- const whenConnected = this.whenConnected();
20281
+ const whenConnected = this.waitForSocketConnection({ rejectOnClose: false });
20454
20282
  socket.reconnect();
20455
20283
  this.initialized = false;
20456
20284
  await whenConnected;
@@ -20459,7 +20287,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20459
20287
  }
20460
20288
  realtimeSocket() {
20461
20289
  if (this.socket === null) {
20462
- throw new UnsupportedRuntimeTransportError("This operation requires the realtime transport.");
20290
+ throw new PHPSandboxError("This operation requires the realtime transport.");
20463
20291
  }
20464
20292
  return this.socket;
20465
20293
  }
@@ -20473,7 +20301,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20473
20301
  initializationListener.dispose();
20474
20302
  this.initialized = result;
20475
20303
  if (result.type === "error") {
20476
- reject(new NotebookInitError(result.message, result.data));
20304
+ reject(new RemoteError(result.message, {
20305
+ source: "runtime",
20306
+ status: 503,
20307
+ code: "NotebookInitializationFailed",
20308
+ details: result.data
20309
+ }));
20477
20310
  return;
20478
20311
  }
20479
20312
  resolve(result);
@@ -20488,34 +20321,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20488
20321
  });
20489
20322
  return __privateGet(this, _initPromise);
20490
20323
  };
20324
+ var NotebookInstance = _NotebookInstance;
20491
20325
  var NotebookSecrets = class {
20492
20326
  constructor(client, notebookId) {
20493
20327
  this.client = client;
20494
20328
  this.notebookId = notebookId;
20495
20329
  }
20496
- list(options) {
20497
- return this.client.notebook.secrets.list(this.notebookId, options);
20498
- }
20499
- set(name, input) {
20500
- return this.client.notebook.secrets.set(this.notebookId, name, input);
20501
- }
20502
- setMany(input) {
20503
- return this.client.notebook.secrets.setMany(this.notebookId, input);
20504
- }
20505
- delete(name, options) {
20506
- return this.client.notebook.secrets.delete(this.notebookId, name, options);
20330
+ async list(options) {
20331
+ const params = new URLSearchParams();
20332
+ if (options?.environment) params.set("environment", options.environment);
20333
+ const query = params.toString();
20334
+ const response = await this.client.get(
20335
+ `/notebook/${this.notebookId}/secrets${query ? `?${query}` : ""}`
20336
+ );
20337
+ return response.data;
20507
20338
  }
20508
- };
20509
- var ComposerCredentials = class {
20510
- constructor(client, notebookId) {
20511
- this.client = client;
20512
- this.notebookId = notebookId;
20339
+ async set(name, input) {
20340
+ const payload = typeof input === "string" ? { name, value: input } : { name, ...input };
20341
+ const response = await this.client.put(`/notebook/${this.notebookId}/secrets`, payload);
20342
+ return response.data;
20513
20343
  }
20514
- set(input) {
20515
- return this.client.notebook.composerCredentials.set(this.notebookId, input);
20344
+ async setMany(input) {
20345
+ const response = await this.client.put(`/notebook/${this.notebookId}/secrets`, {
20346
+ secrets: normalizeNotebookSecretInputs(input)
20347
+ });
20348
+ return response.data;
20516
20349
  }
20517
- remove(type, url2) {
20518
- return this.client.notebook.composerCredentials.remove(this.notebookId, type, url2);
20350
+ async delete(name, options) {
20351
+ const params = new URLSearchParams();
20352
+ if (options?.environment) params.set("environment", options.environment);
20353
+ const query = params.toString();
20354
+ await this.client.delete(
20355
+ `/notebook/${this.notebookId}/secrets/${encodeURIComponent(name)}${query ? `?${query}` : ""}`
20356
+ );
20519
20357
  }
20520
20358
  };
20521
20359
  var NotebookPreview = class {
@@ -20523,20 +20361,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20523
20361
  this.client = client;
20524
20362
  this.notebookId = notebookId;
20525
20363
  }
20526
- get(url2) {
20527
- return this.client.notebook.preview.get(this.notebookId, url2);
20364
+ async get(url2) {
20365
+ const query = url2 === void 0 ? "" : `?${new URLSearchParams({ url: url2 }).toString()}`;
20366
+ const response = await this.client.get(`/notebook/${this.notebookId}/preview${query}`);
20367
+ return response.data;
20528
20368
  }
20529
- setPassword(input) {
20530
- return this.client.notebook.preview.setPassword(this.notebookId, input);
20369
+ async setPassword(input) {
20370
+ const response = await this.client.put(`/notebook/${this.notebookId}/preview`, input);
20371
+ return response.data;
20531
20372
  }
20532
- disable() {
20533
- return this.client.notebook.preview.disable(this.notebookId);
20373
+ async disable() {
20374
+ await this.client.delete(`/notebook/${this.notebookId}/preview`);
20534
20375
  }
20535
- createSession(input) {
20536
- return this.client.notebook.preview.createSession(this.notebookId, input);
20376
+ async createSession(input) {
20377
+ const response = await this.client.post(
20378
+ `/notebook/${this.notebookId}/preview/session`,
20379
+ input
20380
+ );
20381
+ return response.data;
20537
20382
  }
20538
- createHandoff(input) {
20539
- return this.client.notebook.preview.createHandoff(this.notebookId, input);
20383
+ async createHandoff(input) {
20384
+ const response = await this.client.post(
20385
+ `/notebook/${this.notebookId}/preview/handoff`,
20386
+ input
20387
+ );
20388
+ return response.data;
20540
20389
  }
20541
20390
  };
20542
20391
  var NotebookMail = class {
@@ -20544,23 +20393,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20544
20393
  this.client = client;
20545
20394
  this.notebookId = notebookId;
20546
20395
  }
20547
- status() {
20548
- return this.client.notebook.mail.status(this.notebookId);
20396
+ async status() {
20397
+ const response = await this.client.get(`/notebook/${this.notebookId}/mail`);
20398
+ return response.data;
20549
20399
  }
20550
- enable() {
20551
- return this.client.notebook.mail.enable(this.notebookId);
20400
+ async enable() {
20401
+ const response = await this.client.put(`/notebook/${this.notebookId}/mail`);
20402
+ return response.data;
20552
20403
  }
20553
- disable() {
20554
- return this.client.notebook.mail.disable(this.notebookId);
20404
+ async disable() {
20405
+ await this.client.delete(`/notebook/${this.notebookId}/mail`);
20555
20406
  }
20556
- list(options = {}) {
20557
- return this.client.notebook.mail.list(this.notebookId, options);
20407
+ async list(options = {}) {
20408
+ return this.client.get(
20409
+ `/notebook/${this.notebookId}/mails${formatQueryString(options)}`
20410
+ );
20558
20411
  }
20559
- get(hash2) {
20560
- return this.client.notebook.mail.get(this.notebookId, hash2);
20412
+ async get(hash2) {
20413
+ const response = await this.client.get(
20414
+ `/notebook/${this.notebookId}/mails/${encodeURIComponent(hash2)}`
20415
+ );
20416
+ return response.data;
20561
20417
  }
20562
- delete(hash2) {
20563
- return this.client.notebook.mail.delete(this.notebookId, hash2);
20418
+ async delete(hash2) {
20419
+ await this.client.delete(`/notebook/${this.notebookId}/mails/${encodeURIComponent(hash2)}`);
20564
20420
  }
20565
20421
  };
20566
20422
  function formatQueryString(params) {