@freeappstore/cli 0.1.2 → 0.1.3

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.
@@ -15,6 +15,12 @@ export interface FasConfig {
15
15
  obtainedAt: number;
16
16
  };
17
17
  }
18
+ /**
19
+ * Strips trailing slashes so callers can do `${apiBase}/v1/foo` without
20
+ * worrying about producing `https://host//v1/foo`. Defensive: a stored or
21
+ * env-supplied value with a trailing slash is normalised on read.
22
+ */
23
+ export declare function normalizeApiBase(s: string): string;
18
24
  export declare function readConfig(): Promise<FasConfig>;
19
25
  export declare function writeConfig(config: FasConfig): Promise<void>;
20
26
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAMD,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAQrD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CASrD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlE"}
@@ -6,14 +6,23 @@ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
6
6
  const DEFAULT_CONFIG = {
7
7
  apiBase: process.env['FAS_API_BASE'] ?? 'https://api.freeappstore.online',
8
8
  };
9
+ /**
10
+ * Strips trailing slashes so callers can do `${apiBase}/v1/foo` without
11
+ * worrying about producing `https://host//v1/foo`. Defensive: a stored or
12
+ * env-supplied value with a trailing slash is normalised on read.
13
+ */
14
+ export function normalizeApiBase(s) {
15
+ return s.replace(/\/+$/, '');
16
+ }
9
17
  export async function readConfig() {
10
18
  try {
11
19
  const raw = await readFile(CONFIG_FILE, 'utf8');
12
20
  const parsed = JSON.parse(raw);
13
- return { ...DEFAULT_CONFIG, ...parsed };
21
+ const merged = { ...DEFAULT_CONFIG, ...parsed };
22
+ return { ...merged, apiBase: normalizeApiBase(merged.apiBase) };
14
23
  }
15
24
  catch {
16
- return { ...DEFAULT_CONFIG };
25
+ return { ...DEFAULT_CONFIG, apiBase: normalizeApiBase(DEFAULT_CONFIG.apiBase) };
17
26
  }
18
27
  }
19
28
  export async function writeConfig(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAoBpD,MAAM,cAAc,GAAc;IAChC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,iCAAiC;CAC1E,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAuB,CAAC;QACrD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAiB;IACjD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/E,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAoBpD,MAAM,cAAc,GAAc;IAChC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,iCAAiC;CAC1E,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAuB,CAAC;QACrD,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAChD,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;IAClF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAiB;IACjD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/E,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { normalizeApiBase } from './config.js';
3
+ describe('normalizeApiBase', () => {
4
+ it('leaves a clean URL alone', () => {
5
+ expect(normalizeApiBase('https://api.freeappstore.online')).toBe('https://api.freeappstore.online');
6
+ });
7
+ it('strips a single trailing slash (regression: //health URLs)', () => {
8
+ expect(normalizeApiBase('https://api.freeappstore.online/')).toBe('https://api.freeappstore.online');
9
+ });
10
+ it('strips multiple trailing slashes', () => {
11
+ expect(normalizeApiBase('https://api.freeappstore.online////')).toBe('https://api.freeappstore.online');
12
+ });
13
+ it('preserves path segments and only strips the rightmost slashes', () => {
14
+ expect(normalizeApiBase('https://api.example.com/v1/')).toBe('https://api.example.com/v1');
15
+ expect(normalizeApiBase('https://api.example.com/v1//')).toBe('https://api.example.com/v1');
16
+ });
17
+ it('handles localhost dev URLs', () => {
18
+ expect(normalizeApiBase('http://localhost:8787/')).toBe('http://localhost:8787');
19
+ expect(normalizeApiBase('http://127.0.0.1:8787')).toBe('http://127.0.0.1:8787');
20
+ });
21
+ });
22
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/lib/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,gBAAgB,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAC9D,iCAAiC,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC,CAAC,IAAI,CAC/D,iCAAiC,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,gBAAgB,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CAClE,iCAAiC,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC3F,MAAM,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACjF,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAcA,wBAAgB,GAAG,IAAI,KAAK,CAAC,YAAY,CAwCxC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAcA,wBAAgB,GAAG,IAAI,KAAK,CAAC,YAAY,CAkDxC"}
package/dist/tui/App.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Box, Text, useApp, useInput } from 'ink';
2
+ import { Box, Text, useApp } from 'ink';
3
3
  import { useEffect, useState } from 'react';
4
4
  import { Doctor } from './screens/Doctor.js';
5
5
  import { Menu } from './screens/Menu.js';
