@juuno-sdk/cli 1.0.5 → 1.0.7

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 (36) hide show
  1. package/README.md +204 -20
  2. package/bin/cli.js +79 -184
  3. package/dist/assets/main-B8xiNI5_.js +1 -0
  4. package/dist/assets/main-COSZCfRq.css +1 -0
  5. package/dist/cli/src/auth/index.d.ts +51 -0
  6. package/dist/cli/src/auth/index.d.ts.map +1 -0
  7. package/dist/cli/src/auth/index.js +156 -0
  8. package/dist/cli/src/deploy/index.d.ts +12 -0
  9. package/dist/cli/src/deploy/index.d.ts.map +1 -0
  10. package/dist/cli/src/deploy/index.js +129 -0
  11. package/dist/cli/src/info/index.d.ts +12 -0
  12. package/dist/cli/src/info/index.d.ts.map +1 -0
  13. package/dist/cli/src/info/index.js +111 -0
  14. package/dist/cli/src/list/index.d.ts +22 -0
  15. package/dist/cli/src/list/index.d.ts.map +1 -0
  16. package/dist/cli/src/list/index.js +102 -0
  17. package/dist/cli/src/login/index.d.ts +12 -0
  18. package/dist/cli/src/login/index.d.ts.map +1 -0
  19. package/dist/cli/src/login/index.js +61 -0
  20. package/dist/cli/src/logout/index.d.ts +5 -0
  21. package/dist/cli/src/logout/index.d.ts.map +1 -0
  22. package/dist/cli/src/logout/index.js +26 -0
  23. package/dist/cli/src/simulator/index.d.ts +13 -0
  24. package/dist/cli/src/simulator/index.d.ts.map +1 -0
  25. package/dist/cli/src/simulator/index.js +136 -0
  26. package/dist/cli/src/whoami/index.d.ts +5 -0
  27. package/dist/cli/src/whoami/index.d.ts.map +1 -0
  28. package/dist/cli/src/whoami/index.js +24 -0
  29. package/dist/cli/tsconfig.build.tsbuildinfo +1 -0
  30. package/dist/index.html +2 -2
  31. package/package.json +8 -7
  32. package/dist/assets/main-BIR58A5i.css +0 -1
  33. package/dist/assets/main-BYDwbwR9.js +0 -1
  34. package/src/App.vue +0 -350
  35. package/src/deploy/index.ts +0 -202
  36. package/src/main.ts +0 -5
package/README.md CHANGED
@@ -31,19 +31,49 @@ npx juuno-cli dev --app http://localhost:3000
31
31
  npx juuno-cli dev --app https://cdn.example.com/my-app/
32
32
  ```
33
33
 
34
+ ### Authentication
35
+
36
+ Login once to authenticate with Juuno. Your token will be saved and reused automatically.
37
+
38
+ ```bash
39
+ # Login (one-time setup)
40
+ npx juuno-cli login
41
+
42
+ # Check authentication status
43
+ npx juuno-cli whoami
44
+
45
+ # Logout when needed
46
+ npx juuno-cli logout
47
+ ```
48
+
34
49
  ### Deployment
35
50
 
36
- Deploy your app to Juuno CDN.
51
+ Deploy your app to Juuno.
37
52
 
38
53
  ```bash
39
- # Deploy from default ./dist directory
54
+ # Deploy (uses saved credentials from login)
40
55
  npx juuno-cli deploy
41
56
 
42
57
  # Specify build directory
43
58
  npx juuno-cli deploy --build-dir ./build
59
+ ```
60
+
61
+ ### List Apps
62
+
63
+ View all your deployed apps.
64
+
65
+ ```bash
66
+ # List all apps (uses saved credentials)
67
+ npx juuno-cli list
68
+ ```
69
+
70
+ ### App Info
71
+
72
+ Get detailed information about a specific app.
44
73
 
45
- # Provide API key inline (otherwise will prompt)
46
- npx juuno-cli deploy --api-key your-juuno-api-key
74
+ ```bash
75
+ # Show app details (uses saved credentials)
76
+ npx juuno-cli info app_abc123
47
77
  ```
48
78
 
49
79
  ### npm Scripts
@@ -64,6 +94,9 @@ Add to your `package.json`:
64
94
  Then run:
65
95
 
66
96
  ```bash
97
+ # One-time setup: Login to Juuno
98
+ npx juuno-cli login
99
+
67
100
  # Terminal 1: Your app dev server
68
101
  npm run dev
69
102
 
@@ -154,6 +187,35 @@ Options:
154
187
  --help Show help
