@trendify/cli 0.1.39 → 0.1.40

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 +1 @@
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
+ {"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;AAkDF,wBAAgB,uBAAuB,IAAI,wBAAwB,CAElE;AA+KD,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"}
@@ -111,7 +111,9 @@ async function fetchLatestPublishedVersion(packageName) {
111
111
  const packument = (await response.json());
112
112
  const latestVersion = packument['dist-tags']?.[DEFAULT_NPM_DIST_TAG];
113
113
  if (typeof latestVersion === 'string' && latestVersion.trim()) {
114
- return latestVersion.trim();
114
+ const normalizedVersion = latestVersion.trim();
115
+ await fetchPublishedVersionManifest(packageName, normalizedVersion);
116
+ return normalizedVersion;
115
117
  }
116
118
  throw new Error(`O dist-tag "${DEFAULT_NPM_DIST_TAG}" nao foi encontrado no registry.`);
117
119
  }
@@ -125,6 +127,47 @@ async function fetchLatestPublishedVersion(packageName) {
125
127
  }
126
128
  throw new Error(`Nao foi possivel consultar o dist-tag "${DEFAULT_NPM_DIST_TAG}" no registry do npm. ${toErrorMessage(lastError)}`);
127
129
  }
130
+ async function fetchPublishedVersionManifest(packageName, version) {
131
+ const versionUrl = new URL(`${DEFAULT_NPM_REGISTRY_URL}/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`);
132
+ versionUrl.searchParams.set('ts', Date.now().toString());
133
+ let lastError = null;
134
+ for (let attempt = 0; attempt < 2; attempt += 1) {
135
+ const controller = new AbortController();
136
+ const timeout = setTimeout(() => {
137
+ controller.abort();
138
+ }, REGISTRY_REQUEST_TIMEOUT_MS);
139
+ try {
140
+ const response = await fetch(versionUrl, {
141
+ method: 'GET',
142
+ headers: {
143
+ accept: 'application/json',
144
+ 'cache-control': 'no-cache',
145
+ pragma: 'no-cache',
146
+ },
147
+ cache: 'no-store',
148
+ signal: controller.signal,
149
+ });
150
+ clearTimeout(timeout);
151
+ if (!response.ok) {
152
+ throw new Error(`Registry respondeu com status ${response.status} para a versao ${version}.`);
153
+ }
154
+ const manifest = (await response.json());
155
+ const tarballUrl = manifest.dist?.tarball;
156
+ if (typeof tarballUrl === 'string' && tarballUrl.trim()) {
157
+ return manifest;
158
+ }
159
+ throw new Error(`A versao ${version} foi encontrada, mas nao informou um tarball valido.`);
160
+ }
161
+ catch (error) {
162
+ clearTimeout(timeout);
163
+ lastError = error;
164
+ if (attempt < 1) {
165
+ await wait(750);
166
+ }
167
+ }
168
+ }
169
+ throw new Error(`A versao ${version} ainda nao esta pronta para instalacao. ${toErrorMessage(lastError)}`);
170
+ }
128
171
  export async function checkForCliUpdate() {
129
172
  const { packageName, packageVersion } = readInstalledPackageMetadata();
130
173
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trendify/cli",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
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",
@@ -61,6 +61,120 @@ function Write-StateFile {
61
61
  Move-Item -Path $tempFilePath -Destination $Path -Force
62
62
  }
63
63
 
64
+ function Get-TargetTarballUrl {
65
+ param(
66
+ [string]$NodeCommand,
67
+ [string]$PackageName,
68
+ [string]$TargetVersion
69
+ )
70
+
71
+ $env:PACKAGE_NAME_FOR_FETCH = $PackageName
72
+ $env:TARGET_VERSION_FOR_FETCH = $TargetVersion
73
+
74
+ try {
75
+ $tarballUrl = & $NodeCommand -e @'
76
+ const packageName = process.env.PACKAGE_NAME_FOR_FETCH;
77
+ const targetVersion = process.env.TARGET_VERSION_FOR_FETCH;
78
+
79
+ if (!packageName || !targetVersion) {
80
+ process.exit(1);
81
+ }
82
+
83
+ const versionUrl = new URL(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/${encodeURIComponent(targetVersion)}`);
84
+ versionUrl.searchParams.set('ts', Date.now().toString());
85
+
86
+ fetch(versionUrl, {
87
+ method: 'GET',
88
+ headers: {
89
+ accept: 'application/json',
90
+ 'cache-control': 'no-cache',
91
+ pragma: 'no-cache',
92
+ },
93
+ cache: 'no-store',
94
+ })
95
+ .then(async (response) => {
96
+ if (!response.ok) {
97
+ throw new Error(`Registry respondeu com status ${response.status}.`);
98
+ }
99
+
100
+ const manifest = await response.json();
101
+ const tarballUrl = manifest?.dist?.tarball;
102
+
103
+ if (typeof tarballUrl !== 'string' || tarballUrl.trim().length === 0) {
104
+ throw new Error('Tarball nao encontrado.');
105
+ }
106
+
107
+ process.stdout.write(tarballUrl.trim());
108
+ })
109
+ .catch(() => {
110
+ process.exit(1);
111
+ });
112
+ '@ 2> $null
113
+
114
+ if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($tarballUrl)) {
115
+ return $null
116
+ }
117
+
118
+ return $tarballUrl.Trim()
119
+ } finally {
120
+ Remove-Item Env:\PACKAGE_NAME_FOR_FETCH -ErrorAction SilentlyContinue
121
+ Remove-Item Env:\TARGET_VERSION_FOR_FETCH -ErrorAction SilentlyContinue
122
+ }
123
+ }
124
+
125
+ function Wait-ForTargetVersion {
126
+ param(
127
+ [string]$NodeCommand,
128
+ [string]$NpmCommand,
129
+ [string]$PackageName,
130
+ [string]$TargetVersion,
131
+ [int]$RetryAttempts,
132
+ [int]$RetryDelaySeconds
133
+ )
134
+
135
+ for ($attempt = 1; $attempt -le $RetryAttempts; $attempt += 1) {
136
+ $tarballUrl = Get-TargetTarballUrl -NodeCommand $NodeCommand -PackageName $PackageName -TargetVersion $TargetVersion
137
+
138
+ if (-not [string]::IsNullOrWhiteSpace($tarballUrl)) {
139
+ return $tarballUrl
140
+ }
141
+
142
+ if ($attempt -lt $RetryAttempts) {
143
+ Write-Host "A versao publicada ainda nao esta disponivel para instalacao no npm. Nova tentativa em ${RetryDelaySeconds}s..."
144
+ Start-Sleep -Seconds $RetryDelaySeconds
145
+ }
146
+ }
147
+
148
+ return $null
149
+ }
150
+
151
+ function Install-TargetVersion {
152
+ param(
153
+ [string]$NpmCommand,
154
+ [string]$TarballUrl,
155
+ [string]$CachePath,
156
+ [int]$RetryAttempts,
157
+ [int]$RetryDelaySeconds
158
+ )
159
+
160
+ for ($attempt = 1; $attempt -le $RetryAttempts; $attempt += 1) {
161
+ & $NpmCommand install --global --cache $CachePath --prefer-online $TarballUrl
162
+
163
+ if ($LASTEXITCODE -eq 0) {
164
+ return $true
165
+ }
166
+
167
+ if ($attempt -lt $RetryAttempts) {
168
+ Write-Host ''
169
+ Write-Host "A instalacao nao foi concluida. Nova tentativa em ${RetryDelaySeconds}s..."
170
+ Write-Host ''
171
+ Start-Sleep -Seconds $RetryDelaySeconds
172
+ }
173
+ }
174
+
175
+ return $false
176
+ }
177
+
64
178
  if (-not (Test-Path -LiteralPath $stateFilePath)) {
65
179
  exit 0
66
180
  }
@@ -75,6 +189,11 @@ $packageName = if ($state['PACKAGE_NAME']) { $state['PACKAGE_NAME'] } else { '@t
75
189
  $currentVersion = if ($state['CURRENT_VERSION']) { $state['CURRENT_VERSION'] } else { 'desconhecida' }
76
190
  $targetVersion = if ($state['TARGET_VERSION']) { $state['TARGET_VERSION'] } else { 'latest' }
77
191
  $npmCommand = if (Get-Command 'npm.cmd' -ErrorAction SilentlyContinue) { 'npm.cmd' } else { 'npm' }
192
+ $updateRetryAttempts = 3
193
+ $updateRetryDelaySeconds = 3
194
+ $npmCachePath = Join-Path ([System.IO.Path]::GetTempPath()) ("trendify-cli-updater-npm-cache-" + [System.Guid]::NewGuid().ToString('N'))
195
+
196
+ New-Item -ItemType Directory -Path $npmCachePath -Force | Out-Null
78
197
 
79
198
  Reset-Terminal
80
199
  Write-Host 'Trendify CLI'
@@ -85,15 +204,29 @@ Write-Host ''
85
204
  Write-StateFile -Path $stateFilePath -Values $state -Status 'updating'
86
205
 
87
206
  try {
88
- & $npmCommand install --global "$packageName@$targetVersion"
89
- if ($LASTEXITCODE -ne 0) {
207
+ $targetTarballUrl = Wait-ForTargetVersion -NodeCommand $nodeCommand -NpmCommand $npmCommand -PackageName $packageName -TargetVersion $targetVersion -RetryAttempts $updateRetryAttempts -RetryDelaySeconds $updateRetryDelaySeconds
208
+
209
+ if ([string]::IsNullOrWhiteSpace($targetTarballUrl)) {
210
+ throw "target-version-unavailable"
211
+ }
212
+
213
+ if (-not (Install-TargetVersion -NpmCommand $npmCommand -TarballUrl $targetTarballUrl -CachePath $npmCachePath -RetryAttempts $updateRetryAttempts -RetryDelaySeconds $updateRetryDelaySeconds)) {
90
214
  throw "npm install finalizou com codigo $LASTEXITCODE."
91
215
  }
92
216
  } catch {
93
217
  Write-StateFile -Path $stateFilePath -Values $state -Status 'failed'
94
- Write-Error 'Falha ao atualizar automaticamente o CLI.'
95
- Write-Host "Execute manualmente: npm install -g $packageName@$targetVersion"
218
+ if ($_.Exception.Message -eq 'target-version-unavailable') {
219
+ Write-Error "A versao $targetVersion do CLI ainda nao esta disponivel para instalacao no npm."
220
+ Write-Host 'Isso costuma acontecer por alguns instantes logo apos a publicacao.'
221
+ Write-Host 'Tente novamente em alguns segundos.'
222
+ } else {
223
+ Write-Error 'Falha ao atualizar automaticamente o CLI.'
224
+ Write-Host 'Se o erro foi ETARGET, aguarde alguns instantes e tente novamente.'
225
+ Write-Host "Comando manual: npm install -g $packageName@$targetVersion"
226
+ }
96
227
  exit 1
228
+ } finally {
229
+ Remove-Item -LiteralPath $npmCachePath -Recurse -Force -ErrorAction SilentlyContinue
97
230
  }
98
231
 
99
232
  Remove-Item -LiteralPath $stateFilePath -Force -ErrorAction SilentlyContinue
@@ -13,7 +13,7 @@ cleanup() {
13
13
  fi
14
14
 
15
15
  if [ -n "${TRENDIFY_TEMP_UPDATER_DIR:-}" ]; then
16
- rmdir "$TRENDIFY_TEMP_UPDATER_DIR" >/dev/null 2>&1 || true
16
+ rm -rf "$TRENDIFY_TEMP_UPDATER_DIR" >/dev/null 2>&1 || true
17
17
  fi
18
18
  }
19
19
 
@@ -59,6 +59,85 @@ create_temp_updater_dir() {
59
59
  exit 1
60
60
  }
61
61
 
62
+ resolve_target_tarball_url() {
63
+ PACKAGE_NAME_FOR_FETCH=$PACKAGE_NAME TARGET_VERSION_FOR_FETCH=$TARGET_VERSION "$NODE_COMMAND" -e '
64
+ const packageName = process.env.PACKAGE_NAME_FOR_FETCH;
65
+ const targetVersion = process.env.TARGET_VERSION_FOR_FETCH;
66
+
67
+ if (!packageName || !targetVersion) {
68
+ process.exit(1);
69
+ }
70
+
71
+ const versionUrl = new URL(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/${encodeURIComponent(targetVersion)}`);
72
+ versionUrl.searchParams.set("ts", Date.now().toString());
73
+
74
+ fetch(versionUrl, {
75
+ method: "GET",
76
+ headers: {
77
+ accept: "application/json",
78
+ "cache-control": "no-cache",
79
+ pragma: "no-cache",
80
+ },
81
+ cache: "no-store",
82
+ })
83
+ .then(async (response) => {
84
+ if (!response.ok) {
85
+ throw new Error(`Registry respondeu com status ${response.status}.`);
86
+ }
87
+
88
+ const manifest = await response.json();
89
+ const tarballUrl = manifest?.dist?.tarball;
90
+
91
+ if (typeof tarballUrl !== "string" || tarballUrl.trim().length === 0) {
92
+ throw new Error("Tarball nao encontrado.");
93
+ }
94
+
95
+ process.stdout.write(tarballUrl.trim());
96
+ })
97
+ .catch(() => {
98
+ process.exit(1);
99
+ });
100
+ '
101
+ }
102
+
103
+ wait_for_target_tarball_url() {
104
+ ATTEMPT=1
105
+
106
+ while [ "$ATTEMPT" -le "$UPDATE_RETRY_ATTEMPTS" ]; do
107
+ if TARGET_TARBALL_URL=$(resolve_target_tarball_url 2>/dev/null); then
108
+ return 0
109
+ fi
110
+
111
+ if [ "$ATTEMPT" -lt "$UPDATE_RETRY_ATTEMPTS" ]; then
112
+ printf 'A versao publicada ainda nao esta disponivel para instalacao no npm. Nova tentativa em %ss...\n' "$UPDATE_RETRY_DELAY_SECONDS"
113
+ sleep "$UPDATE_RETRY_DELAY_SECONDS"
114
+ fi
115
+
116
+ ATTEMPT=$((ATTEMPT + 1))
117
+ done
118
+
119
+ return 1
120
+ }
121
+
122
+ install_target_version() {
123
+ ATTEMPT=1
124
+
125
+ while [ "$ATTEMPT" -le "$UPDATE_RETRY_ATTEMPTS" ]; do
126
+ if npm install --global --cache "$NPM_CACHE_DIR" --prefer-online "$TARGET_TARBALL_URL"; then
127
+ return 0
128
+ fi
129
+
130
+ if [ "$ATTEMPT" -lt "$UPDATE_RETRY_ATTEMPTS" ]; then
131
+ printf '\nA instalacao nao foi concluida. Nova tentativa em %ss...\n\n' "$UPDATE_RETRY_DELAY_SECONDS"
132
+ sleep "$UPDATE_RETRY_DELAY_SECONDS"
133
+ fi
134
+
135
+ ATTEMPT=$((ATTEMPT + 1))
136
+ done
137
+
138
+ return 1
139
+ }
140
+
62
141
  if [ "${TRENDIFY_UPDATER_STAGE:-launcher}" != "temp" ]; then
63
142
  TEMP_UPDATER_DIR=$(create_temp_updater_dir)
64
143
  TEMP_UPDATER_PATH="$TEMP_UPDATER_DIR/update-runner.sh"
@@ -83,6 +162,12 @@ PACKAGE_NAME=${PACKAGE_NAME:-@trendify/cli}
83
162
  CURRENT_VERSION=${CURRENT_VERSION:-desconhecida}
84
163
  TARGET_VERSION=${TARGET_VERSION:-latest}
85
164
  REQUESTED_AT=${REQUESTED_AT:-unknown}
165
+ UPDATE_RETRY_ATTEMPTS=${UPDATE_RETRY_ATTEMPTS:-3}
166
+ UPDATE_RETRY_DELAY_SECONDS=${UPDATE_RETRY_DELAY_SECONDS:-3}
167
+ NPM_CACHE_DIR="${TRENDIFY_TEMP_UPDATER_DIR}/npm-cache"
168
+ TARGET_TARBALL_URL=
169
+
170
+ mkdir -p "$NPM_CACHE_DIR"
86
171
 
87
172
  reset_terminal
88
173
  printf 'Trendify CLI\n'
@@ -91,10 +176,19 @@ printf '[2/4] Atualizando %s de v%s para v%s...\n\n' "$PACKAGE_NAME" "$CURRENT_V
91
176
 
92
177
  write_state_file "updating"
93
178
 
94
- if ! npm install --global "${PACKAGE_NAME}@${TARGET_VERSION}"; then
179
+ if ! wait_for_target_tarball_url; then
180
+ write_state_file "failed"
181
+ printf '\nA versao %s do CLI ainda nao esta disponivel para instalacao no npm.\n' "$TARGET_VERSION" >&2
182
+ printf 'Isso costuma acontecer por alguns instantes logo apos a publicacao.\n' >&2
183
+ printf 'Tente novamente em alguns segundos.\n' >&2
184
+ exit 1
185
+ fi
186
+
187
+ if ! install_target_version; then
95
188
  write_state_file "failed"
96
189
  printf '\nFalha ao atualizar automaticamente o CLI.\n' >&2
97
- printf 'Execute manualmente: npm install -g %s@%s\n' "$PACKAGE_NAME" "$TARGET_VERSION" >&2
190
+ printf 'Se o erro foi ETARGET, aguarde alguns instantes e tente novamente.\n' >&2
191
+ printf 'Comando manual: npm install -g %s@%s\n' "$PACKAGE_NAME" "$TARGET_VERSION" >&2
98
192
  exit 1
99
193
  fi
100
194