@enformik/cli 0.5.0 → 0.6.0

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/site.js CHANGED
@@ -11,7 +11,7 @@ export class DeployClient {
11
11
  constructor(o) {
12
12
  this.o = o;
13
13
  // Her kullanım yolunda (deploy, status, whoami, app check) dağıtım anahtarı düz metin gitmesin.
14
- assertSecureUrl(o.consoleUrl, 'Konsol adresi');
14
+ assertSecureUrl(o.consoleUrl, 'Console URL');
15
15
  }
16
16
  url(path) { return joinUrl(this.o.consoleUrl, `/api/deploy/v1${path}`); }
17
17
  headers(extra = {}) {
@@ -46,6 +46,31 @@ export class DeployClient {
46
46
  return (await this.call(`/deployments/${id}`, { retries: 2 })).deployment;
47
47
  }
48
48
  }
49
+ /**
50
+ * Finalizes a deployment. A `409 invalid_state` can mean the first finalize worked and only its reply was lost (the request was retried), or
51
+ * another run of the same CI job already finalized it, so the deployment's real state decides: running or finished -> carry on with that state;
52
+ * still waiting for its upload / finalize -> the error stands.
53
+ */
54
+ export async function finalizeDeployment(client, dep) {
55
+ try {
56
+ await client.finalize(dep.deploymentId);
57
+ return { ...dep, status: 'validating' };
58
+ }
59
+ catch (e) {
60
+ if (!(e instanceof CliError) || e.code !== 'invalid_state')
61
+ throw e;
62
+ let cur;
63
+ try {
64
+ cur = await client.status(dep.deploymentId);
65
+ }
66
+ catch {
67
+ throw e;
68
+ } // the state could not be read: the original (actionable) error is the better message
69
+ if (cur.status === 'awaiting_upload' || cur.status === 'uploaded')
70
+ throw e;
71
+ return { ...dep, ...cur };
72
+ }
73
+ }
49
74
  /** Üst üste bu kadar yoklama hatasından sonra bırakılır. */
50
75
  const MAX_POLL_FAILURES = 5;
51
76
  const TERMINAL = new Set(['live', 'failed', 'expired', 'superseded']);
@@ -67,7 +92,8 @@ export async function waitForDeployment(client, id, opts) {
67
92
  catch (e) {
68
93
  // Geçici hata (ağ, 5xx): sunucu dağıtımı yayınlıyor olabilir, tek bir yoklama hatası CI'ı kırmasın.
69
94
  // Kalıcı hatalar (geçersiz anahtar, 404…) kodla gelir ve hemen iletilir.
70
- const transient = e instanceof CliError && (!e.code || e.code === 'deploy_unavailable');
95
+ // Bir 429 (kodsuz) da geçicidir: sunucu dağıtımı sürdürüyor, yoklamayı kısıtlama yüzünden bırakmayız.
96
+ const transient = (e instanceof CliError && (!e.code || e.code === 'deploy_unavailable')) || (e instanceof ApiError && e.status === 429 && !e.code);
71
97
  if (!transient || ++failures >= MAX_POLL_FAILURES)
72
98
  throw e;
73
99
  if (now() - start > opts.timeoutMs)
@@ -82,7 +108,7 @@ export async function waitForDeployment(client, id, opts) {
82
108
  if (isTerminal(v.status))
83
109
  return v;
84
110
  if (now() - start > opts.timeoutMs)
85
- throw new CliError(`Zaman aşımı: dağıtım ${Math.round(opts.timeoutMs / 1000)} sn içinde tamamlanmadı (son durum: ${v.status}). Konsolun "Sürümler" sekmesinden izleyebilirsiniz.`);
111
+ throw new CliError(`Timed out: the deployment did not finish within ${Math.round(opts.timeoutMs / 1000)} s (last status: ${v.status}). You can follow it on the console's "Releases" tab.`);
86
112
  await sleep(interval);
87
113
  interval = Math.min(interval + 500, 5000);
88
114
  }
@@ -128,25 +154,31 @@ export function idempotencyKey(env, rand = randomUUID, contentSha) {
128
154
  return `cli-${rand()}`.slice(0, 64);
129
155
  }
130
156
  const HINTS = {
131
- invalid_key: 'Dağıtım anahtarı geçersiz, iptal edilmiş ya da bu siteye ait değil. ENFORMIK_DEPLOY_KEY değerini kontrol edin.',
132
- key_expired: 'Dağıtım anahtarının süresi dolmuş. Konsolda yeni bir anahtar oluşturup CI gizli değişkenini güncelleyin.',
133
- rate_limited: 'Çok fazla geçersiz anahtar denemesi; biraz bekleyip yeniden deneyin.',
134
- developer_site_disabled: 'Bu ortamda geliştirici sitesi etkin değil. Konsolda "Geliştirici sitesi" penceresinden etkinleştirin.',
135
- environment_inactive: 'Web sitesi ortamı şu anda kullanılamıyor (ör. abonelik askıda).',
136
- deploy_in_progress: 'Bu ortamda devam eden bir dağıtım var; bitmesini bekleyip yeniden deneyin.',
137
- deploy_unavailable: 'Dağıtım altyapısı şu anda hazır değil; biraz sonra yeniden deneyin.',
138
- deployment_expired: 'Yükleme süresi dolmuş; komutu yeniden çalıştırın.',
139
- quota_exceeded: 'Arşiv izin verilen boyutu aşıyor (en çok 50 MB).',
140
- size_mismatch: 'Yüklenen içerik bildirilen boyutla uyuşmuyor; komutu yeniden çalıştırın.',
141
- checksum_mismatch: 'Yüklenen içeriğin sağlama toplamı uyuşmuyor (yükleme bozulmuş olabilir); komutu yeniden çalıştırın.',
157
+ invalid_key: 'The deploy key is invalid, revoked, or does not belong to this site. Check the ENFORMIK_DEPLOY_KEY value.',
158
+ key_expired: 'The deploy key has expired. Create a new key in the console and update the CI secret variable.',
159
+ rate_limited: 'Too many invalid key attempts; wait a moment and try again.',
160
+ developer_site_disabled: 'The developer site is not enabled in this environment. Enable it from the "Developer site" dialog in the console.',
161
+ environment_inactive: 'The website environment is currently unavailable (e.g. the subscription is suspended).',
162
+ deploy_in_progress: 'A deployment is already in progress in this environment; wait for it to finish and try again.',
163
+ deploy_unavailable: 'The deployment infrastructure is not ready right now; try again shortly.',
164
+ deployment_expired: 'The upload window has expired; run the command again.',
165
+ invalid_state: 'The deployment is not in a state that allows this step (for example it was already finalized or its upload is incomplete); run the command again.',
166
+ quota_exceeded: 'The archive exceeds the allowed size (50 MB max).',
167
+ size_mismatch: 'The uploaded content does not match the declared size; run the command again.',
168
+ checksum_mismatch: 'The checksum of the uploaded content does not match (the upload may be corrupted); run the command again.',
142
169
  };
143
170
  export function describeDeployError(e) {
144
171
  if (!(e instanceof ApiError))
145
172
  return e;
173
+ // Any 429 except one with a known hint (the deploy-key limiter) keeps its rate-limit message and JSON shape (status, retryAfterSeconds).
174
+ if (e.status === 429 && !(e.code && HINTS[e.code]))
175
+ return e;
146
176
  const hint = e.code ? HINTS[e.code] : undefined;
147
177
  const detail = e.body?.details;
148
178
  let msg = hint ?? e.message ?? `HTTP ${e.status}`;
149
179
  if (e.code === 'artifact_invalid' && Array.isArray(detail))
150
- msg = `Arşiv geçerli değil: ${detail.map((d) => d.message).join('; ')}`;
180
+ msg = `Invalid archive: ${detail.map((d) => d.message).join('; ')}`;
181
+ if (e.status === 429 && e.retryAfterSeconds !== undefined)
182
+ msg += ` (retry in about ${e.retryAfterSeconds} s)`;
151
183
  return new CliError(msg, 1, e.code, e.body);
152
184
  }
package/dist/zip.js CHANGED
@@ -28,7 +28,7 @@ const MAX_U32 = 0xffffffff;
28
28
  /** Girdileri sıralı (deterministik) olarak outPath'e zipler. */
29
29
  export function writeZipFile(files, outPath) {
30
30
  if (files.length > MAX_ENTRIES)
31
- throw new Error(`Zip en fazla ${MAX_ENTRIES} girdi içerebilir.`);
31
+ throw new Error(`A zip can contain at most ${MAX_ENTRIES} entries.`);
32
32
  const sorted = [...files].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
33
33
  const fd = openSync(outPath, 'w');
34
34
  let offset = 0;
@@ -44,7 +44,7 @@ export function writeZipFile(files, outPath) {
44
44
  for (const f of sorted) {
45
45
  const data = readFileSync(f.path);
46
46
  if (data.length >= MAX_U32)
47
- throw new Error(`Dosya çok büyük (zip64 desteklenmiyor): ${f.name}`);
47
+ throw new Error(`File too large (zip64 is not supported): ${f.name}`);
48
48
  const name = Buffer.from(f.name, 'utf8');
49
49
  const deflated = deflateRawSync(data, { level: 6 });
50
50
  const useDeflate = deflated.length < data.length;
@@ -96,7 +96,7 @@ export function writeZipFile(files, outPath) {
96
96
  end.writeUInt32LE(cdStart, 16);
97
97
  write(end);
98
98
  if (offset >= MAX_U32)
99
- throw new Error('Zip 4 GB sınırını aşıyor.');
99
+ throw new Error('The zip exceeds the 4 GB limit.');
100
100
  return { entries: sorted.length, bytes: offset };
101
101
  }
102
102
  finally {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@enformik/cli",
3
- "version": "0.5.0",
4
- "description": "Enformik geliştirici CLI'si: web sitesi dağıtımı ve uygulama modülü (şema) yükseltme.",
3
+ "version": "0.6.0",
4
+ "description": "Enformik developer CLI: website deployment and application module (schema) upgrades.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {