@hakimedes/dsh-easyremote 0.2.0

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/android.js +50 -0
  4. package/dist/android.js.map +1 -0
  5. package/dist/autostart.js +104 -0
  6. package/dist/autostart.js.map +1 -0
  7. package/dist/cli-views.js +32 -0
  8. package/dist/cli-views.js.map +1 -0
  9. package/dist/cli.js +584 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/cloudflared.js +54 -0
  12. package/dist/cloudflared.js.map +1 -0
  13. package/dist/command-router.js +12 -0
  14. package/dist/command-router.js.map +1 -0
  15. package/dist/connector-install.js +42 -0
  16. package/dist/connector-install.js.map +1 -0
  17. package/dist/controller.js +206 -0
  18. package/dist/controller.js.map +1 -0
  19. package/dist/doctor.js +46 -0
  20. package/dist/doctor.js.map +1 -0
  21. package/dist/domain.js +33 -0
  22. package/dist/domain.js.map +1 -0
  23. package/dist/download.js +59 -0
  24. package/dist/download.js.map +1 -0
  25. package/dist/index.js +16 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/install-state.js +48 -0
  28. package/dist/install-state.js.map +1 -0
  29. package/dist/local-runtime.js +115 -0
  30. package/dist/local-runtime.js.map +1 -0
  31. package/dist/maintenance.js +58 -0
  32. package/dist/maintenance.js.map +1 -0
  33. package/dist/named-tunnel.js +49 -0
  34. package/dist/named-tunnel.js.map +1 -0
  35. package/dist/runtime.js +110 -0
  36. package/dist/runtime.js.map +1 -0
  37. package/dist/setup-progress.js +23 -0
  38. package/dist/setup-progress.js.map +1 -0
  39. package/dist/supervisor.js +81 -0
  40. package/dist/supervisor.js.map +1 -0
  41. package/dist/wizard.js +251 -0
  42. package/dist/wizard.js.map +1 -0
  43. package/package.json +56 -0
  44. package/runtime/connector/README.md +52 -0
  45. package/runtime/connector/cordis.patch.yml +3 -0
  46. package/runtime/connector/dsh.plugin.json +16 -0
  47. package/runtime/connector/lib/client.js +262 -0
  48. package/runtime/connector/lib/command-cache.d.ts +7 -0
  49. package/runtime/connector/lib/command-cache.js +37 -0
  50. package/runtime/connector/lib/command-cache.js.map +1 -0
  51. package/runtime/connector/lib/connector-config.d.ts +20 -0
  52. package/runtime/connector/lib/connector-config.js +74 -0
  53. package/runtime/connector/lib/connector-config.js.map +1 -0
  54. package/runtime/connector/lib/dsh-api.d.ts +38 -0
  55. package/runtime/connector/lib/dsh-api.js +76 -0
  56. package/runtime/connector/lib/dsh-api.js.map +1 -0
  57. package/runtime/connector/lib/index.d.ts +4 -0
  58. package/runtime/connector/lib/index.js +913 -0
  59. package/runtime/connector/lib/index.js.map +1 -0
  60. package/runtime/connector/lib/protocol.d.ts +15 -0
  61. package/runtime/connector/lib/protocol.js +96 -0
  62. package/runtime/connector/lib/protocol.js.map +1 -0
  63. package/runtime/connector/package.json +44 -0
  64. package/runtime/hub/database.js +239 -0
  65. package/runtime/hub/database.js.map +1 -0
  66. package/runtime/hub/index.js +1804 -0
  67. package/runtime/hub/index.js.map +1 -0
  68. package/runtime/hub/schema.js +111 -0
  69. package/runtime/hub/schema.js.map +1 -0