@@ -10,18 +10,29 @@ export function App() {
10
10
  const [screen, setScreen] = useState('welcome');
11
11
  const [session, setSession] = useState({ loaded: false, login: null });
12
12
  useEffect(() => {
13
+ let active = true;
13
14
  void (async () => {
14
- const config = await readConfig();
15
- const login = config.github?.login ?? null;
15
+ let login = null;
16
+ try {
17
+ const config = await readConfig();
18
+ login = config.github?.login ?? null;
19
+ }
20
+ catch {
21
+ // Corrupt or unreadable config — degrade to "not signed in" rather
22
+ // than getting stuck on the loading spinner forever.
23
+ }
24
+ if (!active)
25
+ return;
16
26
  setSession({ loaded: true, login });
17
27
  setScreen(login ? 'menu' : 'welcome');
18
28
  })();
29
+ return () => {
30
+ active = false;
31
+ };
19
32
  }, []);
20
- // Global keys: q to quit, except while typing into an input.
21
- useInput((input, key) => {
22
- if (input === 'q' && !key.shift)
23
- exit();
24
- });
33
+ // No global 'q'-to-quit handler at the App level — child screens with
34
+ // text inputs (NewApp wizard) need to receive 'q' as input. Each screen
35
+ // owns its own keyboard shortcuts. Ctrl-C still exits via ink's default.
25
36
  if (!session.loaded) {
26
37
  return (_jsx(Box, { children: _jsx(Text, { children: "Loading\u2026" }) }));
27
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Doctor.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/Doctor.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAoC5D"}
1
+ {"version":3,"file":"Doctor.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/Doctor.tsx"],"names":[],"mappings":"AAKA,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CA2C5D"}
@@ -6,9 +6,17 @@ import { runDoctor } from '../../one-shot/doctor.js';
6
6
  export function Doctor({ onBack }) {
7
7
  const [results, setResults] = useState(null);
8
8
  useEffect(() => {
9
+ // Track mount so we don't call setResults on an unmounted component
10
+ // if the user navigates away while checks are still running.
11
+ let active = true;
9
12
  void (async () => {
10
- setResults(await runDoctor());
13
+ const r = await runDoctor();
14
+ if (active)
15
+ setResults(r);
11
16
  })();
17
+ return () => {
18
+ active = false;
19
+ };
12
20
  }, []);
13
21
  useInput((input, key) => {
14
22
  if (key.escape || input === 'b')
@@ -1 +1 @@
1
- {"version":3,"file":"Doctor.js","sourceRoot":"","sources":["../../../src/tui/screens/Doctor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAoB,MAAM,0BAA0B,CAAC;AAMvE,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM,EAAS;IACtC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IAEnE,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,UAAU,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG;YAAE,MAAM,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAChB,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAClB,EACP,KAAC,IAAI,wCAAwB,IACzB,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAClB,KAAC,SAAS,IAAc,MAAM,EAAE,CAAC,IAAjB,CAAC,CAAC,IAAI,CAAe,CACtC,CAAC,EACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,iDAEpB,GACH,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,MAAM,EAA2B;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/F,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnF,OAAO,CACL,MAAC,GAAG,eACF,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,aACf,IAAI,EACJ,IAAI,IACA,EACP,KAAC,IAAI,cAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAQ,EACrC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,kBACxB,MAAM,CAAC,MAAM,GACT,IACH,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Doctor.js","sourceRoot":"","sources":["../../../src/tui/screens/Doctor.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAoB,MAAM,0BAA0B,CAAC;AAMvE,MAAM,UAAU,MAAM,CAAC,EAAE,MAAM,EAAS;IACtC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IAEnE,SAAS,CAAC,GAAG,EAAE;QACb,oEAAoE;QACpE,6DAA6D;QAC7D,IAAI,MAAM,GAAG,IAAI,CAAC;QAClB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;YAC5B,IAAI,MAAM;gBAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG;YAAE,MAAM,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAChB,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAClB,EACP,KAAC,IAAI,wCAAwB,IACzB,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAClB,KAAC,SAAS,IAAc,MAAM,EAAE,CAAC,IAAjB,CAAC,CAAC,IAAI,CAAe,CACtC,CAAC,EACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,iDAEpB,GACH,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,MAAM,EAA2B;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/F,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnF,OAAO,CACL,MAAC,GAAG,eACF,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,aACf,IAAI,EACJ,IAAI,IACA,EACP,KAAC,IAAI,cAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAQ,EACrC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,kBACxB,MAAM,CAAC,MAAM,GACT,IACH,CACP,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/Menu.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAO3C,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAgBnE"}
1
+ {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/Menu.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAO3C,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAsBnE"}
@@ -1,11 +1,17 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Box, Text } from 'ink';
2
+ import { Box, Text, useInput } from 'ink';
3
3
  import SelectInput from 'ink-select-input';
4
4
  export function Menu({ login, onSelect }) {
5
5
  const items = [
6
6
  { label: 'Doctor — run health checks', value: 'doctor' },
7
7
  { label: 'Quit', value: 'quit' },
8
8
  ];
9
+ // Menu-scoped keyboard shortcut. Lives here (not at App level) so it
10
+ // doesn't fire when a child screen has a text input.
11
+ useInput((input) => {
12
+ if (input === 'q')
13
+ onSelect('quit');
14
+ });
9
15
  return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [login ? `Signed in as @${login}.` : 'Not signed in.', " What would you like to do?"] }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: items, onSelect: (item) => onSelect(item.value) }) })] }));
10
16
  }
11
17
  //# sourceMappingURL=Menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../src/tui/screens/Menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAc3C,MAAM,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IAC7C,MAAM,KAAK,GAAW;QACpB,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,QAAQ,EAAE;QACxD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;KACjC,CAAC;IAEF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,eACF,KAAK,CAAC,CAAC,CAAC,iBAAiB,KAAK,GAAG,CAAC,CAAC,CAAC,gBAAgB,mCAChD,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IAAa,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAI,GAC/E,IACF,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../src/tui/screens/Menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAc3C,MAAM,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IAC7C,MAAM,KAAK,GAAW;QACpB,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,QAAQ,EAAE;QACxD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;KACjC,CAAC;IAEF,qEAAqE;IACrE,qDAAqD;IACrD,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,IAAI,KAAK,KAAK,GAAG;YAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,eACF,KAAK,CAAC,CAAC,CAAC,iBAAiB,KAAK,GAAG,CAAC,CAAC,CAAC,gBAAgB,mCAChD,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IAAa,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAI,GAC/E,IACF,CACP,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freeappstore/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "fas — CLI for publishing free apps to freeappstore.online",
5
5
  "license": "MIT",
6
6
  "type": "module",