@freeappstore/cli 0.4.37 → 0.4.38

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.
@@ -1,3 +1,8 @@
1
1
  import { Command } from 'commander';
2
2
  export declare const logsCommand: Command;
3
+ /**
4
+ * Success only on exit code 0. A process killed by a signal exits with code
5
+ * null, which used to count as success (#283).
6
+ */
7
+ export declare function ghExitError(code: number | null, signal: NodeJS.Signals | null): Error | null;
3
8
  //# sourceMappingURL=logs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,WAAW,SAyBpB,CAAC"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,WAAW,SA0BpB,CAAC;AAEL;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAK5F"}
@@ -20,12 +20,22 @@ export const logsCommand = new Command('logs')
20
20
  rejectFn(err);
21
21
  }
22
22
  });
23
- child.on('exit', (code) => {
24
- if (code === 0 || code === null)
25
- resolveFn();
23
+ child.on('exit', (code, signal) => {
24
+ const err = ghExitError(code, signal);
25
+ if (err)
26
+ rejectFn(err);
26
27
  else
27
- rejectFn(new Error(`gh exited with code ${code}`));
28
+ resolveFn();
28
29
  });
29
30
  });
30
31
  });
32
+ /**
33
+ * Success only on exit code 0. A process killed by a signal exits with code
34
+ * null, which used to count as success (#283).
35
+ */
36
+ export function ghExitError(code, signal) {
37
+ if (code === 0)
38
+ return null;
39
+ return new Error(code === null ? `gh was stopped by ${signal ?? 'a signal'}` : `gh exited with code ${code}`);
40
+ }
31
41
  //# sourceMappingURL=logs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,sDAAsD,CAAC;KACnE,QAAQ,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACxD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAExB,MAAM,IAAI,GAAG,uBAAuB,KAAK,EAAE,CAAC;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,OAAO,CAAC,CAAC;IAEhE,MAAM,IAAI,OAAO,CAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;YAC1E,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,QAAQ,CAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI;gBAAE,SAAS,EAAE,CAAC;;gBACxC,QAAQ,CAAC,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,sDAAsD,CAAC;KACnE,QAAQ,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACxD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAExB,MAAM,IAAI,GAAG,uBAAuB,KAAK,EAAE,CAAC;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,OAAO,CAAC,CAAC;IAEhE,MAAM,IAAI,OAAO,CAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;YAC1E,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,QAAQ,CAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtC,IAAI,GAAG;gBAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;;gBAClB,SAAS,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAmB,EAAE,MAA6B;IAC5E,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,IAAI,KAAK,CACd,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,qBAAqB,MAAM,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,uBAAuB,IAAI,EAAE,CAC5F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.test.d.ts","sourceRoot":"","sources":["../../src/commands/logs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ghExitError } from './logs.js';
3
+ // #283: a gh killed by a signal (exit code null) counted as success.
4
+ describe('ghExitError', () => {
5
+ it('is null only for exit code 0', () => {
6
+ expect(ghExitError(0, null)).toBeNull();
7
+ });
8
+ it('fails on a non-zero code', () => {
9
+ expect(ghExitError(1, null)?.message).toBe('gh exited with code 1');
10
+ });
11
+ it('fails when gh was killed by a signal', () => {
12
+ expect(ghExitError(null, 'SIGTERM')?.message).toBe('gh was stopped by SIGTERM');
13
+ });
14
+ });
15
+ //# sourceMappingURL=logs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.test.js","sourceRoot":"","sources":["../../src/commands/logs.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qEAAqE;AACrE,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,3 +1,10 @@
1
1
  import { Command } from 'commander';
2
+ import { type FasConfig } from '../lib/config.js';
2
3
  export declare const whoamiCommand: Command;
4
+ /**
5
+ * The session line. sessionDaysRemaining() is null both when there's no
6
+ * session token and when an older CLI saved one without a timestamp; only
7
+ * the second is active (#283).
8
+ */
9
+ export declare function sessionStatus(config: FasConfig): string;
3
10
  //# sourceMappingURL=whoami.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,eAAO,MAAM,aAAa,SAsBtB,CAAC"}
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,kBAAkB,CAAC;AAEpF,eAAO,MAAM,aAAa,SAatB,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAMvD"}
@@ -11,15 +11,21 @@ export const whoamiCommand = new Command('whoami')
11
11
  process.stdout.write(`@${config.github.login}\n`);