155
188
  ```
156
189
 
190
+ ### Login Command
191
+
192
+ ```bash
193
+ juuno-cli login [options]
194
+
195
+ Options:
196
+ --email <email> Your Juuno email (will prompt if not provided)
197
+ --password <pwd> Your Juuno password (will prompt if not provided)
198
+ --help Show help
199
+ ```
200
+
201
+ Saves credentials to `~/.juuno/credentials.json` for automatic reuse.
202
+
203
+ ### Logout Command
204
+
205
+ ```bash
206
+ juuno-cli logout
207
+ ```
208
+
209
+ Removes stored credentials from `~/.juuno/credentials.json`.
210
+
211
+ ### Whoami Command
212
+
213
+ ```bash
214
+ juuno-cli whoami
215
+ ```
216
+
217
+ Shows current authentication status.
218
+
157
219
  ### Deploy Command
158
220
 
159
221
  ```bash
@@ -161,34 +223,129 @@ juuno-cli deploy [options]
161
223
 
162
224
  Options:
163
225
  --build-dir <dir> Build directory to deploy (default: ./dist)
164
- --api-key <key> Juuno API key (will prompt if not provided)
226
+ --token <token> Override with specific token (for CI/CD)
227
+ --email <email> Login with email instead of using saved credentials
228
+ --password <pwd> Use with --email
229
+ --help Show help
230
+ ```
231
+
232
+ ### List Command
233
+
234
+ ```bash
235
+ juuno-cli list [options]
236
+
237
+ Options:
238
+ --token <token> Override with specific token (for CI/CD)
239
+ --email <email> Login with email instead of using saved credentials
240
+ --password <pwd> Use with --email
165
241
  --help Show help
166
242
  ```
167
243
 
244
+ ### Info Command
245
+
246
+ ```bash
247
+ juuno-cli info <app-id> [options]
248
+
249
+ Arguments:
250
+ <app-id> The app ID to get information about
251
+
252
+ Options:
253
+ --token <token> Override with specific token (for CI/CD)
254
+ --email <email> Login with email instead of using saved credentials
255
+ --password <pwd> Use with --email
256
+ --help Show help
257
+ ```
258
+
259
+ ## Environment Variables
260
+
261
+ ```bash
262
+ # API endpoint (defaults to production)
263
+ export JUUNO_API_URL=https://api.juuno.co
264
+
265
+ # For staging
266
+ export JUUNO_API_URL=https://api.stage.juuno.co
267
+
268
+ # Authentication token (for CI/CD, overrides saved credentials)
269
+ export JUUNO_API_TOKEN=your-auth-token
270
+ ```
271
+
168
272
  ## Deployment Workflow
169
273
 
170
- 1. **Build your app**: Run your build command to generate the dist bundle
171
- 2. **Deploy to CDN**: Use `juuno-cli deploy` to upload your app
172
- 3. **Get API key**: Obtain a Juuno API key from your account settings
173
- 4. **Configure in Juuno**: Add the returned manifest URL to your Juuno account
274
+ ### Quick Start
174
275
 
175
276
  ```bash
176
- # Complete deployment flow
277
+ # 1. Login once
278
+ npx juuno-cli login
279
+
280
+ # 2. Build and deploy
177
281
  npm run build
178
282
  npx juuno-cli deploy
179
283
 
