okai 0.0.22 → 0.0.23

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 ADDED
@@ -0,0 +1,352 @@
1
+ declare global {
2
+ export class AuditBase {
3
+ createdDate: Date
4
+ createdBy: string
5
+ modifiedDate: Date
6
+ modifiedBy: string
7
+ deletedDate?: Date
8
+ deletedBy?: string
9
+ }
10
+
11
+ export type TypeOf = `typeof(${string})`
12
+ export type InputAttrOptions = { type?:string, value?:string, placeholder?:string, help?:string, label?:string, title?:string, size?:string,
13
+ pattern?:string, readOnly?:boolean, required?:boolean, disabled?:boolean, autocomplete?:string, autofocus?:string,
14
+ min?:string, max?:string, step?:string, minLength?:number, maxLength?:number, accept?:string, capture?:string, multiple?:boolean,
15
+ allowableValues?:string[], allowableValuesEnum?:TypeOf, options?:string, ignore?:boolean, evalAllowableValues?:string, evalAllowableEntries?:string, }
16
+ export type ScriptValueOptions = { value?: any, expression?: string, eval?: string, noCache?: boolean }
17
+
18
+ type ClassDecoratorDef = (
19
+ target: any,
20
+ context: ClassDecoratorContext
21
+ ) => void
22
+
23
+ type ClassFieldDecoratorDef = (
24
+ target: any,
25
+ context: ClassFieldDecoratorContext
26
+ ) => void
27
+
28
+ type ClassOrFieldDecoratorDef = (
29
+ target: any,
30
+ context: ClassDecoratorContext | ClassFieldDecoratorContext
31
+ ) => void
32
+
33
+ export function validateRequest(validator:string) : ClassDecoratorDef
34
+ export function validateIsAuthenticated() : ClassDecoratorDef
35
+ export function validateIsAdmin() : ClassDecoratorDef
36
+ export function validateAuthSecret() : ClassDecoratorDef
37
+ export function validateHasRole(role:string) : ClassDecoratorDef
38
+ export function validateHasRoles(roles:string[]) : ClassDecoratorDef
39
+ export function validateHasPermission(permission:string) : ClassDecoratorDef
40
+ export function validateHasPermissions(permissions:string[]) : ClassDecoratorDef
41
+ export function validateHasClaim(claim:string) : ClassDecoratorDef
42
+ export function validateHasScope(scope:string) : ClassDecoratorDef
43
+ export function validateApiKey(scope?:string) : ClassDecoratorDef
44
+
45
+ export function schema(schema:string) : ClassDecoratorDef
46
+ export function compositeKey(columns:string[]) : ClassDecoratorDef
47
+ export function compositeIndex(unique:boolean, columns:string[]) : ClassDecoratorDef
48
+ export function preCreateTable(sql:string) : ClassDecoratorDef
49
+ export function preDropTable(sql:string) : ClassDecoratorDef
50
+ export function postCreateTable(sql:string) : ClassDecoratorDef
51
+ export function postDropTable(sql:string) : ClassDecoratorDef
52
+
53
+ export function api(description:string, opt?:{ bodyParameter?:number, requestContentType?:string, isRequired?:boolean }) : ClassDecoratorDef
54
+ export function apiResponse(statusCode:number, description:string, opt?:{ isDefaultResponse?:boolean, responseType?:TypeOf }) : ClassDecoratorDef
55
+
56
+ export function dataContract() : ClassDecoratorDef
57
+ export function route(path:string, opt?:{ summary?:string, notes?:string, verbs?:string, priority?:number, matches?:string, }) : ClassDecoratorDef
58
+ export function icon(opt?:{ svg?:string, uri?:string, alt?:string, cls?:string, }) : ClassDecoratorDef
59
+ export function field(opt?:InputAttrOptions & { name?:string, fieldCss?:string, inputCss?:string, labelCss?:string, }) : ClassDecoratorDef
60
+ export function tag(name:string) : ClassDecoratorDef
61
+ export function worker(name:string) : ClassDecoratorDef
62
+ export function notes(notes:string) : ClassDecoratorDef
63
+ export function namedConnection(name:string) : ClassDecoratorDef
64
+
65
+ export enum QueryTerm { Default = 0, And = 1, Or = 2, Ensure = 3, }
66
+ export function queryDb(defaultTerm:QueryTerm) : ClassDecoratorDef
67
+ export function queryData(defaultTerm:QueryTerm) : ClassDecoratorDef
68
+ export function autoFilter(term:QueryTerm, field?:string, opt?:{ operand?:string, template?:string, valueFormat:string }) : ClassDecoratorDef
69
+ export function autoPopulate(field?:string, opt?:ScriptValueOptions) : ClassDecoratorDef
70
+ export class SqlTemplate {
71
+ static IsNull: string
72
+ static IsNotNull: string
73
+ static GreaterThanOrEqual: string
74
+ static GreaterThan: string
75
+ static LessThan: string
76
+ static LessThanOrEqual: string
77
+ static NotEqual: string
78
+ static CaseSensitiveLike: string
79
+ static CaseInsensitiveLike: string
80
+ }
81
+
82
+ export function alias(table:string) : ClassOrFieldDecoratorDef
83
+ export function meta(name:string,value:string) : ClassOrFieldDecoratorDef
84
+ export function priority(value:string) : ClassOrFieldDecoratorDef
85
+
86
+ // Enum decorators
87
+ export function flags() : ClassDecoratorDef
88
+ export function enumMember(opt:{ value:string }) : ClassFieldDecoratorDef
89
+
90
+ export function validate(validator:string) : ClassFieldDecoratorDef
91
+ export function validateNull() : ClassFieldDecoratorDef
92
+ export function validateEmpty() : ClassFieldDecoratorDef
93
+ export function validateEmail() : ClassFieldDecoratorDef
94
+ export function validateNotNull() : ClassFieldDecoratorDef
95
+ export function validateNotEmpty() : ClassFieldDecoratorDef
96
+ export function validateCreditCard() : ClassFieldDecoratorDef
97
+ export function validateLength(min:number, max:number) : ClassFieldDecoratorDef
98
+ export function validateExactLength(length:number) : ClassFieldDecoratorDef
99
+ export function validateMinimumLength(min:number) : ClassFieldDecoratorDef
100
+ export function validateMaximumLength(max:number) : ClassFieldDecoratorDef
101
+ export function validateLessThanLength(value:number) : ClassFieldDecoratorDef
102
+ export function validateLessThanOrEqual(value:number) : ClassFieldDecoratorDef
103
+ export function validateGreaterThanLength(value:number) : ClassFieldDecoratorDef
104
+ export function validateGreaterThanOrEqual(value:number) : ClassFieldDecoratorDef
105
+ export function validateScalePrecision(scale:number, precision:number) : ClassFieldDecoratorDef
106
+ export function validateRegularExpression(pattern:string) : ClassFieldDecoratorDef
107
+ export function validateEqualExpression(value:string|number|boolean) : ClassFieldDecoratorDef
108
+ export function validateNotEqualExpression(value:string|number|boolean) : ClassFieldDecoratorDef
109
+ export function validateInclusiveBetween(from:string|number,to:string|number) : ClassFieldDecoratorDef
110
+ export function validateExclusiveBetween(from:string|number,to:string|number) : ClassFieldDecoratorDef
111
+
112
+ export function allowReset() : ClassFieldDecoratorDef
113
+ export function denyReset() : ClassFieldDecoratorDef
114
+
115
+ export function primaryKey() : ClassFieldDecoratorDef
116
+ export function autoId() : ClassFieldDecoratorDef
117
+ export function autoIncrement() : ClassFieldDecoratorDef
118
+ export function belongTo(BelongToTableType:TypeOf) : ClassFieldDecoratorDef
119
+ export function index(opt?:{ name?:string, unique?:boolean, clustered?:boolean, nonClustered?:boolean, }) : ClassFieldDecoratorDef
120
+ export function compute() : ClassFieldDecoratorDef
121
+ export function computed() : ClassFieldDecoratorDef
122
+ export function persisted() : ClassFieldDecoratorDef
123
+ export function uniqueConstraint(columns:string[]) : ClassFieldDecoratorDef
124
+ export function addColumn() : ClassFieldDecoratorDef
125
+ export function removeColumn() : ClassFieldDecoratorDef
126
+ export function checkConstraint(constraint:string) : ClassFieldDecoratorDef
127
+ export function customField(sql:string, order?:number) : ClassFieldDecoratorDef
128
+ export function customSelect(sql:string) : ClassFieldDecoratorDef
129
+ export function customInsert(sql:string) : ClassFieldDecoratorDef
130
+ export function customUpdate(sql:string) : ClassFieldDecoratorDef
131
+ export function decimalLength(precision:number, scale?:number) : ClassFieldDecoratorDef
132
+ export function Default(value:string|number|boolean) : ClassFieldDecoratorDef
133
+ export function description(description:string) : ClassFieldDecoratorDef
134
+ export function enumAsInt() : ClassFieldDecoratorDef
135
+ export function excludeMetadata() : ClassFieldDecoratorDef
136
+ export function excludeFromDescription() : ClassFieldDecoratorDef
137
+ export function explicitAutoQuery() : ClassFieldDecoratorDef
138
+ export type foreignKeyBehavior = "NO ACTION"|"RESTRICT"|"SET NULL"|"SET DEFAULT"|"CASCADE"
139
+ export function foreignKey(type:string, opt?:{ onDelete?:foreignKeyBehavior, onUpdate?:foreignKeyBehavior, foreignKeyName?:string }) : ClassFieldDecoratorDef
140
+ export function ignore() : ClassFieldDecoratorDef
141
+ export function ignoreOnUpdate() : ClassFieldDecoratorDef
142
+ export function ignoreOnInsert() : ClassFieldDecoratorDef
143
+ export function ignoreDataMember() : ClassFieldDecoratorDef
144
+ export function reference() : ClassFieldDecoratorDef
145
+ export function referenceField(model:TypeOf, id?:string, field?:string) : ClassFieldDecoratorDef
146
+ export function references(type:TypeOf) : ClassFieldDecoratorDef
147
+ export function required() : ClassFieldDecoratorDef
148
+ export function returnOnInsert() : ClassFieldDecoratorDef
149
+ export function rowVersion() : ClassFieldDecoratorDef
150
+ export function unique() : ClassFieldDecoratorDef
151
+
152
+ export enum ValueStyle { Single, Multiple, List, }
153
+ export function queryDbField(opt?:{ term:QueryTerm, operand?:string, template?:string, field?:string, valueFormat?:string, valueStyle?:ValueStyle, valueArity?:number }) : ClassFieldDecoratorDef
154
+ export function queryDataField(opt?:{ term:QueryTerm, condition?:string, field?:string }) : ClassFieldDecoratorDef
155
+
156
+ export enum AutoUpdateStyle { Always, NonDefaults }
157
+ export function autoUpdate(style:AutoUpdateStyle) : ClassFieldDecoratorDef
158
+ export function autoDefault(opt:ScriptValueOptions) : ClassFieldDecoratorDef
159
+ export function autoMap(to:string) : ClassFieldDecoratorDef
160
+ export function autoIgnore() : ClassFieldDecoratorDef
161
+ export function autoApply(name:string, args?:string[]) : ClassFieldDecoratorDef
162
+
163
+ export function apiMember(opt?:{ name?:string, verb?:string, parameterType?:string, description?:string, dataType?:string,
164
+ format?:string, isRequired?:boolean, isOptional?:boolean, allowMultiple?:boolean, route?:string, excludeInSchema?:boolean
165
+ }) : ClassFieldDecoratorDef
166
+ export function apiAllowableValues(name:string, opt?:{ type?:"RANGE"|"LIST", min?:number, max?:number, values?:string[] }) : ClassFieldDecoratorDef
167
+
168
+ export function dataMember(opt?:{ name?:string, order?:number, isRequired?:boolean }) : ClassFieldDecoratorDef
169
+ export function input(opt?:InputAttrOptions) : ClassFieldDecoratorDef
170
+ export function fieldCss(opt?:{ field?:string, input?:string, label?:string, }) : ClassFieldDecoratorDef
171
+ export function explorerCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassFieldDecoratorDef
172
+ export function locodeCss(opt?:{ form?:string, fieldset?:string, field?:string, }) : ClassFieldDecoratorDef
173
+ export function uploadTo(location:string) : ClassFieldDecoratorDef
174
+ export function ref(opt?:{ modelType?:TypeOf, model?:string, refId?:string, refLabel?:string, selfId?:string, queryType?:TypeOf, none?:boolean, }) : ClassFieldDecoratorDef
175
+ export type FormatMethods = "currency"|"bytes"|"icon"|"iconRounded"|"attachment"|"link"|"linkMailTo"|"linkTel"|"enumFlags"|"hidden"
176
+ export function format(method:FormatMethods, opt?:{ options?:string, locale?:string }) : ClassFieldDecoratorDef
177
+
178
+ export enum IntlFormat { Number, DateTime, RelativeTime }
179
+ export enum NumberStyle { Undefined=0, Decimal, Currency, Percent, Unit, }
180
+ export enum DateStyle { Undefined=0, Full, Long, Medium, Short, }
181
+ export enum TimeStyle { Undefined=0, Full, Long, Medium, Short, }
182
+ export enum Numeric { Undefined=0, Always, Auto, }
183
+
184
+ export enum DatePart { Undefined=0, Numeric, Digits2, }
185
+ export enum DateMonth { Undefined=0, Numeric, Digits2, Narrow, Short, Long, }
186
+ export enum DateText { Undefined=0, Narrow, Short, Long }
187
+
188
+ export enum CurrencyDisplay { Undefined=0, Symbol, NarrowSymbol, Code, Name, }
189
+ export enum CurrencySign { Undefined=0, Accounting, Standard, }
190
+ export enum SignDisplay { Undefined=0, Always, Auto, ExceptZero, Negative, Never, }
191
+ export enum RoundingMode { Undefined=0, Ceil, Floor, Expand, Trunc, HalfCeil, HalfFloor, HalfExpand, HalfTrunc, HalfEven, }
192
+
193
+ export enum UnitDisplay { Undefined=0, Long, Short, Narrow }
194
+ export enum Notation { Undefined=0, Standard, Scientific, Engineering, Compact, }
195
+
196
+ export type IntlOptions = { locale?:string, options?:string, number?:NumberStyle, date?:DateStyle, time?:TimeStyle, numeric?:Numeric,
197
+ currency?:string, currencyDisplay?:CurrencyDisplay, currencySign?:CurrencySign, signDisplay?:SignDisplay, roundingMode?:RoundingMode,
198
+ unit?:string, unitDisplay?:UnitDisplay, notation?:Notation,
199
+ minimumIntegerDigits?:number, minimumFractionDigits?:number, maximumFractionDigits?:number, minimumSignificantDigits?:number, maximumSignificantDigits?:number, fractionalSecondDigits?:number,
200
+ weekday?:DateText, era?:DateText, year?:DatePart, month?:DateMonth, day?:DatePart, hour?:DatePart, minute?:DatePart, second?:DatePart,
201
+ timeZoneName?:DateText, timeZone?:string, hour12?:boolean
202
+ }
203
+
204
+ export function intl(type:IntlFormat, opt?:IntlOptions) : ClassFieldDecoratorDef
205
+ export function intlNumber(number?:NumberStyle) : ClassFieldDecoratorDef
206
+ export function intlDateTime(date?:DateStyle, time?:TimeStyle) : ClassFieldDecoratorDef
207
+ export function intlRelativeTime(numeric?:Numeric) : ClassFieldDecoratorDef
208
+
209
+ //RequestAttrs & TypeAttrs & DataModelAttrs & RequestPropAttrs & DataModelPropAttrs
210
+ export class All {
211
+ // RequestAttrs
212
+ api:typeof api
213
+ apiResponse:typeof apiResponse
214
+ validateRequest:typeof validateRequest
215
+ validateIsAuthenticated:typeof validateIsAuthenticated
216
+ validateIsAdmin:typeof validateIsAdmin
217
+ validateAuthSecret:typeof validateAuthSecret
218
+ validateHasRole:typeof validateHasRole
219
+ validateHasRoles:typeof validateHasRoles
220
+ validateHasPermission:typeof validateHasPermission
221
+ validateHasPermissions:typeof validateHasPermissions
222
+ validateHasClaim:typeof validateHasClaim
223
+ validateHasScope:typeof validateHasScope
224
+ validateApiKey:typeof validateApiKey
225
+
226
+ queryDb:typeof queryDb
227
+ queryData:typeof queryData
228
+ autoFilter:typeof autoFilter
229
+ autoPopulate:typeof autoPopulate
230
+
231
+ route:typeof route
232
+ field:typeof field
233
+ tag:typeof tag
234
+ notes:typeof notes
235
+
236
+ // Type and Attrs
237
+ dataContract:typeof dataContract
238
+
239
+ // DataModelAttrs
240
+ schema:typeof schema
241
+ compositeKey:typeof compositeKey
242
+ preCreateTable:typeof preCreateTable
243
+ preDropTable:typeof preDropTable
244
+ postCreateTable:typeof postCreateTable
245
+ postDropTable:typeof postDropTable
246
+
247
+ namedConnection:typeof namedConnection
248
+ icon:typeof icon
249
+
250
+ // Class or Field Attrs
251
+ alias:typeof alias
252
+ meta:typeof meta // Type
253
+ flags:typeof flags // Enum
254
+
255
+ // RequestPropAttrs
256
+ validate:typeof validate
257
+ validateNull:typeof validateNull
258
+ validateEmpty:typeof validateEmpty
259
+ validateEmail:typeof validateEmail
260
+ validateNotNull:typeof validateNotNull
261
+ validateNotEmpty:typeof validateNotEmpty
262
+ validateCreditCard:typeof validateCreditCard
263
+ validateLength:typeof validateLength
264
+ validateExactLength:typeof validateExactLength
265
+ validateMinimumLength:typeof validateMinimumLength
266
+ validateMaximumLength:typeof validateMaximumLength
267
+ validateLessThanLength:typeof validateLessThanLength
268
+ validateLessThanOrEqual:typeof validateLessThanOrEqual
269
+ validateGreaterThanLength:typeof validateGreaterThanLength
270
+ validateGreaterThanOrEqual:typeof validateGreaterThanOrEqual
271
+ validateScalePrecision:typeof validateScalePrecision
272
+ validateRegularExpression:typeof validateRegularExpression
273
+ validateEqualExpression:typeof validateEqualExpression
274
+ validateNotEqualExpression:typeof validateNotEqualExpression
275
+ validateInclusiveBetween:typeof validateInclusiveBetween
276
+ validateExclusiveBetween:typeof validateExclusiveBetween
277
+ allowReset:typeof allowReset
278
+ denyReset:typeof denyReset
279
+
280
+ queryDbField:typeof queryDbField
281
+ queryDataField:typeof queryDataField
282
+ autoUpdate:typeof autoUpdate
283
+ autoDefault:typeof autoDefault
284
+ autoMap:typeof autoMap
285
+ autoIgnore:typeof autoIgnore
286
+ autoApply:typeof autoApply
287
+
288
+ apiMember:typeof apiMember
289
+ apiAllowableValues:typeof apiAllowableValues
290
+ dataMember:typeof dataMember
291
+ input:typeof input
292
+ fieldCss:typeof fieldCss
293
+ uploadTo:typeof uploadTo
294
+
295
+ enumMember:typeof enumMember
296
+
297
+ // DataModelPropAttrs
298
+ // alias:typeof alias
299
+ // meta:typeof meta
300
+ priority:typeof priority
301
+
302
+ primaryKey:typeof primaryKey
303
+ autoId:typeof autoId
304
+ autoIncrement:typeof autoIncrement
305
+ index:typeof index
306
+ compute:typeof compute
307
+ computed:typeof computed
308
+ persisted:typeof persisted
309
+ uniqueConstraint:typeof uniqueConstraint
310
+ addColumn:typeof addColumn
311
+ removeColumn:typeof removeColumn
312
+ belongTo:typeof belongTo
313
+ checkConstraint:typeof checkConstraint
314
+ customField:typeof customField
315
+ customSelect:typeof customSelect
316
+ customInsert:typeof customInsert
317
+ customUpdate:typeof customUpdate
318
+ decimalLength:typeof decimalLength
319
+ Default:typeof Default
320
+ description:typeof description
321
+ enumAsInt:typeof enumAsInt
322
+ excludeMetadata:typeof excludeMetadata
323
+ excludeFromDescription:typeof excludeFromDescription
324
+ explicitAutoQuery:typeof explicitAutoQuery
325
+ foreignKey:typeof foreignKey
326
+ ignore:typeof ignore
327
+ ignoreOnUpdate:typeof ignoreOnUpdate
328
+ ignoreOnInsert:typeof ignoreOnInsert
329
+ ignoreDataMember:typeof ignoreDataMember
330
+ reference:typeof reference
331
+ referenceField:typeof referenceField
332
+ references:typeof references
333
+ required:typeof required
334
+ returnOnInsert:typeof returnOnInsert
335
+ rowVersion:typeof rowVersion
336
+ unique:typeof unique
337
+
338
+ ref:typeof ref
339
+ format:typeof format
340
+ intl:typeof intl
341
+ intlNumber:typeof intlNumber
342
+ intlDateTime:typeof intlDateTime
343
+ intlRelativeTime:typeof intlRelativeTime
344
+ }
345
+ export const Read : All
346
+ export const Write : All
347
+ export const Create : All
348
+ export const Update : All
349
+ export const Delete : All
350
+ }
351
+
352
+ export {}
package/dist/cs-apis.js CHANGED
@@ -80,6 +80,8 @@ export class CSharpApiGenerator extends CSharpGenerator {
80
80
  const groupName = getGroupName(ast);
81
81
  const friendlyGroupName = splitCase(groupName);
82
82
  ast.operations.forEach(op => {
83
+ if (op.request.attributes?.find(x => x.name === 'Tag'))
84
+ return;
83
85
  if (!op.tags)
84
86
  op.tags = [];
85
87
  op.tags.push(friendlyGroupName);
package/dist/cs-ast.js CHANGED
@@ -1,4 +1,4 @@
1
- import { plural, toPascalCase } from "./utils.js";
1
+ import { leftPart, plural, rightPart, toPascalCase } from "./utils.js";
2
2
  import { Icons } from "./icons.js";
3
3
  const sys = (name, genericArgs) => ({ name, namespace: "System", genericArgs });
4
4
  const sysObj = sys("object");
@@ -34,6 +34,129 @@ export class CSharpAst {
34
34
  commonValueTypes = [
35
35
  "int", "Int32", "long", "Int64", "string",
36
36
  ];
37
+ requestAttrs = [
38
+ 'api',
39
+ 'apiResponse',
40
+ 'validateRequest',
41
+ 'validateIsAuthenticated',
42
+ 'validateIsAdmin',
43
+ 'validateAuthSecret',
44
+ 'validateHasRole',
45
+ 'validateHasRoles',
46
+ 'validateHasPermission',
47
+ 'validateHasPermissions',
48
+ 'validateHasClaim',
49
+ 'validateHasScope',
50
+ 'validateApiKey',
51
+ 'queryDb',
52
+ 'queryData',
53
+ 'autoFilter',
54
+ 'autoPopulate',
55
+ 'route',
56
+ 'field',
57
+ 'tag',
58
+ 'notes',
59
+ 'meta',
60
+ 'dataContract',
61
+ ].map(x => x.toLowerCase());
62
+ modelAttrs = [
63
+ 'schema',
64
+ 'compositeKey',
65
+ 'preCreateTable',
66
+ 'preDropTable',
67
+ 'postCreateTable',
68
+ 'postDropTable',
69
+ 'namedConnection',
70
+ 'alias',
71
+ 'icon',
72
+ 'meta',
73
+ 'dataContract',
74
+ ].map(x => x.toLowerCase());
75
+ requestPropAttrs = [
76
+ 'validate',
77
+ 'validateNull',
78
+ 'validateEmpty',
79
+ 'validateEmail',
80
+ 'validateNotNull',
81
+ 'validateNotEmpty',
82
+ 'validateCreditCard',
83
+ 'validateLength',
84
+ 'validateExactLength',
85
+ 'validateMinimumLength',
86
+ 'validateMaximumLength',
87
+ 'validateLessThanLength',
88
+ 'validateLessThanOrEqual',
89
+ 'validateGreaterThanLength',
90
+ 'validateGreaterThanOrEqual',
91
+ 'validateScalePrecision',
92
+ 'validateRegularExpression',
93
+ 'validateEqualExpression',
94
+ 'validateNotEqualExpression',
95
+ 'validateInclusiveBetween',
96
+ 'validateExclusiveBetween',
97
+ 'allowReset',
98
+ 'denyReset',
99
+ 'queryDbField',
100
+ 'queryDataField',
101
+ 'autoUpdate',
102
+ 'autoDefault',
103
+ 'autoMap',
104
+ 'autoIgnore',
105
+ 'autoApply',
106
+ 'apiMember',
107
+ 'apiAllowableValues',
108
+ 'dataMember',
109
+ 'input',
110
+ 'fieldCss',
111
+ 'uploadTo',
112
+ ].map(x => x.toLowerCase());
113
+ modelPropAttrs = [
114
+ 'alias',
115
+ 'meta',
116
+ 'priority',
117
+ 'primaryKey',
118
+ 'autoId',
119
+ 'autoIncrement',
120
+ 'index',
121
+ 'compute',
122
+ 'computed',
123
+ 'persisted',
124
+ 'uniqueConstraint',
125
+ 'addColumn',
126
+ 'removeColumn',
127
+ 'belongTo',
128
+ 'checkConstraint',
129
+ 'customField',
130
+ 'customSelect',
131
+ 'customInsert',
132
+ 'customUpdate',
133
+ 'decimalLength',
134
+ 'Default',
135
+ 'description',
136
+ 'enumAsInt',
137
+ 'excludeMetadata',
138
+ 'excludeFromDescription',
139
+ 'explicitAutoQuery',
140
+ 'foreignKey',
141
+ 'ignore',
142
+ 'ignoreOnUpdate',
143
+ 'ignoreOnInsert',
144
+ 'ignoreDataMember',
145
+ 'reference',
146
+ 'referenceField',
147
+ 'references',
148
+ 'required',
149
+ 'returnOnInsert',
150
+ 'rowVersion',
151
+ 'unique',
152
+ 'dataMember',
153
+ 'ref',
154
+ 'format',
155
+ 'intl',
156
+ 'intlNumber',
157
+ 'intlDateTime',
158
+ 'intlRelativeTime',
159
+ ].map(x => x.toLowerCase());
37
160
  unwrap(type) {
38
161
  if (type.endsWith("?")) {
39
162
  return type.substring(0, type.length - 1);
@@ -76,19 +199,26 @@ export class CSharpAst {
76
199
  return this.typeMap[type] ?? { name: type, namespace: "MyApp" };
77
200
  }
78
201
  csharpAttribute(attr) {
79
- const to = { name: toPascalCase(attr.name) };
202
+ const attrName = attr.name.includes('.')
203
+ ? rightPart(attr.name, '.')
204
+ : attr.name;
205
+ const to = { name: toPascalCase(attrName) };
80
206
  const attrType = (value) => typeof value == 'string'
81
- ? (`${value}`.startsWith('typeof') ? "Type" : "string")
207
+ ? ((value.startsWith('typeof(') || value.startsWith('nameof(')) && value.endsWith(')')
208
+ ? "constant" :
209
+ value.match(/^[A-Z][A-Za-z0-9_]+\.[A-Z][A-Za-z0-9_]+$/) //Axx.Bxx
210
+ ? "constant"
211
+ : "string")
82
212
  : typeof value == "object"
83
213
  ? (value instanceof Date ? "string" : Array.isArray(value) ? "array" : "object")
84
214
  : typeof value;
85
215
  if (attr.constructorArgs?.length) {
86
216
  to.constructorArgs = attr.constructorArgs.map(x => {
87
- const type = attrType(x.value);
217
+ const type = attrType(x);
88
218
  return {
89
219
  name: 'String',
90
220
  type,
91
- value: `${x.value}`
221
+ value: `${x}`
92
222
  };
93
223
  });
94
224
  }
@@ -102,21 +232,27 @@ export class CSharpAst {
102
232
  };
103
233
  });
104
234
  }
235
+ if (attr.name.includes('.')) {
236
+ to.namespace = leftPart(attr.name, '.');
237
+ }
105
238
  return to;
106
239
  }
107
240
  addMetadataType(cls) {
108
241
  const type = {
109
242
  name: this.toCsName(cls.name),
110
243
  namespace: "MyApp",
111
- description: cls.comment,
112
244
  properties: cls.properties.map(p => {
113
245
  const type = this.csharpType(p.type, p.name);
114
246
  const prop = {
115
247
  name: this.toCsName(p.name),
116
248
  type: p.optional ? this.nullable(type.name) : type.name,
117
- namespace: type.namespace,
118
- description: p.comment,
119
249
  };
250
+ if (type.namespace) {
251
+ prop.namespace = type.namespace;
252
+ }
253
+ if (p.comment) {
254
+ prop.description = p.comment;
255
+ }
120
256
  if (prop.name === 'Id') {
121
257
  prop.isPrimaryKey = true;
122
258
  }
@@ -145,6 +281,12 @@ export class CSharpAst {
145
281
  return prop;
146
282
  }),
147
283
  };
284
+ if (cls.comment) {
285
+ type.description = cls.comment;
286
+ }
287
+ if (cls.extends) {
288
+ type.inherits = { name: this.toCsName(cls.extends) };
289
+ }
148
290
  if (cls.annotations?.length) {
149
291
  type.attributes = cls.annotations.map(x => this.csharpAttribute(x));
150
292
  }
@@ -389,6 +531,47 @@ export class CSharpAst {
389
531
  }
390
532
  }
391
533
  }
534
+ attrsFor(dtoType, attrs) {
535
+ const requestAttrs = this.requestAttrs;
536
+ const requestPropAttrs = this.requestPropAttrs;
537
+ const modelAttrs = this.modelAttrs;
538
+ const modelPropAttrs = this.modelPropAttrs;
539
+ function shouldInclude(attr, dtoType) {
540
+ const ns = attr.namespace;
541
+ if (ns) {
542
+ if (ns == "All")
543
+ return true;
544
+ if (ns == "Read")
545
+ return dtoType == "Read";
546
+ if (ns == "Create")
547
+ return dtoType == "Create";
548
+ if (ns == "Update")
549
+ return dtoType == "Update";
550
+ if (ns == "Delete")
551
+ return dtoType == "Delete";
552
+ if (ns == "Write")
553
+ return ["Create", "Update", "Delete"].includes(dtoType);
554
+ }
555
+ else {
556
+ const isRequest = dtoType != "Model";
557
+ const nameLower = attr.name.toLowerCase();
558
+ if (isRequest) {
559
+ return requestAttrs.includes(nameLower) || requestPropAttrs.includes(nameLower);
560
+ }
561
+ else {
562
+ return modelAttrs.includes(nameLower) || modelPropAttrs.includes(nameLower);
563
+ }
564
+ }
565
+ return true;
566
+ }
567
+ const to = [];
568
+ for (const attr of attrs || []) {
569
+ if (shouldInclude(attr, dtoType)) {
570
+ to.push(attr);
571
+ }
572
+ }
573
+ return to;
574
+ }
392
575
  createAutoCrudApis() {
393
576
  for (const type of this.classes) {
394
577
  const hasPk = type.properties?.some(x => x.isPrimaryKey);
@@ -408,21 +591,19 @@ export class CSharpAst {
408
591
  name: "FieldCss",
409
592
  args: [{ name: "Field", type: "string", value: "col-span-12" }]
410
593
  }];
411
- const ignoreDtoAttrs = ['AutoIncrement'];
412
- const idsProps = pk
413
- ? [
414
- Object.assign({}, pk, {
415
- type: `${this.nullable(pk.type)}`,
416
- attributes: pk.attributes?.filter(a => !ignoreDtoAttrs.includes(a.name)),
417
- }),
418
- {
419
- name: `${pk.name}s`,
420
- type: "List`1?",
421
- namespace: "System.Collections.Generic",
422
- genericArgs: [pk.type]
423
- }
424
- ]
425
- : [];
594
+ function onlyAttrs(attrs, only) {
595
+ if (!attrs)
596
+ return;
597
+ return attrs.filter(x => only.includes(x.name));
598
+ }
599
+ const idsProp = pk
600
+ ? {
601
+ name: `${pk.name}s`,
602
+ type: "List`1?",
603
+ namespace: "System.Collections.Generic",
604
+ genericArgs: [pk.type]
605
+ }
606
+ : undefined;
426
607
  if (!queryApi) {
427
608
  queryApi = {
428
609
  method: "GET",
@@ -436,7 +617,16 @@ export class CSharpAst {
436
617
  namespace: "ServiceStack",
437
618
  genericArgs: [type.name]
438
619
  },
439
- properties: idsProps,
620
+ properties: pk
621
+ ? [
622
+ Object.assign({}, pk, {
623
+ type: `${this.nullable(pk.type)}`,
624
+ attributes: onlyAttrs(pk.attributes, this.requestPropAttrs),
625
+ }),
626
+ idsProp
627
+ ]
628
+ : [],
629
+ attributes: this.attrsFor("Read", type.attributes),
440
630
  },
441
631
  returnType: {
442
632
  name: "QueryResponse`1",
@@ -446,17 +636,17 @@ export class CSharpAst {
446
636
  dataModel,
447
637
  };
448
638
  if (isAuditBase) {
449
- if (!queryApi.request.attributes)
450
- queryApi.request.attributes = [];
451
- // [AutoApply(Behavior.AuditQuery)]
452
- queryApi.request.attributes.push({
453
- name: "AutoApply",
454
- constructorArgs: [{
455
- name: "name",
456
- type: "constant",
457
- value: "Behavior.AuditQuery"
458
- }]
459
- });
639
+ if (!queryApi.request.attributes?.find(x => x.name === 'AutoApply')) {
640
+ // [AutoApply(Behavior.AuditQuery)]
641
+ queryApi.request.attributes.push({
642
+ name: "AutoApply",
643
+ constructorArgs: [{
644
+ name: "name",
645
+ type: "constant",
646
+ value: "Behavior.AuditQuery"
647
+ }]
648
+ });
649
+ }
460
650
  }
461
651
  this.result.operations.push(queryApi);
462
652
  }
@@ -464,7 +654,6 @@ export class CSharpAst {
464
654
  let createApi = this.result.operations.find(x => x.request.name === createName);
465
655
  if (!createApi) {
466
656
  const ignorePropsWithAttrs = ['AutoIncrement', 'Reference'];
467
- const ignoreAttrs = [];
468
657
  createApi = {
469
658
  method: "POST",
470
659
  actions: ["ANY"],
@@ -481,8 +670,9 @@ export class CSharpAst {
481
670
  type: x.isPrimaryKey
482
671
  ? x.type
483
672
  : `${x.type}`,
484
- attributes: x.attributes?.filter(a => !ignoreAttrs.includes(a.name)),
673
+ attributes: onlyAttrs(x.attributes, this.requestPropAttrs),
485
674
  })),
675
+ attributes: this.attrsFor("Create", type.attributes),
486
676
  },
487
677
  returnType: {
488
678
  name: "IdResponse",
@@ -512,17 +702,17 @@ export class CSharpAst {
512
702
  }
513
703
  if (isAuditBase) {
514
704
  createApi.requiresAuth = true;
515
- if (!createApi.request.attributes)
516
- createApi.request.attributes = [];
517
- // [AutoApply(Behavior.AuditCreate)]
518
- createApi.request.attributes.push({
519
- name: "AutoApply",
520
- constructorArgs: [{
521
- name: "name",
522
- type: "constant",
523
- value: "Behavior.AuditCreate"
524
- }]
525
- });
705
+ if (!createApi.request.attributes?.find(x => x.name === 'AutoApply')) {
706
+ // [AutoApply(Behavior.AuditCreate)]
707
+ createApi.request.attributes.push({
708
+ name: "AutoApply",
709
+ constructorArgs: [{
710
+ name: "name",
711
+ type: "constant",
712
+ value: "Behavior.AuditCreate"
713
+ }]
714
+ });
715
+ }
526
716
  }
527
717
  this.result.operations.push(createApi);
528
718
  }
@@ -545,8 +735,9 @@ export class CSharpAst {
545
735
  type: x.isPrimaryKey
546
736
  ? x.type
547
737
  : `${this.nullable(x.type)}`,
548
- attributes: x.attributes?.filter(a => !ignoreAttrs.includes(a.name)),
738
+ attributes: onlyAttrs(x.attributes?.filter(a => !ignoreAttrs.includes(a.name)), this.requestPropAttrs),
549
739
  })),
740
+ attributes: this.attrsFor("Update", type.attributes),
550
741
  },
551
742
  returnType: {
552
743
  name: "IdResponse",
@@ -565,17 +756,17 @@ export class CSharpAst {
565
756
  }
566
757
  if (isAuditBase) {
567
758
  updateApi.requiresAuth = true;
568
- if (!updateApi.request.attributes)
569
- updateApi.request.attributes = [];
570
- // [AutoApply(Behavior.AuditModify)]
571
- updateApi.request.attributes.push({
572
- name: "AutoApply",
573
- constructorArgs: [{
574
- name: "name",
575
- type: "constant",
576
- value: "Behavior.AuditModify"
577
- }]
578
- });
759
+ if (!updateApi.request.attributes?.find(x => x.name === 'AutoApply')) {
760
+ // [AutoApply(Behavior.AuditModify)]
761
+ updateApi.request.attributes.push({
762
+ name: "AutoApply",
763
+ constructorArgs: [{
764
+ name: "name",
765
+ type: "constant",
766
+ value: "Behavior.AuditModify"
767
+ }]
768
+ });
769
+ }
579
770
  }
580
771
  this.result.operations.push(updateApi);
581
772
  }
@@ -593,29 +784,43 @@ export class CSharpAst {
593
784
  namespace: "ServiceStack",
594
785
  genericArgs: [type.name]
595
786
  }],
596
- properties: idsProps,
787
+ properties: pk
788
+ ? [
789
+ Object.assign({}, pk, {
790
+ type: `${this.nullable(pk.type)}`,
791
+ attributes: onlyAttrs(pk.attributes, this.requestPropAttrs),
792
+ }),
793
+ idsProp
794
+ ]
795
+ : [],
796
+ attributes: this.attrsFor("Delete", type.attributes),
597
797
  },
