@walkeros/cli 4.3.0 → 4.3.1

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/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Flow, PreviewKey, Elb, Ingest, WalkerOS, Simulation } from '@walkeros/core';
1
+ import { Flow, PreviewKey, Elb, Ingest, WalkerOS, Simulation, ObserveWeb } from '@walkeros/core';
2
2
  export { Flow } from '@walkeros/core';
3
3
  import { BuildOptions as BuildOptions$1 } from 'esbuild';
4
4
  import { z } from '@walkeros/core/dev';
@@ -218,6 +218,15 @@ interface BundleStats {
218
218
  * payload by construction.
219
219
  */
220
220
  declare function buildDataPayload(flowSettings: Flow): Record<string, unknown>;
221
+ /**
222
+ * Generate a stage 2 entry file for wrapping an ALREADY-embedded skeleton.
223
+ *
224
+ * Unlike `generateWebEntry`, this variant imports `__configData` from the
225
+ * skeleton (instead of inlining a `dataPayload` string). Used by the
226
+ * publish-time `wrapSkeleton` helper, which runs on a stage 1 skeleton
227
+ * produced via `bundle({ skipWrapper: true })` — those skeletons already
228
+ * export `__configData` alongside `wireConfig` and `startFlow`.
229
+ */
221
230
  /**
222
231
  * Preview activation wiring. When present and enabled, the generated entry
223
232
  * imports the activator from core and lets it decide whether a preview bundle
@@ -9837,8 +9846,6 @@ interface components {
9837
9846
  flowId: string;
9838
9847
  flowSettingsId: string;
9839
9848
  projectId: string;
9840
- /** @example k9x2m4p7abcd */
9841
- token: string;
9842
9849
  /** Format: uri */
9843
9850
  bundleUrl: string;
9844
9851
  activationUrl: string | null;
@@ -9893,17 +9900,33 @@ interface components {
9893
9900
  serverFlowName: string | null;
9894
9901
  serverEndpoint: string | null;
9895
9902
  web: components['schemas']['ObserveSessionWeb'];
9903
+ server: components['schemas']['ObserveSessionServer'];
9904
+ /** Format: date-time */
9905
+ expiresAt: string;
9906
+ recordsReceived: number;
9896
9907
  createdBy: string;
9897
9908
  /** Format: date-time */
9898
9909
  createdAt: string;
9899
9910
  };
9900
9911
  ObserveSessionWeb: {
9901
- previewId: string;
9902
- token: string;
9912
+ /** Format: uri */
9913
+ activationUrl: string | null;
9914
+ credential: string;
9903
9915
  previewEnabled: boolean;
9904
9916
  /** Format: uri */
9905
9917
  bundleUrl: string;
9906
9918
  } | null;
9919
+ ObserveSessionServer: {
9920
+ /** Format: uri */
9921
+ endpoint: string | null;
9922
+ env: components['schemas']['ObserveSessionServerEnv'];
9923
+ } | null;
9924
+ ObserveSessionServerEnv: {
9925
+ /** Format: uri */
9926
+ WALKEROS_OBSERVER_URL: string;
9927
+ WALKEROS_DEPLOYMENT_ID: string;
9928
+ WALKEROS_INGEST_TOKEN: string;
9929
+ };
9907
9930
  ObserveSessionJourneysResponse: {
9908
9931
  /** @example ses_abc123xyz456 */
9909
9932
  sessionId: string;
@@ -9921,7 +9944,12 @@ interface components {
9921
9944
  CreateObserveSessionRequest: {
9922
9945
  settingsName: string;
9923
9946
  force?: boolean;
9947
+ replace?: boolean;
9948
+ level?: components['schemas']['ObserveLevel'];
9949
+ origins?: string[];
9924
9950
  };
9951
+ /** @enum {string} */
9952
+ ObserveLevel: 'off' | 'standard' | 'trace';
9925
9953
  ObserveSessionHeartbeatResponse: {
9926
9954
  /** @enum {boolean} */
9927
9955
  ok: true;
@@ -11512,15 +11540,14 @@ interface WrapSkeletonOptions {
11512
11540
  */
11513
11541
  previewGrantTargets?: string[];
11514
11542
  /**
11515
- * Browser-only: telemetry wiring. When provided, the wrapped bundle
11516
- * installs an observer built via `createTelemetryObserver` onto
11517
- * `collector.observers` and forwards FlowState records to `observerUrl`
11518
- * using `createBatchedPoster`.
11519
- *
11520
- * Omit (or pass `level: 'off'`) to ship a bundle with zero telemetry
11521
- * plumbing.
11543
+ * Browser-only: STATIC observe connect config baked onto the startFlow
11544
+ * config. PUBLIC values only (`url` + `binding`, plus optional
11545
+ * `flowId`/`level`/`sample` scoping); the runtime connect module reads the
11546
+ * per-session credential out-of-band at boot via the `elbObserve` slot.
11547
+ * This is the preview-artifact observation wiring: it bakes no ingest
11548
+ * token into the emitted bytes.
11522
11549
  */
11523
- telemetry?: TelemetryBundleOptions;
11550
+ observe?: ObserveWeb;
11524
11551
  /**
11525
11552
  * esbuild target. @default 'es2018' for browser, 'node18' for node.
11526
11553
  */
@@ -11530,31 +11557,6 @@ interface WrapSkeletonOptions {
11530
11557
  /** Fine-grained minification options, forwarded to esbuild. */
11531
11558
  minifyOptions?: MinifyOptions;
11532
11559
  }
11533
- interface TelemetryBundleOptions {
11534
- /** Absolute ingest URL. POST receives JSON array of FlowState. */
11535
- observerUrl: string;
11536
- /**
11537
- * Full deployment-scoped trace endpoint, e.g.
11538
- * `https://observer.example.com/trace/<deploymentId>`. Baked into the bundle
11539
- * and polled verbatim; the browser never constructs it from a base.
11540
- *
11541
- * Optional: when omitted, the bundle wires the observer at a fixed `level`
11542
- * with no polling. Suits short-lived, URL-opted-in sessions (e.g. a preview
11543
- * at `level: 'trace'`).
11544
- */
11545
- traceUrl?: string;
11546
- /** Deployment-scoped plaintext token. Sent as `Authorization: Bearer`. */
11547
- ingestToken: string;
11548
- /** Used as the `flowId` on every emitted FlowState. */
11549
- flowId: string;
11550
- /**
11551
- * Baseline verbosity. Default 'standard'. Even an 'off' baseline is wired
11552
- * (as a supplier) so the runtime trace poll can flip it to trace.
11553
- */
11554
- level?: 'off' | 'standard' | 'trace';
11555
- /** Deterministic sample fraction in [0, 1]. Default 1. */
11556
- sample?: number;
11557
- }
11558
11560
  declare function wrapSkeleton(options: WrapSkeletonOptions): Promise<void>;
11559
11561
 
11560
11562
  declare function createApiClient(): openapi_fetch.Client<paths, `${string}/${string}`>;
package/dist/index.js CHANGED
@@ -2506,7 +2506,8 @@ ${dataDeclaration}`;
2506
2506
  const stage2Entry = (buildOptions.platform || "node") === "browser" ? generateWebEntry(stage1Path, dataPayload, {
2507
2507
  windowCollector: buildOptions.windowCollector,
2508
2508
  windowElb: buildOptions.windowElb,
2509
- platform: buildOptions.platform
2509
+ platform: buildOptions.platform,
2510
+ observe: readObserveConnect(flowSettings, logger)
2510
2511
  }) : generateServerEntry(stage1Path, dataPayload);
2511
2512
  const stage2EntryPath = path12.join(TEMP_DIR, "stage2.mjs");
2512
2513
  await fs11.writeFile(stage2EntryPath, stage2Entry);
@@ -3265,6 +3266,45 @@ export default async function(context = {}) {
3265
3266
  return { ...result, httpHandler: httpSource ? httpSource.httpHandler : undefined };
3266
3267
  }`;
3267
3268
  }
3269
+ function readObserveConnect(flowSettings, logger) {
3270
+ const observe = flowSettings.config?.observe;
3271
+ if (!observe) return void 0;
3272
+ const { url, binding, level, sample } = observe;
3273
+ if (url === void 0 && binding === void 0) return void 0;
3274
+ const trimmedUrl = typeof url === "string" ? url.trim() : "";
3275
+ const trimmedBinding = typeof binding === "string" ? binding.trim() : "";
3276
+ if (trimmedUrl !== "" && trimmedBinding !== "") {
3277
+ return {
3278
+ url: trimmedUrl,
3279
+ binding: trimmedBinding,
3280
+ // Same JSON-borne prudence as the pair: only known-shaped public
3281
+ // values reach the emitted literal.
3282
+ ...level === "off" || level === "standard" || level === "trace" ? { level } : {},
3283
+ // Sample is a fraction in [0, 1] per the Flow.Observe contract; the
3284
+ // range test also drops NaN and the infinities.
3285
+ ...typeof sample === "number" && sample >= 0 && sample <= 1 ? { sample } : {}
3286
+ };
3287
+ }
3288
+ const missing = [
3289
+ ...trimmedUrl === "" ? ["url"] : [],
3290
+ ...trimmedBinding === "" ? ["binding"] : []
3291
+ ].join(" and ");
3292
+ logger?.warn(
3293
+ `config.observe has no effect: missing or empty ${missing}. Observe connect wiring was skipped; set both config.observe.url and config.observe.binding to non-empty public values.`
3294
+ );
3295
+ return void 0;
3296
+ }
3297
+ function emitObserveAssignment(observe) {
3298
+ const literal = {
3299
+ url: observe.url,
3300
+ binding: observe.binding,
3301
+ ...observe.flowId !== void 0 ? { flowId: observe.flowId } : {},
3302
+ ...observe.level !== void 0 ? { level: observe.level } : {},
3303
+ ...observe.sample !== void 0 ? { sample: observe.sample } : {}
3304
+ };
3305
+ return `
3306
+ config.observe = ${JSON.stringify(literal)};`;
3307
+ }
3268
3308
  function generateWebEntry(stage1Path, dataPayload, options = {}) {
3269
3309
  const assignments = [];
3270
3310
  if (options.windowCollector) {
@@ -3285,30 +3325,14 @@ function generateWebEntry(stage1Path, dataPayload, options = {}) {
3285
3325
  }
3286
3326
  }` : "";
3287
3327
  const stage1Specifier = toFileImportSpecifier(stage1Path);
3288
- const telemetryImport = options.telemetry ? `
3289
- import { createBatchedPoster as __cbp, createTelemetryObserver as __cto } from '@walkeros/core';` : "";
3290
- const telemetryBlock = options.telemetry ? `
3291
- // --- Telemetry wiring ---
3292
- {
3293
- const __emit = __cbp({
3294
- url: ${JSON.stringify(options.telemetry.observerUrl)},
3295
- token: ${JSON.stringify(options.telemetry.ingestToken)},
3296
- });
3297
- const __observer = __cto(__emit, {
3298
- flowId: ${JSON.stringify(options.telemetry.flowId)},
3299
- level: ${JSON.stringify(options.telemetry.level ?? "standard")},
3300
- sample: ${JSON.stringify(options.telemetry.sample ?? 1)},
3301
- });
3302
- collector.observers.add(__observer);
3303
- collector.observeLevel = function () { return ${JSON.stringify(options.telemetry.level ?? "standard")}; };
3304
- }` : "";
3305
- return `import { startFlow, wireConfig } from '${stage1Specifier}';${telemetryImport}
3328
+ const observeBlock = options.observe ? emitObserveAssignment(options.observe) : "";
3329
+ return `import { startFlow, wireConfig } from '${stage1Specifier}';
3306
3330
 
3307
3331
  const __configData = ${dataPayload};
3308
3332
 
3309
3333
  (async () => {
3310
- const config = wireConfig(__configData);${envBlock}
3311
- const { collector, elb } = await startFlow(config);${telemetryBlock}${assignmentCode}
3334
+ const config = wireConfig(__configData);${envBlock}${observeBlock}
3335
+ const { collector, elb } = await startFlow(config);${assignmentCode}
3312
3336
  })();`;
3313
3337
  }
3314
3338
  function generateWrapEntry(stage1Path, options = {}) {
@@ -3376,92 +3400,12 @@ ${grantTargets.map((key) => {
3376
3400
  }
3377
3401
  }` : "";
3378
3402
  const stage1Specifier = toFileImportSpecifier(stage1Path);
3379
- const hasPoll = !!options.telemetry?.traceUrl;
3380
- const telemetryImport = options.telemetry ? hasPoll ? `
3381
- import { createBatchedPoster as __cbp, createTelemetryObserver as __cto, resolveTelemetryOptions as __cto_resolve } from '@walkeros/core';` : `
3382
- import { createBatchedPoster as __cbp, createTelemetryObserver as __cto } from '@walkeros/core';` : "";
3383
- const telemetryPoller = options.telemetry && hasPoll ? `
3384
- let __traceUntil = null;
3385
- let __tracePollInFlight = false;
3386
- function __pollTrace() {
3387
- if (typeof fetch === 'undefined' || __tracePollInFlight) return;
3388
- __tracePollInFlight = true;
3389
- // Bound each poll so a stalled trace endpoint can't pin the in-flight guard
3390
- // forever (and stack concurrent fetches via setInterval).
3391
- var __ctrl = typeof AbortController !== 'undefined' ? new AbortController() : null;
3392
- var __t = __ctrl ? setTimeout(function () { __ctrl.abort(); }, 10000) : null;
3393
- fetch(${JSON.stringify(options.telemetry.traceUrl)}, {
3394
- headers: { Authorization: ${JSON.stringify(`Bearer ${options.telemetry.ingestToken}`)} },
3395
- signal: __ctrl ? __ctrl.signal : undefined,
3396
- })
3397
- .then(function (__res) {
3398
- if (!__res || __res.status !== 200) return;
3399
- return __res.json().then(function (__body) {
3400
- if (!__body || typeof __body !== 'object') return;
3401
- var __value = __body.traceUntil;
3402
- // Mirror the server poller: set on a non-empty string, clear on null,
3403
- // leave unchanged on anything else. The null path is the disable case
3404
- // (stop a trace early) and MUST be honored so web deployments can be
3405
- // turned off without waiting for the old timestamp to lapse.
3406
- if (typeof __value === 'string' && __value.length > 0) {
3407
- __traceUntil = __value;
3408
- } else if (__value === null) {
3409
- __traceUntil = null;
3410
- }
3411
- });
3412
- })
3413
- .catch(function () {})
3414
- .finally(function () {
3415
- if (__t) clearTimeout(__t);
3416
- __tracePollInFlight = false;
3417
- });
3418
- }
3419
- ` : "";
3420
- const telemetryBlock = options.telemetry ? hasPoll ? `
3421
- // --- Telemetry wiring ---
3422
- {
3423
- const __emit = __cbp({
3424
- url: ${JSON.stringify(options.telemetry.observerUrl)},
3425
- token: ${JSON.stringify(options.telemetry.ingestToken)},
3426
- });
3427
- // Single resolver drives both the observer projection and observeLevel so
3428
- // the reported level can never drift from what the observer emits.
3429
- const __resolveTelemetry = () => __cto_resolve({
3430
- flowId: ${JSON.stringify(options.telemetry.flowId)},
3431
- observe: {
3432
- level: ${JSON.stringify(options.telemetry.level ?? "standard")},
3433
- sample: ${JSON.stringify(options.telemetry.sample ?? 1)},
3434
- },
3435
- traceUntil: __traceUntil,
3436
- });
3437
- const __observer = __cto(__emit, __resolveTelemetry);
3438
- collector.observers.add(__observer);
3439
- collector.observeLevel = function () {
3440
- const __opts = __resolveTelemetry();
3441
- return __opts ? __opts.level : 'off';
3442
- };
3443
- __pollTrace();
3444
- setInterval(__pollTrace, 15000 + Math.floor(Math.random() * 5000));
3445
- }` : `
3446
- // --- Telemetry wiring ---
3447
- {
3448
- const __emit = __cbp({
3449
- url: ${JSON.stringify(options.telemetry.observerUrl)},
3450
- token: ${JSON.stringify(options.telemetry.ingestToken)},
3451
- });
3452
- const __observer = __cto(__emit, {
3453
- flowId: ${JSON.stringify(options.telemetry.flowId)},
3454
- level: ${JSON.stringify(options.telemetry.level ?? "standard")},
3455
- sample: ${JSON.stringify(options.telemetry.sample ?? 1)},
3456
- });
3457
- collector.observers.add(__observer);
3458
- collector.observeLevel = function () { return ${JSON.stringify(options.telemetry.level ?? "standard")}; };
3459
- }` : "";
3460
- return `${previewImport}import { startFlow, wireConfig, __configData } from '${stage1Specifier}';${telemetryImport}
3461
- ${telemetryPoller}
3403
+ const observeBlock = options.observe ? emitObserveAssignment(options.observe) : "";
3404
+ return `${previewImport}import { startFlow, wireConfig, __configData } from '${stage1Specifier}';
3405
+
3462
3406
  (async () => {${previewBlock}
3463
- const config = wireConfig(__configData);${envBlock}${previewGrantBlock}
3464
- const { collector, elb } = await startFlow(config);${telemetryBlock}${assignmentCode}
3407
+ const config = wireConfig(__configData);${envBlock}${previewGrantBlock}${observeBlock}
3408
+ const { collector, elb } = await startFlow(config);${assignmentCode}
3465
3409
  })();`;
3466
3410
  }
3467
3411
  function singleQuoteLiteral(value) {
@@ -8305,7 +8249,7 @@ function validateMapping(input) {
8305
8249
  // src/commands/validate/validators/entry.ts
8306
8250
  import Ajv from "ajv";
8307
8251
  import { fetchPackageSchema } from "@walkeros/core";
8308
- var CLIENT_HEADER = "walkeros-cli/4.3.0";
8252
+ var CLIENT_HEADER = "walkeros-cli/4.3.1";
8309
8253
  var SECTIONS = ["destinations", "sources", "transformers"];
8310
8254
  function resolveEntry(path20, flowConfig) {
8311
8255
  const flows = flowConfig.flows;
@@ -8870,8 +8814,8 @@ import createClient from "openapi-fetch";
8870
8814
  init_config_file();
8871
8815
  import { createHash } from "crypto";
8872
8816
  import semver4 from "semver";
8873
- var bakedContractVersion = true ? "3.1.0" : PLACEHOLDER;
8874
- var bakedContractHash = true ? "d3753dd02864fc19892f74a6a9afddb2081fc7a3f249991a681ae6c5540be650" : "";
8817
+ var bakedContractVersion = true ? "4.0.0" : PLACEHOLDER;
8818
+ var bakedContractHash = true ? "79c9e2d3bd2a72f1a95ba52742c4acdfe446c3835d5d169654f94e95da0e545e" : "";
8875
8819
  function isRecord3(value) {
8876
8820
  return value !== null && typeof value === "object" && !Array.isArray(value);
8877
8821
  }
@@ -10195,23 +10139,13 @@ async function wrapSkeleton(options) {
10195
10139
  const absoluteSkeletonPath = path19.resolve(skeletonPath);
10196
10140
  const skeletonText = await fs18.readFile(absoluteSkeletonPath, "utf-8");
10197
10141
  const devExternals = extractDevExternals(skeletonText);
10198
- const tInput = options.telemetry;
10199
- const tLevel = tInput?.level ?? "standard";
10200
- const telemetry = tInput ? {
10201
- observerUrl: tInput.observerUrl,
10202
- ingestToken: tInput.ingestToken,
10203
- flowId: tInput.flowId,
10204
- level: tLevel,
10205
- ...tInput.traceUrl !== void 0 ? { traceUrl: tInput.traceUrl } : {},
10206
- ...tInput.sample !== void 0 ? { sample: tInput.sample } : {}
10207
- } : void 0;
10208
10142
  const entryText = platform === "browser" ? generateWrapEntry(absoluteSkeletonPath, {
10209
10143
  ...windowCollector ? { windowCollector } : {},
10210
10144
  ...windowElb ? { windowElb } : {},
10211
10145
  ...options.preview ? { preview: options.preview } : {},
10212
10146
  ...options.previewGrantTargets ? { previewGrantTargets: options.previewGrantTargets } : {},
10213
10147
  platform,
10214
- ...telemetry ? { telemetry } : {}
10148
+ ...options.observe ? { observe: options.observe } : {}
10215
10149
  }) : generateWrapEntryServer(absoluteSkeletonPath);
10216
10150
  const entryDir = await fs18.mkdtemp(path19.join(os3.tmpdir(), "walkeros-wrap-"));
10217
10151
  const entryPath = path19.join(entryDir, "flow.mjs");
@@ -10224,7 +10158,7 @@ async function wrapSkeleton(options) {
10224
10158
  format: "esm",
10225
10159
  platform,
10226
10160
  outfile: outputPath,
10227
- // Resolve `@walkeros/core` (used by the telemetry block) from the CLI
10161
+ // Resolve `@walkeros/core` (used by the preview activator) from the CLI
10228
10162
  // package's own dependency tree and the workspace root. Without this,
10229
10163
  // esbuild looks under the temp entryDir which has no node_modules.
10230
10164
  // The wrap step always runs from inside the CLI process; both the