anentrypoint-design 0.0.192 → 0.0.193

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.192",
3
+ "version": "0.0.193",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -464,17 +464,52 @@ export const config = makePage((ctx) => {
464
464
  // ---- env -------------------------------------------------------------------
465
465
 
466
466
  export const env = makePage((ctx) => {
467
- async function load() { try { ctx.set({ loading: false, data: await api('/api/env'), error: null }); } catch (e) { ctx.set({ loading: false, error: e }); } }
467
+ Object.assign(ctx.state, { auth: null, vars: null, draft: {}, busy: '', note: null });
468
+ async function load() {
469
+ try {
470
+ const [auth, vars] = await Promise.all([api('/api/auth').catch(() => null), api('/api/env').catch(() => null)]);
471
+ ctx.set({ loading: false, auth, vars, error: null });
472
+ } catch (e) { ctx.set({ loading: false, error: e }); }
473
+ }
474
+ // Set a provider key through the dashboard (POST /api/auth). The key is sent
475
+ // once and never echoed back — GET /api/auth returns only a masked fingerprint.
476
+ async function setKey(provider) {
477
+ const key = (ctx.state.draft[provider] || '').trim();
478
+ if (!key) { ctx.set({ note: { kind: 'warn', msg: 'key required for ' + provider } }); return; }
479
+ ctx.set({ busy: provider, note: null });
480
+ try { await api('/api/auth', { method: 'POST', body: { provider, key } }); ctx.state.draft[provider] = ''; await load(); ctx.set({ note: { kind: 'success', msg: 'stored ' + provider } }); }
481
+ catch (e) { ctx.set({ note: { kind: 'error', msg: String(e.message || e) } }); }
482
+ ctx.set({ busy: '' });
483
+ }
484
+ async function removeKey(provider) {
485
+ ctx.set({ busy: provider, note: null });
486
+ try { await api('/api/auth/' + encodeURIComponent(provider), { method: 'DELETE' }); await load(); ctx.set({ note: { kind: 'success', msg: 'removed ' + provider } }); }
487
+ catch (e) { ctx.set({ note: { kind: 'error', msg: String(e.message || e) } }); }
488
+ ctx.set({ busy: '' });
489
+ }
468
490
  load();
469
491
  return () => {
470
492
  const s = ctx.state;
471
- if (s.loading) return loadingState('loading environment…');
472
- if (s.error) return errorState(s.error, load);
473
- const d = s.data || {};
474
- const rows = Object.entries(d).map(([k, v]) => [k, v === true || v === 'set' ? Chip({ tone: 'ok', children: 'set' }) : (v ? truncSpan(v, TRUNC_SUB) : Chip({ tone: 'neutral', children: 'unset' }))]);
493
+ if (s.loading) return loadingState('loading keys…');
494
+ if (s.error && !s.auth) return errorState(s.error, load);
495
+ const auth = Array.isArray(s.auth) ? s.auth : [];
496
+ const vars = Array.isArray(s.vars) ? s.vars : [];
497
+ // Non-provider env vars (platform tokens etc) stay a read-only presence table.
498
+ const providerEnvs = new Set(auth.map(a => a.env));
499
+ const otherRows = vars.filter(v => !providerEnvs.has(v.key)).map(v => [v.key, v.set ? Chip({ tone: 'ok', children: v.source || 'set' }) : Chip({ tone: 'neutral', children: 'unset' })]);
475
500
  return [
476
- PageHeader({ eyebrow: 'freddie', title: 'env', lede: 'environment / key presence' }),
477
- section('variables', rows.length ? Table({ headers: ['key', 'status'], rows }) : emptyState('no env data')),
501
+ PageHeader({ eyebrow: 'freddie', title: 'keys', lede: 'provider api keys · stored locally, never displayed' }),
502
+ noteAlert(s.note),
503
+ section('provider keys',
504
+ auth.length ? auth.map((a, i) => Row({
505
+ key: i, title: a.provider, sub: a.env + (a.set ? ' · ' + a.source + (a.fingerprint ? ' · ' + a.fingerprint : '') : ''),
506
+ trailing: h('span', { class: 'fd-row-actions' },
507
+ a.set ? Chip({ tone: 'ok', children: 'set' }) : Chip({ tone: 'neutral', children: 'unset' }),
508
+ TextField({ type: 'password', value: s.draft[a.provider] || '', onInput: (v) => { s.draft[a.provider] = v; }, placeholder: 'paste key', 'aria-label': 'key for ' + a.provider }),
509
+ Btn({ primary: true, disabled: s.busy === a.provider, children: s.busy === a.provider ? '…' : 'save', onClick: () => setKey(a.provider) }),
510
+ (a.set && a.source === 'stored') ? Btn({ danger: true, disabled: s.busy === a.provider, children: 'remove', onClick: () => removeKey(a.provider) }) : null),
511
+ })) : emptyState('no providers')),
512
+ otherRows.length ? section('other environment', Table({ headers: ['key', 'status'], rows: otherRows })) : null,
478
513
  ];
479
514
  };
480
515
  });