@@ -0,0 +1,115 @@
1
+ import { createServer } from 'node:net';
2
+ import { createHash } from 'node:crypto';
3
+ import { spawn } from 'node:child_process';
4
+ import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { artifactFor, CLOUDFLARED_VERSION } from './cloudflared.js';
7
+ import { installCloudflaredArtifact } from './download.js';
8
+ export async function findAvailablePort(preferred = 8787, probe = isLoopbackPortFree) {
9
+ for (let offset = 0; offset < 100; offset += 1) {
10
+ const port = preferred + offset;
11
+ if (port > 65_535)
12
+ break;
13
+ if (await probe(port))
14
+ return port;
15
+ }
16
+ throw new Error(`No free loopback port found from ${preferred}`);
17
+ }
18
+ export async function ensureCloudflaredRuntime(paths, options = {}) {
19
+ const platform = options.platform ?? process.platform;
20
+ const arch = options.arch ?? process.arch;
21
+ const artifact = artifactFor(platform, arch);
22
+ const expected = {
23
+ version: CLOUDFLARED_VERSION,
24
+ platform,
25
+ arch,
26
+ artifact: artifact.name,
27
+ sha256: artifact.sha256,
28
+ };
29
+ if (inspectCloudflaredRuntime(paths, { platform, arch }).ok)
30
+ return;
31
+ mkdirSync(paths.cloudflaredDir, { recursive: true, mode: 0o700 });
32
+ await (options.installer ?? installCloudflaredArtifact)({ artifact, destination: paths.cloudflaredExecutable });
33
+ writeFileSync(paths.cloudflaredManifest, `${JSON.stringify({
34
+ ...expected,
35
+ executableSha256: fileSha256(paths.cloudflaredExecutable),
36
+ }, null, 2)}\n`, { mode: 0o600 });
37
+ }
38
+ export function inspectCloudflaredRuntime(paths, options = {}) {
39
+ if (!existsSync(paths.cloudflaredExecutable) || !existsSync(paths.cloudflaredManifest)) {
40
+ return { ok: false, detail: 'cloudflared is not installed' };
41
+ }
42
+ try {
43
+ const platform = options.platform ?? process.platform;
44
+ const arch = options.arch ?? process.arch;
45
+ const artifact = artifactFor(platform, arch);
46
+ const manifest = JSON.parse(readFileSync(paths.cloudflaredManifest, 'utf8'));
47
+ const metadataMatches = manifest.version === CLOUDFLARED_VERSION
48
+ && manifest.platform === platform
49
+ && manifest.arch === arch
50
+ && manifest.artifact === artifact.name
51
+ && manifest.sha256 === artifact.sha256;
52
+ const executableHash = fileSha256(paths.cloudflaredExecutable);
53
+ const hashMatches = typeof manifest.executableSha256 === 'string'
54
+ && manifest.executableSha256 === executableHash;
55
+ return {
56
+ ok: metadataMatches && hashMatches,
57
+ detail: metadataMatches && hashMatches
58
+ ? `verified cloudflared ${CLOUDFLARED_VERSION}`
59
+ : 'cloudflared metadata or executable checksum mismatch',
60
+ };
61
+ }
62
+ catch (error) {
63
+ return { ok: false, detail: error instanceof Error ? error.message : String(error) };
64
+ }
65
+ }
66
+ function fileSha256(path) {
67
+ return createHash('sha256').update(readFileSync(path)).digest('hex');
68
+ }
69
+ export function spawnLoggedProcess(paths, launch, role, mirrorOutput = true) {
70
+ mkdirSync(paths.logsDir, { recursive: true, mode: 0o700 });
71
+ const log = createWriteStream(join(paths.logsDir, `${role}.log`), { flags: 'a', mode: 0o600 });
72
+ const child = spawn(launch.command, launch.args, {
73
+ env: launch.env ?? process.env,
74
+ stdio: ['ignore', 'pipe', 'pipe'],
75
+ windowsHide: true,
76
+ });
77
+ child.stdout?.pipe(log, { end: false });
78
+ child.stderr?.pipe(log, { end: false });
79
+ if (mirrorOutput) {
80
+ child.stdout?.pipe(process.stdout, { end: false });
81
+ child.stderr?.pipe(process.stderr, { end: false });
82
+ }
83
+ child.once('close', () => log.end());
84
+ return child;
85
+ }
86
+ export function runProcessLaunch(launch, interactive = false) {
87
+ return new Promise((resolve, reject) => {
88
+ const child = spawn(launch.command, launch.args, {
89
+ env: launch.env ?? process.env,
90
+ stdio: interactive ? 'inherit' : ['ignore', 'pipe', 'pipe'],
91
+ windowsHide: true,
92
+ });
93
+ const errors = [];
94
+ if (!interactive)
95
+ child.stderr?.on('data', (chunk) => errors.push(chunk));
96
+ child.once('error', reject);
97
+ child.once('close', (code) => {
98
+ if (code === 0)
99
+ resolve();
100
+ else
101
+ reject(new Error(`Command failed (${code ?? 'signal'}): ${Buffer.concat(errors).toString('utf8').trim()}`));
102
+ });
103
+ });
104
+ }
105
+ function isLoopbackPortFree(port) {
106
+ return new Promise((resolve) => {
107
+ const server = createServer();
108
+ server.unref();
109
+ server.once('error', () => resolve(false));
110
+ server.listen({ host: '127.0.0.1', port, exclusive: true }, () => {
111
+ server.close(() => resolve(true));
112
+ });
113
+ });
114
+ }
115
+ //# sourceMappingURL=local-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-runtime.js","sourceRoot":"","sources":["../src/local-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { backup, DatabaseSync } from 'node:sqlite';
2
+ import { chmodSync, copyFileSync, existsSync, mkdirSync, renameSync, writeFileSync, } from 'node:fs';
3
+ import { basename, join } from 'node:path';
4
+ const SAFE_METADATA = [
5
+ 'installState',
6
+ 'connectorConfig',
7
+ 'publicEntry',
8
+ 'setupProgress',
9
+ 'namedConfig',
10
+ 'cloudflaredManifest',
11
+ ];
12
+ export async function createBackup(paths, destination) {
13
+ if (!existsSync(paths.database))
14
+ throw new Error('Hub database does not exist');
15
+ const backupDirectory = destination ?? join(paths.backupsDir, new Date().toISOString().replaceAll(':', '-'));
16
+ mkdirSync(backupDirectory, { recursive: true, mode: 0o700 });
17
+ const database = new DatabaseSync(paths.database, { readOnly: true });
18
+ try {
19
+ await backup(database, join(backupDirectory, 'hub.sqlite'));
20
+ }
21
+ finally {
22
+ database.close();
23
+ }
24
+ for (const key of SAFE_METADATA) {
25
+ const source = paths[key];
26
+ if (existsSync(source))
27
+ copyFileSecure(source, join(backupDirectory, basename(source)));
28
+ }
29
+ writeFileSync(join(backupDirectory, 'backup.json'), `${JSON.stringify({
30
+ schemaVersion: 1,
31
+ createdAt: new Date().toISOString(),
32
+ includesSecrets: false,
33
+ }, null, 2)}\n`, { mode: 0o600 });
34
+ return backupDirectory;
35
+ }
36
+ export async function restoreBackup(paths, source, options) {
37
+ if (options.isRunning())
38
+ throw new Error('Stop DSH EasyRemote before restoring a backup');
39
+ const sourcePaths = [join(source, 'hub.sqlite'), join(source, 'data', 'hub.sqlite')];
40
+ const sourceDatabase = sourcePaths.find(existsSync);
41
+ if (!sourceDatabase)
42
+ throw new Error('Backup does not contain hub.sqlite');
43
+ mkdirSync(paths.dataDir, { recursive: true, mode: 0o700 });
44
+ const temporaryDatabase = `${paths.database}.restore-${process.pid}`;
45
+ copyFileSecure(sourceDatabase, temporaryDatabase);
46
+ renameSync(temporaryDatabase, paths.database);
47
+ if (process.platform !== 'win32')
48
+ chmodSync(paths.database, 0o600);
49
+ const installState = join(source, 'install.json');
50
+ if (existsSync(installState))
51
+ copyFileSecure(installState, paths.installState);
52
+ }
53
+ function copyFileSecure(source, destination) {
54
+ copyFileSync(source, destination);
55
+ if (process.platform !== 'win32')
56
+ chmodSync(destination, 0o600);
57
+ }
58
+ //# sourceMappingURL=maintenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../src/maintenance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ export function buildLoginLaunch(executable) {
3
+ return { command: executable, args: ['tunnel', 'login'] };
4
+ }
5
+ export function buildCreateTunnelLaunch(executable, originCertificate, credentialsFile, tunnelName) {
6
+ return {
7
+ command: executable,
8
+ args: [
9
+ 'tunnel', '--origincert', originCertificate, '--credentials-file', credentialsFile,
10
+ 'create', tunnelName,
11
+ ],
12
+ };
13
+ }
14
+ export function buildDnsRouteLaunch(executable, originCertificate, tunnelId, hostname) {
15
+ return {
16
+ command: executable,
17
+ args: ['tunnel', '--origincert', originCertificate, 'route', 'dns', tunnelId, hostname],
18
+ };
19
+ }
20
+ export function readTunnelCredentials(credentialsFile) {
21
+ let value;
22
+ try {
23
+ value = JSON.parse(readFileSync(credentialsFile, 'utf8'));
24
+ }
25
+ catch (error) {
26
+ throw new Error(`Tunnel credentials are not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
27
+ }
28
+ if (!value || typeof value !== 'object' || Array.isArray(value)
29
+ || typeof value.TunnelID !== 'string') {
30
+ throw new Error('Tunnel credentials do not contain TunnelID');
31
+ }
32
+ return { tunnelId: value.TunnelID, credentialsFile };
33
+ }
34
+ export async function provisionNamedTunnel(options) {
35
+ const exists = options.exists ?? existsSync;
36
+ if (!exists(options.originCertificate)) {
37
+ await options.run(buildLoginLaunch(options.executable), true);
38
+ if (!existsSync(options.originCertificate)) {
39
+ throw new Error('Cloudflare authorization completed without creating cert.pem');
40
+ }
41
+ }
42
+ if (!exists(options.credentialsFile)) {
43
+ await options.run(buildCreateTunnelLaunch(options.executable, options.originCertificate, options.credentialsFile, options.tunnelName));
44
+ }
45
+ const credentials = readTunnelCredentials(options.credentialsFile);
46
+ await options.run(buildDnsRouteLaunch(options.executable, options.originCertificate, credentials.tunnelId, options.hostname));
47
+ return credentials;
48
+ }
49
+ //# sourceMappingURL=named-tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"named-tunnel.js","sourceRoot":"","sources":["../src/named-tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAInD,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,iBAAyB,EACzB,eAAuB,EACvB,UAAkB;IAElB,OAAO;QACL,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE;YACJ,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe;YAClF,QAAQ,EAAE,UAAU;SACrB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,iBAAyB,EACzB,QAAgB,EAChB,QAAgB;IAEhB,OAAO;QACL,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC;KACxF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,eAAuB;IAC3D,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;WAC1D,OAAQ,KAAiC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,QAAQ,EAAG,KAA8B,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC;AACjF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAQ1C;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,CAAC,GAAG,CAAC,uBAAuB,CACvC,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,iBAAiB,EACzB,OAAO,CAAC,eAAe,EACvB,OAAO,CAAC,UAAU,CACnB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACnE,MAAM,OAAO,CAAC,GAAG,CAAC,mBAAmB,CACnC,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,iBAAiB,EACzB,WAAW,CAAC,QAAQ,EACpB,OAAO,CAAC,QAAQ,CACjB,CAAC,CAAC;IACH,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { chmodSync, mkdirSync, renameSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ export function createRuntimePaths(root) {
5
+ const cloudflaredDir = join(root, 'cloudflared');
6
+ const dataDir = join(root, 'data');
7
+ const secretsDir = join(root, 'secrets');
8
+ const runDir = join(root, 'run');
9
+ return {
10
+ root,
11
+ installState: join(root, 'install.json'),
12
+ setupProgress: join(root, 'setup.json'),
13
+ connectorConfig: join(root, 'connector.json'),
14
+ publicEntry: join(root, 'public-origin.json'),
15
+ dataDir,
16
+ database: join(dataDir, 'hub.sqlite'),
17
+ secretsDir,
18
+ jwtSecret: join(secretsDir, 'jwt-secret'),
19
+ cloudflaredDir,
20
+ cloudflaredExecutable: join(cloudflaredDir, process.platform === 'win32' ? 'cloudflared.exe' : 'cloudflared'),
21
+ cloudflaredManifest: join(cloudflaredDir, 'install.json'),
22
+ quickConfig: join(cloudflaredDir, 'quick.yml'),
23
+ namedConfig: join(cloudflaredDir, 'named.yml'),
24
+ logsDir: join(root, 'logs'),
25
+ runDir,
26
+ hubPid: join(runDir, 'hub.pid'),
27
+ tunnelPid: join(runDir, 'tunnel.pid'),
28
+ backupsDir: join(root, 'backups'),
29
+ packagesDir: join(root, 'packages'),
30
+ serviceDir: join(root, 'service'),
31
+ };
32
+ }
33
+ export function buildHubLaunch(paths, port, jwtSecret, hubScript) {
34
+ return {
35
+ command: process.execPath,
36
+ args: [hubScript],
37
+ env: {
38
+ ...process.env,
39
+ HOST: '127.0.0.1',
40
+ PORT: String(port),
41
+ DATABASE_PATH: paths.database,
42
+ HUB_ENTRY_FILE: paths.publicEntry,
43
+ HUB_ENTRY: `http://127.0.0.1:${port}`,
44
+ JWT_SECRET: jwtSecret,
45
+ NODE_ENV: 'production',
46
+ DSH_EASYREMOTE_VERSION: '0.2.0',
47
+ },
48
+ };
49
+ }
50
+ export function buildQuickTunnelLaunch(paths, hubPort, executable) {
51
+ return {
52
+ command: executable,
53
+ args: [
54
+ 'tunnel', '--config', paths.quickConfig, '--no-autoupdate',
55
+ '--url', `http://127.0.0.1:${hubPort}`, '--loglevel', 'info',
56
+ ],
57
+ };
58
+ }
59
+ export function buildNamedTunnelLaunch(paths, tunnelId, executable) {
60
+ return {
61
+ command: executable,
62
+ args: ['tunnel', '--config', paths.namedConfig, '--no-autoupdate', 'run', tunnelId],
63
+ };
64
+ }
65
+ export function writeConnectorConfig(paths, hubUrl, nodeName, defaultCwd) {
66
+ const parsed = new URL(hubUrl);
67
+ if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')
68
+ throw new Error('Connector Hub URL must use HTTP or HTTPS');
69
+ writeSecureJson(paths.connectorConfig, {
70
+ schemaVersion: 1,
71
+ hubUrl: parsed.origin,
72
+ ...(nodeName?.trim() ? { nodeName: nodeName.trim() } : {}),
73
+ ...(defaultCwd?.trim() ? { defaultCwd: defaultCwd.trim() } : {}),
74
+ });
75
+ }
76
+ export function writePublicEntry(paths, publicOrigin) {
77
+ const parsed = new URL(publicOrigin);
78
+ if (!['http:', 'https:'].includes(parsed.protocol))
79
+ throw new Error('Public origin must use HTTP or HTTPS');
80
+ writeSecureJson(paths.publicEntry, { publicOrigin: parsed.origin });
81
+ }
82
+ export function writeNamedTunnelConfig(paths, options) {
83
+ const yaml = [
84
+ `tunnel: ${JSON.stringify(options.tunnelId)}`,
85
+ `credentials-file: ${JSON.stringify(options.credentialsFile)}`,
86
+ 'ingress:',
87
+ ` - hostname: ${JSON.stringify(options.hostname)}`,
88
+ ` service: http://127.0.0.1:${options.hubPort}`,
89
+ ' - service: http_status:404',
90
+ '',
91
+ ].join('\n');
92
+ writeSecureFile(paths.namedConfig, yaml);
93
+ }
94
+ export function writeQuickTunnelConfig(paths) {
95
+ writeSecureFile(paths.quickConfig, '{}\n');
96
+ }
97
+ function writeSecureJson(path, value) {
98
+ writeSecureFile(path, `${JSON.stringify(value, null, 2)}\n`);
99
+ }
100
+ function writeSecureFile(path, value) {
101
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
102
+ const temporaryPath = `${path}.${randomUUID()}.tmp`;
103
+ writeFileSync(temporaryPath, value, { mode: 0o600 });
104
+ if (process.platform !== 'win32')
105
+ chmodSync(temporaryPath, 0o600);
106
+ renameSync(temporaryPath, path);
107
+ if (process.platform !== 'win32')
108
+ chmodSync(path, 0o600);
109
+ }
110
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ export function loadSetupProgress(path) {
5
+ if (!existsSync(path))
6
+ return null;
7
+ const value = JSON.parse(readFileSync(path, 'utf8'));
8
+ if (value.schemaVersion !== 1 || typeof value.phase !== 'string' || typeof value.updatedAt !== 'number') {
9
+ throw new Error('Invalid setup progress');
10
+ }
11
+ return value;
12
+ }
13
+ export function saveSetupProgress(path, progress) {
14
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
15
+ const temporaryPath = `${path}.${randomUUID()}.tmp`;
16
+ writeFileSync(temporaryPath, `${JSON.stringify(progress, null, 2)}\n`, { mode: 0o600 });
17
+ if (process.platform !== 'win32')
18
+ chmodSync(temporaryPath, 0o600);
19
+ renameSync(temporaryPath, path);
20
+ if (process.platform !== 'win32')
21
+ chmodSync(path, 0o600);
22
+ }
23
+ //# sourceMappingURL=setup-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-progress.js","sourceRoot":"","sources":["../src/setup-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAkB,CAAC;IACtE,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxG,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,QAAuB;IACrE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;IACpD,aAAa,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAClE,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { parseQuickTunnelOrigin } from './cloudflared.js';
2
+ export async function waitForHubMeta(origin, options = {}) {
3
+ const fetcher = options.fetcher ?? fetch;
4
+ const timeoutMs = options.timeoutMs ?? 15_000;
5
+ const retryMs = options.retryMs ?? 150;
6
+ const deadline = Date.now() + timeoutMs;
7
+ let lastError;
8
+ while (Date.now() <= deadline) {
9
+ try {
10
+ const response = await fetcher(`${origin}/v1/meta`);
11
+ if (!response.ok)
12
+ throw new Error(`Hub returned HTTP ${response.status}`);
13
+ const value = await response.json();
14
+ if (!value || typeof value.hubId !== 'string' || typeof value.publicOrigin !== 'string') {
15
+ throw new Error('Hub returned invalid metadata');
16
+ }
17
+ return value;
18
+ }
19
+ catch (error) {
20
+ lastError = error;
21
+ await new Promise((resolve) => setTimeout(resolve, retryMs));
22
+ }
23
+ }
24
+ throw new Error(`Local Hub did not become ready: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
25
+ }
26
+ export function waitForQuickOrigin(child, timeoutMs = 30_000) {
27
+ return new Promise((resolve, reject) => {
28
+ let settled = false;
29
+ const streams = [child.stdout, child.stderr].filter((stream) => Boolean(stream));
30
+ const cleanup = () => {
31
+ clearTimeout(timer);
32
+ for (const stream of streams)
33
+ stream.off('data', onData);
34
+ };
35
+ const finish = (error, value) => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ cleanup();
40
+ if (error)
41
+ reject(error);
42
+ else
43
+ resolve(value);
44
+ };
45
+ const onData = (chunk) => {
46
+ const origin = parseQuickTunnelOrigin(String(chunk));
47
+ if (origin)
48
+ finish(null, origin);
49
+ };
50
+ const timer = setTimeout(() => finish(new Error('Timed out waiting for Quick Tunnel URL')), timeoutMs);
51
+ for (const stream of streams)
52
+ stream.on('data', onData);
53
+ child.once?.('error', (error) => finish(error));
54
+ child.once?.('close', (code) => {
55
+ if (!settled)
56
+ finish(new Error(`cloudflared exited before publishing a URL (${code ?? 'signal'})`));
57
+ });
58
+ });
59
+ }
60
+ export function stopManagedChild(child, timeoutMs = 5_000) {
61
+ if (child.exitCode != null || child.signalCode != null)
62
+ return Promise.resolve();
63
+ return new Promise((resolve) => {
64
+ let done = false;
65
+ const finish = () => {
66
+ if (done)
67
+ return;
68
+ done = true;
69
+ clearTimeout(timer);
70
+ resolve();
71
+ };
72
+ child.once('close', finish);
73
+ child.kill('SIGTERM');
74
+ const timer = setTimeout(() => {
75
+ if (child.exitCode == null && child.signalCode == null)
76
+ child.kill('SIGKILL');
77
+ finish();
78
+ }, timeoutMs);
79
+ });
80
+ }
81
+ //# sourceMappingURL=supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}