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/api.d.ts +105 -38
- package/dist/cs-apis.js +25 -18
- package/dist/cs-ast.js +76 -23
- package/dist/cs-gen.js +41 -5
- package/dist/cs-migrations.js +6 -4
- package/dist/icons.js +129 -7
- package/dist/index.js +69 -18
- package/dist/info.js +22 -6
- package/dist/ts-once.js +34 -1
- package/dist/ts-parser.js +134 -18
- package/dist/tsd-gen.js +69 -8
- package/dist/ui-mjs.js +2 -2
- package/dist/utils.js +33 -1
- package/package.json +1 -1
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
|
4
|
-
static
|
5
|
-
static
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
166
|
-
|
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]
|
169
|
-
if (impls) {
|
170
|
-
cls.implements
|
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
|
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
|
-
|
268
|
-
|
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'
|
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
|
-
|
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(
|
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
|
-
?
|
68
|
-
|
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
|
-
|
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}`;
|