180
- # Follow the prompts:
181
- # 1. Enter your Juuno API key
182
- # 2. CLI uploads to S3 and returns manifest URL
183
- # 3. Add manifest URL to Juuno account (SDK > Custom Apps)
284
+ # Deploy again anytime (no re-authentication needed)
285
+ npm run build
286
+ npx juuno-cli deploy
184
287
  ```
185
288
 
186
- Your app will be hosted at:
289
+ ### Complete Flow
290
+
291
+ 1. **Login**: Authenticate once with `juuno-cli login`
292
+ 2. **Build**: Run your build command to generate the dist bundle
293
+ 3. **Deploy**: Use `juuno-cli deploy` - automatically uses saved credentials
294
+ 4. **Success**: Your app is deployed and ready to use
187
295
 
296
+ The CLI saves your authentication token to `~/.juuno/credentials.json` and reuses it automatically for subsequent commands.
297
+
298
+ ## Authentication
299
+
300
+ ### Primary Method: Login Command (Recommended)
301
+
302
+ ```bash
303
+ # Login once
304
+ npx juuno-cli login
305
+
306
+ # All subsequent commands use saved credentials
307
+ npx juuno-cli deploy
308
+ npx juuno-cli list
309
+ npx juuno-cli info app_abc123
310
+
311
+ # Check login status
312
+ npx juuno-cli whoami
313
+
314
+ # Logout when needed
315
+ npx juuno-cli logout
188
316
  ```
189
- https://[bucket].s3.[region].amazonaws.com/[account]/[app-id]/[version]/manifest.json
317
+
318
+ ### Alternative Methods
319
+
320
+ **For CI/CD (environment variable):**
321
+
322
+ ```bash
323
+ export JUUNO_API_TOKEN=your-auth-token
324
+ npx juuno-cli deploy
325
+ ```
326
+
327
+ **One-off commands (email/password):**
328
+
329
+ ```bash
330
+ npx juuno-cli deploy --email user@example.com --password yourpassword
331
+ ```
332
+
333
+ **Explicit token override:**
334
+
335
+ ```bash
336
+ npx juuno-cli deploy --token your-auth-token
190
337
  ```
191
338
 
339
+ ### Authentication Priority
340
+
341
+ The CLI checks for credentials in this order:
342
+
343
+ 1. `--token` flag (explicit override)
344
+ 2. `JUUNO_API_TOKEN` environment variable (CI/CD)
345
+ 3. Saved credentials from `~/.juuno/credentials.json` (from `juuno-cli login`)
346
+ 4. `--email` and `--password` flags (one-off login)
347
+ 5. Error: "Not logged in"
348
+
192
349
  ## Troubleshooting
193
350
 
194
351
  ### CORS Errors
@@ -219,6 +376,17 @@ export { defaultMeta } from './settings';
219
376
 
220
377
  The simulator uses import maps to load dependencies. If you see import errors, check that your app properly externalizes `vue` and `@juuno-sdk/app-sdk`.
221
378
 
379
+ ### Authentication Errors
380
+
381
+ If you get authentication errors:
382
+
383
+ 1. Run `juuno-cli login` to authenticate
384
+ 2. Check login status with `juuno-cli whoami`
385
+ 3. Verify your email and password are correct
386
+ 4. Check that you have developer access to your Juuno account
387
+ 5. Ensure `JUUNO_API_URL` points to the correct environment (if using staging)
388
+ 6. If credentials are corrupted, run `juuno-cli logout` then `juuno-cli login` again
389
+
222
390
  ## Example
223
391
 
224
392
  See [@juuno-sdk/app-sdk-example](../app-sdk-example) for a complete working example.
@@ -232,14 +400,30 @@ See [@juuno-sdk/app-sdk-example](../app-sdk-example) for a complete working exam
232
400
 
233
401
  The CLI provides both programmatic and command-line interfaces:
234
402
 
235
- - **CLI Commands**: `juuno-cli dev`, `juuno-cli deploy`
236
- - **Programmatic API**: Import deployment functions for custom workflows
403
+ - **CLI Commands**: `juuno-cli login`, `juuno-cli logout`, `juuno-cli whoami`, `juuno-cli dev`, `juuno-cli deploy`, `juuno-cli list`, `juuno-cli info`
404
+ - **Programmatic API**: Import functions for custom workflows
237
405
 
238
406
  ```typescript
239
- import { deployApp } from '@juuno-sdk/cli';
407
+ import { deployApp, login, logout } from '@juuno-sdk/cli';
240
408
 
409
+ // Login and save credentials
410
+ await login({
411
+ email: 'user@example.com',
412
+ password: 'yourpassword',
413
+ });
414
+
415
+ // Deploy (uses saved credentials automatically)
241
416
  await deployApp({
242
417
  buildDir: './dist',
243
- apiKey: process.env.JUUNO_API_KEY,
418
+ });
419
+
420
+ // Or override with specific token
421
+ await deployApp({
422
+ buildDir: './dist',
423
+ token: process.env.JUUNO_API_TOKEN,
244
424
  });
