@openapi-qraft/plugin 2.3.2 → 2.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/lib/QraftCommand.d.ts +10 -3
  3. package/dist/lib/QraftCommand.d.ts.map +1 -1
  4. package/dist/lib/QraftCommand.js +83 -21
  5. package/dist/lib/QraftCommand.js.map +1 -1
  6. package/dist/lib/RedoclyConfigCommand.d.ts +22 -0
  7. package/dist/lib/RedoclyConfigCommand.d.ts.map +1 -0
  8. package/dist/lib/RedoclyConfigCommand.js +127 -0
  9. package/dist/lib/RedoclyConfigCommand.js.map +1 -0
  10. package/dist/lib/getRedocAPIsToQraft.d.ts +15 -0
  11. package/dist/lib/getRedocAPIsToQraft.d.ts.map +1 -0
  12. package/dist/lib/getRedocAPIsToQraft.js +45 -0
  13. package/dist/lib/getRedocAPIsToQraft.js.map +1 -0
  14. package/dist/lib/handleSchemaInput.js +1 -1
  15. package/dist/lib/loadRedoclyConfig.d.ts +12 -0
  16. package/dist/lib/loadRedoclyConfig.d.ts.map +1 -0
  17. package/dist/lib/loadRedoclyConfig.js +17 -0
  18. package/dist/lib/loadRedoclyConfig.js.map +1 -0
  19. package/dist/lib/maybeEscapeShellArg.d.ts +2 -0
  20. package/dist/lib/maybeEscapeShellArg.d.ts.map +1 -0
  21. package/dist/lib/maybeEscapeShellArg.js +9 -0
  22. package/dist/lib/maybeEscapeShellArg.js.map +1 -0
  23. package/dist/lib/open-api/readSchema.d.ts +2 -1
  24. package/dist/lib/open-api/readSchema.d.ts.map +1 -1
  25. package/dist/lib/open-api/readSchema.js +1 -7
  26. package/dist/lib/open-api/readSchema.js.map +1 -1
  27. package/dist/lib/parseConfigToArgs.d.ts +7 -0
  28. package/dist/lib/parseConfigToArgs.d.ts.map +1 -0
  29. package/dist/lib/parseConfigToArgs.js +130 -0
  30. package/dist/lib/parseConfigToArgs.js.map +1 -0
  31. package/dist/lib/shouldQuoteCommandLineArg.d.ts +11 -0
  32. package/dist/lib/shouldQuoteCommandLineArg.d.ts.map +1 -0
  33. package/dist/lib/shouldQuoteCommandLineArg.js +33 -0
  34. package/dist/lib/shouldQuoteCommandLineArg.js.map +1 -0
  35. package/dist/packageVersion.d.ts +1 -1
  36. package/dist/packageVersion.js +1 -1
  37. package/package.json +2 -2
  38. package/src/lib/QraftCommand.ts +139 -28
  39. package/src/lib/RedoclyConfigCommand.ts +221 -0
  40. package/src/lib/getRedocAPIsToQraft.ts +87 -0
  41. package/src/lib/handleSchemaInput.ts +1 -1
  42. package/src/lib/loadRedoclyConfig.ts +47 -0
  43. package/src/lib/maybeEscapeShellArg.ts +10 -0
  44. package/src/lib/open-api/readSchema.ts +3 -11
  45. package/src/lib/parseConfigToArgs.ts +134 -0
  46. package/src/lib/shouldQuoteCommandLineArg.ts +32 -0
  47. package/src/packageVersion.ts +1 -1
@@ -1,11 +1,5 @@
1
- import { createConfig } from '@redocly/openapi-core';
2
1
  import { validateAndBundle } from 'openapi-typescript/dist/lib/redoc.js';
