@juuno-sdk/cli 1.0.5 → 1.0.6

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 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
@@ -16,35 +16,26 @@ import { tmpdir } from 'os';
16
16
  const __filename = fileURLToPath(import.meta.url);
17
17
  const __dirname = dirname(__filename);
18
18
 
19
- // Parse command line arguments
19
+ // Parse command line arguments.
20
20
  const args = process.argv.slice(2);
21
21
 
22
- // Check if first argument is a command
22
+ // Check if first argument is a command.
23
23
  const command = args[0];
24
24
 
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();
25
+ // Helper function to parse auth options from args.
26
+ function parseAuthOptions(args) {
27
+ const emailIndex = args.indexOf('--email');
28
+ const passwordIndex = args.indexOf('--password');
29
+ const tokenIndex = args.indexOf('--token');
30
+
31
+ return {
32
+ email: emailIndex !== -1 ? args[emailIndex + 1] : undefined,
33
+ password: passwordIndex !== -1 ? args[passwordIndex + 1] : undefined,
34
+ token: tokenIndex !== -1 ? args[tokenIndex + 1] : undefined,
35
+ };
44
36
  }
45
- const appUrlIndex = args.indexOf('--app');
46
- const portIndex = args.indexOf('--port');
47
37
 
38
+ // Handle help command.
48
39
  if (args.includes('--help') || args.includes('-h') || command === 'help') {
49
40
  console.log(`
50
41
  Juuno CLI - Official CLI for Juuno external app development
@@ -53,30 +44,145 @@ Usage:
53
44
  juuno-cli <command> [options]
54
45
 
55
46
  Commands:
47
+ login Authenticate with Juuno
48
+ logout Remove stored credentials
49
+ whoami Show authentication status
56
50
  dev Launch the app simulator (default)
57
- deploy Deploy your app to Juuno CDN
51
+ deploy Deploy your app to Juuno
52
+ list List your deployed apps
53
+ info <app-id> Show detailed information about an app
58
54
  help Show this help message
59
55
 
56
+ Authentication Commands:
57
+ login [--email <email>] [--password <pwd>]
58
+ Authenticate and save credentials to ~/.juuno/credentials.json
59
+ Subsequent commands will use the saved token automatically.
60
+
61
+ logout
62
+ Remove stored credentials.
63
+
64
+ whoami
65
+ Show current authentication status.
66
+
60
67
  Simulator Options:
61
68
  --app <url> URL of your external app (required)
62
69
  --port <number> Port for simulator (default: 5004)
63
70
 
64
71
  Deploy Options:
65
- --build-dir <dir> Build directory to deploy (default: ./dist)
66
- --api-key <key> Juuno API key (will prompt if not provided)
72
+ --build-dir <dir> Build directory to deploy (default: ./dist)
73
+
74
+ Authentication Options (for deploy, list, info):
75
+ By default, these commands use the token saved by 'juuno-cli login'.
76
+ You can override with:
77
+ --token <token> Use specific token (for CI/CD)
78
+ --email <email> Login with email/password (skips saved token)
79
+ --password <pwd> Use with --email
80
+
81
+ Environment Variables:
82
+ JUUNO_API_URL API URL (default: https://api.juuno.co)
83
+ JUUNO_API_TOKEN Authentication token (for CI/CD, skips saved credentials)
67
84
 
68
85
  Examples:
86
+ # Authenticate (one-time setup)
87
+ juuno-cli login
88
+
69
89
  # Start simulator
70
90
  juuno-cli dev --app http://localhost:3000
71
- juuno-cli --app http://localhost:3000
72
91
 
73
- # Deploy app
92
+ # Deploy app (uses saved credentials)
74
93
  juuno-cli deploy
75
- juuno-cli deploy --build-dir ./dist --api-key your-api-key
94
+ juuno-cli deploy --build-dir ./dist
95
+
96
+ # List apps (uses saved credentials)
97
+ juuno-cli list
98
+
99
+ # Show app info (uses saved credentials)
100
+ juuno-cli info app_abc123
101
+
102
+ # Check authentication status
103
+ juuno-cli whoami
104
+
105
+ # Logout
106
+ juuno-cli logout
76
107
  `);
77
108
  process.exit(0);
78
109
  }
79
110
 
