specshield 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/projectConfig.js +50 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specshield",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.1",
|
|
4
4
|
"description": "Contract compatibility testing for APIs — catch breaking OpenAPI changes before they reach your consumers, with can-i-deploy deploy gating and GitHub PR checks. (a.k.a. bidirectional contract testing.)",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -92,9 +92,30 @@ const REQUIRED_FIELDS = {
|
|
|
92
92
|
'list-consumers': ['org'],
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Option names that CAN be defaulted from `.specshield.yml`.
|
|
97
|
+
*
|
|
98
|
+
* Deliberately NOT every required field: `version`, `consumerVersion` and
|
|
99
|
+
* `providerVersion` are per-invocation values (a git SHA, a release tag) with no
|
|
100
|
+
* sensible project-wide default, so `bdctDefaultFor` has no case for them.
|
|
101
|
+
*
|
|
102
|
+
* This set exists so the "missing required options" error can tell the truth about
|
|
103
|
+
* where each field can be set. Pointing a user at `.specshield.yml` for a field the
|
|
104
|
+
* config can never supply sends them to edit a file, re-run, hit the identical error,
|
|
105
|
+
* and conclude the config file is broken.
|
|
106
|
+
*
|
|
107
|
+
* MUST stay in sync with the cases handled in {@link bdctDefaultFor} — the
|
|
108
|
+
* "config-backed fields" test asserts both directions.
|
|
109
|
+
*/
|
|
110
|
+
const CONFIG_BACKED_FIELDS = new Set([
|
|
111
|
+
'org', 'server', 'env',
|
|
112
|
+
'provider', 'consumer', 'service',
|
|
113
|
+
'spec', 'contract', 'format', 'branch',
|
|
114
|
+
]);
|
|
115
|
+
|
|
95
116
|
/**
|
|
96
117
|
* Map a CLI option name to a path inside `.specshield.yml > bdct`.
|
|
97
|
-
* Returns
|
|
118
|
+
* Returns undefined when there is no defaulting rule for that option.
|
|
98
119
|
*/
|
|
99
120
|
function bdctDefaultFor(bdct, name, command) {
|
|
100
121
|
if (!bdct) return undefined;
|
|
@@ -181,14 +202,35 @@ function applyBdctDefaults(opts, command, { cwd = process.cwd() } = {}) {
|
|
|
181
202
|
const missing = required.filter(k => !opts[k]);
|
|
182
203
|
if (missing.length > 0) {
|
|
183
204
|
const flagFor = (k) => '--' + k.replace(/[A-Z]/g, m => '-' + m.toLowerCase());
|
|
205
|
+
const list = (ks) => ks.map(flagFor).join(', ');
|
|
206
|
+
|
|
207
|
+
// Split the advice: only fields the config can actually supply get pointed at
|
|
208
|
+
// `.specshield.yml`. The rest are flag-only and must say so, or the user edits
|
|
209
|
+
// the config, re-runs, and hits the same error with no idea why.
|
|
210
|
+
const configurable = missing.filter(k => CONFIG_BACKED_FIELDS.has(k));
|
|
211
|
+
const flagOnly = missing.filter(k => !CONFIG_BACKED_FIELDS.has(k));
|
|
212
|
+
|
|
184
213
|
const msg = [
|
|
185
214
|
`Missing required ${missing.length === 1 ? 'option' : 'options'} for \`bdct ${command}\`: `
|
|
186
|
-
+ missing
|
|
215
|
+
+ list(missing),
|
|
187
216
|
];
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
217
|
+
|
|
218
|
+
if (flagOnly.length > 0) {
|
|
219
|
+
msg.push(
|
|
220
|
+
` ${list(flagOnly)} must be passed as CLI ${flagOnly.length === 1 ? 'flag' : 'flags'} — ` +
|
|
221
|
+
`${flagOnly.length === 1 ? 'it has' : 'they have'} no \`.specshield.yml\` equivalent ` +
|
|
222
|
+
'(version values change per run).');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (configurable.length > 0) {
|
|
226
|
+
msg.push(cfg._file
|
|
227
|
+
? ` ${list(configurable)} can be passed as CLI flags or set under \`bdct\` in ${cfg._file}.`
|
|
228
|
+
: ` ${list(configurable)} can be passed as CLI flags, or run \`specshield init\` to write a \`.specshield.yml\`.`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (command === 'verify' && flagOnly.length > 0) {
|
|
232
|
+
msg.push(' e.g. specshield bdct verify --consumer <NAME> --provider <NAME> '
|
|
233
|
+
+ '--consumer-version <VER> --provider-version <VER>');
|
|
192
234
|
}
|
|
193
235
|
const err = new Error(msg.join('\n'));
|
|
194
236
|
err.code = 'MISSING_REQUIRED_OPTIONS';
|
|
@@ -205,4 +247,6 @@ module.exports = {
|
|
|
205
247
|
clearCache,
|
|
206
248
|
applyBdctDefaults,
|
|
207
249
|
REQUIRED_FIELDS,
|
|
250
|
+
CONFIG_BACKED_FIELDS,
|
|
251
|
+
bdctDefaultFor,
|
|
208
252
|
};
|