@phpsandbox/sdk 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +7 -18
- package/dist/browser/phpsandbox-sdk.esm.js +7 -3
- package/dist/browser/phpsandbox-sdk.esm.min.js +7 -7
- package/dist/browser/phpsandbox-sdk.iife.js +7 -3
- package/dist/browser/phpsandbox-sdk.iife.min.js +7 -7
- package/dist/index.d.ts +21 -5
- package/dist/index.js +5 -2
- package/dist/{integrations.d.ts → integrations/account.d.ts} +1 -1
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +2 -0
- package/dist/{sandbox-integrations.d.ts → integrations/sandbox.d.ts} +2 -2
- package/dist/{sandbox-integrations.js → integrations/sandbox.js} +1 -1
- package/dist/log.d.ts +1 -1
- package/dist/log.js +1 -1
- package/dist/metrics.d.ts +1 -1
- package/dist/metrics.js +1 -1
- package/dist/ports.d.ts +1 -1
- package/dist/ports.js +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/package.json +5 -9
- package/docs/api-summary.md +0 -181
- package/docs/cdn-usage.md +0 -68
- package/docs/getting-started.md +0 -169
- package/examples/README.md +0 -203
- package/examples/basic.ts +0 -15
- package/examples/get.ts +0 -22
- package/examples/git-merge-smoke.ts +0 -395
- package/examples/laravel-load-test.ts +0 -2800
- package/examples/notebook-readonly-smoke.ts +0 -806
- package/examples/publication-provider-label.ts +0 -11
- package/examples/publish-cloudflare-container.ts +0 -65
- package/examples/publish-laravel-cloud.ts +0 -123
- package/examples/publish-ssh-agent.ts +0 -211
- /package/dist/{integrations.js → integrations/account.js} +0 -0
- /package/dist/{runtime-telemetry.d.ts → telemetry.d.ts} +0 -0
- /package/dist/{runtime-telemetry.js → telemetry.js} +0 -0
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { PublicationProviderName } from '@phpsandbox/sdk';
|
|
2
|
-
|
|
3
|
-
const publicationProviderLabels: Record<PublicationProviderName, string> = {
|
|
4
|
-
'cloudflare-containers': 'Cloudflare Containers',
|
|
5
|
-
'ssh-server': 'SSH Server',
|
|
6
|
-
'laravel-cloud': 'Laravel Cloud',
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export function publicationProviderLabel(provider: PublicationProviderName): string {
|
|
10
|
-
return publicationProviderLabels[provider] ?? provider;
|
|
11
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { PHPSandbox } from '@phpsandbox/sdk';
|
|
2
|
-
import { publicationProviderLabel } from './publication-provider-label.js';
|
|
3
|
-
|
|
4
|
-
const token = process.env.PHPSANDBOX_TOKEN;
|
|
5
|
-
if (!token) {
|
|
6
|
-
throw new Error('Missing PHPSANDBOX_TOKEN');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const notebookId = process.env.PHPSANDBOX_NOTEBOOK_ID;
|
|
10
|
-
if (!notebookId) {
|
|
11
|
-
throw new Error('Missing PHPSANDBOX_NOTEBOOK_ID');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const slug = process.env.PHPSANDBOX_PUBLISH_SLUG ?? `sdk-cloudflare-${Date.now().toString(36)}`;
|
|
15
|
-
const apiUrl = process.env.PHPSANDBOX_API_URL;
|
|
16
|
-
const cloudflareAccountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
17
|
-
const cloudflareApiToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
18
|
-
if (!cloudflareAccountId || !cloudflareApiToken) {
|
|
19
|
-
throw new Error('Missing CLOUDFLARE_ACCOUNT_ID or CLOUDFLARE_API_TOKEN');
|
|
20
|
-
}
|
|
21
|
-
const client = PHPSandbox.realtime(token, apiUrl);
|
|
22
|
-
const notebook = await client.notebook.get(notebookId);
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const existingIntegration = (await client.integrations.list()).find(({ provider }) => provider === 'cloudflare');
|
|
26
|
-
const integration = existingIntegration
|
|
27
|
-
? await existingIntegration.update({ authorization: { type: 'token', token: cloudflareApiToken } })
|
|
28
|
-
: await client.integrations.link({
|
|
29
|
-
provider: 'cloudflare',
|
|
30
|
-
authorization: { type: 'token', token: cloudflareApiToken },
|
|
31
|
-
});
|
|
32
|
-
await notebook.integrations.attach({ integration });
|
|
33
|
-
|
|
34
|
-
const publication = await notebook.publication();
|
|
35
|
-
if (publication && publication.data.provider.name !== 'cloudflare-containers') {
|
|
36
|
-
throw new Error(`Notebook is already published to ${publicationProviderLabel(publication.data.provider.name)}. Destroy that publication before changing providers.`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const run = publication
|
|
40
|
-
? await publication.publish()
|
|
41
|
-
: await notebook.publish({
|
|
42
|
-
slug,
|
|
43
|
-
provider: {
|
|
44
|
-
name: 'cloudflare-containers',
|
|
45
|
-
accountId: cloudflareAccountId,
|
|
46
|
-
size: 'small',
|
|
47
|
-
sleepAfter: '30m',
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
for await (const event of run.events()) {
|
|
52
|
-
if (event.type === 'phase') {
|
|
53
|
-
console.log('phase:', event.name);
|
|
54
|
-
} else if (event.type === 'log') {
|
|
55
|
-
process.stdout.write(event.content);
|
|
56
|
-
} else if (event.type === 'result') {
|
|
57
|
-
console.log('result:', event);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const current = await run.publication();
|
|
62
|
-
console.log('publication:', current.data.id, current.data.status, current.data.url);
|
|
63
|
-
} finally {
|
|
64
|
-
notebook.dispose();
|
|
65
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { PHPSandbox, type Integration, type LaravelCloudRegion } from '@phpsandbox/sdk';
|
|
2
|
-
import { publicationProviderLabel } from './publication-provider-label.js';
|
|
3
|
-
|
|
4
|
-
const token = process.env.PHPSANDBOX_TOKEN;
|
|
5
|
-
if (!token) {
|
|
6
|
-
throw new Error('Missing PHPSANDBOX_TOKEN');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const notebookId = process.env.PHPSANDBOX_NOTEBOOK_ID;
|
|
10
|
-
if (!notebookId) {
|
|
11
|
-
throw new Error('Missing PHPSANDBOX_NOTEBOOK_ID');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const slug = process.env.PHPSANDBOX_PUBLISH_SLUG ?? `sdk-laravel-cloud-${Date.now().toString(36)}`;
|
|
15
|
-
const region: LaravelCloudRegion = 'eu-central-1';
|
|
16
|
-
const apiUrl = process.env.PHPSANDBOX_API_URL ?? 'https://api.phpsandbox.io/v1';
|
|
17
|
-
|
|
18
|
-
if (new URL(apiUrl).hostname.endsWith('.test') && process.env.NODE_TLS_REJECT_UNAUTHORIZED === undefined) {
|
|
19
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const client = PHPSandbox.realtime(token, apiUrl);
|
|
23
|
-
const notebook = await client.notebook.get(notebookId);
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
const publication = await notebook.publication();
|
|
27
|
-
if (publication && publication.data.provider.name !== 'laravel-cloud') {
|
|
28
|
-
throw new Error(`Notebook is already published to ${publicationProviderLabel(publication.data.provider.name)}. Destroy that publication before changing providers.`);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const run = publication ? await publication.publish() : await publishFirstLaravelCloudPublication();
|
|
32
|
-
|
|
33
|
-
for await (const event of run.events()) {
|
|
34
|
-
if (event.type === 'phase') {
|
|
35
|
-
console.log('phase:', event.name);
|
|
36
|
-
} else if (event.type === 'log') {
|
|
37
|
-
process.stdout.write(`${event.content}\n`);
|
|
38
|
-
} else if (event.type === 'result') {
|
|
39
|
-
console.log('result:', event);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const current = await run.publication();
|
|
44
|
-
console.log('publication:', current.data.id, current.data.status, current.data.url);
|
|
45
|
-
} finally {
|
|
46
|
-
notebook.dispose();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function publishFirstLaravelCloudPublication() {
|
|
50
|
-
const repository = process.env.PHPSANDBOX_LARAVEL_CLOUD_REPOSITORY;
|
|
51
|
-
if (!repository) {
|
|
52
|
-
throw new Error('Missing PHPSANDBOX_LARAVEL_CLOUD_REPOSITORY');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const githubToken = process.env.PHPSANDBOX_GITHUB_TOKEN;
|
|
56
|
-
if (!githubToken) {
|
|
57
|
-
throw new Error('Missing PHPSANDBOX_GITHUB_TOKEN');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const gitAuthorName = process.env.PHPSANDBOX_GIT_AUTHOR_NAME;
|
|
61
|
-
if (!gitAuthorName) {
|
|
62
|
-
throw new Error('Missing PHPSANDBOX_GIT_AUTHOR_NAME');
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const gitAuthorEmail = process.env.PHPSANDBOX_GIT_AUTHOR_EMAIL;
|
|
66
|
-
if (!gitAuthorEmail) {
|
|
67
|
-
throw new Error('Missing PHPSANDBOX_GIT_AUTHOR_EMAIL');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const apiKey = process.env.PHPSANDBOX_LARAVEL_CLOUD_API_KEY;
|
|
71
|
-
if (!apiKey) {
|
|
72
|
-
throw new Error('Missing PHPSANDBOX_LARAVEL_CLOUD_API_KEY');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const existingIntegration = (await client.integrations.list()).find(({ provider }) => provider === 'github');
|
|
76
|
-
const github = existingIntegration
|
|
77
|
-
? await existingIntegration.update({ authorization: { type: 'token', token: githubToken } })
|
|
78
|
-
: await client.integrations.link({
|
|
79
|
-
provider: 'github',
|
|
80
|
-
authorization: { type: 'token', token: githubToken },
|
|
81
|
-
});
|
|
82
|
-
await selectSandboxIntegration(github);
|
|
83
|
-
const target = await notebook.git.targets.create({
|
|
84
|
-
provider: 'github',
|
|
85
|
-
repository,
|
|
86
|
-
author: { name: gitAuthorName, email: gitAuthorEmail },
|
|
87
|
-
branch: 'main',
|
|
88
|
-
setDefault: true,
|
|
89
|
-
});
|
|
90
|
-
const source = await target.sync();
|
|
91
|
-
|
|
92
|
-
console.log('source:', source.data.repository, source.data.branch, source.data.lastCommitSha);
|
|
93
|
-
|
|
94
|
-
const existingLaravelCloudIntegration = (await client.integrations.list())
|
|
95
|
-
.find(({ provider }) => provider === 'laravel-cloud');
|
|
96
|
-
const laravelCloud = existingLaravelCloudIntegration
|
|
97
|
-
? await existingLaravelCloudIntegration.update({ authorization: { type: 'token', token: apiKey } })
|
|
98
|
-
: await client.integrations.link({
|
|
99
|
-
provider: 'laravel-cloud',
|
|
100
|
-
authorization: { type: 'token', token: apiKey },
|
|
101
|
-
});
|
|
102
|
-
await selectSandboxIntegration(laravelCloud);
|
|
103
|
-
|
|
104
|
-
return notebook.publish({
|
|
105
|
-
slug,
|
|
106
|
-
provider: {
|
|
107
|
-
name: 'laravel-cloud',
|
|
108
|
-
region,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function selectSandboxIntegration(integration: Integration): Promise<void> {
|
|
114
|
-
const binding = (await notebook.integrations.list())
|
|
115
|
-
.find((candidate) => candidate.integration.provider === integration.provider);
|
|
116
|
-
|
|
117
|
-
if (binding) {
|
|
118
|
-
await binding.update({ integration });
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
await notebook.integrations.attach({ integration });
|
|
123
|
-
}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
2
|
-
import { existsSync, mkdtempSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { PHPSandbox, type ServerInstance } from '@phpsandbox/sdk';
|
|
7
|
-
import { publicationProviderLabel } from './publication-provider-label.js';
|
|
8
|
-
|
|
9
|
-
const token = process.env.PHPSANDBOX_TOKEN;
|
|
10
|
-
if (!token) {
|
|
11
|
-
throw new Error('Missing PHPSANDBOX_TOKEN');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const notebookId = process.env.PHPSANDBOX_NOTEBOOK_ID;
|
|
15
|
-
if (!notebookId) {
|
|
16
|
-
throw new Error('Missing PHPSANDBOX_NOTEBOOK_ID');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const slug = process.env.PHPSANDBOX_PUBLISH_SLUG ?? `sdk-ssh-${Date.now().toString(36)}`;
|
|
20
|
-
const apiUrl = process.env.PHPSANDBOX_API_URL ?? 'https://api.phpsandbox.io/v1';
|
|
21
|
-
const isLocal = new URL(apiUrl).hostname.endsWith('.test');
|
|
22
|
-
|
|
23
|
-
if (isLocal && process.env.NODE_TLS_REJECT_UNAUTHORIZED === undefined) {
|
|
24
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const client = PHPSandbox.realtime(token, apiUrl);
|
|
28
|
-
const notebook = await client.notebook.get(notebookId);
|
|
29
|
-
let agent: ChildProcessWithoutNullStreams | null = null;
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const publication = await notebook.publication();
|
|
33
|
-
if (publication && publication.data.provider.name !== 'ssh-server') {
|
|
34
|
-
throw new Error(`Notebook is already published to ${publicationProviderLabel(publication.data.provider.name)}. Destroy that publication before changing providers.`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const run = publication
|
|
38
|
-
? await publication.publish()
|
|
39
|
-
: await notebook.publish({
|
|
40
|
-
slug,
|
|
41
|
-
provider: { name: 'ssh-server', serverId: (await resolveServer()).data.id },
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
for await (const event of run.events()) {
|
|
45
|
-
if (event.type === 'phase') {
|
|
46
|
-
console.log('phase:', event.name);
|
|
47
|
-
} else if (event.type === 'log') {
|
|
48
|
-
process.stdout.write(event.content);
|
|
49
|
-
} else if (event.type === 'result') {
|
|
50
|
-
console.log('result:', event);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const current = await run.publication();
|
|
55
|
-
console.log('publication:', current.data.id, current.data.status, current.data.url);
|
|
56
|
-
|
|
57
|
-
if (current.data.url) {
|
|
58
|
-
const response = await fetch(current.data.url);
|
|
59
|
-
console.log('http:', response.status, response.statusText, await response.text());
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(`Publication URL returned ${response.status} ${response.statusText}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
} finally {
|
|
65
|
-
notebook.dispose();
|
|
66
|
-
if (agent) {
|
|
67
|
-
stopLocalAgent(agent);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function resolveServer(): Promise<ServerInstance> {
|
|
72
|
-
const serverId = process.env.PHPSANDBOX_PUBLISH_SERVER_ID;
|
|
73
|
-
if (serverId) {
|
|
74
|
-
const server = await client.servers.get(serverId);
|
|
75
|
-
console.log('server:', server.data.id, server.data.status);
|
|
76
|
-
return server;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const server = await client.servers.create({
|
|
80
|
-
name: `SDK SSH ${slug}`,
|
|
81
|
-
host: process.env.PHPSANDBOX_PUBLISH_SERVER_HOST ?? 'localhost',
|
|
82
|
-
ssh: {
|
|
83
|
-
user: process.env.USER ?? 'local',
|
|
84
|
-
port: Number(process.env.PHPSANDBOX_PUBLISH_SERVER_PORT ?? 22),
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
console.log('server:', server.data.id, server.data.status);
|
|
89
|
-
|
|
90
|
-
if (!isLocal) {
|
|
91
|
-
throw new Error('Created server registration. Install the agent on the target server, then rerun with PHPSANDBOX_PUBLISH_SERVER_ID.');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!server.data.token) {
|
|
95
|
-
throw new Error('Created server registration without an agent token.');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
agent = await startLocalAgent(server.data.id, server.data.token);
|
|
99
|
-
const connected = await server.waitReady({ timeout: 120_000, interval: 1_000 });
|
|
100
|
-
console.log('server:', connected.data.id, connected.data.status);
|
|
101
|
-
|
|
102
|
-
return connected;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function startLocalAgent(serverId: string, serverToken: string): Promise<ChildProcessWithoutNullStreams> {
|
|
106
|
-
const dir = mkdtempSync(join(tmpdir(), 'phpsandbox-sdk-ssh-agent-'));
|
|
107
|
-
const configPath = join(dir, 'agent.yaml');
|
|
108
|
-
const stateDir = join(dir, 'state');
|
|
109
|
-
const controlPlane = process.env.PHPSANDBOX_AGENT_CONTROL_PLANE ?? 'wss://okra-edge.ciroue.test/_okra/agent/connect';
|
|
110
|
-
|
|
111
|
-
writeFileSync(configPath, [
|
|
112
|
-
`server_id: "${serverId}"`,
|
|
113
|
-
`token: "${serverToken}"`,
|
|
114
|
-
`control_plane: "${controlPlane}"`,
|
|
115
|
-
`state_dir: "${stateDir}"`,
|
|
116
|
-
'',
|
|
117
|
-
].join('\n'));
|
|
118
|
-
|
|
119
|
-
const rookDir = process.env.PHPSANDBOX_ROOK_DIR
|
|
120
|
-
?? fileURLToPath(new URL('../../rook/', import.meta.url));
|
|
121
|
-
if (!existsSync(join(rookDir, 'cmd/rook/main.go'))) {
|
|
122
|
-
throw new Error('Cannot find local Rook repo. Set PHPSANDBOX_ROOK_DIR to the rook directory.');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const child = spawn('go', ['run', './cmd/rook', '--config', configPath], {
|
|
126
|
-
cwd: rookDir,
|
|
127
|
-
detached: true,
|
|
128
|
-
env: {
|
|
129
|
-
...process.env,
|
|
130
|
-
SSL_CERT_FILE: localCaCertPath(),
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
process.once('exit', () => stopLocalAgent(child));
|
|
135
|
-
|
|
136
|
-
await waitForAgent(child);
|
|
137
|
-
console.log('agent:', 'connected');
|
|
138
|
-
|
|
139
|
-
return child;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function stopLocalAgent(child: ChildProcessWithoutNullStreams): void {
|
|
143
|
-
if (child.exitCode !== null || child.signalCode !== null) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (child.pid && child.pid > 0) {
|
|
148
|
-
try {
|
|
149
|
-
process.kill(-child.pid, 'SIGTERM');
|
|
150
|
-
return;
|
|
151
|
-
} catch {
|
|
152
|
-
// Fall back to killing the direct child when process group signaling is unavailable.
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
child.kill('SIGTERM');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function waitForAgent(child: ChildProcessWithoutNullStreams): Promise<void> {
|
|
160
|
-
return new Promise((resolve, reject) => {
|
|
161
|
-
let settled = false;
|
|
162
|
-
let output = '';
|
|
163
|
-
const timeout = setTimeout(() => {
|
|
164
|
-
finish(new Error(`Timed out waiting for Rook to connect. ${output.trim()}`));
|
|
165
|
-
}, 120_000);
|
|
166
|
-
|
|
167
|
-
const finish = (error?: Error) => {
|
|
168
|
-
if (settled) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
settled = true;
|
|
172
|
-
clearTimeout(timeout);
|
|
173
|
-
child.stdout.off('data', onStdout);
|
|
174
|
-
child.stderr.off('data', onStderr);
|
|
175
|
-
child.off('exit', onExit);
|
|
176
|
-
if (error) {
|
|
177
|
-
reject(error);
|
|
178
|
-
} else {
|
|
179
|
-
resolve();
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const append = (chunk: Buffer) => {
|
|
184
|
-
output = `${output}${chunk.toString()}`.slice(-4000);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const onStdout = (chunk: Buffer) => {
|
|
188
|
-
append(chunk);
|
|
189
|
-
if (chunk.toString().includes('connected, waiting for commands')) {
|
|
190
|
-
finish();
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
const onStderr = (chunk: Buffer) => append(chunk);
|
|
195
|
-
const onExit = (code: number | null) => {
|
|
196
|
-
finish(new Error(`Rook exited before connecting with code ${code}. ${output.trim()}`));
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
child.stdout.on('data', onStdout);
|
|
200
|
-
child.stderr.on('data', onStderr);
|
|
201
|
-
child.once('exit', onExit);
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function localCaCertPath(): string {
|
|
206
|
-
const configured = process.env.PHPSANDBOX_LOCAL_CA_CERT
|
|
207
|
-
?? process.env.NODE_EXTRA_CA_CERTS
|
|
208
|
-
?? `${process.env.HOME}/.config/valet/CA/LaravelValetCASelfSigned.pem`;
|
|
209
|
-
|
|
210
|
-
return configured.replace(/^"(.*)"$/, '$1');
|
|
211
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|