@nativescript/cloudflare-cli 0.1.0-beta.6 → 0.1.0-beta.8
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 +2 -1
- package/dist/bin.js +61 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
```sh
|
|
4
4
|
npx @nativescript/cloudflare-cli live # a phone app: opens the IDE and prints a QR code for NativeScript Preview
|
|
5
|
+
npx @nativescript/cloudflare-cli live --react # the same with a framework: --ng (Angular), --react, --vue, --svelte or --solid
|
|
5
6
|
npx @nativescript/cloudflare-cli live --mac # a Mac app: opens the IDE and runs the app on this Mac, streamed into the IDE
|
|
6
7
|
npx @nativescript/cloudflare-cli live --electron # an Electron app with native views, run the same way
|
|
7
8
|
```
|
|
8
9
|
|
|
9
|
-
`live` creates a project on preview.nativescript.org (`--server` or `NS_EDGE_SERVER` for another edge), saves it to `.ns-edge.json` and opens its IDE. Run it again in the same folder to reopen that project (no
|
|
10
|
+
`live` creates a project on preview.nativescript.org (`--server` or `NS_EDGE_SERVER` for another edge), saves it to `.ns-edge.json` and opens its IDE. The framework flags are `ns create`'s (`--ng`/`--angular`, `--react`, `--vue`, `--svelte`, `--solid`, `--ts`); without one a phone project is plain TypeScript with XML views. Run it again in the same folder to reopen that project (no flag needed), or add `--new` for another; a flag for a different kind of project than the folder's asks for `--new`. While `live` runs a Mac app it restarts the app if it crashes, unless it crashes three times in a minute. Without a create token the project is free: a few hosted agent turns a day, no backend, deleted after 30 days unused. `--no-open` skips the browser; with `--mac` or `--electron`, `--allow-eval` lets the agent run code on this Mac.
|
|
10
11
|
|
|
11
12
|
## Mirror a local project
|
|
12
13
|
|
package/dist/bin.js
CHANGED
|
@@ -9,12 +9,34 @@ import { applyChanges, collect, createProject, projectUrl, report, SYNCED } from
|
|
|
9
9
|
const CONFIG = '.ns-edge.json';
|
|
10
10
|
const DEBOUNCE_MS = 120;
|
|
11
11
|
const LIVE_SERVER = process.env.NS_EDGE_SERVER ?? 'https://preview.nativescript.org';
|
|
12
|
-
/** The hosts `live --mac` and `
|
|
12
|
+
/** The hosts `live --mac`, `--electron` and `--expo` run; bump them with each host release this CLI is tested against. */
|
|
13
13
|
const DESKTOP_HOSTS = {
|
|
14
|
-
macos: '@nativescript/cloudflare-desktop@0.1.0-alpha.5',
|
|
15
|
-
electron: '@nativescript/cloudflare-electron@0.1.0-alpha.2',
|
|
14
|
+
macos: { spec: '@nativescript/cloudflare-desktop@0.1.0-alpha.5', bin: 'ns-edge-desktop' },
|
|
15
|
+
electron: { spec: '@nativescript/cloudflare-electron@0.1.0-alpha.2', bin: 'ns-edge-electron' },
|
|
16
|
+
expo: { spec: '@nativescript/cloudflare-expo-desktop@0.1.0-alpha.0', bin: 'ns-edge-expo-desktop' },
|
|
17
|
+
};
|
|
18
|
+
const DESKTOP_TEMPLATES = new Set(['macos', 'electron', 'expo']);
|
|
19
|
+
const DESKTOP_FLAGS = { macos: 'mac', electron: 'electron', expo: 'expo' };
|
|
20
|
+
/** The NativeScript CLI's `ns create` framework flags, so `live` and `create` take the same ones. */
|
|
21
|
+
const FRAMEWORK_FLAGS = {
|
|
22
|
+
angular: ['ng', 'angular'],
|
|
23
|
+
react: ['react', 'reactjs'],
|
|
24
|
+
vue: ['vue', 'vuejs'],
|
|
25
|
+
svelte: ['svelte'],
|
|
26
|
+
solid: ['solid', 'solidjs'],
|
|
27
|
+
core: ['ts', 'tsc', 'typescript'],
|
|
28
|
+
};
|
|
29
|
+
const TEMPLATE_KINDS = {
|
|
30
|
+
core: 'a phone',
|
|
31
|
+
angular: 'an Angular phone',
|
|
32
|
+
react: 'a React phone',
|
|
33
|
+
vue: 'a Vue phone',
|
|
34
|
+
svelte: 'a Svelte phone',
|
|
35
|
+
solid: 'a Solid phone',
|
|
36
|
+
macos: 'a Mac',
|
|
37
|
+
electron: 'an Electron',
|
|
38
|
+
expo: 'an Expo Desktop',
|
|
16
39
|
};
|
|
17
|
-
const DESKTOP_TEMPLATES = new Set(['macos', 'electron']);
|
|
18
40
|
const MAX_CRASHES = 3;
|
|
19
41
|
const CRASH_WINDOW_MS = 60_000;
|
|
20
42
|
const RESTART_DELAY_MS = 1000;
|
|
@@ -30,6 +52,22 @@ const flag = (name) => {
|
|
|
30
52
|
return i >= 0 ? args[i + 1] : undefined;
|
|
31
53
|
};
|
|
32
54
|
const has = (name) => args.includes(`--${name}`);
|
|
55
|
+
/** The template --template, a framework flag or a desktop flag asks for, if any; asking for two is an error. */
|
|
56
|
+
function requestedTemplate() {
|
|
57
|
+
const asked = new Set();
|
|
58
|
+
const named = flag('template');
|
|
59
|
+
if (named)
|
|
60
|
+
asked.add(named);
|
|
61
|
+
for (const [template, names] of Object.entries(FRAMEWORK_FLAGS))
|
|
62
|
+
if (names.some((name) => has(name)))
|
|
63
|
+
asked.add(template);
|
|
64
|
+
for (const [template, name] of Object.entries(DESKTOP_FLAGS))
|
|
65
|
+
if (has(name))
|
|
66
|
+
asked.add(template);
|
|
67
|
+
if (asked.size > 1)
|
|
68
|
+
throw new Error(`Pick one kind of project: this asked for ${[...asked].join(' and ')}.`);
|
|
69
|
+
return [...asked][0];
|
|
70
|
+
}
|
|
33
71
|
const root = process.cwd();
|
|
34
72
|
async function loadRef() {
|
|
35
73
|
let ref;
|
|
@@ -90,6 +128,8 @@ async function runDesktopHost(ref) {
|
|
|
90
128
|
const device = `${projectUrl(ref)}#${ref.deviceKey}`;
|
|
91
129
|
const extra = has('allow-eval') ? ['--allow-eval'] : [];
|
|
92
130
|
const host = DESKTOP_HOSTS[ref.template ?? 'macos'] ?? DESKTOP_HOSTS.macos;
|
|
131
|
+
// NS_EDGE_HOST runs another spec of the host (a version, or file:<packed .tgz>) to test a release before publishing it.
|
|
132
|
+
const spec = process.env.NS_EDGE_HOST ?? host.spec;
|
|
93
133
|
let child;
|
|
94
134
|
let stopping = false;
|
|
95
135
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
@@ -100,7 +140,7 @@ async function runDesktopHost(ref) {
|
|
|
100
140
|
}
|
|
101
141
|
const crashes = [];
|
|
102
142
|
for (;;) {
|
|
103
|
-
child = spawn('npx', ['-y', host, device, '--yes', ...extra], { stdio: 'inherit' });
|
|
143
|
+
child = spawn('npx', ['-y', '--package', spec, '--', host.bin, device, '--yes', ...extra], { stdio: 'inherit' });
|
|
104
144
|
const exit = await new Promise((resolve, reject) => {
|
|
105
145
|
child.on('error', reject);
|
|
106
146
|
child.on('exit', (code, signal) => resolve({ code, signal }));
|
|
@@ -123,17 +163,16 @@ const commands = {
|
|
|
123
163
|
async live() {
|
|
124
164
|
for (const later of ['ios', 'android', 'all']) {
|
|
125
165
|
if (has(later))
|
|
126
|
-
throw new Error(`--${later} isn't available yet. Run \`live\` for a phone app or \`live --mac\` for a Mac app.`);
|
|
166
|
+
throw new Error(`--${later} isn't available yet. Run \`live\` for a phone app, or \`live --mac\`, \`--electron\` or \`--expo\` for a Mac app.`);
|
|
127
167
|
}
|
|
128
168
|
let ref = has('new') ? null : await savedProject();
|
|
129
|
-
|
|
130
|
-
|
|
169
|
+
const requested = requestedTemplate();
|
|
170
|
+
// Without a template flag, this folder's project runs as whatever it was made as.
|
|
171
|
+
const template = requested ?? ref?.template ?? 'core';
|
|
131
172
|
const desktop = DESKTOP_TEMPLATES.has(template);
|
|
132
|
-
if (ref &&
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (ref && desktop && ref.template !== template) {
|
|
136
|
-
throw new Error(`This folder's project (${CONFIG}) is a ${ref.template} project. Add --new to replace it, or run this in another folder.`);
|
|
173
|
+
if (ref && requested && (ref.template ?? 'core') !== requested) {
|
|
174
|
+
const current = TEMPLATE_KINDS[ref.template ?? 'core'] ?? `a ${ref.template}`;
|
|
175
|
+
throw new Error(`This folder's project (${CONFIG}) is ${current} project. Add --new to start ${TEMPLATE_KINDS[requested] ?? `a ${requested}`} one, or run this in another folder.`);
|
|
137
176
|
}
|
|
138
177
|
if (ref) {
|
|
139
178
|
console.log(`Opening this folder's project ${ref.id} (${CONFIG})`);
|
|
@@ -141,7 +180,7 @@ const commands = {
|
|
|
141
180
|
else {
|
|
142
181
|
ref = await createProject(flag('server') ?? LIVE_SERVER, flag('token') ?? process.env.NS_EDGE_CREATE_TOKEN, template);
|
|
143
182
|
await writeFile(join(root, CONFIG), JSON.stringify(ref, null, 2) + '\n');
|
|
144
|
-
console.log(`Created ${template
|
|
183
|
+
console.log(`Created ${TEMPLATE_KINDS[template] ?? `a ${template}`} project, saved to ${CONFIG} (it holds the project's keys: keep it private and out of git).`);
|
|
145
184
|
if (ref.free) {
|
|
146
185
|
console.log(`It's a free project: ${ref.free.agentTurnsPerDay} hosted agent turn${ref.free.agentTurnsPerDay === 1 ? '' : 's'} a day, deleted after ${ref.free.idleDays} days unused. ` +
|
|
147
186
|
'For an unlimited agent, add your own API key in the agent panel or connect Claude Code from Connect agent.');
|
|
@@ -152,7 +191,8 @@ const commands = {
|
|
|
152
191
|
if (!has('no-open'))
|
|
153
192
|
openInBrowser(ide);
|
|
154
193
|
if (desktop) {
|
|
155
|
-
|
|
194
|
+
const first = template === 'electron' ? ' (the first run downloads Electron)' : template === 'expo' ? ' (the first run downloads the Expo Desktop shell)' : '';
|
|
195
|
+
console.log(`Starting the app on this Mac${first}. Its window streams to the IDE's Device pane. Press Ctrl+C to stop.\n`);
|
|
156
196
|
return runDesktopHost(ref);
|
|
157
197
|
}
|
|
158
198
|
const device = `${projectUrl(ref)}#${ref.deviceKey}`;
|
|
@@ -162,7 +202,7 @@ const commands = {
|
|
|
162
202
|
},
|
|
163
203
|
async create() {
|
|
164
204
|
const server = flag('server') ?? 'http://localhost:5173';
|
|
165
|
-
const ref = await createProject(server, flag('token') ?? process.env.NS_EDGE_CREATE_TOKEN,
|
|
205
|
+
const ref = await createProject(server, flag('token') ?? process.env.NS_EDGE_CREATE_TOKEN, requestedTemplate());
|
|
166
206
|
await writeFile(join(root, CONFIG), JSON.stringify(ref, null, 2) + '\n');
|
|
167
207
|
console.log(`Created project ${ref.id} (saved to ${CONFIG}; it holds the project keys, keep it out of git)`);
|
|
168
208
|
await printPairing(ref);
|
|
@@ -232,10 +272,12 @@ const commands = {
|
|
|
232
272
|
async help() {
|
|
233
273
|
console.log(`ns-edge <command>
|
|
234
274
|
|
|
235
|
-
live [--mac|--electron] [--new] [--no-open] [--allow-eval]
|
|
275
|
+
live [--ng|--react|--vue|--svelte|--solid|--mac|--electron|--expo] [--new] [--no-open] [--allow-eval]
|
|
236
276
|
create a project (or reopen this folder's), open its IDE, and print a QR code
|
|
237
|
-
for your phone; --
|
|
238
|
-
|
|
277
|
+
for your phone; --ng, --react, --vue, --svelte or --solid picks the framework
|
|
278
|
+
(plain TypeScript with XML views otherwise); --mac, --electron or --expo runs it
|
|
279
|
+
on this Mac instead
|
|
280
|
+
create [--server <url>] [--token <t>] [--ng|--react|--vue|--svelte|--solid|--template <name>]
|
|
239
281
|
create an edge project and save .ns-edge.json
|
|
240
282
|
push upload app/ and server/ in one transaction
|
|
241
283
|
watch push, then stream every save to the edge
|
package/package.json
CHANGED