okai 0.0.28 → 0.0.30

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/dist/ts-once.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { pick, toCamelCase, toPascalCase } from "./utils.js";
2
2
  // Tranforms that are only applied once on AI TypeScript AST
3
- export function createTdAstFromAIAst(tsAst) {
3
+ export function createTdAstFromAIAst(tsAst, gropName) {
4
4
  mergeInterfacesAndClasses(tsAst);
5
5
  rewriteToPascalCase(tsAst);
6
6
  replaceReferences(tsAst);
@@ -9,6 +9,15 @@ export function createTdAstFromAIAst(tsAst) {
9
9
  // replaceUserRefs(cls)
10
10
  rewriteDuplicateTypePropNames(cls);
11
11
  rewriteSelfReferencingIds(cls);
12
+ convertToAuditBase(cls);
13
+ addCustomInputs(cls);
14
+ if (gropName) {
15
+ if (!cls.annotations)
16
+ cls.annotations = [];
17
+ if (!cls.annotations.some(x => x.name === 'tag')) {
18
+ cls.annotations.push({ name: 'tag', constructorArgs: [gropName] });
19
+ }
20
+ }
12
21
  });
13
22
  changeUserRefsToAuditBase(tsAst);
14
23
  return tsAst;
@@ -119,6 +128,21 @@ function rewriteSelfReferencingIds(type) {
119
128
  selfRefId.name = `parentId`;
120
129
  }
121
130
  }
131
+ export function addCustomInputs(cls) {
132
+ const currencyTypeProps = [
133
+ "price", "cost", "total", "salary", "balance", "tax", "fee"
134
+ ];
135
+ for (const prop of cls.properties ?? []) {
136
+ if (currencyTypeProps.some(x => prop.name.toLowerCase().includes(x))) {
137
+ if (!prop.annotations)
138
+ prop.annotations = [];
139
+ prop.annotations.push({
140
+ name: "IntlNumber",
141
+ args: { Currency: "NumberCurrency.USD" }
142
+ });
143
+ }
144
+ }
145
+ }
122
146
  function rewriteToPascalCase(ast) {
123
147
  ast?.classes.forEach(t => {
124
148
  t.name = toPascalCase(t.name);
@@ -131,6 +155,14 @@ function rewriteToPascalCase(ast) {
131
155
  });
132
156
  });
133
157
  }
