@phpsandbox/sdk 0.1.9 → 0.1.11

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 (61) 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 +552 -692
  7. package/dist/browser/phpsandbox-sdk.esm.min.js +24 -24
  8. package/dist/browser/phpsandbox-sdk.iife.js +552 -692
  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/http.d.ts +6 -0
  20. package/dist/http.js +11 -0
  21. package/dist/index.d.ts +54 -144
  22. package/dist/index.js +170 -289
  23. package/dist/integrations.d.ts +0 -2
  24. package/dist/integrations.js +5 -11
  25. package/dist/log.d.ts +0 -2
  26. package/dist/lsp.js +1 -1
  27. package/dist/metrics.d.ts +3 -3
  28. package/dist/ports.d.ts +1 -1
  29. package/dist/publications.d.ts +4 -54
  30. package/dist/publications.js +25 -103
  31. package/dist/runtime/rest.js +35 -18
  32. package/dist/runtime.d.ts +68 -0
  33. package/dist/runtime.js +46 -0
  34. package/dist/sandbox-integrations.d.ts +1 -2
  35. package/dist/sandbox-integrations.js +11 -14
  36. package/dist/schemas/publications.d.ts +0 -6
  37. package/dist/schemas/publications.js +0 -1
  38. package/dist/servers.d.ts +4 -2
  39. package/dist/servers.js +5 -8
  40. package/dist/shell.d.ts +2 -14
  41. package/dist/shell.js +1 -21
  42. package/dist/socket/index.d.ts +6 -7
  43. package/dist/socket/index.js +39 -25
  44. package/dist/types.d.ts +0 -12
  45. package/dist/types.js +1 -15
  46. package/docs/api-summary.md +28 -28
  47. package/docs/cdn-usage.md +43 -55
  48. package/docs/getting-started.md +43 -26
  49. package/examples/README.md +5 -35
  50. package/examples/basic.ts +9 -18
  51. package/examples/get.ts +2 -2
  52. package/examples/git-merge-smoke.ts +2 -3
  53. package/examples/laravel-load-test.ts +31 -36
  54. package/examples/notebook-readonly-smoke.ts +12 -26
  55. package/examples/publication-provider-label.ts +1 -1
  56. package/examples/publish-cloudflare-container.ts +2 -2
  57. package/examples/publish-laravel-cloud.ts +2 -2
  58. package/examples/publish-ssh-agent.ts +2 -2
  59. package/package.json +4 -3
  60. package/dist/container.d.ts +0 -65
  61. 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);
19291
- }
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);
19234
+ return this.client.stream(`/publications/${this.data.id}/builds/${buildId}/logs/stream`).then((stream) => parseNdjsonStream(stream, PublicationLogChunkDataSchema));
19297
19235
  }
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;
@@ -19537,15 +19475,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19537
19475
  }
19538
19476
  };
19539
19477
 
19478
+ // src/http.ts
19479
+ function authenticatedRequest(input, init) {
19480
+ return new Request(input, {
19481
+ ...init,
19482
+ redirect: "manual"
19483
+ });
19484
+ }
19485
+
19540
19486
  // src/runtime/rest.ts
19541
19487
  var restActionRoutes = {
19542
19488
  "runtime.ready": { method: "GET", path: "/runtime" },
19543
- ping: { method: "GET", path: "/runtime/ping" },
19544
19489
  "config.get": { method: "GET", path: "/runtime/config" },
19545
19490
  "config.update": { method: "PATCH", path: "/runtime/config" },
19546
19491
  "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
19492
  "container.restart": { method: "POST", path: "/runtime/container/restart" },
19550
19493
  "container.stop": { method: "POST", path: "/runtime/container/stop" },
19551
19494
  "container.set-php": { method: "PUT", path: "/runtime/container/php" },
@@ -19598,10 +19541,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19598
19541
  const actionUrl = new URL(runtimeUrl);
19599
19542
  const ticket = actionUrl.searchParams.get("ticket") ?? "";
19600
19543
  if (ticket === "") {
19601
- throw new UnsupportedRuntimeTransportError("The notebook connection does not contain a runtime ticket.");
19544
+ throw new PHPSandboxError("The notebook connection does not contain a runtime ticket.");
19602
19545
  }
19603
19546
  this.ticket = ticket;
19604
- actionUrl.protocol = actionUrl.protocol === "wss:" ? "https:" : "http:";
19547
+ if (actionUrl.protocol === "wss:") {
19548
+ actionUrl.protocol = "https:";
19549
+ } else if (actionUrl.protocol === "ws:") {
19550
+ actionUrl.protocol = "http:";
19551
+ }
19605
19552
  actionUrl.pathname = `/api/v1/notebooks/${encodeURIComponent(this.notebookId)}`;
19606
19553
  actionUrl.searchParams.delete("ticket");
19607
19554
  actionUrl.hash = "";
@@ -19617,27 +19564,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19617
19564
  return this.invokeRaw(action, data ?? {}, options);
19618
19565
  }
