bdy 1.25.1-stage → 1.25.2-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.
- package/distTs/package.json +2 -6
- package/distTs/src/command/api/info.js +224 -255
- package/distTs/src/command/api/list.js +14 -17
- package/distTs/src/command/yaml/actions/detect.js +11 -2
- package/distTs/src/command/yaml/actions/info.js +22 -12
- package/distTs/src/command/yaml/actions/list.js +11 -20
- package/distTs/src/command/yaml/actions/schema.js +43 -87
- package/distTs/src/command/yaml/pipeline.js +9 -25
- package/distTs/src/command/yaml/render.js +83 -71
- package/distTs/src/command/yaml/schemaUtils.js +12 -50
- package/distTs/src/command/yaml/validate.js +32 -27
- package/distTs/src/diskCache.js +0 -1
- package/distTs/src/openapi.js +16 -68
- package/distTs/src/texts.js +7 -9
- package/package.json +2 -6
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.detectActions = detectActions;
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
|
+
const node_sea_1 = require("node:sea");
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
9
10
|
const picomatch_1 = __importDefault(require("picomatch"));
|
|
10
11
|
const utils_1 = require("../../../utils");
|
|
@@ -15,8 +16,16 @@ let cachedRules = null;
|
|
|
15
16
|
function loadDetectRules() {
|
|
16
17
|
if (cachedRules)
|
|
17
18
|
return cachedRules;
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
// Detection only feeds the "Suggested based on your repo" list, so a missing or
|
|
20
|
+
// unreadable rule file costs a suggestion rather than the command.
|
|
21
|
+
try {
|
|
22
|
+
cachedRules = JSON.parse((0, node_sea_1.isSea)()
|
|
23
|
+
? (0, node_sea_1.getAsset)('detect-rules.json', 'utf8')
|
|
24
|
+
: (0, fs_1.readFileSync)(path_1.default.resolve((0, utils_1.getRootDir)(), 'detect-rules.json'), 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
cachedRules = {};
|
|
28
|
+
}
|
|
20
29
|
return cachedRules;
|
|
21
30
|
}
|
|
22
31
|
function safeReadDir(dir) {
|
|
@@ -10,14 +10,16 @@ const schema_1 = require("./schema");
|
|
|
10
10
|
const schemaUtils_1 = require("../schemaUtils");
|
|
11
11
|
const detect_1 = require("./detect");
|
|
12
12
|
const render_1 = require("../render");
|
|
13
|
+
async function suggestionLine(query) {
|
|
14
|
+
return (await (0, schema_1.searchActions)(query, 5)).map((hit) => `${hit.type} (${hit.name})`);
|
|
15
|
+
}
|
|
13
16
|
const commandYamlActionsInfo = (0, utils_1.newCommand)('info', texts_1.DESC_COMMAND_YAML_ACTIONS_INFO);
|
|
14
17
|
commandYamlActionsInfo.argument('<type>', texts_1.OPTION_ACTION_TYPE);
|
|
15
18
|
commandYamlActionsInfo.option('--format <text|json>', texts_1.OPTION_FORMAT);
|
|
16
19
|
commandYamlActionsInfo.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_YAML_ACTIONS_INFO}`);
|
|
17
20
|
commandYamlActionsInfo.action(async (type, options) => {
|
|
18
21
|
await (0, schemaUtils_1.ensureYamlSchema)();
|
|
19
|
-
const
|
|
20
|
-
const action = (0, schema_1.findAction)(actions, type);
|
|
22
|
+
const action = await (0, schema_1.findAction)(type);
|
|
21
23
|
if (!action) {
|
|
22
24
|
if (options.format === 'json') {
|
|
23
25
|
output_1.default.json(null);
|
|
@@ -25,14 +27,16 @@ commandYamlActionsInfo.action(async (type, options) => {
|
|
|
25
27
|
return;
|
|
26
28
|
}
|
|
27
29
|
output_1.default.error((0, texts_1.ERR_ACTION_NOT_FOUND)(type));
|
|
28
|
-
const suggestions =
|
|
30
|
+
const suggestions = await suggestionLine(type);
|
|
29
31
|
if (suggestions.length > 0) {
|
|
30
|
-
output_1.default.muted((0, texts_1.TXT_ACTION_DID_YOU_MEAN)(suggestions.
|
|
32
|
+
output_1.default.muted((0, texts_1.TXT_ACTION_DID_YOU_MEAN)(suggestions.join(', ')));
|
|
31
33
|
}
|
|
32
34
|
else {
|
|
33
35
|
const detectedTypes = (0, detect_1.detectActions)(process.cwd());
|
|
34
36
|
if (detectedTypes.size > 0) {
|
|
35
|
-
const detected =
|
|
37
|
+
const detected = (await (0, schema_1.loadSchema)())
|
|
38
|
+
.filter((a) => detectedTypes.has(a.type))
|
|
39
|
+
.slice(0, 5);
|
|
36
40
|
output_1.default.muted((0, texts_1.TXT_ACTION_SUGGESTED_FROM_REPO)(detected.map((a) => `${a.type} (${a.name})`).join(', ')));
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -40,7 +44,7 @@ commandYamlActionsInfo.action(async (type, options) => {
|
|
|
40
44
|
output_1.default.exitNormal();
|
|
41
45
|
return;
|
|
42
46
|
}
|
|
43
|
-
const { common, specific } = (0, schema_1.splitProperties)(action);
|
|
47
|
+
const { common, specific } = await (0, schema_1.splitProperties)(action);
|
|
44
48
|
if (options.format === 'json') {
|
|
45
49
|
output_1.default.json({
|
|
46
50
|
type: action.type,
|
|
@@ -49,9 +53,10 @@ commandYamlActionsInfo.action(async (type, options) => {
|
|
|
49
53
|
description: action.description,
|
|
50
54
|
required: action.required,
|
|
51
55
|
fields: {
|
|
52
|
-
specific: (0, render_1.propertiesJson)(specific
|
|
53
|
-
common: (0, render_1.propertiesJson)(common
|
|
56
|
+
specific: (0, render_1.propertiesJson)(specific),
|
|
57
|
+
common: (0, render_1.propertiesJson)(common),
|
|
54
58
|
},
|
|
59
|
+
types: (0, render_1.typesJson)(action.types),
|
|
55
60
|
examples: action.examples,
|
|
56
61
|
});
|
|
57
62
|
output_1.default.exitNormal();
|
|
@@ -61,14 +66,19 @@ commandYamlActionsInfo.action(async (type, options) => {
|
|
|
61
66
|
output_1.default.gray(` · ${action.type}`);
|
|
62
67
|
output_1.default.gray(action.description);
|
|
63
68
|
output_1.default.normal('');
|
|
64
|
-
if (
|
|
69
|
+
if (specific.length > 0) {
|
|
65
70
|
output_1.default.blue('Type-specific fields');
|
|
66
|
-
(0, render_1.outputProperties)(specific
|
|
71
|
+
(0, render_1.outputProperties)(specific);
|
|
67
72
|
output_1.default.normal('');
|
|
68
73
|
}
|
|
69
|
-
if (
|
|
74
|
+
if (common.length > 0) {
|
|
70
75
|
output_1.default.blue('Common fields');
|
|
71
|
-
(0, render_1.outputProperties)(common
|
|
76
|
+
(0, render_1.outputProperties)(common);
|
|
77
|
+
}
|
|
78
|
+
if (Object.keys(action.types).length > 0) {
|
|
79
|
+
output_1.default.normal('');
|
|
80
|
+
output_1.default.blue('Types');
|
|
81
|
+
(0, render_1.outputTypes)(action.types);
|
|
72
82
|
}
|
|
73
83
|
if (action.examples.length > 0) {
|
|
74
84
|
output_1.default.normal('');
|
|
@@ -12,9 +12,7 @@ const detect_1 = require("./detect");
|
|
|
12
12
|
function actionTable(actions) {
|
|
13
13
|
const data = [['TYPE', 'NAME', 'DESCRIPTION']];
|
|
14
14
|
for (const action of actions) {
|
|
15
|
-
const desc = action.description.length > 80
|
|
16
|
-
? action.description.substring(0, 77) + '...'
|
|
17
|
-
: action.description;
|
|
15
|
+
const desc = action.description.length > 80 ? `${action.description.substring(0, 77)}...` : action.description;
|
|
18
16
|
data.push([action.type, action.name, desc]);
|
|
19
17
|
}
|
|
20
18
|
return data;
|
|
@@ -35,17 +33,14 @@ commandYamlActionsList.option('--format <text|json>', texts_1.OPTION_FORMAT);
|
|
|
35
33
|
commandYamlActionsList.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_YAML_ACTIONS_LIST}`);
|
|
36
34
|
commandYamlActionsList.action(async (options) => {
|
|
37
35
|
await (0, schemaUtils_1.ensureYamlSchema)();
|
|
38
|
-
const actions = (0, schema_1.loadSchema)();
|
|
36
|
+
const actions = await (0, schema_1.loadSchema)();
|
|
39
37
|
const detectedTypes = (0, detect_1.detectActions)(process.cwd());
|
|
38
|
+
const byType = new Map(actions.map((a) => [a.type, a]));
|
|
40
39
|
if (options.search) {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
results.sort((a, b) => {
|
|
46
|
-
const ai = hits.findIndex((h) => h.id === a.slug);
|
|
47
|
-
const bi = hits.findIndex((h) => h.id === b.slug);
|
|
48
|
-
return ai - bi;
|
|
40
|
+
const ranked = await (0, schema_1.searchActions)(options.search);
|
|
41
|
+
const results = ranked.flatMap((hit) => {
|
|
42
|
+
const action = byType.get(hit.type);
|
|
43
|
+
return action ? [action] : [];
|
|
49
44
|
});
|
|
50
45
|
if (results.length === 0) {
|
|
51
46
|
if (options.format === 'json') {
|
|
@@ -53,11 +48,7 @@ commandYamlActionsList.action(async (options) => {
|
|
|
53
48
|
output_1.default.exitNormal();
|
|
54
49
|
return;
|
|
55
50
|
}
|
|
56
|
-
const suggestions = index.autoSuggest(options.search);
|
|
57
51
|
output_1.default.error((0, texts_1.ERR_ACTION_SEARCH_NO_RESULTS)(options.search));
|
|
58
|
-
if (suggestions.length > 0) {
|
|
59
|
-
output_1.default.muted((0, texts_1.TXT_ACTION_DID_YOU_MEAN)(suggestions.map((s) => s.suggestion).join(', ')));
|
|
60
|
-
}
|
|
61
52
|
if (detectedTypes.size > 0) {
|
|
62
53
|
const detected = actions.filter((a) => detectedTypes.has(a.type));
|
|
63
54
|
output_1.default.normal('');
|
|
@@ -77,20 +68,20 @@ commandYamlActionsList.action(async (options) => {
|
|
|
77
68
|
output_1.default.exitNormal();
|
|
78
69
|
return;
|
|
79
70
|
}
|
|
80
|
-
const
|
|
71
|
+
const byTypeName = (a, b) => a.type.localeCompare(b.type);
|
|
81
72
|
if (options.format === 'json') {
|
|
82
|
-
output_1.default.json(actionJson([...actions].sort(
|
|
73
|
+
output_1.default.json(actionJson([...actions].sort(byTypeName), detectedTypes));
|
|
83
74
|
output_1.default.exitNormal();
|
|
84
75
|
return;
|
|
85
76
|
}
|
|
86
77
|
if (detectedTypes.size > 0) {
|
|
87
|
-
const detected = actions.filter((a) => detectedTypes.has(a.type)).sort(
|
|
78
|
+
const detected = actions.filter((a) => detectedTypes.has(a.type)).sort(byTypeName);
|
|
88
79
|
output_1.default.blue('Suggested');
|
|
89
80
|
output_1.default.table(actionTable(detected));
|
|
90
81
|
output_1.default.normal('');
|
|
91
82
|
}
|
|
92
83
|
output_1.default.blue(`All actions (${actions.length})`);
|
|
93
|
-
output_1.default.table(actionTable([...actions].sort(
|
|
84
|
+
output_1.default.table(actionTable([...actions].sort(byTypeName)));
|
|
94
85
|
output_1.default.exitNormal();
|
|
95
86
|
});
|
|
96
87
|
exports.default = commandYamlActionsList;
|
|
@@ -1,104 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadSchema = loadSchema;
|
|
4
|
-
exports.getCommonFields = getCommonFields;
|
|
5
4
|
exports.splitProperties = splitProperties;
|
|
6
5
|
exports.findAction = findAction;
|
|
7
|
-
exports.
|
|
8
|
-
exports.suggestActions = suggestActions;
|
|
6
|
+
exports.searchActions = searchActions;
|
|
9
7
|
const schemaUtils_1 = require("../schemaUtils");
|
|
8
|
+
const toActionDef = (member) => ({
|
|
9
|
+
key: member.definition,
|
|
10
|
+
slug: member.slug,
|
|
11
|
+
name: member.name,
|
|
12
|
+
type: member.value,
|
|
13
|
+
description: member.description,
|
|
14
|
+
properties: member.properties,
|
|
15
|
+
required: member.required,
|
|
16
|
+
examples: member.examples,
|
|
17
|
+
tags: member.tags,
|
|
18
|
+
types: member.document?.types ?? {},
|
|
19
|
+
});
|
|
10
20
|
let memCached = null;
|
|
11
|
-
function
|
|
12
|
-
const base = defKey.replace(/ActionYaml$/, '');
|
|
13
|
-
return base
|
|
14
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
15
|
-
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
|
|
16
|
-
.toLowerCase();
|
|
17
|
-
}
|
|
18
|
-
function parseSchema(raw) {
|
|
19
|
-
const defs = raw.$defs || {};
|
|
20
|
-
const actionKeys = Object.keys(defs).filter((k) => k.endsWith('ActionYaml') && defs[k].deprecated !== true);
|
|
21
|
-
const sharedDefs = (0, schemaUtils_1.getSharedDefs)();
|
|
22
|
-
return actionKeys.map((key) => {
|
|
23
|
-
const def = defs[key];
|
|
24
|
-
const typeConst = def.properties?.type?.const || def.properties?.type?.enum?.[0] || '';
|
|
25
|
-
const properties = def.properties ? (0, schemaUtils_1.resolveRefs)(def.properties, sharedDefs) : {};
|
|
26
|
-
return {
|
|
27
|
-
key,
|
|
28
|
-
slug: deriveSlug(key),
|
|
29
|
-
name: def['x-name'] || def.title || key,
|
|
30
|
-
type: typeConst,
|
|
31
|
-
description: def.description || '',
|
|
32
|
-
properties,
|
|
33
|
-
required: def.required || [],
|
|
34
|
-
examples: def.examples || [],
|
|
35
|
-
tags: [...new Set([
|
|
36
|
-
...(def['x-tags'] || []),
|
|
37
|
-
...((def['x-subtypes'] || []).flatMap((s) => s['x-tags'] || [])),
|
|
38
|
-
])],
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
function loadSchema() {
|
|
21
|
+
async function loadSchema() {
|
|
43
22
|
if (memCached)
|
|
44
23
|
return memCached;
|
|
45
|
-
const
|
|
46
|
-
|
|
24
|
+
const scope = (0, schemaUtils_1.actionsScope)();
|
|
25
|
+
const members = await Promise.all((await scope.list()).map((type) => scope.get(type)));
|
|
26
|
+
memCached = members.filter((member) => member !== undefined).map(toActionDef);
|
|
47
27
|
return memCached;
|
|
48
28
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
function getCommonFields() {
|
|
52
|
-
if (commonCached)
|
|
53
|
-
return commonCached;
|
|
54
|
-
const actions = loadSchema();
|
|
55
|
-
let common = null;
|
|
56
|
-
for (const action of actions) {
|
|
57
|
-
const keys = Object.keys(action.properties);
|
|
58
|
-
if (common === null) {
|
|
59
|
-
common = new Set(keys);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
common = new Set(keys.filter((k) => common.has(k)));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
commonCached = common || new Set();
|
|
66
|
-
return commonCached;
|
|
29
|
+
async function getCommonFields() {
|
|
30
|
+
return new Set(await (0, schemaUtils_1.actionsScope)().commonFields());
|
|
67
31
|
}
|
|
68
|
-
function splitProperties(action) {
|
|
69
|
-
const commonFields = getCommonFields();
|
|
70
|
-
const common =
|
|
71
|
-
const specific =
|
|
72
|
-
for (const
|
|
73
|
-
|
|
74
|
-
common[key] = prop;
|
|
75
|
-
else
|
|
76
|
-
specific[key] = prop;
|
|
32
|
+
async function splitProperties(action) {
|
|
33
|
+
const commonFields = await getCommonFields();
|
|
34
|
+
const common = [];
|
|
35
|
+
const specific = [];
|
|
36
|
+
for (const property of action.properties) {
|
|
37
|
+
(commonFields.has(property.name) ? common : specific).push(property);
|
|
77
38
|
}
|
|
78
39
|
return { common, specific };
|
|
79
40
|
}
|
|
80
|
-
function findAction(
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
index.addAll(actions.map((a) => ({ id: a.slug, name: a.name, type: a.type, description: a.description, tags: a.tags.join(' '), slug: a.slug })));
|
|
98
|
-
return index;
|
|
41
|
+
async function findAction(query) {
|
|
42
|
+
const scope = (0, schemaUtils_1.actionsScope)();
|
|
43
|
+
const asked = query.toUpperCase();
|
|
44
|
+
const byType = (await scope.list()).find((type) => type === asked);
|
|
45
|
+
const member = byType ? await scope.get(byType) : await memberBySlug(query.toLowerCase());
|
|
46
|
+
return member && !member.deprecated ? toActionDef(member) : undefined;
|
|
47
|
+
}
|
|
48
|
+
async function memberBySlug(slug) {
|
|
49
|
+
const scope = (0, schemaUtils_1.actionsScope)();
|
|
50
|
+
for (const type of await scope.list()) {
|
|
51
|
+
const member = await scope.get(type);
|
|
52
|
+
if (member?.slug === slug)
|
|
53
|
+
return member;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
99
56
|
}
|
|
100
|
-
function
|
|
101
|
-
const hits =
|
|
102
|
-
|
|
103
|
-
return hits.map((h) => bySlug.get(h.id)).filter(Boolean);
|
|
57
|
+
async function searchActions(query, limit = Infinity) {
|
|
58
|
+
const hits = await (0, schemaUtils_1.actionsScope)().search(query, { fuzzy: 0.3, limit });
|
|
59
|
+
return hits.map((hit) => ({ type: hit.key, name: hit.name }));
|
|
104
60
|
}
|
|
@@ -8,44 +8,28 @@ const output_1 = __importDefault(require("../../output"));
|
|
|
8
8
|
const texts_1 = require("../../texts");
|
|
9
9
|
const schemaUtils_1 = require("./schemaUtils");
|
|
10
10
|
const render_1 = require("./render");
|
|
11
|
-
let cached = null;
|
|
12
|
-
function loadPipelineRoot() {
|
|
13
|
-
if (cached)
|
|
14
|
-
return cached;
|
|
15
|
-
const defs = (0, schemaUtils_1.getAllDefs)();
|
|
16
|
-
const sharedDefs = (0, schemaUtils_1.getSharedDefs)();
|
|
17
|
-
const pipelineDef = defs['PipelineYaml'];
|
|
18
|
-
if (!pipelineDef?.properties) {
|
|
19
|
-
cached = { properties: {}, required: [], examples: [] };
|
|
20
|
-
return cached;
|
|
21
|
-
}
|
|
22
|
-
cached = {
|
|
23
|
-
properties: (0, schemaUtils_1.resolveRefs)(pipelineDef.properties, sharedDefs),
|
|
24
|
-
required: pipelineDef.required || [],
|
|
25
|
-
examples: pipelineDef.examples || [],
|
|
26
|
-
};
|
|
27
|
-
return cached;
|
|
28
|
-
}
|
|
29
11
|
const commandYamlPipeline = (0, utils_1.newCommand)('pipeline', texts_1.DESC_COMMAND_YAML_PIPELINE);
|
|
30
12
|
commandYamlPipeline.option('--format <text|json>', texts_1.OPTION_FORMAT);
|
|
31
13
|
commandYamlPipeline.addHelpText('after', `\nEXAMPLES:${texts_1.EXAMPLE_YAML_PIPELINE}`);
|
|
32
14
|
commandYamlPipeline.action(async (options) => {
|
|
33
15
|
await (0, schemaUtils_1.ensureYamlSchema)();
|
|
34
|
-
const
|
|
16
|
+
const scope = (0, schemaUtils_1.pipelinesScope)();
|
|
17
|
+
const properties = await scope.properties('PipelineYaml');
|
|
18
|
+
const examples = ((await scope.root())?.examples ?? []);
|
|
35
19
|
if (options.format === 'json') {
|
|
36
20
|
output_1.default.json({
|
|
37
|
-
properties: (0, render_1.propertiesJson)(
|
|
38
|
-
required:
|
|
39
|
-
examples
|
|
21
|
+
properties: (0, render_1.propertiesJson)(properties),
|
|
22
|
+
required: properties.filter((p) => p.required).map((p) => p.name),
|
|
23
|
+
examples,
|
|
40
24
|
});
|
|
41
25
|
}
|
|
42
26
|
else {
|
|
43
27
|
output_1.default.blue('Pipeline properties');
|
|
44
28
|
output_1.default.normal('');
|
|
45
|
-
(0, render_1.outputProperties)(
|
|
46
|
-
if (
|
|
29
|
+
(0, render_1.outputProperties)(properties);
|
|
30
|
+
if (examples.length > 0) {
|
|
47
31
|
output_1.default.normal('');
|
|
48
|
-
(0, render_1.outputExamples)(
|
|
32
|
+
(0, render_1.outputExamples)(examples);
|
|
49
33
|
}
|
|
50
34
|
}
|
|
51
35
|
output_1.default.exitNormal();
|
|
@@ -3,91 +3,103 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatType = formatType;
|
|
7
|
-
exports.formatDescription = formatDescription;
|
|
8
6
|
exports.propertiesJson = propertiesJson;
|
|
9
7
|
exports.outputProperties = outputProperties;
|
|
8
|
+
exports.typesJson = typesJson;
|
|
9
|
+
exports.outputTypes = outputTypes;
|
|
10
10
|
exports.outputExamples = outputExamples;
|
|
11
11
|
const output_1 = __importDefault(require("../../output"));
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (prop.items?.title)
|
|
21
|
-
return `${prop.items.title}[]`;
|
|
22
|
-
return 'array';
|
|
23
|
-
}
|
|
24
|
-
if (prop.type === 'object' && prop.properties)
|
|
25
|
-
return 'object';
|
|
26
|
-
return prop.type || 'any';
|
|
27
|
-
}
|
|
28
|
-
function formatDescription(prop) {
|
|
12
|
+
const shownProperty = (prop) => prop;
|
|
13
|
+
const shownField = (field) => ({
|
|
14
|
+
...field,
|
|
15
|
+
minimum: field.constraints?.minimum,
|
|
16
|
+
maximum: field.constraints?.maximum,
|
|
17
|
+
});
|
|
18
|
+
const typeOf = (one) => (one.const !== undefined ? `"${one.const}"` : one.type);
|
|
19
|
+
function describe(one) {
|
|
29
20
|
const parts = [];
|
|
30
|
-
if (
|
|
31
|
-
parts.push(
|
|
32
|
-
if (
|
|
33
|
-
parts.push(`Value: ${
|
|
34
|
-
if (
|
|
35
|
-
parts.push(`Values: ${
|
|
36
|
-
if (
|
|
37
|
-
parts.push(`Min: ${
|
|
38
|
-
if (
|
|
39
|
-
parts.push(`Max: ${
|
|
21
|
+
if (one.description)
|
|
22
|
+
parts.push(one.description.replace(/\.$/, ''));
|
|
23
|
+
if (one.const !== undefined)
|
|
24
|
+
parts.push(`Value: ${one.const}`);
|
|
25
|
+
if (one.enum)
|
|
26
|
+
parts.push(`Values: ${one.enum.join(', ')}`);
|
|
27
|
+
if (one.minimum !== undefined)
|
|
28
|
+
parts.push(`Min: ${one.minimum}`);
|
|
29
|
+
if (one.maximum !== undefined)
|
|
30
|
+
parts.push(`Max: ${one.maximum}`);
|
|
40
31
|
return parts.join('. ');
|
|
41
32
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const out = {};
|
|
55
|
-
for (const key of sortedKeys(properties, required)) {
|
|
56
|
-
const prop = properties[key];
|
|
57
|
-
const field = {
|
|
58
|
-
type: formatType(prop),
|
|
59
|
-
required: required.includes(key),
|
|
60
|
-
};
|
|
61
|
-
if (prop.description)
|
|
62
|
-
field.description = prop.description;
|
|
63
|
-
if (prop.const !== undefined)
|
|
64
|
-
field.const = prop.const;
|
|
65
|
-
if (prop.enum)
|
|
66
|
-
field.enum = prop.enum;
|
|
67
|
-
if (prop.minimum !== undefined)
|
|
68
|
-
field.minimum = prop.minimum;
|
|
69
|
-
if (prop.maximum !== undefined)
|
|
70
|
-
field.maximum = prop.maximum;
|
|
71
|
-
out[key] = field;
|
|
72
|
-
}
|
|
33
|
+
function row(one) {
|
|
34
|
+
const out = { type: typeOf(one), required: one.required };
|
|
35
|
+
if (one.description)
|
|
36
|
+
out.description = one.description;
|
|
37
|
+
if (one.const !== undefined)
|
|
38
|
+
out.const = one.const;
|
|
39
|
+
if (one.enum)
|
|
40
|
+
out.enum = one.enum;
|
|
41
|
+
if (one.minimum !== undefined)
|
|
42
|
+
out.minimum = one.minimum;
|
|
43
|
+
if (one.maximum !== undefined)
|
|
44
|
+
out.maximum = one.maximum;
|
|
73
45
|
return out;
|
|
74
46
|
}
|
|
75
|
-
function
|
|
76
|
-
const keys = sortedKeys(properties, required);
|
|
47
|
+
function table(rows) {
|
|
77
48
|
const data = [['FIELD', 'TYPE', 'REQUIRED', 'DESCRIPTION']];
|
|
78
|
-
for (const
|
|
79
|
-
const
|
|
80
|
-
const desc = formatDescription(prop);
|
|
81
|
-
const truncDesc = desc.length > 100 ? desc.substring(0, 97) + '...' : desc;
|
|
49
|
+
for (const one of rows) {
|
|
50
|
+
const desc = describe(one);
|
|
82
51
|
data.push([
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
required
|
|
86
|
-
|
|
52
|
+
one.name,
|
|
53
|
+
typeOf(one),
|
|
54
|
+
one.required ? 'yes' : '',
|
|
55
|
+
desc.length > 100 ? `${desc.substring(0, 97)}...` : desc,
|
|
87
56
|
]);
|
|
88
57
|
}
|
|
89
58
|
output_1.default.table(data);
|
|
90
59
|
}
|
|
60
|
+
function sorted(properties) {
|
|
61
|
+
return properties.map(shownProperty).toSorted((a, b) => {
|
|
62
|
+
if (a.required !== b.required)
|
|
63
|
+
return a.required ? -1 : 1;
|
|
64
|
+
return a.name.localeCompare(b.name);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Top level only: every action carries `trigger_conditions`, whose tree dwarfs its own fields.
|
|
68
|
+
function propertiesJson(properties) {
|
|
69
|
+
const out = {};
|
|
70
|
+
for (const one of sorted(properties))
|
|
71
|
+
out[one.name] = row(one);
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function outputProperties(properties) {
|
|
75
|
+
table(sorted(properties));
|
|
76
|
+
}
|
|
77
|
+
// A map's synthetic key row can be named after a real sibling field and read as its duplicate.
|
|
78
|
+
const namedFields = (type) => type.fields.filter((one) => one.dynamicKey !== true).map(shownField);
|
|
79
|
+
function typesJson(types) {
|
|
80
|
+
const out = {};
|
|
81
|
+
for (const [name, type] of Object.entries(types)) {
|
|
82
|
+
if (!type) {
|
|
83
|
+
out[name] = null;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const fields = {};
|
|
87
|
+
for (const one of namedFields(type))
|
|
88
|
+
fields[one.name] = row(one);
|
|
89
|
+
out[name] = fields;
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
function outputTypes(types) {
|
|
94
|
+
const named = Object.entries(types).filter((entry) => entry[1] !== null && entry[1].fields.length > 0);
|
|
95
|
+
if (named.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
for (const [name, type] of named) {
|
|
98
|
+
output_1.default.normal('');
|
|
99
|
+
output_1.default.blue(name);
|
|
100
|
+
table(namedFields(type));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
91
103
|
function formatExampleYaml(value) {
|
|
92
104
|
try {
|
|
93
105
|
const YAML = require('yaml');
|
|
@@ -105,7 +117,7 @@ function outputExamples(examples) {
|
|
|
105
117
|
output_1.default.blue('Examples');
|
|
106
118
|
for (const ex of examples) {
|
|
107
119
|
output_1.default.normal('');
|
|
108
|
-
output_1.default.yellow(`# ${ex.title}`);
|
|
120
|
+
output_1.default.yellow(`# ${ex.title ?? 'Example'}`);
|
|
109
121
|
output_1.default.gray(formatExampleYaml(ex.value));
|
|
110
122
|
}
|
|
111
123
|
}
|
|
@@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.pipelinesScope = exports.actionsScope = void 0;
|
|
6
7
|
exports.ensureYamlSchema = ensureYamlSchema;
|
|
7
8
|
exports.loadRawSchema = loadRawSchema;
|
|
8
9
|
exports.getDefValidator = getDefValidator;
|
|
9
10
|
exports.validateAgainstDef = validateAgainstDef;
|
|
10
11
|
exports.validateAgainstSchema = validateAgainstSchema;
|
|
11
12
|
exports.getAllDefs = getAllDefs;
|
|
12
|
-
|
|
13
|
-
exports.resolveRefs = resolveRefs;
|
|
13
|
+
const docs_schema_1 = require("@buddy-works/docs-schema");
|
|
14
14
|
const utils_1 = require("../../utils");
|
|
15
15
|
const input_1 = __importDefault(require("../../input"));
|
|
16
16
|
const diskCache_1 = require("../../diskCache");
|
|
@@ -35,6 +35,16 @@ function readCachedSchema() {
|
|
|
35
35
|
throw new Error((0, texts_1.ERR_YAML_SCHEMA_READ_FAILED)(path));
|
|
36
36
|
return JSON.parse(raw);
|
|
37
37
|
}
|
|
38
|
+
let client = null;
|
|
39
|
+
function schemas() {
|
|
40
|
+
if (!client)
|
|
41
|
+
client = docs_schema_1.BuddySchema.from({ pipelines: loadRawSchema() });
|
|
42
|
+
return client;
|
|
43
|
+
}
|
|
44
|
+
const actionsScope = () => schemas().actions;
|
|
45
|
+
exports.actionsScope = actionsScope;
|
|
46
|
+
const pipelinesScope = () => schemas().pipelines;
|
|
47
|
+
exports.pipelinesScope = pipelinesScope;
|
|
38
48
|
let cachedRaw = null;
|
|
39
49
|
let ajvInstance = null;
|
|
40
50
|
const validatorCache = new Map();
|
|
@@ -114,51 +124,3 @@ function getAllDefs() {
|
|
|
114
124
|
const raw = loadRawSchema();
|
|
115
125
|
return raw.$defs || {};
|
|
116
126
|
}
|
|
117
|
-
function getSharedDefs() {
|
|
118
|
-
const defs = getAllDefs();
|
|
119
|
-
const shared = {};
|
|
120
|
-
for (const [k, v] of Object.entries(defs)) {
|
|
121
|
-
if (!k.endsWith('ActionYaml')) {
|
|
122
|
-
shared[k] = v;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return shared;
|
|
126
|
-
}
|
|
127
|
-
function resolveRefs(properties, sharedDefs, depth = 0) {
|
|
128
|
-
if (depth > 5)
|
|
129
|
-
return properties;
|
|
130
|
-
const resolved = {};
|
|
131
|
-
for (const [key, prop] of Object.entries(properties)) {
|
|
132
|
-
if (prop.$ref) {
|
|
133
|
-
const refName = prop.$ref.replace('#/$defs/', '');
|
|
134
|
-
const refDef = sharedDefs[refName];
|
|
135
|
-
if (refDef) {
|
|
136
|
-
resolved[key] = { ...refDef, description: prop.description || refDef.description };
|
|
137
|
-
if (refDef.properties) {
|
|
138
|
-
resolved[key].properties = resolveRefs(refDef.properties, sharedDefs, depth + 1);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
resolved[key] = prop;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
else if (prop.type === 'array' && prop.items?.$ref) {
|
|
146
|
-
const refName = prop.items.$ref.replace('#/$defs/', '');
|
|
147
|
-
const refDef = sharedDefs[refName];
|
|
148
|
-
if (refDef) {
|
|
149
|
-
const resolvedItems = { ...refDef };
|
|
150
|
-
if (refDef.properties) {
|
|
151
|
-
resolvedItems.properties = resolveRefs(refDef.properties, sharedDefs, depth + 1);
|
|
152
|
-
}
|
|
153
|
-
resolved[key] = { ...prop, items: resolvedItems };
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
resolved[key] = prop;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
resolved[key] = prop;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return resolved;
|
|
164
|
-
}
|