oip-common 0.0.36 → 0.0.38
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/assets/i18n/en.json +124 -74
- package/assets/i18n/ru.json +268 -223
- package/fesm2022/oip-common.mjs +2027 -597
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +250 -9
- package/package.json +1 -1
- package/scripts/generate-api.mjs +147 -147
- package/templates/http-client.ejs +18 -5
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { OnInit, OnDestroy, WritableSignal, Type, Provider, InjectionToken, EventEmitter, Renderer2, PipeTransform } from '@angular/core';
|
|
2
|
+
import { OnInit, OnDestroy, WritableSignal, Type, Provider, InjectionToken, EventEmitter, Renderer2, OnChanges, SimpleChanges, PipeTransform } from '@angular/core';
|
|
3
3
|
import { MessageService, ToastMessageOptions, MenuItem, ConfirmationService, FilterMetadata } from 'primeng/api';
|
|
4
4
|
import { ActivatedRoute, QueryParamsHandling, IsActiveMatchOptions, Params, Router, UrlTree } from '@angular/router';
|
|
5
5
|
import { TranslateService, InterpolationParameters, Translation, TranslationObject } from '@ngx-translate/core';
|
|
@@ -43,6 +43,8 @@ declare class MsgService {
|
|
|
43
43
|
info(detail: any, summary?: any, life?: number): void;
|
|
44
44
|
warn(detail: any, summary?: any, life?: number): void;
|
|
45
45
|
error(detail: any, summary?: any, life?: number): void;
|
|
46
|
+
extractErrorMessage(error: unknown, fallback: string): string;
|
|
47
|
+
errorFromException(error: unknown, fallback: string, summary?: string, life?: number): void;
|
|
46
48
|
contrast(detail: any, summary?: any, life?: number): void;
|
|
47
49
|
secondary(detail: any, summary?: any, life?: number): void;
|
|
48
50
|
static ɵfac: i0.ɵɵFactoryDeclaration<MsgService, never>;
|
|
@@ -169,6 +171,8 @@ declare class LayoutService {
|
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
declare abstract class BaseModuleComponent<TBackendStoreSettings, TLocalStoreSettings> implements OnInit, OnDestroy {
|
|
174
|
+
private isInitialized;
|
|
175
|
+
private moduleInstanceReloadPromise;
|
|
172
176
|
/**
|
|
173
177
|
* Provide access to app settings
|
|
174
178
|
*/
|
|
@@ -300,6 +304,12 @@ declare abstract class BaseModuleComponent<TBackendStoreSettings, TLocalStoreSet
|
|
|
300
304
|
* @return {Promise<void>} A promise that resolves when the settings are saved. Reject if an error occurs.
|
|
301
305
|
*/
|
|
302
306
|
saveSettings(settings: TBackendStoreSettings): Promise<void>;
|
|
307
|
+
/**
|
|
308
|
+
* Called whenever the module instance changes, including the first load.
|
|
309
|
+
* Derived components can override this to refresh module-specific data.
|
|
310
|
+
*/
|
|
311
|
+
protected onModuleInstanceChange(): Promise<void>;
|
|
312
|
+
private reloadModuleInstance;
|
|
303
313
|
static ɵfac: i0.ɵɵFactoryDeclaration<BaseModuleComponent<any, any>, never>;
|
|
304
314
|
static ɵcmp: i0.ɵɵComponentDeclaration<BaseModuleComponent<any, any>, "ng-component", never, {}, {}, never, never, true, never>;
|
|
305
315
|
}
|
|
@@ -695,12 +705,6 @@ interface FullRequestParams extends Omit<RequestInit, "body"> {
|
|
|
695
705
|
cancelToken?: CancelToken;
|
|
696
706
|
}
|
|
697
707
|
type RequestParams = Omit<FullRequestParams, "body" | "method" | "query" | "path">;
|
|
698
|
-
interface ApiConfig<SecurityDataType = unknown> {
|
|
699
|
-
baseUrl?: string;
|
|
700
|
-
baseApiParams?: Omit<RequestParams, "baseUrl" | "cancelToken" | "signal">;
|
|
701
|
-
securityWorker?: (securityData: SecurityDataType | null) => Promise<RequestParams | void> | RequestParams | void;
|
|
702
|
-
customFetch?: typeof fetch;
|
|
703
|
-
}
|
|
704
708
|
type CancelToken = Symbol | string | number;
|
|
705
709
|
declare enum ContentType {
|
|
706
710
|
Json = "application/json",
|
|
@@ -710,13 +714,15 @@ declare enum ContentType {
|
|
|
710
714
|
Text = "text/plain"
|
|
711
715
|
}
|
|
712
716
|
declare class HttpClient<SecurityDataType = unknown> {
|
|
717
|
+
protected securityService: SecurityService;
|
|
718
|
+
protected layoutService: LayoutService;
|
|
713
719
|
baseUrl: string;
|
|
714
720
|
private securityData;
|
|
715
721
|
private securityWorker?;
|
|
716
722
|
private abortControllers;
|
|
717
723
|
private customFetch;
|
|
718
724
|
private baseApiParams;
|
|
719
|
-
constructor(
|
|
725
|
+
constructor();
|
|
720
726
|
setSecurityData: (data: SecurityDataType | null) => void;
|
|
721
727
|
protected encodeQueryParam(key: string, value: any): string;
|
|
722
728
|
protected addQueryParam(query: QueryParamsType, key: string): string;
|
|
@@ -1167,6 +1173,241 @@ declare class AppFloatingConfiguratorComponent {
|
|
|
1167
1173
|
static ɵcmp: i0.ɵɵComponentDeclaration<AppFloatingConfiguratorComponent, "app-floating-configurator", never, {}, {}, never, never, true, never>;
|
|
1168
1174
|
}
|
|
1169
1175
|
|
|
1176
|
+
/** Attachment response DTO. */
|
|
1177
|
+
interface AttachmentDto {
|
|
1178
|
+
/**
|
|
1179
|
+
* Attachment identifier.
|
|
1180
|
+
* @format int64
|
|
1181
|
+
*/
|
|
1182
|
+
attachmentId?: number;
|
|
1183
|
+
/** Original file name. */
|
|
1184
|
+
fileName?: string | null;
|
|
1185
|
+
/** MIME type of the file. */
|
|
1186
|
+
fileType?: string | null;
|
|
1187
|
+
/**
|
|
1188
|
+
* File size in bytes.
|
|
1189
|
+
* @format int64
|
|
1190
|
+
*/
|
|
1191
|
+
fileSize?: number;
|
|
1192
|
+
/**
|
|
1193
|
+
* Upload timestamp.
|
|
1194
|
+
* @format date-time
|
|
1195
|
+
*/
|
|
1196
|
+
uploadedAt?: Date;
|
|
1197
|
+
/**
|
|
1198
|
+
* File storage identifier.
|
|
1199
|
+
* @format uuid
|
|
1200
|
+
*/
|
|
1201
|
+
storageFileId?: string;
|
|
1202
|
+
/** Download URL for the file. */
|
|
1203
|
+
downloadUrl?: string | null;
|
|
1204
|
+
}
|
|
1205
|
+
/** Comment response DTO. */
|
|
1206
|
+
interface CommentDto {
|
|
1207
|
+
/**
|
|
1208
|
+
* Comment identifier.
|
|
1209
|
+
* @format int64
|
|
1210
|
+
*/
|
|
1211
|
+
commentId?: number;
|
|
1212
|
+
/**
|
|
1213
|
+
* Related entity type identifier.
|
|
1214
|
+
* @format int64
|
|
1215
|
+
*/
|
|
1216
|
+
objectTypeId?: number;
|
|
1217
|
+
/**
|
|
1218
|
+
* Related entity identifier.
|
|
1219
|
+
* @format int64
|
|
1220
|
+
*/
|
|
1221
|
+
objectId?: number;
|
|
1222
|
+
/** Raw markdown comment content. */
|
|
1223
|
+
content?: string | null;
|
|
1224
|
+
/**
|
|
1225
|
+
* Author identifier.
|
|
1226
|
+
* @format int64
|
|
1227
|
+
*/
|
|
1228
|
+
userId?: number;
|
|
1229
|
+
/** Author display name. */
|
|
1230
|
+
authorDisplayName?: string | null;
|
|
1231
|
+
/** Author e-mail. */
|
|
1232
|
+
authorEmail?: string | null;
|
|
1233
|
+
/**
|
|
1234
|
+
* Comment creation time.
|
|
1235
|
+
* @format date-time
|
|
1236
|
+
*/
|
|
1237
|
+
createdAt?: Date;
|
|
1238
|
+
/**
|
|
1239
|
+
* Comment last update time.
|
|
1240
|
+
* @format date-time
|
|
1241
|
+
*/
|
|
1242
|
+
updatedAt?: Date | null;
|
|
1243
|
+
/** Whether the comment was edited. */
|
|
1244
|
+
isEdited?: boolean;
|
|
1245
|
+
/**
|
|
1246
|
+
* Number of edit history entries.
|
|
1247
|
+
* @format int32
|
|
1248
|
+
*/
|
|
1249
|
+
historyCount?: number;
|
|
1250
|
+
/** Whether the current user can edit this comment. */
|
|
1251
|
+
canEdit?: boolean;
|
|
1252
|
+
/** Whether the current user can delete this comment. */
|
|
1253
|
+
canDelete?: boolean;
|
|
1254
|
+
/** Attachments for the comment. */
|
|
1255
|
+
attachments?: AttachmentDto[] | null;
|
|
1256
|
+
/** Reactions aggregated for the comment. */
|
|
1257
|
+
reactions?: CommentReactionDto[] | null;
|
|
1258
|
+
/** Mentions for the comment. */
|
|
1259
|
+
mentions?: CommentMentionDto[] | null;
|
|
1260
|
+
}
|
|
1261
|
+
/** Comment edit history response DTO. */
|
|
1262
|
+
interface CommentHistoryDto {
|
|
1263
|
+
/**
|
|
1264
|
+
* History entry identifier.
|
|
1265
|
+
* @format int64
|
|
1266
|
+
*/
|
|
1267
|
+
commentEditHistoryId?: number;
|
|
1268
|
+
/** Previous comment content. */
|
|
1269
|
+
oldContent?: string | null;
|
|
1270
|
+
/** Updated comment content. */
|
|
1271
|
+
newContent?: string | null;
|
|
1272
|
+
/**
|
|
1273
|
+
* Editor identifier.
|
|
1274
|
+
* @format int64
|
|
1275
|
+
*/
|
|
1276
|
+
editedByUserId?: number;
|
|
1277
|
+
/** Editor display name. */
|
|
1278
|
+
editedByDisplayName?: string | null;
|
|
1279
|
+
/**
|
|
1280
|
+
* Time of edit.
|
|
1281
|
+
* @format date-time
|
|
1282
|
+
*/
|
|
1283
|
+
editedAt?: Date;
|
|
1284
|
+
}
|
|
1285
|
+
/** Mention response DTO. */
|
|
1286
|
+
interface CommentMentionDto {
|
|
1287
|
+
/**
|
|
1288
|
+
* Mentioned user identifier.
|
|
1289
|
+
* @format int64
|
|
1290
|
+
*/
|
|
1291
|
+
mentionedUserId?: number;
|
|
1292
|
+
/** Display name of the mentioned user. */
|
|
1293
|
+
displayName?: string | null;
|
|
1294
|
+
/** E-mail of the mentioned user. */
|
|
1295
|
+
email?: string | null;
|
|
1296
|
+
/**
|
|
1297
|
+
* Position within the markdown text.
|
|
1298
|
+
* @format int32
|
|
1299
|
+
*/
|
|
1300
|
+
position?: number;
|
|
1301
|
+
}
|
|
1302
|
+
/** Aggregated reaction response DTO. */
|
|
1303
|
+
interface CommentReactionDto {
|
|
1304
|
+
/** Emoji code. */
|
|
1305
|
+
emojiCode?: string | null;
|
|
1306
|
+
/**
|
|
1307
|
+
* Number of reactions with the same emoji.
|
|
1308
|
+
* @format int32
|
|
1309
|
+
*/
|
|
1310
|
+
count?: number;
|
|
1311
|
+
/** Whether the current user reacted with this emoji. */
|
|
1312
|
+
reactedByCurrentUser?: boolean;
|
|
1313
|
+
}
|
|
1314
|
+
/** Mention candidate response DTO. */
|
|
1315
|
+
interface MentionUserDto {
|
|
1316
|
+
/**
|
|
1317
|
+
* User identifier.
|
|
1318
|
+
* @format int64
|
|
1319
|
+
*/
|
|
1320
|
+
userId?: number;
|
|
1321
|
+
/** Display name. */
|
|
1322
|
+
displayName?: string | null;
|
|
1323
|
+
/** E-mail. */
|
|
1324
|
+
email?: string | null;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
declare function getInitialsFromString(input: string): string;
|
|
1328
|
+
|
|
1329
|
+
type HistoryState = {
|
|
1330
|
+
loading: boolean;
|
|
1331
|
+
opened: boolean;
|
|
1332
|
+
items: DiscussionHistoryItem[];
|
|
1333
|
+
};
|
|
1334
|
+
type DiscussionAttachment = Required<AttachmentDto>;
|
|
1335
|
+
type DiscussionReaction = Required<CommentReactionDto>;
|
|
1336
|
+
type DiscussionMentionUser = Required<MentionUserDto>;
|
|
1337
|
+
type DiscussionComment = Omit<CommentDto, 'attachments' | 'reactions' | 'mentions'> & {
|
|
1338
|
+
commentId: number;
|
|
1339
|
+
content: string;
|
|
1340
|
+
authorDisplayName: string;
|
|
1341
|
+
authorEmail: string;
|
|
1342
|
+
isEdited: boolean;
|
|
1343
|
+
historyCount: number;
|
|
1344
|
+
canEdit: boolean;
|
|
1345
|
+
canDelete: boolean;
|
|
1346
|
+
attachments: DiscussionAttachment[];
|
|
1347
|
+
reactions: DiscussionReaction[];
|
|
1348
|
+
};
|
|
1349
|
+
type DiscussionHistoryItem = Required<CommentHistoryDto>;
|
|
1350
|
+
declare class DiscussionComponent implements OnChanges, OnDestroy, OnInit {
|
|
1351
|
+
private readonly msgService;
|
|
1352
|
+
private readonly discussionApi;
|
|
1353
|
+
private readonly sanitizer;
|
|
1354
|
+
private readonly translateService;
|
|
1355
|
+
private readonly cdr;
|
|
1356
|
+
private readonly confirmationService;
|
|
1357
|
+
protected readonly layoutService: LayoutService;
|
|
1358
|
+
objectTypeId: number;
|
|
1359
|
+
objectId: number;
|
|
1360
|
+
comments: DiscussionComment[];
|
|
1361
|
+
loading: boolean;
|
|
1362
|
+
submitting: boolean;
|
|
1363
|
+
previewMode: boolean;
|
|
1364
|
+
newComment: string;
|
|
1365
|
+
editContent: string;
|
|
1366
|
+
editingCommentId: number | null;
|
|
1367
|
+
pendingFiles: File[];
|
|
1368
|
+
mentionSuggestions: DiscussionMentionUser[];
|
|
1369
|
+
historyByComment: Record<number, HistoryState>;
|
|
1370
|
+
emojiPalette: string[];
|
|
1371
|
+
private mentionSearchTimer;
|
|
1372
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
1373
|
+
ngOnInit(): Promise<void>;
|
|
1374
|
+
ngOnDestroy(): void;
|
|
1375
|
+
loadComments(): Promise<void>;
|
|
1376
|
+
createComment(): Promise<void>;
|
|
1377
|
+
startEdit(comment: DiscussionComment): void;
|
|
1378
|
+
cancelEdit(): void;
|
|
1379
|
+
saveEdit(comment: DiscussionComment): Promise<void>;
|
|
1380
|
+
deleteComment(comment: DiscussionComment): void;
|
|
1381
|
+
toggleHistory(comment: DiscussionComment): Promise<void>;
|
|
1382
|
+
onFilesSelected(event: Event): void;
|
|
1383
|
+
removePendingFile(file: File): void;
|
|
1384
|
+
onInlineFilesSelected(comment: DiscussionComment, event: Event): Promise<void>;
|
|
1385
|
+
deleteAttachment(comment: DiscussionComment, attachment: DiscussionAttachment): void;
|
|
1386
|
+
private performDeleteComment;
|
|
1387
|
+
private performDeleteAttachment;
|
|
1388
|
+
downloadAttachment(attachment: DiscussionAttachment): Promise<void>;
|
|
1389
|
+
toggleReaction(comment: DiscussionComment, reaction: DiscussionReaction): Promise<void>;
|
|
1390
|
+
reactWithEmoji(comment: DiscussionComment, emojiCode: string, popover?: {
|
|
1391
|
+
hide: () => void;
|
|
1392
|
+
}): Promise<void>;
|
|
1393
|
+
onComposerInput(): void;
|
|
1394
|
+
insertMention(candidate: DiscussionMentionUser): void;
|
|
1395
|
+
renderMarkdown(markdown: string): string;
|
|
1396
|
+
formatBytes(value: number): string;
|
|
1397
|
+
hasUserReaction(comment: DiscussionComment): boolean;
|
|
1398
|
+
getReactions(comment: DiscussionComment): DiscussionReaction[];
|
|
1399
|
+
private applyReactions;
|
|
1400
|
+
private normalizeComment;
|
|
1401
|
+
private normalizeAttachment;
|
|
1402
|
+
private normalizeReaction;
|
|
1403
|
+
private normalizeMentionUser;
|
|
1404
|
+
private normalizeHistoryItem;
|
|
1405
|
+
private extractMentionQuery;
|
|
1406
|
+
protected readonly getInitialsFromString: typeof getInitialsFromString;
|
|
1407
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DiscussionComponent, never>;
|
|
1408
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DiscussionComponent, "discussion", never, { "objectTypeId": { "alias": "objectTypeId"; "required": true; }; "objectId": { "alias": "objectId"; "required": true; }; }, {}, never, never, true, never>;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1170
1411
|
interface SecurityDto {
|
|
1171
1412
|
code: string;
|
|
1172
1413
|
name: string;
|
|
@@ -1281,5 +1522,5 @@ declare class SecurePipe implements PipeTransform {
|
|
|
1281
1522
|
*/
|
|
1282
1523
|
declare const httpLoaderAuthFactory: (httpClient: HttpClient$1) => StsConfigHttpLoader;
|
|
1283
1524
|
|
|
1284
|
-
export { AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppLayoutComponent, AppModulesComponent, AppTopbar, AuthGuardService, BaseDataService, BaseModuleComponent, ConfigComponent, ContentType, DbMigrationComponent, ErrorComponent, FooterComponent, HttpClient, KeycloakSecurityService, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, MsgService, NotfoundComponent, NotificationService, ProfileComponent, SecurePipe, SecurityComponent, SecurityDataService, SecurityService, SecurityStorageService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserService, httpLoaderAuthFactory, langIntercept, provideLogoComponent };
|
|
1525
|
+
export { AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppLayoutComponent, AppModulesComponent, AppTopbar, AuthGuardService, BaseDataService, BaseModuleComponent, ConfigComponent, ContentType, DbMigrationComponent, DiscussionComponent, ErrorComponent, FooterComponent, HttpClient, KeycloakSecurityService, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, MsgService, NotfoundComponent, NotificationService, ProfileComponent, SecurePipe, SecurityComponent, SecurityDataService, SecurityService, SecurityStorageService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserService, httpLoaderAuthFactory, langIntercept, provideLogoComponent };
|
|
1285
1526
|
export type { AppConfig, LanguageDto, MenuChangeEvent, NoSettingsDto, PutSecurityDto, RequestParams, SecurityDto, TopBarDto };
|
package/package.json
CHANGED
package/scripts/generate-api.mjs
CHANGED
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { generateApi, generateTemplates } from "swagger-typescript-api";
|
|
4
|
-
import { ArgumentParser } from "argparse";
|
|
5
|
-
|
|
6
|
-
const parser = new ArgumentParser({
|
|
7
|
-
description: "Argparse example"
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
parser.add_argument("-o", "--output", { help: "Output path" });
|
|
11
|
-
parser.add_argument("-i", "--input", { help: "Input swagger file path" });
|
|
12
|
-
parser.add_argument("-t", "--templates", { help: "Templates" });
|
|
13
|
-
parser.add_argument("-d", "--data-contract-prefix", { help: "Data Contract Prefix" });
|
|
14
|
-
parser.add_argument("-c", "--use-common-client", { action: "store_true", help: "Use common http client" });
|
|
15
|
-
|
|
16
|
-
let a = parser.parse_args();
|
|
17
|
-
a.data_contract_prefix ??= "";
|
|
18
|
-
|
|
19
|
-
console.log(a);
|
|
20
|
-
/* NOTE: all fields are optional expect one of `input`, `url`, `spec` */
|
|
21
|
-
|
|
22
|
-
let config = {
|
|
23
|
-
input: path.resolve(process.cwd(), a.input),
|
|
24
|
-
templates: path.resolve(process.cwd(), a.templates),
|
|
25
|
-
httpClientType: "fetch", // or "fetch"
|
|
26
|
-
defaultResponseAsSuccess: false,
|
|
27
|
-
generateClient: true,
|
|
28
|
-
useCommonClient: a.use_common_client,
|
|
29
|
-
generateRouteTypes: false,
|
|
30
|
-
generateResponses: true,
|
|
31
|
-
toJS: false,
|
|
32
|
-
extractRequestParams: true,
|
|
33
|
-
extractRequestBody: true,
|
|
34
|
-
extractEnums: true,
|
|
35
|
-
unwrapResponseData: true,
|
|
36
|
-
modular: true,
|
|
37
|
-
prettier: {
|
|
38
|
-
printWidth: 120,
|
|
39
|
-
tabWidth: 2,
|
|
40
|
-
trailingComma: "all",
|
|
41
|
-
parser: "typescript"
|
|
42
|
-
},
|
|
43
|
-
defaultResponseType: "void",
|
|
44
|
-
singleHttpClient: false,
|
|
45
|
-
cleanOutput: false,
|
|
46
|
-
enumNamesAsValues: false,
|
|
47
|
-
moduleNameFirstTag: true,
|
|
48
|
-
generateUnionEnums: false,
|
|
49
|
-
dataContractPrefix: a.data_contract_prefix,
|
|
50
|
-
typePrefix: "",
|
|
51
|
-
typeSuffix: "",
|
|
52
|
-
enumKeyPrefix: "",
|
|
53
|
-
enumKeySuffix: "",
|
|
54
|
-
addReadonly: false,
|
|
55
|
-
sortTypes: false,
|
|
56
|
-
sortRouters: false,
|
|
57
|
-
extractingOptions: {
|
|
58
|
-
requestBodySuffix: ["Payload", "Body", "Input"],
|
|
59
|
-
requestParamsSuffix: ["Params"],
|
|
60
|
-
responseBodySuffix: ["Data", "Result", "Output"],
|
|
61
|
-
responseErrorSuffix: ["Error", "Fail", "Fails", "ErrorData", "HttpError", "BadResponse"]
|
|
62
|
-
},
|
|
63
|
-
/** allow to generate extra files based with this extra templates, see more below */
|
|
64
|
-
extraTemplates: [],
|
|
65
|
-
anotherArrayType: false,
|
|
66
|
-
fixInvalidTypeNamePrefix: "Type",
|
|
67
|
-
fixInvalidEnumKeyPrefix: "Value",
|
|
68
|
-
codeGenConstructs: (constructs) => ({
|
|
69
|
-
...constructs,
|
|
70
|
-
RecordType: (key, value) => `MyRecord<key, value>`
|
|
71
|
-
}),
|
|
72
|
-
primitiveTypeConstructs: (constructs) => ({
|
|
73
|
-
...constructs,
|
|
74
|
-
string: {
|
|
75
|
-
"date-time": "Date"
|
|
76
|
-
}
|
|
77
|
-
}),
|
|
78
|
-
hooks: {
|
|
79
|
-
onCreateComponent: (component) => {},
|
|
80
|
-
onCreateRequestParams: (rawType) => {},
|
|
81
|
-
onCreateRoute: (routeData) => {},
|
|
82
|
-
onCreateRouteName: (routeNameInfo, rawRouteInfo) => {
|
|
83
|
-
if (routeNameInfo.usage.startsWith(rawRouteInfo.moduleName)) {
|
|
84
|
-
const str = routeNameInfo.usage.substring(rawRouteInfo.moduleName.length);
|
|
85
|
-
routeNameInfo.usage = str[0].toLowerCase() + str.slice(1);
|
|
86
|
-
routeNameInfo.original = routeNameInfo.usage;
|
|
87
|
-
}
|
|
88
|
-
return routeNameInfo;
|
|
89
|
-
},
|
|
90
|
-
onFormatRouteName: (routeInfo, templateRouteName) => {},
|
|
91
|
-
onFormatTypeName: (typeName, rawTypeName, schemaType) => {},
|
|
92
|
-
onInit: (configuration) => {},
|
|
93
|
-
onPreParseSchema: (originalSchema, typeName, schemaType) => {},
|
|
94
|
-
onParseSchema: (originalSchema, parsedSchema) => {},
|
|
95
|
-
onPrepareConfig: (currentConfiguration) => {}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
const toKebabCase = (str) =>
|
|
99
|
-
str &&
|
|
100
|
-
str
|
|
101
|
-
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
|
102
|
-
.map((x) => x.toLowerCase())
|
|
103
|
-
.join("-");
|
|
104
|
-
|
|
105
|
-
generateApi(config)
|
|
106
|
-
.then(async ({ files, configuration }) => {
|
|
107
|
-
let dir = path.join(process.cwd(), a.output);
|
|
108
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir);
|
|
109
|
-
|
|
110
|
-
for (const f of files) {
|
|
111
|
-
if (f.fileContent) {
|
|
112
|
-
if (a.use_common_client && f.fileName === "http-client") {
|
|
113
|
-
console.log("Use common http client from oip, skip generate http-client.ts");
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (f.fileName === "data-contracts") {
|
|
118
|
-
f.fileName = config.dataContractPrefix + f.fileName;
|
|
119
|
-
} else if (f.fileName.endsWith("http-client")) {
|
|
120
|
-
// do nothing
|
|
121
|
-
} else {
|
|
122
|
-
f.fileName = `${toKebabCase(f.fileName)}.api`;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const absolutePath = path.join(dir, `${f.fileName}${f.fileExtension}`);
|
|
126
|
-
fs.writeFile(absolutePath, f.fileContent, (err) => {
|
|
127
|
-
if (err) {
|
|
128
|
-
console.log(err);
|
|
129
|
-
} else {
|
|
130
|
-
console.log(`File create: ${f.fileName}${f.fileExtension}`);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
})
|
|
136
|
-
.catch((e) => console.error(e));
|
|
137
|
-
|
|
138
|
-
/*
|
|
139
|
-
generateTemplates({
|
|
140
|
-
cleanOutput: false,
|
|
141
|
-
output: './output/',
|
|
142
|
-
httpClientType: "fetch",
|
|
143
|
-
modular: true,
|
|
144
|
-
silent: false,
|
|
145
|
-
rewrite: false,
|
|
146
|
-
});
|
|
147
|
-
*/
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { generateApi, generateTemplates } from "swagger-typescript-api";
|
|
4
|
+
import { ArgumentParser } from "argparse";
|
|
5
|
+
|
|
6
|
+
const parser = new ArgumentParser({
|
|
7
|
+
description: "Argparse example"
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
parser.add_argument("-o", "--output", { help: "Output path" });
|
|
11
|
+
parser.add_argument("-i", "--input", { help: "Input swagger file path" });
|
|
12
|
+
parser.add_argument("-t", "--templates", { help: "Templates" });
|
|
13
|
+
parser.add_argument("-d", "--data-contract-prefix", { help: "Data Contract Prefix" });
|
|
14
|
+
parser.add_argument("-c", "--use-common-client", { action: "store_true", help: "Use common http client" });
|
|
15
|
+
|
|
16
|
+
let a = parser.parse_args();
|
|
17
|
+
a.data_contract_prefix ??= "";
|
|
18
|
+
|
|
19
|
+
console.log(a);
|
|
20
|
+
/* NOTE: all fields are optional expect one of `input`, `url`, `spec` */
|
|
21
|
+
|
|
22
|
+
let config = {
|
|
23
|
+
input: path.resolve(process.cwd(), a.input),
|
|
24
|
+
templates: path.resolve(process.cwd(), a.templates),
|
|
25
|
+
httpClientType: "fetch", // or "fetch"
|
|
26
|
+
defaultResponseAsSuccess: false,
|
|
27
|
+
generateClient: true,
|
|
28
|
+
useCommonClient: a.use_common_client,
|
|
29
|
+
generateRouteTypes: false,
|
|
30
|
+
generateResponses: true,
|
|
31
|
+
toJS: false,
|
|
32
|
+
extractRequestParams: true,
|
|
33
|
+
extractRequestBody: true,
|
|
34
|
+
extractEnums: true,
|
|
35
|
+
unwrapResponseData: true,
|
|
36
|
+
modular: true,
|
|
37
|
+
prettier: {
|
|
38
|
+
printWidth: 120,
|
|
39
|
+
tabWidth: 2,
|
|
40
|
+
trailingComma: "all",
|
|
41
|
+
parser: "typescript"
|
|
42
|
+
},
|
|
43
|
+
defaultResponseType: "void",
|
|
44
|
+
singleHttpClient: false,
|
|
45
|
+
cleanOutput: false,
|
|
46
|
+
enumNamesAsValues: false,
|
|
47
|
+
moduleNameFirstTag: true,
|
|
48
|
+
generateUnionEnums: false,
|
|
49
|
+
dataContractPrefix: a.data_contract_prefix,
|
|
50
|
+
typePrefix: "",
|
|
51
|
+
typeSuffix: "",
|
|
52
|
+
enumKeyPrefix: "",
|
|
53
|
+
enumKeySuffix: "",
|
|
54
|
+
addReadonly: false,
|
|
55
|
+
sortTypes: false,
|
|
56
|
+
sortRouters: false,
|
|
57
|
+
extractingOptions: {
|
|
58
|
+
requestBodySuffix: ["Payload", "Body", "Input"],
|
|
59
|
+
requestParamsSuffix: ["Params"],
|
|
60
|
+
responseBodySuffix: ["Data", "Result", "Output"],
|
|
61
|
+
responseErrorSuffix: ["Error", "Fail", "Fails", "ErrorData", "HttpError", "BadResponse"]
|
|
62
|
+
},
|
|
63
|
+
/** allow to generate extra files based with this extra templates, see more below */
|
|
64
|
+
extraTemplates: [],
|
|
65
|
+
anotherArrayType: false,
|
|
66
|
+
fixInvalidTypeNamePrefix: "Type",
|
|
67
|
+
fixInvalidEnumKeyPrefix: "Value",
|
|
68
|
+
codeGenConstructs: (constructs) => ({
|
|
69
|
+
...constructs,
|
|
70
|
+
RecordType: (key, value) => `MyRecord<key, value>`
|
|
71
|
+
}),
|
|
72
|
+
primitiveTypeConstructs: (constructs) => ({
|
|
73
|
+
...constructs,
|
|
74
|
+
string: {
|
|
75
|
+
"date-time": "Date"
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
hooks: {
|
|
79
|
+
onCreateComponent: (component) => {},
|
|
80
|
+
onCreateRequestParams: (rawType) => {},
|
|
81
|
+
onCreateRoute: (routeData) => {},
|
|
82
|
+
onCreateRouteName: (routeNameInfo, rawRouteInfo) => {
|
|
83
|
+
if (routeNameInfo.usage.startsWith(rawRouteInfo.moduleName)) {
|
|
84
|
+
const str = routeNameInfo.usage.substring(rawRouteInfo.moduleName.length);
|
|
85
|
+
routeNameInfo.usage = str[0].toLowerCase() + str.slice(1);
|
|
86
|
+
routeNameInfo.original = routeNameInfo.usage;
|
|
87
|
+
}
|
|
88
|
+
return routeNameInfo;
|
|
89
|
+
},
|
|
90
|
+
onFormatRouteName: (routeInfo, templateRouteName) => {},
|
|
91
|
+
onFormatTypeName: (typeName, rawTypeName, schemaType) => {},
|
|
92
|
+
onInit: (configuration) => {},
|
|
93
|
+
onPreParseSchema: (originalSchema, typeName, schemaType) => {},
|
|
94
|
+
onParseSchema: (originalSchema, parsedSchema) => {},
|
|
95
|
+
onPrepareConfig: (currentConfiguration) => {}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const toKebabCase = (str) =>
|
|
99
|
+
str &&
|
|
100
|
+
str
|
|
101
|
+
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
|
102
|
+
.map((x) => x.toLowerCase())
|
|
103
|
+
.join("-");
|
|
104
|
+
|
|
105
|
+
generateApi(config)
|
|
106
|
+
.then(async ({ files, configuration }) => {
|
|
107
|
+
let dir = path.join(process.cwd(), a.output);
|
|
108
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir);
|
|
109
|
+
|
|
110
|
+
for (const f of files) {
|
|
111
|
+
if (f.fileContent) {
|
|
112
|
+
if (a.use_common_client && f.fileName === "http-client") {
|
|
113
|
+
console.log("Use common http client from oip, skip generate http-client.ts");
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (f.fileName === "data-contracts") {
|
|
118
|
+
f.fileName = config.dataContractPrefix + f.fileName;
|
|
119
|
+
} else if (f.fileName.endsWith("http-client")) {
|
|
120
|
+
// do nothing
|
|
121
|
+
} else {
|
|
122
|
+
f.fileName = `${toKebabCase(f.fileName)}.api`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const absolutePath = path.join(dir, `${f.fileName}${f.fileExtension}`);
|
|
126
|
+
fs.writeFile(absolutePath, f.fileContent, (err) => {
|
|
127
|
+
if (err) {
|
|
128
|
+
console.log(err);
|
|
129
|
+
} else {
|
|
130
|
+
console.log(`File create: ${f.fileName}${f.fileExtension}`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
.catch((e) => console.error(e));
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
generateTemplates({
|
|
140
|
+
cleanOutput: false,
|
|
141
|
+
output: './output/',
|
|
142
|
+
httpClientType: "fetch",
|
|
143
|
+
modular: true,
|
|
144
|
+
silent: false,
|
|
145
|
+
rewrite: false,
|
|
146
|
+
});
|
|
147
|
+
*/
|
|
@@ -58,9 +58,21 @@ export enum ContentType {
|
|
|
58
58
|
|
|
59
59
|
@Injectable({ providedIn: 'root' })
|
|
60
60
|
export class HttpClient<SecurityDataType = unknown> {
|
|
61
|
+
protected securityService = inject(SecurityService);
|
|
62
|
+
protected layoutService = inject(LayoutService);
|
|
61
63
|
public baseUrl: string = "<%~ apiConfig.baseUrl %>";
|
|
62
64
|
private securityData: SecurityDataType | null = null;
|
|
63
|
-
private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"]
|
|
65
|
+
private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"] =
|
|
66
|
+
(securityData) => ({
|
|
67
|
+
headers: {
|
|
68
|
+
"Accept-language": this.layoutService.language()
|
|
69
|
+
? this.layoutService.language()
|
|
70
|
+
: 'en',
|
|
71
|
+
"X-Timezone": this.layoutService.timeZone(),
|
|
72
|
+
Authorization: `Bearer ${securityData}`,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
64
76
|
private abortControllers = new Map<CancelToken, AbortController>();
|
|
65
77
|
private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams);
|
|
66
78
|
|
|
@@ -71,10 +83,11 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
71
83
|
referrerPolicy: 'no-referrer',
|
|
72
84
|
}
|
|
73
85
|
|
|
74
|
-
constructor(
|
|
75
|
-
|
|
86
|
+
constructor() {
|
|
87
|
+
this.securityService.getAccessToken().subscribe((token) => {
|
|
88
|
+
this.securityData = token;
|
|
89
|
+
});
|
|
76
90
|
}
|
|
77
|
-
|
|
78
91
|
public setSecurityData = (data: SecurityDataType | null) => {
|
|
79
92
|
this.securityData = data;
|
|
80
93
|
}
|
|
@@ -190,7 +203,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
190
203
|
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
191
204
|
const queryString = query && this.toQueryString(query);
|
|
192
205
|
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
|
193
|
-
|
|
206
|
+
let responseFormat = format || requestParams.format;
|
|
194
207
|
|
|
195
208
|
return this.customFetch(
|
|
196
209
|
`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`,
|