@basis-theory-labs/cli 1.13.0 → 2.1.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.
Files changed (55) hide show
  1. package/README.md +166 -87
  2. package/dist/applications/management.d.ts +8 -10
  3. package/dist/applications/management.js +14 -10
  4. package/dist/base.d.ts +2 -2
  5. package/dist/base.js +27 -14
  6. package/dist/commands/applications/create.js +6 -3
  7. package/dist/commands/applications/index.js +3 -1
  8. package/dist/commands/proxies/create.d.ts +17 -1
  9. package/dist/commands/proxies/create.js +84 -8
  10. package/dist/commands/proxies/index.js +3 -2
  11. package/dist/commands/proxies/logs.js +2 -1
  12. package/dist/commands/proxies/update.d.ts +17 -1
  13. package/dist/commands/proxies/update.js +66 -6
  14. package/dist/commands/reactors/create.d.ts +11 -1
  15. package/dist/commands/reactors/create.js +70 -8
  16. package/dist/commands/reactors/index.js +3 -2
  17. package/dist/commands/reactors/logs.js +2 -1
  18. package/dist/commands/reactors/update.d.ts +11 -1
  19. package/dist/commands/reactors/update.js +45 -5
  20. package/dist/logs/connect.d.ts +5 -5
  21. package/dist/logs/connect.js +1 -2
  22. package/dist/logs/index.d.ts +3 -3
  23. package/dist/logs/server.js +1 -2
  24. package/dist/proxies/management.d.ts +7 -7
  25. package/dist/proxies/management.js +16 -9
  26. package/dist/proxies/runtime.d.ts +5 -0
  27. package/dist/proxies/runtime.js +66 -0
  28. package/dist/proxies/utils.d.ts +26 -5
  29. package/dist/proxies/utils.js +78 -7
  30. package/dist/reactors/management.d.ts +7 -7
  31. package/dist/reactors/management.js +16 -9
  32. package/dist/reactors/runtime.d.ts +3 -0
  33. package/dist/reactors/runtime.js +27 -0
  34. package/dist/reactors/utils.d.ts +16 -5
  35. package/dist/reactors/utils.js +4 -1
  36. package/dist/runtime/flags.d.ts +10 -0
  37. package/dist/runtime/flags.js +37 -0
  38. package/dist/runtime/index.d.ts +3 -0
  39. package/dist/runtime/index.js +20 -0
  40. package/dist/runtime/state.d.ts +6 -0
  41. package/dist/runtime/state.js +86 -0
  42. package/dist/runtime/utils.d.ts +34 -0
  43. package/dist/runtime/utils.js +132 -0
  44. package/dist/utils.d.ts +12 -2
  45. package/dist/utils.js +44 -4
  46. package/oclif.manifest.json +333 -122
  47. package/package.json +4 -3
  48. package/dist/commands/reactorFormulas/index.d.ts +0 -10
  49. package/dist/commands/reactorFormulas/index.js +0 -27
  50. package/dist/commands/reactorFormulas/update.d.ts +0 -18
  51. package/dist/commands/reactorFormulas/update.js +0 -71
  52. package/dist/reactorFormulas/management.d.ts +0 -5
  53. package/dist/reactorFormulas/management.js +0 -54
  54. package/dist/reactorFormulas/utils.d.ts +0 -26
  55. package/dist/reactorFormulas/utils.js +0 -49
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POLL_TIMEOUT = exports.POLL_INTERVAL = exports.needsPolling = exports.waitForResourceState = void 0;
4
+ const core_1 = require("@oclif/core");
5
+ const POLL_INTERVAL = 2000; // 2 seconds
6
+ exports.POLL_INTERVAL = POLL_INTERVAL;
7
+ const POLL_TIMEOUT = 600000; // 10 minutes
8
+ exports.POLL_TIMEOUT = POLL_TIMEOUT;
9
+ const formatErrorMessage = (resource, resourceType) => {
10
+ const { state, requested } = resource;
11
+ const resourceName = resourceType === 'reactor' ? 'Reactor' : 'Proxy';
12
+ const parts = [`${resourceName} reached ${state} state`];
13
+ if (requested === null || requested === void 0 ? void 0 : requested.errorCode) {
14
+ parts.push(`errorCode: ${requested.errorCode}`);
15
+ }
16
+ if (requested === null || requested === void 0 ? void 0 : requested.errorMessage) {
17
+ parts.push(`errorMessage: ${requested.errorMessage}`);
18
+ }
19
+ if (requested === null || requested === void 0 ? void 0 : requested.errorDetails) {
20
+ parts.push(`errorDetails: ${JSON.stringify(requested.errorDetails)}`);
21
+ }
22
+ return parts.join('\n');
23
+ };
24
+ const needsPolling = (state) => state === 'creating' || state === 'updating';
25
+ exports.needsPolling = needsPolling;
26
+ const formatElapsedTime = (startTime) => {
27
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
28
+ const minutes = Math.floor(elapsed / 60);
29
+ const seconds = elapsed % 60;
30
+ if (minutes > 0) {
31
+ return `${minutes}m ${seconds}s`;
32
+ }
33
+ return `${seconds}s`;
34
+ };
35
+ const createTimer = (startTime, getState) => setInterval(() => {
36
+ const state = getState();
37
+ if (state) {
38
+ core_1.ux.action.status = `${state} (${formatElapsedTime(startTime)})`;
39
+ }
40
+ }, 1000);
41
+ const waitForResourceState = async (bt, resourceType, id, initialState) => {
42
+ // If initial state is provided and doesn't need polling, return immediately
43
+ if (initialState !== undefined && !needsPolling(initialState)) {
44
+ return;
45
+ }
46
+ const deadline = Date.now() + POLL_TIMEOUT;
47
+ const startTime = Date.now();
48
+ let currentState;
49
+ const timer = createTimer(startTime, () => currentState);
50
+ core_1.ux.action.start('Status');
51
+ /* eslint-disable no-await-in-loop */
52
+ try {
53
+ while (Date.now() < deadline) {
54
+ let resource;
55
+ try {
56
+ resource = await (resourceType === 'reactor'
57
+ ? bt.reactors.get(id)
58
+ : bt.proxies.get(id));
59
+ }
60
+ catch (error) {
61
+ core_1.ux.action.stop(`error (${formatElapsedTime(startTime)})`);
62
+ throw new Error(`Failed to check ${resourceType} state: ${error.message}`);
63
+ }
64
+ currentState = resource.state;
65
+ core_1.ux.action.status = `${currentState} (${formatElapsedTime(startTime)})`;
66
+ if (currentState === 'active') {
67
+ core_1.ux.action.stop(`ready (${formatElapsedTime(startTime)})`);
68
+ return;
69
+ }
70
+ if (currentState === 'failed' || currentState === 'outdated') {
71
+ core_1.ux.action.stop(`failed (${formatElapsedTime(startTime)})`);
72
+ throw new Error(formatErrorMessage(resource, resourceType));
73
+ }
74
+ await new Promise((resolve) => {
75
+ setTimeout(resolve, POLL_INTERVAL);
76
+ });
77
+ }
78
+ core_1.ux.action.stop(`timeout (${formatElapsedTime(startTime)})`);
79
+ throw new Error(`Timeout waiting for ${resourceType} to reach final state`);
80
+ }
81
+ finally {
82
+ clearInterval(timer);
83
+ }
84
+ /* eslint-enable no-await-in-loop */
85
+ };
86
+ exports.waitForResourceState = waitForResourceState;
@@ -0,0 +1,34 @@
1
+ import type { BasisTheory } from '@basis-theory/node-sdk';
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"];
5
+ declare const isLegacyRuntimeImage: (image: string | undefined) => boolean;
6
+ declare const validateRuntimeImage: (image: string | undefined) => void;
7
+ declare const CONFIGURABLE_RUNTIME_FLAGS: readonly ["timeout", "resources", "warm-concurrency", "permissions", "dependencies"];
8
+ interface RuntimeFlagProps {
9
+ image?: string;
10
+ dependencies?: string;
11
+ timeout?: number;
12
+ warmConcurrency?: number;
13
+ resources?: string;
14
+ permissions?: string[];
15
+ }
16
+ interface RuntimeFlags {
17
+ image?: string;
18
+ timeout?: number;
19
+ 'warm-concurrency'?: number;
20
+ resources?: string;
21
+ dependencies?: string;
22
+ permissions?: string[];
23
+ }
24
+ interface ConfigurableRuntimeOptions {
25
+ timeout?: number;
26
+ warmConcurrency?: number;
27
+ resources?: string;
28
+ dependencies?: string;
29
+ permissions?: string[];
30
+ }
31
+ declare const buildRuntime: (props: RuntimeFlagProps) => BasisTheory.Runtime | undefined;
32
+ declare const promptRuntimeOptions: (flags: RuntimeFlags, labelPrefix?: string) => Promise<ConfigurableRuntimeOptions>;
33
+ declare const promptRuntimeImage: (image: string | undefined, message?: string) => Promise<string>;
34
+ export { LEGACY_RUNTIME_IMAGE, CONFIGURABLE_RUNTIME_IMAGES, VALID_RUNTIME_IMAGES, CONFIGURABLE_RUNTIME_FLAGS, isLegacyRuntimeImage, validateRuntimeImage, buildRuntime, promptRuntimeOptions, promptRuntimeImage, type RuntimeFlagProps, type RuntimeFlags, type ConfigurableRuntimeOptions, };
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promptRuntimeImage = exports.promptRuntimeOptions = exports.buildRuntime = exports.validateRuntimeImage = exports.isLegacyRuntimeImage = exports.CONFIGURABLE_RUNTIME_FLAGS = exports.VALID_RUNTIME_IMAGES = exports.CONFIGURABLE_RUNTIME_IMAGES = exports.LEGACY_RUNTIME_IMAGE = void 0;
4
+ const files_1 = require("../files");
5
+ const utils_1 = require("../utils");
6
+ const LEGACY_RUNTIME_IMAGE = 'node-bt';
7
+ exports.LEGACY_RUNTIME_IMAGE = LEGACY_RUNTIME_IMAGE;
8
+ const CONFIGURABLE_RUNTIME_IMAGES = ['node22'];
9
+ exports.CONFIGURABLE_RUNTIME_IMAGES = CONFIGURABLE_RUNTIME_IMAGES;
10
+ const VALID_RUNTIME_IMAGES = [
11
+ LEGACY_RUNTIME_IMAGE,
12
+ ...CONFIGURABLE_RUNTIME_IMAGES,
13
+ ];
14
+ exports.VALID_RUNTIME_IMAGES = VALID_RUNTIME_IMAGES;
15
+ const isLegacyRuntimeImage = (image) => image === undefined || image === LEGACY_RUNTIME_IMAGE;
16
+ exports.isLegacyRuntimeImage = isLegacyRuntimeImage;
17
+ const validateRuntimeImage = (image) => {
18
+ if (image === undefined) {
19
+ return;
20
+ }
21
+ if (!VALID_RUNTIME_IMAGES.includes(image)) {
22
+ throw new Error(`Invalid runtime image "${image}". Valid options: ${VALID_RUNTIME_IMAGES.join(', ')}`);
23
+ }
24
+ };
25
+ exports.validateRuntimeImage = validateRuntimeImage;
26
+ const CONFIGURABLE_RUNTIME_FLAGS = [
27
+ 'timeout',
28
+ 'resources',
29
+ 'warm-concurrency',
30
+ 'permissions',
31
+ 'dependencies',
32
+ ];
33
+ exports.CONFIGURABLE_RUNTIME_FLAGS = CONFIGURABLE_RUNTIME_FLAGS;
34
+ const buildRuntime = (props) => {
35
+ const { image, dependencies, timeout, warmConcurrency, resources, permissions, } = props;
36
+ if (!image &&
37
+ !dependencies &&
38
+ !timeout &&
39
+ !warmConcurrency &&
40
+ !resources &&
41
+ !(permissions === null || permissions === void 0 ? void 0 : permissions.length)) {
42
+ return undefined;
43
+ }
44
+ let parsedDependencies;
45
+ if (dependencies) {
46
+ try {
47
+ parsedDependencies = JSON.parse((0, files_1.readFileContents)(dependencies));
48
+ }
49
+ catch (error) {
50
+ throw new Error(`Failed to parse dependencies file "${dependencies}": ${error.message}`);
51
+ }
52
+ }
53
+ const runtime = {};
54
+ if (image) {
55
+ runtime.image = image;
56
+ }
57
+ if (parsedDependencies) {
58
+ runtime.dependencies = parsedDependencies;
59
+ }
60
+ if (timeout !== undefined) {
61
+ runtime.timeout = timeout;
62
+ }
63
+ if (warmConcurrency !== undefined) {
64
+ runtime.warmConcurrency = warmConcurrency;
65
+ }
66
+ if (resources) {
67
+ runtime.resources = resources;
68
+ }
69
+ if (permissions === null || permissions === void 0 ? void 0 : permissions.length) {
70
+ runtime.permissions = permissions;
71
+ }
72
+ return runtime;
73
+ };
74
+ exports.buildRuntime = buildRuntime;
75
+ const promptRuntimeOptions = async (flags, labelPrefix) => {
76
+ const prefix = labelPrefix ? `${labelPrefix}: ` : '';
77
+ const timeout = await (0, utils_1.promptIntegerIfUndefined)(flags.timeout, {
78
+ message: `${prefix}Timeout in seconds (1-30, press Enter for default: 10):`,
79
+ min: 1,
80
+ max: 30,
81
+ });
82
+ const warmConcurrency = await (0, utils_1.promptIntegerIfUndefined)(flags['warm-concurrency'], {
83
+ message: `${prefix}Warm concurrency (0-1, press Enter for default: 0):`,
84
+ min: 0,
85
+ max: 1,
86
+ });
87
+ const resources = await (0, utils_1.promptSelectIfUndefined)(flags.resources, {
88
+ message: `${prefix}Resource tier:`,
89
+ choices: [
90
+ {
91
+ value: 'standard',
92
+ name: 'standard (default)',
93
+ },
94
+ {
95
+ value: 'large',
96
+ name: 'large',
97
+ },
98
+ {
99
+ value: 'xlarge',
100
+ name: 'xlarge',
101
+ },
102
+ ],
103
+ });
104
+ const dependencies = await (0, utils_1.promptStringIfUndefined)(flags.dependencies, {
105
+ message: `${prefix}(Optional) Dependencies file path (JSON format):`,
106
+ });
107
+ const permissions = await (0, utils_1.promptCommaSeparatedIfUndefined)(flags.permissions, {
108
+ message: `${prefix}(Optional) Permissions (comma-separated, e.g. token:read, token:create):`,
109
+ });
110
+ return {
111
+ timeout,
112
+ warmConcurrency,
113
+ resources,
114
+ dependencies: dependencies || undefined,
115
+ permissions,
116
+ };
117
+ };
118
+ exports.promptRuntimeOptions = promptRuntimeOptions;
119
+ const promptRuntimeImage = (image, message = 'Which runtime do you want to use?') => (0, utils_1.promptSelectIfUndefined)(image, {
120
+ message,
121
+ choices: [
122
+ {
123
+ value: LEGACY_RUNTIME_IMAGE,
124
+ name: `${LEGACY_RUNTIME_IMAGE} (legacy)`,
125
+ },
126
+ ...CONFIGURABLE_RUNTIME_IMAGES.map((runtime) => ({
127
+ value: runtime,
128
+ name: `${runtime} (configurable)`,
129
+ })),
130
+ ],
131
+ });
132
+ exports.promptRuntimeImage = promptRuntimeImage;
package/dist/utils.d.ts CHANGED
@@ -1,15 +1,25 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { PaginatedList } from '@basis-theory/basis-theory-js/types/sdk';
4
3
  import checkbox from '@inquirer/checkbox';
