@opra/cli 1.0.0-alpha.21 → 1.0.0-alpha.22

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.
@@ -13,6 +13,26 @@ async function generateHttpController(controller) {
13
13
  let file = this._filesMap.get(controller);
14
14
  if (file)
15
15
  return file;
16
+ const generateParamDoc = async (name, type, options) => {
17
+ let typeDef;
18
+ if (type) {
19
+ const xt = await this.generateDataType(type, 'typeDef', file);
20
+ typeDef = xt.kind === 'embedded' ? 'object' : xt.typeName;
21
+ }
22
+ else
23
+ typeDef = 'any';
24
+ if (options?.isArray)
25
+ typeDef += '[]';
26
+ let out = `\n * @param {${typeDef}} ` + (options?.required ? name : `[${name}]`);
27
+ if (options?.description)
28
+ out += ` - ${(0, string_utils_js_1.wrapJSDocString)(options?.description)}`;
29
+ if (type instanceof common_1.ComplexType && type.embedded) {
30
+ for (const f of type.fields.values()) {
31
+ out += await generateParamDoc(name + '.' + f.name, f.type, f);
32
+ }
33
+ }
34
+ return out;
35
+ };
16
36
  const className = (0, putil_varhelpers_1.pascalCase)(controller.name) + 'Controller';
17
37
  file = this.addFile(node_path_1.default.join(this._apiPath, className + '.ts'));
18
38
  file.addImport('@opra/client', ['HttpRequestObservable', 'kClient', 'OpraHttpClient']);
@@ -21,12 +41,16 @@ async function generateHttpController(controller) {
21
41
  classBlock.doc = `/**
22
42
  * ${(0, string_utils_js_1.wrapJSDocString)(controller.description || '')}
23
43
  * @class ${className}
24
- * @url ${node_path_1.default.posix.join(this.serviceUrl, '$schema', '#resources/' + className)}
44
+ * @apiUrl ${node_path_1.default.posix.join(this.serviceUrl, controller.getFullUrl())}
25
45
  */`;
26
46
  classBlock.head = `\nexport class ${className} extends HttpControllerNode {\n\t`;
27
47
  classBlock.properties = '';
28
48
  const classConstBlock = (classBlock.classConstBlock = new code_block_js_1.CodeBlock());
29
- classConstBlock.head = `\n\nconstructor(client: OpraHttpClient) {`;
49
+ classConstBlock.head = `\n/**
50
+ * @param {OpraHttpClient} client - OpraHttpClient instance to operate
51
+ * @constructor
52
+ */
53
+ constructor(client: OpraHttpClient) {`;
30
54
  classConstBlock.body = `\n\tsuper(client);`;
31
55
  classConstBlock.tail = `\b\n}\n`;
32
56
  if (controller.controllers.size) {
@@ -74,7 +98,9 @@ async function generateHttpController(controller) {
74
98
  if (i)
75
99
  operationBlock.doc.regExParameters = block;
76
100
  }
77
- operationBlock.doc.tail = `\n */\n`;
101
+ operationBlock.doc.tail = `
102
+ * @apiUrl ${node_path_1.default.posix.join(this.serviceUrl, operation.getFullUrl())}
103
+ */\n`;
78
104
  operationBlock.head = `${operation.name}(`;
79
105
  /** Process operation parameters */
80
106
  const pathParams = [];
@@ -126,13 +152,19 @@ async function generateHttpController(controller) {
126
152
  let typeArr = [];
127
153
  for (const content of operation.requestBody.content) {
128
154
  if (content.type) {
155
+ /** Generate JSDoc for parameter */
156
+ operationBlock.doc.parameters += await generateParamDoc('$body', content.type, {
157
+ required: operation.requestBody.required,
158
+ description: content.description || content.type.description,
159
+ });
160
+ /** */
129
161
  const xt = await this.generateDataType(content.type, 'typeDef', file);
130
162
  let typeDef = xt.kind === 'embedded' ? xt.code : xt.typeName;
131
163
  if (typeDef === 'any') {
132
164
  typeArr = [];
133
165
  break;
134
166
  }
135
- if (typeDef) {
167
+ if (xt.kind === 'named') {
136
168
  if (operation.requestBody.partial) {
137
169
  file.addImport('ts-gems', ['PartialDTO']);
138
170
  typeDef = `PartialDTO<${typeDef}>`;
@@ -160,7 +192,7 @@ async function generateHttpController(controller) {
160
192
  }
161
193
  const typeDef = typeArr.join(' | ') || 'any';
162
194
  operationBlock.head += `$body: ${typeDef}`;
163
- operationBlock.doc.parameters += `\n * @param {${typeDef}} $body - Http body`;
195
+ // operationBlock.doc.parameters += `\n * @param {${typeDef}} $body - Http body` + bodyFields;
164
196
  hasBody = true;
165
197
  }
166
198
  /** process query params */
@@ -171,8 +203,13 @@ async function generateHttpController(controller) {
171
203
  operationBlock.head += ', ';
172
204
  operationBlock.head += '\n\t$params' + (isHeadersRequired || isQueryRequired ? '' : '?') + ': {\n\t';
173
205
  operationBlock.doc.parameters += '\n * @param {object} $params - Available parameters for the operation';
206
+ let hasAdditionalFields = false;
174
207
  for (const prm of queryParams) {
175
- operationBlock.head += `/**\n * ${prm.description || ''}\n */\n`;
208
+ if (typeof prm.name !== 'string') {
209
+ hasAdditionalFields = true;
210
+ continue;
211
+ }
212
+ operationBlock.doc.parameters += await generateParamDoc('$params.' + prm.name, prm.type, prm);
176
213
  operationBlock.head += `${prm.name}${prm.required ? '' : '?'}: `;
177
214
  if (prm.type) {
178
215
  const xt = await this.generateDataType(prm.type, 'typeDef', file);
@@ -184,6 +221,9 @@ async function generateHttpController(controller) {
184
221
  else
185
222
  operationBlock.head += `any;\n`;
186
223
  }
224
+ if (hasAdditionalFields) {
225
+ operationBlock.head += '[index: string]: any;\n';
226
+ }
187
227
  operationBlock.head += '\b}\b';
188
228
  }
189
229
  /** process header params */
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import typeIs from '@browsery/type-is';
3
- import { HttpController, MimeTypes } from '@opra/common';
3
+ import { ComplexType, HttpController, MimeTypes } from '@opra/common';
4
4
  import { camelCase, pascalCase } from 'putil-varhelpers';
5
5
  import { CodeBlock } from '../../code-block.js';
6
6
  import { locateNamedType } from '../utils/locate-named-type.js';
@@ -9,6 +9,26 @@ export async function generateHttpController(controller) {
9
9
  let file = this._filesMap.get(controller);
10
10
  if (file)
11
11
  return file;
12
+ const generateParamDoc = async (name, type, options) => {
13
+ let typeDef;
14
+ if (type) {
15
+ const xt = await this.generateDataType(type, 'typeDef', file);
16
+ typeDef = xt.kind === 'embedded' ? 'object' : xt.typeName;
17
+ }
18
+ else
19
+ typeDef = 'any';
20
+ if (options?.isArray)
21
+ typeDef += '[]';
22
+ let out = `\n * @param {${typeDef}} ` + (options?.required ? name : `[${name}]`);
23
+ if (options?.description)
24
+ out += ` - ${wrapJSDocString(options?.description)}`;
25
+ if (type instanceof ComplexType && type.embedded) {
26
+ for (const f of type.fields.values()) {
27
+ out += await generateParamDoc(name + '.' + f.name, f.type, f);
28
+ }
29
+ }
30
+ return out;
31
+ };
12
32
  const className = pascalCase(controller.name) + 'Controller';
13
33
  file = this.addFile(path.join(this._apiPath, className + '.ts'));
14
34
  file.addImport('@opra/client', ['HttpRequestObservable', 'kClient', 'OpraHttpClient']);
@@ -17,12 +37,16 @@ export async function generateHttpController(controller) {
17
37
  classBlock.doc = `/**
18
38
  * ${wrapJSDocString(controller.description || '')}
19
39
  * @class ${className}
20
- * @url ${path.posix.join(this.serviceUrl, '$schema', '#resources/' + className)}
40
+ * @apiUrl ${path.posix.join(this.serviceUrl, controller.getFullUrl())}
21
41
  */`;
22
42
  classBlock.head = `\nexport class ${className} extends HttpControllerNode {\n\t`;
23
43
  classBlock.properties = '';
24
44
  const classConstBlock = (classBlock.classConstBlock = new CodeBlock());
25
- classConstBlock.head = `\n\nconstructor(client: OpraHttpClient) {`;
45
+ classConstBlock.head = `\n/**
46
+ * @param {OpraHttpClient} client - OpraHttpClient instance to operate
47
+ * @constructor
48
+ */
49
+ constructor(client: OpraHttpClient) {`;
26
50
  classConstBlock.body = `\n\tsuper(client);`;
27
51
  classConstBlock.tail = `\b\n}\n`;
28
52
  if (controller.controllers.size) {
@@ -70,7 +94,9 @@ export async function generateHttpController(controller) {
70
94
  if (i)
71
95
  operationBlock.doc.regExParameters = block;
72
96
  }
73
- operationBlock.doc.tail = `\n */\n`;
97
+ operationBlock.doc.tail = `
98
+ * @apiUrl ${path.posix.join(this.serviceUrl, operation.getFullUrl())}
99
+ */\n`;
74
100
  operationBlock.head = `${operation.name}(`;
75
101
  /** Process operation parameters */
76
102
  const pathParams = [];
@@ -122,13 +148,19 @@ export async function generateHttpController(controller) {
122
148
  let typeArr = [];
123
149
  for (const content of operation.requestBody.content) {
124
150
  if (content.type) {
151
+ /** Generate JSDoc for parameter */
152
+ operationBlock.doc.parameters += await generateParamDoc('$body', content.type, {
153
+ required: operation.requestBody.required,
154
+ description: content.description || content.type.description,
155
+ });
156
+ /** */
125
157
  const xt = await this.generateDataType(content.type, 'typeDef', file);
126
158
  let typeDef = xt.kind === 'embedded' ? xt.code : xt.typeName;
127
159
  if (typeDef === 'any') {
128
160
  typeArr = [];
129
161
  break;
130
162
  }
131
- if (typeDef) {
163
+ if (xt.kind === 'named') {
132
164
  if (operation.requestBody.partial) {
133
165
  file.addImport('ts-gems', ['PartialDTO']);
134
166
  typeDef = `PartialDTO<${typeDef}>`;
@@ -156,7 +188,7 @@ export async function generateHttpController(controller) {
156
188
  }
157
189
  const typeDef = typeArr.join(' | ') || 'any';
158
190
  operationBlock.head += `$body: ${typeDef}`;
159
- operationBlock.doc.parameters += `\n * @param {${typeDef}} $body - Http body`;
191
+ // operationBlock.doc.parameters += `\n * @param {${typeDef}} $body - Http body` + bodyFields;
160
192
  hasBody = true;
161
193
  }
162
194
  /** process query params */
@@ -167,8 +199,13 @@ export async function generateHttpController(controller) {
167
199
  operationBlock.head += ', ';
168
200
  operationBlock.head += '\n\t$params' + (isHeadersRequired || isQueryRequired ? '' : '?') + ': {\n\t';
169
201
  operationBlock.doc.parameters += '\n * @param {object} $params - Available parameters for the operation';
202
+ let hasAdditionalFields = false;
170
203
  for (const prm of queryParams) {
171
- operationBlock.head += `/**\n * ${prm.description || ''}\n */\n`;
204
+ if (typeof prm.name !== 'string') {
205
+ hasAdditionalFields = true;
206
+ continue;
207
+ }
208
+ operationBlock.doc.parameters += await generateParamDoc('$params.' + prm.name, prm.type, prm);
172
209
  operationBlock.head += `${prm.name}${prm.required ? '' : '?'}: `;
173
210
  if (prm.type) {
174
211
  const xt = await this.generateDataType(prm.type, 'typeDef', file);
@@ -180,6 +217,9 @@ export async function generateHttpController(controller) {
180
217
  else
181
218
  operationBlock.head += `any;\n`;
182
219
  }
220
+ if (hasAdditionalFields) {
221
+ operationBlock.head += '[index: string]: any;\n';
222
+ }
183
223
  operationBlock.head += '\b}\b';
184
224
  }
185
225
  /** process header params */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/cli",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.22",
4
4
  "description": "Opra CLI tools",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -32,8 +32,8 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@browsery/type-is": "^1.6.18-r3",
35
- "@opra/client": "^1.0.0-alpha.21",
36
- "@opra/common": "^1.0.0-alpha.21",
35
+ "@opra/client": "^1.0.0-alpha.22",
36
+ "@opra/common": "^1.0.0-alpha.22",
37
37
  "chalk": "^5.3.0",
38
38
  "commander": "^12.0.0",
39
39
  "js-string-escape": "^1.0.1",