@basis-theory-labs/cli 4.0.0 → 4.2.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/README.md CHANGED
@@ -19,7 +19,7 @@ $ npm install -g @basis-theory-labs/cli
19
19
  $ bt COMMAND
20
20
  running command...
21
21
  $ bt (--version)
22
- @basis-theory-labs/cli/4.0.0 linux-x64 node-v22.23.1
22
+ @basis-theory-labs/cli/4.2.0 linux-x64 node-v22.23.1
23
23
  $ bt --help [COMMAND]
24
24
  USAGE
25
25
  $ bt COMMAND
@@ -62,7 +62,7 @@ EXAMPLES
62
62
  $ bt applications
63
63
  ```
64
64
 
65
- _See code: [dist/commands/applications/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.0.0/dist/commands/applications/index.ts)_
65
+ _See code: [dist/commands/applications/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.2.0/dist/commands/applications/index.ts)_
66
66
 
67
67
  ## `bt applications create`
68
68
 
@@ -151,7 +151,7 @@ EXAMPLES
151
151
  $ bt proxies
152
152
  ```
153
153
 
154
- _See code: [dist/commands/proxies/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.0.0/dist/commands/proxies/index.ts)_
154
+ _See code: [dist/commands/proxies/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.2.0/dist/commands/proxies/index.ts)_
155
155
 
156
156
  ## `bt proxies create`
157
157
 
@@ -160,9 +160,9 @@ Creates a new Pre-Configured Proxy. Requires `proxy:create` Management Applicati
160
160
  ```
161
161
  USAGE
162
162
  $ bt proxies create -x <value> [-n <value>] [-u <value>] [-q <value>] [-s <value>] [-i <value>] [-c <value>] [-a]
163
- [--request-transform-image node-bt|node22] [--request-transform-package-json <value>] [--request-transform-timeout
164
- <value>] [--request-transform-warm-concurrency <value>] [--request-transform-resources standard|large|xlarge]
165
- [--request-transform-permissions <value>] [--response-transform-image node-bt|node22]
163
+ [--request-transform-image node-bt|node22|node24] [--request-transform-package-json <value>]
164
+ [--request-transform-timeout <value>] [--request-transform-warm-concurrency <value>] [--request-transform-resources
165
+ standard|large|xlarge] [--request-transform-permissions <value>] [--response-transform-image node-bt|node22|node24]
166
166
  [--response-transform-package-json <value>] [--response-transform-timeout <value>]
167
167
  [--response-transform-warm-concurrency <value>] [--response-transform-resources standard|large|xlarge]
168
168
  [--response-transform-permissions <value>] [--no-wait]
@@ -178,27 +178,29 @@ FLAGS
178
178
  -u, --destination-url=<value> URL to which requests will be proxied
179
179
  -x, --management-key=<value> (required) management key used for connecting with the reactor / proxy
180
180
  --no-wait do not wait for proxy to be ready (requires at least one transform with
181
- node22)
182
- --request-transform-image=<option> request-transform runtime image (node-bt|node22)
183
- <options: node-bt|node22>
181
+ node22 | node24)
182
+ --request-transform-image=<option> request-transform runtime image (node-bt|node22|node24)
183
+ <options: node-bt|node22|node24>
184
184
  --request-transform-package-json=<value> path to runtime package.json JSON file (top-level dependencies
185
185
  required; supports resolutions or overrides fallback; pinned versions
186
- required) (node22 only)
187
- --request-transform-permissions=<value>... request-transform permission to grant, repeatable (node22 only)
188
- --request-transform-resources=<option> request-transform resource tier (node22 only)
186
+ required) (node22 | node24 only)
187
+ --request-transform-permissions=<value>... request-transform permission to grant, repeatable (node22 | node24
188
+ only)
189
+ --request-transform-resources=<option> request-transform resource tier (node22 | node24 only)
189
190
  <options: standard|large|xlarge>
190
- --request-transform-timeout=<value> request-transform timeout in seconds, 10-30 (node22 only)
191
- --request-transform-warm-concurrency=<value> request-transform warm concurrency, 0-1 (node22 only)
192
- --response-transform-image=<option> response-transform runtime image (node-bt|node22)
193
- <options: node-bt|node22>
191
+ --request-transform-timeout=<value> request-transform timeout in seconds, 10-30 (node22 | node24 only)
192
+ --request-transform-warm-concurrency=<value> request-transform warm concurrency, 0-1 (node22 | node24 only)
193
+ --response-transform-image=<option> response-transform runtime image (node-bt|node22|node24)
194
+ <options: node-bt|node22|node24>
194
195
  --response-transform-package-json=<value> path to runtime package.json JSON file (top-level dependencies
195
196
  required; supports resolutions or overrides fallback; pinned versions
196
- required) (node22 only)
197
- --response-transform-permissions=<value>... response-transform permission to grant, repeatable (node22 only)
198
- --response-transform-resources=<option> response-transform resource tier (node22 only)
197
+ required) (node22 | node24 only)
198
+ --response-transform-permissions=<value>... response-transform permission to grant, repeatable (node22 | node24
199
+ only)
200
+ --response-transform-resources=<option> response-transform resource tier (node22 | node24 only)
199
201
  <options: standard|large|xlarge>
200
- --response-transform-timeout=<value> response-transform timeout in seconds, 10-30 (node22 only)
201
- --response-transform-warm-concurrency=<value> response-transform warm concurrency, 0-1 (node22 only)
202
+ --response-transform-timeout=<value> response-transform timeout in seconds, 10-30 (node22 | node24 only)
203
+ --response-transform-warm-concurrency=<value> response-transform warm concurrency, 0-1 (node22 | node24 only)
202
204
 
203
205
  DESCRIPTION
204
206
  Creates a new Pre-Configured Proxy. Requires `proxy:create` Management Application permission
@@ -285,9 +287,9 @@ Updates an existing Pre-Configured Proxy. Requires `proxy:update` Management App
285
287
  ```
286
288
  USAGE
287
289
  $ bt proxies update ID -x <value> [-n <value>] [-u <value>] [-q <value>] [-s <value>] [-i <value>] [-c <value>]
288
- [-a] [--request-transform-image node-bt|node22] [--request-transform-package-json <value>]
290
+ [-a] [--request-transform-image node-bt|node22|node24] [--request-transform-package-json <value>]
289
291
  [--request-transform-timeout <value>] [--request-transform-warm-concurrency <value>] [--request-transform-resources
290
- standard|large|xlarge] [--request-transform-permissions <value>] [--response-transform-image node-bt|node22]
292
+ standard|large|xlarge] [--request-transform-permissions <value>] [--response-transform-image node-bt|node22|node24]
291
293
  [--response-transform-package-json <value>] [--response-transform-timeout <value>]
292
294
  [--response-transform-warm-concurrency <value>] [--response-transform-resources standard|large|xlarge]
293
295
  [--response-transform-permissions <value>] [--no-wait] [-w] [-l]
@@ -308,27 +310,29 @@ FLAGS
308
310
  -w, --watch Watch for changes in informed files
309
311
  -x, --management-key=<value> (required) management key used for connecting with the reactor / proxy
310
312
  --no-wait do not wait for proxy to be ready (requires at least one transform with
311
- node22)
312
- --request-transform-image=<option> request-transform runtime image (node-bt|node22)
313
- <options: node-bt|node22>
313
+ node22 | node24)
314
+ --request-transform-image=<option> request-transform runtime image (node-bt|node22|node24)
315
+ <options: node-bt|node22|node24>
314
316
  --request-transform-package-json=<value> path to runtime package.json JSON file (top-level dependencies
315
317
  required; supports resolutions or overrides fallback; pinned versions
316
- required) (node22 only)
317
- --request-transform-permissions=<value>... request-transform permission to grant, repeatable (node22 only)
318
- --request-transform-resources=<option> request-transform resource tier (node22 only)
318
+ required) (node22 | node24 only)
319
+ --request-transform-permissions=<value>... request-transform permission to grant, repeatable (node22 | node24
320
+ only)
321
+ --request-transform-resources=<option> request-transform resource tier (node22 | node24 only)
319
322
  <options: standard|large|xlarge>
