bdy 1.24.8 → 1.25.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,83 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.fetchOpenApiSchema = fetchOpenApiSchema;
7
4
  const bundle_1 = require("@scalar/json-magic/bundle");
8
5
  const node_1 = require("@scalar/json-magic/bundle/plugins/node");
9
6
  const openapi_parser_1 = require("@scalar/openapi-parser");
10
- const node_crypto_1 = require("node:crypto");
11
7
  const node_fs_1 = require("node:fs");
12
- const node_path_1 = __importDefault(require("node:path"));
13
8
  const node_v8_1 = require("node:v8");
14
9
  const texts_1 = require("./texts");
15
10
  const utils_1 = require("./utils");
11
+ const diskCache_1 = require("./diskCache");
16
12
  const BUNDLE_PLUGINS = [(0, node_1.readFiles)(), (0, node_1.fetchUrls)(), (0, node_1.parseYaml)(), (0, node_1.parseJson)()];
17
- // Hard cache window: within this period the cached schema is served with no
18
- // network at all. After it expires the schema is revalidated (conditional GET),
19
- // and a successful revalidation (304/200) resets the window.
20
- const CACHE_TTL_MS = 60 * 60 * 1000;
21
- // One cache set per schema URL (region/stage differ), keyed by a URL hash.
22
- function cachePaths(url) {
23
- const dir = node_path_1.default.join((0, utils_1.getHomeDirectory)(), 'openapi');
24
- if (!(0, node_fs_1.existsSync)(dir))
25
- (0, node_fs_1.mkdirSync)(dir, { recursive: true });
26
- const key = (0, node_crypto_1.createHash)('sha256').update(url).digest('hex').slice(0, 16);
27
- return {
28
- raw: node_path_1.default.join(dir, `${key}.json`),
29
- schema: node_path_1.default.join(dir, `${key}.v8`),
30
- meta: node_path_1.default.join(dir, `${key}.meta.json`),
31
- };
32
- }
33
- function readMeta(metaPath) {
34
- try {
35
- return JSON.parse((0, node_fs_1.readFileSync)(metaPath, 'utf8'));
36
- }
37
- catch {
38
- return {};
39
- }
40
- }
41
- // Write via temp + rename so a Ctrl+C can't leave a truncated cache file.
42
- function writeAtomic(filePath, data) {
43
- const tmp = `${filePath}.${process.pid}.tmp`;
44
- (0, node_fs_1.writeFileSync)(tmp, data);
45
- (0, node_fs_1.renameSync)(tmp, filePath);
46
- }
47
- /**
48
- * Refresh the cached raw schema body via a single conditional GET.
49
- * 304 → keep cache ('unchanged'); 200 → rewrite raw + validators ('updated');
50
- * network error → reuse any cached body ('unchanged') or report 'none'.
51
- */
52
- async function refresh(url, paths) {
53
- const hasRaw = (0, node_fs_1.existsSync)(paths.raw);
54
- const meta = hasRaw ? readMeta(paths.meta) : {};
55
- // The server serves a strong content-based ETag (identical across instances),
56
- // so revalidate with If-None-Match.
57
- const headers = {};
58
- if (hasRaw && meta.etag)
59
- headers['If-None-Match'] = meta.etag;
60
- try {
61
- const res = await fetch(url, { headers });
62
- if (res.status === 304 && hasRaw) {
63
- // Reset the hard-cache window; keep the existing validator.
64
- writeAtomic(paths.meta, JSON.stringify({ etag: meta.etag, fetchedAt: Date.now() }));
65
- return 'unchanged';
66
- }
67
- if (res.ok) {
68
- writeAtomic(paths.raw, await res.text());
69
- writeAtomic(paths.meta, JSON.stringify({
70
- etag: res.headers.get('etag') ?? undefined,
71
- fetchedAt: Date.now(),
72
- }));
73
- return 'updated';
74
- }
75
- }
76
- catch {
77
- // network error — fall back to the cached body if present
78
- }
79
- return hasRaw ? 'unchanged' : 'none';
80
- }
81
13
  // Bundle + dereference a schema source (local path or remote URL).
