onveloz 0.0.0-beta.46 → 0.0.0-beta.47

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,5 +1,5 @@
1
1
  import { C as endGroup, D as log, E as isMcpMode, O as startGroup, k as success, n as loadConfig, r as requireAuth, w as info } from "./config-DaQHTlyP.mjs";
2
- import { a as findStrippedConfigKeys, c as resolveConfigForEnv, d as suggestConfigKeyFix, s as parseVelozConfig } from "./veloz-config-iN8SFxrR.mjs";
2
+ import { a as findStrippedConfigKeys, c as resolveConfigForEnv, d as suggestConfigKeyFix, s as parseVelozConfig } from "./veloz-config-59H2mWOA.mjs";
3
3
  import { createORPCClient } from "@orpc/client";
4
4
  import { RPCLink } from "@orpc/client/fetch";
5
5
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
@@ -193,7 +193,7 @@ function getGitBranch() {
193
193
 
194
194
  //#endregion
195
195
  //#region src/lib/client.ts
196
- const CLI_VERSION = "0.0.0-beta.46";
196
+ const CLI_VERSION = "0.0.0-beta.47";
197
197
  const USER_AGENT = `veloz-cli/${CLI_VERSION}`;
198
198
  /**
199
199
  * Client source — "cli" by default; the init wizard sets this to "cli-wizard"
@@ -257,19 +257,20 @@ async function getClient() {
257
257
 
258
258
  //#endregion
259
259
  //#region src/lib/deploy-constants.ts
260
+ const labels = {
261
+ QUEUED: "Na fila",
262
+ BUILDING: "Compilando",
263
+ BUILD_FAILED: "Falha na compilação",
264
+ DEPLOYING: "Realizando deploy",
265
+ WAITING_ON_PROVIDER: "Provisionando",
266
+ LIVE: "Ativo",
267
+ FAILED: "Falhou",
268
+ CANCELLED: "Cancelado",
269
+ SKIPPED: "Ignorado",
270
+ SUPERSEDED: "Substituído"
271
+ };
260
272
  /** Portuguese label per deployment status, keyed by the status string the server streams. */
261
- const statusLabels = new Map([
262
- ["QUEUED", "Na fila"],
263
- ["BUILDING", "Compilando"],
264
- ["BUILD_FAILED", "Falha na compilação"],
265
- ["DEPLOYING", "Realizando deploy"],
266
- ["WAITING_ON_PROVIDER", "Provisionando"],
267
- ["LIVE", "Ativo"],
268
- ["FAILED", "Falhou"],
269
- ["CANCELLED", "Cancelado"],
270
- ["SKIPPED", "Ignorado"],
271
- ["SUPERSEDED", "Substituído"]
272
- ]);
273
+ const statusLabels = new Map(Object.entries(labels));
273
274
  function makeStatusIcons() {
274
275
  if (!process.stdout.isTTY) return new Map([
275
276
  ["QUEUED", "○"],
@@ -831,7 +832,7 @@ async function streamDeploymentLogs(deploymentId, serviceId, serviceName, option
831
832
  isVerbose,
832
833
  useTui: options.useTui
833
834
  })) {
834
- const { renderDeployTUI } = await import("./deploy-tui-DsIMdS4Y.mjs");
835
+ const { renderDeployTUI } = await import("./deploy-tui-BY_5U4Al.mjs");
835
836
  return renderDeployTUI(deploymentId, serviceId, serviceName);
836
837
  }
837
838
  const allLogLines = [];
@@ -1,6 +1,6 @@
1
- import { f as statusLabels, h as getClient, i as parseBuildLine, n as fetchDeployUrls, r as isHiddenMessage, s as getFailureHints, t as cleanDisplayLine, u as TERMINAL_STATUSES } from "./deploy-stream-kdbyBK5b.mjs";
1
+ import { f as statusLabels, h as getClient, i as parseBuildLine, n as fetchDeployUrls, r as isHiddenMessage, s as getFailureHints, t as cleanDisplayLine, u as TERMINAL_STATUSES } from "./deploy-stream-Crwv3sYL.mjs";
2
2
  import { k as success, w as info } from "./config-DaQHTlyP.mjs";
3
- import "./veloz-config-iN8SFxrR.mjs";
3
+ import "./veloz-config-59H2mWOA.mjs";
4
4
  import chalk from "chalk";
5
5
  import { useEffect, useRef, useState } from "react";
6
6
  import { Box, Static, Text, render, useApp } from "ink";
@@ -0,0 +1,5 @@
1
+ import "./Schema-Cg34DK63.mjs";
2
+ import "./veloz-config-59H2mWOA.mjs";
3
+ import { i as startEdgeDev, n as edgeDevOptionsSchema, r as runEdgeDev, t as EdgeDevError } from "./edge-dev-Wrtj1z2W.mjs";
4
+
5
+ export { runEdgeDev };
@@ -1,5 +1,5 @@
1
1
  import { A as isGreaterThanOrEqualTo, B as withDecodingDefaultKey, C as decodeUnknownPromise, Ct as getOrElse, D as isBetween, F as makeFilter, H as acquireRelease, I as optional, K as callback, L as optionalKey, M as isLengthBetween, Mt as isObjectOrArray, N as isMaxLength, Nt as flow, O as isFinite, P as isPattern, Q as mapError, R as suspend, S as decodeUnknownOption, St as isFailure, T as fromJsonString, Tt as getOrThrowWith, X as gen, Y as fn, Z as ignore, _ as Union, a as Literals, at as raceFirst, c as NullishOr, d as String, f as Struct, ft as sync, g as UndefinedOr, i as Literal, j as isInt, jt as hasProperty, k as isGreaterThan, l as Number$1, lt as scoped, m as TaggedStruct, mt as try_, n as Boolean, o as NonEmptyString, ot as result, p as StructWithRest, pt as tryPromise, q as fail, r as Date$1, rt as promise, s as NullOr, st as runPromise, t as ArraySchema, u as Record, ut as succeed, v as Unknown, vt as TaggedError, w as decodeUnknownSync, x as decodeUnknownEffect, z as toTaggedUnion } from "./Schema-Cg34DK63.mjs";
2
- import { F as nativeWorkerEntrypointSchema, I as nativeWorkerScheduleCronSchema, M as MAX_WORKER_SCHEDULED_CRON_LENGTH, N as nativeWorkerAssetsDirectorySchema, P as nativeWorkerCompatibilityDateSchema, j as MAX_WORKER_SCHEDULED_BINDINGS } from "./veloz-config-iN8SFxrR.mjs";
2
+ import { F as nativeWorkerCompatibilityDateSchema, I as nativeWorkerEntrypointSchema, L as nativeWorkerScheduleCronSchema, M as MAX_WORKER_SCHEDULED_BINDINGS, N as MAX_WORKER_SCHEDULED_CRON_LENGTH, P as nativeWorkerAssetsDirectorySchema } from "./veloz-config-59H2mWOA.mjs";
3
3
  import { createHash } from "node:crypto";
4
4
  import { constants } from "node:fs";
5
5
  import { join, relative, resolve, sep } from "node:path";
@@ -273,6 +273,36 @@ const decodeHostRetirementRecord = flow(decodeUnknownSync(StoredRecords), (decod
273
273
  };
274
274
  });
275
275
  const decodeRetirementEnvelope = decodeUnknownSync(strictStruct({ retirement: Unknown }));
276
+ /**
277
+ * Hands a completed retirement's hostname to its next owner (#2337). The
278
+ * retirement names the removal that finished; `nextServiceId` is the service
279
+ * whose admission is taking the name.
280
+ */
281
+ const HostReleaseRequestSchema = Struct({
282
+ intent: HostRetirementIntentSchema,
283
+ nextServiceId: NonEmptyString
284
+ });
285
+ /** The durable tombstone of one released retirement, kept per hostname and removal. */
286
+ const HostReleaseSchema = Struct({
287
+ version: Literal(1),
288
+ intent: HostRetirementIntentSchema,
289
+ expectedMapDigest: NullOr(String),
290
+ nextServiceId: NonEmptyString
291
+ });
292
+ const parseHostReleaseRequest = flow(decodeUnknownSync(HostReleaseRequestSchema.annotate({ parseOptions: { onExcessProperty: "error" } })), (request) => {
293
+ parseHostRetirementIntent(request.intent);
294
+ if (request.nextServiceId.length > 128) throw new Error("Invalid release owner");
295
+ return request;
296
+ });
297
+ const decodeHostRelease = flow(decodeUnknownSync(HostReleaseSchema.annotate({ parseOptions: { onExcessProperty: "error" } })), (release) => {
298
+ parseHostReleaseRequest({
299
+ intent: release.intent,
300
+ nextServiceId: release.nextServiceId
301
+ });
302
+ if (release.expectedMapDigest !== null && !SHA256_HEX.test(release.expectedMapDigest)) throw new Error("Invalid retirement map digest");
303
+ return release;
304
+ });
305
+ const decodeReleaseEnvelope = decodeUnknownSync(strictStruct({ release: Unknown }));
276
306
 
277
307
  //#endregion
278
308
  //#region ../../packages/route-authority-contract/src/authority-mirror.ts
@@ -451,7 +481,7 @@ const parseHostnameReceipt = flow(contractDecoder(strictStruct({
451
481
  prepareDigest: parsePrepareDigest$1(envelope.prepareDigest),
452
482
  committedMapDigest: parseCommittedMapDigest$1(envelope.committedMapDigest)
453
483
  }));
454
- const WorkerRedeployReceiptEnvelope = strictStruct({
484
+ const parseWorkerRedeployReceipt = flow(contractDecoder(strictStruct({
455
485
  contractVersion: Literal(2),
456
486
  cellId: Unknown,
457
487
  registryEntryDigest: Unknown,
@@ -460,8 +490,7 @@ const WorkerRedeployReceiptEnvelope = strictStruct({
460
490
  routeFence: Unknown,
461
491
  intentDigest: Unknown,
462
492
  hostnames: ArraySchema(Unknown).check(isLengthBetween(1, MAX_HOSTNAMES$1))
463
- });
464
- const parseWorkerRedeployReceipt = flow(contractDecoder(WorkerRedeployReceiptEnvelope, "Workers redeploy receipt is invalid"), (envelope) => {
493
+ }), "Workers redeploy receipt is invalid"), (envelope) => {
465
494
  const hostnames = envelope.hostnames.map((hostname) => parseHostnameReceipt(hostname));
466
495
  if (new Set(hostnames.map((hostname) => hostname.hostname)).size !== hostnames.length || [...hostnames].sort((left, right) => left.hostname.localeCompare(right.hostname)).some((hostname, index) => hostname !== hostnames[index])) throw new Error("Workers redeploy receipt hostnames are invalid");
467
496
  return {
@@ -784,6 +813,9 @@ const decodeExpiringDeployment = contractDecoder(strictStruct({
784
813
  ...WorkerDeploymentTargetFields,
785
814
  expiresAt: Number$1.check(isInt(), isGreaterThan(0))
786
815
  }), "Route authority version-map expiry is invalid");
816
+ function assertUniqueDeploymentIds(deployments, maximum) {
817
+ if (deployments.length > maximum || new Set(deployments.map((deployment) => deployment.deploymentId)).size !== deployments.length) throw new Error("Route authority version map has duplicate or excessive deployments");
818
+ }
787
819
  const PreviousDeployments = ArraySchema(Unknown).check(isMaxLength(MAX_VERSION_MAP_PREVIOUS_DEPLOYMENTS));
788
820
  const decodeVersionMapPreflight = contractDecoder(strictStruct({
789
821
  current: Unknown,
@@ -928,17 +960,19 @@ const decodeUpstreamHostState = contractDecoder(strictStruct({
928
960
  upstream: Unknown,
929
961
  authProtected: optionalKey(Unknown)
930
962
  }), "Route authority upstream HostState is invalid");
931
- const decodeWorkersHostState = contractDecoder(strictStruct({
963
+ const decodeVersionedWorkersHostState = contractDecoder(strictStruct({
932
964
  ...HostOwnershipFields,
933
965
  state: Literal("live"),
966
+ schemaVersion: Literal(2),
934
967
  target: Unknown,
935
968
  authProtected: optionalKey(Unknown)
936
- }), "Route authority Workers HostState is invalid");
937
- const decodeWorkersHostTarget = contractDecoder(strictStruct({
969
+ }), "Route authority versioned Workers HostState is invalid");
970
+ const decodeVersionedWorkersHostTarget = contractDecoder(strictStruct({
938
971
  kind: Literal("wfp"),
939
- scriptName: Unknown,
940
- outboundPolicy: Unknown
941
- }), "Route authority Workers HostState target is invalid");
972
+ current: Unknown,
973
+ previous: PreviousDeployments,
974
+ staged: optionalKey(Unknown)
975
+ }), "Route authority versioned Workers HostState target is invalid");
942
976
  const decodeAuthProtection = contractDecoder(UndefinedOr(Literal(true)), "Route authority HostState auth protection is invalid");
943
977
  const HostStateServiceId = String.check(isLengthBetween(1, 128));
944
978
  const decodeDeploymentHostState = contractDecoder(strictStruct({
@@ -970,28 +1004,46 @@ const parseUpstreamHostState = flow(decodeUpstreamHostState, (envelope) => {
970
1004
  upstream
971
1005
  };
972
1006
  });
973
- const parseWorkersHostState = flow(decodeWorkersHostState, (envelope) => {
974
- const target = decodeWorkersHostTarget(envelope.target);
975
- const scriptName = parseScriptName(target.scriptName);
976
- const outboundPolicy = parseOutboundPolicy(target.outboundPolicy);
977
- const workerTarget = {
978
- kind: target.kind,
979
- scriptName,
980
- outboundPolicy
1007
+ /** A drained target keeps its expiry; the drain window is judged by the redeploy that reads it. */
1008
+ const parseRetainedDeployment = flow(decodeExpiringDeployment, ({ expiresAt, ...target }) => ({
1009
+ ...parseWorkerDeploymentTarget(target),
1010
+ expiresAt
1011
+ }));
1012
+ const parseVersionedWorkersHostState = flow(decodeVersionedWorkersHostState, (envelope) => {
1013
+ const record = decodeVersionedWorkersHostTarget(envelope.target);
1014
+ const current = parseWorkerDeploymentTarget(record.current);
1015
+ const previous = record.previous.map((target$1) => parseRetainedDeployment(target$1));
1016
+ const staged = record.staged === void 0 ? void 0 : parseRetainedDeployment(record.staged);
1017
+ assertUniqueDeploymentIds([
1018
+ current,
1019
+ ...previous,
1020
+ ...staged === void 0 ? [] : [staged]
1021
+ ], MAX_VERSION_MAP_PREVIOUS_DEPLOYMENTS + 2);
1022
+ const target = staged === void 0 ? {
1023
+ kind: record.kind,
1024
+ current,
1025
+ previous
1026
+ } : {
1027
+ kind: record.kind,
1028
+ current,
1029
+ previous,
1030
+ staged
981
1031
  };
982
1032
  return decodeAuthProtection(envelope.authProtected) === true ? {
983
1033
  state: envelope.state,
984
- target: workerTarget,
1034
+ schemaVersion: envelope.schemaVersion,
1035
+ target,
985
1036
  authProtected: true
986
1037
  } : {
987
1038
  state: envelope.state,
988
- target: workerTarget
1039
+ schemaVersion: envelope.schemaVersion,
1040
+ target
989
1041
  };
990
1042
  });
991
1043
  const parseHostState = flow(decodeHostStateRecord, (record) => {
992
1044
  const migrationOperationId = record.migrationOperationId === void 0 ? void 0 : parseMigrationOperationId(record.migrationOperationId);
993
1045
  if (record.state === "live" && "upstream" in record) return withMigrationOwner(parseUpstreamHostState(record), migrationOperationId);
994
- if (record.state === "live" && "target" in record) return withMigrationOwner(parseWorkersHostState(record), migrationOperationId);
1046
+ if (record.state === "live" && "schemaVersion" in record) return withMigrationOwner(parseVersionedWorkersHostState(record), migrationOperationId);
995
1047
  if (record.state === "building" || record.state === "build_failed") {
996
1048
  const { state, serviceId, deploymentId } = decodeDeploymentHostState(record);
997
1049
  return withMigrationOwner({
@@ -1030,6 +1082,7 @@ const decodeRouteProjectionIntent = contractDecoder(strictStruct({
1030
1082
  operationId: Unknown,
1031
1083
  routeFence: Unknown,
1032
1084
  zoneId: Unknown,
1085
+ serviceId: optionalKey(Unknown),
1033
1086
  hostnames: ProjectedHostnames
1034
1087
  }), "Route authority projection intent is invalid");
1035
1088
  const decodeHostnameIntent = contractDecoder(strictStruct({
@@ -1064,6 +1117,9 @@ const parseRouteProjectionIntent = flow(rejectForbiddenKeys, decodeRouteProjecti
1064
1117
  if (new Set(hostnames.map((hostname) => hostname.hostname)).size !== hostnames.length) throw new Error("Route authority projection contains duplicate hostnames");
1065
1118
  const sortedHostnames = [...hostnames].sort((left, right) => left.hostname.localeCompare(right.hostname));
1066
1119
  if (sortedHostnames.some((hostname, index) => hostname !== hostnames[index])) throw new Error("Route authority projection hostnames must be sorted");
1120
+ const service = decodeOptionalServiceId(envelope);
1121
+ const [first] = sortedHostnames;
1122
+ if (service.serviceId !== void 0 && first !== void 0 && sortedHostnames.some((hostname) => !hostStatesEqual(hostname.projectedState, first.projectedState) || !hostStatesEqual(hostname.expectedPreviousState, first.expectedPreviousState))) throw new Error("Route authority service projection must share one HostState");
1067
1123
  const parsed = {
1068
1124
  contractVersion: envelope.contractVersion,
1069
1125
  cellId,
@@ -1071,6 +1127,7 @@ const parseRouteProjectionIntent = flow(rejectForbiddenKeys, decodeRouteProjecti
1071
1127
  operationId,
1072
1128
  routeFence,
1073
1129
  zoneId,
1130
+ ...service,
1074
1131
  hostnames: sortedHostnames
1075
1132
  };
1076
1133
  if (new TextEncoder().encode(canonicalJson(parsed)).byteLength > MAX_CONTRACT_BYTES) throw new Error("Route authority projection intent is too large");
@@ -1137,12 +1194,26 @@ const parseRouteProjectionReceipt = flow(rejectForbiddenKeys, decodeRouteProject
1137
1194
  hostnames: sortedHostnames
1138
1195
  };
1139
1196
  });
1197
+ /**
1198
+ * Which hostnames a finished operation projected, read without its HostStates.
1199
+ * A stored receipt keeps the HostState shape that was current when it was
1200
+ * written, and a PROMOTED migration from before v2 can still name a Service's
1201
+ * active deployment (#1318). The redeploy path and the script reaper need only
1202
+ * the hostnames, so they must not depend on a shape the contract dropped.
1203
+ */
1204
+ const parseRouteProjectionReceiptOutcome = flow(rejectForbiddenKeys, decodeRouteProjectionReceipt, (envelope) => ({
1205
+ result: envelope.result,
1206
+ hostnames: envelope.hostnames.map((entry) => normalizeHostname(decodeHostnameReceipt(entry).hostname))
1207
+ }));
1140
1208
  async function sha256Hex(value) {
1141
1209
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
1142
1210
  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
1143
1211
  }
1144
1212
  /** Read the immutable target fields of a mapping; callers validate its expiry separately. */
1145
1213
  const parseWorkerDeploymentMappingTarget = flow(contractDecoder(Record(String, Unknown), "Worker deployment mapping is invalid"), ({ expiresAt: _expiresAt, ...target }) => parseWorkerDeploymentTarget(target));
1214
+ function hostStatesEqual(left, right) {
1215
+ return canonicalJson(left) === canonicalJson(right);
1216
+ }
1146
1217
 
1147
1218
  //#endregion
1148
1219
  //#region ../../packages/providers/core/src/desired-state.ts
@@ -1,6 +1,6 @@
1
1
  import { $ as match, G as andThen, K as callback, _t as void_, at as raceFirst, et as never, ft as sync, lt as scoped, st as runPromise } from "./Schema-Cg34DK63.mjs";
2
- import "./veloz-config-iN8SFxrR.mjs";
3
- import { i as startEdgeDev, n as edgeDevOptionsSchema } from "./edge-dev-ATMqwxjd.mjs";
2
+ import "./veloz-config-59H2mWOA.mjs";
3
+ import { i as startEdgeDev, n as edgeDevOptionsSchema } from "./edge-dev-Wrtj1z2W.mjs";
4
4
  import { parentPort, workerData } from "node:worker_threads";
5
5
 
6
6
  //#region src/lib/edge-dev-worker.ts