19619
19566
  send() {
19620
- throw new UnsupportedRuntimeTransportError("Fire-and-forget actions require the realtime transport.");
19567
+ throw new PHPSandboxError("Fire-and-forget actions require the realtime transport.");
19621
19568
  }
19622
19569
  async invokeRaw(action, data, options) {
19623
19570
  const abort = runtimeAbort(options);
19624
19571
  try {
19625
19572
  for (let attempt = 0; attempt < 2; attempt += 1) {
19626
- const response = await this.fetch(this.request(action, data, abort.signal));
19573
+ const response = await runtimeFetch(this.fetch, this.request(action, data, abort.signal));
19627
19574
  if (response.status === 401 && attempt === 0 && this.refresh !== void 0) {
19628
19575
  await this.refreshAuthorization();
19629
19576
  continue;
19630
19577
  }
19631
19578
  const payload = await runtimeActionResponse(response);
19632
19579
  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);
19580
+ throw remoteError("runtime", payload.error, response);
19637
19581
  }
19638
19582
  return payload.data;
19639
19583
  }
19640
- throw new ErrorEvent(401, `Runtime action ${action} could not be authorized.`, {});
19584
+ throw new RemoteError(`Runtime action ${action} could not be authorized.`, {
19585
+ source: "runtime",
19586
+ status: 401,
19587
+ code: "AuthenticationRequired"
19588
+ });
19641
19589
  } finally {
19642
19590
  abort.dispose();
19643
19591
  }
@@ -19645,7 +19593,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19645
19593
  request(action, data, signal) {
19646
19594
  const route = restActionRoutes[action];
19647
19595
  if (route === void 0) {
19648
- throw new UnsupportedRuntimeTransportError(`Runtime action ${action} requires the realtime transport.`);
19596
+ throw new PHPSandboxError(`Runtime action ${action} requires the realtime transport.`);
19649
19597
  }
19650
19598
  const url2 = new URL(this.actionUrl);
19651
19599
  url2.pathname += route.path;
@@ -19654,7 +19602,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19654
19602
  Authorization: `Bearer ${this.ticket}`
19655
19603
  };
19656
19604
  const body = runtimeActionRequestBody(action, data, url2, headers);
19657
- return new Request(url2, {
19605
+ return authenticatedRequest(url2, {
19658
19606
  method: route.method,
19659
19607
  headers,
19660
19608
  body: route.method === "GET" ? void 0 : body,
@@ -19672,18 +19620,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19672
19620
  }
19673
19621
  }
19674
19622
  };
19623
+ async function runtimeFetch(fetch, request) {
19624
+ try {
19625
+ return await fetch(request);
19626
+ } catch (error51) {
19627
+ if (error51 instanceof DOMException && error51.name === "AbortError") {
19628
+ throw error51;
19629
+ }
19630
+ throw new TransportError("Unable to reach the PHPSandbox runtime.", "ConnectionFailed", error51);
19631
+ }
19632
+ }
19675
19633
  async function runtimeActionResponse(response) {
19676
19634
  if (response.ok && response.headers.get("content-type")?.toLowerCase().startsWith("application/octet-stream")) {
19677
19635
  return { data: new Uint8Array(await response.arrayBuffer()) };
19678
19636
  }
19679
19637
  const body = await response.text();
19680
19638
  if (body === "") {
19639
+ if (response.ok) {
19640
+ throw new TransportError("PHPSandbox runtime returned an empty response.", "InvalidResponse", response);
19641
+ }
19681
19642
  return {};
19682
19643
  }
19683
19644
  try {
19684
19645
  return JSON.parse(body);
19685
- } catch {
19686
- return { error: { code: response.status, message: body } };
19646
+ } catch (error51) {
19647
+ throw new TransportError("PHPSandbox runtime returned an invalid JSON response.", "InvalidResponse", error51);
19687
19648
  }
19688
19649
  }
19689
19650
  function runtimeActionRequestBody(action, data, url2, headers) {
@@ -19777,10 +19738,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19777
19738
  for (const [name, value] of Object.entries(options)) {
19778
19739
  if (value !== void 0) query.set(name, String(value));
19779
19740
  }
19780
- const response = await this.client.get(
19741
+ return this.client.get(
19781
19742
  `${this.path()}${query.size === 0 ? "" : `?${query.toString()}`}`
19782
19743
  );
19783
- return response.data;
19784
19744
  }
19785
19745
  async get(id) {
19786
19746
  const response = await this.client.get(this.path(`/${encodeURIComponent(id)}`));
@@ -19812,18 +19772,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19812
19772
  const response = await this.client.get(`/integrations/${encodeURIComponent(integrationId(integration))}`);
19813
19773
  return new Integration(response.data, this.client);
19814
19774
  }
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
19775
  };
19826
- var Integration = class {
19776
+ var Integration = class _Integration {
19827
19777
  constructor(data, client) {
19828
19778
  this.data = data;
19829
19779
  this.client = client;
@@ -19837,11 +19787,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19837
19787
  get label() {
19838
19788
  return this.data.label;
19839
19789
  }
19840
- update(input) {
19841
- return new IntegrationApi(this.client).update(this, input);
19790
+ async update(input) {
19791
+ const response = await this.client.patch(
19792
+ `/integrations/${encodeURIComponent(this.id)}`,
19793
+ input
19794
+ );
19795
+ return new _Integration(response.data, this.client);
19842
19796
  }
19843
- unlink() {
19844
- return new IntegrationApi(this.client).unlink(this);
19797
+ async unlink() {
19798
+ await this.client.delete(`/integrations/${encodeURIComponent(this.id)}`);
19845
19799
  }
19846
19800
  };
19847
19801
  function integrationId(integration) {
@@ -19869,16 +19823,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19869
19823
  const response = await this.client.get(this.bindingPath(integration));
19870
19824
  return new SandboxIntegration(response.data, this.notebookId, this.client);
19871
19825
  }
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
19826
  path() {
19883
19827
  return `/notebook/${this.notebookId}/integrations`;
19884
19828
  }
@@ -19886,7 +19830,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19886
19830
  return `${this.path()}/${encodeURIComponent(sandboxIntegrationId(integration))}`;
19887
19831
  }
19888
19832
  };
19889
- var SandboxIntegration = class {
19833
+ var SandboxIntegration = class _SandboxIntegration {
19890
19834
  constructor(data, notebookId, client) {
19891
19835
  this.data = data;
19892
19836
  this.notebookId = notebookId;
@@ -19901,11 +19845,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19901
19845
  get effects() {
19902
19846
  return this.data.effects;
19903
19847
  }
19904
- update(input) {
19905
- return new SandboxIntegrationApi(this.notebookId, this.client).update(this, input);
19848
+ async update(input) {
19849
+ const response = await this.client.patch(this.path(), {
19850
+ ...input,
19851
+ integration: input.integration === void 0 ? void 0 : integrationId(input.integration)
19852
+ });
19853
+ return new _SandboxIntegration(response.data, this.notebookId, this.client);
19854
+ }
19855
+ async detach() {
19856
+ await this.client.delete(this.path());
19906
19857
  }
19907
- detach() {
19908
- return new SandboxIntegrationApi(this.notebookId, this.client).detach(this);
19858
+ path() {
19859
+ return `/notebook/${this.notebookId}/integrations/${encodeURIComponent(this.id)}`;
19909
19860
  }
19910
19861
  };
19911
19862
  function sandboxIntegrationId(integration) {
@@ -19922,87 +19873,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19922
19873
  ...typeof value === "string" ? { value } : value
19923
19874
  }));
19924
19875
  }
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
19876
  var NotebookApi = class {
19965
19877
  constructor(client) {
19966
19878
  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
19879
  }
19973
- async create(template, input = {}, init = true) {
19880
+ async create(template, input = {}) {
19974
19881
  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);
19882
+ return new NotebookInstance(response.data, this.client);
19980
19883
  }
19981
19884
  async get(id) {
19982
19885
  const response = await this.client.get(`/notebook/${id}`);
19983
19886
  return new NotebookInstance(response.data, this.client);
19984
19887
  }
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;
19888
+ open(data) {
19889
+ return new NotebookInstance(data, this.client);
20006
19890
  }
20007
19891
  };
20008
19892
  function normalizeApiBaseUrl(url2) {
@@ -20013,15 +19897,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20013
19897
  baseUrl.hash = "";
20014
19898
  return baseUrl.toString();
20015
19899
  }
20016
- var Client = class {
20017
- constructor(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20018
- this.runtimeTransportValue = "realtime";
19900
+ var ClientImplementation = class {
19901
+ constructor(token, url2 = "https://api.phpsandbox.io/v1", options = {}, runtimeTransport = "realtime") {
20019
19902
  this.fetch = globalThis.fetch;
20020
19903
  this.publications = new PublicationApi(this);
20021
19904
  this.notebook = new NotebookApi(this);
20022
19905
  this.servers = new ServerApi(this);
20023
19906
  this.integrations = new IntegrationApi(this);
20024
- this.options = Object.assign({ startClosed: true }, options);
19907
+ this.options = { ...options };
19908
+ this.runtimeTransportValue = runtimeTransport;
20025
19909
  this.baseUrl = normalizeApiBaseUrl(url2);
20026
19910
  if (options.fetch) {
20027
19911
  this.fetch = options.fetch;
@@ -20051,23 +19935,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20051
19935
  return this.makeRequest("PATCH", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
20052
19936
  }
20053
19937
  async stream(path) {
20054
- const response = await this.fetch(
20055
- new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
19938
+ const response = await this.fetchResponse(
19939
+ authenticatedRequest(new URL(path.replace(/^\//, ""), this.baseUrl), {
20056
19940
  method: "GET",
20057
19941
  headers: this.headers
20058
19942
  })
20059
19943
  );
20060
19944
  if (!response.ok) {
20061
- throw new ApiError(response, await response.text());
19945
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20062
19946
  }
20063
19947
  if (!response.body) {
20064
- throw new Error("PHPSandbox API Error: response body is not readable");
19948
+ throw new TransportError("PHPSandbox API response body is not readable.", "InvalidResponse", response);
20065
19949
  }
20066
19950
  return response.body;
20067
19951
  }
20068
19952
  async sse(url2) {
20069
- const response = await this.fetch(
20070
- new Request(url2, {
19953
+ const response = await this.fetchResponse(
19954
+ authenticatedRequest(url2, {
20071
19955
  method: "GET",
20072
19956
  headers: {
20073
19957
  ...this.headers,
@@ -20076,140 +19960,89 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20076
19960
  })
20077
19961
  );
20078
19962
  if (!response.ok) {
20079
- throw new ApiError(response, await response.text());
19963
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20080
19964
  }
20081
19965
  if (!response.body) {
20082
- throw new Error("PHPSandbox API Error: SSE response body is not readable");
19966
+ throw new TransportError("PHPSandbox API SSE response body is not readable.", "InvalidResponse", response);
20083
19967
  }
20084
19968
  return response.body;
20085
19969
  }
20086
19970
  async makeRequest(method, path, init) {
20087
- const response = await this.fetch(
20088
- new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
19971
+ const response = await this.fetchResponse(
19972
+ authenticatedRequest(new URL(path.replace(/^\//, ""), this.baseUrl), {
20089
19973
  method,
20090
19974
  ...init,
20091
19975
  headers: this.headers
20092
19976
  })
20093
19977
  );
20094
19978
  if (!response.ok) {
20095
- throw new ApiError(response, await response.text());
19979
+ throw remoteError("core", errorPayload(await responsePayload(response)), response);
20096
19980
  }
20097
19981
  if (response.status === 204) {
20098
19982
  return { data: void 0 };
20099
19983
  }
20100
19984
  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;
19985
+ if (body === "") {
19986
+ throw new TransportError("PHPSandbox API returned an empty response.", "InvalidResponse", response);
19987
+ }
19988
+ try {
19989
+ const payload = JSON.parse(body);
19990
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload) || !Object.prototype.hasOwnProperty.call(payload, "data")) {
19991
+ throw new TransportError("PHPSandbox API returned an invalid success response.", "InvalidResponse", response);
19992
+ }
19993
+ return payload;
19994
+ } catch (error51) {
19995
+ if (TransportError.is(error51)) {
19996
+ throw error51;
19997
+ }
19998
+ throw new TransportError("PHPSandbox API returned an invalid JSON response.", "InvalidResponse", error51);
19999
+ }
20150
20000
  }
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()}`);
20001
+ async fetchResponse(request) {
20002
+ try {
20003
+ return await this.fetch(request);
20004
+ } catch (error51) {
20005
+ if (error51 instanceof DOMException && error51.name === "AbortError") {
20006
+ throw error51;
20007
+ }
20008
+ throw new TransportError("Unable to reach the PHPSandbox API.", "ConnectionFailed", error51);
20009
+ }
20155
20010
  }
20156
20011
  };
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;
20012
+ async function responsePayload(response) {
20013
+ const body = await response.text();
20014
+ if (body === "") {
20015
+ return void 0;
20176
20016
  }
20177
- async createHandoff(id, input) {
20178
- const response = await this.client.post(`/notebook/${id}/preview/handoff`, input);
20179
- return response.data;
20017
+ try {
20018
+ return JSON.parse(body);
20019
+ } catch (error51) {
20020
+ throw new TransportError("PHPSandbox API returned an invalid JSON response.", "InvalidResponse", error51);
20180
20021
  }
20181
- };
20182
- var NotebookMailApi = class {
20022
+ }
20023
+ function errorPayload(payload) {
20024
+ return payload !== null && typeof payload === "object" && !Array.isArray(payload) ? payload.error : void 0;
20025
+ }
20026
+ var PHPSandbox = class _PHPSandbox {
20183
20027
  constructor(client) {
20184
20028
  this.client = client;
20029
+ this.notebook = client.notebook;
20030
+ this.publications = client.publications;
20031
+ this.servers = client.servers;
20032
+ this.integrations = client.integrations;
20185
20033
  }
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;
20034
+ get runtimeTransport() {
20035
+ return this.client.runtimeTransport;
20202
20036
  }
20203
- async get(id, hash2) {
20204
- const response = await this.client.get(`/notebook/${id}/mails/${encodeURIComponent(hash2)}`);
20205
- return response.data;
20037
+ static realtime(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20038
+ return new _PHPSandbox(new ClientImplementation(token, url2, options));
20206
20039
  }
20207
- async delete(id, hash2) {
20208
- await this.client.delete(`/notebook/${id}/mails/${encodeURIComponent(hash2)}`);
20040
+ static rest(token, url2 = "https://api.phpsandbox.io/v1", options = {}) {
20041
+ return new _PHPSandbox(new ClientImplementation(token, url2, options, "rest"));
20209
20042
  }
20210
20043
  };
20211
20044
  var _initPromise, _NotebookInstance_instances, init_fn;
20212
- var NotebookInstance = class {
20045
+ var _NotebookInstance = class _NotebookInstance {
20213
20046
  constructor(data, client) {
20214
20047
  this.data = data;
20215
20048
  this.client = client;
@@ -20238,7 +20071,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20238
20071
  };
20239
20072
  this.socket = new Transport(connectionUrl, this.emitter, {
20240
20073
  debug: client.options.debug,
20241
- startClosed: client.options.startClosed,
20242
20074
  webSocket: client.options.webSocket
20243
20075
  });
20244
20076
  this.watchConnection();
@@ -20252,12 +20084,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20252
20084
  this.auth = new Auth(this);
20253
20085
  this.lsp = new Lsp(this);
20254
20086
  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);
20087
+ this.runtime = new Runtime(this);
20259
20088
  this.repl = new Repl(this);
20260
- this.container = new Container(this);
20261
20089
  this.shell = new Shell(this);
20262
20090
  this.git = new Git(this, client);
20263
20091
  this.services = new Services(this);
@@ -20281,21 +20109,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20281
20109
  throw terminalError;
20282
20110
  }
20283
20111
  const ready = async () => {
20284
- if (this.client.options.startClosed && !socket.isConnected) {
20112
+ if (!socket.isConnected) {
20285
20113
  await socket.connect();
20286
20114
  }
20287
20115
  return __privateGet(this, _initPromise);
20288
20116
  };
20289
20117
  return ready();
20290
20118
  }
20291
- fork(input = {}) {
20292
- return this.client.notebook.fork(this.data.id, input);
20119
+ async fork(input = {}) {
20120
+ const response = await this.client.post(`/notebook/${this.data.id}/fork`, input);
20121
+ return new _NotebookInstance(response.data, this.client);
20293
20122
  }
20294
- publication() {
20295
- return this.client.notebook.publication.current(this.data.id);
20123
+ async publication() {
20124
+ try {
20125
+ const response = await this.client.get(`/notebook/${this.data.id}/publication`);
20126
+ return new PublicationInstance(response.data, this.client, this.data.id);
20127
+ } catch (error51) {
20128
+ if (RemoteError.is(error51) && error51.status === 404) {
20129
+ return null;
20130
+ }
20131
+ throw error51;
20132
+ }
20296
20133
  }
20297
- publish(input) {
20298
- return this.client.notebook.publication.publish(this.data.id, input);
20134
+ async publish(input) {
20135
+ const response = await this.client.post(`/notebook/${this.data.id}/publication`, input);
20136
+ const run = new PublicationRun(new PublicationInstance(response.data, this.client, this.data.id), this.client);
20137
+ run.start();
20138
+ return run;
20299
20139
  }
20300
20140
  run(command, argsOrOpts = [], opts) {
20301
20141
  if (Array.isArray(argsOrOpts)) {
@@ -20309,19 +20149,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20309
20149
  }
20310
20150
  return this.run(command, argsOrOpts).wait();
20311
20151
  }
20312
- gitCredentials() {
20313
- return this.client.notebook.gitCredentials(this.data.id);
20152
+ async destroy() {
20153
+ await this.client.delete(`/notebook/${this.data.id}`);
20154
+ this.socket?.terminate(new RemoteError("Notebook has been deleted.", {
20155
+ source: "runtime",
20156
+ status: 503,
20157
+ code: "NotebookUnavailable",
20158
+ details: { id: this.data.id }
20159
+ }));
20314
20160
  }
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
- });
20161
+ restart() {
20162
+ return this.invoke("container.restart");
20319
20163
  }
20320
20164
  stop() {
20321
- return this.container.stop();
20322
- }
20323
- restart() {
20324
- return this.container.restart();
20165
+ return this.invoke("container.stop");
20325
20166
  }
20326
20167
  invoke(action, data = {}, options = {}) {
20327
20168
  if (this.restInvoker !== null) {
@@ -20338,9 +20179,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20338
20179
  }
20339
20180
  return this.realtimeSocket().send(action, data || {});
20340
20181
  }
20341
- ping() {
20342
- return this.invoke("ping");
20343
- }
20344
20182
  listen(event, handler) {
20345
20183
  const disposable = this.emitter.listen(event, handler);
20346
20184
  this.disposables.push(disposable);
@@ -20355,9 +20193,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20355
20193
  connected() {
20356
20194
  return this.waitForSocketConnection({ rejectOnClose: true });
20357
20195
  }
20358
- whenConnected() {
20359
- return this.waitForSocketConnection({ rejectOnClose: false });
20360
- }
20361
20196
  waitForSocketConnection(options) {
20362
20197
  const socket = this.realtimeSocket();
20363
20198
  const terminalError = socket.getTerminalError();
@@ -20429,7 +20264,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20429
20264
  }
20430
20265
  restInitialization() {
20431
20266
  if (this.restInvoker === null) {
20432
- throw new UnsupportedRuntimeTransportError("This operation requires the REST transport.");
20267
+ throw new PHPSandboxError("This operation requires the REST transport.");
20433
20268
  }
20434
20269
  if (__privateGet(this, _initPromise) === null) {
20435
20270
  __privateSet(this, _initPromise, this.restInvoker.ready().then((result) => {
@@ -20442,15 +20277,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20442
20277
  }
20443
20278
  return __privateGet(this, _initPromise);
20444
20279
  }
20445
- update(input) {
20446
- return this.client.notebook.update(this.data.id, input);
20447
- }
20448
20280
  onDidInitialize(handler) {
20449
20281
  return this.listen("notebook.initialized", handler);
20450
20282
  }
20451
20283
  async reconnect() {
20452
20284
  const socket = this.realtimeSocket();
20453
- const whenConnected = this.whenConnected();
20285
+ const whenConnected = this.waitForSocketConnection({ rejectOnClose: false });
20454
20286
  socket.reconnect();
20455
20287
  this.initialized = false;
20456
20288
  await whenConnected;
@@ -20459,7 +20291,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20459
20291
  }
20460
20292
  realtimeSocket() {
20461
20293
  if (this.socket === null) {
20462
- throw new UnsupportedRuntimeTransportError("This operation requires the realtime transport.");
20294
+ throw new PHPSandboxError("This operation requires the realtime transport.");
20463
20295
  }
20464
20296
  return this.socket;
20465
20297
  }
@@ -20473,7 +20305,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20473
20305
  initializationListener.dispose();
20474
20306
  this.initialized = result;
20475
20307
  if (result.type === "error") {
20476
- reject(new NotebookInitError(result.message, result.data));
20308
+ reject(new RemoteError(result.message, {
20309
+ source: "runtime",
20310
+ status: 503,
20311
+ code: "NotebookInitializationFailed",
20312
+ details: result.data
20313
+ }));
20477
20314
  return;
20478
20315
  }
20479
20316
  resolve(result);
@@ -20488,34 +20325,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20488
20325
  });
20489
20326
  return __privateGet(this, _initPromise);
20490
20327
  };
20328
+ var NotebookInstance = _NotebookInstance;
20491
20329
  var NotebookSecrets = class {
20492
20330
  constructor(client, notebookId) {
20493
20331
  this.client = client;
20494
20332
  this.notebookId = notebookId;
20495
20333
  }
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);
20334
+ async list(options) {
20335
+ const params = new URLSearchParams();
20336
+ if (options?.environment) params.set("environment", options.environment);
20337
+ const query = params.toString();
20338
+ const response = await this.client.get(
20339
+ `/notebook/${this.notebookId}/secrets${query ? `?${query}` : ""}`
20340
+ );
20341
+ return response.data;
20507
20342
  }
20508
- };
20509
- var ComposerCredentials = class {
20510
- constructor(client, notebookId) {
20511
- this.client = client;
20512
- this.notebookId = notebookId;
20343
+ async set(name, input) {
20344
+ const payload = typeof input === "string" ? { name, value: input } : { name, ...input };
20345
+ const response = await this.client.put(`/notebook/${this.notebookId}/secrets`, payload);
20346
+ return response.data;
20513
20347
  }
20514
- set(input) {
20515
- return this.client.notebook.composerCredentials.set(this.notebookId, input);
20348
+ async setMany(input) {
20349
+ const response = await this.client.put(`/notebook/${this.notebookId}/secrets`, {
20350
+ secrets: normalizeNotebookSecretInputs(input)
20351
+ });
20352
+ return response.data;
20516
20353
  }
20517
- remove(type, url2) {
20518
- return this.client.notebook.composerCredentials.remove(this.notebookId, type, url2);
20354
+ async delete(name, options) {
20355
+ const params = new URLSearchParams();
20356
+ if (options?.environment) params.set("environment", options.environment);
20357
+ const query = params.toString();
20358
+ await this.client.delete(
20359
+ `/notebook/${this.notebookId}/secrets/${encodeURIComponent(name)}${query ? `?${query}` : ""}`
20360
+ );
20519
20361
  }
20520
20362
  };
20521
20363
  var NotebookPreview = class {
@@ -20523,20 +20365,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20523
20365
  this.client = client;
20524
20366
  this.notebookId = notebookId;
20525
20367
  }
20526
- get(url2) {
20527
- return this.client.notebook.preview.get(this.notebookId, url2);
20368
+ async get(url2) {
20369
+ const query = url2 === void 0 ? "" : `?${new URLSearchParams({ url: url2 }).toString()}`;
20370
+ const response = await this.client.get(`/notebook/${this.notebookId}/preview${query}`);
20371
+ return response.data;
20528
20372
  }
20529
- setPassword(input) {
20530
- return this.client.notebook.preview.setPassword(this.notebookId, input);
20373
+ async setPassword(input) {
20374
+ const response = await this.client.put(`/notebook/${this.notebookId}/preview`, input);
20375
+ return response.data;
20531
20376
  }
20532
- disable() {
20533
- return this.client.notebook.preview.disable(this.notebookId);
20377
+ async disable() {
20378
+ await this.client.delete(`/notebook/${this.notebookId}/preview`);
20534
20379
  }
20535
- createSession(input) {
20536
- return this.client.notebook.preview.createSession(this.notebookId, input);
20380
+ async createSession(input) {
20381
+ const response = await this.client.post(
20382
+ `/notebook/${this.notebookId}/preview/session`,
20383
+ input
20384
+ );
20385
+ return response.data;
20537
20386
  }
20538
- createHandoff(input) {
20539
- return this.client.notebook.preview.createHandoff(this.notebookId, input);
20387
+ async createHandoff(input) {
20388
+ const response = await this.client.post(
20389
+ `/notebook/${this.notebookId}/preview/handoff`,
20390
+ input
20391
+ );
20392
+ return response.data;
20540
20393
  }
20541
20394
  };
20542
20395
  var NotebookMail = class {
@@ -20544,23 +20397,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20544
20397
  this.client = client;
20545
20398
  this.notebookId = notebookId;
20546
20399
  }
20547
- status() {
20548
- return this.client.notebook.mail.status(this.notebookId);
20400
+ async status() {
20401
+ const response = await this.client.get(`/notebook/${this.notebookId}/mail`);
20402
+ return response.data;
20549
20403
  }
20550
- enable() {
20551
- return this.client.notebook.mail.enable(this.notebookId);
20404
+ async enable() {
20405
+ const response = await this.client.put(`/notebook/${this.notebookId}/mail`);
20406
+ return response.data;
20552
20407
  }
20553
- disable() {
20554
- return this.client.notebook.mail.disable(this.notebookId);
20408
+ async disable() {
20409
+ await this.client.delete(`/notebook/${this.notebookId}/mail`);
20555
20410
  }
20556
- list(options = {}) {
20557
- return this.client.notebook.mail.list(this.notebookId, options);
20411
+ async list(options = {}) {
20412
+ return this.client.get(
20413
+ `/notebook/${this.notebookId}/mails${formatQueryString(options)}`
20414
+ );
20558
20415
  }
20559
- get(hash2) {
20560
- return this.client.notebook.mail.get(this.notebookId, hash2);
20416
+ async get(hash2) {
20417
+ const response = await this.client.get(
20418
+ `/notebook/${this.notebookId}/mails/${encodeURIComponent(hash2)}`
20419
+ );
20420
+ return response.data;
20561
20421
  }
20562
- delete(hash2) {
20563
- return this.client.notebook.mail.delete(this.notebookId, hash2);
20422
+ async delete(hash2) {
20423
+ await this.client.delete(`/notebook/${this.notebookId}/mails/${encodeURIComponent(hash2)}`);
20564
20424
  }
20565
20425
  };
20566
20426
  function formatQueryString(params) {