82
14
  async function buildSchema(source) {
83
15
  const data = await (0, bundle_1.bundle)(source, {
@@ -88,8 +20,8 @@ async function buildSchema(source) {
88
20
  return schema ?? null;
89
21
  }
90
22
  // The dereferenced schema has circular refs, so it is cached with v8
91
- // serialization (JSON.stringify can't handle cycles). The blob is
92
- // Node-version specific, so a failed load just rebuilds from the raw body.
23
+ // serialization (JSON.stringify can't handle cycles). The blob is Node-version
24
+ // specific, so a failed load just rebuilds from the raw body.
93
25
  function loadCachedSchema(schemaPath) {
94
26
  try {
95
27
  return (0, node_v8_1.deserialize)((0, node_fs_1.readFileSync)(schemaPath));
@@ -100,7 +32,7 @@ function loadCachedSchema(schemaPath) {
100
32
  }
101
33
  function saveCachedSchema(schemaPath, schema) {
102
34
  try {
103
- writeAtomic(schemaPath, (0, node_v8_1.serialize)(schema));
35
+ (0, diskCache_1.writeAtomic)(schemaPath, (0, node_v8_1.serialize)(schema));
104
36
  }
105
37
  catch {
106
38
  // caching is best-effort
@@ -109,20 +41,18 @@ function saveCachedSchema(schemaPath, schema) {
109
41
  async function fetchOpenApiSchema(baseUrl) {
110
42
  try {
111
43
  const url = (0, utils_1.getOpenApiEndpointByApiBaseUrl)(baseUrl);
112
- const paths = cachePaths(url);
44
+ const paths = (0, diskCache_1.cachePaths)('openapi', url);
113
45
  // Hard cache: within the TTL, serve the cached schema with no network call.
114
- const meta = readMeta(paths.meta);
115
- if (meta.fetchedAt && Date.now() - meta.fetchedAt < CACHE_TTL_MS) {
46
+ if ((0, diskCache_1.isHardFresh)((0, diskCache_1.readMeta)(paths.meta))) {
116
47
  const cached = loadCachedSchema(paths.schema);
117
48
  if (cached)
118
49
  return cached;
119
50
  }
120
- const state = await refresh(url, paths);
51
+ const state = await (0, diskCache_1.refresh)(url, paths);
121
52
  let schema;
122
53
  if (state === 'unchanged') {
123
- // Fast path: reuse the cached dereferenced schema, skipping the
124
- // download, bundle() and dereference() entirely. Rebuild from the raw
125
- // body if the v8 blob is missing or unreadable (e.g. Node upgrade).
54
+ // Reuse the cached dereferenced schema, skipping download/bundle/dereference.
55
+ // Rebuild from the raw body if the v8 blob is missing or unreadable.
126
56
  schema = loadCachedSchema(paths.schema);
127
57
  if (!schema) {
128
58
  schema = await buildSchema(paths.raw);
@@ -136,8 +66,7 @@ async function fetchOpenApiSchema(baseUrl) {
136
66
  saveCachedSchema(paths.schema, schema);
137
67
  }
138
68
  else {
139
- // No cache and no usable response — last resort: bundle the remote URL
140
- // directly (preserves the original cold/offline behaviour).
69
+ // No cache and no usable response — bundle the remote URL directly.
141
70
  schema = await buildSchema(url);
142
71
  }
143
72
  if (schema)
@@ -21,7 +21,7 @@ exports.OPT_COMMAND_DOMAIN_ONLY_AVAILABLE = exports.OPT_COMMAND_DOMAIN_SORT = ex
21
21
  exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO_INITIALIZED = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = exports.OPT_COMMAND_PROJECT_LINK_TRY_NOW = exports.OPT_COMMAND_PROJECT_LINK_SET_GIT_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = exports.OPT_COMMAND_PROJECT_LINK_GIT = exports.OPT_COMMAND_PROJECT_LINK_RELINK = exports.DESC_COMMAND_PROJECT_LINK = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT_GIT = exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = exports.DESC_COMMAND_PROJECT = exports.TXT_ARTIFACT_VERSION_DOWNLOAD = exports.TXT_ARTIFACT_PUBLISH = exports.TXT_ARTIFACT_CREATED = exports.TXT_ARTIFACT_VERSION_DELETED = exports.TXT_ARTIFACT_DELETED = exports.ERR_COMMAND_ARTIFACT_TYPE = exports.OPT_COMMAND_ARTIFACT_VERSION = exports.OPT_COMMAND_ARTIFACT_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_CREATE_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_NAME = exports.OPT_COMMAND_ARTIFACT_TYPE = exports.DESC_COMMAND_ARTIFACT_CREATE = exports.DESC_COMMAND_ARTIFACT_COMPOSER_PUBLISH = exports.DESC_COMMAND_ARTIFACT_GET = exports.TXT_ARTIFACT_DOCKER_LOGIN_FAILED = exports.TXT_ARTIFACT_DOCKER_LOGIN_SUCCESS = exports.TXT_ARTIFACT_VERSION_DELETE_CONFIRM = exports.TXT_ARTIFACT_DELETE_CONFIRM = exports.DESC_COMMAND_ARTIFACT_DELETE = exports.ERR_COMMAND_ARTIFACT_NO_PROJECTS = exports.DESC_COMMAND_ARTIFACT_VERSION_GET = exports.DESC_COMMAND_ARTIFACT_VERSION_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION_DELETE = exports.DESC_COMMAND_ARTIFACT_DOCKER_LOGIN = exports.DESC_COMMAND_ARTIFACT_LIST = exports.DESC_COMMAND_ARTIFACT_COMPOSER = exports.DESC_COMMAND_ARTIFACT_VERSION = exports.ERR_COMMAND_DOMAIN_UNAVAILABLE = exports.OPTION_COMMAND_DOMAIN_IDENTIFIER = exports.ERR_COMMAND_DOMAIN_NO_DOMAINS = exports.TXT_COMMAND_DOMAIN_PROMPT_REQUIRED = exports.TXT_COMMAND_DOMAIN_BUY_SELECT_DOMAIN = exports.TXT_COMMAND_DOMAIN_PROVIDE_PROMPT = exports.ERR_COMMAND_DOMAIN_NOT_FOUND = void 0;
22
22
  exports.EXAMPLE_TARGET_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = exports.EXAMPLE_SANDBOX_EXEC_LOGS = exports.EXAMPLE_SANDBOX_APP_STATUS = exports.EXAMPLE_SANDBOX_APP_STOP = exports.EXAMPLE_SANDBOX_APP_REMOVE = exports.EXAMPLE_SANDBOX_APP_ADD = exports.EXAMPLE_SANDBOX_APP_START = exports.EXAMPLE_SANDBOX_APP_LOGS = exports.EXAMPLE_SANDBOX_EXEC_LIST = exports.EXAMPLE_SANDBOX_APP_LIST = exports.EXAMPLE_SANDBOX_EXEC_KILL = exports.EXAMPLE_SANDBOX_SSH = exports.EXAMPLE_SANDBOX_EXEC_COMMAND = exports.EXAMPLE_TUNNEL_START = exports.EXAMPLE_TUNNEL_TCP = exports.EXAMPLE_TUNNEL_TLS = exports.EXAMPLE_AGENT_TUNNEL_START = exports.EXAMPLE_AGENT_TUNNEL_STATUS = exports.EXAMPLE_AGENT_TUNNEL_REMOVE = exports.EXAMPLE_AGENT_TUNNEL_LIST = exports.EXAMPLE_TUNNEL_HTTP = exports.EXAMPLE_SANDBOX_CREATE = exports.EXAMPLE_DISTRO_CREATE = exports.EXAMPLE_ROUTE_CREATE = exports.EXAMPLE_ROUTE_LIST = exports.EXAMPLE_ROUTE_UPDATE = exports.EXAMPLE_ROUTE_DELETE = exports.EXAMPLE_DISTRO_DELETE = exports.EXAMPLE_ROUTE_GET = exports.EXAMPLE_DISTRO_UPDATE = exports.EXAMPLE_DISTRO_GET = exports.EXAMPLE_DISTRO_LIST = exports.EXAMPLE_SANDBOX_CP = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_CREATED = exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = exports.TXT_COMMAND_PROJECT_LINK_NAME = exports.TXT_COMMAND_PROJECT_LINK_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_LINK_TO = exports.TXT_COMMAND_PROJECT_LINK_EXISTING_DESC = exports.TXT_COMMAND_PROJECT_LINK_EXISTING = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW_DESC = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW = exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = void 0;
23
23
  exports.EXAMPLE_CRAWL_RUN = exports.EXAMPLE_TESTS_CAPTURE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CLOSE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CREATE = exports.EXAMPLE_TESTS_VISUAL_LINK = exports.EXAMPLE_TESTS_VISUAL_UPLOAD = exports.EXAMPLE_TESTS_VISUAL_SETUP = exports.EXAMPLE_TESTS_UNIT_LINK = exports.EXAMPLE_TESTS_UNIT_UPLOAD = exports.EXAMPLE_ARTIFACT_VERSION_DELETE = exports.EXAMPLE_ARTIFACT_VERSION_GET = exports.EXAMPLE_ARTIFACT_VERSION_LIST = exports.EXAMPLE_ARTIFACT_CREATE = exports.EXAMPLE_ARTIFACT_DELETE = exports.EXAMPLE_ARTIFACT_DOWNLOAD = exports.EXAMPLE_ARTIFACT_PUBLISH = exports.EXAMPLE_ARTIFACT_COMPOSER_PUBLISH = exports.EXAMPLE_ARTIFACT_VERSION_CREATE = exports.EXAMPLE_PIPELINE_RUN_RETRY = exports.EXAMPLE_PIPELINE_RUN_LIST = exports.EXAMPLE_PIPELINE_LIST = exports.EXAMPLE_PIPELINE_YML = exports.EXAMPLE_PIPELINE_GET = exports.EXAMPLE_PIPELINE_UPDATE = exports.EXAMPLE_PIPELINE_DELETE = exports.EXAMPLE_PIPELINE_CREATE = exports.EXAMPLE_PIPELINE_RUN_CANCEL = exports.EXAMPLE_PIPELINE_RUN_APPLY = exports.EXAMPLE_PIPELINE_RUN_LOGS = exports.EXAMPLE_PIPELINE_RUN_JSONL = exports.EXAMPLE_PIPELINE_RUN_STATUS = exports.EXAMPLE_PIPELINE_RUN_START = exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_ENVIRONMENT_DELETE = exports.EXAMPLE_ENVIRONMENT_UPDATE = exports.EXAMPLE_ENVIRONMENT_CREATE = exports.EXAMPLE_ENVIRONMENT_GET = exports.EXAMPLE_ENVIRONMENT_LIST = exports.EXAMPLE_TARGET_EXEC_LOGS = exports.EXAMPLE_TARGET_EXEC_LIST = exports.EXAMPLE_TARGET_EXEC_KILL = exports.EXAMPLE_TARGET_EXEC_STATUS = exports.EXAMPLE_TARGET_EXEC_COMMAND = exports.EXAMPLE_TARGET_DELETE = exports.EXAMPLE_TARGET_UPDATE = exports.EXAMPLE_TARGET_CREATE = exports.EXAMPLE_TARGET_GET = void 0;
24
- exports.EXAMPLE_CRAWL_LINK = void 0;
24
+ exports.ERR_YAML_SCHEMA_READ_FAILED = exports.ERR_YAML_SCHEMA_FETCH_FAILED = exports.TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS = exports.ERR_YAML_ITEM_UNKNOWN = exports.ERR_YAML_ITEM_MISSING = exports.ERR_YAML_MUST_BE = exports.ERR_YAML_PIPELINE_NOT_OBJECT = exports.ERR_YAML_EMPTY_ARRAY = exports.ERR_YAML_PLAIN_OBJECT = exports.ERR_YAML_NOT_ARRAY = exports.ERR_YAML_PARSE = exports.ERR_YAML_VALIDATE_FAILED_COUNT = exports.TXT_YAML_VALIDATE_ALL_PASS = exports.ERR_YAML_VALIDATE_FAILED = exports.ERR_YAML_VALIDATE_FILE_NOT_FOUND = exports.OPTION_YAML_VALIDATE_FILE = exports.DESC_COMMAND_YAML_VALIDATE = exports.DESC_COMMAND_YAML_ACTIONS_INFO = exports.DESC_COMMAND_YAML_ACTIONS_LIST = exports.DESC_COMMAND_YAML_ACTIONS = exports.DESC_COMMAND_YAML_PIPELINE = exports.DESC_COMMAND_YAML = exports.TXT_ACTION_SUGGESTED_FROM_REPO = exports.TXT_ACTION_USE_LIST = exports.TXT_ACTION_DID_YOU_MEAN = exports.ERR_ACTION_SEARCH_NO_RESULTS = exports.ERR_ACTION_NOT_FOUND = exports.OPTION_ACTION_TYPE = exports.OPTION_ACTION_SEARCH = exports.EXAMPLE_YAML_VALIDATE = exports.EXAMPLE_YAML_ACTIONS_INFO = exports.EXAMPLE_YAML_ACTIONS_LIST = exports.EXAMPLE_YAML_PIPELINE = exports.EXAMPLE_CRAWL_LINK = void 0;
25
25
  const utils_1 = require("./utils");
26
26
  exports.ERR_CANCELLED = 'Cancelled';
27
27
  exports.ERR_REST_API_GENERAL_ERROR = 'Something went wrong';
@@ -1893,3 +1893,68 @@ exports.EXAMPLE_CRAWL_LINK = `
1893
1893
  bdy crawl link
1894
1894
  ### link non-interactively to a specific suite:
1895
1895
  bdy crawl link -w workspace -p project -s suite-identifier`;
1896
+ exports.EXAMPLE_YAML_PIPELINE = `
1897
+ ### show pipeline schema and examples:
1898
+ bdy yaml pipeline
1899
+ ### the same schema as json:
1900
+ bdy yaml pipeline --format json`;
1901
+ exports.EXAMPLE_YAML_ACTIONS_LIST = `
1902
+ ### list all action types:
1903
+ bdy yaml actions list
1904
+ ### search action types:
1905
+ bdy yaml actions list --search kubernetes
1906
+ ### list as json, for an editor plugin or an agent:
1907
+ bdy yaml actions list --format json`;
1908
+ exports.EXAMPLE_YAML_ACTIONS_INFO = `
1909
+ ### show action schema and example:
1910
+ bdy yaml actions info KUBERNETES_CLI
1911
+ ### the same schema as json:
1912
+ bdy yaml actions info KUBERNETES_CLI --format json`;
1913
+ exports.EXAMPLE_YAML_VALIDATE = `
1914
+ ### validate a pipeline file:
1915
+ bdy yaml validate buddy.yml`;
1916
+ // action texts (used by yaml/action commands)
1917
+ exports.OPTION_ACTION_SEARCH = 'Search by name, type, or description';
1918
+ exports.OPTION_ACTION_TYPE = 'Action type or slug (e.g. BUILD, KUBERNETES_CLI, transfer)';
1919
+ const ERR_ACTION_NOT_FOUND = (type) => `Action "${type}" not found`;
1920
+ exports.ERR_ACTION_NOT_FOUND = ERR_ACTION_NOT_FOUND;
1921
+ const ERR_ACTION_SEARCH_NO_RESULTS = (query) => `No actions found for "${query}"`;
1922
+ exports.ERR_ACTION_SEARCH_NO_RESULTS = ERR_ACTION_SEARCH_NO_RESULTS;
1923
+ const TXT_ACTION_DID_YOU_MEAN = (types) => `Did you mean: ${types}`;
1924
+ exports.TXT_ACTION_DID_YOU_MEAN = TXT_ACTION_DID_YOU_MEAN;
1925
+ exports.TXT_ACTION_USE_LIST = 'Use "bdy yaml actions list" to browse all actions';
1926
+ const TXT_ACTION_SUGGESTED_FROM_REPO = (actions) => `Suggested based on your repo: ${actions}`;
1927
+ exports.TXT_ACTION_SUGGESTED_FROM_REPO = TXT_ACTION_SUGGESTED_FROM_REPO;
1928
+ // yaml commands
1929
+ exports.DESC_COMMAND_YAML = 'Browse and validate Buddy pipeline YAML';
1930
+ exports.DESC_COMMAND_YAML_PIPELINE = 'Show pipeline YAML schema and examples';
1931
+ exports.DESC_COMMAND_YAML_ACTIONS = 'Browse Buddy YAML action types';
1932
+ exports.DESC_COMMAND_YAML_ACTIONS_LIST = 'List all action types';
1933
+ exports.DESC_COMMAND_YAML_ACTIONS_INFO = 'Show action schema and example for a type';
1934
+ exports.DESC_COMMAND_YAML_VALIDATE = 'Validate a pipeline YAML file';
1935
+ exports.OPTION_YAML_VALIDATE_FILE = 'Path to YAML pipeline file';
1936
+ const ERR_YAML_VALIDATE_FILE_NOT_FOUND = (file) => `File not found: ${file}`;
1937
+ exports.ERR_YAML_VALIDATE_FILE_NOT_FOUND = ERR_YAML_VALIDATE_FILE_NOT_FOUND;
1938
+ exports.ERR_YAML_VALIDATE_FAILED = 'Pipeline validation failed';
1939
+ exports.TXT_YAML_VALIDATE_ALL_PASS = 'Pipeline validation passed';
1940
+ const ERR_YAML_VALIDATE_FAILED_COUNT = (count) => `${exports.ERR_YAML_VALIDATE_FAILED} (${count} ${count === 1 ? 'error' : 'errors'})`;
1941
+ exports.ERR_YAML_VALIDATE_FAILED_COUNT = ERR_YAML_VALIDATE_FAILED_COUNT;
1942
+ const ERR_YAML_PARSE = (message) => `YAML parse error: ${message}`;
1943
+ exports.ERR_YAML_PARSE = ERR_YAML_PARSE;
1944
+ exports.ERR_YAML_NOT_ARRAY = 'Invalid pipeline YAML: expected an array of pipeline objects';
1945
+ exports.ERR_YAML_PLAIN_OBJECT = 'Invalid pipeline YAML: expected an array (e.g. "- pipeline: my-pipeline"), got a plain object';
1946
+ exports.ERR_YAML_EMPTY_ARRAY = 'Invalid pipeline YAML: empty array';
1947
+ const ERR_YAML_PIPELINE_NOT_OBJECT = (index) => `Pipeline #${index}: expected an object`;
1948
+ exports.ERR_YAML_PIPELINE_NOT_OBJECT = ERR_YAML_PIPELINE_NOT_OBJECT;
1949
+ const ERR_YAML_MUST_BE = (expected, got) => `must be an ${expected}, got ${got}`;
1950
+ exports.ERR_YAML_MUST_BE = ERR_YAML_MUST_BE;
1951
+ const ERR_YAML_ITEM_MISSING = (field) => `missing "${field}"`;
1952
+ exports.ERR_YAML_ITEM_MISSING = ERR_YAML_ITEM_MISSING;
1953
+ const ERR_YAML_ITEM_UNKNOWN = (field, value) => `unknown ${field} "${value}"`;
1954
+ exports.ERR_YAML_ITEM_UNKNOWN = ERR_YAML_ITEM_UNKNOWN;
1955
+ const TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS = (keys) => `Unknown top-level keys: ${keys}`;
1956
+ exports.TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS = TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS;
1957
+ const ERR_YAML_SCHEMA_FETCH_FAILED = (url) => `Failed to fetch yaml-schema from ${url} and no cached copy is available`;
1958
+ exports.ERR_YAML_SCHEMA_FETCH_FAILED = ERR_YAML_SCHEMA_FETCH_FAILED;
1959
+ const ERR_YAML_SCHEMA_READ_FAILED = (path) => `Failed to read yaml-schema from ${path}`;
1960
+ exports.ERR_YAML_SCHEMA_READ_FAILED = ERR_YAML_SCHEMA_READ_FAILED;
@@ -48,6 +48,7 @@ exports.getDockerRegistryHostByApiBaseUrl = getDockerRegistryHostByApiBaseUrl;
48
48
  exports.getMcpUrlByApiBaseUrl = getMcpUrlByApiBaseUrl;
49
49
  exports.getMcpToolCategory = getMcpToolCategory;
50
50
  exports.openApiPrepareUrl = openApiPrepareUrl;
51
+ exports.getApiEnv = getApiEnv;
51
52
  exports.getOpenApiEndpointByApiBaseUrl = getOpenApiEndpointByApiBaseUrl;
52
53
  exports.isValidDomain = isValidDomain;
53
54
  exports.isInSandbox = isInSandbox;
@@ -1022,24 +1023,28 @@ function openApiPrepareUrl(url, workspace, project) {
1022
1023
  preparedUrl = preparedUrl.replaceAll('{project_name}', project);
1023
1024
  return preparedUrl;
1024
1025
  }
1025
- function getOpenApiEndpointByApiBaseUrl(baseUrl) {
1026
- if (baseUrl.hostname.includes('api.buddy.works') ||
1027
- baseUrl.hostname.includes('api.eu.buddy.works') ||
1028
- baseUrl.hostname.includes('api.asia.buddy.works')) {
1029
- return 'https://es.buddy.works/openapi/production/restapi.json';
1030
- }
1031
- else if (baseUrl.hostname.includes('api.awsstage.net') ||
1032
- baseUrl.hostname.includes('api.eu.awsstage.net') ||
1033
- baseUrl.hostname.includes('api.buddy.mom')) {
1034
- return 'https://es.buddy.works/openapi/stage/restapi.json';
1026
+ function getApiEnv(baseUrl) {
1027
+ const host = baseUrl.hostname;
1028
+ if (host.includes('api.buddy.works') ||
1029
+ host.includes('api.eu.buddy.works') ||
1030
+ host.includes('api.asia.buddy.works')) {
1031
+ return 'production';
1032
+ }
1033
+ else if (host.includes('api.awsstage.net') ||
1034
+ host.includes('api.eu.awsstage.net') ||
1035
+ host.includes('api.buddy.mom')) {
1036
+ return 'stage';
1035
1037
  }
1036
- else if (baseUrl.hostname.includes('api.awsmaster.net')) {
1037
- return 'https://es.buddy.works/openapi/master/restapi.json';
1038
+ else if (host.includes('api.awsmaster.net')) {
1039
+ return 'master';
1038
1040
  }
1039
1041
  else {
1040
- return 'https://es.buddy.works/openapi/dev/restapi.json';
1042
+ return 'dev';
1041
1043
  }
1042
1044
  }
1045
+ function getOpenApiEndpointByApiBaseUrl(baseUrl) {
1046
+ return `https://es.buddy.works/openapi/${getApiEnv(baseUrl)}/restapi.json`;
1047
+ }
1043
1048
  function isValidDomain(prompt) {
1044
1049
  return /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i.test(prompt);
1045
1050
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.24.8",
4
+ "version": "1.25.0-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "homepage": "https://buddy.works/docs/cli",
@@ -12,7 +12,7 @@
12
12
  "lint": "eslint \"*/**\"",
13
13
  "lint:types": "tsc --skipLibCheck --noEmit --project tsconfig.json && tsc --skipLibCheck --project test/tsconfig.json && tsc --skipLibCheck --project e2e/tsconfig.json",
14
14
  "watch": "tsc --watch --project tsconfig.json & tsc --watch --project src/visualTest/utils/tsconfig.json",
15
- "buildTs": "(tsc --project tsconfig.json & tsc --project src/visualTest/utils/tsconfig.json & wait) && cp package.json distTs/package.json && curl -fsSL https://raw.githubusercontent.com/buddy/cli/main/README.md -o README.md",
15
+ "buildTs": "(tsc --project tsconfig.json & tsc --project src/visualTest/utils/tsconfig.json & wait) && cp package.json distTs/package.json && cp detect-rules.json distTs/detect-rules.json && curl -fsSL https://raw.githubusercontent.com/buddy/cli/main/README.md -o README.md",
16
16
  "e2e": "npm run buildTs && vitest run --config e2e/vitest.config.ts",
17
17
  "e2e:version": "vitest run --config e2e/vitest.config.ts e2e/modules/version/",
18
18
  "e2e:tunnel-config": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel-config/",
@@ -29,6 +29,7 @@
29
29
  "e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
30
30
  "e2e:target": "vitest run --config e2e/vitest.config.ts e2e/modules/target/",
31
31
  "e2e:environment": "vitest run --config e2e/vitest.config.ts e2e/modules/environment/",
32
+ "e2e:yaml": "vitest run --config e2e/vitest.config.ts e2e/modules/yaml/",
32
33
  "unit": "vitest run --config vitest.config.ts"
33
34
  },
34
35
  "files": [
@@ -58,6 +59,8 @@
58
59
  "@scalar/openapi-parser": "0.28.7",
59
60
  "@scalar/openapi-types": "0.9.1",
60
61
  "@xhmikosr/decompress": "11.1.3",
62
+ "ajv": "8.20.0",
63
+ "ajv-formats": "3.0.1",
61
64
  "basic-auth": "2.0.1",
62
65
  "chalk": "5.6.2",
63
66
  "commander": "15.0.0",
@@ -74,6 +77,7 @@
74
77
  "jsonwebtoken": "9.0.3",
75
78
  "mime-db": "1.54.0",
76
79
  "mime-types": "3.0.2",
80
+ "minisearch": "7.2.0",
77
81
  "netmask": "2.1.1",
78
82
  "node-forge": "1.4.0",
79
83
  "open": "11.0.0",
@@ -92,6 +96,7 @@
92
96
  "uuid": "14.0.0",
93
97
  "which": "4.0.0",
94
98
  "ws": "8.21.0",
99
+ "yaml": "2.8.3",
95
100
  "zod": "3.25.76"
96
101
  },
97
102
  "devDependencies": {