245
425
  ```
426
+
427
+ ## Development
428
+
429
+ See [DEVELOPMENT.md](./DEVELOPMENT.md) for local development, building, and publishing guidelines.
package/bin/cli.js CHANGED
@@ -1,50 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { spawn } from 'child_process';
4
3
  import { fileURLToPath } from 'url';
5
4
  import { dirname, join } from 'path';
6
- import {
7
- readFileSync,
8
- writeFileSync,
9
- mkdirSync,
10
- copyFileSync,
11
- readdirSync,
12
- rmSync,
13
- } from 'fs';
14
- import { tmpdir } from 'os';
5
+ import { runCommand } from './cli-router.js';
15
6
 
16
7
  const __filename = fileURLToPath(import.meta.url);
17
8
  const __dirname = dirname(__filename);
18
9
 
19
- // Parse command line arguments
10
+ // Parse command line arguments.
20
11
  const args = process.argv.slice(2);
21
12
 
22
- // Check if first argument is a command
13
+ // Check if first argument is a command.
23
14
  const command = args[0];
24
15
 
25
- // Handle deploy command
26
- if (command === 'deploy') {
27
- const { deployApp } = await import('../src/deploy/index.ts');
28
-
29
- // Parse deploy options
30
- const buildDirIndex = args.indexOf('--build-dir');
31
- const apiKeyIndex = args.indexOf('--api-key');
32
-
33
- const buildDir = buildDirIndex !== -1 ? args[buildDirIndex + 1] : './dist';
34
- const apiKey = apiKeyIndex !== -1 ? args[apiKeyIndex + 1] : undefined;
35
-
36
- await deployApp({ buildDir, apiKey });
37
- process.exit(0);
38
- }
39
-
40
- // Handle simulator command (default behavior)
41
- // Remove the command from args if it was 'dev'
42
- if (command === 'dev') {
43
- args.shift();
44
- }
45
- const appUrlIndex = args.indexOf('--app');
46
- const portIndex = args.indexOf('--port');
47
-
16
+ // Handle help command.
48
17
  if (args.includes('--help') || args.includes('-h') || command === 'help') {
49
18
  console.log(`
50
19
  Juuno CLI - Official CLI for Juuno external app development
@@ -53,30 +22,93 @@ Usage:
53
22
  juuno-cli <command> [options]
54
23
 
55
24
  Commands:
25
+ login Authenticate with Juuno
26
+ logout Remove stored credentials
27
+ whoami Show authentication status
56
28
  dev Launch the app simulator (default)
57
- deploy Deploy your app to Juuno CDN
29
+ deploy Deploy your app to Juuno
30
+ list List your deployed apps
31
+ info <app-id> Show detailed information about an app
58
32
  help Show this help message
59
33
 
34
+ Authentication Commands:
35
+ login [--email <email>] [--password <pwd>]
36
+ Authenticate and save credentials to ~/.juuno/credentials.json
37
+ Subsequent commands will use the saved token automatically.
38
+
39
+ logout
40
+ Remove stored credentials.
41
+
42
+ whoami
43
+ Show current authentication status.
44
+
60
45
  Simulator Options:
61
46
  --app <url> URL of your external app (required)
62
47
  --port <number> Port for simulator (default: 5004)
63
48
 
64
49
  Deploy Options:
65
- --build-dir <dir> Build directory to deploy (default: ./dist)
66
- --api-key <key> Juuno API key (will prompt if not provided)
50
+ --build-dir <dir> Build directory to deploy (default: ./dist)
51
+
52
+ Authentication Options (for deploy, list, info):
53
+ By default, these commands use the token saved by 'juuno-cli login'.
54
+ You can override with:
55
+ --token <token> Use specific token (for CI/CD)
56
+ --email <email> Login with email/password (skips saved token)
57
+ --password <pwd> Use with --email
58
+
59
+ Environment Variables:
60
+ JUUNO_API_URL API URL (default: https://api.juuno.co)
61
+ JUUNO_API_TOKEN Authentication token (for CI/CD, skips saved credentials)
67
62
 
68
63
  Examples:
64
+ # Authenticate (one-time setup)
65
+ juuno-cli login
66
+
69
67
  # Start simulator
70
68
  juuno-cli dev --app http://localhost:3000
71
- juuno-cli --app http://localhost:3000
72
69
 
73
- # Deploy app
70
+ # Deploy app (uses saved credentials)
74
71
  juuno-cli deploy
75
- juuno-cli deploy --build-dir ./dist --api-key your-api-key
72
+ juuno-cli deploy --build-dir ./dist
73
+
74
+ # List apps (uses saved credentials)
75
+ juuno-cli list
76
+
77
+ # Show app info (uses saved credentials)
78
+ juuno-cli info app_abc123
79
+
80
+ # Check authentication status
81
+ juuno-cli whoami
82
+
83
+ # Logout
84
+ juuno-cli logout
76
85
  `);
77
86
  process.exit(0);
78
87
  }
79
88
 
89
+ // Handle commands via shared router (uses built JS imports for production).
90
+ if (
91
+ command === 'login' ||
92
+ command === 'logout' ||
93
+ command === 'whoami' ||
94
+ command === 'deploy' ||
95
+ command === 'list' ||
96
+ command === 'info'
97
+ ) {
98
+ const exitCode = await runCommand(command, args, '../dist/cli/src/');
99
+ process.exit(exitCode);
100
+ }
101
+
102
+ // Handle simulator command (default behavior).
103
+ // Remove the command from args if it was 'dev'.
104
+ let simulatorArgs = args;
105
+ if (command === 'dev') {
106
+ simulatorArgs = args.slice(1);
107
+ }
108
+
109
+ const appUrlIndex = simulatorArgs.indexOf('--app');
110
+ const portIndex = simulatorArgs.indexOf('--port');
111
+
80
112
  if (appUrlIndex === -1) {
81
113
  console.error('Error: --app parameter is required for simulator');
82
114
  console.error('Usage: juuno-cli dev --app <url>');
@@ -84,154 +116,17 @@ if (appUrlIndex === -1) {
84
116
  process.exit(1);
85
117
  }
86
118
 
87
- const appUrl = args[appUrlIndex + 1];
88
- const port = portIndex !== -1 ? args[portIndex + 1] : '5004';
119
+ const appUrl = simulatorArgs[appUrlIndex + 1];
120
+ const port = portIndex !== -1 ? simulatorArgs[portIndex + 1] : '5004';
89
121
 
90
122
  if (!appUrl) {
91
123
  console.error('Error: --app parameter requires a URL value');
92
124
  process.exit(1);
93
125
  }
94
126
 
95
- // Path to the built dist directory
127
+ // Path to the built dist directory.
96
128
  const distPath = join(__dirname, '..', 'dist');
97
129
 
98
- // Create a temporary directory for the modified dist
99
- const tempDir = join(tmpdir(), `juuno-simulator-${Date.now()}`);
100
- mkdirSync(tempDir, { recursive: true });
101
-
102
- // Copy all files from dist to temp directory
103
- function copyDir(src, dest) {
104
- const entries = readdirSync(src, { withFileTypes: true });
105
-
106
- for (const entry of entries) {
107
- const srcPath = join(src, entry.name);
108
- const destPath = join(dest, entry.name);
109
-
110
- if (entry.isDirectory()) {
111
- mkdirSync(destPath, { recursive: true });
112
- copyDir(srcPath, destPath);
113
- } else {
114
- copyFileSync(srcPath, destPath);
115
- }
116
- }
117
- }
118
-
119
- copyDir(distPath, tempDir);
120
-
121
- // Inject the app URL and import map CDN URLs into index.html
122
- const indexPath = join(tempDir, 'index.html');
123
- let indexHtml = readFileSync(indexPath, 'utf-8');
124
-
125
- // Fill in the import map with CDN URLs for vue and @juuno-sdk/app-sdk
126
- indexHtml = indexHtml.replace(
127
- '"vue": ""',
128
- '"vue": "https://cdn.jsdelivr.net/npm/vue@3.5.22/dist/vue.esm-browser.prod.js"',
129
- );
130
- indexHtml = indexHtml.replace(
131
- '"@juuno-sdk/app-sdk": ""',
132
- '"@juuno-sdk/app-sdk": "https://cdn.jsdelivr.net/npm/@juuno-sdk/app-sdk@1.0.2/dist/index.js"',
133
- );
134
-
135
- // Fill in CDN URLs for externalized dependencies from the SDK
136
- indexHtml = indexHtml.replace(
137
- '"@vueuse/core": ""',
138
- '"@vueuse/core": "https://cdn.jsdelivr.net/npm/@vueuse/core@11.4.1/index.mjs"',
139
- );
140
- indexHtml = indexHtml.replace(
141
- '"@tiptap/vue-3": ""',
142
- '"@tiptap/vue-3": "https://cdn.jsdelivr.net/npm/@tiptap/vue-3@2.10.5/dist/index.js"',
143
- );
144
- indexHtml = indexHtml.replace(
145
- '"@tiptap/starter-kit": ""',
146
- '"@tiptap/starter-kit": "https://cdn.jsdelivr.net/npm/@tiptap/starter-kit@2.10.5/dist/index.js"',
147
- );
148
- indexHtml = indexHtml.replace(
149
- '"@tiptap/extension-underline": ""',
150
- '"@tiptap/extension-underline": "https://cdn.jsdelivr.net/npm/@tiptap/extension-underline@2.10.5/dist/index.js"',
151
- );
152
- indexHtml = indexHtml.replace(
153
- '"lodash-es": ""',
154
- '"lodash-es": "https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js"',
155
- );
156
- indexHtml = indexHtml.replace(
157
- '"date-fns": ""',
158
- '"date-fns": "https://cdn.jsdelivr.net/npm/date-fns@4.1.0/index.mjs"',
159
- );
160
- indexHtml = indexHtml.replace(
161
- '"url-parse": ""',
162
- '"url-parse": "https://cdn.jsdelivr.net/npm/url-parse@1.5.10/dist/url-parse.min.js"',
163
- );
164
-
165
- // Fill in the import map with external app entrypoints
166
- indexHtml = indexHtml.replace(
167
- '"external-app/player": ""',
168
- `"external-app/player": "${appUrl}/player/index.js"`,
169
- );
170
- indexHtml = indexHtml.replace(
171
- '"external-app/config": ""',
172
- `"external-app/config": "${appUrl}/config/index.js"`,
173
- );
174
-
175
- // Inject the app URL as a global variable before any scripts load
176
- const injection = `
177
- <script>
178
- window.__JUUNO_EXTERNAL_APP_URL__ = '${appUrl}';
179
- </script>
180
- `;
181
-
182
- indexHtml = indexHtml.replace('</head>', `${injection}</head>`);
183
- writeFileSync(indexPath, indexHtml);
184
-
185
- console.log(`
186
- šŸš€ Juuno App Simulator Starting...
187
-
188
- External App: ${appUrl}
189
- Simulator URL: http://localhost:${port}
190
-
191
- Press Ctrl+C to stop
192
- `);
193
-
194
- // Serve the modified temp directory
195
- const server = spawn(
196
- 'npx',
197
- ['sirv-cli', tempDir, '--port', port, '--cors', '--single'],
198
- {
199
- stdio: 'inherit',
200
- shell: true,
201
- },
202
- );
203
-
204
- server.on('error', (err) => {
205
- console.error('Failed to start server:', err);
206
- process.exit(1);
207
- });
208
-
209
- server.on('exit', (code) => {
210
- if (code !== 0) {
211
- console.error(`Server exited with code ${code}`);
212
- }
213
- process.exit(code);
214
- });
215
-
216
- // Cleanup function
217
- function cleanup() {
218
- try {
219
- rmSync(tempDir, { recursive: true, force: true });
220
- } catch (err) {
221
- // Ignore cleanup errors
222
- }
223
- }
224
-
225
- // Handle termination
226
- process.on('SIGINT', () => {
227
- console.log('\n\nšŸ‘‹ Stopping simulator...');
228
- server.kill();
229
- cleanup();
230
- process.exit(0);
231
- });
232
-
233
- process.on('SIGTERM', () => {
234
- server.kill();
235
- cleanup();
236
- process.exit(0);
237
- });
130
+ // Launch simulator (imports from built JS).
131
+ const { launchSimulator } = await import('../dist/cli/src/simulator/index.js');
132
+ launchSimulator(appUrl, port, distPath);
@@ -0,0 +1 @@
1
+ import{defineComponent as A,ref as g,shallowRef as y,reactive as P,onMounted as k,createElementBlock as f,openBlock as d,createElementVNode as t,toDisplayString as _,createTextVNode as h,createBlock as E,resolveDynamicComponent as x,createApp as O}from"vue";import{provideAppConfigContext as I}from"@juuno-sdk/app-sdk";(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))u(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const l of r.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&u(l)}).observe(document,{childList:!0,subtree:!0});function i(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function u(o){if(o.ep)return;o.ep=!0;const r=i(o);fetch(o.href,r)}})();const b="modulepreload",R=function(p){return"/"+p},C={},L=function(a,i,u){let o=Promise.resolve();if(i&&i.length>0){let l=function(n){return Promise.all(n.map(e=>Promise.resolve(e).then(m=>({status:"fulfilled",value:m}),m=>({status:"rejected",reason:m}))))};document.getElementsByTagName("link");const s=document.querySelector("meta[property=csp-nonce]"),v=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));o=l(i.map(n=>{if(n=R(n),n in C)return;C[n]=!0;const e=n.endsWith(".css"),m=e?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${n}"]${m}`))return;const c=document.createElement("link");if(c.rel=e?"stylesheet":b,e||(c.as="script"),c.crossOrigin="",c.href=n,v&&c.setAttribute("nonce",v),document.head.appendChild(c),e)return new Promise((w,S)=>{c.addEventListener("load",w),c.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${n}`)))})}))}function r(l){const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=l,window.dispatchEvent(s),!s.defaultPrevented)throw l}return o.then(l=>{for(const s of l||[])s.status==="rejected"&&r(s.reason);return a().catch(r)})},U={class:"juuno-cli"},N={class:"header"},T={class:"header-content"},j={class:"header-info"},D={class:"app-url"},V={key:0,class:"loading-state"},q={class:"url-info"},B={key:1,class:"error-state"},F={class:"error-message"},J={class:"error-details"},$={key:2,class:"container"},M={class:"player-section"},K={class:"player-preview"},W={key:1,class:"placeholder"},X={class:"config-section"},z={class:"config-panel"},G={key:1,class:"placeholder"},H={name:"JuunoCLI"},Q=A({...H,setup(p){const a=g(window.__JUUNO_EXTERNAL_APP_URL__||"http://localhost:5002/index.js"),i=y(null),u=y(null),o=g(!0),r=g(null),l=P({idx:"simulator-scene-1",name:"Simulator Test Scene",app:null,app_idx:"simulator-app-1",created_at:new Date().toISOString(),display_time:5e3,language:"en",order:0,playlist_idx:"simulator-playlist-1",updated_at:new Date().toISOString(),translations:{},meta:{title:"Test App",backgroundColor:"#2c3e50",textColor:"#ecf0f1"},mediaAssets:[]}),v=I({async save(n){console.log("Simulator: Scene updated",n),Object.assign(l,n)}},{scene:l});return k(async()=>{try{o.value=!0,r.value=null,console.log(`Loading external app from: ${a.value}`);const n=await L(()=>import("external-app/player"),[]);if(i.value=n.default,!i.value)throw new Error("External app must export a default component from /player");try{const e=await L(()=>import("external-app/config"),[]);u.value=e.default||null}catch(e){console.warn("Config component not found or failed to load:",e),u.value=null}v.load(l),console.log("āœ… External app loaded successfully"),o.value=!1}catch(n){console.error("Failed to load external app:",n),r.value=n instanceof Error?n.message:"Failed to load external app",o.value=!1}}),(n,e)=>(d(),f("div",U,[t("header",N,[t("div",T,[e[0]||(e[0]=t("h1",null,"Juuno CLI",-1)),t("div",j,[t("span",D,_(a.value),1)])])]),o.value?(d(),f("div",V,[e[1]||(e[1]=t("div",{class:"spinner"},null,-1)),e[2]||(e[2]=t("p",null,"Loading external app...",-1)),t("p",q,_(a.value),1)])):r.value?(d(),f("div",B,[e[6]||(e[6]=t("div",{class:"error-icon"},"āš ļø",-1)),e[7]||(e[7]=t("h2",null,"Failed to Load App",-1)),t("p",F,_(r.value),1),t("div",J,[t("p",null,[e[3]||(e[3]=t("strong",null,"App URL:",-1)),h(" "+_(a.value),1)]),e[4]||(e[4]=t("p",null,[t("strong",null,"Common Issues:")],-1)),e[5]||(e[5]=t("ul",null,[t("li",null,"App dev server not running"),t("li",null,"CORS not enabled on app dev server"),t("li",null," App doesn't export required components from /player and /config "),t("li",null,"Incorrect URL provided"),t("li",null,"Missing exports field in package.json")],-1))])])):(d(),f("div",$,[t("div",M,[e[8]||(e[8]=t("h2",null,"Player View",-1)),t("div",K,[i.value?(d(),E(x(i.value),{key:0,scene:l},null,8,["scene"])):(d(),f("div",W,"No player component found"))])]),t("div",X,[e[9]||(e[9]=t("h2",null,"Configuration UI",-1)),t("div",z,[u.value?(d(),E(x(u.value),{key:0})):(d(),f("div",G,"No config component found"))])])])),e[10]||(e[10]=t("footer",{class:"footer"},[t("p",null,[t("strong",null,"Juuno CLI"),h(" - Test your external app in a production-like environment ")])],-1))]))}}),Y=(p,a)=>{const i=p.__vccOpts||p;for(const[u,o]of a)i[u]=o;return i},Z=Y(Q,[["__scopeId","data-v-5e08f5e3"]]),ee=O(Z);ee.mount("#app");
@@ -0,0 +1 @@
1
+ [data-v-5e08f5e3]{box-sizing:border-box}.juuno-cli[data-v-5e08f5e3]{min-height:100vh;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;background-color:#f5f5f5}.header[data-v-5e08f5e3]{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:1.5rem 2rem;box-shadow:0 2px 4px #0000001a}.header-content[data-v-5e08f5e3]{max-width:1600px;margin:0 auto}.header h1[data-v-5e08f5e3]{margin:0 0 .5rem;font-size:1.75rem;font-weight:600}.header-info[data-v-5e08f5e3]{display:flex;justify-content:space-between;align-items:center;gap:1rem}.app-url[data-v-5e08f5e3]{font-size:.875rem;opacity:.9;font-family:Courier New,monospace}.loading-state[data-v-5e08f5e3],.error-state[data-v-5e08f5e3]{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem;text-align:center}.spinner[data-v-5e08f5e3]{width:50px;height:50px;border:4px solid #f3f3f3;border-top:4px solid #667eea;border-radius:50%;animation:spin-5e08f5e3 1s linear infinite}@keyframes spin-5e08f5e3{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.url-info[data-v-5e08f5e3]{margin-top:1rem;font-size:.875rem;color:#666;font-family:Courier New,monospace}.error-icon[data-v-5e08f5e3]{font-size:4rem;margin-bottom:1rem}.error-message[data-v-5e08f5e3]{color:#d32f2f;font-weight:500;margin:1rem 0}.error-details[data-v-5e08f5e3]{background:#fff;border-radius:8px;padding:1.5rem;margin-top:2rem;text-align:left;max-width:600px}.error-details ul[data-v-5e08f5e3]{margin:.5rem 0 0 1.5rem;padding:0}.error-details li[data-v-5e08f5e3]{margin:.25rem 0}.container[data-v-5e08f5e3]{flex:1;display:grid;grid-template-columns:1fr 1fr;gap:2rem;padding:2rem;max-width:1600px;margin:0 auto;width:100%}.player-section[data-v-5e08f5e3],.config-section[data-v-5e08f5e3]{background:#fff;border-radius:8px;padding:1.5rem;box-shadow:0 1px 3px #0000001a}.player-section h2[data-v-5e08f5e3],.config-section h2[data-v-5e08f5e3]{margin:0 0 1rem;font-size:1.25rem;font-weight:600;color:#333}.player-preview[data-v-5e08f5e3]{aspect-ratio:16 / 9;background:#000;border-radius:4px;overflow:hidden;box-shadow:0 4px 6px #0000001a}.config-panel[data-v-5e08f5e3]{background:#fafafa;border-radius:4px;padding:1rem;min-height:400px}.placeholder[data-v-5e08f5e3]{display:flex;align-items:center;justify-content:center;height:100%;color:#999;font-style:italic}.footer[data-v-5e08f5e3]{background:#fff;padding:1.5rem;text-align:center;border-top:1px solid #e0e0e0;color:#666;font-size:.875rem}.footer p[data-v-5e08f5e3]{margin:0}@media (max-width: 1200px){.container[data-v-5e08f5e3]{grid-template-columns:1fr}}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Authentication credentials for the developer API.
3
+ */
4
+ export interface AuthCredentials {
5
+ email: string;
6
+ password: string;
7
+ }
8
+ /**
9
+ * Authentication token response from the API.
10
+ */
11
+ export interface AuthTokenResponse {
12
+ success: boolean;
13
+ token: string;
14
+ }
15
+ /**
16
+ * Options for authentication.
17
+ */
18
+ export interface AuthOptions {
19
+ email?: string;
20
+ password?: string;
21
+ token?: string;
22
+ }
23
+ /**
24
+ * Saves authentication token to local credentials file.
25
+ */
26
+ export declare function saveToken(token: string): void;
27
+ /**
28
+ * Loads authentication token from local credentials file.
29
+ */
30
+ export declare function loadToken(): string | null;
31
+ /**
32
+ * Removes stored credentials file.
33
+ */
34
+ export declare function removeToken(): void;
35
+ /**
36
+ * Checks if user is currently logged in.
37
+ */
38
+ export declare function isLoggedIn(): boolean;
39
+ /**
40
+ * Gets the API URL from environment or uses default.
41
+ */
42
+ export declare function getApiUrl(): string;
43
+ /**
44
+ * Gets the authentication token from options, environment, or stored credentials.
45
+ */
46
+ export declare function getAuthToken(options: AuthOptions): Promise<string>;
47
+ /**
48
+ * Authenticates with the developer API using email and password.
49
+ */
50
+ export declare function loginWithCredentials(credentials: AuthCredentials): Promise<string>;
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/auth/index.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6BD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAa7C;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAczC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAMlC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBxE;AAiCD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,eAAe,GAC3B,OAAO,CAAC,MAAM,CAAC,CAoCjB"}