598
798
  returnsVoid: true,
599
799
  dataModel,
600
800
  };
601
801
  if (isAuditBase) {
602
802
  deleteApi.requiresAuth = true;
603
- if (!deleteApi.request.attributes)
604
- deleteApi.request.attributes = [];
605
- // [AutoApply(Behavior.AuditSoftDelete)]
606
- deleteApi.request.attributes.push({
607
- name: "AutoApply",
608
- constructorArgs: [{
609
- name: "name",
610
- type: "constant",
611
- value: "Behavior.AuditSoftDelete"
612
- }]
613
- });
803
+ if (!deleteApi.request.attributes?.find(x => x.name === 'AutoApply')) {
804
+ // [AutoApply(Behavior.AuditSoftDelete)]
805
+ deleteApi.request.attributes.push({
806
+ name: "AutoApply",
807
+ constructorArgs: [{
808
+ name: "name",
809
+ type: "constant",
810
+ value: "Behavior.AuditSoftDelete"
811
+ }]
812
+ });
813
+ }
614
814
  }
615
815
  this.result.operations.push(deleteApi);
616
816
  }
617
817
  }
618
818
  }
819
+ filterModelAttributes() {
820
+ for (const type of this.classes) {
821
+ type.attributes = this.attrsFor("Model", type.attributes);
822
+ }
823
+ }
619
824
  // Add Icon for BuiltIn UIs and AutoQueryGrid to known type names
