@zubyjs/share 1.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/index.d.ts +12 -0
- package/index.js +33 -0
- package/package.json +45 -0
- package/tunnel.d.ts +11 -0
- package/tunnel.js +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @zubyjs/share
|
|
2
|
+
|
|
3
|
+
The plugin for Zuby.js that allows you to share your local development/prod
|
|
4
|
+
server with anyone in the world using the Cloudflare [Quick Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/) service.
|
|
5
|
+
This is useful when you want to show your work to someone else,
|
|
6
|
+
or quickly test it on a different device.
|
|
7
|
+
|
|
8
|
+
By using this plugin,
|
|
9
|
+
you agree to the Cloudflare's [Terms of Service](https://www.cloudflare.com/terms/),
|
|
10
|
+
[Privacy Policy](https://www.cloudflare.com/privacypolicy/),
|
|
11
|
+
and [Tunnel License](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/license/).
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
First, install the `@zubyjs/share` package using your favorite package manager.
|
|
16
|
+
If you aren't sure, you can use npm:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @zubyjs/share
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then add the `@zubyjs/share` plugin to your `zuby.config.mjs` file under the `plugins` option:
|
|
23
|
+
|
|
24
|
+
```diff lang="js" title="zuby.config.mjs"
|
|
25
|
+
import { defineConfig } from 'zuby';
|
|
26
|
+
import preact from '@zubyjs/preact';
|
|
27
|
+
+ import share from '@zubyjs/share';
|
|
28
|
+
|
|
29
|
+
export default defineConfig({
|
|
30
|
+
outDir: '.zuby',
|
|
31
|
+
jsx: preact(),
|
|
32
|
+
+ plugins: [
|
|
33
|
+
+ share()
|
|
34
|
+
+ ]
|
|
35
|
+
^^^^^^^^
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
And that's it!
|
|
40
|
+
Now you can run `npx zuby dev` or `npx zuby preview` to start sharing your local server.
|
|
41
|
+
The plugin will expose your local dev/prod server to the internet over a tunnel
|
|
42
|
+
and provide you a unique link that you can share with anyone.
|
|
43
|
+
Once you stop the server, the tunnel will be closed.
|
|
44
|
+
|
|
45
|
+
Example output:
|
|
46
|
+
|
|
47
|
+
```diff lang="json"
|
|
48
|
+
Zuby.js v1.0.58 started in 379ms
|
|
49
|
+
|
|
50
|
+
┃ Mode development
|
|
51
|
+
┃ Local http://127.0.0.1:3000/
|
|
52
|
+
┃ Network use --host and --port to expose
|
|
53
|
+
|
|
54
|
+
┃ Share https://accidents-head-random.trycloudflare.com
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
NOTE: Always make sure that all zuby packages are in sync in your `package.json` file:
|
|
58
|
+
|
|
59
|
+
```diff lang="json"
|
|
60
|
+
{
|
|
61
|
+
"name": "my-zuby-app",
|
|
62
|
+
"version": "1.0.0",
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"zuby": "latest",
|
|
65
|
+
"@zubyjs/share": "latest"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Contributing
|
|
71
|
+
|
|
72
|
+
This package is part of Zuby.js workspace and maintained by the team behind the [Zuby package](https://www.npmjs.com/package/zuby).
|
|
73
|
+
Please refer to it for more details how to contribute.
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ZubyInternalConfig, ZubyPlugin } from 'zuby/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Zuby.js plugin that allows you to easily
|
|
4
|
+
* share your local server with anyone over the internet
|
|
5
|
+
* using Cloudflare Quick Tunnels.
|
|
6
|
+
* @returns ZubyPlugin
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: () => ZubyPlugin;
|
|
9
|
+
export default _default;
|
|
10
|
+
export declare function createTunnel({ config }: {
|
|
11
|
+
config: ZubyInternalConfig;
|
|
12
|
+
}): Promise<void>;
|
package/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { startTunnel } from './tunnel.js';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
/**
|
|
4
|
+
* Zuby.js plugin that allows you to easily
|
|
5
|
+
* share your local server with anyone over the internet
|
|
6
|
+
* using Cloudflare Quick Tunnels.
|
|
7
|
+
* @returns ZubyPlugin
|
|
8
|
+
*/
|
|
9
|
+
export default () => ({
|
|
10
|
+
name: 'zuby-share-plugin',
|
|
11
|
+
description: 'Share your local development server with anyone over the internet',
|
|
12
|
+
hooks: {
|
|
13
|
+
'zuby:dev:start': createTunnel,
|
|
14
|
+
'zuby:preview:start': createTunnel,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
export async function createTunnel({ config }) {
|
|
18
|
+
const { server, customLogger: logger } = config;
|
|
19
|
+
const hostname = server?.host;
|
|
20
|
+
const port = server?.port;
|
|
21
|
+
if (!hostname || !port)
|
|
22
|
+
return;
|
|
23
|
+
const tunnel = await startTunnel({
|
|
24
|
+
hostname,
|
|
25
|
+
port,
|
|
26
|
+
verifyTLS: false,
|
|
27
|
+
});
|
|
28
|
+
if (!tunnel) {
|
|
29
|
+
return logger.error(' ┃ Share: Failed to start the tunnel');
|
|
30
|
+
}
|
|
31
|
+
const tunnelUrl = await tunnel.getURL();
|
|
32
|
+
logger?.info(` ┃ Share ${chalk.gray(tunnelUrl)}\r\n`);
|
|
33
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zubyjs/share",
|
|
3
|
+
"version": "1.0.58",
|
|
4
|
+
"description": "Zuby.js share plugin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"release": "cd ./dist && npm publish --access public && cd ..",
|
|
9
|
+
"bump-version": "npm version patch",
|
|
10
|
+
"build": "rm -rf dist/ stage/ && mkdir dist && tsc && cp -rf package.json README.md stage/share/src/* dist/ && rm -rf stage/",
|
|
11
|
+
"push-build": "npm run build && cd dist && yalc push --force && cd ..",
|
|
12
|
+
"test": "exit 0"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"directory": "dist",
|
|
16
|
+
"linkDirectory": true
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"zuby": "^1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"chalk": "^5.3.0",
|
|
23
|
+
"untun": "0.1.3"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://gitlab.com/futrou/zuby.js/-/issues",
|
|
27
|
+
"email": "zuby@futrou.com"
|
|
28
|
+
},
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://gitlab.com/futrou/zuby.js.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://zubyjs.com",
|
|
35
|
+
"keywords": [
|
|
36
|
+
"zuby-plugin",
|
|
37
|
+
"zuby",
|
|
38
|
+
"share",
|
|
39
|
+
"tunnel",
|
|
40
|
+
"cloudflare"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/tunnel.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TunnelOptions {
|
|
2
|
+
port?: number | string;
|
|
3
|
+
hostname?: string;
|
|
4
|
+
protocol?: 'http' | 'https';
|
|
5
|
+
verifyTLS?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface Tunnel {
|
|
8
|
+
getURL: () => Promise<string>;
|
|
9
|
+
close: () => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare function startTunnel(opts: TunnelOptions): Promise<undefined | Tunnel>;
|
package/tunnel.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { normalizePath } from 'zuby/utils/pathUtils.js';
|
|
5
|
+
export async function startTunnel(opts) {
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const untunDistPath = normalizePath(require.resolve('untun'));
|
|
8
|
+
const cloudflaredPath = normalizePath(resolve(untunDistPath, '..', 'chunks', 'index.mjs'));
|
|
9
|
+
const { installCloudflared, startCloudflaredTunnel, cloudflaredBinPath } = await import(`file:///${cloudflaredPath}`);
|
|
10
|
+
const url = `${opts.protocol || 'http'}://${opts.hostname ?? 'localhost'}:${opts.port ?? 3000}`;
|
|
11
|
+
if (!existsSync(cloudflaredBinPath)) {
|
|
12
|
+
await installCloudflared();
|
|
13
|
+
}
|
|
14
|
+
const args = [['--url', url], opts.verifyTLS ? undefined : ['--no-tls-verify', '']].filter(Boolean);
|
|
15
|
+
const tunnel = await startCloudflaredTunnel(Object.fromEntries(args));
|
|
16
|
+
const cleanup = async () => {
|
|
17
|
+
await tunnel.stop();
|
|
18
|
+
};
|
|
19
|
+
for (const signal of ['SIGINT', 'SIGUSR1', 'SIGUSR2']) {
|
|
20
|
+
process.once(signal, cleanup);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
getURL: async () => await tunnel.url,
|
|
24
|
+
close: async () => {
|
|
25
|
+
await cleanup();
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|