oip-common 0.0.33 → 0.0.37

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/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>;
@@ -1163,6 +1165,241 @@ declare class AppFloatingConfiguratorComponent {
1163
1165
  static ɵcmp: i0.ɵɵComponentDeclaration<AppFloatingConfiguratorComponent, "app-floating-configurator", never, {}, {}, never, never, true, never>;
1164
1166
  }
1165
1167
 
1168
+ /** Attachment response DTO. */
1169
+ interface AttachmentDto {
1170
+ /**
1171
+ * Attachment identifier.
1172
+ * @format int64
1173
+ */
1174
+ attachmentId?: number;
1175
+ /** Original file name. */
1176
+ fileName?: string | null;
1177
+ /** MIME type of the file. */
1178
+ fileType?: string | null;
1179
+ /**
1180
+ * File size in bytes.
1181
+ * @format int64
1182
+ */
1183
+ fileSize?: number;
1184
+ /**
1185
+ * Upload timestamp.
1186
+ * @format date-time
1187
+ */
1188
+ uploadedAt?: Date;
1189
+ /**
1190
+ * File storage identifier.
1191
+ * @format uuid
1192
+ */
1193
+ storageFileId?: string;
1194
+ /** Download URL for the file. */
1195
+ downloadUrl?: string | null;
1196
+ }
1197
+ /** Comment response DTO. */
1198
+ interface CommentDto {
1199
+ /**
1200
+ * Comment identifier.
1201
+ * @format int64
1202
+ */
1203
+ commentId?: number;
1204
+ /**
1205
+ * Related entity type identifier.
1206
+ * @format int64
1207
+ */
1208
+ objectTypeId?: number;
1209
+ /**
1210
+ * Related entity identifier.
1211
+ * @format int64
1212
+ */
1213
+ objectId?: number;
1214
+ /** Raw markdown comment content. */
1215
+ content?: string | null;
1216
+ /**
1217
+ * Author identifier.
1218
+ * @format int64
1219
+ */
1220
+ userId?: number;
1221
+ /** Author display name. */
1222
+ authorDisplayName?: string | null;
1223
+ /** Author e-mail. */
1224
+ authorEmail?: string | null;
1225
+ /**
1226
+ * Comment creation time.
1227
+ * @format date-time
1228
+ */
1229
+ createdAt?: Date;
1230
+ /**
1231
+ * Comment last update time.
1232
+ * @format date-time
1233
+ */
1234
+ updatedAt?: Date | null;
1235
+ /** Whether the comment was edited. */
1236
+ isEdited?: boolean;
1237
+ /**
1238
+ * Number of edit history entries.
1239
+ * @format int32
1240
+ */
1241
+ historyCount?: number;
1242
+ /** Whether the current user can edit this comment. */
1243
+ canEdit?: boolean;
1244
+ /** Whether the current user can delete this comment. */
1245
+ canDelete?: boolean;
1246
+ /** Attachments for the comment. */
1247
+ attachments?: AttachmentDto[] | null;
1248
+ /** Reactions aggregated for the comment. */
1249
+ reactions?: CommentReactionDto[] | null;
1250
+ /** Mentions for the comment. */
1251
+ mentions?: CommentMentionDto[] | null;
1252
+ }
1253
+ /** Comment edit history response DTO. */
1254
+ interface CommentHistoryDto {
1255
+ /**
1256
+ * History entry identifier.
1257
+ * @format int64
1258
+ */
1259
+ commentEditHistoryId?: number;
1260
+ /** Previous comment content. */
1261
+ oldContent?: string | null;
1262
+ /** Updated comment content. */
1263
+ newContent?: string | null;
1264
+ /**
1265
+ * Editor identifier.
1266
+ * @format int64
1267
+ */
1268
+ editedByUserId?: number;
1269
+ /** Editor display name. */
1270
+ editedByDisplayName?: string | null;
1271
+ /**
1272
+ * Time of edit.
1273
+ * @format date-time
1274
+ */
1275
+ editedAt?: Date;
1276
+ }
1277
+ /** Mention response DTO. */
1278
+ interface CommentMentionDto {
1279
+ /**
1280
+ * Mentioned user identifier.
1281
+ * @format int64
1282
+ */
1283
+ mentionedUserId?: number;
1284
+ /** Display name of the mentioned user. */
1285
+ displayName?: string | null;
1286
+ /** E-mail of the mentioned user. */
1287
+ email?: string | null;
1288
+ /**
1289
+ * Position within the markdown text.
1290
+ * @format int32
1291
+ */
1292
+ position?: number;
1293
+ }
1294
+ /** Aggregated reaction response DTO. */
1295
+ interface CommentReactionDto {
1296
+ /** Emoji code. */
1297
+ emojiCode?: string | null;
1298
+ /**
1299
+ * Number of reactions with the same emoji.
1300
+ * @format int32
1301
+ */
1302
+ count?: number;
1303
+ /** Whether the current user reacted with this emoji. */
1304
+ reactedByCurrentUser?: boolean;
1305
+ }
1306
+ /** Mention candidate response DTO. */
1307
+ interface MentionUserDto {
1308
+ /**
1309
+ * User identifier.
1310
+ * @format int64
1311
+ */
1312
+ userId?: number;
1313
+ /** Display name. */
1314
+ displayName?: string | null;
1315
+ /** E-mail. */
1316
+ email?: string | null;
1317
+ }
1318
+
1319
+ declare function getInitialsFromString(input: string): string;
1320
+
1321
+ type HistoryState = {
1322
+ loading: boolean;
1323
+ opened: boolean;
1324
+ items: DiscussionHistoryItem[];
1325
+ };
1326
+ type DiscussionAttachment = Required<AttachmentDto>;
1327
+ type DiscussionReaction = Required<CommentReactionDto>;
1328
+ type DiscussionMentionUser = Required<MentionUserDto>;
1329
+ type DiscussionComment = Omit<CommentDto, 'attachments' | 'reactions' | 'mentions'> & {
1330
+ commentId: number;
1331
+ content: string;
1332
+ authorDisplayName: string;
1333
+ authorEmail: string;
1334
+ isEdited: boolean;
1335
+ historyCount: number;
1336
+ canEdit: boolean;
1337
+ canDelete: boolean;
1338
+ attachments: DiscussionAttachment[];
1339
+ reactions: DiscussionReaction[];
1340
+ };
1341
+ type DiscussionHistoryItem = Required<CommentHistoryDto>;
1342
+ declare class DiscussionComponent implements OnChanges, OnDestroy, OnInit {
1343
+ private readonly msgService;
1344
+ private readonly discussionApi;
1345
+ private readonly sanitizer;
1346
+ private readonly translateService;
1347
+ private readonly cdr;
1348
+ private readonly confirmationService;
1349
+ protected readonly layoutService: LayoutService;
1350
+ objectTypeId: number;
1351
+ objectId: number;
1352
+ comments: DiscussionComment[];
1353
+ loading: boolean;
1354
+ submitting: boolean;
1355
+ previewMode: boolean;
1356
+ newComment: string;
1357
+ editContent: string;
1358
+ editingCommentId: number | null;
1359
+ pendingFiles: File[];
1360
+ mentionSuggestions: DiscussionMentionUser[];
1361
+ historyByComment: Record<number, HistoryState>;
1362
+ emojiPalette: string[];
1363
+ private mentionSearchTimer;
1364
+ ngOnChanges(changes: SimpleChanges): void;
1365
+ ngOnInit(): Promise<void>;
1366
+ ngOnDestroy(): void;
1367
+ loadComments(): Promise<void>;
1368
+ createComment(): Promise<void>;
1369
+ startEdit(comment: DiscussionComment): void;
1370
+ cancelEdit(): void;
1371
+ saveEdit(comment: DiscussionComment): Promise<void>;
1372
+ deleteComment(comment: DiscussionComment): void;
1373
+ toggleHistory(comment: DiscussionComment): Promise<void>;
1374
+ onFilesSelected(event: Event): void;
1375
+ removePendingFile(file: File): void;
1376
+ onInlineFilesSelected(comment: DiscussionComment, event: Event): Promise<void>;
1377
+ deleteAttachment(comment: DiscussionComment, attachment: DiscussionAttachment): void;
1378
+ private performDeleteComment;
1379
+ private performDeleteAttachment;
1380
+ downloadAttachment(attachment: DiscussionAttachment): Promise<void>;
1381
+ toggleReaction(comment: DiscussionComment, reaction: DiscussionReaction): Promise<void>;
1382
+ reactWithEmoji(comment: DiscussionComment, emojiCode: string, popover?: {
1383
+ hide: () => void;
1384
+ }): Promise<void>;
1385
+ onComposerInput(): void;
1386
+ insertMention(candidate: DiscussionMentionUser): void;
1387
+ renderMarkdown(markdown: string): string;
1388
+ formatBytes(value: number): string;
1389
+ hasUserReaction(comment: DiscussionComment): boolean;
1390
+ getReactions(comment: DiscussionComment): DiscussionReaction[];
1391
+ private applyReactions;
1392
+ private normalizeComment;
1393
+ private normalizeAttachment;
1394
+ private normalizeReaction;
1395
+ private normalizeMentionUser;
1396
+ private normalizeHistoryItem;
1397
+ private extractMentionQuery;
1398
+ protected readonly getInitialsFromString: typeof getInitialsFromString;
1399
+ static ɵfac: i0.ɵɵFactoryDeclaration<DiscussionComponent, never>;
1400
+ static ɵcmp: i0.ɵɵComponentDeclaration<DiscussionComponent, "discussion", never, { "objectTypeId": { "alias": "objectTypeId"; "required": true; }; "objectId": { "alias": "objectId"; "required": true; }; }, {}, never, never, true, never>;
1401
+ }
1402
+
1166
1403
  interface SecurityDto {
1167
1404
  code: string;
1168
1405
  name: string;
@@ -1277,5 +1514,5 @@ declare class SecurePipe implements PipeTransform {
1277
1514
  */
1278
1515
  declare const httpLoaderAuthFactory: (httpClient: HttpClient$1) => StsConfigHttpLoader;
1279
1516
 
1280
- 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 };
1517
+ 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 };
1281
1518
  export type { AppConfig, LanguageDto, MenuChangeEvent, NoSettingsDto, PutSecurityDto, RequestParams, SecurityDto, TopBarDto };