3
- export const readSchema = async (source) => {
4
- const redoc = await createConfig({
5
- rules: {
6
- 'operation-operationId-unique': { severity: 'error' }, // throw error on duplicate operationIDs
7
- },
8
- }, { extends: ['minimal'] });
2
+ export const readSchema = async (source, redoc) => {
9
3
  const parsed = await validateAndBundle(source, {
10
4
  redoc,
11
5
  silent: false,
@@ -1 +1 @@
1
- {"version":3,"file":"readSchema.js","sourceRoot":"","sources":["../../../src/lib/open-api/readSchema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAmD,EACnD,EAAE;IACF,MAAM,KAAK,GAAG,MAAM,YAAY,CAC9B;QACE,KAAK,EAAE;YACL,8BAA8B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,wCAAwC;SAChG;KACF,EACD,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE,CACzB,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE;QAC7C,KAAK;QACL,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,OAAO,MAAkB,CAAC;AAC5B,CAAC,CAAC"}
1
+ {"version":3,"file":"readSchema.js","sourceRoot":"","sources":["../../../src/lib/open-api/readSchema.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAmD,EACnD,KAAa,EACb,EAAE;IACF,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE;QAC7C,KAAK;QACL,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,OAAO,MAAkB,CAAC;AAC5B,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Converts a parsed YAML configuration into command line arguments
3
+ * @param config The parsed YAML configuration object
4
+ * @returns Array of command line arguments
5
+ */
6
+ export declare function parseConfigToArgs(config: Record<string, unknown>): string[];
7
+ //# sourceMappingURL=parseConfigToArgs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseConfigToArgs.d.ts","sourceRoot":"","sources":["../../src/lib/parseConfigToArgs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAgI3E"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Converts a parsed YAML configuration into command line arguments
3
+ * @param config The parsed YAML configuration object
4
+ * @returns Array of command line arguments
5
+ */
6
+ export function parseConfigToArgs(config) {
7
+ const args = [];
8
+ const isPrimitive = (val) => typeof val === 'string' ||
9
+ typeof val === 'number' ||
10
+ typeof val === 'boolean';
11
+ function flattenMapping(node, prefixKeys) {
12
+ const results = [];
13
+ if (isPrimitive(node)) {
14
+ if (typeof node === 'boolean') {
15
+ if (node) {
16
+ results.push(prefixKeys.join(':'));
17
+ }
18
+ }
19
+ else {
20
+ results.push(`${prefixKeys.join(':')}:${node.toString()}`);
21
+ }
22
+ return results;
23
+ }
24
+ if (Array.isArray(node)) {
25
+ if (node.every((el) => isPrimitive(el))) {
26
+ const primitives = node.filter((el) => el !== null && el !== undefined);
27
+ const joined = primitives.map((el) => el.toString()).join(',');
28
+ if (joined) {
29
+ results.push(`${prefixKeys.join(':')}:${joined}`);
30
+ }
31
+ return results;
32
+ }
33
+ for (const el of node) {
34
+ if (el == null) {
35
+ continue;
36
+ }
37
+ results.push(...flattenMapping(el, prefixKeys));
38
+ }
39
+ return results;
40
+ }
41
+ if (typeof node === 'object' && node !== null) {
42
+ for (const [key, value] of Object.entries(node)) {
43
+ results.push(...flattenMapping(value, [...prefixKeys, key]));
44
+ }
45
+ return results;
46
+ }
47
+ return results;
48
+ }
49
+ for (const [key, value] of Object.entries(config)) {
50
+ if (typeof value === 'string' || typeof value === 'number') {
51
+ args.push(`--${key}`, value.toString());
52
+ }
53
+ else if (typeof value === 'boolean') {
54
+ if (value) {
55
+ args.push(`--${key}`);
56
+ }
57
+ }
58
+ else if (value == null) {
59
+ continue;
60
+ }
61
+ else if (Array.isArray(value)) {
62
+ if (value.every((el) => isPrimitive(el))) {
63
+ const primitives = value.filter((el) => el !== null && el !== undefined);
64
+ args.push(`--${key}`, ...primitives.map((el) => el.toString()));
65
+ }
66
+ else {
67
+ for (const el of value) {
68
+ if (el == null) {
69
+ continue;
70
+ }
71
+ if (typeof el === 'object') {
72
+ const mappingPaths = flattenMapping(el, []);
73
+ if (mappingPaths.length) {
74
+ args.push(`--${key}`, ...mappingPaths);
75
+ }
76
+ }
77
+ else if (isPrimitive(el)) {
78
+ args.push(`--${key}`, el.toString());
79
+ }
80
+ }
81
+ }
82
+ }
83
+ else if (typeof value === 'object') {
84
+ for (const [childKey, childValue] of Object.entries(value)) {
85
+ if (typeof childValue === 'string' || typeof childValue === 'number') {
86
+ args.push(`--${key}`, childKey, childValue.toString());
87
+ }
88
+ else if (typeof childValue === 'boolean') {
89
+ if (childValue) {
90
+ args.push(`--${key}`, childKey);
91
+ }
92
+ }
93
+ else if (childValue == null) {
94
+ continue;
95
+ }
96
+ else if (Array.isArray(childValue)) {
97
+ if (childValue.every((el) => isPrimitive(el))) {
98
+ const primitives = childValue.filter((el) => el !== null && el !== undefined);
99
+ const joined = primitives.map((el) => el.toString()).join(',');
100
+ args.push(`--${key}`, childKey, joined);
101
+ }
102
+ else {
103
+ for (const el of childValue) {
104
+ if (el == null) {
105
+ continue;
106
+ }
107
+ if (typeof el === 'object') {
108
+ const mappingPaths = flattenMapping(el, [childKey]);
109
+ if (mappingPaths.length) {
110
+ args.push(`--${key}`, ...mappingPaths);
111
+ }
112
+ }
113
+ else if (isPrimitive(el)) {
114
+ args.push(`--${key}`, childKey, el.toString());
115
+ }
116
+ }
117
+ }
118
+ }
119
+ else if (typeof childValue === 'object') {
120
+ const mappingPaths = flattenMapping(childValue, []);
121
+ if (mappingPaths.length) {
122
+ args.push(`--${key}`, childKey, ...mappingPaths);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return args;
129
+ }
130
+ //# sourceMappingURL=parseConfigToArgs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseConfigToArgs.js","sourceRoot":"","sources":["../../src/lib/parseConfigToArgs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAoC,EAAE,CACjE,OAAO,GAAG,KAAK,QAAQ;QACvB,OAAO,GAAG,KAAK,QAAQ;QACvB,OAAO,GAAG,KAAK,SAAS,CAAC;IAE3B,SAAS,cAAc,CAAC,IAAS,EAAE,UAAoB;QACrD,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,OAAO,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,IAAI,EAAE,CAAC;oBACT,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACxC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAC5B,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,CACP,CAAC;gBACnC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC/D,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC;YAED,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;gBACtB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;oBACf,SAAS;gBACX,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC3D,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,SAAS;QACX,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,CACP,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;oBACvB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;wBACf,SAAS;oBACX,CAAC;oBACD,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;wBAC3B,MAAM,YAAY,GAAG,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC5C,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;4BACxB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC;wBACzC,CAAC;oBACH,CAAC;yBAAM,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CACjD,KAAgC,CACjC,EAAE,CAAC;gBACF,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACrE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACzD,CAAC;qBAAM,IAAI,OAAO,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC3C,IAAI,UAAU,EAAE,CAAC;wBACf,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;oBAClC,CAAC;gBACH,CAAC;qBAAM,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;oBAC9B,SAAS;gBACX,CAAC;qBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;oBACrC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;wBAC9C,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAClC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,CACP,CAAC;wBACnC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAC/D,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;oBAC1C,CAAC;yBAAM,CAAC;wBACN,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;4BAC5B,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;gCACf,SAAS;4BACX,CAAC;4BACD,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gCAC3B,MAAM,YAAY,GAAG,cAAc,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gCACpD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;oCACxB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC;gCACzC,CAAC;4BACH,CAAC;iCAAM,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;gCAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;4BACjD,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBAC1C,MAAM,YAAY,GAAG,cAAc,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;oBACpD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;wBACxB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC;oBACnD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Checks if a command-line argument needs to be quoted when used in a command line.
3
+ *
4
+ * Arguments containing special characters like spaces, quotes, or shell metacharacters
5
+ * need to be wrapped in quotes to be properly interpreted by the shell.
6
+ *
7
+ * @param arg The command-line argument to check
8
+ * @returns True if the argument needs quotes, false otherwise
9
+ */
10
+ export declare function shouldQuoteCommandLineArg(arg: string): boolean;
11
+ //# sourceMappingURL=shouldQuoteCommandLineArg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shouldQuoteCommandLineArg.d.ts","sourceRoot":"","sources":["../../src/lib/shouldQuoteCommandLineArg.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAsB9D"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Checks if a command-line argument needs to be quoted when used in a command line.
3
+ *
4
+ * Arguments containing special characters like spaces, quotes, or shell metacharacters
5
+ * need to be wrapped in quotes to be properly interpreted by the shell.
6
+ *
7
+ * @param arg The command-line argument to check
8
+ * @returns True if the argument needs quotes, false otherwise
9
+ */
10
+ export function shouldQuoteCommandLineArg(arg) {
11
+ if (!arg)
12
+ return false;
13
+ // Check for spaces
14
+ if (arg.includes(' '))
15
+ return true;
16
+ // Check for quotes
17
+ if (arg.includes('"') || arg.includes("'"))
18
+ return true;
19
+ // Check for shell metacharacters and special characters
20
+ const shellSpecialChars = /[&|<>(){}[\]$;!*?~`\n\r\t#]/;
21
+ if (shellSpecialChars.test(arg))
22
+ return true;
23
+ // Check for control characters
24
+ // eslint-disable-next-line no-control-regex
25
+ if (/[\x00-\x1F\x7F]/.test(arg))
26
+ return true;
27
+ // Check if argument starts with a dash (to avoid confusion with options)
28
+ if (arg.startsWith('-') && !arg.startsWith('--'))
29
+ return true;
30
+ // Check for wildcards
31
+ return arg.includes('*') || arg.includes('?');
32
+ }
33
+ //# sourceMappingURL=shouldQuoteCommandLineArg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shouldQuoteCommandLineArg.js","sourceRoot":"","sources":["../../src/lib/shouldQuoteCommandLineArg.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,mBAAmB;IACnB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,mBAAmB;IACnB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAExD,wDAAwD;IACxD,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;IACxD,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7C,+BAA+B;IAC/B,4CAA4C;IAC5C,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7C,yEAAyE;IACzE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9D,sBAAsB;IACtB,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const packageVersion = "2.3.2";
1
+ export declare const packageVersion = "2.4.1";
2
2
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // This file was generated automatically
2
- export const packageVersion = '2.3.2';
2
+ export const packageVersion = '2.4.1';
3
3
  //# sourceMappingURL=packageVersion.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-qraft/plugin",
3
- "version": "2.3.2",
3
+ "version": "2.4.1",
4
4
  "packageManager": "yarn@4.0.2",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -78,6 +78,6 @@
78
78
  "repository": {
79
79
  "type": "git",
80
80
  "url": "git+https://github.com/OpenAPI-Qraft/openapi-qraft.git",
81
- "directory": "packages/cli"
81
+ "directory": "packages/plugin"
82
82
  }
83
83
  }
@@ -1,14 +1,16 @@
1
- import type { Option } from 'commander';
2
1
  import { sep } from 'node:path';
3
2
  import process from 'node:process';
4
3
  import { pathToFileURL, URL } from 'node:url';
4
+ import { Config, createConfig, getMergedConfig } from '@redocly/openapi-core';
5
5
  import c from 'ansi-colors';
6
- import { Command } from 'commander';
6
+ import { Command, CommanderError, Option, ParseOptions } from 'commander';
7
7
  import ora, { Ora } from 'ora';
8
8
  import { packageVersion } from '../packageVersion.js';
9
9
  import { filterDocumentPaths } from './filterDocumentPaths.js';
10
10
  import { GeneratorFile } from './GeneratorFile.js';
11
+ import { getRedocAPIsToQraft } from './getRedocAPIsToQraft.js';
11
12
  import { handleSchemaInput } from './handleSchemaInput.js';
13
+ import { loadRedoclyConfig } from './loadRedoclyConfig.js';
12
14
  import { getServices } from './open-api/getServices.js';
13
15
  import { OpenAPISchemaType } from './open-api/OpenAPISchemaType.js';
14
16
  import { OpenAPIService } from './open-api/OpenAPIService.js';
@@ -23,15 +25,21 @@ import {
23
25
  parseOperationNameModifier,
24
26
  processOperationNameModifierOption,
25
27
  } from './processOperationNameModifierOption.js';
28
+ import { redoclyOption } from './RedoclyConfigCommand.js';
26
29
  import { splitCommaSeparatedGlobs } from './splitCommaSeparatedGlobs.js';
27
30
  import { writeGeneratorFiles } from './writeGeneratorFiles.js';
28
31
 
29
32
  export class QraftCommand extends Command {
33
+ static spinner = ora();
34
+
30
35
  protected readonly cwd: URL;
31
36
  protected registeredPluginActions: QraftCommandActionCallback[] = [];
32
37
 
33
- constructor() {
34
- super();
38
+ /**
39
+ * @param name - not used
40
+ */
41
+ constructor(name?: string) {
42
+ super(name);
35
43
  this.cwd = pathToFileURL(`${process.cwd()}/`);
36
44
 
37
45
  this.usage('[input] [options]')
@@ -40,39 +48,47 @@ export class QraftCommand extends Command {
40
48
  'Input OpenAPI Document file path, URL (json, yml)',
41
49
  null
42
50
  )
43
- .requiredOption(
51
+ .option(
44
52
  '-o, --output-dir <path>',
45
53
  'Output directory for generated services'
46
54
  )
47
- .option(
48
- '-rm, --clean',
49
- 'Clean output directory before generating services'
55
+ .addOption(
56
+ new Option(
57
+ '-rm, --clean',
58
+ 'Clean output directory before generating services'
59
+ )
50
60
  )
51
61
  .option(
52
62
  '--filter-services <glob-patterns...>',
53
- 'Filter services to be generated by glob pattern. Eg: "/user/**,/post/**". See NPM `micromatch` package for more details.'
63
+ 'Filter services to be generated using glob patterns. Example: "/user/**,/post/**". For more details, see the NPM `micromatch` package documentation.'
54
64
  )
55
65
  .option(
56
66
  '--operation-predefined-parameters <patterns...>',
57
- 'Predefined parameters for services. The specified services parameters will be optional. Eg: "/**:header.x-monite-version,query.x-api-key" or "get /**:header.x-monite-entity-id"'
67
+ 'Predefined parameters for services. The specified service parameters will be optional. Example: "/**:header.x-monite-version,query.x-api-key" or "get /**:header.x-monite-entity-id"',
68
+ parseColonSeparatedList
58
69
  )
59
70
  .option(
60
71
  '--operation-name-modifier <patterns...>',
61
72
  'Modifies operation names using a pattern. Use the `==>` operator to separate the regular expression (left) and the substitution string (right). For example: "post /**:[A-Za-z]+Id ==> createOne"'
62
73
  )
63
- .option(
64
- '--postfix-services <string>',
65
- 'Postfix to be added to the generated service name (eg: Service)'
74
+ .addOption(
75
+ new Option(
76
+ '--postfix-services <string>',
77
+ 'Postfix to be added to the generated service name (eg: Service)'
78
+ )
66
79
  )
67
80
  .option(
68
81
  '--service-name-base <endpoint[<index>] | tags>',
69
82
  'Use OpenAPI Operation `endpoint[<index>]` path part (e.g.: "/0/1/2") or `tags` as the base name of the service.',
70
83
  'endpoint[0]'
71
84
  )
72
- .option(
73
- '--file-header <string>',
74
- 'Header to be added to the generated file (eg: /* eslint-disable */)'
75
- );
85
+ .addOption(
86
+ new Option(
87
+ '--file-header <string>',
88
+ 'Header to be added to the generated file (eg: /* eslint-disable */)'
89
+ )
90
+ )
91
+ .addOption(redoclyOption);
76
92
  }
77
93
 
78
94
  action(callback: QraftCommandActionCallback): this {
@@ -95,15 +111,33 @@ export class QraftCommand extends Command {
95
111
  process.exit(0);
96
112
  }
97
113
 
98
- console.info(`✨ ${c.bold(`OpenAPI Qraft ${packageVersion}`)}`);
114
+ const spinner = QraftCommand.spinner;
115
+
116
+ spinner.start('Initializing process...');
117
+
118
+ const redoc = args.redocly
119
+ ? getMergedConfig(
120
+ await loadRedoclyConfig(args.redocly, this.cwd),
121
+ inputs[0]
122
+ )
123
+ : await createConfig(
124
+ {
125
+ rules: {
126
+ // throw error on duplicate operationIDs
127
+ 'operation-operationId-unique': { severity: 'error' },
128
+ },
129
+ },
130
+ { extends: ['minimal'] }
131
+ );
99
132
 
100
- const spinner = ora('Starting ⛏︎').start();
133
+ const input = args.redocly
134
+ ? handleRedoclySchemaInput(redoc, inputs[0], this.cwd, spinner)
135
+ : handleSchemaInput(inputs[0], this.cwd, spinner);
101
136
 
102
- const input = handleSchemaInput(inputs[0], this.cwd, spinner);
137
+ spinner.text = 'Reading OpenAPI Document...';
103
138
 
104
- spinner.text = 'Reading OpenAPI Schema';
105
139
  let schema = filterDocumentPaths(
106
- await readSchema(input),
140
+ await readSchema(input, redoc),
107
141
  splitCommaSeparatedGlobs(args.filterServices)
108
142
  );
109
143
 
@@ -122,7 +156,7 @@ export class QraftCommand extends Command {
122
156
  if (predefinedParametersErrors.length) {
123
157
  predefinedParametersErrors.forEach((error) => spinner.warn(error));
124
158
  spinner.fail(
125
- 'Error occurred during operation predefined parameters setup.'
159
+ 'An error occurred while setting up operation predefined parameters.'
126
160
  );
127
161
  process.exit(1);
128
162
  }
@@ -130,7 +164,7 @@ export class QraftCommand extends Command {
130
164
  schema = predefineSchemaParameters(schema, predefinedParametersGlobs);
131
165
  }
132
166
 
133
- spinner.text = 'Getting OpenAPI Services';
167
+ spinner.text = 'Retrieving OpenAPI Services...';
134
168
  let services = getServices(schema as OpenAPISchemaType, {
135
169
  postfixServices: args.postfixServices,
136
170
  serviceNameBase: args.serviceNameBase,
@@ -188,7 +222,7 @@ export class QraftCommand extends Command {
188
222
  services = modifiedServicesOperationNames;
189
223
  }
190
224
 
191
- spinner.text = 'Generating code';
225
+ spinner.text = 'Generating code...';
192
226
 
193
227
  const outputDir = normalizeOutputDirPath(args.outputDir);
194
228
 
@@ -223,7 +257,9 @@ export class QraftCommand extends Command {
223
257
  await writeGeneratorFiles({ fileItems, spinner });
224
258
  }
225
259
  } catch (error) {
226
- spinner.fail(c.red('Error occurred during generation'));
260
+ spinner.fail(
261
+ c.red('An error occurred during the code generation process.')
262
+ );
227
263
 
228
264
  if (error instanceof Error) {
229
265
  console.error(c.red(error.message), c.red(error.stack ?? ''));
@@ -233,7 +269,7 @@ export class QraftCommand extends Command {
233
269
  }
234
270
  }
235
271
 
236
- spinner.succeed(c.green('Qraft has been finished'));
272
+ spinner.succeed(c.green('Qraft process completed successfully'));
237
273
  }
238
274
 
239
275
  protected registerPluginAction(callback: QraftCommandActionCallback) {
@@ -334,6 +370,35 @@ export class QraftCommand extends Command {
334
370
  );
335
371
  }
336
372
 
373
+ addOption(option: Option): this {
374
+ if (
375
+ this.findSimilarOption({
376
+ flags: option.flags,
377
+ mandatory: option.mandatory,
378
+ })
379
+ ) {
380
+ return this;
381
+ }
382
+
383
+ return super.addOption(option);
384
+ }
385
+
386
+ parseAsync(argv?: readonly string[], options?: ParseOptions): Promise<this> {
387
+ if (options?.from !== 'user') this.logVersion();
388
+ return super.parseAsync(argv, options);
389
+ }
390
+
391
+ parse(argv?: readonly string[], options?: ParseOptions): this {
392
+ if (options?.from !== 'user') this.logVersion();
393
+ return super.parse(argv, options);
394
+ }
395
+
396
+ protected logVersion() {
397
+ QraftCommand.spinner.info(
398
+ `✨ ${c.bold(`OpenAPI Qraft ${packageVersion}`)}`
399
+ );
400
+ }
401
+
337
402
  protected findSimilarOption(option: { flags: string; mandatory: boolean }) {
338
403
  try {
339
404
  return findSimilarOption(option, this.options);
@@ -342,7 +407,7 @@ export class QraftCommand extends Command {
342
407
  c.red(
343
408
  error instanceof Error
344
409
  ? error.message
345
- : 'Error occurred during option setup'
410
+ : 'An error occurred during command option setup'
346
411
  )
347
412
  );
348
413
 
@@ -496,3 +561,49 @@ export function splitOptionFlags(flags: string) {
496
561
 
497
562
  return { shortFlag, longFlag };
498
563
  }
564
+
565
+ function parseColonSeparatedList(value: string, previous: unknown) {
566
+ if (Array.isArray(previous)) {
567
+ const previousValue = previous.at(-1);
568
+
569
+ if (
570
+ typeof previousValue === 'string' &&
571
+ !previousValue.includes(':') &&
572
+ !value.includes(':')
573
+ ) {
574
+ return previous.slice(0, -1).concat(`${previousValue}:${value}`);
575
+ }
576
+
577
+ return previous.concat(value);
578
+ }
579
+
580
+ return [value];
581
+ }
582
+
583
+ function handleRedoclySchemaInput(
584
+ redoc: Config,
585
+ inputAPIName: string,
586
+ cwd: URL,
587
+ spinner: Ora
588
+ ) {
589
+ if (!inputAPIName) {
590
+ throw new CommanderError(
591
+ 1,
592
+ 'ERR_MISSING_API',
593
+ 'No API specified. Please specify the API to be generated.'
594
+ );
595
+ }
596
+
597
+ const api = getRedocAPIsToQraft(redoc, cwd, spinner, inputAPIName)[
598
+ inputAPIName
599
+ ];
600
+
601
+ if (!api)
602
+ throw new CommanderError(
603
+ 1,
604
+ 'ERR_MISSING_API',
605
+ `API not found in Redocly API (${inputAPIName}) found in the Redocly configuration: ${inputAPIName}. Please specify the correct API.`
606
+ );
607
+
608
+ return new URL(api['root'], cwd);
609
+ }