@hahnpro/hpc-api 2026.7.2 → 2026.7.3
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/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/src/lib/interfaces/event.interface.d.ts +1 -1
- package/src/lib/interfaces/task.interface.d.ts +1 -1
- package/src/lib/interfaces/type-guards.d.ts +16 -6
- package/src/lib/interfaces/type-guards.js +108 -38
- package/src/lib/interfaces/user-settings.interface.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @hahnpro/hpc-api
|
|
2
2
|
|
|
3
|
+
# 2026.7.3
|
|
4
|
+
|
|
5
|
+
- Added partial-object validation support to the `isAsset`, `isContent`, `isEvent`, `isLogbookEntry`, and `isTask` type guards
|
|
6
|
+
- Expanded `isAsset` to validate populated asset types as well as all supported asset fields
|
|
7
|
+
- Added stricter enum, resource-reference, and attachment-handling validation to the content analysis, event, and user-message type guards
|
|
8
|
+
- Changed `Event.level (string)` to `EventLevel`
|
|
9
|
+
- Updated `Task.expiryDate` and its type guard to accept strings as well as `Date` values
|
|
10
|
+
|
|
3
11
|
# 2026.7.2
|
|
4
12
|
|
|
5
13
|
- Added dedicated logbook API service, logbook interfaces, and mock support
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type UserMessage } from './ai.interface';
|
|
2
2
|
import type { Asset } from './asset.interface';
|
|
3
3
|
import type { Author } from './author.interface';
|
|
4
|
-
import type
|
|
4
|
+
import { type Content, type ContentAnalysis } from './content.interface';
|
|
5
5
|
import { type Event } from './event.interface';
|
|
6
6
|
import { type LogbookEntry } from './logbook.interface';
|
|
7
7
|
import { type Owner } from './owner.interface';
|
|
@@ -11,10 +11,20 @@ export declare function isAuthor(value: unknown): value is Author;
|
|
|
11
11
|
export declare function isOwner(value: unknown): value is Owner;
|
|
12
12
|
export declare function isStorage(value: unknown): value is Storage;
|
|
13
13
|
export declare function isContentAnalysis(value: unknown): value is ContentAnalysis;
|
|
14
|
-
export declare function isAsset(value: unknown): value is Asset;
|
|
15
|
-
export declare function
|
|
16
|
-
export declare function
|
|
14
|
+
export declare function isAsset(value: unknown, isPartial?: false): value is Asset;
|
|
15
|
+
export declare function isAsset(value: unknown, isPartial: true): value is Partial<Asset>;
|
|
16
|
+
export declare function isAsset(value: unknown, isPartial: boolean): value is Asset | Partial<Asset>;
|
|
17
|
+
export declare function isContent(value: unknown, isPartial?: false): value is Content;
|
|
18
|
+
export declare function isContent(value: unknown, isPartial: true): value is Partial<Content>;
|
|
19
|
+
export declare function isContent(value: unknown, isPartial: boolean): value is Content | Partial<Content>;
|
|
20
|
+
export declare function isEvent(value: unknown, isPartial?: false): value is Event;
|
|
21
|
+
export declare function isEvent(value: unknown, isPartial: true): value is Partial<Event>;
|
|
22
|
+
export declare function isEvent(value: unknown, isPartial: boolean): value is Event | Partial<Event>;
|
|
17
23
|
export declare function isAssignee(value: unknown): value is Assignee;
|
|
18
|
-
export declare function isLogbookEntry(value: unknown): value is LogbookEntry;
|
|
19
|
-
export declare function
|
|
24
|
+
export declare function isLogbookEntry(value: unknown, isPartial?: false): value is LogbookEntry;
|
|
25
|
+
export declare function isLogbookEntry(value: unknown, isPartial: true): value is Partial<LogbookEntry>;
|
|
26
|
+
export declare function isLogbookEntry(value: unknown, isPartial: boolean): value is LogbookEntry | Partial<LogbookEntry>;
|
|
27
|
+
export declare function isTask(value: unknown, isPartial?: false): value is Task;
|
|
28
|
+
export declare function isTask(value: unknown, isPartial: true): value is Partial<Task>;
|
|
29
|
+
export declare function isTask(value: unknown, isPartial: boolean): value is Task | Partial<Task>;
|
|
20
30
|
export declare function isUserMessage(value: unknown): value is UserMessage;
|
|
@@ -12,9 +12,11 @@ exports.isLogbookEntry = isLogbookEntry;
|
|
|
12
12
|
exports.isTask = isTask;
|
|
13
13
|
exports.isUserMessage = isUserMessage;
|
|
14
14
|
const ai_interface_1 = require("./ai.interface");
|
|
15
|
+
const content_interface_1 = require("./content.interface");
|
|
15
16
|
const event_interface_1 = require("./event.interface");
|
|
16
17
|
const logbook_interface_1 = require("./logbook.interface");
|
|
17
18
|
const owner_interface_1 = require("./owner.interface");
|
|
19
|
+
const resource_interface_1 = require("./resource.interface");
|
|
18
20
|
const task_interface_1 = require("./task.interface");
|
|
19
21
|
function isRecord(value) {
|
|
20
22
|
return typeof value === 'object' && value !== null;
|
|
@@ -32,10 +34,14 @@ const isArrayOf = (value, predicate) => Array.isArray(value) && value.every(pred
|
|
|
32
34
|
const isOptionalArrayOf = (value, predicate) => value === undefined || isArrayOf(value, predicate);
|
|
33
35
|
const isStringArray = (value) => isArrayOf(value, isString);
|
|
34
36
|
const isOptionalStringArray = (value) => isOptionalArrayOf(value, isString);
|
|
37
|
+
const isOptionalUnknownArray = (value) => value === undefined || Array.isArray(value);
|
|
38
|
+
const hasOwn = (value, property) => Object.prototype.hasOwnProperty.call(value, property);
|
|
35
39
|
const isMessageAttachment = (value) => isRecord(value) && isOptionalString(value.id) && isString(value.filename) && isString(value.text);
|
|
40
|
+
const isResourceReference = (value) => isRecord(value) && isString(value.id) && isEnumValue(resource_interface_1.ResourceType, value.resourceType) && isOptionalBoolean(value.dependent);
|
|
36
41
|
const isOneOf = (value, allowed) => allowed.includes(value);
|
|
37
42
|
const isEnumValue = (target, value) => Object.values(target).includes(value);
|
|
38
43
|
const hasPermissions = (value) => isStringArray(value.readPermissions) && isStringArray(value.readWritePermissions);
|
|
44
|
+
const hasOptionalPermissions = (value) => isOptionalStringArray(value.readPermissions) && isOptionalStringArray(value.readWritePermissions);
|
|
39
45
|
const hasResourceMeta = (value, options) => {
|
|
40
46
|
const { owner, author, date } = options;
|
|
41
47
|
if (owner && value.owner !== undefined && !owner(value.owner)) {
|
|
@@ -89,61 +95,114 @@ function isContentAnalysis(value) {
|
|
|
89
95
|
}
|
|
90
96
|
return (isString(value.id) &&
|
|
91
97
|
isString(value.contentId) &&
|
|
92
|
-
|
|
98
|
+
isEnumValue(content_interface_1.ContentAnalysisStatus, value.status) &&
|
|
93
99
|
isOptionalString(value.error) &&
|
|
94
100
|
isOptionalString(value.text) &&
|
|
95
101
|
isOptionalArrayOf(value.pages, (page) => isRecord(page) && isNumber(page.pageNumber) && isOptionalString(page.text)));
|
|
96
102
|
}
|
|
97
|
-
function
|
|
103
|
+
function isTemplate(value) {
|
|
104
|
+
return isRecord(value) && isString(value.id) && isString(value.name) && isRecord(value.template);
|
|
105
|
+
}
|
|
106
|
+
function isAssetType(value) {
|
|
98
107
|
if (!isRecord(value)) {
|
|
99
108
|
return false;
|
|
100
109
|
}
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
const hasValidAllowedParents = value.allowedParents === undefined || isStringArray(value.allowedParents) || isArrayOf(value.allowedParents, isAssetType);
|
|
111
|
+
const hasValidSupertype = value.supertype === undefined || isString(value.supertype) || isAssetType(value.supertype);
|
|
112
|
+
const hasValidTabPermissions = value.tabPermissions === undefined || (isRecord(value.tabPermissions) && Object.values(value.tabPermissions).every(isStringArray));
|
|
113
|
+
const hasValidTemplates = value.templates === undefined || isStringArray(value.templates) || isArrayOf(value.templates, isTemplate);
|
|
114
|
+
return (isOptionalString(value.id) &&
|
|
103
115
|
isString(value.name) &&
|
|
104
|
-
|
|
116
|
+
isOptionalStringArray(value.tags) &&
|
|
117
|
+
isOptionalString(value.translationId) &&
|
|
118
|
+
hasValidAllowedParents &&
|
|
119
|
+
isOptionalString(value.allowedParent$name) &&
|
|
105
120
|
hasPermissions(value) &&
|
|
106
|
-
|
|
121
|
+
hasValidSupertype &&
|
|
122
|
+
isOptionalString(value.supertype$name) &&
|
|
123
|
+
hasOwn(value, 'typeSchema') &&
|
|
124
|
+
hasOwn(value, 'uiSchema') &&
|
|
125
|
+
isOptionalString(value.author) &&
|
|
126
|
+
isOptionalNumber(value.revision) &&
|
|
127
|
+
isOptionalBoolean(value.isSystemAssetType) &&
|
|
128
|
+
isOptionalString(value.startTab) &&
|
|
129
|
+
hasValidTabPermissions &&
|
|
130
|
+
isOptionalNumber(value.templateVersion) &&
|
|
131
|
+
hasValidTemplates &&
|
|
132
|
+
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
|
|
133
|
+
}
|
|
134
|
+
function isAsset(value, isPartial = false) {
|
|
135
|
+
if (!isRecord(value)) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
let requiredFieldsValid = false;
|
|
139
|
+
if (!isPartial) {
|
|
140
|
+
requiredFieldsValid =
|
|
141
|
+
isOptionalString(value.id) && isString(value.name) && hasPermissions(value) && (isString(value.type) || isAssetType(value.type));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
requiredFieldsValid =
|
|
145
|
+
isOptionalString(value.id) &&
|
|
146
|
+
isOptionalString(value.name) &&
|
|
147
|
+
hasOptionalPermissions(value) &&
|
|
148
|
+
isOptional(value.type, (type) => isString(type) || isAssetType(type));
|
|
149
|
+
}
|
|
150
|
+
return (requiredFieldsValid &&
|
|
151
|
+
isOptionalString(value.externalKey) &&
|
|
152
|
+
isOptionalString(value.translationId) &&
|
|
107
153
|
isOptionalString(value.type$name) &&
|
|
108
154
|
isOptionalStringArray(value.tags) &&
|
|
109
155
|
isOptionalString(value.parent) &&
|
|
110
156
|
isOptionalString(value.parent$name) &&
|
|
157
|
+
isOptionalStringArray(value.ancestors) &&
|
|
158
|
+
isOptionalUnknownArray(value.relations) &&
|
|
159
|
+
isOptionalString(value.image) &&
|
|
111
160
|
isOptionalStringArray(value.attachments) &&
|
|
112
161
|
isOptionalStringArray(value.notificationEndpoints) &&
|
|
113
162
|
isOptionalStringArray(value.aliases) &&
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
hasResourceMeta(value, { owner: isOwner, author: isAuthor }));
|
|
163
|
+
isOptionalString(value.author) &&
|
|
164
|
+
isOptionalNumber(value.revision) &&
|
|
165
|
+
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
|
|
118
166
|
}
|
|
119
|
-
function isContent(value) {
|
|
167
|
+
function isContent(value, isPartial = false) {
|
|
120
168
|
if (!isRecord(value)) {
|
|
121
169
|
return false;
|
|
122
170
|
}
|
|
123
171
|
const hasValidAnalysis = value.analysis === undefined || isString(value.analysis) || isContentAnalysis(value.analysis);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
172
|
+
let requiredFieldsValid = false;
|
|
173
|
+
if (!isPartial) {
|
|
174
|
+
requiredFieldsValid =
|
|
175
|
+
isString(value.fileId) && isString(value.filename) && isString(value.mimetype) && isNumber(value.size) && hasPermissions(value);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
requiredFieldsValid =
|
|
179
|
+
isOptionalString(value.fileId) &&
|
|
180
|
+
isOptionalString(value.filename) &&
|
|
181
|
+
isOptionalString(value.mimetype) &&
|
|
182
|
+
isOptionalNumber(value.size) &&
|
|
183
|
+
hasOptionalPermissions(value);
|
|
184
|
+
}
|
|
185
|
+
return (requiredFieldsValid &&
|
|
186
|
+
isOptionalString(value.id) &&
|
|
127
187
|
isOptionalString(value.description) &&
|
|
128
|
-
isString(value.mimetype) &&
|
|
129
|
-
isNumber(value.size) &&
|
|
130
|
-
hasPermissions(value) &&
|
|
131
188
|
isOptionalStringArray(value.tags) &&
|
|
132
189
|
isOptionalStringArray(value.assets) &&
|
|
133
190
|
isOptionalArrayOf(value.files, isStorage) &&
|
|
134
|
-
|
|
135
|
-
|
|
191
|
+
hasValidAnalysis &&
|
|
192
|
+
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
|
|
136
193
|
}
|
|
137
|
-
function isEvent(value) {
|
|
194
|
+
function isEvent(value, isPartial = false) {
|
|
138
195
|
if (!isRecord(value)) {
|
|
139
196
|
return false;
|
|
140
197
|
}
|
|
141
|
-
|
|
142
|
-
|
|
198
|
+
const requiredFieldsValid = isPartial
|
|
199
|
+
? isOptionalString(value.name) && hasOptionalPermissions(value) && isOptional(value.level, (level) => isEnumValue(event_interface_1.EventLevel, level))
|
|
200
|
+
: isString(value.name) && hasPermissions(value) && isEnumValue(event_interface_1.EventLevel, value.level);
|
|
201
|
+
return (requiredFieldsValid &&
|
|
202
|
+
isOptionalString(value.id) &&
|
|
143
203
|
isOptionalString(value.description) &&
|
|
144
204
|
isOptionalStringArray(value.tags) &&
|
|
145
|
-
|
|
146
|
-
isEnumValue(event_interface_1.EventLevel, value.level) &&
|
|
205
|
+
isOptionalArrayOf(value.refs, isResourceReference) &&
|
|
147
206
|
isOptional(value.data, isRecord) &&
|
|
148
207
|
isOptionalString(value.assetRef) &&
|
|
149
208
|
isOptionalString(value.assetRef$name) &&
|
|
@@ -152,20 +211,27 @@ function isEvent(value) {
|
|
|
152
211
|
isOptionalString(value.eventRef) &&
|
|
153
212
|
isOptionalString(value.cause) &&
|
|
154
213
|
isOptionalString(value.group) &&
|
|
155
|
-
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: isString }));
|
|
214
|
+
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: (candidate) => isString(candidate) || isDate(candidate) }));
|
|
156
215
|
}
|
|
157
216
|
function isAssignee(value) {
|
|
158
217
|
return isRecord(value) && isString(value.id) && isEnumValue(task_interface_1.AssigneeType, value.type);
|
|
159
218
|
}
|
|
160
|
-
function isLogbookEntry(value) {
|
|
219
|
+
function isLogbookEntry(value, isPartial = false) {
|
|
161
220
|
if (!isRecord(value)) {
|
|
162
221
|
return false;
|
|
163
222
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
223
|
+
const requiredFieldsValid = isPartial
|
|
224
|
+
? isOptionalString(value.taskId) &&
|
|
225
|
+
isOptionalString(value.date) &&
|
|
226
|
+
isOptionalNumber(value.duration) &&
|
|
227
|
+
isOptional(value.source, (source) => isEnumValue(logbook_interface_1.LogbookEntrySource, source)) &&
|
|
228
|
+
isOptionalString(value.id)
|
|
229
|
+
: isString(value.taskId) &&
|
|
230
|
+
isString(value.date) &&
|
|
231
|
+
isNumber(value.duration) &&
|
|
232
|
+
isEnumValue(logbook_interface_1.LogbookEntrySource, value.source) &&
|
|
233
|
+
isString(value.id);
|
|
234
|
+
return (requiredFieldsValid &&
|
|
169
235
|
isOptionalString(value.comment) &&
|
|
170
236
|
isOptionalString(value.createdAt) &&
|
|
171
237
|
isOptionalString(value.updatedAt) &&
|
|
@@ -173,34 +239,37 @@ function isLogbookEntry(value) {
|
|
|
173
239
|
isOptional(value.data, isRecord) &&
|
|
174
240
|
isOptional(value.createdBy, isAuthor));
|
|
175
241
|
}
|
|
176
|
-
function isTask(value) {
|
|
242
|
+
function isTask(value, isPartial = false) {
|
|
177
243
|
if (!isRecord(value)) {
|
|
178
244
|
return false;
|
|
179
245
|
}
|
|
180
246
|
const hasValidStatusHistory = value.statusHistoryLog === undefined ||
|
|
181
247
|
(Array.isArray(value.statusHistoryLog) && value.statusHistoryLog.every((status) => isEnumValue(task_interface_1.TaskStatus, status)));
|
|
182
|
-
|
|
248
|
+
const requiredFieldsValid = isPartial
|
|
249
|
+
? isOptionalString(value.name) &&
|
|
250
|
+
isOptional(value.priority, (priority) => isEnumValue(task_interface_1.Priority, priority)) &&
|
|
251
|
+
hasOptionalPermissions(value) &&
|
|
252
|
+
isOptionalArrayOf(value.assignedTo, isAssignee)
|
|
253
|
+
: isString(value.name) && isEnumValue(task_interface_1.Priority, value.priority) && hasPermissions(value) && isArrayOf(value.assignedTo, isAssignee);
|
|
254
|
+
return (requiredFieldsValid &&
|
|
255
|
+
isOptionalString(value.id) &&
|
|
183
256
|
isOptionalDateOrString(value.createdAt) &&
|
|
184
257
|
isOptionalDateOrString(value.updatedAt) &&
|
|
185
258
|
isOptionalDateOrString(value.deletedAt) &&
|
|
186
259
|
isOptionalNumber(value.revision) &&
|
|
187
260
|
hasResourceMeta(value, { owner: isOwner, author: isAuthor, date: (candidate) => isString(candidate) || candidate instanceof Date }) &&
|
|
188
|
-
isString(value.name) &&
|
|
189
261
|
isOptionalString(value.description) &&
|
|
190
|
-
isEnumValue(task_interface_1.Priority, value.priority) &&
|
|
191
262
|
isOptionalStringArray(value.tags) &&
|
|
192
|
-
hasPermissions(value) &&
|
|
193
263
|
isOptionalString(value.assetRef) &&
|
|
194
264
|
isOptionalString(value.assetRef$name) &&
|
|
195
265
|
isOptionalString(value.eventRef) &&
|
|
196
266
|
isOptionalString(value.eventRef$name) &&
|
|
197
267
|
isOptionalNumber(value.gitHubNr) &&
|
|
198
268
|
isOptionalString(value.schedule) &&
|
|
199
|
-
(value.expiryDate
|
|
269
|
+
isOptionalDateOrString(value.expiryDate) &&
|
|
200
270
|
isOptionalString(value.parent) &&
|
|
201
271
|
isOptionalString(value.parent$name) &&
|
|
202
272
|
isOptionalStringArray(value.subTasks) &&
|
|
203
|
-
isArrayOf(value.assignedTo, isAssignee) &&
|
|
204
273
|
isOptionalString(value.acceptedBy) &&
|
|
205
274
|
(value.status === undefined || isEnumValue(task_interface_1.TaskStatus, value.status)) &&
|
|
206
275
|
hasValidStatusHistory &&
|
|
@@ -220,5 +289,6 @@ function isUserMessage(value) {
|
|
|
220
289
|
isOptionalString(value.content) &&
|
|
221
290
|
isOptionalBoolean(value.hidden) &&
|
|
222
291
|
isOptionalBoolean(value.useWebSearch) &&
|
|
292
|
+
isOptional(value.attachmentHandling, (mode) => isEnumValue(ai_interface_1.AttachmentHandlingMode, mode)) &&
|
|
223
293
|
isOptionalArrayOf(value.attachments, isMessageAttachment));
|
|
224
294
|
}
|