@thymian/common-cli 0.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.
- package/README.md +11 -0
- package/dist/base-cli-run-command.d.ts +81 -0
- package/dist/base-cli-run-command.d.ts.map +1 -0
- package/dist/base-cli-run-command.js +405 -0
- package/dist/base-cli-run-command.js.map +1 -0
- package/dist/default-config.d.ts +3 -0
- package/dist/default-config.d.ts.map +1 -0
- package/dist/default-config.js +27 -0
- package/dist/default-config.js.map +1 -0
- package/dist/error-cache.d.ts +31 -0
- package/dist/error-cache.d.ts.map +1 -0
- package/dist/error-cache.js +36 -0
- package/dist/error-cache.js.map +1 -0
- package/dist/feedback.d.ts +13 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +30 -0
- package/dist/feedback.js.map +1 -0
- package/dist/flags/filter-flag.d.ts +20 -0
- package/dist/flags/filter-flag.d.ts.map +1 -0
- package/dist/flags/filter-flag.js +63 -0
- package/dist/flags/filter-flag.js.map +1 -0
- package/dist/flags/option-flag.d.ts +39 -0
- package/dist/flags/option-flag.d.ts.map +1 -0
- package/dist/flags/option-flag.js +144 -0
- package/dist/flags/option-flag.js.map +1 -0
- package/dist/flags/rule-set-flag.d.ts +5 -0
- package/dist/flags/rule-set-flag.d.ts.map +1 -0
- package/dist/flags/rule-set-flag.js +9 -0
- package/dist/flags/rule-set-flag.js.map +1 -0
- package/dist/flags/spec-flag.d.ts +11 -0
- package/dist/flags/spec-flag.d.ts.map +1 -0
- package/dist/flags/spec-flag.js +25 -0
- package/dist/flags/spec-flag.js.map +1 -0
- package/dist/flags/traffic-flag.d.ts +10 -0
- package/dist/flags/traffic-flag.d.ts.map +1 -0
- package/dist/flags/traffic-flag.js +24 -0
- package/dist/flags/traffic-flag.js.map +1 -0
- package/dist/get-config.d.ts +20 -0
- package/dist/get-config.d.ts.map +1 -0
- package/dist/get-config.js +82 -0
- package/dist/get-config.js.map +1 -0
- package/dist/hooks/feedback-hook.d.ts +9 -0
- package/dist/hooks/feedback-hook.d.ts.map +1 -0
- package/dist/hooks/feedback-hook.js +2 -0
- package/dist/hooks/feedback-hook.js.map +1 -0
- package/dist/hooks/plugin-init-hook.d.ts +20 -0
- package/dist/hooks/plugin-init-hook.d.ts.map +1 -0
- package/dist/hooks/plugin-init-hook.js +2 -0
- package/dist/hooks/plugin-init-hook.js.map +1 -0
- package/dist/hooks/spec-search-hook.d.ts +18 -0
- package/dist/hooks/spec-search-hook.d.ts.map +1 -0
- package/dist/hooks/spec-search-hook.js +2 -0
- package/dist/hooks/spec-search-hook.js.map +1 -0
- package/dist/hooks/traffic-search-hook.d.ts +18 -0
- package/dist/hooks/traffic-search-hook.d.ts.map +1 -0
- package/dist/hooks/traffic-search-hook.js +2 -0
- package/dist/hooks/traffic-search-hook.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/merge-inputs.d.ts +34 -0
- package/dist/merge-inputs.d.ts.map +1 -0
- package/dist/merge-inputs.js +50 -0
- package/dist/merge-inputs.js.map +1 -0
- package/dist/oclif.d.ts +2 -0
- package/dist/oclif.d.ts.map +1 -0
- package/dist/oclif.js +2 -0
- package/dist/oclif.js.map +1 -0
- package/dist/promise-queue.d.ts +7 -0
- package/dist/promise-queue.d.ts.map +1 -0
- package/dist/promise-queue.js +24 -0
- package/dist/promise-queue.js.map +1 -0
- package/dist/prompts.d.ts +5 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +7 -0
- package/dist/prompts.js.map +1 -0
- package/dist/read-plugins.d.ts +2 -0
- package/dist/read-plugins.d.ts.map +1 -0
- package/dist/read-plugins.js +23 -0
- package/dist/read-plugins.js.map +1 -0
- package/dist/safe-parse.d.ts +2 -0
- package/dist/safe-parse.d.ts.map +1 -0
- package/dist/safe-parse.js +22 -0
- package/dist/safe-parse.js.map +1 -0
- package/dist/thymian-base-command.d.ts +21 -0
- package/dist/thymian-base-command.d.ts.map +1 -0
- package/dist/thymian-base-command.js +60 -0
- package/dist/thymian-base-command.js.map +1 -0
- package/dist/thymian-config-schema.d.ts +85 -0
- package/dist/thymian-config-schema.d.ts.map +1 -0
- package/dist/thymian-config-schema.js +79 -0
- package/dist/thymian-config-schema.js.map +1 -0
- package/dist/thymian-config-schema.json +116 -0
- package/dist/thymian-config.d.ts +19 -0
- package/dist/thymian-config.d.ts.map +1 -0
- package/dist/thymian-config.js +2 -0
- package/dist/thymian-config.js.map +1 -0
- package/dist/validate-config.d.ts +8 -0
- package/dist/validate-config.d.ts.map +1 -0
- package/dist/validate-config.js +18 -0
- package/dist/validate-config.js.map +1 -0
- package/dist/workflow-outcome.d.ts +5 -0
- package/dist/workflow-outcome.d.ts.map +1 -0
- package/dist/workflow-outcome.js +21 -0
- package/dist/workflow-outcome.js.map +1 -0
- package/dist/yaml.d.ts +2 -0
- package/dist/yaml.d.ts.map +1 -0
- package/dist/yaml.js +2 -0
- package/dist/yaml.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,qBAAa,QAAQ;IAKjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,MAAM,CAAS;gBAGrB,OAAO,EAAE,OAAO,EACC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;IAK1C,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAWpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,mBAAmB,IAAI,OAAO;IAI9B,MAAM,CAAC,UAAU,CACf,OAAO,EACH,kBAAkB,CAAC,OAAO,OAAO,CAAC,GAClC,iBAAiB,CAAC,OAAO,OAAO,CAAC,GACpC,QAAQ;CAMZ"}
|
package/dist/feedback.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class Feedback {
|
|
2
|
+
onRun;
|
|
3
|
+
wasRun = false;
|
|
4
|
+
constructor(initial, onRun) {
|
|
5
|
+
this.onRun = onRun;
|
|
6
|
+
this.wasRun = initial;
|
|
7
|
+
}
|
|
8
|
+
async run() {
|
|
9
|
+
if (this.wasRun) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (this.shouldPrintFeedback()) {
|
|
13
|
+
this.wasRun = true;
|
|
14
|
+
await this.onRun();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async error() {
|
|
18
|
+
if (!this.wasRun) {
|
|
19
|
+
await this.onRun();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// print the feedback hint in 20% of the cases
|
|
23
|
+
shouldPrintFeedback() {
|
|
24
|
+
return Math.random() < 0.2;
|
|
25
|
+
}
|
|
26
|
+
static forCommand(command) {
|
|
27
|
+
return new Feedback(command.jsonEnabled() || command.shouldSuppressFeedback(), () => command.config.runHook('thymian.feedback', {}));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,QAAQ;IAKA;IAJX,MAAM,GAAG,KAAK,CAAC;IAEvB,YACE,OAAgB,EACC,KAA6B;QAA7B,UAAK,GAAL,KAAK,CAAwB;QAE9C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,GAAG;QACP,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,mBAAmB;QACjB,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,UAAU,CACf,OAEqC;QAErC,OAAO,IAAI,QAAQ,CACjB,OAAO,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,sBAAsB,EAAE,EACzD,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CACrD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type HttpFilterExpression } from '@thymian/core';
|
|
2
|
+
export declare const filters: {
|
|
3
|
+
method: (method?: import("@thymian/core").HttpMethod) => import("@thymian/core").RequestFilterExpression;
|
|
4
|
+
statusCode: (value: string) => import("@thymian/core").ResponseFilterExpression;
|
|
5
|
+
responseHeader: (header?: import("@thymian/core").HttpHeader, value?: unknown) => import("@thymian/core").ResponseFilterExpression;
|
|
6
|
+
requestHeader: (header: import("@thymian/core").HttpHeader, value?: unknown) => import("@thymian/core").RequestFilterExpression;
|
|
7
|
+
path: (path?: string) => import("@thymian/core").RequestFilterExpression;
|
|
8
|
+
port: (value: string) => import("@thymian/core").RequestFilterExpression;
|
|
9
|
+
protocol: (value: string) => import("@thymian/core").RequestFilterExpression;
|
|
10
|
+
origin: (origin?: string) => import("@thymian/core").RequestFilterExpression;
|
|
11
|
+
authorization: (value: string) => import("@thymian/core").RequestFilterExpression;
|
|
12
|
+
responseMediaType: (mediaType: string) => import("@thymian/core").ResponseFilterExpression;
|
|
13
|
+
requestMediaType: (mediaType: string) => import("@thymian/core").RequestFilterExpression;
|
|
14
|
+
};
|
|
15
|
+
export declare function parseFilterExpression(input: string): HttpFilterExpression;
|
|
16
|
+
export declare const filterFlag: import("@oclif/core/interfaces").FlagDefinition<HttpFilterExpression, import("@oclif/core/interfaces").CustomOptions, {
|
|
17
|
+
multiple: true;
|
|
18
|
+
requiredOrDefaulted: false;
|
|
19
|
+
}>;
|
|
20
|
+
//# sourceMappingURL=filter-flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-flag.d.ts","sourceRoot":"","sources":["../../src/flags/filter-flag.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,oBAAoB,EAW1B,MAAM,eAAe,CAAC;AAevB,eAAO,MAAM,OAAO;;;;;;;;;;;;CA8B+C,CAAC;AAUpE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAoBzE;AAED,eAAO,MAAM,UAAU;;;EASrB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Errors, Flags } from '@oclif/core';
|
|
2
|
+
import { authorization, method, origin, path, port, protocol, requestHeader, requestMediaType, responseHeader, responseMediaType, statusCode, } from '@thymian/core';
|
|
3
|
+
const filterRegexp = /^(.*):(.*)$/;
|
|
4
|
+
function toNumberOrThrow(value) {
|
|
5
|
+
const code = Number(value);
|
|
6
|
+
if (isNaN(code)) {
|
|
7
|
+
throw new Errors.CLIError(`Invalid status code: ${value}. Must be a number.`);
|
|
8
|
+
}
|
|
9
|
+
return code;
|
|
10
|
+
}
|
|
11
|
+
export const filters = {
|
|
12
|
+
method,
|
|
13
|
+
statusCode: (value) => statusCode(toNumberOrThrow(value)),
|
|
14
|
+
responseHeader,
|
|
15
|
+
requestHeader,
|
|
16
|
+
path,
|
|
17
|
+
port: (value) => port(toNumberOrThrow(value)),
|
|
18
|
+
protocol: (value) => {
|
|
19
|
+
if (value !== 'http' && value !== 'https') {
|
|
20
|
+
throw new Errors.CLIError(`Protocol must be either 'http' or 'https', got: ${value}`);
|
|
21
|
+
}
|
|
22
|
+
return protocol(value);
|
|
23
|
+
},
|
|
24
|
+
origin,
|
|
25
|
+
authorization: (value) => {
|
|
26
|
+
if (value === 'true') {
|
|
27
|
+
return authorization(true);
|
|
28
|
+
}
|
|
29
|
+
if (value === 'false') {
|
|
30
|
+
return authorization(false);
|
|
31
|
+
}
|
|
32
|
+
throw new Errors.CLIError(`Authorization must be either 'true' or 'false', got: ${value}`);
|
|
33
|
+
},
|
|
34
|
+
responseMediaType,
|
|
35
|
+
requestMediaType,
|
|
36
|
+
};
|
|
37
|
+
const availableFilters = Object.keys(filters);
|
|
38
|
+
function isAvailableFilter(name) {
|
|
39
|
+
return availableFilters.includes(name);
|
|
40
|
+
}
|
|
41
|
+
export function parseFilterExpression(input) {
|
|
42
|
+
if (!filterRegexp.test(input)) {
|
|
43
|
+
throw new Errors.CLIError(`Invalid filter: ${input}. Use format <filter>:<value>.`);
|
|
44
|
+
}
|
|
45
|
+
const [filter, ...values] = input.split(':');
|
|
46
|
+
if (typeof filter === 'undefined') {
|
|
47
|
+
throw new Errors.CLIError(`Filter cannot be undefined.`);
|
|
48
|
+
}
|
|
49
|
+
if (!isAvailableFilter(filter)) {
|
|
50
|
+
throw new Errors.CLIError(`Unknown filter: ${filter}. Available filters: ${availableFilters.join(', ')}.`);
|
|
51
|
+
}
|
|
52
|
+
return filters[filter](values.join(':'));
|
|
53
|
+
}
|
|
54
|
+
export const filterFlag = Flags.custom({
|
|
55
|
+
description: 'Filter transactions by properties. Use multiple times for AND. Available filters: ' +
|
|
56
|
+
availableFilters.join(''),
|
|
57
|
+
multiple: true,
|
|
58
|
+
helpValue: 'filter:value',
|
|
59
|
+
charAliases: ['f'],
|
|
60
|
+
helpGroup: 'BASE',
|
|
61
|
+
parse: async (input) => parseFilterExpression(input),
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=filter-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-flag.js","sourceRoot":"","sources":["../../src/flags/filter-flag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface PluginOptionOverride {
|
|
2
|
+
pluginName: string;
|
|
3
|
+
path: (string | number)[];
|
|
4
|
+
value: unknown;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Parse a single `-o` flag value into a structured override.
|
|
8
|
+
*
|
|
9
|
+
* Format: `<pluginName>.<property.path[index]...>=<value>`
|
|
10
|
+
*
|
|
11
|
+
* The plugin name may be scoped (`@scope/name`). The first `.` after
|
|
12
|
+
* the plugin name separates it from the property path. The property
|
|
13
|
+
* path supports arbitrarily deep nesting via dot notation and bracket
|
|
14
|
+
* array indexing, following the Helm `--set` convention:
|
|
15
|
+
*
|
|
16
|
+
* @thymian/plugin-reporter.formatters.text.summaryOnly=true
|
|
17
|
+
* @thymian/plugin-sampler.items[0].name=Authorization
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseOptionFlag(input: string): PluginOptionOverride;
|
|
20
|
+
/**
|
|
21
|
+
* Parse a dotted property path that may contain bracket-based array
|
|
22
|
+
* indices into an array of string keys and numeric indices.
|
|
23
|
+
*
|
|
24
|
+
* Examples:
|
|
25
|
+
* `formatters.text.summaryOnly` → ['formatters', 'text', 'summaryOnly']
|
|
26
|
+
* `items[0].name` → ['items', 0, 'name']
|
|
27
|
+
* `a[1][2].b` → ['a', 1, 2, 'b']
|
|
28
|
+
*/
|
|
29
|
+
export declare function parsePropertyPath(path: string): (string | number)[];
|
|
30
|
+
/**
|
|
31
|
+
* Set a deeply nested value on an object, creating intermediate objects
|
|
32
|
+
* or arrays as needed based on the path segments.
|
|
33
|
+
*/
|
|
34
|
+
export declare function deepSet(obj: Record<string, unknown>, path: (string | number)[], value: unknown): void;
|
|
35
|
+
export declare const optionFlag: import("@oclif/core/interfaces").FlagDefinition<PluginOptionOverride, import("@oclif/core/interfaces").CustomOptions, {
|
|
36
|
+
multiple: true;
|
|
37
|
+
requiredOrDefaulted: false;
|
|
38
|
+
}>;
|
|
39
|
+
//# sourceMappingURL=option-flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"option-flag.d.ts","sourceRoot":"","sources":["../../src/flags/option-flag.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAwBnE;AA8CD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CA0CnE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,KAAK,EAAE,OAAO,GACb,IAAI,CAiBN;AAED,eAAO,MAAM,UAAU;;;EASrB,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Errors, Flags } from '@oclif/core';
|
|
2
|
+
import { safeParse } from '../safe-parse.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parse a single `-o` flag value into a structured override.
|
|
5
|
+
*
|
|
6
|
+
* Format: `<pluginName>.<property.path[index]...>=<value>`
|
|
7
|
+
*
|
|
8
|
+
* The plugin name may be scoped (`@scope/name`). The first `.` after
|
|
9
|
+
* the plugin name separates it from the property path. The property
|
|
10
|
+
* path supports arbitrarily deep nesting via dot notation and bracket
|
|
11
|
+
* array indexing, following the Helm `--set` convention:
|
|
12
|
+
*
|
|
13
|
+
* @thymian/plugin-reporter.formatters.text.summaryOnly=true
|
|
14
|
+
* @thymian/plugin-sampler.items[0].name=Authorization
|
|
15
|
+
*/
|
|
16
|
+
export function parseOptionFlag(input) {
|
|
17
|
+
const eqIdx = input.indexOf('=');
|
|
18
|
+
if (eqIdx === -1) {
|
|
19
|
+
throw new Errors.CLIError(`Invalid option format: "${input}". Expected <pluginName>.<property>=<value>.`);
|
|
20
|
+
}
|
|
21
|
+
const fullKey = input.slice(0, eqIdx);
|
|
22
|
+
const rawValue = input.slice(eqIdx + 1);
|
|
23
|
+
const { pluginName, propertyPath } = splitPluginNameAndPath(fullKey);
|
|
24
|
+
if (!pluginName || propertyPath.length === 0) {
|
|
25
|
+
throw new Errors.CLIError(`Invalid option format: "${input}". Expected <pluginName>.<property>=<value>.`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
pluginName,
|
|
29
|
+
path: propertyPath,
|
|
30
|
+
value: safeParse(rawValue),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Split a full key like `@thymian/plugin-reporter.formatters.text.path` into
|
|
35
|
+
* the plugin name (`@thymian/plugin-reporter`) and the property path segments
|
|
36
|
+
* (`['formatters', 'text', 'path']`).
|
|
37
|
+
*
|
|
38
|
+
* Scoped packages (`@scope/name`) are handled: the plugin name extends
|
|
39
|
+
* up to and including the segment that contains a `/`.
|
|
40
|
+
*/
|
|
41
|
+
function splitPluginNameAndPath(fullKey) {
|
|
42
|
+
const firstDot = fullKey.indexOf('.');
|
|
43
|
+
if (firstDot === -1) {
|
|
44
|
+
return { pluginName: fullKey, propertyPath: [] };
|
|
45
|
+
}
|
|
46
|
+
// For scoped packages (@scope/name), the plugin name extends past the
|
|
47
|
+
// first dot when the portion before the first dot starts with '@' and
|
|
48
|
+
// does not yet contain a '/'.
|
|
49
|
+
let pluginName;
|
|
50
|
+
let rest;
|
|
51
|
+
const beforeDot = fullKey.slice(0, firstDot);
|
|
52
|
+
if (beforeDot.startsWith('@') && !beforeDot.includes('/')) {
|
|
53
|
+
// Scoped: `@scope` — need to find the next `.` after the `/`
|
|
54
|
+
const slashIdx = fullKey.indexOf('/');
|
|
55
|
+
if (slashIdx === -1) {
|
|
56
|
+
return { pluginName: fullKey, propertyPath: [] };
|
|
57
|
+
}
|
|
58
|
+
const dotAfterSlash = fullKey.indexOf('.', slashIdx);
|
|
59
|
+
if (dotAfterSlash === -1) {
|
|
60
|
+
return { pluginName: fullKey, propertyPath: [] };
|
|
61
|
+
}
|
|
62
|
+
pluginName = fullKey.slice(0, dotAfterSlash);
|
|
63
|
+
rest = fullKey.slice(dotAfterSlash + 1);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
pluginName = beforeDot;
|
|
67
|
+
rest = fullKey.slice(firstDot + 1);
|
|
68
|
+
}
|
|
69
|
+
return { pluginName, propertyPath: parsePropertyPath(rest) };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse a dotted property path that may contain bracket-based array
|
|
73
|
+
* indices into an array of string keys and numeric indices.
|
|
74
|
+
*
|
|
75
|
+
* Examples:
|
|
76
|
+
* `formatters.text.summaryOnly` → ['formatters', 'text', 'summaryOnly']
|
|
77
|
+
* `items[0].name` → ['items', 0, 'name']
|
|
78
|
+
* `a[1][2].b` → ['a', 1, 2, 'b']
|
|
79
|
+
*/
|
|
80
|
+
export function parsePropertyPath(path) {
|
|
81
|
+
const segments = [];
|
|
82
|
+
let current = '';
|
|
83
|
+
for (let i = 0; i < path.length; i++) {
|
|
84
|
+
const ch = path[i];
|
|
85
|
+
if (ch === '.') {
|
|
86
|
+
if (current) {
|
|
87
|
+
segments.push(current);
|
|
88
|
+
current = '';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (ch === '[') {
|
|
92
|
+
if (current) {
|
|
93
|
+
segments.push(current);
|
|
94
|
+
current = '';
|
|
95
|
+
}
|
|
96
|
+
const closeBracket = path.indexOf(']', i + 1);
|
|
97
|
+
if (closeBracket === -1) {
|
|
98
|
+
throw new Errors.CLIError(`Invalid property path: "${path}". Unclosed bracket at position ${i}.`);
|
|
99
|
+
}
|
|
100
|
+
const indexStr = path.slice(i + 1, closeBracket);
|
|
101
|
+
const index = Number(indexStr);
|
|
102
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
103
|
+
throw new Errors.CLIError(`Invalid array index "[${indexStr}]" in property path: "${path}". Array indices must be non-negative integers.`);
|
|
104
|
+
}
|
|
105
|
+
segments.push(index);
|
|
106
|
+
i = closeBracket;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
current += ch;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (current) {
|
|
113
|
+
segments.push(current);
|
|
114
|
+
}
|
|
115
|
+
return segments;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Set a deeply nested value on an object, creating intermediate objects
|
|
119
|
+
* or arrays as needed based on the path segments.
|
|
120
|
+
*/
|
|
121
|
+
export function deepSet(obj, path, value) {
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
123
|
+
let current = obj;
|
|
124
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
125
|
+
const segment = path[i];
|
|
126
|
+
const nextSegment = path[i + 1];
|
|
127
|
+
if (current[segment] === undefined || current[segment] === null) {
|
|
128
|
+
current[segment] = typeof nextSegment === 'number' ? [] : {};
|
|
129
|
+
}
|
|
130
|
+
current = current[segment];
|
|
131
|
+
}
|
|
132
|
+
const lastSegment = path[path.length - 1];
|
|
133
|
+
current[lastSegment] = value;
|
|
134
|
+
}
|
|
135
|
+
export const optionFlag = Flags.custom({
|
|
136
|
+
description: 'Override plugin options. Format: <pluginName>.<property.path>=<value>. ' +
|
|
137
|
+
'Supports nested paths (dot notation) and array indices (bracket notation).',
|
|
138
|
+
multiple: true,
|
|
139
|
+
helpValue: '<plugin>.<path>=<value>',
|
|
140
|
+
charAliases: ['o'],
|
|
141
|
+
helpGroup: 'BASE',
|
|
142
|
+
parse: async (input) => parseOptionFlag(input),
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=option-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"option-flag.js","sourceRoot":"","sources":["../../src/flags/option-flag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-flag.d.ts","sourceRoot":"","sources":["../../src/flags/rule-set-flag.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;EAOtB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
export const ruleSetFlag = Flags.custom({
|
|
3
|
+
description: 'Add a rule set package to use for validation (e.g. @thymian/rules-rfc-9110). Can be specified multiple times.',
|
|
4
|
+
multiple: true,
|
|
5
|
+
helpValue: 'package-name',
|
|
6
|
+
helpGroup: 'BASE',
|
|
7
|
+
parse: async (input) => input,
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=rule-set-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-flag.js","sourceRoot":"","sources":["../../src/flags/rule-set-flag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAS;IAC9C,WAAW,EACT,+GAA+G;IACjH,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,MAAM;IACjB,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK;CAC9B,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SpecificationInput } from '@thymian/core';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a `--spec` flag value of the format `<type>:<location>` into a SpecificationInput.
|
|
4
|
+
* Both type and location are required.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseSpecFlag(input: string): SpecificationInput;
|
|
7
|
+
export declare const specFlag: import("@oclif/core/interfaces").FlagDefinition<SpecificationInput, import("@oclif/core/interfaces").CustomOptions, {
|
|
8
|
+
multiple: true;
|
|
9
|
+
requiredOrDefaulted: false;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=spec-flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-flag.d.ts","sourceRoot":"","sources":["../../src/flags/spec-flag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAmB/D;AAED,eAAO,MAAM,QAAQ;;;EAOnB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Errors, Flags } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a `--spec` flag value of the format `<type>:<location>` into a SpecificationInput.
|
|
4
|
+
* Both type and location are required.
|
|
5
|
+
*/
|
|
6
|
+
export function parseSpecFlag(input) {
|
|
7
|
+
const colonIndex = input.indexOf(':');
|
|
8
|
+
if (colonIndex === -1) {
|
|
9
|
+
throw new Errors.CLIError(`Invalid --spec format: "${input}". Expected format: <type>:<location> (e.g. openapi:./openapi.yaml).`);
|
|
10
|
+
}
|
|
11
|
+
const type = input.slice(0, colonIndex);
|
|
12
|
+
const location = input.slice(colonIndex + 1);
|
|
13
|
+
if (!type || !location) {
|
|
14
|
+
throw new Errors.CLIError(`Invalid --spec format: "${input}". Expected format: <type>:<location> (e.g. openapi:./openapi.yaml).`);
|
|
15
|
+
}
|
|
16
|
+
return { type, location };
|
|
17
|
+
}
|
|
18
|
+
export const specFlag = Flags.custom({
|
|
19
|
+
description: 'Specification input in the format <type>:<location> (e.g. openapi:./openapi.yaml).',
|
|
20
|
+
multiple: true,
|
|
21
|
+
helpValue: 'type:location',
|
|
22
|
+
helpGroup: 'BASE',
|
|
23
|
+
parse: async (input) => parseSpecFlag(input),
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=spec-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-flag.js","sourceRoot":"","sources":["../../src/flags/spec-flag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAG5C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,MAAM,CAAC,QAAQ,CACvB,2BAA2B,KAAK,sEAAsE,CACvG,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,MAAM,CAAC,QAAQ,CACvB,2BAA2B,KAAK,sEAAsE,CACvG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAqB;IACvD,WAAW,EACT,oFAAoF;IACtF,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,eAAe;IAC1B,SAAS,EAAE,MAAM;IACjB,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC;CAC7C,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TrafficInput } from '@thymian/core';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a `--traffic` flag value of the format `<type>:<location>` into a TrafficInput.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseTrafficFlag(input: string): TrafficInput;
|
|
6
|
+
export declare const trafficFlag: import("@oclif/core/interfaces").FlagDefinition<TrafficInput, import("@oclif/core/interfaces").CustomOptions, {
|
|
7
|
+
multiple: true;
|
|
8
|
+
requiredOrDefaulted: false;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=traffic-flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traffic-flag.d.ts","sourceRoot":"","sources":["../../src/flags/traffic-flag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAmB5D;AAED,eAAO,MAAM,WAAW;;;EAOtB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Errors, Flags } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a `--traffic` flag value of the format `<type>:<location>` into a TrafficInput.
|
|
4
|
+
*/
|
|
5
|
+
export function parseTrafficFlag(input) {
|
|
6
|
+
const colonIndex = input.indexOf(':');
|
|
7
|
+
if (colonIndex === -1) {
|
|
8
|
+
throw new Errors.CLIError(`Invalid --traffic format: "${input}". Expected format: <type>:<location> (e.g. har:./traffic.har).`);
|
|
9
|
+
}
|
|
10
|
+
const type = input.slice(0, colonIndex);
|
|
11
|
+
const location = input.slice(colonIndex + 1);
|
|
12
|
+
if (!type || !location) {
|
|
13
|
+
throw new Errors.CLIError(`Invalid --traffic format: "${input}". Expected format: <type>:<location> (e.g. har:./traffic.har).`);
|
|
14
|
+
}
|
|
15
|
+
return { type, location };
|
|
16
|
+
}
|
|
17
|
+
export const trafficFlag = Flags.custom({
|
|
18
|
+
description: 'Traffic input in the format <type>:<location> (e.g. har:./traffic.har).',
|
|
19
|
+
multiple: true,
|
|
20
|
+
helpValue: 'type:location',
|
|
21
|
+
helpGroup: 'BASE',
|
|
22
|
+
parse: async (input) => parseTrafficFlag(input),
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=traffic-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traffic-flag.js","sourceRoot":"","sources":["../../src/flags/traffic-flag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAG5C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,MAAM,CAAC,QAAQ,CACvB,8BAA8B,KAAK,iEAAiE,CACrG,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,MAAM,CAAC,QAAQ,CACvB,8BAA8B,KAAK,iEAAiE,CACrG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAe;IACpD,WAAW,EACT,yEAAyE;IAC3E,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,eAAe;IAC1B,SAAS,EAAE,MAAM;IACjB,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC;CAChD,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ThymianConfig } from './thymian-config.js';
|
|
2
|
+
export interface GetConfigOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Explicit config file path provided via `--config` flag.
|
|
5
|
+
* When set, the file MUST exist — a missing file is a hard error (exit 2).
|
|
6
|
+
*/
|
|
7
|
+
configPath?: string;
|
|
8
|
+
/** Working directory for file resolution. Defaults to `process.cwd()`. */
|
|
9
|
+
cwd?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolve and load a Thymian configuration.
|
|
13
|
+
*
|
|
14
|
+
* Resolution chain:
|
|
15
|
+
* 1. If `configPath` is given (explicit `--config`), load that file or error.
|
|
16
|
+
* 2. Otherwise probe cwd for well-known config file names.
|
|
17
|
+
* 3. If no file is found, return `defaultConfig`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getConfig(options?: GetConfigOptions): Promise<ThymianConfig>;
|
|
20
|
+
//# sourceMappingURL=get-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-config.d.ts","sourceRoot":"","sources":["../src/get-config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,aAAa,CAAC,CA2BxB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { parse } from 'yaml';
|
|
5
|
+
import { defaultConfig } from './default-config.js';
|
|
6
|
+
import { validateConfig } from './validate-config.js';
|
|
7
|
+
/** Well-known config file names checked in order when no explicit `--config` is given. */
|
|
8
|
+
const DEFAULT_CONFIG_NAMES = ['thymian.config.yaml'];
|
|
9
|
+
/**
|
|
10
|
+
* Resolve and load a Thymian configuration.
|
|
11
|
+
*
|
|
12
|
+
* Resolution chain:
|
|
13
|
+
* 1. If `configPath` is given (explicit `--config`), load that file or error.
|
|
14
|
+
* 2. Otherwise probe cwd for well-known config file names.
|
|
15
|
+
* 3. If no file is found, return `defaultConfig`.
|
|
16
|
+
*/
|
|
17
|
+
export async function getConfig(options = {}) {
|
|
18
|
+
const cwd = options.cwd ?? process.cwd();
|
|
19
|
+
// Step A: explicit --config path
|
|
20
|
+
if (options.configPath) {
|
|
21
|
+
const fullPath = path.isAbsolute(options.configPath)
|
|
22
|
+
? options.configPath
|
|
23
|
+
: path.join(cwd, options.configPath);
|
|
24
|
+
if (!existsSync(fullPath)) {
|
|
25
|
+
console.error(`Config not found at ${fullPath}.`);
|
|
26
|
+
process.exit(2);
|
|
27
|
+
}
|
|
28
|
+
return loadAndValidate(fullPath);
|
|
29
|
+
}
|
|
30
|
+
// Step B: probe well-known config file names in cwd
|
|
31
|
+
for (const name of DEFAULT_CONFIG_NAMES) {
|
|
32
|
+
const fullPath = path.join(cwd, name);
|
|
33
|
+
if (existsSync(fullPath)) {
|
|
34
|
+
return loadAndValidate(fullPath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Step B fallback: no config file found — use built-in defaults
|
|
38
|
+
return defaultConfig;
|
|
39
|
+
}
|
|
40
|
+
async function loadAndValidate(fullPath) {
|
|
41
|
+
try {
|
|
42
|
+
const fileContent = await fs.readFile(fullPath, 'utf-8');
|
|
43
|
+
const { ext } = path.parse(fullPath);
|
|
44
|
+
let config;
|
|
45
|
+
if (ext === '.json') {
|
|
46
|
+
try {
|
|
47
|
+
config = JSON.parse(fileContent);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw new Error(`Invalid JSON file at path ${fullPath}.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (ext === '.yaml' || ext === '.yml') {
|
|
54
|
+
try {
|
|
55
|
+
config = parse(fileContent);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new Error(`Invalid yaml file at path ${fullPath}.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
throw new Error(`Unsupported file extension "${ext}" for Thymian configuration.`);
|
|
63
|
+
}
|
|
64
|
+
const validationResult = validateConfig(config);
|
|
65
|
+
if (!validationResult.valid) {
|
|
66
|
+
throw new Error(`Invalid Thymian config`, {
|
|
67
|
+
cause: validationResult.message,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return config;
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
if (e instanceof Error) {
|
|
74
|
+
console.error(`Cannot run Thymian CLI because of: ${e.message}`);
|
|
75
|
+
if (e.cause) {
|
|
76
|
+
console.error(e.cause);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
process.exit(2);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=get-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-config.js","sourceRoot":"","sources":["../src/get-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/feedback-hook.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,KAAK;QACb,kBAAkB,EAAE;YAClB,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;SACvC,CAAC;KACH;CACF;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-hook.js","sourceRoot":"","sources":["../../src/hooks/feedback-hook.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ThymianPluginConfiguration } from '../thymian-config.js';
|
|
2
|
+
declare module '@oclif/core/interfaces' {
|
|
3
|
+
interface Hooks {
|
|
4
|
+
'thymian-plugin.init': {
|
|
5
|
+
options: ThymianPluginInitOptions;
|
|
6
|
+
return: ThymianPluginInitResult;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export type ThymianPluginInitOptions = {
|
|
11
|
+
cwd: string;
|
|
12
|
+
interactive: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type ThymianPluginInitResult<T extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>> = {
|
|
15
|
+
pluginName: string;
|
|
16
|
+
configuration: ThymianPluginConfiguration<T>;
|
|
17
|
+
include: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type ThymianPluginInitHook<T extends Record<PropertyKey, unknown> = Record<PropertyKey, unknown>> = (options: ThymianPluginInitOptions) => Promise<ThymianPluginInitResult<T>>;
|
|
20
|
+
//# sourceMappingURL=plugin-init-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-init-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/plugin-init-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,KAAK;QACb,qBAAqB,EAAE;YACrB,OAAO,EAAE,wBAAwB,CAAC;YAClC,MAAM,EAAE,uBAAuB,CAAC;SACjC,CAAC;KACH;CACF;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,uBAAuB,CACjC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IACnE;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,IACnE,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-init-hook.js","sourceRoot":"","sources":["../../src/hooks/plugin-init-hook.ts"],"names":[],"mappings":""}
|