5
4
  import confirm from '@inquirer/confirm';
6
5
  import input from '@inquirer/input';
7
6
  import select from '@inquirer/select';
7
+ interface PaginatedList<T> {
8
+ data: T[];
9
+ page: number;
10
+ hasNextPage: boolean;
11
+ }
8
12
  declare const selectOrNavigate: <T>(list: PaginatedList<T>, prop: string) => Promise<T | "previous" | "next">;
9
13
  declare const promptStringIfUndefined: (value: string | undefined, options: Parameters<typeof input>[0]) => Promise<string>;
10
14
  declare const promptSelectIfUndefined: (value: string | undefined, options: Parameters<typeof select>[0]) => Promise<string>;
11
15
  declare const promptCheckboxIfUndefined: (value: string[] | undefined, options: Parameters<typeof checkbox>[0]) => Promise<string[]>;
12
16
  declare const promptUrlIfUndefined: (value: URL | undefined, options: Parameters<typeof input>[0]) => Promise<URL>;
13
17
  declare const promptBooleanIfUndefined: (value: boolean | undefined, options: Parameters<typeof confirm>[0]) => Promise<boolean>;
18
+ declare const promptIntegerIfUndefined: (value: number | undefined, options: {
19
+ message: string;
20
+ min?: number;
21
+ max?: number;
22
+ }) => Promise<number | undefined>;
23
+ declare const promptCommaSeparatedIfUndefined: (value: string[] | undefined, options: Parameters<typeof input>[0]) => Promise<string[] | undefined>;
14
24
  declare const cleanUpOnExit: (action: () => unknown) => typeof process;