package/package.json CHANGED
@@ -1,15 +1,12 @@
1
1
  {
2
2
  "name": "oip-common",
3
- "version": "0.0.33",
3
+ "version": "0.0.37",
4
4
  "description": "A template for cross-platform web applications based on sakai-ng and primeNG",
5
5
  "main": "index.js",
6
6
  "keywords": [
7
7
  "oip",
8
8
  "template"
9
9
  ],
10
- "bin": {
11
- "oip-generate-api": "./dist/oip-common/scripts/generate-api.mjs"
12
- },
13
10
  "author": "Igor Tyulyakov aka g101k",
14
11
  "license": "MIT",
15
12
  "repository": {
@@ -1,19 +1,17 @@
1
- #!/usr/bin/env node
2
-
3
1
  import fs from "node:fs";
4
2
  import path from "node:path";
5
- import {generateApi, generateTemplates} from "swagger-typescript-api";
6
- import {ArgumentParser} from 'argparse';
3
+ import { generateApi, generateTemplates } from "swagger-typescript-api";
4
+ import { ArgumentParser } from "argparse";
7
5
 
8
6
  const parser = new ArgumentParser({
9
- description: 'Argparse example'
7
+ description: "Argparse example"
10
8
  });
11
9
 
12
- parser.add_argument('-o', '--output', {help: 'Output path'});
13
- parser.add_argument('-i', '--input', {help: 'Input swagger file path'});
14
- parser.add_argument('-t', '--templates', {help: 'Templates'});
15
- parser.add_argument('-d', '--data-contract-prefix', {help: 'Data Contract Prefix'});
16
- parser.add_argument('-c', '--use-common-client', {action: 'store_true', help: 'Use common http client'});
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" });
17
15
 
18
16
  let a = parser.parse_args();
19
17
  a.data_contract_prefix ??= "";
@@ -40,7 +38,7 @@ let config = {
40
38
  printWidth: 120,
41
39
  tabWidth: 2,
42
40
  trailingComma: "all",
43
- parser: "typescript",
41
+ parser: "typescript"
44
42
  },
45
43
  defaultResponseType: "void",
46
44
  singleHttpClient: false,
@@ -60,14 +58,7 @@ let config = {
60
58
  requestBodySuffix: ["Payload", "Body", "Input"],
61
59
  requestParamsSuffix: ["Params"],
62
60
  responseBodySuffix: ["Data", "Result", "Output"],
63
- responseErrorSuffix: [
64
- "Error",
65
- "Fail",
66
- "Fails",
67
- "ErrorData",
68
- "HttpError",
69
- "BadResponse",
70
- ],
61
+ responseErrorSuffix: ["Error", "Fail", "Fails", "ErrorData", "HttpError", "BadResponse"]
71
62
  },
72
63
  /** allow to generate extra files based with this extra templates, see more below */
73
64
  extraTemplates: [],
@@ -76,21 +67,18 @@ let config = {
76
67
  fixInvalidEnumKeyPrefix: "Value",
77
68
  codeGenConstructs: (constructs) => ({
78
69
  ...constructs,
79
- RecordType: (key, value) => `MyRecord<key, value>`,
70
+ RecordType: (key, value) => `MyRecord<key, value>`
80
71
  }),
81
72
  primitiveTypeConstructs: (constructs) => ({
82
73
  ...constructs,
83
74
  string: {
84
- "date-time": "Date",
85
- },
75
+ "date-time": "Date"
76
+ }
86
77
  }),
87
78
  hooks: {
88
- onCreateComponent: (component) => {
89
- },
90
- onCreateRequestParams: (rawType) => {
91
- },
92
- onCreateRoute: (routeData) => {
93
- },
79
+ onCreateComponent: (component) => {},
80
+ onCreateRequestParams: (rawType) => {},
81
+ onCreateRoute: (routeData) => {},
94
82
  onCreateRouteName: (routeNameInfo, rawRouteInfo) => {
95
83
  if (routeNameInfo.usage.startsWith(rawRouteInfo.moduleName)) {
96
84
  const str = routeNameInfo.usage.substring(rawRouteInfo.moduleName.length);
@@ -99,40 +87,36 @@ let config = {
99
87
  }
100
88
  return routeNameInfo;
101
89
  },
102
- onFormatRouteName: (routeInfo, templateRouteName) => {
103
- },
104
- onFormatTypeName: (typeName, rawTypeName, schemaType) => {
105
- },
106
- onInit: (configuration) => {
107
- },
108
- onPreParseSchema: (originalSchema, typeName, schemaType) => {
109
- },
110
- onParseSchema: (originalSchema, parsedSchema) => {
111
- },
112
- onPrepareConfig: (currentConfiguration) => {
113
- },
114
- },
115
- }
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
+ };
116
98
  const toKebabCase = (str) =>
117
99
  str &&
118
100
  str
119
101
  .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
120
- .map(x => x.toLowerCase())
121
- .join('-');
102
+ .map((x) => x.toLowerCase())
103
+ .join("-");
122
104
 
123
105
  generateApi(config)
124
- .then(async ({files, configuration}) => {
106
+ .then(async ({ files, configuration }) => {
107
+ let dir = path.join(process.cwd(), a.output);
108
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir);
109
+
125
110
  for (const f of files) {
126
111
  if (f.fileContent) {
127
- if (f.fileName === 'http-client')
112
+ if (a.use_common_client && f.fileName === "http-client") {
113
+ console.log("Use common http client from oip, skip generate http-client.ts");
128
114
  continue;
129
- let dir = path.join(process.cwd(), a.output);
130
- if (!fs.existsSync(dir))
131
- fs.mkdirSync(dir);
115
+ }
132
116
 
133
- if (f.fileName === 'data-contracts') {
117
+ if (f.fileName === "data-contracts") {
134
118
  f.fileName = config.dataContractPrefix + f.fileName;
135
- } else if (f.fileName.endsWith('http-client')) {
119
+ } else if (f.fileName.endsWith("http-client")) {
136
120
  // do nothing
137
121
  } else {
138
122
  f.fileName = `${toKebabCase(f.fileName)}.api`;
package/templates/api.ejs CHANGED
@@ -1,3 +1,7 @@
1
+ /* eslint-disable */
2
+ /* tslint:disable */
3
+ // @ts-nocheck
4
+
1
5
  <%
2
6
  const { utils, route, config, modelTypes } = it;
3
7
  const { _, pascalCase, require } = utils;
@@ -1,3 +1,7 @@
1
+ /* eslint-disable */
2
+ /* tslint:disable */
3
+ // @ts-nocheck
4
+
1
5
  <%
2
6
  const { apiConfig, generateResponses, config } = it;
3
7
  %>
@@ -54,9 +58,21 @@ export enum ContentType {
54
58
 
55
59
  @Injectable({ providedIn: 'root' })
56
60
  export class HttpClient<SecurityDataType = unknown> {
61
+ protected securityService = inject(SecurityService);
62
+ protected layoutService = inject(LayoutService);
57
63
  public baseUrl: string = "<%~ apiConfig.baseUrl %>";
58
64
  private securityData: SecurityDataType | null = null;
59
- 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
+
60
76
  private abortControllers = new Map<CancelToken, AbortController>();
61
77
  private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams);
62
78
 
@@ -67,10 +83,11 @@ export class HttpClient<SecurityDataType = unknown> {
67
83
  referrerPolicy: 'no-referrer',
68
84
  }
69
85
 
70
- constructor(apiConfig: ApiConfig<SecurityDataType> = {}) {
71
- Object.assign(this, apiConfig);
86
+ constructor() {
87
+ this.securityService.getAccessToken().subscribe((token) => {
88
+ this.securityData = token;
89
+ });
72
90
  }
73
-
74
91
  public setSecurityData = (data: SecurityDataType | null) => {
75
92
  this.securityData = data;
76
93
  }
@@ -186,7 +203,7 @@ export class HttpClient<SecurityDataType = unknown> {
186
203
  const requestParams = this.mergeRequestParams(params, secureParams);
187
204
  const queryString = query && this.toQueryString(query);
188
205
  const payloadFormatter = this.contentFormatters[type || ContentType.Json];
189
- const responseFormat = format || requestParams.format;
206
+ let responseFormat = format || requestParams.format;
190
207
 
191
208
  return this.customFetch(
192
209
  `${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`,