320
- --request-transform-timeout=<value> request-transform timeout in seconds, 10-30 (node22 only)
321
- --request-transform-warm-concurrency=<value> request-transform warm concurrency, 0-1 (node22 only)
322
- --response-transform-image=<option> response-transform runtime image (node-bt|node22)
323
- <options: node-bt|node22>
323
+ --request-transform-timeout=<value> request-transform timeout in seconds, 10-30 (node22 | node24 only)
324
+ --request-transform-warm-concurrency=<value> request-transform warm concurrency, 0-1 (node22 | node24 only)
325
+ --response-transform-image=<option> response-transform runtime image (node-bt|node22|node24)
326
+ <options: node-bt|node22|node24>
324
327
  --response-transform-package-json=<value> path to runtime package.json JSON file (top-level dependencies
325
328
  required; supports resolutions or overrides fallback; pinned versions
326
- required) (node22 only)
327
- --response-transform-permissions=<value>... response-transform permission to grant, repeatable (node22 only)
328
- --response-transform-resources=<option> response-transform resource tier (node22 only)
329
+ required) (node22 | node24 only)
330
+ --response-transform-permissions=<value>... response-transform permission to grant, repeatable (node22 | node24
331
+ only)
332
+ --response-transform-resources=<option> response-transform resource tier (node22 | node24 only)
329
333
  <options: standard|large|xlarge>
330
- --response-transform-timeout=<value> response-transform timeout in seconds, 10-30 (node22 only)
331
- --response-transform-warm-concurrency=<value> response-transform warm concurrency, 0-1 (node22 only)
334
+ --response-transform-timeout=<value> response-transform timeout in seconds, 10-30 (node22 | node24 only)
335
+ --response-transform-warm-concurrency=<value> response-transform warm concurrency, 0-1 (node22 | node24 only)
332
336
 
333
337
  DESCRIPTION
334
338
  Updates an existing Pre-Configured Proxy. Requires `proxy:update` Management Application permission
@@ -378,7 +382,7 @@ EXAMPLES
378
382
  $ bt reactors
379
383
  ```
380
384
 
381
- _See code: [dist/commands/reactors/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.0.0/dist/commands/reactors/index.ts)_
385
+ _See code: [dist/commands/reactors/index.ts](https://github.com/Basis-Theory-Labs/basistheory-cli/blob/v4.2.0/dist/commands/reactors/index.ts)_
382
386
 
383
387
  ## `bt reactors create`
384
388
 
@@ -386,7 +390,7 @@ Creates a new Reactor. Requires `reactor:create` Management Application permissi
386
390
 
387
391
  ```
388
392
  USAGE
389
- $ bt reactors create -x <value> [-n <value>] [-c <value>] [-i <value>] [-r <value>] [--image node-bt|node22]
393
+ $ bt reactors create -x <value> [-n <value>] [-c <value>] [-i <value>] [-r <value>] [--image node-bt|node22|node24]
390
394
  [--package-json <value>] [--timeout <value>] [--warm-concurrency <value>] [--resources standard|large|xlarge]
391
395
  [--permissions <value>] [--no-wait] [--async]
392
396
 
@@ -396,18 +400,18 @@ FLAGS
396
400
  -n, --name=<value> name of the Reactor
397
401
  -r, --code=<value> path to JavaScript file containing the Reactor code
398
402
  -x, --management-key=<value> (required) management key used for connecting with the reactor / proxy
399
- --[no-]async execute Reactor invocations asynchronously (node22 only)
400
- --image=<option> runtime image (node-bt|node22)
401
- <options: node-bt|node22>
403
+ --[no-]async execute Reactor invocations asynchronously (node22 | node24 only)
404
+ --image=<option> runtime image (node-bt|node22|node24)
405
+ <options: node-bt|node22|node24>
402
406
  --no-wait do not wait for resource provisioning to complete
403
407
  --package-json=<value> path to runtime package.json JSON file (top-level dependencies required; supports
404
- resolutions or overrides fallback; pinned versions required) (node22 only)
405
- --permissions=<value>... permission to grant, repeatable (node22 only)
406
- --resources=<option> resource tier (node22 only, default: standard)
408
+ resolutions or overrides fallback; pinned versions required) (node22 | node24 only)
409
+ --permissions=<value>... permission to grant, repeatable (node22 | node24 only)
410
+ --resources=<option> resource tier (node22 | node24 only, default: standard)
407
411
  <options: standard|large|xlarge>
408
- --timeout=<value> timeout in seconds, 10-900 (node22 only; maximum 30 when runtime async is disabled;
409
- default: 10)
410
- --warm-concurrency=<value> number of warm instances, 0-1 (node22 only, default: 0)
412
+ --timeout=<value> timeout in seconds, 10-900 (node22 | node24 only; maximum 30 when runtime async is
413
+ disabled; default: 10)
414
+ --warm-concurrency=<value> number of warm instances, 0-1 (node22 | node24 only, default: 0)
411
415
 
412
416
  DESCRIPTION
413
417
  Creates a new Reactor. Requires `reactor:create` Management Application permission
@@ -482,9 +486,9 @@ Updates an existing Reactor. Requires `reactor:update` Management Application pe
482
486
 