15
- export { selectOrNavigate, promptStringIfUndefined, promptSelectIfUndefined, promptCheckboxIfUndefined, promptUrlIfUndefined, promptBooleanIfUndefined, cleanUpOnExit, };
25
+ export { selectOrNavigate, promptStringIfUndefined, promptSelectIfUndefined, promptCheckboxIfUndefined, promptUrlIfUndefined, promptBooleanIfUndefined, promptIntegerIfUndefined, promptCommaSeparatedIfUndefined, cleanUpOnExit, PaginatedList, };
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cleanUpOnExit = exports.promptBooleanIfUndefined = exports.promptUrlIfUndefined = exports.promptCheckboxIfUndefined = exports.promptSelectIfUndefined = exports.promptStringIfUndefined = exports.selectOrNavigate = void 0;
3
+ exports.cleanUpOnExit = exports.promptCommaSeparatedIfUndefined = exports.promptIntegerIfUndefined = exports.promptBooleanIfUndefined = exports.promptUrlIfUndefined = exports.promptCheckboxIfUndefined = exports.promptSelectIfUndefined = exports.promptStringIfUndefined = exports.selectOrNavigate = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const checkbox_1 = tslib_1.__importDefault(require("@inquirer/checkbox"));
6
6
  const confirm_1 = tslib_1.__importDefault(require("@inquirer/confirm"));