620
825
  addIconsToKnownTypes() {
621
826
  for (const type of this.typesWithPrimaryKeys) {
@@ -696,6 +901,7 @@ export class CSharpAst {
696
901
  this.hideReferenceProperties();
697
902
  this.replaceUserReferencesWithAuditTables();
698
903
  this.createAutoCrudApis();
904
+ this.filterModelAttributes();
699
905
  }
700
906
  parse(ast) {
701
907
  const classes = ast.classes.concat(ast.interfaces);
package/dist/cs-gen.js CHANGED
@@ -41,7 +41,7 @@ export class CSharpGenerator {
41
41
  body += value;
42
42
  }
43
43
  }
44
- if (!body && attr.args?.length) {
44
+ if (attr.args?.length) {
45
45
  for (const arg of attr.args) {
46
46
  this.addNamespace(arg.namespace);
47
47
  if (body)
package/dist/index.js CHANGED
@@ -57,7 +57,7 @@ function parseArgs(...args) {
57
57
  break;
58
58
  }
59
59
  }
60
- else if (ret.type === "help" && ["help", "info", "init", "ls", "rm", "update", "accept"].includes(arg)) {
60
+ else if (ret.type === "help" && ["help", "info", "init", "ls", "add", "rm", "update", "accept"].includes(arg)) {
61
61
  if (arg == "help")
62
62
  ret.type = "help";
63
63
  else if (arg == "info")
@@ -82,6 +82,10 @@ function parseArgs(...args) {
82
82
  ret.type = "list";
83
83
  ret.list = args[++i];
84
84
  }
85
+ else if (arg == "add") {
86
+ ret.type = "add";
87
+ ret.add = args[++i];
88
+ }
85
89
  else if (arg == "accept") {
86
90
  ret.type = "accept";
87
91
  ret.accept = args[++i];
@@ -208,6 +212,24 @@ Options:
208
212
  process.exit(0);
209
213
  }
210
214
  }
215
+ if (command.type === "add") {
216
+ if (command.add == "types" || command.add?.startsWith("api")) {
217
+ const apiFile = path.join(import.meta.dirname, 'api.d.ts');
218
+ if (!fs.existsSync(apiFile)) {
219
+ console.log(`Could not find: ${apiFile}`);
220
+ process.exit(1);
221
+ }
222
+ const toFile = path.join(info.serviceModelDir, 'api.d.ts');
223
+ fs.copyFileSync(apiFile, toFile);
224
+ console.log(`Added: ${toFile}`);
225
+ process.exit(0);
226
+ }
227
+ else {
228
+ console.log(`Unknown add command: ${command.add}`);
229
+ console.log(`Usage: add types`);
230
+ process.exit(1);
231
+ }
232
+ }
211
233
  function assertTsdPath(tsdFile) {
212
234
  const tryPaths = [
213
235
  path.join(process.cwd(), tsdFile),
@@ -320,6 +342,13 @@ Options:
320
342
  }
321
343
  fs.unlinkSync(tsdPath);
322
344
  console.log(`Removed: ${tsdPath}`);
345
+ const serviceModelDir = path.dirname(tsdPath);
346
+ const tsds = fs.readdirSync(serviceModelDir).filter(x => x.endsWith('.d.ts'));
347
+ if (tsds.length == 1 && tsds[0] == 'api.d.ts') {
348
+ const typesApiPath = path.join(serviceModelDir, 'api.d.ts');
349
+ fs.unlinkSync(typesApiPath);
350
+ console.log(`Removed: ${typesApiPath}`);
351
+ }
323
352
  process.exit(0);
324
353
  }
325
354
  if (command.type == "accept") {
@@ -608,15 +637,18 @@ function chooseFile(ctx, info, gist, comamnd) {
608
637
  const migrationFileName = path.basename(migrationPath);
609
638
  const migrationCls = leftPart(migrationFileName, '.');
610
639
  const migrationContent = replaceMyApp(csMigrationFiles[Object.keys(csMigrationFiles)[0]].replaceAll('Migration1000', migrationCls), info.projectName);
611
- const sb = [];
612
- sb.push(`/*prompt: ${titleBar.content.replaceAll('/*', '').replaceAll('*/', '')}`);
613
- sb.push(`api: ~/${path.join(relativeServiceModelDir, apiFileName)}`);
614
- sb.push(`migration: ~/${path.join(relativeMigrationDir, migrationFileName)}`);
615
- sb.push(`*/`);
616
- sb.push('');
617
- sb.push(tsd);
640
+ const sb = [
641
+ `/// <reference path="./api.d.ts" />`,
642
+ `/*prompt: ${titleBar.content.replaceAll('/*', '').replaceAll('*/', '')}`,
643
+ `api: ~/${path.join(relativeServiceModelDir, apiFileName)}`,
644
+ `migration: ~/${path.join(relativeMigrationDir, migrationFileName)}`,
645
+ `*/`,
646
+ '',
647
+ tsd,
648
+ ];
618
649
  const tsdContent = sb.join('\n');
619
650
  const tsdFileName = `${groupName}.d.ts`;
651
+ const typesApiPath = path.join(info.slnDir, relativeServiceModelDir, `api.d.ts`);
620
652
  const fullTsdPath = path.join(info.slnDir, relativeServiceModelDir, tsdFileName);
621
653
  const fullApiPath = path.join(info.slnDir, relativeServiceModelDir, apiFileName);
622
654
  const fullMigrationPath = path.join(info.slnDir, relativeMigrationDir, migrationFileName);
@@ -635,6 +667,8 @@ function chooseFile(ctx, info, gist, comamnd) {
635
667
  fs.writeFileSync(fullMigrationPath, migrationContent, { encoding: 'utf-8' });
636
668
  console.log(`Saved: ${fullMigrationPath}`);
637
669
  }
670
+ const apiFile = path.join(import.meta.dirname, 'api.d.ts');
671
+ fs.writeFileSync(typesApiPath, fs.readFileSync(apiFile, 'utf-8'));
638
672
  const script = path.basename(process.argv[1]);
639
673
  console.log(`\nTo regenerate classes, update '${tsdFileName}' then run:`);
640
674
  console.log(`$ ${script} ${tsdFileName}`);
package/dist/ts-parser.js CHANGED
@@ -4,7 +4,8 @@ export class TypeScriptParser {
4
4
  static ENUM_PATTERN = /enum\s+(\w+)\s*{([^}]*)}/g;
5
5
  static PROPERTY_PATTERN = /(?:(?<modifier>private|public|protected|readonly)\s+)*(?<name>\w+)(?<optional>\?)?\s*:\s*(?<type>[\w<>[\],\s]+)(?<union>\|\s*[\w<>[\],|,\s]+)?\s*;?/;
6
6
  static ENUM_MEMBER_PATTERN = /(\w+)\s*(?:=\s*("[^"]*"|'[^']*'|\d+|[^,\n]+))?\s*/;
7
- static ANNOTATION_PATTERN = /@\w+\(.*\)/;
7
+ // private static readonly ANNOTATION_PATTERN = /@(\w+\.?\w*)\s*\((.*)\)/
8
+ static ANNOTATION_PATTERN = /@([A-Za-z_][A-Za-z0-9_]*\.?[A-Za-z_]?[A-Za-z0-9_]*)\s*\((.*)\)/;
8
9
  classes = [];
9
10
  interfaces = [];
10
11
  enums = [];
@@ -260,7 +261,7 @@ export class TypeScriptParser {
260
261
  }
261
262
  export function parseAnnotation(annotation) {
262
263
  // Match @name and everything inside ()
263
- const regex = /@(\w+)\s*\((.*)\)/;
264
+ const regex = /@(\w+\.?\w*)\s*\((.*)\)/;
264
265
  const match = annotation.match(regex);
265
266
  if (!match)
266
267
  return null;
package/dist/tsd-gen.js CHANGED
@@ -32,6 +32,12 @@ export class TsdGenerator {
32
32
  return `${prefix}@${attr.name}(${sbArgs.join(',')})`;
33
33
  }
34
34
  toInterface(ast) {
35
+ return this.toType(ast, 'interface');
36
+ }
37
+ toClass(ast) {
38
+ return this.toType(ast, 'class');
39
+ }
40
+ toType(ast, type) {
35
41
  const sb = [];
36
42
  if (ast.comment) {
37
43
  sb.push(ast.comment.split('\n').map(x => `// ${x}`).join('\n'));
@@ -42,7 +48,7 @@ export class TsdGenerator {
42
48
  }
43
49
  }
44
50
  const extend = ast.extends ? ` extends ${ast.extends}` : '';
45
- sb.push(`export interface ${ast.name}${extend} {`);
51
+ sb.push(`export ${type} ${ast.name}${extend} {`);
46
52
  for (const prop of ast.properties) {
47
53
  if (prop.comment) {
48
54
  sb.push(prop.comment.split('\n').map(x => ` // ${x}`).join('\n'));
@@ -76,7 +82,7 @@ export class TsdGenerator {
76
82
  sb.push('}');
77
83
  return sb.join('\n');
78
84
  }
79
- generate(ast) {
85
+ generate(ast, type = 'interface') {
80
86
  this.ast = ast;
81
87
  const sb = [];
82
88
  for (const cls of ast.enums ?? []) {
@@ -84,12 +90,12 @@ export class TsdGenerator {
84
90
  sb.push('');
85
91
  }
86
92
  for (const cls of ast.interfaces ?? []) {
87
- sb.push(this.toInterface(cls));
93
+ sb.push(this.toType(cls, type));
88
94
  sb.push('');
89
95
  }
90
96
  for (const cls of ast.classes ?? []) {
91
97
  const iface = this.clsToInterface(cls);
92
- sb.push(this.toInterface(iface));
98
+ sb.push(this.toType(iface, type));
93
99
  sb.push('');
94
100
  }
95
101
  const tsd = sb.join('\n');
@@ -154,6 +160,6 @@ export class TsdDataModelGenerator extends TsdGenerator {
154
160
  if (ast.interfaces) {
155
161
  ast.interfaces = ast.interfaces.filter(x => x.name !== 'User');
156
162
  }
157
- return super.generate(ast);
163
+ return super.generate(ast, "class");
158
164
  }
159
165
  }
package/dist/utils.js CHANGED
@@ -113,6 +113,14 @@ export function leftPart(s, needle) {
113
113
  ? s
114
114
  : s.substring(0, pos);
115
115
  }
116
+ export function rightPart(s, needle) {
117
+ if (s == null)
118
+ return null;
119
+ let pos = s.indexOf(needle);
120
+ return pos == -1
121
+ ? s
122
+ : s.substring(pos + needle.length);
123
+ }
116
124
  export function splitCase(t) {
117
125
  return typeof t != 'string' ? t : t.replace(/([A-Z]|[0-9]+)/g, ' $1').replace(/_/g, ' ').trim();
118
126
  }
@@ -126,13 +134,13 @@ export function tsdWithPrompt(tsd, prompt) {
126
134
  return `/*prompt: ${prompt}\n*/\n\n${tsd}`;
127
135
  }
128
136
  export function tsdWithoutPrompt(tsd) {
129
- return tsd.trim().startsWith('/*prompt:')
137
+ return tsd.includes('/*prompt:')
130
138
  ? tsd.substring(tsd.indexOf('*/') + 2).trim()
131
139
  : tsd;
132
140
  }
133
141
  export function parseTsdHeader(tsd) {
134
142
  const header = tsd.includes('/*prompt:')
135
- ? leftPart(tsd, '*/').replace('/*prompt:', '').trim()
143
+ ? leftPart(rightPart(tsd, '/*prompt:'), '*/').trim()
136
144
  : null;
137
145
  if (!header)
138
146
  return null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "okai",
3
3
  "type": "module",
4
- "version": "0.0.22",
4
+ "version": "0.0.23",
5
5
  "bin": "./dist/okai.js",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  "import": "./dist/index.js"
13
13
  },
14
14
  "scripts": {
15
- "build": "bun run clean && tsc && chmod +x ./dist/okai.js",
15
+ "build": "bun run clean && tsc && shx cp ./src/api.d.ts ./dist && chmod +x ./dist/okai.js",
16
16
  "build-bun": "bun run clean && bun build.ts",
17
17
  "clean": "shx rm -rf ./dist",
18
18
  "test": "bun test --",