483
487
  ```
484
488
  USAGE
485
- $ bt reactors update ID -x <value> [-n <value>] [-c <value>] [-i <value>] [-r <value>] [--image node-bt|node22]
486
- [--package-json <value>] [--timeout <value>] [--warm-concurrency <value>] [--resources standard|large|xlarge]
487
- [--permissions <value>] [--no-wait] [--async] [-w] [-l]
489
+ $ bt reactors update ID -x <value> [-n <value>] [-c <value>] [-i <value>] [-r <value>] [--image
490
+ node-bt|node22|node24] [--package-json <value>] [--timeout <value>] [--warm-concurrency <value>] [--resources
491
+ standard|large|xlarge] [--permissions <value>] [--no-wait] [--async] [-w] [-l]
488
492
 
489
493
  ARGUMENTS
490
494
  ID Reactor id to update
@@ -495,20 +499,20 @@ FLAGS
495
499
  -l, --logs Start logs server after update
496
500
  -n, --name=<value> name of the Reactor
497
501
  -r, --code=<value> path to JavaScript file containing the Reactor code
498
- -w, --watch Watch for changes in informed files
502
+ -w, --watch Watch for changes in supplied code, configuration, and runtime package files
499
503
  -x, --management-key=<value> (required) management key used for connecting with the reactor / proxy
500
- --[no-]async execute Reactor invocations asynchronously (node22 only)
501
- --image=<option> runtime image (node-bt|node22)
502
- <options: node-bt|node22>
504
+ --[no-]async execute Reactor invocations asynchronously (node22 | node24 only)
505
+ --image=<option> runtime image (node-bt|node22|node24)
506
+ <options: node-bt|node22|node24>
503
507
  --no-wait do not wait for resource provisioning to complete
504
508
  --package-json=<value> path to runtime package.json JSON file (top-level dependencies required; supports
505
- resolutions or overrides fallback; pinned versions required) (node22 only)
506
- --permissions=<value>... permission to grant, repeatable (node22 only)
507
- --resources=<option> resource tier (node22 only, default: standard)
509
+ resolutions or overrides fallback; pinned versions required) (node22 | node24 only)
510
+ --permissions=<value>... permission to grant, repeatable (node22 | node24 only)
511
+ --resources=<option> resource tier (node22 | node24 only, default: standard)
508
512
  <options: standard|large|xlarge>
509
- --timeout=<value> timeout in seconds, 10-900 (node22 only; maximum 30 when runtime async is disabled;
510
- default: 10)
511
- --warm-concurrency=<value> number of warm instances, 0-1 (node22 only, default: 0)
513
+ --timeout=<value> timeout in seconds, 10-900 (node22 | node24 only; maximum 30 when runtime async is
514
+ disabled; default: 10)
515
+ --warm-concurrency=<value> number of warm instances, 0-1 (node22 | node24 only, default: 0)
512
516
 
513
517
  DESCRIPTION
514
518
  Updates an existing Reactor. Requires `reactor:update` Management Application permission
@@ -522,6 +526,11 @@ EXAMPLES
522
526
 
523
527
  $ bt reactors update <reactor-id> --code ./reactor.js --image node22
524
528
 
529
+ Watch a node22 reactor for code, configuration, and dependency changes
530
+
531
+ $ bt reactors update <reactor-id> --code ./reactor.js --configuration ./config.env --package-json ./package.json \
532
+ --image node22 --watch
533
+
525
534
  Update a reactor with node22 and all runtime options
526
535
 
527
536
  $ bt reactors update <reactor-id> --name "My Reactor" --code ./reactor.js --configuration ./config.env --image \
@@ -54,7 +54,7 @@ class Update extends base_1.BaseCommand {
54
54
  await (0, logs_1.showProxyLogs)(bt, id);
55
55
  }
56
56
  if (watch && isConfigurableRuntime) {
57
- this.warn(`--watch is not supported for configurable runtimes (${runtime_2.CONFIGURABLE_RUNTIME_IMAGES.join(' | ')}). Skipping watch.`);
57
+ this.warn(`--watch is not supported for configurable runtimes (${runtime_2.CONFIGURABLE_RUNTIME_IMAGES_LABEL}). Skipping watch.`);
58
58
  }
59
59
  else if (watch) {
60
60
  const entries = Object.entries({
@@ -13,13 +13,15 @@ class Update extends base_1.BaseCommand {
13
13
  var _a, _b, _c, _d;
14
14
  const { bt, args: { id }, flags, } = await this.parse(Update);
15
15
  const { name, code, 'application-id': applicationId, configuration, image, 'package-json': packageJson, timeout, 'warm-concurrency': warmConcurrency, resources, permissions, 'no-wait': noWait, async: runtimeAsync, watch, logs, } = flags;
16
- const existingReactor = (0, runtime_1.hasReactorRuntimeFlags)(flags) ||
16
+ const existingReactor = watch ||
17
+ (0, runtime_1.hasReactorRuntimeFlags)(flags) ||
17
18
  (applicationId !== undefined && image === undefined)
18
19
  ? await (0, management_1.getReactor)(bt, id)
19
20
  : undefined;
20
21
  const effectiveImage = image !== null && image !== void 0 ? image : (_a = existingReactor === null || existingReactor === void 0 ? void 0 : existingReactor.runtime) === null || _a === void 0 ? void 0 : _a.image;
21
22
  const effectiveRuntimeAsync = (_c = runtimeAsync !== null && runtimeAsync !== void 0 ? runtimeAsync : (_b = existingReactor === null || existingReactor === void 0 ? void 0 : existingReactor.runtime) === null || _b === void 0 ? void 0 : _b.async) !== null && _c !== void 0 ? _c : false;
22
23
  const effectiveTimeout = timeout !== null && timeout !== void 0 ? timeout : (_d = existingReactor === null || existingReactor === void 0 ? void 0 : existingReactor.runtime) === null || _d === void 0 ? void 0 : _d.timeout;
24
+ const isConfigurableRuntime = !(0, runtime_2.isLegacyRuntimeImage)(effectiveImage);
23
25
  (0, runtime_1.validateReactorRuntimeFlags)(flags, effectiveImage);
24
26
  (0, runtime_1.validateReactorApplicationId)(applicationId, effectiveImage);
25
27
  if (timeout !== undefined || runtimeAsync !== undefined) {
@@ -42,36 +44,110 @@ class Update extends base_1.BaseCommand {
42
44
  runtime,
43
45
  });
44
46
  await (0, management_1.patchReactor)(bt, id, model);
45
- const reactor = await (0, management_1.getReactor)(bt, id);
46
- const isConfigurableRuntime = (0, runtime_2.needsPolling)(reactor.state);
47
- if (!noWait) {
48
- await (0, runtime_2.waitForResourceState)(bt, 'reactor', id, reactor.state);
49
- }
50
- this.log('Reactor updated successfully!');
51
- if (logs) {
52
- await (0, logs_1.showReactorLogs)(bt, id);
53
- }
54
- if (watch && isConfigurableRuntime) {
55
- this.warn(`--watch is not supported for configurable runtimes (${runtime_2.CONFIGURABLE_RUNTIME_IMAGES.join(' | ')}). Skipping watch.`);
56
- }
57
- else if (watch) {
58
- const entries = Object.entries({
59
- code,
60
- configuration,
61
- }).filter(([, value]) => Boolean(value));
62
- const files = entries.reduce((arr, [, file]) => [...arr, file], []);
47
+ const watchedEntries = Object.entries({
48
+ code,
49
+ configuration,
50
+ ...(isConfigurableRuntime ? { packageJson } : {}),
51
+ }).filter(([, value]) => Boolean(value));
52
+ const startWatching = (initialUpdateCompleted) => {
53
+ const files = watchedEntries.reduce((arr, [, file]) => [...arr, file], []);
63
54
  if (files.length) {
64
55
  this.log(`Watching files for changes: ${files.join(', ')} `);
65
56
  }
66
- entries.forEach(([prop, file]) => {
67
- (0, files_1.watchForChanges)(file, async () => {
68
- core_1.ux.action.start(`Detected change in ${file}. Pushing changes`);
69
- await (0, management_1.patchReactor)(bt, id, (0, utils_1.createModelFromFlags)({
70
- [prop]: file,
71
- }));
72
- core_1.ux.action.stop('✅\t');
57
+ if (isConfigurableRuntime) {
58
+ const waitUntilReactorIsAvailable = async () => {
59
+ await initialUpdateCompleted;
60
+ const currentReactor = await (0, management_1.getReactor)(bt, id);
61
+ if (!(0, runtime_2.needsPolling)(currentReactor.state)) {
62
+ return;
63
+ }
64
+ try {
65
+ await (0, runtime_2.waitForResourceState)(bt, 'reactor', id, currentReactor.state);
66
+ }
67
+ catch (error) {
68
+ const latestReactor = await (0, management_1.getReactor)(bt, id);
69
+ if (latestReactor.state !== 'failed' &&
70
+ latestReactor.state !== 'outdated') {
71
+ throw error;
72
+ }
73
+ }
74
+ };
75
+ const pushLatestChanges = (0, files_1.createCoalescingHandler)(async (markLatestStateCaptured) => {
76
+ await waitUntilReactorIsAvailable();
77
+ core_1.ux.action.start('Pushing latest watched changes');
78
+ try {
79
+ markLatestStateCaptured();
80
+ await (0, management_1.patchReactor)(bt, id, (0, utils_1.createModelFromFlags)({
81
+ code,
82
+ configuration,
83
+ runtime: (0, runtime_2.buildReactorRuntime)({ packageJson }),
84
+ }));
85
+ core_1.ux.action.stop('✅\t');
86
+ }
87
+ catch (error) {
88
+ core_1.ux.action.stop('failed ❌');
89
+ throw error;
90
+ }
91
+ const updatedReactor = await (0, management_1.getReactor)(bt, id);
92
+ await (0, runtime_2.waitForResourceState)(bt, 'reactor', id, updatedReactor.state);
93
+ }, (error) => {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ this.warn(`Failed to push watched Reactor changes: ${message}`);
73
96
  });
74
- });
97
+ watchedEntries.forEach(([, file]) => {
98
+ (0, files_1.watchForChanges)(file, () => {
99
+ this.log(`Detected change in ${file}. Queuing latest files`);
100
+ return pushLatestChanges();
101
+ });
102
+ });
103
+ }
104
+ else {
105
+ watchedEntries.forEach(([prop, file]) => {
106
+ (0, files_1.watchForChanges)(file, async () => {
107
+ core_1.ux.action.start(`Detected change in ${file}. Pushing changes`);
108
+ await (0, management_1.patchReactor)(bt, id, (0, utils_1.createModelFromFlags)({
109
+ [prop]: file,
110
+ }));
111
+ core_1.ux.action.stop('✅\t');
112
+ });
113
+ });
114
+ }
115
+ };
116
+ let initialUpdateError;
117
+ const completeInitialUpdate = async () => {
118
+ if (!noWait) {
119
+ try {
120
+ const initialState = isConfigurableRuntime
121
+ ? 'updating'
122
+ : (await (0, management_1.getReactor)(bt, id)).state;
123
+ await (0, runtime_2.waitForResourceState)(bt, 'reactor', id, initialState);
124
+ }
125
+ catch (error) {
126
+ if (!watch || !isConfigurableRuntime) {
127
+ throw error;
128
+ }
129
+ initialUpdateError = error;
130
+ const message = error instanceof Error ? error.message : String(error);
131
+ this.warn(`Initial Reactor update failed: ${message}`);
132
+ }
133
+ }
134
+ if (initialUpdateError) {
135
+ this.log('Watch remains active. Save a watched file to retry the latest snapshot.');
136
+ }
137
+ else {
138
+ this.log('Reactor updated successfully!');
139
+ }
140
+ };
141
+ const initialUpdateCompleted = completeInitialUpdate();
142
+ if (watch && isConfigurableRuntime) {
143
+ startWatching(initialUpdateCompleted);
144
+ }
145
+ await initialUpdateCompleted;
146
+ if (logs && !initialUpdateError) {
147
+ await (0, logs_1.showReactorLogs)(bt, id);
148
+ }
149
+ if (watch && !isConfigurableRuntime) {
150
+ startWatching();
75
151
  }
76
152
  }
77
153
  }
@@ -86,6 +162,15 @@ Update.examples = [
86
162
  description: 'Update a reactor with node22 runtime',
87
163
  command: '<%= config.bin %> <%= command.id %> <reactor-id> --code ./reactor.js --image node22',
88
164
  },
165
+ {
166
+ description: 'Watch a node22 reactor for code, configuration, and dependency changes',
167
+ command: '<%= config.bin %> <%= command.id %> <reactor-id> ' +
168
+ '--code ./reactor.js ' +
169
+ '--configuration ./config.env ' +
170
+ '--package-json ./package.json ' +
171
+ '--image node22 ' +
172
+ '--watch',
173
+ },
89
174
  {
90
175
  description: 'Update a reactor with node22 and all runtime options',
91
176
  command: '<%= config.bin %> <%= command.id %> <reactor-id> ' +
@@ -106,7 +191,7 @@ Update.flags = {
106
191
  ...utils_1.REACTOR_FLAGS,
107
192
  watch: core_1.Flags.boolean({
108
193
  char: 'w',
109
- description: 'Watch for changes in informed files',
194
+ description: 'Watch for changes in supplied code, configuration, and runtime package files',
110
195
  default: false,
111
196
  required: false,
112
197
  }),
package/dist/files.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as fs from 'fs';
2
2
  declare const readFileContents: (filePath: string) => string;
3
+ declare const createCoalescingHandler: (handler: (markLatestStateCaptured: () => void) => Promise<void>, onError: (error: unknown) => void) => (() => Promise<void>);
3
4
  declare const watchForChanges: (filePath: string, handler: (contents: string) => unknown) => fs.FSWatcher;
4
- export { readFileContents, watchForChanges };
5
+ export { createCoalescingHandler, readFileContents, watchForChanges };
package/dist/files.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.watchForChanges = exports.readFileContents = void 0;
3
+ exports.watchForChanges = exports.readFileContents = exports.createCoalescingHandler = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fs = tslib_1.__importStar(require("fs"));
6
6
  const lodash_debounce_1 = tslib_1.__importDefault(require("lodash.debounce"));
@@ -8,6 +8,36 @@ const path = tslib_1.__importStar(require("path"));
8
8
  const readFileContents = (filePath) => fs.readFileSync(path.resolve(process.cwd(), filePath)).toString();
9
9
  exports.readFileContents = readFileContents;
10
10
  const FILE_WATCH_DEBOUNCE_DELAY = 1000;
11
+ const createCoalescingHandler = (handler, onError) => {
12
+ let pending = false;
13
+ let running;
14
+ const markLatestStateCaptured = () => {
15
+ pending = false;
16
+ };
17
+ /* eslint-disable no-await-in-loop */
18
+ const drain = async () => {
19
+ while (pending) {
20
+ pending = false;
21
+ try {
22
+ await handler(markLatestStateCaptured);
23
+ }
24
+ catch (error) {
25
+ onError(error);
26
+ }
27
+ }
28
+ };
29
+ /* eslint-enable no-await-in-loop */
30
+ return () => {
31
+ pending = true;
32
+ if (!running) {
33
+ running = drain().finally(() => {
34
+ running = undefined;
35
+ });
36
+ }
37
+ return running;
38
+ };
39
+ };
40
+ exports.createCoalescingHandler = createCoalescingHandler;
11
41
  const watchForChanges = (filePath, handler) => {
12
42
  let lastContents = '';
13
43
  const debounced = (0, lodash_debounce_1.default)(() => {
@@ -14,7 +14,7 @@ const validateTransformRuntimeFlags = (prefix, flags, image) => {
14
14
  }
15
15
  if (setFlags.length && (0, runtime_1.isLegacyRuntimeImage)(image)) {
16
16
  const flagNames = setFlags.map((f) => `--${f}`).join(', ');
17
- throw new Error(`Configurable runtime flags (${flagNames}) require --${prefix}-image ${runtime_1.CONFIGURABLE_RUNTIME_IMAGES.join(' | ')}`);
17
+ throw new Error(`Configurable runtime flags (${flagNames}) require --${prefix}-image ${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL}`);
18
18
  }
19
19
  };
20
20
  exports.validateTransformRuntimeFlags = validateTransformRuntimeFlags;
@@ -37,57 +37,57 @@ const PROXY_FLAGS = {
37
37
  default: true,
38
38
  }),
39
39
  'request-transform-image': core_1.Flags.string({
40
- description: `request-transform runtime image (${runtime_1.VALID_RUNTIME_IMAGES.join('|')})`,
40
+ description: `request-transform runtime image (${runtime_1.VALID_RUNTIME_IMAGES_LABEL})`,
41
41
  options: [...runtime_1.VALID_RUNTIME_IMAGES],
42
42
  }),
43
43
  'request-transform-package-json': core_1.Flags.file({
44
- description: 'path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)',
44
+ description: `path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
45
45
  }),