@@ -8,10 +8,10 @@ const input_1 = tslib_1.__importDefault(require("@inquirer/input"));
8
8
  const select_1 = tslib_1.__importDefault(require("@inquirer/select"));
9
9
  const core_1 = require("@oclif/core");
10
10
  const selectOrNavigate = async (list, prop) => {
11
- const { data, pagination } = list;
11
+ const { data, page, hasNextPage } = list;
12
12
  let prompt = `Select one (${prop})`;
13
- const hasNext = pagination.totalPages > pagination.pageNumber;
14
- const hasPrevious = pagination.pageNumber > 1;
13
+ const hasNext = hasNextPage;
14
+ const hasPrevious = page > 1;
15
15
  if (hasPrevious) {
16
16
  prompt += " or 'p' for previous page ";
17
17
  }
@@ -82,6 +82,46 @@ const promptBooleanIfUndefined = (value, options) => {
82
82
  return (0, confirm_1.default)(options);
83
83
  };
84
84
  exports.promptBooleanIfUndefined = promptBooleanIfUndefined;
85
+ const promptIntegerIfUndefined = async (value, options) => {
86
+ if (value !== undefined) {
87
+ return value;
88
+ }
89
+ const result = await (0, input_1.default)({
90
+ message: options.message,
91
+ validate: (val) => {
92
+ if (!val.trim()) {
93
+ return true;
94
+ } // Allow empty for optional
95
+ const num = Number(val);
96
+ if (Number.isNaN(num) || !Number.isInteger(num)) {
97
+ return 'Please enter a valid integer';
98
+ }
99
+ if (options.min !== undefined && num < options.min) {
100
+ return `Value must be at least ${options.min}`;
101
+ }
102
+ if (options.max !== undefined && num > options.max) {
103
+ return `Value must be at most ${options.max}`;
104
+ }
105
+ return true;
106
+ },
107
+ });
108
+ return result.trim() ? Number(result) : undefined;
109
+ };
110
+ exports.promptIntegerIfUndefined = promptIntegerIfUndefined;
111
+ const promptCommaSeparatedIfUndefined = async (value, options) => {
112
+ if (value && value.length > 0) {
113
+ return value;
114
+ }
115
+ const result = await (0, input_1.default)(options);
116
+ if (!result.trim()) {
117
+ return undefined;
118
+ }
119
+ return result
120
+ .split(',')
121
+ .map((item) => item.trim())
122
+ .filter((item) => item.length > 0);
123
+ };
124
+ exports.promptCommaSeparatedIfUndefined = promptCommaSeparatedIfUndefined;
85
125
  const cleanUpOnExit = (action) => process.on('SIGINT', async () => {
86
126
  await action();
87
127
  process.exit(1);