@ikonintegration/module-config-api 2.0.20 → 2.0.22

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/Api.ts CHANGED
@@ -2934,7 +2934,7 @@ export interface FaqResponse {
2934
2934
  answer?: string
2935
2935
  }
2936
2936
 
2937
- export interface InputL7Xnhpovxz {
2937
+ export interface Input83M8Qu78L7J {
2938
2938
  /**
2939
2939
  * Tenant ID this FAQ belongs to
2940
2940
  * @example "tenant456"
@@ -2957,7 +2957,7 @@ export interface InputL7Xnhpovxz {
2957
2957
  answer?: string
2958
2958
  }
2959
2959
 
2960
- export interface InputMr9V08Vrqrh {
2960
+ export interface Input8Ywv6L6Asf {
2961
2961
  /**
2962
2962
  * Tenant ID this FAQ belongs to
2963
2963
  * @example "tenant456"
@@ -3136,10 +3136,15 @@ export interface CertificationResponse {
3136
3136
  */
3137
3137
  eventID: string
3138
3138
  /**
3139
- * Email template identifier override for the event
3139
+ * Optional email template identifier override for the event
3140
3140
  * @example "template001"
3141
3141
  */
3142
- templateID: string
3142
+ templateID?: string
3143
+ /**
3144
+ * Optional array of email addresses that will be receive a cc for this event
3145
+ * @example "["mail1@email.com","mail2@email.com"]"
3146
+ */
3147
+ cc: string[]
3143
3148
  }[]
3144
3149
  /** Warning threshold for incomplete certification */
3145
3150
  warningIncompleteCertificationDays?: {
@@ -3201,6 +3206,11 @@ export interface CertificationResponse {
3201
3206
  * @example false
3202
3207
  */
3203
3208
  overrideCompletionRequirementOnRenewal?: boolean
3209
+ /**
3210
+ * supercedes overrideCompletionRequirementOnRenewal when used, calculates the cert expiration date in a renewal using the certification renewal completion date
3211
+ * @example false
3212
+ */
3213
+ calculateExpirationUsingRenewalCompletionDate?: boolean
3204
3214
  /** Application configuration */
3205
3215
  application?: any
3206
3216
  /** Renewal configuration */
@@ -3349,10 +3359,15 @@ export interface CertificationRequestBody {
3349
3359
  */
3350
3360
  eventID: string
3351
3361
  /**
3352
- * Email template identifier override for the event
3362
+ * Optional email template identifier override for the event
3353
3363
  * @example "template001"
3354
3364
  */
3355
- templateID: string
3365
+ templateID?: string
3366
+ /**
3367
+ * Optional array of email addresses that will be receive a cc for this event
3368
+ * @example "["mail1@email.com","mail2@email.com"]"
3369
+ */
3370
+ cc: string[]
3356
3371
  }[]
3357
3372
  /** Warning threshold for incomplete certification */
3358
3373
  warningIncompleteCertificationDays?: {
@@ -3414,6 +3429,11 @@ export interface CertificationRequestBody {
3414
3429
  * @example false
3415
3430
  */
3416
3431
  overrideCompletionRequirementOnRenewal?: boolean
3432
+ /**
3433
+ * supercedes overrideCompletionRequirementOnRenewal when used, calculates the cert expiration date in a renewal using the certification renewal completion date
3434
+ * @example false
3435
+ */
3436
+ calculateExpirationUsingRenewalCompletionDate?: boolean
3417
3437
  /** Application configuration */
3418
3438
  application?: any
3419
3439
  /** Renewal configuration */
@@ -3583,10 +3603,15 @@ export interface CertificationListResponse {
3583
3603
  */
3584
3604
  eventID: string
3585
3605
  /**
3586
- * Email template identifier override for the event
3606
+ * Optional email template identifier override for the event
3587
3607
  * @example "template001"
3588
3608
  */
3589
- templateID: string
3609
+ templateID?: string
3610
+ /**
3611
+ * Optional array of email addresses that will be receive a cc for this event
3612
+ * @example "["mail1@email.com","mail2@email.com"]"
3613
+ */
3614
+ cc: string[]
3590
3615
  }[]
3591
3616
  /** Warning threshold for incomplete certification */
3592
3617
  warningIncompleteCertificationDays?: {
@@ -3648,6 +3673,11 @@ export interface CertificationListResponse {
3648
3673
  * @example false
3649
3674
  */
3650
3675
  overrideCompletionRequirementOnRenewal?: boolean
3676
+ /**
3677
+ * supercedes overrideCompletionRequirementOnRenewal when used, calculates the cert expiration date in a renewal using the certification renewal completion date
3678
+ * @example false
3679
+ */
3680
+ calculateExpirationUsingRenewalCompletionDate?: boolean
3651
3681
  /** Application configuration */
3652
3682
  application?: any
3653
3683
  /** Renewal configuration */
@@ -3969,10 +3999,15 @@ export interface CourseResponse {
3969
3999
  */
3970
4000
  eventID: string
3971
4001
  /**
3972
- * Email template identifier override for the event
4002
+ * Optional email template identifier override for the event
3973
4003
  * @example "template001"
3974
4004
  */
3975
- templateID: string
4005
+ templateID?: string
4006
+ /**
4007
+ * Optional array of email addresses that will be receive a cc for this event
4008
+ * @example "["mail1@email.com","mail2@email.com"]"
4009
+ */
4010
+ cc: string[]
3976
4011
  }[]
3977
4012
  /**
3978
4013
  * Display name
@@ -4286,10 +4321,15 @@ export interface CourseRequestBody {
4286
4321
  */
4287
4322
  eventID: string
4288
4323
  /**
4289
- * Email template identifier override for the event
4324
+ * Optional email template identifier override for the event
4290
4325
  * @example "template001"
4291
4326
  */
4292
- templateID: string
4327
+ templateID?: string
4328
+ /**
4329
+ * Optional array of email addresses that will be receive a cc for this event
4330
+ * @example "["mail1@email.com","mail2@email.com"]"
4331
+ */
4332
+ cc: string[]
4293
4333
  }[]
4294
4334
  /**
4295
4335
  * Display name
@@ -4665,10 +4705,15 @@ export interface CourseListResponse {
4665
4705
  */
4666
4706
  eventID: string
4667
4707
  /**
4668
- * Email template identifier override for the event
4708
+ * Optional email template identifier override for the event
4669
4709
  * @example "template001"
4670
4710
  */
4671
- templateID: string
4711
+ templateID?: string
4712
+ /**
4713
+ * Optional array of email addresses that will be receive a cc for this event
4714
+ * @example "["mail1@email.com","mail2@email.com"]"
4715
+ */
4716
+ cc: string[]
4672
4717
  }[]
4673
4718
  /**
4674
4719
  * Display name
@@ -5432,7 +5477,7 @@ export class HttpClient<SecurityDataType = unknown> {
5432
5477
 
5433
5478
  /**
5434
5479
  * @title No title
5435
- * @version 2.0.20
5480
+ * @version 2.0.22
5436
5481
  * @baseUrl http://localhost:8080
5437
5482
  * @contact Ikon Integration <ikon@ikonintegration.com> (http://example.com)
5438
5483
  */
@@ -6097,7 +6142,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
6097
6142
  * @request POST:/tenant/{tenantID}/faq/{faqID}
6098
6143
  * @secure
6099
6144
  */
6100
- createFaq: (tenantId: string, faqId: string, data: InputL7Xnhpovxz, params: RequestParams = {}) =>
6145
+ createFaq: (tenantId: string, faqId: string, data: Input83M8Qu78L7J, params: RequestParams = {}) =>
6101
6146
  this.request<CreateFaqData, CreateFaqError>({
6102
6147
  path: `/tenant/${tenantId}/faq/${faqId}`,
6103
6148
  method: 'POST',
@@ -6116,7 +6161,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
6116
6161
  * @request PUT:/tenant/{tenantID}/faq/{faqID}
6117
6162
  * @secure
6118
6163
  */
6119
- updateFaq: (tenantId: string, faqId: string, data: InputMr9V08Vrqrh, params: RequestParams = {}) =>
6164
+ updateFaq: (tenantId: string, faqId: string, data: Input8Ywv6L6Asf, params: RequestParams = {}) =>
6120
6165
  this.request<UpdateFaqData, UpdateFaqError>({
6121
6166
  path: `/tenant/${tenantId}/faq/${faqId}`,
6122
6167
  method: 'PUT',
package/CacheClient.ts CHANGED
@@ -1,21 +1,26 @@
1
1
  // @ts-nocheck — This file is compiled in CI alongside generated sources (Api.js)
2
- import { Api } from './Api.js'
3
- import type { CustomerResponse, TenantResponse } from './Api.js'
4
2
  import { MemoryCache } from './MemoryCache.js'
5
- import { RedisLike, CacheConfig, CacheConstants } from './CacheTypes.js'
3
+ import {
4
+ RedisLike,
5
+ CacheConfig,
6
+ CacheConstants,
7
+ CachedCustomer,
8
+ CachedTenant,
9
+ CachedCertification,
10
+ CachedCourse,
11
+ } from './CacheTypes.js'
6
12
 
7
13
  /**
8
14
  * Extended client that wraps the auto-generated Api with Redis cache support.
9
- * Provides direct Redis-backed lookups for customers, tenants, certifications, and courses.
15
+ * Provides direct Redis-backed lookups for expanded customers, tenants, certifications, and courses
16
+ * as they are stored in the persistent cache (not the raw API responses).
10
17
  *
11
18
  * Usage:
12
19
  * ```ts
13
- * import { CacheClient } from "@ikonintegration/module-config-api/cache";
20
+ * import { CacheClient } from "@ikonintegration/module-config-api";
14
21
  *
15
22
  * const client = new CacheClient({
16
- * // API layer (passed to the generated Api client)
17
23
  * baseUrl: "https://api.example.com",
18
- * // Cache layer (optional — enables Redis-backed lookups)
19
24
  * cache: {
20
25
  * endpoint: "redis.example.com",
21
26
  * username: "default",
@@ -27,28 +32,21 @@ import { RedisLike, CacheConfig, CacheConstants } from './CacheTypes.js'
27
32
  * ```
28
33
  */
29
34
  export class CacheClient {
30
- public api: Api<unknown>
31
35
  private _localCache: MemoryCache
36
+
32
37
  private _remoteCache: RedisLike | null = null
38
+
33
39
  private _cacheConfig: CacheConfig | null
34
40
 
35
- constructor(options: {
36
- baseUrl?: string
37
- baseApiParams?: ConstructorParameters<typeof Api>[0]
38
- cache?: CacheConfig
39
- }) {
40
- this.api = new Api({
41
- baseURL: options.baseUrl,
42
- ...options.baseApiParams,
43
- })
41
+ constructor(options: { cache?: CacheConfig }) {
44
42
  this._localCache = new MemoryCache()
45
43
  this._cacheConfig = options.cache || null
46
44
  }
47
45
 
48
46
  /********* CACHE LAYER — Customers *********/
49
47
 
50
- async getAllCustomers(): Promise<CustomerResponse[] | null> {
51
- let allCustomers = this._localCache.getValue<CustomerResponse[]>(CacheConstants.CustomerPrefix)
48
+ async getAllCustomers(): Promise<CachedCustomer[] | null> {
49
+ let allCustomers = this._localCache.getValue<CachedCustomer[]>(CacheConstants.CustomerPrefix)
52
50
  if (!allCustomers) {
53
51
  console.debug('ConfigClient - Customers Fetch All')
54
52
  allCustomers = await this._getAllRemoteCustomers()
@@ -58,12 +56,12 @@ export class CacheClient {
58
56
  return allCustomers
59
57
  }
60
58
 
61
- async getCustomerByID(customerID: string): Promise<CustomerResponse | null> {
59
+ async getCustomerByID(customerID: string): Promise<CachedCustomer | null> {
62
60
  // Attempt local cache
63
- let customer = this._localCache.getValue<CustomerResponse>(`${CacheConstants.CustomerPrefix}${customerID}`)
61
+ let customer = this._localCache.getValue<CachedCustomer>(`${CacheConstants.CustomerPrefix}${customerID}`)
64
62
  // Attempt from allCustomers local cache
65
63
  if (!customer) {
66
- const allCustomers = this._localCache.getValue<CustomerResponse[]>(CacheConstants.CustomerPrefix)
64
+ const allCustomers = this._localCache.getValue<CachedCustomer[]>(CacheConstants.CustomerPrefix)
67
65
  customer = allCustomers?.find(c => c.id === customerID) || null
68
66
  }
69
67
  // Attempt remote cache
@@ -80,8 +78,8 @@ export class CacheClient {
80
78
 
81
79
  /********* CACHE LAYER — Tenants *********/
82
80
 
83
- async getAllTenants(): Promise<TenantResponse[] | null> {
84
- let allTenants = this._localCache.getValue<TenantResponse[]>(CacheConstants.TenantPrefix)
81
+ async getAllTenants(): Promise<CachedTenant[] | null> {
82
+ let allTenants = this._localCache.getValue<CachedTenant[]>(CacheConstants.TenantPrefix)
85
83
  if (!allTenants) {
86
84
  console.debug('ConfigClient - Tenants Fetch All')
87
85
  allTenants = await this._getAllRemoteTenants()
@@ -91,8 +89,8 @@ export class CacheClient {
91
89
  return allTenants
92
90
  }
93
91
 
94
- async getTenantByID(tenantID: string): Promise<TenantResponse | null> {
95
- let tenant = this._localCache.getValue<TenantResponse>(`${CacheConstants.TenantPrefix}${tenantID}`)
92
+ async getTenantByID(tenantID: string): Promise<CachedTenant | null> {
93
+ let tenant = this._localCache.getValue<CachedTenant>(`${CacheConstants.TenantPrefix}${tenantID}`)
96
94
  if (!tenant) {
97
95
  console.debug('ConfigClient - Tenant Fetch:', tenantID)
98
96
  await this._initCacheClient()
@@ -106,19 +104,19 @@ export class CacheClient {
106
104
 
107
105
  /********* CACHE LAYER — Certifications & Courses *********/
108
106
 
109
- async getCertificationByID(certID: string, tenantID: string) {
107
+ async getCertificationByID(certID: string, tenantID: string): Promise<CachedCertification | null> {
110
108
  const tenant = await this.getTenantByID(tenantID)
111
- if (!tenant || !Array.isArray((tenant as any).certifications)) return null
112
- return (tenant as any).certifications.find((c: any) => c.id === certID) || null
109
+ if (!tenant?.certifications) return null
110
+ return tenant.certifications.find(c => c.id === certID) || null
113
111
  }
114
112
 
115
- async getCourseByID(courseID: string, tenantID: string) {
113
+ async getCourseByID(courseID: string, tenantID: string): Promise<CachedCourse | null> {
116
114
  const tenant = await this.getTenantByID(tenantID)
117
- if (!tenant || !Array.isArray((tenant as any).certifications)) return null
118
- for (const cert of (tenant as any).certifications) {
115
+ if (!tenant?.certifications) return null
116
+ for (const cert of tenant.certifications) {
119
117
  for (const req of cert.requirements || []) {
120
118
  if (Array.isArray(req)) {
121
- const found = req.find((r: any) => r.id === courseID)
119
+ const found = req.find(r => r.id === courseID)
122
120
  if (found) return found
123
121
  } else if (req.id === courseID) return req
124
122
  }
@@ -126,25 +124,29 @@ export class CacheClient {
126
124
  return null
127
125
  }
128
126
 
129
- async getCourseInCertificationByID(certificationID: string, courseID: string, tenantID: string) {
127
+ async getCourseInCertificationByID(
128
+ certificationID: string,
129
+ courseID: string,
130
+ tenantID: string
131
+ ): Promise<CachedCourse | null> {
130
132
  const tenant = await this.getTenantByID(tenantID)
131
- if (!tenant || !Array.isArray((tenant as any).certifications)) return null
132
- const cert = (tenant as any).certifications.find((c: any) => c.id === certificationID)
133
+ if (!tenant?.certifications) return null
134
+ const cert = tenant.certifications.find(c => c.id === certificationID)
133
135
  if (!cert) return null
134
136
  for (const req of cert.requirements || []) {
135
137
  if (Array.isArray(req)) {
136
- const found = req.find((r: any) => r.id === courseID)
138
+ const found = req.find(r => r.id === courseID)
137
139
  if (found) return found
138
140
  } else if (req.id === courseID) return req
139
141
  }
140
142
  return null
141
143
  }
142
144
 
143
- async getAllCoursesByTenantID(tenantID: string) {
145
+ async getAllCoursesByTenantID(tenantID: string): Promise<CachedCourse[] | null> {
144
146
  const tenant = await this.getTenantByID(tenantID)
145
- if (!tenant || !Array.isArray((tenant as any).certifications)) return null
146
- const courses: any[] = []
147
- for (const cert of (tenant as any).certifications) {
147
+ if (!tenant?.certifications) return null
148
+ const courses: CachedCourse[] = []
149
+ for (const cert of tenant.certifications) {
148
150
  for (const req of cert.requirements || []) {
149
151
  if (Array.isArray(req)) {
150
152
  for (const sub of req) courses.push(sub)
@@ -154,11 +156,11 @@ export class CacheClient {
154
156
  return courses
155
157
  }
156
158
 
157
- async getAllCoursesByCertificationID(certID: string, tenantID: string) {
159
+ async getAllCoursesByCertificationID(certID: string, tenantID: string): Promise<CachedCourse[] | null> {
158
160
  const tenant = await this.getTenantByID(tenantID)
159
- if (!tenant || !Array.isArray((tenant as any).certifications)) return null
160
- const courses: any[] = []
161
- for (const cert of (tenant as any).certifications) {
161
+ if (!tenant?.certifications) return null
162
+ const courses: CachedCourse[] = []
163
+ for (const cert of tenant.certifications) {
162
164
  if (cert.id !== certID) continue
163
165
  for (const req of cert.requirements || []) {
164
166
  if (Array.isArray(req)) {
@@ -169,18 +171,18 @@ export class CacheClient {
169
171
  return courses
170
172
  }
171
173
 
172
- async getAllCourses() {
174
+ async getAllCourses(): Promise<CachedCourse[]> {
173
175
  return this.getAllCoursesByCustomerID(null)
174
176
  }
175
177
 
176
- async getAllCoursesByCustomerID(customerID: string | null) {
178
+ async getAllCoursesByCustomerID(customerID: string | null): Promise<CachedCourse[]> {
177
179
  const allTenants = await this.getAllTenants()
178
180
  if (!allTenants) return []
179
- const filtered = allTenants.filter(t => !customerID || (t as any).customerID === customerID)
180
- const courses: any[] = []
181
+ const filtered = allTenants.filter(t => !customerID || t.customerID === customerID)
182
+ const courses: CachedCourse[] = []
181
183
  for (const tenant of filtered) {
182
- if (!Array.isArray((tenant as any).certifications)) continue
183
- for (const cert of (tenant as any).certifications) {
184
+ if (!tenant.certifications) continue
185
+ for (const cert of tenant.certifications) {
184
186
  for (const req of cert.requirements || []) {
185
187
  if (Array.isArray(req)) {
186
188
  for (const sub of req) {
@@ -199,13 +201,13 @@ export class CacheClient {
199
201
 
200
202
  async getCourseProviderByIDs(courseProviderID: string, customerID: string) {
201
203
  const customer = await this.getCustomerByID(customerID)
202
- if (!customer || !Array.isArray((customer as any).courseProviders)) return null
203
- return (customer as any).courseProviders.find((p: any) => p === courseProviderID) || null
204
+ if (!customer?.allowedOnlineCourseProviders) return null
205
+ return customer.allowedOnlineCourseProviders.find(p => p.id === courseProviderID) || null
204
206
  }
205
207
 
206
208
  /********* Private *********/
207
209
 
208
- private async _getAllRemoteCustomers(): Promise<CustomerResponse[] | null> {
210
+ private async _getAllRemoteCustomers(): Promise<CachedCustomer[] | null> {
209
211
  await this._initCacheClient()
210
212
  if (!this._remoteCache) return null
211
213
  const allKeys = await this._remoteCache.keys(`${CacheConstants.CustomerPrefix}*`)
@@ -214,7 +216,7 @@ export class CacheClient {
214
216
  return Array.isArray(raw) ? raw.map(r => JSON.parse(r)) : null
215
217
  }
216
218
 
217
- private async _getAllRemoteTenants(): Promise<TenantResponse[] | null> {
219
+ private async _getAllRemoteTenants(): Promise<CachedTenant[] | null> {
218
220
  await this._initCacheClient()
219
221
  if (!this._remoteCache) return null
220
222
  const allKeys = await this._remoteCache.keys(`${CacheConstants.TenantPrefix}*`)