111
+ // Handle login command.
112
+ if (command === 'login') {
113
+ const { login } = await import('../dist/cli/src/login/index.js');
114
+
115
+ const authOptions = parseAuthOptions(args);
116
+
117
+ await login({ email: authOptions.email, password: authOptions.password });
118
+ process.exit(0);
119
+ }
120
+
121
+ // Handle logout command.
122
+ if (command === 'logout') {
123
+ const { logout } = await import('../dist/cli/src/logout/index.js');
124
+
125
+ await logout();
126
+ process.exit(0);
127
+ }
128
+
129
+ // Handle whoami command.
130
+ if (command === 'whoami') {
131
+ const { whoami } = await import('../dist/cli/src/whoami/index.js');
132
+
133
+ await whoami();
134
+ process.exit(0);
135
+ }
136
+
137
+ // Handle deploy command.
138
+ if (command === 'deploy') {
139
+ const { deployApp } = await import('../dist/cli/src/deploy/index.js');
140
+
141
+ const buildDirIndex = args.indexOf('--build-dir');
142
+ const buildDir = buildDirIndex !== -1 ? args[buildDirIndex + 1] : './dist';
143
+
144
+ const authOptions = parseAuthOptions(args);
145
+
146
+ await deployApp({ buildDir, ...authOptions });
147
+ process.exit(0);
148
+ }
149
+
150
+ // Handle list command.
151
+ if (command === 'list') {
152
+ const { listApps } = await import('../dist/cli/src/list/index.js');
153
+
154
+ const authOptions = parseAuthOptions(args);
155
+
156
+ await listApps(authOptions);
157
+ process.exit(0);
158
+ }
159
+
160
+ // Handle info command.
161
+ if (command === 'info') {
162
+ const { getAppInfo } = await import('../dist/cli/src/info/index.js');
163
+
164
+ const appIdx = args[1];
165
+
166
+ if (!appIdx || appIdx.startsWith('--')) {
167
+ console.error('Error: App ID is required');
168
+ console.error('Usage: juuno-cli info <app-id> [options]');
169
+ process.exit(1);
170
+ }
171
+
172
+ const authOptions = parseAuthOptions(args);
173
+
174
+ await getAppInfo({ appIdx, ...authOptions });
175
+ process.exit(0);
176
+ }
177
+
178
+ // Handle simulator command (default behavior).
179
+ // Remove the command from args if it was 'dev'.
180
+ if (command === 'dev') {
181
+ args.shift();
182
+ }
183
+ const appUrlIndex = args.indexOf('--app');
184
+ const portIndex = args.indexOf('--port');
185
+
80
186
  if (appUrlIndex === -1) {
81
187
  console.error('Error: --app parameter is required for simulator');
82
188
  console.error('Usage: juuno-cli dev --app <url>');
@@ -92,14 +198,14 @@ if (!appUrl) {
92
198
  process.exit(1);
93
199
  }
94
200
 
95
- // Path to the built dist directory
201
+ // Path to the built dist directory.
96
202
  const distPath = join(__dirname, '..', 'dist');
97
203
 
98
- // Create a temporary directory for the modified dist
204
+ // Create a temporary directory for the modified dist.
99
205
  const tempDir = join(tmpdir(), `juuno-simulator-${Date.now()}`);
100
206
  mkdirSync(tempDir, { recursive: true });
101
207
 
102
- // Copy all files from dist to temp directory
208
+ // Copy all files from dist to temp directory.
103
209
  function copyDir(src, dest) {
104
210
  const entries = readdirSync(src, { withFileTypes: true });
105
211
 
@@ -118,11 +224,11 @@ function copyDir(src, dest) {
118
224
 
119
225
  copyDir(distPath, tempDir);
120
226
 
121
- // Inject the app URL and import map CDN URLs into index.html
227
+ // Inject the app URL and import map CDN URLs into index.html.
122
228
  const indexPath = join(tempDir, 'index.html');
123
229
  let indexHtml = readFileSync(indexPath, 'utf-8');
124
230
 
125
- // Fill in the import map with CDN URLs for vue and @juuno-sdk/app-sdk
231
+ // Fill in the import map with CDN URLs for vue and @juuno-sdk/app-sdk.
126
232
  indexHtml = indexHtml.replace(
127
233
  '"vue": ""',
128
234
  '"vue": "https://cdn.jsdelivr.net/npm/vue@3.5.22/dist/vue.esm-browser.prod.js"',
@@ -132,7 +238,7 @@ indexHtml = indexHtml.replace(
132
238
  '"@juuno-sdk/app-sdk": "https://cdn.jsdelivr.net/npm/@juuno-sdk/app-sdk@1.0.2/dist/index.js"',
133
239
  );
134
240
 
135
- // Fill in CDN URLs for externalized dependencies from the SDK
241
+ // Fill in CDN URLs for externalized dependencies from the SDK.
136
242
  indexHtml = indexHtml.replace(
137
243
  '"@vueuse/core": ""',
138
244
  '"@vueuse/core": "https://cdn.jsdelivr.net/npm/@vueuse/core@11.4.1/index.mjs"',
@@ -162,7 +268,7 @@ indexHtml = indexHtml.replace(
162
268
  '"url-parse": "https://cdn.jsdelivr.net/npm/url-parse@1.5.10/dist/url-parse.min.js"',
163
269
  );
164
270
 
165
- // Fill in the import map with external app entrypoints
271
+ // Fill in the import map with external app entrypoints.
166
272
  indexHtml = indexHtml.replace(
167
273
  '"external-app/player": ""',
168
274
  `"external-app/player": "${appUrl}/player/index.js"`,
@@ -172,7 +278,7 @@ indexHtml = indexHtml.replace(
172
278
  `"external-app/config": "${appUrl}/config/index.js"`,
173
279
  );
174
280
 
175
- // Inject the app URL as a global variable before any scripts load
281
+ // Inject the app URL as a global variable before any scripts load.
176
282
  const injection = `
177
283
  <script>
178
284
  window.__JUUNO_EXTERNAL_APP_URL__ = '${appUrl}';
@@ -191,7 +297,7 @@ console.log(`
191
297
  Press Ctrl+C to stop
192
298
  `);
193
299
 
194
- // Serve the modified temp directory
300
+ // Serve the modified temp directory.
195
301
  const server = spawn(
196
302
  'npx',
197
303
  ['sirv-cli', tempDir, '--port', port, '--cors', '--single'],
@@ -213,16 +319,16 @@ server.on('exit', (code) => {
213
319
  process.exit(code);
214
320
  });
215
321
 
216
- // Cleanup function
322
+ // Cleanup function.
217
323
  function cleanup() {
218
324
  try {
219
325
  rmSync(tempDir, { recursive: true, force: true });
220
326
  } catch (err) {
221
- // Ignore cleanup errors
327
+ // Ignore cleanup errors.
222
328
  }
223
329
  }
224
330
 
225
- // Handle termination
331
+ // Handle termination.
226
332
  process.on('SIGINT', () => {
227
333
  console.log('\n\nšŸ‘‹ Stopping simulator...');
228
334
  server.kill();
@@ -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"}