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/api.d.ts
CHANGED
@@ -1,4 +1,61 @@
|
|
1
1
|
declare global {
|
2
|
+
export class bool {}
|
3
|
+
export class byte {} export class Byte {}
|
4
|
+
export class sbyte {} export class SByte {}
|
5
|
+
export class char {} export class Char {}
|
6
|
+
export class decimal {} export class Decimal {}
|
7
|
+
export class double {} export class Double {}
|
8
|
+
export class float {} export class Single {}
|
9
|
+
export class int {} export class Int32 {}
|
10
|
+
export class uint {} export class UInt32 {}
|
11
|
+
export class nint {} export class IntPtr {}
|
12
|
+
export class nuint {} export class UIntPtr {}
|
13
|
+
export class long {} export class Int64 {}
|
14
|
+
export class ulong {} export class UInt64 {}
|
15
|
+
export class short {} export class Int16 {}
|
16
|
+
export class ushort {} export class UInt16 {}
|
17
|
+
export class dynamic {} export class Dynamic {}
|
18
|
+
export class DateTime {}
|
19
|
+
export class TimeSpan {}
|
20
|
+
export class DateOnly {}
|
21
|
+
export class TimeOnly {}
|
22
|
+
export class Guid {}
|
23
|
+
export class List<T> {}
|
24
|
+
export class HashSet<T> {}
|
25
|
+
export class Dictionary<Key,Value> {}
|
26
|
+
export class Color {}
|
27
|
+
|
28
|
+
export interface IReturn<T> {}
|
29
|
+
export interface IReturnVoid {}
|
30
|
+
|
31
|
+
export interface IGet {}
|
32
|
+
export interface IPost {}
|
33
|
+
export interface IPut {}
|
34
|
+
export interface IPatch {}
|
35
|
+
export interface IDelete {}
|
36
|
+
export interface IOptions {}
|
37
|
+
|
38
|
+
export interface ICreateDb<Table> {}
|
39
|
+
export interface IPatchDb<Table> {}
|
40
|
+
export interface IUpdateDb<Table> {}
|
41
|
+
export interface IDeleteDb<Table> {}
|
42
|
+
export class QueryDb<T> extends QueryBase {}
|
43
|
+
export class QueryDb2<From,Into> extends QueryBase {}
|
44
|
+
export class QueryBase {}
|
45
|
+
|
46
|
+
export interface IHasSessionId {}
|
47
|
+
export interface IHasBearerToken {}
|
48
|
+
|
49
|
+
export class EmptyResponse {}
|
50
|
+
export class IdResponse {}
|
51
|
+
export class StringsResponse {}
|
52
|
+
export class StringResponse {}
|
53
|
+
export class IntResponse {}
|
54
|
+
export class BoolResponse {}
|
55
|
+
export class ErrorResponse {}
|
56
|
+
export class ResponseError {}
|
57
|
+
export class ResponseStatus {}
|
58
|
+
|
2
59
|
export class AuditBase {
|
3
60
|
createdDate: Date
|
4
61
|
createdBy: string
|
@@ -20,9 +77,9 @@ declare global {
|
|
20
77
|
}
|
21
78
|
|
22
79
|
export type TypeOf = `typeof(${string})`
|
23
|
-
export type InputAttrOptions = { type?:string, value?:string, placeholder?:string, help?:string, label?:string, title?:string, size?:string,
|
24
|
-
pattern?:string, readOnly?:boolean, required?:boolean, disabled?:boolean, autocomplete?:string, autofocus?:string,
|
25
|
-
min?:string, max?:string, step?:string, minLength?:number, maxLength?:number, accept?:string, capture?:string, multiple?:boolean,
|
80
|
+
export type InputAttrOptions = { type?:string, value?:string, placeholder?:string, help?:string, label?:string, title?:string, size?:string,
|
81
|
+
pattern?:string, readOnly?:boolean, required?:boolean, disabled?:boolean, autocomplete?:string, autofocus?:string,
|
82
|
+
min?:string, max?:string, step?:string, minLength?:number, maxLength?:number, accept?:string, capture?:string, multiple?:boolean,
|
26
83
|
allowableValues?:string[], allowableValuesEnum?:TypeOf, options?:string, ignore?:boolean, evalAllowableValues?:string, evalAllowableEntries?:string, }
|
27
84
|
export type ScriptValueOptions = { value?: any, expression?: string, eval?: string, noCache?: boolean }
|
28
85
|
|
@@ -52,7 +109,7 @@ declare global {
|
|
52
109
|
export function validateHasClaim(claim:string) : ClassDecoratorDef
|
53
110
|
export function validateHasScope(scope:string) : ClassDecoratorDef
|
54
111
|
export function validateApiKey(scope?:string) : ClassDecoratorDef
|
55
|
-
|
112
|
+
|
56
113
|
export function schema(schema:string) : ClassDecoratorDef
|
57
114
|
export function compositeKey(columns:string[]) : ClassDecoratorDef
|
58
115
|
export function compositeIndex(unique:boolean, columns:string[]) : ClassDecoratorDef
|
@@ -60,24 +117,28 @@ declare global {
|
|
60
117
|
export function preDropTable(sql:string) : ClassDecoratorDef
|
61
118
|
export function postCreateTable(sql:string) : ClassDecoratorDef
|
62
119
|
export function postDropTable(sql:string) : ClassDecoratorDef
|
63
|
-
|
120
|
+
|
64
121
|
export function api(description:string, opt?:{ bodyParameter?:number, requestContentType?:string, isRequired?:boolean }) : ClassDecoratorDef
|
65
122
|
export function apiResponse(statusCode:number, description:string, opt?:{ isDefaultResponse?:boolean, responseType?:TypeOf }) : ClassDecoratorDef
|
66
|
-
|
123
|
+
|
67
124
|
export function dataContract() : ClassDecoratorDef
|
68
|
-
export function route(path:string, opt?:{ summary?:string, notes?:string, verbs?:string, priority?:number, matches?:string, }) : ClassDecoratorDef
|
125
|
+
export function route(path:string, opt?:{ summary?:string, notes?:string, verbs?:string, priority?:number, matches?:string, }|string) : ClassDecoratorDef
|
69
126
|
export function icon(opt?:{ svg?:string, uri?:string, alt?:string, cls?:string, }) : ClassDecoratorDef
|
70
127
|
export function field(opt?:InputAttrOptions & { name?:string, fieldCss?:string, inputCss?:string, labelCss?:string, }) : ClassDecoratorDef
|
71
128
|
export function tag(name:string) : ClassDecoratorDef
|
72
129
|
export function worker(name:string) : ClassDecoratorDef
|
73
130
|
export function notes(notes:string) : ClassDecoratorDef
|
74
131
|
export function namedConnection(name:string) : ClassDecoratorDef
|
75
|
-
|
132
|
+
export function explorerCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassDecoratorDef
|
133
|
+
export function locodeCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassDecoratorDef
|
134
|
+
|
76
135
|
export enum QueryTerm { Default = 0, And = 1, Or = 2, Ensure = 3, }
|
77
136
|
export function queryDb(defaultTerm:QueryTerm) : ClassDecoratorDef
|
78
137
|
export function queryData(defaultTerm:QueryTerm) : ClassDecoratorDef
|
79
138
|
export function autoFilter(term:QueryTerm, field?:string, opt?:{ operand?:string, template?:string, valueFormat:string }) : ClassDecoratorDef
|
80
139
|
export function autoPopulate(field?:string, opt?:ScriptValueOptions) : ClassDecoratorDef
|
140
|
+
export function autoApply(name:string|Behavior, args?:string[]) : ClassDecoratorDef
|
141
|
+
|
81
142
|
export class SqlTemplate {
|
82
143
|
static IsNull: string
|
83
144
|
static IsNotNull: string
|
@@ -89,15 +150,23 @@ declare global {
|
|
89
150
|
static CaseSensitiveLike: string
|
90
151
|
static CaseInsensitiveLike: string
|
91
152
|
}
|
153
|
+
export enum Behavior {
|
154
|
+
AuditQuery,
|
155
|
+
AuditCreate,
|
156
|
+
AuditModify,
|
157
|
+
AuditDelete,
|
158
|
+
AuditSoftDelete,
|
159
|
+
}
|
92
160
|
|
93
161
|
export function alias(table:string) : ClassOrFieldDecoratorDef
|
94
162
|
export function meta(name:string,value:string) : ClassOrFieldDecoratorDef
|
95
163
|
export function priority(value:string) : ClassOrFieldDecoratorDef
|
96
|
-
|
164
|
+
export function description(description:string) : ClassOrFieldDecoratorDef
|
165
|
+
|
97
166
|
// Enum decorators
|
98
167
|
export function flags() : ClassDecoratorDef
|
99
168
|
export function enumMember(opt:{ value:string }) : ClassFieldDecoratorDef
|
100
|
-
|
169
|
+
|
101
170
|
export function validate(validator:string) : ClassFieldDecoratorDef
|
102
171
|
export function validateNull() : ClassFieldDecoratorDef
|
103
172
|
export function validateEmpty() : ClassFieldDecoratorDef
|
@@ -119,10 +188,10 @@ declare global {
|
|
119
188
|
export function validateNotEqualExpression(value:string|number|boolean) : ClassFieldDecoratorDef
|
120
189
|
export function validateInclusiveBetween(from:string|number,to:string|number) : ClassFieldDecoratorDef
|
121
190
|
export function validateExclusiveBetween(from:string|number,to:string|number) : ClassFieldDecoratorDef
|
122
|
-
|
191
|
+
|
123
192
|
export function allowReset() : ClassFieldDecoratorDef
|
124
193
|
export function denyReset() : ClassFieldDecoratorDef
|
125
|
-
|
194
|
+
|
126
195
|
export function primaryKey() : ClassFieldDecoratorDef
|
127
196
|
export function autoId() : ClassFieldDecoratorDef
|
128
197
|
export function autoIncrement() : ClassFieldDecoratorDef
|
@@ -141,7 +210,6 @@ declare global {
|
|
141
210
|
export function customUpdate(sql:string) : ClassFieldDecoratorDef
|
142
211
|
export function decimalLength(precision:number, scale?:number) : ClassFieldDecoratorDef
|
143
212
|
export function Default(value:string|number|boolean) : ClassFieldDecoratorDef
|
144
|
-
export function description(description:string) : ClassFieldDecoratorDef
|
145
213
|
export function enumAsInt() : ClassFieldDecoratorDef
|
146
214
|
export function excludeMetadata() : ClassFieldDecoratorDef
|
147
215
|
export function excludeFromDescription() : ClassFieldDecoratorDef
|
@@ -159,61 +227,58 @@ declare global {
|
|
159
227
|
export function returnOnInsert() : ClassFieldDecoratorDef
|
160
228
|
export function rowVersion() : ClassFieldDecoratorDef
|
161
229
|
export function unique() : ClassFieldDecoratorDef
|
162
|
-
|
230
|
+
|
163
231
|
export enum ValueStyle { Single, Multiple, List, }
|
164
232
|
export function queryDbField(opt?:{ term:QueryTerm, operand?:string, template?:string, field?:string, valueFormat?:string, valueStyle?:ValueStyle, valueArity?:number }) : ClassFieldDecoratorDef
|
165
233
|
export function queryDataField(opt?:{ term:QueryTerm, condition?:string, field?:string }) : ClassFieldDecoratorDef
|
166
|
-
|
234
|
+
|
167
235
|
export enum AutoUpdateStyle { Always, NonDefaults }
|
168
236
|
export function autoUpdate(style:AutoUpdateStyle) : ClassFieldDecoratorDef
|
169
|
-
export function autoDefault(opt:ScriptValueOptions) :
|
170
|
-
export function autoMap(to:string) :
|
237
|
+
export function autoDefault(opt:ScriptValueOptions) : ClassOrFieldDecoratorDef
|
238
|
+
export function autoMap(to:string) : ClassOrFieldDecoratorDef
|
171
239
|
export function autoIgnore() : ClassFieldDecoratorDef
|
172
|
-
|
173
|
-
|
240
|
+
|
174
241
|
export function apiMember(opt?:{ name?:string, verb?:string, parameterType?:string, description?:string, dataType?:string,
|
175
242
|
format?:string, isRequired?:boolean, isOptional?:boolean, allowMultiple?:boolean, route?:string, excludeInSchema?:boolean
|
176
243
|
}) : ClassFieldDecoratorDef
|
177
244
|
export function apiAllowableValues(name:string, opt?:{ type?:"RANGE"|"LIST", min?:number, max?:number, values?:string[] }) : ClassFieldDecoratorDef
|
178
|
-
|
245
|
+
|
179
246
|
export function dataMember(opt?:{ name?:string, order?:number, isRequired?:boolean }) : ClassFieldDecoratorDef
|
180
247
|
export function input(opt?:InputAttrOptions) : ClassFieldDecoratorDef
|
181
248
|
export function fieldCss(opt?:{ field?:string, input?:string, label?:string, }) : ClassFieldDecoratorDef
|
182
|
-
export function explorerCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassFieldDecoratorDef
|
183
|
-
export function locodeCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassFieldDecoratorDef
|
184
249
|
export function uploadTo(location:string) : ClassFieldDecoratorDef
|
185
250
|
export function ref(opt?:{ modelType?:TypeOf, model?:string, refId?:string, refLabel?:string, selfId?:string, queryType?:TypeOf, none?:boolean, }) : ClassFieldDecoratorDef
|
186
251
|
export type FormatMethods = "currency"|"bytes"|"icon"|"iconRounded"|"attachment"|"link"|"linkMailTo"|"linkTel"|"enumFlags"|"hidden"
|
187
252
|
export function format(method:FormatMethods, opt?:{ options?:string, locale?:string }) : ClassFieldDecoratorDef
|
188
|
-
|
253
|
+
|
189
254
|
export enum IntlFormat { Number, DateTime, RelativeTime }
|
190
255
|
export enum NumberStyle { Undefined=0, Decimal, Currency, Percent, Unit, }
|
191
256
|
export enum DateStyle { Undefined=0, Full, Long, Medium, Short, }
|
192
257
|
export enum TimeStyle { Undefined=0, Full, Long, Medium, Short, }
|
193
258
|
export enum Numeric { Undefined=0, Always, Auto, }
|
194
|
-
|
259
|
+
|
195
260
|
export enum DatePart { Undefined=0, Numeric, Digits2, }
|
196
261
|
export enum DateMonth { Undefined=0, Numeric, Digits2, Narrow, Short, Long, }
|
197
262
|
export enum DateText { Undefined=0, Narrow, Short, Long }
|
198
|
-
|
263
|
+
|
199
264
|
export enum CurrencyDisplay { Undefined=0, Symbol, NarrowSymbol, Code, Name, }
|
200
265
|
export enum CurrencySign { Undefined=0, Accounting, Standard, }
|
201
266
|
export enum SignDisplay { Undefined=0, Always, Auto, ExceptZero, Negative, Never, }
|
202
267
|
export enum RoundingMode { Undefined=0, Ceil, Floor, Expand, Trunc, HalfCeil, HalfFloor, HalfExpand, HalfTrunc, HalfEven, }
|
203
|
-
|
268
|
+
|
204
269
|
export enum UnitDisplay { Undefined=0, Long, Short, Narrow }
|
205
270
|
export enum Notation { Undefined=0, Standard, Scientific, Engineering, Compact, }
|
206
|
-
|
271
|
+
|
207
272
|
export type IntlOptions = { locale?:string, options?:string, number?:NumberStyle, date?:DateStyle, time?:TimeStyle, numeric?:Numeric,
|
208
273
|
currency?:string, currencyDisplay?:CurrencyDisplay, currencySign?:CurrencySign, signDisplay?:SignDisplay, roundingMode?:RoundingMode,
|
209
274
|
unit?:string, unitDisplay?:UnitDisplay, notation?:Notation,
|
210
|
-
minimumIntegerDigits?:number, minimumFractionDigits?:number, maximumFractionDigits?:number, minimumSignificantDigits?:number, maximumSignificantDigits?:number, fractionalSecondDigits?:number,
|
211
|
-
weekday?:DateText, era?:DateText, year?:DatePart, month?:DateMonth, day?:DatePart, hour?:DatePart, minute?:DatePart, second?:DatePart,
|
275
|
+
minimumIntegerDigits?:number, minimumFractionDigits?:number, maximumFractionDigits?:number, minimumSignificantDigits?:number, maximumSignificantDigits?:number, fractionalSecondDigits?:number,
|
276
|
+
weekday?:DateText, era?:DateText, year?:DatePart, month?:DateMonth, day?:DatePart, hour?:DatePart, minute?:DatePart, second?:DatePart,
|
212
277
|
timeZoneName?:DateText, timeZone?:string, hour12?:boolean
|
213
278
|
}
|
214
|
-
|
279
|
+
|
215
280
|
export function intl(type:IntlFormat, opt?:IntlOptions) : ClassFieldDecoratorDef
|
216
|
-
export function intlNumber(number?:NumberStyle) : ClassFieldDecoratorDef
|
281
|
+
export function intlNumber(number?:NumberStyle|IntlOptions, opt?:IntlOptions) : ClassFieldDecoratorDef
|
217
282
|
export function intlDateTime(date?:DateStyle, time?:TimeStyle) : ClassFieldDecoratorDef
|
218
283
|
export function intlRelativeTime(numeric?:Numeric) : ClassFieldDecoratorDef
|
219
284
|
|
@@ -238,15 +303,16 @@ declare global {
|
|
238
303
|
queryData:typeof queryData
|
239
304
|
autoFilter:typeof autoFilter
|
240
305
|
autoPopulate:typeof autoPopulate
|
306
|
+
autoApply:typeof autoApply
|
241
307
|
|
242
308
|
route:typeof route
|
243
309
|
field:typeof field
|
244
310
|
tag:typeof tag
|
245
311
|
notes:typeof notes
|
246
|
-
|
312
|
+
|
247
313
|
// Type and Attrs
|
248
314
|
dataContract:typeof dataContract
|
249
|
-
|
315
|
+
|
250
316
|
// DataModelAttrs
|
251
317
|
schema:typeof schema
|
252
318
|
compositeKey:typeof compositeKey
|
@@ -257,12 +323,14 @@ declare global {
|
|
257
323
|
|
258
324
|
namedConnection:typeof namedConnection
|
259
325
|
icon:typeof icon
|
326
|
+
locodeCss: typeof locodeCss
|
327
|
+
explorerCss: typeof explorerCss
|
260
328
|
|
261
329
|
// Class or Field Attrs
|
262
330
|
alias:typeof alias
|
263
331
|
meta:typeof meta // Type
|
264
332
|
flags:typeof flags // Enum
|
265
|
-
|
333
|
+
|
266
334
|
// RequestPropAttrs
|
267
335
|
validate:typeof validate
|
268
336
|
validateNull:typeof validateNull
|
@@ -294,7 +362,6 @@ declare global {
|
|
294
362
|
autoDefault:typeof autoDefault
|
295
363
|
autoMap:typeof autoMap
|
296
364
|
autoIgnore:typeof autoIgnore
|
297
|
-
autoApply:typeof autoApply
|
298
365
|
|
299
366
|
apiMember:typeof apiMember
|
300
367
|
apiAllowableValues:typeof apiAllowableValues
|
@@ -304,11 +371,12 @@ declare global {
|
|
304
371
|
uploadTo:typeof uploadTo
|
305
372
|
|
306
373
|
enumMember:typeof enumMember
|
307
|
-
|
374
|
+
|
308
375
|
// DataModelPropAttrs
|
309
376
|
// alias:typeof alias
|
310
377
|
// meta:typeof meta
|
311
378
|
priority:typeof priority
|
379
|
+
description:typeof description
|
312
380
|
|
313
381
|
primaryKey:typeof primaryKey
|
314
382
|
autoId:typeof autoId
|
@@ -328,7 +396,6 @@ declare global {
|
|
328
396
|
customUpdate:typeof customUpdate
|
329
397
|
decimalLength:typeof decimalLength
|
330
398
|
Default:typeof Default
|
331
|
-
description:typeof description
|
332
399
|
enumAsInt:typeof enumAsInt
|
333
400
|
excludeMetadata:typeof excludeMetadata
|
334
401
|
excludeFromDescription:typeof excludeFromDescription
|
@@ -352,7 +419,7 @@ declare global {
|
|
352
419
|
intlNumber:typeof intlNumber
|
353
420
|
intlDateTime:typeof intlDateTime
|
354
421
|
intlRelativeTime:typeof intlRelativeTime
|
355
|
-
}
|
422
|
+
}
|
356
423
|
export const Read : All
|
357
424
|
export const Write : All
|
358
425
|
export const Create : All
|
package/dist/cs-apis.js
CHANGED
@@ -22,42 +22,49 @@ export class CSharpApiGenerator extends CSharpGenerator {
|
|
22
22
|
: `IReturnVoid`);
|
23
23
|
}
|
24
24
|
}
|
25
|
-
|
25
|
+
const attrs = cls.attributes ?? [];
|
26
|
+
const hasTypeAttr = (name) => attrs.some(x => x.name === name);
|
27
|
+
if (op.tags?.length && !attrs.some(x => x.name === 'Tag')) {
|
26
28
|
for (const tag of op.tags) {
|
27
|
-
|
29
|
+
attrs.push({ name: 'Tag', constructorArgs: [{ name: 'tag', type: 'string', value: tag }] });
|
28
30
|
}
|
29
31
|
}
|
30
32
|
if (op.requiredRoles?.length) {
|
31
33
|
const adminRole = op.requiredRoles.includes('Admin');
|
32
|
-
if (adminRole && !
|
33
|
-
|
34
|
+
if (adminRole && !hasTypeAttr('ValidateIsAdmin')) {
|
35
|
+
attrs.push({ name: 'ValidateIsAdmin' });
|
34
36
|
}
|
35
37
|
const roles = op.requiredRoles.filter(r => r !== 'Admin');
|
36
|
-
if (roles.length && !
|
37
|
-
|
38
|
+
if (roles.length && !hasTypeAttr('ValidateHasRole')) {
|
39
|
+
attrs.push({ name: 'ValidateHasRole', constructorArgs: [{ name: 'role', type: 'string', value: roles[0] }] });
|
38
40
|
}
|
39
41
|
}
|
40
|
-
else if (op.requiresAuth && !
|
41
|
-
|
42
|
+
else if (op.requiresAuth && !(hasTypeAttr('ValidateIsAuthenticated') || hasTypeAttr('ValidateIsAdmin') || hasTypeAttr('ValidateHasRole'))) {
|
43
|
+
attrs.push({ name: 'ValidateIsAuthenticated' });
|
42
44
|
}
|
43
|
-
if (cls.description && !
|
44
|
-
|
45
|
+
if (cls.description && !hasTypeAttr('Api')) {
|
46
|
+
attrs.push({ name: 'Api', constructorArgs: [{ name: 'description', type: 'string', value: cls.description }] });
|
45
47
|
}
|
46
|
-
|
47
|
-
sb.push(this.toAttribtue(attr));
|
48
|
-
}
|
49
|
-
if (op.routes?.length) {
|
48
|
+
if (op.routes?.length && !attrs.some(x => x.name === 'Route')) {
|
50
49
|
for (const route of op.routes) {
|
51
|
-
|
50
|
+
attrs.push({ name: 'Route', constructorArgs: [
|
51
|
+
{ name: 'path', type: 'string', value: route.path },
|
52
|
+
{ name: 'verbs', type: 'string', value: route.verbs ?? "POST" }
|
53
|
+
] });
|
52
54
|
}
|
53
55
|
}
|
56
|
+
for (const attr of this.sortAttributes(attrs)) {
|
57
|
+
sb.push(this.toAttribtue(attr));
|
58
|
+
}
|
54
59
|
sb.push(clsDef);
|
55
60
|
sb.push('{');
|
56
61
|
for (const prop of cls.properties) {
|
62
|
+
const hasPropAttr = (name) => prop.attributes?.some(x => x.name === name);
|
63
|
+
const attrs = prop.attributes ?? [];
|
57
64
|
this.addNamespace(prop.namespace);
|
58
|
-
if (prop.description && !
|
65
|
+
if (prop.description && !hasPropAttr('ApiMember')) {
|
59
66
|
if (!prop.description.includes('\n')) {
|
60
|
-
|
67
|
+
attrs.push({ name: 'ApiMember', args: [{ name: 'Description', type: 'string', value: prop.description.replace(/"/g, '\\"') }] });
|
61
68
|
}
|
62
69
|
else {
|
63
70
|
sb.push(` [ApiMember(Description=\n` +
|
@@ -66,7 +73,7 @@ export class CSharpApiGenerator extends CSharpGenerator {
|
|
66
73
|
` """)]`);
|
67
74
|
}
|
68
75
|
}
|
69
|
-
for (const attr of
|
76
|
+
for (const attr of this.sortAttributes(attrs)) {
|
70
77
|
const def = this.toAttribtue(attr);
|
71
78
|
sb.push(` ${def}`);
|
72
79
|
}
|
package/dist/cs-ast.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { getGroupName, leftPart, plural, rightPart, splitCase, toPascalCase } from "./utils.js";
|
2
|
-
import {
|
1
|
+
import { getGroupName, lastLeftPart, leftPart, plural, rightPart, splitCase, toPascalCase } from "./utils.js";
|
2
|
+
import { getIcon } from "./icons.js";
|
3
3
|
const sys = (name, genericArgs) => ({ name, namespace: "System", genericArgs });
|
4
4
|
const sysObj = sys("object");
|
5
5
|
const sysDictObj = { name: "Dictionary", genericArgs: ["string", "object"], namespace: "System.Collections.Generic" };
|
@@ -38,9 +38,6 @@ export class CSharpAst {
|
|
38
38
|
decimalTypeProps = [
|
39
39
|
"price", "cost", "amount", "total", "salary", "balance", "rate", "discount", "tax", "fee"
|
40
40
|
];
|
41
|
-
currencyTypeProps = [
|
42
|
-
"price", "cost", "total", "salary", "balance", "tax", "fee"
|
43
|
-
];
|
44
41
|
valueTypes = [
|
45
42
|
"int", "long", "short", "ulong", "ushort", "sbyte", "uint", "char", "byte", "float", "double", "decimal", "bool",
|
46
43
|
"Int16", "Int32", "Int64", "UInt16", "UInt32", "UInt64", "SByte", "Byte", "Single", "Double", "Decimal", "Boolean",
|
@@ -75,6 +72,7 @@ export class CSharpAst {
|
|
75
72
|
'field',
|
76
73
|
'tag',
|
77
74
|
'notes',
|
75
|
+
'description',
|
78
76
|
'meta',
|
79
77
|
'dataContract',
|
80
78
|
].map(x => x.toLowerCase());
|
@@ -90,6 +88,8 @@ export class CSharpAst {
|
|
90
88
|
'icon',
|
91
89
|
'meta',
|
92
90
|
'dataContract',
|
91
|
+
'notes',
|
92
|
+
'description',
|
93
93
|
].map(x => x.toLowerCase());
|
94
94
|
requestPropAttrs = [
|
95
95
|
'validate',
|
@@ -179,6 +179,11 @@ export class CSharpAst {
|
|
179
179
|
'intlDateTime',
|
180
180
|
'intlRelativeTime',
|
181
181
|
].map(x => x.toLowerCase());
|
182
|
+
// Only generate these attributes when it's API specific, e.g. Read.notes("...")
|
183
|
+
targetOnlyAttrs = [
|
184
|
+
'notes',
|
185
|
+
'description',
|
186
|
+
].map(x => x.toLowerCase());
|
182
187
|
// Ignore properties with these attributes on APIs
|
183
188
|
ignoreCreateProps = [
|
184
189
|
'autoIncrement',
|
@@ -312,14 +317,6 @@ export class CSharpAst {
|
|
312
317
|
if (!prop.isValueType && !prop.type.endsWith('?')) {
|
313
318
|
prop.isRequired = true;
|
314
319
|
}
|
315
|
-
if (this.currencyTypeProps.some(x => prop.name.toLowerCase().includes(x))) {
|
316
|
-
if (!prop.attributes)
|
317
|
-
prop.attributes = [];
|
318
|
-
prop.attributes.push({
|
319
|
-
name: "IntlNumber",
|
320
|
-
args: [{ name: "Currency", type: "constant", value: "NumberCurrency.USD" }]
|
321
|
-
});
|
322
|
-
}
|
323
320
|
if (p.annotations?.length) {
|
324
321
|
prop.attributes = p.annotations.map(x => this.csharpAttribute(x));
|
325
322
|
}
|
@@ -332,6 +329,9 @@ export class CSharpAst {
|
|
332
329
|
if (cls.extends) {
|
333
330
|
type.inherits = { name: this.toCsName(cls.extends) };
|
334
331
|
}
|
332
|
+
if (cls.implements?.length) {
|
333
|
+
type.implements = cls.implements.filter(x => !x.startsWith("IReturn")).map(x => this.csharpType(x));
|
334
|
+
}
|
335
335
|
if (cls.annotations?.length) {
|
336
336
|
type.attributes = cls.annotations.map(x => this.csharpAttribute(x));
|
337
337
|
}
|
@@ -348,8 +348,46 @@ export class CSharpAst {
|
|
348
348
|
this.addMetadataType(refType);
|
349
349
|
}
|
350
350
|
});
|
351
|
-
if (
|
352
|
-
this.result.types.
|
351
|
+
if (isDataModel(type) || type.isEnum) {
|
352
|
+
if (!this.result.types.find(x => x.name === cls.name && x.namespace === 'MyApp')) {
|
353
|
+
this.result.types.push(type);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
else {
|
357
|
+
if (!this.result.operations.find(x => x.request.name === cls.name)) {
|
358
|
+
let method = "POST";
|
359
|
+
if (cls.extends?.startsWith('Query')) {
|
360
|
+
method = "GET";
|
361
|
+
}
|
362
|
+
let impls = cls.implements;
|
363
|
+
if (impls?.length) {
|
364
|
+
if (impls.includes('ICreate')) {
|
365
|
+
method = "POST";
|
366
|
+
}
|
367
|
+
else if (impls.includes('IUpdate')) {
|
368
|
+
method = "PUT";
|
369
|
+
}
|
370
|
+
else if (impls.includes('IPatch')) {
|
371
|
+
method = "PATCH";
|
372
|
+
}
|
373
|
+
else if (impls.includes('IDelete')) {
|
374
|
+
method = "DELETE";
|
375
|
+
}
|
376
|
+
}
|
377
|
+
const op = {
|
378
|
+
request: type,
|
379
|
+
actions: ["ANY"],
|
380
|
+
method,
|
381
|
+
};
|
382
|
+
const iReturn = impls?.find(x => x.startsWith('IReturn<'));
|
383
|
+
if (iReturn) {
|
384
|
+
op.returnType = this.csharpType(lastLeftPart(rightPart(iReturn, '<'), '>'));
|
385
|
+
}
|
386
|
+
if (impls?.includes('IReturnVoid')) {
|
387
|
+
op.returnsVoid = true;
|
388
|
+
}
|
389
|
+
this.result.operations.push(op);
|
390
|
+
}
|
353
391
|
}
|
354
392
|
return type;
|
355
393
|
}
|
@@ -413,6 +451,7 @@ export class CSharpAst {
|
|
413
451
|
? this.ignoreDeleteValidators
|
414
452
|
: []
|
415
453
|
: [];
|
454
|
+
const targetOnlyAttrs = this.targetOnlyAttrs;
|
416
455
|
function shouldInclude(attr, dtoType) {
|
417
456
|
if (!validAttrs.includes(attr.name.toLowerCase()))
|
418
457
|
return false;
|
@@ -436,6 +475,9 @@ export class CSharpAst {
|
|
436
475
|
const nameLower = attr.name.toLowerCase();
|
437
476
|
if (isRequest) {
|
438
477
|
if (attrType === "Type") {
|
478
|
+
if (targetOnlyAttrs.includes(nameLower)) {
|
479
|
+
return false;
|
480
|
+
}
|
439
481
|
return requestAttrs.includes(nameLower);
|
440
482
|
}
|
441
483
|
else if (attrType === "Prop") {
|
@@ -467,12 +509,15 @@ export class CSharpAst {
|
|
467
509
|
const groupName = getGroupName(this.result);
|
468
510
|
const friendlyGroupName = splitCase(groupName);
|
469
511
|
for (const type of this.classes) {
|
512
|
+
if (!isDataModel(type))
|
513
|
+
continue;
|
470
514
|
const hasPk = type.properties?.some(x => x.isPrimaryKey);
|
471
515
|
if (!hasPk)
|
472
516
|
continue;
|
473
517
|
const pluralizedType = plural(type.name);
|
474
518
|
const queryName = `Query${pluralizedType}`;
|
475
|
-
let queryApi = this.result.operations.find(x => x.request.name === queryName
|
519
|
+
let queryApi = this.result.operations.find(x => x.request.name === queryName
|
520
|
+
|| (x.request.inherits?.name.startsWith('Query') && x.request.inherits?.genericArgs?.some(a => a === type.name)));
|
476
521
|
const pk = type.properties?.find(x => x.isPrimaryKey);
|
477
522
|
const dataModel = { name: type.name, namespace: type.name };
|
478
523
|
const isAuditBase = type.inherits?.name === 'AuditBase';
|
@@ -545,7 +590,8 @@ export class CSharpAst {
|
|
545
590
|
this.result.operations.push(queryApi);
|
546
591
|
}
|
547
592
|
let createName = `Create${type.name}`;
|
548
|
-
let createApi = this.result.operations.find(x => x.request.name === createName
|
593
|
+
let createApi = this.result.operations.find(x => x.request.name === createName
|
594
|
+
|| (x.request.implements?.some(i => i.name.startsWith("ICreate") && x.dataModel == dataModel)));
|
549
595
|
if (!createApi) {
|
550
596
|
createApi = {
|
551
597
|
method: "POST",
|
@@ -619,7 +665,9 @@ export class CSharpAst {
|
|
619
665
|
this.result.operations.push(createApi);
|
620
666
|
}
|
621
667
|
let updateName = `Update${type.name}`;
|
622
|
-
let updateApi = this.result.operations.find(x => x.request.name === updateName
|
668
|
+
let updateApi = this.result.operations.find(x => x.request.name === updateName
|
669
|
+
|| x.dataModel == dataModel && (x.request.implements?.some(i => i.name.startsWith("IPatch")) ||
|
670
|
+
x.request.implements?.some(i => i.name.startsWith("IUpdate"))));
|
623
671
|
if (!updateApi) {
|
624
672
|
updateApi = {
|
625
673
|
method: "PATCH",
|
@@ -672,7 +720,8 @@ export class CSharpAst {
|
|
672
720
|
this.result.operations.push(updateApi);
|
673
721
|
}
|
674
722
|
let deleteName = `Delete${type.name}`;
|
675
|
-
let deleteApi = this.result.operations.find(x => x.request.name === deleteName
|
723
|
+
let deleteApi = this.result.operations.find(x => x.request.name === deleteName
|
724
|
+
|| (x.request.implements?.some(i => i.name.startsWith("IDelete") && x.dataModel == dataModel)));
|
676
725
|
if (!deleteApi) {
|
677
726
|
deleteApi = {
|
678
727
|
method: "DELETE",
|
@@ -721,6 +770,8 @@ export class CSharpAst {
|
|
721
770
|
}
|
722
771
|
filterModelAttributes() {
|
723
772
|
for (const type of this.classes) {
|
773
|
+
if (!isDataModel(type))
|
774
|
+
continue;
|
724
775
|
if (type.attributes?.length) {
|
725
776
|
type.attributes = this.attrsFor("Model", "Type", type.attributes);
|
726
777
|
}
|
@@ -822,9 +873,6 @@ export function replaceReference(gen, fromType, toType) {
|
|
822
873
|
}
|
823
874
|
}
|
824
875
|
}
|
825
|
-
export function replaceServiceReferences(gen) {
|
826
|
-
replaceReferences(gen, ['Service']);
|
827
|
-
}
|
828
876
|
export function replaceReferences(gen, references) {
|
829
877
|
// The most important types are the ones with the most references
|
830
878
|
const refCount = (t) => t.properties?.filter(p => gen.result.types.find(x => x.name === p.type && p.namespace === 'MyApp')).length || 0;
|
@@ -1000,7 +1048,7 @@ export function addAutoIncrementAttrs(gen) {
|
|
1000
1048
|
// Add Icon for BuiltIn UIs and AutoQueryGrid to known type names
|
1001
1049
|
export function addIconsToKnownTypes(gen) {
|
1002
1050
|
for (const type of gen.typesWithPrimaryKeys) {
|
1003
|
-
const icon =
|
1051
|
+
const icon = getIcon(type.name);
|
1004
1052
|
if (icon) {
|
1005
1053
|
if (!type.attributes)
|
1006
1054
|
type.attributes = [];
|
@@ -1059,3 +1107,8 @@ export function replaceUserReferencesWithAuditTables(gen) {
|
|
1059
1107
|
// Remove User Table
|
1060
1108
|
gen.result.types = gen.result.types.filter(x => x.name !== 'User');
|
1061
1109
|
}
|
1110
|
+
export function isDataModel(type) {
|
1111
|
+
const apiInterfacePrefixes = ['IReturn', 'IQuery', 'ICreate', 'IUpdate', 'IPatch', 'IDelete', 'IGet', 'IPost', 'IPut'];
|
1112
|
+
return (!type.inherits || !type.inherits.name.startsWith("Query"))
|
1113
|
+
&& (!type.implements || !type.implements.some(x => apiInterfacePrefixes.some(prefix => x.name.startsWith(prefix))));
|
1114
|
+
}
|