46
46
  'request-transform-timeout': core_1.Flags.integer({
47
- description: 'request-transform timeout in seconds, 10-30 (node22 only)',
47
+ description: `request-transform timeout in seconds, 10-30 (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
48
48
  min: 10,
49
49
  max: 30,
50
50
  }),
51
51
  'request-transform-warm-concurrency': core_1.Flags.integer({
52
- description: 'request-transform warm concurrency, 0-1 (node22 only)',
52
+ description: `request-transform warm concurrency, 0-1 (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
53
53
  min: 0,
54
54
  max: 1,
55
55
  }),
56
56
  'request-transform-resources': core_1.Flags.string({
57
- description: 'request-transform resource tier (node22 only)',
57
+ description: `request-transform resource tier (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
58
58
  options: ['standard', 'large', 'xlarge'],
59
59
  }),
60
60
  'request-transform-permissions': core_1.Flags.string({
61
- description: 'request-transform permission to grant, repeatable (node22 only)',
61
+ description: `request-transform permission to grant, repeatable (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
62
62
  multiple: true,
63
63
  }),
64
64
  'response-transform-image': core_1.Flags.string({
65
- description: `response-transform runtime image (${runtime_1.VALID_RUNTIME_IMAGES.join('|')})`,
65
+ description: `response-transform runtime image (${runtime_1.VALID_RUNTIME_IMAGES_LABEL})`,
66
66
  options: [...runtime_1.VALID_RUNTIME_IMAGES],
67
67
  }),
68
68
  'response-transform-package-json': core_1.Flags.file({
69
- description: 'path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)',
69
+ description: `path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
70
70
  }),
71
71
  'response-transform-timeout': core_1.Flags.integer({
72
- description: 'response-transform timeout in seconds, 10-30 (node22 only)',
72
+ description: `response-transform timeout in seconds, 10-30 (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
73
73
  min: 10,
74
74
  max: 30,
75
75
  }),
76
76
  'response-transform-warm-concurrency': core_1.Flags.integer({
77
- description: 'response-transform warm concurrency, 0-1 (node22 only)',
77
+ description: `response-transform warm concurrency, 0-1 (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
78
78
  min: 0,
79
79
  max: 1,
80
80
  }),
81
81
  'response-transform-resources': core_1.Flags.string({
82
- description: 'response-transform resource tier (node22 only)',
82
+ description: `response-transform resource tier (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
83
83
  options: ['standard', 'large', 'xlarge'],
84
84
  }),
85
85
  'response-transform-permissions': core_1.Flags.string({
86
- description: 'response-transform permission to grant, repeatable (node22 only)',
86
+ description: `response-transform permission to grant, repeatable (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
87
87
  multiple: true,
88
88
  }),
89
89
  'no-wait': core_1.Flags.boolean({
90
- description: 'do not wait for proxy to be ready (requires at least one transform with node22)',
90
+ description: `do not wait for proxy to be ready (requires at least one transform with ${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL})`,
91
91
  default: false,
92
92
  }),
93
93
  };
@@ -18,13 +18,13 @@ const validateReactorRuntimeFlags = (flags, image) => {
18
18
  }
19
19
  if (setFlags.length && (0, runtime_1.isLegacyRuntimeImage)(image)) {
20
20
  const flagNames = setFlags.map((f) => `--${f}`).join(', ');
21
- throw new Error(`Configurable runtime flags (${flagNames}) require --image ${runtime_1.CONFIGURABLE_RUNTIME_IMAGES.join(' | ')}`);
21
+ throw new Error(`Configurable runtime flags (${flagNames}) require --image ${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL}`);
22
22
  }
23
23
  };
24
24
  exports.validateReactorRuntimeFlags = validateReactorRuntimeFlags;
25
25
  const validateReactorApplicationId = (applicationId, image) => {
26
26
  if (applicationId && !(0, runtime_1.isLegacyRuntimeImage)(image)) {
27
- throw new Error(`--application-id is not allowed with configurable runtimes (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES.join(' | ')}). Use --permissions to grant specific access instead.`);
27
+ throw new Error(`--application-id is not allowed with configurable runtimes (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL}). Use --permissions to grant specific access instead.`);
28
28
  }
29
29
  };
30
30
  exports.validateReactorApplicationId = validateReactorApplicationId;
@@ -4,10 +4,10 @@ declare const REACTOR_FLAGS: {
4
4
  image: import("@oclif/core/lib/interfaces/parser").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
5
5
  'package-json': import("@oclif/core/lib/interfaces/parser").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
6
6
  timeout: import("@oclif/core/lib/interfaces/parser").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
- 'warm-concurrency': import("@oclif/core/lib/interfaces/parser").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
- resources: import("@oclif/core/lib/interfaces/parser").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>; /**
9
- * Path to code file
7
+ 'warm-concurrency': import("@oclif/core/lib/interfaces/parser").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>; /**
8
+ * Reactor's application id
10
9
  */
10
+ resources: import("@oclif/core/lib/interfaces/parser").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
11
  permissions: import("@oclif/core/lib/interfaces/parser").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
12
  'no-wait': import("@oclif/core/lib/interfaces/parser").BooleanFlag<boolean>;
13
13
  name: import("@oclif/core/lib/interfaces/parser").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
@@ -24,7 +24,7 @@ const REACTOR_FLAGS = {
24
24
  }),
25
25
  ...runtime_1.RUNTIME_FLAGS,
26
26
  async: core_1.Flags.boolean({
27
- description: 'execute Reactor invocations asynchronously (node22 only)',
27
+ description: `execute Reactor invocations asynchronously (${runtime_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
28
28
  allowNo: true,
29
29
  }),
30
30
  };
@@ -5,28 +5,28 @@ const core_1 = require("@oclif/core");
5
5
  const utils_1 = require("./utils");
6
6
  const RUNTIME_FLAGS = {
7
7
  image: core_1.Flags.string({
8
- description: `runtime image (${utils_1.VALID_RUNTIME_IMAGES.join('|')})`,
8
+ description: `runtime image (${utils_1.VALID_RUNTIME_IMAGES_LABEL})`,
9
9
  options: [...utils_1.VALID_RUNTIME_IMAGES],
10
10
  }),
11
11
  'package-json': core_1.Flags.file({
12
- description: 'path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)',
12
+ description: `path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (${utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
13
13
  }),
14
14
  timeout: core_1.Flags.integer({
15
- description: 'timeout in seconds, 10-900 (node22 only; maximum 30 when runtime async is disabled; default: 10)',
15
+ description: `timeout in seconds, 10-900 (${utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only; maximum 30 when runtime async is disabled; default: 10)`,
16
16
  min: 10,
17
17
  max: 900,
18
18
  }),
19
19
  'warm-concurrency': core_1.Flags.integer({
20
- description: 'number of warm instances, 0-1 (node22 only, default: 0)',
20
+ description: `number of warm instances, 0-1 (${utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only, default: 0)`,
21
21
  min: 0,
22
22
  max: 1,
23
23
  }),
24
24
  resources: core_1.Flags.string({
25
- description: 'resource tier (node22 only, default: standard)',
25
+ description: `resource tier (${utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only, default: standard)`,
26
26
  options: ['standard', 'large', 'xlarge'],
27
27
  }),
28
28
  permissions: core_1.Flags.string({
29
- description: 'permission to grant, repeatable (node22 only)',
29
+ description: `permission to grant, repeatable (${utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL} only)`,
30
30
  multiple: true,
31
31
  }),
32
32
  'no-wait': core_1.Flags.boolean({
@@ -1,3 +1,3 @@
1
- export { LEGACY_RUNTIME_IMAGE, CONFIGURABLE_RUNTIME_IMAGES, VALID_RUNTIME_IMAGES, CONFIGURABLE_RUNTIME_FLAGS, REACTOR_CONFIGURABLE_RUNTIME_FLAGS, isLegacyRuntimeImage, validateRuntimeImage, parseRuntimePackageJsonFile, buildRuntime, buildReactorRuntime, getMaxRuntimeTimeout, validateRuntimeTimeout, promptRuntimeOptions, promptRuntimeImage, type ConfigurableRuntimeOptions, type RuntimeFlagProps, type RuntimeFlags, } from './utils';
1
+ export { LEGACY_RUNTIME_IMAGE, CONFIGURABLE_RUNTIME_IMAGES, CONFIGURABLE_RUNTIME_IMAGES_LABEL, VALID_RUNTIME_IMAGES, VALID_RUNTIME_IMAGES_LABEL, CONFIGURABLE_RUNTIME_FLAGS, REACTOR_CONFIGURABLE_RUNTIME_FLAGS, isLegacyRuntimeImage, validateRuntimeImage, parseRuntimePackageJsonFile, buildRuntime, buildReactorRuntime, getMaxRuntimeTimeout, validateRuntimeTimeout, promptRuntimeOptions, promptRuntimeImage, type ConfigurableRuntimeOptions, type RuntimeFlagProps, type RuntimeFlags, } from './utils';
2
2
  export { RUNTIME_FLAGS } from './flags';
3
3
  export { waitForResourceState, needsPolling, POLL_INTERVAL, POLL_TIMEOUT, } from './state';
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.POLL_TIMEOUT = exports.POLL_INTERVAL = exports.needsPolling = exports.waitForResourceState = exports.RUNTIME_FLAGS = exports.promptRuntimeImage = exports.promptRuntimeOptions = exports.validateRuntimeTimeout = exports.getMaxRuntimeTimeout = exports.buildReactorRuntime = exports.buildRuntime = exports.parseRuntimePackageJsonFile = exports.validateRuntimeImage = exports.isLegacyRuntimeImage = exports.REACTOR_CONFIGURABLE_RUNTIME_FLAGS = exports.CONFIGURABLE_RUNTIME_FLAGS = exports.VALID_RUNTIME_IMAGES = exports.CONFIGURABLE_RUNTIME_IMAGES = exports.LEGACY_RUNTIME_IMAGE = void 0;
3
+ exports.POLL_TIMEOUT = exports.POLL_INTERVAL = exports.needsPolling = exports.waitForResourceState = exports.RUNTIME_FLAGS = exports.promptRuntimeImage = exports.promptRuntimeOptions = exports.validateRuntimeTimeout = exports.getMaxRuntimeTimeout = exports.buildReactorRuntime = exports.buildRuntime = exports.parseRuntimePackageJsonFile = exports.validateRuntimeImage = exports.isLegacyRuntimeImage = exports.REACTOR_CONFIGURABLE_RUNTIME_FLAGS = exports.CONFIGURABLE_RUNTIME_FLAGS = exports.VALID_RUNTIME_IMAGES_LABEL = exports.VALID_RUNTIME_IMAGES = exports.CONFIGURABLE_RUNTIME_IMAGES_LABEL = exports.CONFIGURABLE_RUNTIME_IMAGES = exports.LEGACY_RUNTIME_IMAGE = void 0;
4
4
  var utils_1 = require("./utils");
5
5
  Object.defineProperty(exports, "LEGACY_RUNTIME_IMAGE", { enumerable: true, get: function () { return utils_1.LEGACY_RUNTIME_IMAGE; } });
6
6
  Object.defineProperty(exports, "CONFIGURABLE_RUNTIME_IMAGES", { enumerable: true, get: function () { return utils_1.CONFIGURABLE_RUNTIME_IMAGES; } });
7
+ Object.defineProperty(exports, "CONFIGURABLE_RUNTIME_IMAGES_LABEL", { enumerable: true, get: function () { return utils_1.CONFIGURABLE_RUNTIME_IMAGES_LABEL; } });
7
8
  Object.defineProperty(exports, "VALID_RUNTIME_IMAGES", { enumerable: true, get: function () { return utils_1.VALID_RUNTIME_IMAGES; } });
9
+ Object.defineProperty(exports, "VALID_RUNTIME_IMAGES_LABEL", { enumerable: true, get: function () { return utils_1.VALID_RUNTIME_IMAGES_LABEL; } });
8
10
  Object.defineProperty(exports, "CONFIGURABLE_RUNTIME_FLAGS", { enumerable: true, get: function () { return utils_1.CONFIGURABLE_RUNTIME_FLAGS; } });
9
11
  Object.defineProperty(exports, "REACTOR_CONFIGURABLE_RUNTIME_FLAGS", { enumerable: true, get: function () { return utils_1.REACTOR_CONFIGURABLE_RUNTIME_FLAGS; } });
10
12
  Object.defineProperty(exports, "isLegacyRuntimeImage", { enumerable: true, get: function () { return utils_1.isLegacyRuntimeImage; } });
@@ -64,9 +64,11 @@ const waitForResourceState = async (bt, resourceType, id, initialState) => {
64
64
  }
65
65
  const deadline = Date.now() + POLL_TIMEOUT;
66
66
  const startTime = Date.now();
67
- let currentState;
67
+ let currentState = initialState;
68
68
  const timer = createTimer(startTime, () => currentState);
69
- core_1.ux.action.start('Status');
69
+ core_1.ux.action.start('Status', currentState
70
+ ? `${currentState} (${formatElapsedTime(startTime)})`
71
+ : undefined);
70
72
  /* eslint-disable no-await-in-loop */
71
73
  try {
72
74
  while (Date.now() < deadline) {
@@ -83,11 +85,11 @@ const waitForResourceState = async (bt, resourceType, id, initialState) => {
83
85
  currentState = resource.state;
84
86
  core_1.ux.action.status = `${currentState} (${formatElapsedTime(startTime)})`;
85
87
  if (currentState === 'active') {
86
- core_1.ux.action.stop(`ready (${formatElapsedTime(startTime)})`);
88
+ core_1.ux.action.stop(`ready (${formatElapsedTime(startTime)}) ✅`);
87
89
  return;
88
90
  }
89
91
  if (currentState === 'failed' || currentState === 'outdated') {
90
- core_1.ux.action.stop(`failed (${formatElapsedTime(startTime)})`);
92
+ core_1.ux.action.stop(`failed (${formatElapsedTime(startTime)}) ❌`);
91
93
  throw new Error(formatErrorMessage(resource, resourceType));
92
94
  }
93
95
  await new Promise((resolve) => {
@@ -1,7 +1,9 @@
1
1
  import type { BasisTheory } from '@basis-theory/node-sdk';
2
2
  declare const LEGACY_RUNTIME_IMAGE = "node-bt";
3
- declare const CONFIGURABLE_RUNTIME_IMAGES: readonly ["node22"];
4
- declare const VALID_RUNTIME_IMAGES: readonly ["node-bt", "node22"];
3
+ declare const CONFIGURABLE_RUNTIME_IMAGES: readonly ["node22", "node24"];
4
+ declare const CONFIGURABLE_RUNTIME_IMAGES_LABEL: string;
5
+ declare const VALID_RUNTIME_IMAGES: readonly ["node-bt", "node22", "node24"];
6
+ declare const VALID_RUNTIME_IMAGES_LABEL: string;
5
7
  declare const isLegacyRuntimeImage: (image: string | undefined) => boolean;
6
8
  declare const validateRuntimeImage: (image: string | undefined) => void;
7
9
  declare const CONFIGURABLE_RUNTIME_FLAGS: readonly ["timeout", "resources", "warm-concurrency", "permissions", "package-json"];
@@ -43,4 +45,4 @@ declare const getMaxRuntimeTimeout: (runtimeAsync: boolean) => number;
43
45
  declare const validateRuntimeTimeout: (timeout: number | undefined, runtimeAsync: boolean) => void;
44
46
  declare const promptRuntimeOptions: (flags: RuntimeFlags, labelPrefix?: string, timeoutMax?: number) => Promise<ConfigurableRuntimeOptions>;
45
47
  declare const promptRuntimeImage: (image: string | undefined, message?: string) => Promise<string>;
46
- export { LEGACY_RUNTIME_IMAGE, CONFIGURABLE_RUNTIME_IMAGES, VALID_RUNTIME_IMAGES, CONFIGURABLE_RUNTIME_FLAGS, REACTOR_CONFIGURABLE_RUNTIME_FLAGS, isLegacyRuntimeImage, validateRuntimeImage, parseRuntimePackageJsonFile, buildRuntime, buildReactorRuntime, getMaxRuntimeTimeout, validateRuntimeTimeout, promptRuntimeOptions, promptRuntimeImage, type RuntimeFlagProps, type RuntimeFlags, type ConfigurableRuntimeOptions, };
48
+ export { LEGACY_RUNTIME_IMAGE, CONFIGURABLE_RUNTIME_IMAGES, CONFIGURABLE_RUNTIME_IMAGES_LABEL, VALID_RUNTIME_IMAGES, VALID_RUNTIME_IMAGES_LABEL, CONFIGURABLE_RUNTIME_FLAGS, REACTOR_CONFIGURABLE_RUNTIME_FLAGS, isLegacyRuntimeImage, validateRuntimeImage, parseRuntimePackageJsonFile, buildRuntime, buildReactorRuntime, getMaxRuntimeTimeout, validateRuntimeTimeout, promptRuntimeOptions, promptRuntimeImage, type RuntimeFlagProps, type RuntimeFlags, type ConfigurableRuntimeOptions, };
@@ -1,17 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promptRuntimeImage = exports.promptRuntimeOptions = exports.validateRuntimeTimeout = exports.getMaxRuntimeTimeout = exports.buildReactorRuntime = exports.buildRuntime = exports.parseRuntimePackageJsonFile = exports.validateRuntimeImage = exports.isLegacyRuntimeImage = exports.REACTOR_CONFIGURABLE_RUNTIME_FLAGS = exports.CONFIGURABLE_RUNTIME_FLAGS = exports.VALID_RUNTIME_IMAGES = exports.CONFIGURABLE_RUNTIME_IMAGES = exports.LEGACY_RUNTIME_IMAGE = void 0;
3
+ exports.promptRuntimeImage = exports.promptRuntimeOptions = exports.validateRuntimeTimeout = exports.getMaxRuntimeTimeout = exports.buildReactorRuntime = exports.buildRuntime = exports.parseRuntimePackageJsonFile = exports.validateRuntimeImage = exports.isLegacyRuntimeImage = exports.REACTOR_CONFIGURABLE_RUNTIME_FLAGS = exports.CONFIGURABLE_RUNTIME_FLAGS = exports.VALID_RUNTIME_IMAGES_LABEL = exports.VALID_RUNTIME_IMAGES = exports.CONFIGURABLE_RUNTIME_IMAGES_LABEL = exports.CONFIGURABLE_RUNTIME_IMAGES = exports.LEGACY_RUNTIME_IMAGE = void 0;
4
4
  const files_1 = require("../files");
5
5
  const utils_1 = require("../utils");
6
6
  const LEGACY_RUNTIME_IMAGE = 'node-bt';
7
7
  exports.LEGACY_RUNTIME_IMAGE = LEGACY_RUNTIME_IMAGE;
8
- const CONFIGURABLE_RUNTIME_IMAGES = ['node22'];
8
+ const CONFIGURABLE_RUNTIME_IMAGES = ['node22', 'node24'];
9
9
  exports.CONFIGURABLE_RUNTIME_IMAGES = CONFIGURABLE_RUNTIME_IMAGES;
10
+ const CONFIGURABLE_RUNTIME_IMAGES_LABEL = CONFIGURABLE_RUNTIME_IMAGES.join(' | ');
11
+ exports.CONFIGURABLE_RUNTIME_IMAGES_LABEL = CONFIGURABLE_RUNTIME_IMAGES_LABEL;
10
12
  const VALID_RUNTIME_IMAGES = [
11
13
  LEGACY_RUNTIME_IMAGE,
12
14
  ...CONFIGURABLE_RUNTIME_IMAGES,
13
15
  ];
14
16
  exports.VALID_RUNTIME_IMAGES = VALID_RUNTIME_IMAGES;
17
+ const VALID_RUNTIME_IMAGES_LABEL = VALID_RUNTIME_IMAGES.join('|');
18
+ exports.VALID_RUNTIME_IMAGES_LABEL = VALID_RUNTIME_IMAGES_LABEL;
15
19
  const MIN_RUNTIME_TIMEOUT = 10;
16
20
  const MAX_SYNC_RUNTIME_TIMEOUT = 30;
17
21
  const MAX_ASYNC_RUNTIME_TIMEOUT = 900;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.0.0",
2
+ "version": "4.2.0",
3
3
  "commands": {
4
4
  "applications:create": {
5
5
  "id": "applications:create",
@@ -289,35 +289,36 @@
289
289
  "request-transform-image": {
290
290
  "name": "request-transform-image",
291
291
  "type": "option",
292
- "description": "request-transform runtime image (node-bt|node22)",
292
+ "description": "request-transform runtime image (node-bt|node22|node24)",
293
293
  "multiple": false,
294
294
  "options": [
295
295
  "node-bt",
296
- "node22"
296
+ "node22",
297
+ "node24"
297
298
  ]
298
299
  },
299
300
  "request-transform-package-json": {
300
301
  "name": "request-transform-package-json",
301
302
  "type": "option",
302
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
303
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
303
304
  "multiple": false
304
305
  },
305
306
  "request-transform-timeout": {
306
307
  "name": "request-transform-timeout",
307
308
  "type": "option",
308
- "description": "request-transform timeout in seconds, 10-30 (node22 only)",
309
+ "description": "request-transform timeout in seconds, 10-30 (node22 | node24 only)",
309
310
  "multiple": false
310
311
  },
311
312
  "request-transform-warm-concurrency": {
312
313
  "name": "request-transform-warm-concurrency",
313
314
  "type": "option",
314
- "description": "request-transform warm concurrency, 0-1 (node22 only)",
315
+ "description": "request-transform warm concurrency, 0-1 (node22 | node24 only)",
315
316
  "multiple": false
316
317
  },
317
318
  "request-transform-resources": {
318
319
  "name": "request-transform-resources",
319
320
  "type": "option",
320
- "description": "request-transform resource tier (node22 only)",
321
+ "description": "request-transform resource tier (node22 | node24 only)",
321
322
  "multiple": false,
322
323
  "options": [
323
324
  "standard",
@@ -328,41 +329,42 @@
328
329
  "request-transform-permissions": {
329
330
  "name": "request-transform-permissions",
330
331
  "type": "option",
331
- "description": "request-transform permission to grant, repeatable (node22 only)",
332
+ "description": "request-transform permission to grant, repeatable (node22 | node24 only)",
332
333
  "multiple": true
333
334
  },
334
335
  "response-transform-image": {
335
336
  "name": "response-transform-image",
336
337
  "type": "option",
337
- "description": "response-transform runtime image (node-bt|node22)",
338
+ "description": "response-transform runtime image (node-bt|node22|node24)",
338
339
  "multiple": false,
339
340
  "options": [
340
341
  "node-bt",
341
- "node22"
342
+ "node22",
343
+ "node24"
342
344
  ]
343
345
  },
344
346
  "response-transform-package-json": {
345
347
  "name": "response-transform-package-json",
346
348
  "type": "option",
347
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
349
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
348
350
  "multiple": false
349
351
  },
350
352
  "response-transform-timeout": {
351
353
  "name": "response-transform-timeout",
352
354
  "type": "option",
353
- "description": "response-transform timeout in seconds, 10-30 (node22 only)",
355
+ "description": "response-transform timeout in seconds, 10-30 (node22 | node24 only)",
354
356
  "multiple": false
355
357
  },
356
358
  "response-transform-warm-concurrency": {
357
359
  "name": "response-transform-warm-concurrency",
358
360
  "type": "option",
359
- "description": "response-transform warm concurrency, 0-1 (node22 only)",
361
+ "description": "response-transform warm concurrency, 0-1 (node22 | node24 only)",
360
362
  "multiple": false
361
363
  },
362
364
  "response-transform-resources": {
363
365
  "name": "response-transform-resources",
364
366
  "type": "option",
365
- "description": "response-transform resource tier (node22 only)",
367
+ "description": "response-transform resource tier (node22 | node24 only)",
366
368
  "multiple": false,
367
369
  "options": [
368
370
  "standard",
@@ -373,13 +375,13 @@
373
375
  "response-transform-permissions": {
374
376
  "name": "response-transform-permissions",
375
377
  "type": "option",
376
- "description": "response-transform permission to grant, repeatable (node22 only)",
378
+ "description": "response-transform permission to grant, repeatable (node22 | node24 only)",
377
379
  "multiple": true
378
380
  },
379
381
  "no-wait": {
380
382
  "name": "no-wait",
381
383
  "type": "boolean",
382
- "description": "do not wait for proxy to be ready (requires at least one transform with node22)",
384
+ "description": "do not wait for proxy to be ready (requires at least one transform with node22 | node24)",
383
385
  "allowNo": false
384
386
  }
385
387
  },
@@ -605,35 +607,36 @@
605
607
  "request-transform-image": {
606
608
  "name": "request-transform-image",
607
609
  "type": "option",
608
- "description": "request-transform runtime image (node-bt|node22)",
610
+ "description": "request-transform runtime image (node-bt|node22|node24)",
609
611
  "multiple": false,
610
612
  "options": [
611
613
  "node-bt",
612
- "node22"
614
+ "node22",
615
+ "node24"
613
616
  ]
614
617
  },
615
618
  "request-transform-package-json": {
616
619
  "name": "request-transform-package-json",
617
620
  "type": "option",
618
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
621
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
619
622
  "multiple": false
620
623
  },
621
624
  "request-transform-timeout": {
622
625
  "name": "request-transform-timeout",
623
626
  "type": "option",
624
- "description": "request-transform timeout in seconds, 10-30 (node22 only)",
627
+ "description": "request-transform timeout in seconds, 10-30 (node22 | node24 only)",
625
628
  "multiple": false
626
629
  },
627
630
  "request-transform-warm-concurrency": {
628
631
  "name": "request-transform-warm-concurrency",
629
632
  "type": "option",
630
- "description": "request-transform warm concurrency, 0-1 (node22 only)",
633
+ "description": "request-transform warm concurrency, 0-1 (node22 | node24 only)",
631
634
  "multiple": false
632
635
  },
633
636
  "request-transform-resources": {
634
637
  "name": "request-transform-resources",
635
638
  "type": "option",
636
- "description": "request-transform resource tier (node22 only)",
639
+ "description": "request-transform resource tier (node22 | node24 only)",
637
640
  "multiple": false,
638
641
  "options": [
639
642
  "standard",
@@ -644,41 +647,42 @@
644
647
  "request-transform-permissions": {
645
648
  "name": "request-transform-permissions",
646
649
  "type": "option",
647
- "description": "request-transform permission to grant, repeatable (node22 only)",
650
+ "description": "request-transform permission to grant, repeatable (node22 | node24 only)",
648
651
  "multiple": true
649
652
  },
650
653
  "response-transform-image": {
651
654
  "name": "response-transform-image",
652
655
  "type": "option",
653
- "description": "response-transform runtime image (node-bt|node22)",
656
+ "description": "response-transform runtime image (node-bt|node22|node24)",
654
657
  "multiple": false,
655
658
  "options": [
656
659
  "node-bt",
657
- "node22"
660
+ "node22",
661
+ "node24"
658
662
  ]
659
663
  },
660
664
  "response-transform-package-json": {
661
665
  "name": "response-transform-package-json",
662
666
  "type": "option",
663
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
667
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
664
668
  "multiple": false
665
669
  },
666
670
  "response-transform-timeout": {
667
671
  "name": "response-transform-timeout",
668
672
  "type": "option",
669
- "description": "response-transform timeout in seconds, 10-30 (node22 only)",
673
+ "description": "response-transform timeout in seconds, 10-30 (node22 | node24 only)",
670
674
  "multiple": false
671
675
  },
672
676
  "response-transform-warm-concurrency": {
673
677
  "name": "response-transform-warm-concurrency",
674
678
  "type": "option",
675
- "description": "response-transform warm concurrency, 0-1 (node22 only)",
679
+ "description": "response-transform warm concurrency, 0-1 (node22 | node24 only)",
676
680
  "multiple": false
677
681
  },
678
682
  "response-transform-resources": {
679
683
  "name": "response-transform-resources",
680
684
  "type": "option",
681
- "description": "response-transform resource tier (node22 only)",
685
+ "description": "response-transform resource tier (node22 | node24 only)",
682
686
  "multiple": false,
683
687
  "options": [
684
688
  "standard",
@@ -689,13 +693,13 @@
689
693
  "response-transform-permissions": {
690
694
  "name": "response-transform-permissions",
691
695
  "type": "option",
692
- "description": "response-transform permission to grant, repeatable (node22 only)",
696
+ "description": "response-transform permission to grant, repeatable (node22 | node24 only)",
693
697
  "multiple": true
694
698
  },
695
699
  "no-wait": {
696
700
  "name": "no-wait",
697
701
  "type": "boolean",
698
- "description": "do not wait for proxy to be ready (requires at least one transform with node22)",
702
+ "description": "do not wait for proxy to be ready (requires at least one transform with node22 | node24)",
699
703
  "allowNo": false
700
704
  },
701
705
  "watch": {
@@ -792,35 +796,36 @@
792
796
  "image": {
793
797
  "name": "image",
794
798
  "type": "option",
795
- "description": "runtime image (node-bt|node22)",
799
+ "description": "runtime image (node-bt|node22|node24)",
796
800
  "multiple": false,
797
801
  "options": [
798
802
  "node-bt",
799
- "node22"
803
+ "node22",
804
+ "node24"
800
805
  ]
801
806
  },
802
807
  "package-json": {
803
808
  "name": "package-json",
804
809
  "type": "option",
805
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
810
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
806
811
  "multiple": false
807
812
  },
808
813
  "timeout": {
809
814
  "name": "timeout",
810
815
  "type": "option",
811
- "description": "timeout in seconds, 10-900 (node22 only; maximum 30 when runtime async is disabled; default: 10)",
816
+ "description": "timeout in seconds, 10-900 (node22 | node24 only; maximum 30 when runtime async is disabled; default: 10)",
812
817
  "multiple": false
813
818
  },
814
819
  "warm-concurrency": {
815
820
  "name": "warm-concurrency",
816
821
  "type": "option",
817
- "description": "number of warm instances, 0-1 (node22 only, default: 0)",
822
+ "description": "number of warm instances, 0-1 (node22 | node24 only, default: 0)",
818
823
  "multiple": false
819
824
  },
820
825
  "resources": {
821
826
  "name": "resources",
822
827
  "type": "option",
823
- "description": "resource tier (node22 only, default: standard)",
828
+ "description": "resource tier (node22 | node24 only, default: standard)",
824
829
  "multiple": false,
825
830
  "options": [
826
831
  "standard",
@@ -831,7 +836,7 @@
831
836
  "permissions": {
832
837
  "name": "permissions",
833
838
  "type": "option",
834
- "description": "permission to grant, repeatable (node22 only)",
839
+ "description": "permission to grant, repeatable (node22 | node24 only)",
835
840
  "multiple": true
836
841
  },
837
842
  "no-wait": {
@@ -843,7 +848,7 @@
843
848
  "async": {
844
849
  "name": "async",
845
850
  "type": "boolean",
846
- "description": "execute Reactor invocations asynchronously (node22 only)",
851
+ "description": "execute Reactor invocations asynchronously (node22 | node24 only)",
847
852
  "allowNo": true
848
853
  }
849
854
  },
@@ -992,6 +997,10 @@
992
997
  "description": "Update a reactor with node22 runtime",
993
998
  "command": "<%= config.bin %> <%= command.id %> <reactor-id> --code ./reactor.js --image node22"
994
999
  },
1000
+ {
1001
+ "description": "Watch a node22 reactor for code, configuration, and dependency changes",
1002
+ "command": "<%= config.bin %> <%= command.id %> <reactor-id> --code ./reactor.js --configuration ./config.env --package-json ./package.json --image node22 --watch"
1003
+ },
995
1004
  {
996
1005
  "description": "Update a reactor with node22 and all runtime options",
997
1006
  "command": "<%= config.bin %> <%= command.id %> <reactor-id> --name \"My Reactor\" --code ./reactor.js --configuration ./config.env --image node22 --async --timeout 10 --warm-concurrency 0 --resources standard --package-json ./package.json --permissions token:read --permissions token:create"
@@ -1044,35 +1053,36 @@
1044
1053
  "image": {
1045
1054
  "name": "image",
1046
1055
  "type": "option",
1047
- "description": "runtime image (node-bt|node22)",
1056
+ "description": "runtime image (node-bt|node22|node24)",
1048
1057
  "multiple": false,
1049
1058
  "options": [
1050
1059
  "node-bt",
1051
- "node22"
1060
+ "node22",
1061
+ "node24"
1052
1062
  ]
1053
1063
  },
1054
1064
  "package-json": {
1055
1065
  "name": "package-json",
1056
1066
  "type": "option",
1057
- "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 only)",
1067
+ "description": "path to runtime package.json JSON file (top-level dependencies required; supports resolutions or overrides fallback; pinned versions required) (node22 | node24 only)",
1058
1068
  "multiple": false
1059
1069
  },
1060
1070
  "timeout": {
1061
1071
  "name": "timeout",
1062
1072
  "type": "option",
1063
- "description": "timeout in seconds, 10-900 (node22 only; maximum 30 when runtime async is disabled; default: 10)",
1073
+ "description": "timeout in seconds, 10-900 (node22 | node24 only; maximum 30 when runtime async is disabled; default: 10)",
1064
1074
  "multiple": false
1065
1075
  },
1066
1076
  "warm-concurrency": {
1067
1077
  "name": "warm-concurrency",
1068
1078
  "type": "option",
1069
- "description": "number of warm instances, 0-1 (node22 only, default: 0)",
1079
+ "description": "number of warm instances, 0-1 (node22 | node24 only, default: 0)",
1070
1080
  "multiple": false
1071
1081
  },
1072
1082
  "resources": {
1073
1083
  "name": "resources",
1074
1084
  "type": "option",
1075
- "description": "resource tier (node22 only, default: standard)",
1085
+ "description": "resource tier (node22 | node24 only, default: standard)",
1076
1086
  "multiple": false,
1077
1087
  "options": [
1078
1088
  "standard",
@@ -1083,7 +1093,7 @@
1083
1093
  "permissions": {
1084
1094
  "name": "permissions",
1085
1095
  "type": "option",
1086
- "description": "permission to grant, repeatable (node22 only)",
1096
+ "description": "permission to grant, repeatable (node22 | node24 only)",
1087
1097
  "multiple": true
1088
1098
  },
1089
1099
  "no-wait": {
@@ -1095,14 +1105,14 @@
1095
1105
  "async": {
1096
1106
  "name": "async",
1097
1107
  "type": "boolean",
1098
- "description": "execute Reactor invocations asynchronously (node22 only)",
1108
+ "description": "execute Reactor invocations asynchronously (node22 | node24 only)",
1099
1109
  "allowNo": true
1100
1110
  },
1101
1111
  "watch": {
1102
1112
  "name": "watch",
1103
1113
  "type": "boolean",
1104
1114
  "char": "w",
1105
- "description": "Watch for changes in informed files",
1115
+ "description": "Watch for changes in supplied code, configuration, and runtime package files",
1106
1116
  "required": false,
1107
1117
  "allowNo": false
1108
1118
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basis-theory-labs/cli",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "Basis Theory CLI tool",
5
5
  "author": "Davi Aquino @djejaquino",
6
6
  "bin": {