12
12
  // Surface session health so an expired token is self-diagnosable here
13
13
  // rather than as a surprise 401 mid-publish.
14
- const daysLeft = sessionDaysRemaining(config);
15
- if (daysLeft === null) {
16
- process.stdout.write('Session: active\n');
17
- }
18
- else if (daysLeft <= 0) {
19
- process.stdout.write('Session: expired — run `fas login` to refresh.\n');
20
- }
21
- else {
22
- process.stdout.write(`Session: active, expires in ${daysLeft} day${daysLeft === 1 ? '' : 's'}.\n`);
23
- }
14
+ process.stdout.write(`${sessionStatus(config)}\n`);
24
15
  });
16
+ /**
17
+ * The session line. sessionDaysRemaining() is null both when there's no
18
+ * session token and when an older CLI saved one without a timestamp; only
19
+ * the second is active (#283).
20
+ */
21
+ export function sessionStatus(config) {
22
+ if (!config.session?.token)
23
+ return 'Session: none — run `fas login` to sign in to the API.';
24
+ const daysLeft = sessionDaysRemaining(config);
25
+ if (daysLeft === null)
26
+ return 'Session: active (expiry unknown)';
27
+ if (daysLeft <= 0)
28
+ return 'Session: expired — run `fas login` to refresh.';
29
+ return `Session: active, expires in ${daysLeft} day${daysLeft === 1 ? '' : 's'}.`;
30
+ }
25
31
  //# sourceMappingURL=whoami.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAElD,sEAAsE;IACtE,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+BAA+B,QAAQ,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAC7E,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAkB,UAAU,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEpF,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAElD,sEAAsE;IACtE,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEL;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK;QAAE,OAAO,wDAAwD,CAAC;IAC5F,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,kCAAkC,CAAC;IACjE,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,gDAAgD,CAAC;IAC3E,OAAO,+BAA+B,QAAQ,OAAO,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AACpF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=whoami.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.test.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { sessionStatus } from './whoami.js';
3
+ const DAY = 24 * 60 * 60 * 1000;
4
+ const github = { login: 'alice', token: 'gh' };
5
+ // #283: a missing session token used to print "Session: active".
6
+ describe('sessionStatus', () => {
7
+ it('says there is no session when the token is missing', () => {
8
+ expect(sessionStatus({ github })).toBe('Session: none — run `fas login` to sign in to the API.');
9
+ });
10
+ it('is active with unknown expiry for a token saved without a timestamp', () => {
11
+ expect(sessionStatus({ github, session: { token: 't' } })).toBe('Session: active (expiry unknown)');
12
+ });
13
+ it('counts down and reports expiry', () => {
14
+ expect(sessionStatus({ github, session: { token: 't', obtainedAt: Date.now() - DAY } })).toMatch(/^Session: active, expires in \d+ days\.$/);
15
+ expect(sessionStatus({
16
+ github,
17
+ session: { token: 't', obtainedAt: Date.now() - 400 * DAY },
18
+ })).toBe('Session: expired — run `fas login` to refresh.');
19
+ });
20
+ });
21
+ //# sourceMappingURL=whoami.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.test.js","sourceRoot":"","sources":["../../src/commands/whoami.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAChC,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAE/C,iEAAiE;AACjE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAW,CAAC,CAAC,CAAC,IAAI,CAC7C,wDAAwD,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAW,CAAC,CAAC,CAAC,IAAI,CACtE,kCAAkC,CACnC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CACJ,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAW,CAAC,CAC1F,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;QACtD,MAAM,CACJ,aAAa,CAAC;YACZ,MAAM;YACN,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,EAAE;SACnD,CAAC,CACZ,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freeappstore/cli",
3
- "version": "0.4.37",
3
+ "version": "0.4.38",
4
4
  "description": "fas — CLI for publishing free apps to freeappstore.online",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,8 +37,8 @@
37
37
  "ink-spinner": "^5.0.0",
38
38
  "prompts": "^2.4.2",
39
39
  "react": "^19.3.0",
40
- "@freeappstore/quality": "0.1.4",
41
- "@freeappstore/compliance": "0.7.15"
40
+ "@freeappstore/compliance": "0.7.16",
41
+ "@freeappstore/quality": "0.1.4"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^22.20.2",