@trendify/cli 0.1.28 → 0.1.30

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/dist/cli.entry.js CHANGED
@@ -2,7 +2,8 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { render } from 'ink';
4
4
  import { App } from './app.component.js';
5
- import { getInstalledCliMetadata, runCliSelfUpdate } from './shared/services/cli-update.service.js';
5
+ import { CLI_UPDATE_REQUEST_EXIT_CODE } from './shared/constants/process-exit-code.constant.js';
6
+ import { getInstalledCliMetadata, requestCliSelfUpdate } from './shared/services/cli-update.service.js';
6
7
  const { packageVersion: APP_VERSION } = getInstalledCliMetadata();
7
8
  const args = process.argv.slice(2);
8
9
  const initialInput = args
@@ -65,6 +66,17 @@ async function unmountApp() {
65
66
  await currentInstance.waitUntilExit().catch(() => undefined);
66
67
  currentInstance.cleanup();
67
68
  }
69
+ function prepareTerminalForProcessExit() {
70
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === 'function' && process.stdin.isRaw) {
71
+ try {
72
+ process.stdin.setRawMode(false);
73
+ }
74
+ catch {
75
+ // Ignore tty cleanup failures during shutdown.
76
+ }
77
+ }
78
+ process.stdin.pause();
79
+ }
68
80
  function mountApp(feedback = null) {
69
81
  resetTerminalScreen();
70
82
  appInstance = render(_jsx(App, { appVersion: APP_VERSION, initialInput: initialInput, initialNotification: feedback?.message ?? null, initialNotificationTone: feedback?.tone ?? 'success', onSelfUpdate: async (update) => {
@@ -72,12 +84,13 @@ function mountApp(feedback = null) {
72
84
  resetTerminalScreen();
73
85
  process.stdout.write([
74
86
  `Preparando a atualizacao do CLI para v${update.latestVersion}.`,
75
- 'O atualizador externo vai assumir o processo em seguida.',
87
+ 'A aplicacao atual sera encerrada e o launcher externo assumira o terminal.',
76
88
  '',
77
89
  ].join('\n'));
78
- const result = await runCliSelfUpdate(update.packageName, update.latestVersion);
90
+ const result = await requestCliSelfUpdate(update.packageName, update.latestVersion);
79
91
  if (result.ok) {
80
- process.exit(0);
92
+ prepareTerminalForProcessExit();
93
+ process.exit(CLI_UPDATE_REQUEST_EXIT_CODE);
81
94
  }
82
95
  process.stdout.write(`\nFalha ao atualizar automaticamente: ${result.error}\n`);
83
96
  process.stdout.write('A CLI atual continuara disponivel.\n');
@@ -1,4 +1,6 @@
1
1
  export declare const TRENDIFY_HOME_DIR: string;
2
2
  export declare const TRENDIFY_AUTH_DIR: string;
3
3
  export declare const TRENDIFY_AUTH_STORAGE_FILE: string;
4
+ export declare const TRENDIFY_RUNTIME_DIR: string;
5
+ export declare const TRENDIFY_UPDATE_STATE_FILE: string;
4
6
  //# sourceMappingURL=app-paths.config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-paths.config.d.ts","sourceRoot":"","sources":["../../../src/shared/config/app-paths.config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAkC,CAAC;AACjE,eAAO,MAAM,0BAA0B,QAA0C,CAAC"}
1
+ {"version":3,"file":"app-paths.config.d.ts","sourceRoot":"","sources":["../../../src/shared/config/app-paths.config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAkC,CAAC;AACjE,eAAO,MAAM,0BAA0B,QAA0C,CAAC;AAClF,eAAO,MAAM,oBAAoB,QAAqC,CAAC;AACvE,eAAO,MAAM,0BAA0B,QAAiD,CAAC"}
@@ -3,3 +3,5 @@ import { join } from 'node:path';
3
3
  export const TRENDIFY_HOME_DIR = join(homedir(), '.trendify');
4
4
  export const TRENDIFY_AUTH_DIR = join(TRENDIFY_HOME_DIR, 'auth');
5
5
  export const TRENDIFY_AUTH_STORAGE_FILE = join(TRENDIFY_AUTH_DIR, 'storage.json');
6
+ export const TRENDIFY_RUNTIME_DIR = join(TRENDIFY_HOME_DIR, 'runtime');
7
+ export const TRENDIFY_UPDATE_STATE_FILE = join(TRENDIFY_RUNTIME_DIR, 'update-state.env');
@@ -0,0 +1,2 @@
1
+ export declare const CLI_UPDATE_REQUEST_EXIT_CODE = 42;
2
+ //# sourceMappingURL=process-exit-code.constant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-exit-code.constant.d.ts","sourceRoot":"","sources":["../../../src/shared/constants/process-exit-code.constant.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,KAAK,CAAC"}
@@ -0,0 +1 @@
1
+ export const CLI_UPDATE_REQUEST_EXIT_CODE = 42;
@@ -18,7 +18,7 @@ export type CliUpdateCheckResult = {
18
18
  readonly packageName: string;
19
19
  readonly status: 'error';
20
20
  };
21
- export type CliSelfUpdateResult = {
21
+ export type CliUpdateRequestResult = {
22
22
  readonly ok: true;
23
23
  } | {
24
24
  readonly error: string;
@@ -30,6 +30,6 @@ type InstalledPackageMetadata = {
30
30
  };
31
31
  export declare function getInstalledCliMetadata(): InstalledPackageMetadata;
32
32
  export declare function checkForCliUpdate(): Promise<CliUpdateCheckResult>;
33
- export declare function runCliSelfUpdate(packageName: string, latestVersion: string): Promise<CliSelfUpdateResult>;
33
+ export declare function requestCliSelfUpdate(packageName: string, latestVersion: string): Promise<CliUpdateRequestResult>;
34
34
  export {};
35
35
  //# sourceMappingURL=cli-update.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-update.service.d.ts","sourceRoot":"","sources":["../../../src/shared/services/cli-update.service.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,oBAAoB,GAC5B;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;CAC5B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AAEN,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAAC;AAgDF,wBAAgB,uBAAuB,IAAI,wBAAwB,CAElE;AAoLD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA6BvE;AAED,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAY/G"}
1
+ {"version":3,"file":"cli-update.service.d.ts","sourceRoot":"","sources":["../../../src/shared/services/cli-update.service.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,oBAAoB,GAC5B;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;CAC5B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEN,MAAM,MAAM,sBAAsB,GAC9B;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AAEN,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC,CAAC;AA4CF,wBAAgB,uBAAuB,IAAI,wBAAwB,CAElE;AAwHD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA6BvE;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAgBtH"}
@@ -1,6 +1,5 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { spawn, spawnSync } from 'node:child_process';
3
- import { fileURLToPath } from 'node:url';
2
+ import { writePendingCliUpdateRequest } from './update-request.service.js';
4
3
  const DEFAULT_PACKAGE_NAME = '@trendify/cli';
5
4
  const DEFAULT_PACKAGE_VERSION = '0.0.0';
6
5
  const DEFAULT_NPM_DIST_TAG = 'latest';
@@ -10,9 +9,6 @@ const VERSION_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/u;
10
9
  function getPackageManifestPath() {
11
10
  return new URL('../../../package.json', import.meta.url);
12
11
  }
13
- function getNpmCommand() {
14
- return process.platform === 'win32' ? 'npm.cmd' : 'npm';
15
- }
16
12
  function toErrorMessage(error) {
17
13
  if (error instanceof Error && error.message.trim()) {
18
14
  return error.message;
@@ -129,51 +125,6 @@ async function fetchLatestPublishedVersion(packageName) {
129
125
  }
130
126
  throw new Error(`Nao foi possivel consultar o dist-tag "${DEFAULT_NPM_DIST_TAG}" no registry do npm. ${toErrorMessage(lastError)}`);
131
127
  }
132
- function getBundledUpdaterScriptPath() {
133
- return fileURLToPath(new URL('../../../scripts/self-update.sh', import.meta.url));
134
- }
135
- function resolveTerminalPath() {
136
- if (!process.stdin.isTTY && !process.stdout.isTTY) {
137
- return null;
138
- }
139
- const ttyResult = spawnSync('tty', [], {
140
- encoding: 'utf8',
141
- stdio: ['inherit', 'pipe', 'ignore'],
142
- });
143
- if (ttyResult.status !== 0) {
144
- return null;
145
- }
146
- const ttyPath = ttyResult.stdout.trim();
147
- if (!ttyPath || ttyPath === 'not a tty') {
148
- return null;
149
- }
150
- return ttyPath;
151
- }
152
- async function spawnUpdaterProcess(packageName, currentVersion, latestVersion) {
153
- const ttyPath = resolveTerminalPath();
154
- const updaterScriptPath = getBundledUpdaterScriptPath();
155
- await new Promise((resolve, reject) => {
156
- const child = spawn('/bin/sh', [
157
- updaterScriptPath,
158
- packageName,
159
- currentVersion,
160
- latestVersion,
161
- String(process.pid),
162
- ttyPath ?? '',
163
- 'trendify',
164
- ...process.argv.slice(2),
165
- ], {
166
- env: process.env,
167
- stdio: 'inherit',
168
- });
169
- child.on('error', (error) => {
170
- reject(error);
171
- });
172
- child.on('spawn', () => {
173
- resolve();
174
- });
175
- });
176
- }
177
128
  export async function checkForCliUpdate() {
178
129
  const { packageName, packageVersion } = readInstalledPackageMetadata();
179
130
  try {
@@ -202,10 +153,14 @@ export async function checkForCliUpdate() {
202
153
  };
203
154
  }
204
155
  }
205
- export async function runCliSelfUpdate(packageName, latestVersion) {
156
+ export async function requestCliSelfUpdate(packageName, latestVersion) {
206
157
  try {
207
158
  const { packageVersion } = readInstalledPackageMetadata();
208
- await spawnUpdaterProcess(packageName, packageVersion, latestVersion);
159
+ await writePendingCliUpdateRequest({
160
+ currentVersion: packageVersion,
161
+ packageName,
162
+ targetVersion: latestVersion,
163
+ });
209
164
  return { ok: true };
210
165
  }
211
166
  catch (error) {
@@ -0,0 +1,10 @@
1
+ export type PendingCliUpdateRequest = {
2
+ readonly currentVersion: string;
3
+ readonly packageName: string;
4
+ readonly requestedAt: string;
5
+ readonly status: 'pending';
6
+ readonly targetVersion: string;
7
+ };
8
+ export declare function writePendingCliUpdateRequest(request: Omit<PendingCliUpdateRequest, 'requestedAt' | 'status'>): Promise<void>;
9
+ export declare function getCliUpdateStateFilePath(): string;
10
+ //# sourceMappingURL=update-request.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-request.service.d.ts","sourceRoot":"","sources":["../../../src/shared/services/update-request.service.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAmBF,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlI;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD"}
@@ -0,0 +1,32 @@
1
+ import { mkdir, rename, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { TRENDIFY_UPDATE_STATE_FILE } from '../config/app-paths.config.js';
4
+ const UPDATE_STATE_FILE_PATH = process.env.TRENDIFY_UPDATE_STATE_FILE?.trim() || TRENDIFY_UPDATE_STATE_FILE;
5
+ function sanitizeStateValue(value) {
6
+ return value.replaceAll(/\r?\n/gu, '').trim();
7
+ }
8
+ function buildStateFileContents(request) {
9
+ return [
10
+ `STATUS=${request.status}`,
11
+ `PACKAGE_NAME=${sanitizeStateValue(request.packageName)}`,
12
+ `CURRENT_VERSION=${sanitizeStateValue(request.currentVersion)}`,
13
+ `TARGET_VERSION=${sanitizeStateValue(request.targetVersion)}`,
14
+ `REQUESTED_AT=${sanitizeStateValue(request.requestedAt)}`,
15
+ '',
16
+ ].join('\n');
17
+ }
18
+ export async function writePendingCliUpdateRequest(request) {
19
+ const payload = {
20
+ ...request,
21
+ requestedAt: new Date().toISOString(),
22
+ status: 'pending',
23
+ };
24
+ const directoryPath = dirname(UPDATE_STATE_FILE_PATH);
25
+ const temporaryFilePath = `${UPDATE_STATE_FILE_PATH}.tmp-${process.pid}`;
26
+ await mkdir(directoryPath, { recursive: true });
27
+ await writeFile(temporaryFilePath, buildStateFileContents(payload), 'utf8');
28
+ await rename(temporaryFilePath, UPDATE_STATE_FILE_PATH);
29
+ }
30
+ export function getCliUpdateStateFilePath() {
31
+ return UPDATE_STATE_FILE_PATH;
32
+ }
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@trendify/cli",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "CLI do Trendify para descoberta de temas e fluxos de conta.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.entry.js",
7
7
  "types": "dist/cli.entry.d.ts",
8
8
  "bin": {
9
- "trendify": "dist/cli.entry.js"
9
+ "trendify": "bin/trendify.sh"
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
- "scripts/self-update.sh",
13
+ "bin/trendify.sh",
14
+ "scripts/update-runner.sh",
14
15
  ".env",
15
16
  "README.md",
16
17
  ".env.example"