158
+ function convertToAuditBase(cls) {
159
+ const props = cls.properties ?? [];
160
+ const auditFields = ['createdBy', 'updatedBy', 'createdAt', 'updatedAt', 'userId'];
161
+ if (props.find(x => auditFields.includes(x.name))) {
162
+ cls.extends = 'AuditBase';
163
+ cls.properties = props.filter(x => !auditFields.includes(x.name));
164
+ }
165
+ }
134
166
  function changeUserRefsToAuditBase(ast) {
135
167
  const user = ast.classes?.find(x => x.name === 'User') ?? ast.interfaces?.find(x => x.name === 'User');
136
168
  if (user) {
@@ -168,6 +200,7 @@ function interfaceToClass(ast) {
168
200
  export function replaceReferences(tsAst) {
169
201
  const references = [
170
202
  'Service',
203
+ 'Task',
171
204
  ];
172
205
  // The most important types are the ones with the most references
173
206
  const refCount = (t) => t.properties?.filter(p => tsAst.classes.find(x => x.name === p.type)).length || 0;
package/dist/ts-parser.js CHANGED
@@ -1,12 +1,18 @@
1
- import { lastLeftPart, leftPart, rightPart } from "./utils.js";
1
+ import { lastLeftPart, lastRightPart, leftPart, rightPart, trimEnd } from "./utils.js";
2
2
  export class TypeScriptParser {
3
- static CLASS_PATTERN = /class\s+(\w+)(?:\s+extends\s+(\w+))?(?:\s+implements\s+([\w,\s]+))?\s*{/g;
4
- static INTERFACE_PATTERN = /interface\s+(\w+)(?:\s+extends\s+(\w+))?\s*{/g;
5
- static ENUM_PATTERN = /enum\s+(\w+)\s*{([^}]*)}/g;
3
+ static CONFIG_TYPE_PATTERN = /export\s+type\s+Config\s*=\s*{([^}]+)}/;
4
+ static CONFIG_PROPERTY_PATTERN = /(\w+)\s*:\s*("[^"]*"|'[^']*')/g;
5
+ static DEFAULT_EXPORT_PATTERN = /export\s+default\s+({[^}]+})/;
6
+ static CLASS_PATTERN = /class\s+(\w+)(?:\s+extends\s+([\w\s<>,]+))?(?:\s+implements\s+([\w\s<>,]+))?\s*{/gm;
7
+ static INTERFACE_PATTERN = /interface\s+(\w+)(?:\s+extends\s+([\w\s<>,]+))?\s*{/gm;
8
+ static ENUM_PATTERN = /enum\s+(\w+)\s*{([^}]*)}/gm;
6
9
  static PROPERTY_PATTERN = /(?:(?<modifier>private|public|protected|readonly)\s+)*(?<name>\w+)(?<optional>\?)?\s*:\s*(?<type>[\w<>[\],\s]+)(?<union>\|\s*[\w<>[\],|,\s]+)?\s*;?/;
7
10
  static ENUM_MEMBER_PATTERN = /(\w+)\s*(?:=\s*("[^"]*"|'[^']*'|\d+|[^,\n]+))?\s*/;
8
11
  static ANNOTATION_PATTERN = /^\s*@([A-Za-z_][A-Za-z0-9_]*\.?[A-Za-z_]?[A-Za-z0-9_]*)/;
12
+ static ANNOTATION_COMMENT = /\)[\s]*\/\/.*$/;
9
13
  static REFERENCE_PATTERN = /\/\/\/\s*<reference\s+path="([^"]+)"\s*\/>/g;
14
+ config;
15
+ defaultExport;
10
16
  classes = [];
11
17
  interfaces = [];
12
18
  enums = [];
@@ -15,6 +21,12 @@ export class TypeScriptParser {
15
21
  if (line.match(TypeScriptParser.REFERENCE_PATTERN)) {
16
22
  return undefined;
17
23
  }
24
+ if (line.trim().startsWith('@')) {
25
+ if (TypeScriptParser.ANNOTATION_COMMENT.test(line)) {
26
+ return lastRightPart(line, '//').trim();
27
+ }
28
+ return undefined;
29
+ }
18
30
  // Check for single line comment at end of line
19
31
  const singleLineMatch = line.match(/.*?\/\/\s*(.+)$/);
20
32
  if (singleLineMatch) {
@@ -37,11 +49,45 @@ export class TypeScriptParser {
37
49
  }
38
50
  return undefined;
39
51
  }
52
+ parseConfigType(content) {
53
+ const match = content.match(TypeScriptParser.CONFIG_TYPE_PATTERN);
54
+ if (match) {
55
+ const configBody = match[1];
56
+ const config = {};
57
+ let propertyMatch;
58
+ while ((propertyMatch = TypeScriptParser.CONFIG_PROPERTY_PATTERN.exec(configBody))) {
59
+ const [, key, value] = propertyMatch;
60
+ config[key] = value.slice(1, -1); // Remove quotes
61
+ }
62
+ this.config = config;
63
+ }
64
+ }
65
+ parseDefaultExport(content) {
66
+ const match = content.match(TypeScriptParser.DEFAULT_EXPORT_PATTERN);
67
+ if (match) {
68
+ try {
69
+ const configStr = match[1];
70
+ const defaultExport = {};
71
+ const lines = configStr.split('\n');
72
+ for (const line of lines) {
73
+ if (line.includes(':')) {
74
+ const key = leftPart(line, ':').trim();
75
+ const val = trimEnd(rightPart(line, ':').trim(), ',');
76
+ defaultExport[key] = JSON.parse(val);
77
+ }
78
+ }
79
+ this.defaultExport = defaultExport;
80
+ }
81
+ catch (e) {
82
+ console.warn('Failed to parse default export config:', e);
83
+ }
84
+ }
85
+ }
40
86
  parseMetadata(body, line) {
41
87
  const annotations = [];
42
88
  const commments = [];
43
89
  const ANNOTATION = TypeScriptParser.ANNOTATION_PATTERN;
44
- let previousLine = this.getPreviousLine(body, body.indexOf(line));
90
+ let previousLine = this.getPreviousLine(body, body.lastIndexOf(line));
45
91
  while (previousLine && (!previousLine.match(TypeScriptParser.PROPERTY_PATTERN) || previousLine.match(ANNOTATION))) {
46
92
  const annotation = previousLine.match(ANNOTATION) ? parseAnnotation(previousLine) : undefined;
47
93
  if (annotation) {
@@ -53,7 +99,7 @@ export class TypeScriptParser {
53
99
  commments.unshift(comment);
54
100
  }
55
101
  }
56
- previousLine = this.getPreviousLine(body, body.indexOf(previousLine));
102
+ previousLine = this.getPreviousLine(body, body.lastIndexOf(previousLine));
57
103
  }
58
104
  const lineComment = this.getLineComment(line);
59
105
  if (lineComment) {
@@ -65,10 +111,11 @@ export class TypeScriptParser {
65
111
  annotations.push(annotation);
66
112
  }
67
113
  }
68
- return {
114
+ const ret = {
69
115
  comment: commments.length ? commments.join('\n') : undefined,
70
116
  annotations: annotations.length ? annotations : undefined,
71
117
  };
118
+ return ret;
72
119
  }
73
120
  parseClassProperties(classBody) {
74
121
  const props = [];
@@ -101,7 +148,20 @@ export class TypeScriptParser {
101
148
  member.optional = true;
102
149
  }
103
150
  }
104
- const { comment, annotations } = this.parseMetadata(classBody, line);
151
+ let startIndex = index;
152
+ for (let i = index - 1; i >= 0; i--) {
153
+ const prevLine = lines[i].trim();
154
+ if (this.isComment(prevLine) || this.isAnnotation(prevLine)) {
155
+ startIndex = i;
156
+ }
157
+ else {
158
+ if (prevLine != '')
159
+ break;
160
+ }
161
+ }
162
+ const propMetadata = startIndex < index ? lines.slice(startIndex, index + 1).join('\n') : line;
163
+ // console.log('\npropMetadata <!--', propMetadata, '-->\n')
164
+ const { comment, annotations } = this.parseMetadata(propMetadata, line);
105
165
  if (comment)
106
166
  member.comment = comment;
107
167
  if (annotations)
@@ -162,20 +222,27 @@ export class TypeScriptParser {
162
222
  name: match[1],
163
223
  properties: this.parseClassProperties(body),
164
224
  };
165
- if (match[2]) {
166
- cls.extends = match[2];
225
+ const inherits = splitTypes(match[2]);
226
+ if (inherits.length) {
227
+ cls.extends = inherits[0];
228
+ if (inherits.length > 1) {
229
+ cls.implements = inherits.slice(1);
230
+ }
167
231
  }
168
- const impls = match[3]?.split(',').map(i => i.trim());
169
- if (impls) {
170
- cls.implements = impls;
232
+ const impls = splitTypes(match[3]);
233
+ if (impls.length) {
234
+ if (!cls.implements)
235
+ cls.implements = [];
236
+ cls.implements.push(...impls);
171
237
  }
172
238
  if (previousLine) {
173
- const { comment, annotations } = this.parseMetadata(content, previousLine);
239
+ const { comment, annotations } = this.parseMetadata(content.substring(0, match.index), previousLine);
174
240
  if (comment)
175
241
  cls.comment = comment;
176
242
  if (annotations)
177
243
  cls.annotations = annotations;
178
244
  }
245
+ // console.log('cls', cls.name, previousLine, cls.annotations)
179
246
  this.classes.push(cls);
180
247
  }
181
248
  }
@@ -200,14 +267,15 @@ export class TypeScriptParser {
200
267
  };
201
268
  if (value) {
202
269
  // Remove quotes if present
203
- const cleanValue = value.trim().replace(/^["']|["']$/g, '');
270
+ const cleanValue = value.trim().replace(/^["'`]|["'`]$/g, '');
204
271
  member.value = isNaN(Number(cleanValue)) ? cleanValue : Number(cleanValue);
205
272
  }
206
273
  else {
207
- member.value = prevIntValue + 1;
274
+ member.value = prevIntValue;
208
275
  }
209
276
  if (typeof member.value === 'number') {
210
277
  prevIntValue = member.value;
278
+ prevIntValue++;
211
279
  }
212
280
  const previousLine = this.getPreviousLine(enumBody, enumBody.indexOf(line));
213
281
  if (previousLine && this.isComment(previousLine)) {
@@ -222,6 +290,12 @@ export class TypeScriptParser {
222
290
  });
223
291
  return members;
224
292
  }
293
+ isAnnotation(s) {
294
+ if (!s)
295
+ return false;
296
+ s = s.trim();
297
+ return s.startsWith('@');
298
+ }
225
299
  isComment(s) {
226
300
  if (!s)
227
301
  return false;
@@ -247,14 +321,20 @@ export class TypeScriptParser {
247
321
  .join('\n');
248
322
  }
249
323
  parse(sourceCode) {
324
+ this.config = undefined;
325
+ this.defaultExport = undefined;
250
326
  this.classes = [];
251
327
  this.interfaces = [];
252
328
  this.enums = [];
329
+ this.parseConfigType(sourceCode);
330
+ this.parseDefaultExport(sourceCode);
253
331
  this.parseReferences(sourceCode);
254
332
  this.parseInterfaces(sourceCode);
255
333
  this.parseClasses(sourceCode);
256
334
  this.parseEnums(sourceCode);
257
335
  return {
336
+ config: this.config,
337
+ defaultExport: this.defaultExport,
258
338
  references: this.references,
259
339
  classes: this.classes,
260
340
  interfaces: this.interfaces,
@@ -264,8 +344,9 @@ export class TypeScriptParser {
264
344
  }
265
345
  export function parseAnnotation(annotation) {
266
346
  const regex = TypeScriptParser.ANNOTATION_PATTERN;
267
- if (annotation.includes('//')) {
268
- annotation = leftPart(annotation, '//');
347
+ // search for // after closing parenthesis and remove it
348
+ if (TypeScriptParser.ANNOTATION_COMMENT.test(annotation)) {
349
+ annotation = lastLeftPart(annotation, '//');
269
350
  }
270
351
  const match = annotation.match(regex);
271
352
  if (!match)
@@ -340,3 +421,38 @@ function splitArgs(str) {
340
421
  args.push(current.trim());
341
422
  return args;
342
423
  }
424
+ export function splitTypes(input) {
425
+ const result = [];
426
+ let currentToken = '';
427
+ let angleBracketCount = 0;
428
+ // Trim and handle empty input
429
+ input = input?.trim();
430
+ if (!input)
431
+ return [];
432
+ // Process each character
433
+ for (let char of input) {
434
+ if (char === '<') {
435
+ angleBracketCount++;
436
+ currentToken += char;
437
+ }
438
+ else if (char === '>') {
439
+ angleBracketCount--;
440
+ currentToken += char;
441
+ }
442
+ else if (char === ',' && angleBracketCount === 0) {
443
+ // Only split on commas when we're not inside angle brackets
444
+ if (currentToken.trim()) {
445
+ result.push(currentToken.trim());
446
+ }
447
+ currentToken = '';
448
+ }
449
+ else {
450
+ currentToken += char;
451
+ }
452
+ }
453
+ // Add the last token if it exists
454
+ if (currentToken.trim()) {
455
+ result.push(currentToken.trim());
456
+ }
457
+ return result;
458
+ }
package/dist/tsd-gen.js CHANGED
@@ -1,9 +1,24 @@
1
+ import { rightPart } from "./utils.js";
1
2
  export class TsdGenerator {
3
+ export = true;
2
4
  interfaces = [];
3
5
  enums = [];
4
6
  ast = { references: [], classes: [], interfaces: [], enums: [] };
7
+ get typePrefix() {
8
+ return this.export ? 'export ' : '';
9
+ }
10
+ isEnumValue(value) {
11
+ const parts = (value ?? '').split('.');
12
+ if (parts.length !== 2)
13
+ return false;
14
+ const isUpper = (charCode) => charCode >= 65 && charCode <= 90;
15
+ const isAlphaNum = (s) => /^[a-z0-9]+$/i.test(s);
16
+ return isAlphaNum(parts[0]) && isUpper(parts[0].charCodeAt(0)) && isAlphaNum(parts[1]) && isUpper(parts[1].charCodeAt(0));
17
+ }
5
18
  attrValue(type, value) {
6
- return type === 'string' ? `"${value}"` : value;
19
+ return type === 'string' && !this.isEnumValue(value)
20
+ ? `"${value}"`
21
+ : value;
7
22
  }
8
23
  toAttr(attr) {
9
24
  const sbCtorArgs = [];
@@ -32,18 +47,19 @@ export class TsdGenerator {
32
47
  sb.push(ast.comment.split('\n').map(x => `// ${x}`).join('\n'));
33
48
  }
34
49
  if (ast.annotations?.length) {
35
- for (const attr of ast.annotations) {
50
+ for (const attr of sortAnnotations(ast.annotations)) {
36
51
  sb.push(this.toAttr(attr));
37
52
  }
38
53
  }
39
54
  const extend = ast.extends ? ` extends ${ast.extends}` : '';
40
- sb.push(`export ${type} ${ast.name}${extend} {`);
55
+ const impls = ast.implements?.length ? ` implements ${ast.implements.join(', ')}` : '';
56
+ sb.push(`${this.typePrefix}${type} ${ast.name}${extend}${impls} {`);
41
57
  for (const prop of ast.properties) {
42
58
  if (prop.comment) {
43
59
  sb.push(prop.comment.split('\n').map(x => ` // ${x}`).join('\n'));
44
60
  }
45
61
  if (prop.annotations?.length) {
46
- for (const attr of prop.annotations) {
62
+ for (const attr of sortAnnotations(prop.annotations)) {
47
63
  sb.push(' ' + this.toAttr(attr));
48
64
  }
49
65
  }
@@ -57,15 +73,18 @@ export class TsdGenerator {
57
73
  if (ast.comment) {
58
74
  sb.push(ast.comment.split('\n').map(x => `// ${x}`).join('\n'));
59
75
  }
60
- sb.push(`export enum ${ast.name} {`);
76
+ sb.push(`${this.typePrefix}enum ${ast.name} {`);
77
+ const allStringValuesMatch = ast.members.every(x => typeof x.value === 'string' && x.value === x.name);
61
78
  for (let i = 0; i < ast.members.length; i++) {
62
79
  const member = ast.members[i];
63
80
  if (member.comment) {
64
81
  sb.push(member.comment.split('\n').map(x => ` // ${x}`).join('\n'));
65
82
  }
66
83
  const value = typeof member.value === 'string'
67
- ? ` = '${member.value}'`
68
- : member.value !== (i + 1) ? ` = ${member.value}` : '';
84
+ ? allStringValuesMatch
85
+ ? ``
86
+ : ` = ${member.value}`
87
+ : member.value !== i ? ` = ${member.value}` : '';
69
88
  sb.push(` ${member.name}${value},`);
70
89
  }
71
90
  sb.push('}');
@@ -78,8 +97,23 @@ export class TsdGenerator {
78
97
  for (const ref of ast.references) {
79
98
  sb.push(`/// <reference path="${ref.path}" />`);
80
99
  }
81
- sb.push('');
82
100
  }
101
+ if (ast.config) {
102
+ sb.push(`export type Config = {`);
103
+ const knownKeys = ['prompt', 'api', 'migration', 'uiMjs'];
104
+ const maxKeyLen = Object.keys(ast.config).reduce((max, key) => Math.max(max, key.length), 0);
105
+ for (const knownKey of knownKeys) {
106
+ if (ast.config[knownKey]) {
107
+ sb.push(` ${(knownKey + ':').padEnd(maxKeyLen + 1, ' ')} ${JSON.stringify(ast.config[knownKey])}`);
108
+ }
109
+ }
110
+ for (const key of Object.keys(ast.config).filter(k => !knownKeys.includes(k))) {
111
+ sb.push(` ${(key + ':').padEnd(maxKeyLen + 1, ' ')} ${JSON.stringify(ast.config[key])},`);
112
+ }
113
+ sb.push(`}`);
114
+ }
115
+ if (sb.length)
116
+ sb.push('');
83
117
  for (const cls of ast.enums ?? []) {
84
118
  sb.push(this.toEnum(cls));
85
119
  sb.push('');
@@ -96,6 +130,33 @@ export class TsdGenerator {
96
130
  return tsd;
97
131
  }
98
132
  }
133
+ function sortAnnotations(annotations) {
134
+ const to = annotations.sort((x, y) => {
135
+ const prefix = ['Read.', 'Create.', 'Update.', 'Delete.', 'Write.'];
136
+ const xPrefix = prefix.findIndex(p => x.name.startsWith(p));
137
+ const yPrefix = prefix.findIndex(p => y.name.startsWith(p));
138
+ // Sort by Prefix first in order ['Read.','Write.','Update.','Delete.']
139
+ if (xPrefix !== yPrefix)
140
+ return xPrefix == -1 ? 1 : yPrefix == -1 ? -1 : xPrefix - yPrefix;
141
+ const xName = x.name.includes('.') ? rightPart(x.name, '.') : x.name;
142
+ const yName = y.name.includes('.') ? rightPart(y.name, '.') : y.name;
143
+ // then Sort by length of attr name
144
+ if (xName.length !== yName.length)
145
+ return xName.length - yName.length;
146
+ // then Sort by attr name
147
+ if (xName != yName)
148
+ return xName.localeCompare(yName);
149
+ // then Sort by length of constructorArgs[0]
150
+ if ((x.constructorArgs?.length ?? 0) > 0 && (y.constructorArgs?.length ?? 0) > 0)
151
+ return x.constructorArgs[0].length - y.constructorArgs[0].length;
152
+ // then Sort by constructorArgs.length
153
+ if (x.constructorArgs?.length !== y.constructorArgs?.length)
154
+ return (x.constructorArgs?.length ?? 0) - (y.constructorArgs?.length ?? 0);
155
+ // then Sort by args.length
156
+ return (x.args?.length ?? 0) - (y.args?.length ?? 0);
157
+ });
158
+ return to;
159
+ }
99
160
  export function toTsd(tsAst) {
100
161
  const gen = new TsdGenerator();
101
162
  return gen.generate(tsAst);
package/dist/ui-mjs.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getGroupName, plural, toCamelCase } from "./utils.js";
1
+ import { getGroupName, plural, toCamelCase, splitCase } from "./utils.js";
2
2
  /*
3
3
  export default {
4
4
  group: "Bookings",
@@ -24,7 +24,7 @@ export class UiMjsGroupGenerator {
24
24
  generate(ast, groupLabel) {
25
25
  if (!groupLabel) {
26
26
  const groupName = getGroupName(ast);
27
- groupLabel = plural(groupName);
27
+ groupLabel = splitCase(plural(groupName));
28
28
  }
29
29
  const sb = [
30
30
  `export default {`,
package/dist/utils.js CHANGED
@@ -89,6 +89,9 @@ export function requestKey(date) {
89
89
  export function acceptedKey(date) {
90
90
  return `accepted/${timestampKey(date)}`;
91
91
  }
92
+ export function chatKey(date) {
93
+ return `chat/${timestampKey(date)}`;
94
+ }
92
95
  export function timestampKey(date) {
93
96
  const year = date.getFullYear();
94
97
  const month = String(date.getMonth() + 1).padStart(2, '0');
@@ -149,11 +152,40 @@ export function pick(o, keys) {
149
152
  });
150
153
  return to;
151
154
  }
155
+ export function appendQueryString(url, args) {
156
+ for (let k in args) {
157
+ if (args.hasOwnProperty(k)) {
158
+ let val = args[k];
159
+ if (typeof val == 'undefined' || typeof val == 'function' || typeof val == 'symbol')
160
+ continue;
161
+ url += url.indexOf("?") >= 0 ? "&" : "?";
162
+ url += k + (val === null ? '' : "=" + qsValue(val));
163
+ }
164
+ }
165
+ return url;
166
+ }
167
+ function qsValue(arg) {
168
+ if (arg == null)
169
+ return "";
170
+ return encodeURIComponent(arg) || "";
171
+ }
172
+ export function trimEnd(s, c) {
173
+ let end = s.length;
174
+ while (end > 0 && s[end - 1] === c) {
175
+ --end;
176
+ }
177
+ return (end < s.length) ? s.substring(0, end) : s;
178
+ }
152
179
  export function refCount(t) {
153
180
  return t.properties?.filter(x => x.attributes?.some(x => x.name === 'References')).length || 0;
154
181
  }
155
182
  export function getGroupName(ast) {
156
- return plural(ast.types.sort((x, y) => refCount(y) - refCount(x))[0].name);
183
+ let types = ast.types.filter(x => !x.isEnum);
184
+ if (types.length == 0)
185
+ types = ast.operations.map(x => x.request);
186
+ if (types.length == 0)
187
+ return null;
188
+ return plural(types.sort((x, y) => refCount(y) - refCount(x))[0].name);
157
189
  }
158
190
  export function tsdWithPrompt(tsd, prompt) {
159
191
  return `/*prompt: ${prompt}\n*/\n\n${tsd}`;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "okai",
3
3
  "type": "module",
4
- "version": "0.0.28",
4
+ "version": "0.0.30",
5
5
  "bin": "./dist/okai.js",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",