@semiont/core 0.2.2-build.11 → 0.2.2-build.12
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/index.d.ts +1367 -27
- package/dist/index.js +1455 -78
- package/dist/index.js.map +1 -1
- package/package.json +18 -8
- package/dist/annotation-history-utils.d.ts +0 -42
- package/dist/annotation-history-utils.d.ts.map +0 -1
- package/dist/annotation-history-utils.js +0 -258
- package/dist/annotation-history-utils.js.map +0 -1
- package/dist/annotation-types.d.ts +0 -15
- package/dist/annotation-types.d.ts.map +0 -1
- package/dist/annotation-types.js +0 -6
- package/dist/annotation-types.js.map +0 -1
- package/dist/annotation-utils.d.ts +0 -18
- package/dist/annotation-utils.d.ts.map +0 -1
- package/dist/annotation-utils.js +0 -70
- package/dist/annotation-utils.js.map +0 -1
- package/dist/auth-types.d.ts +0 -8
- package/dist/auth-types.d.ts.map +0 -1
- package/dist/auth-types.js +0 -6
- package/dist/auth-types.js.map +0 -1
- package/dist/config/config-validator.d.ts +0 -25
- package/dist/config/config-validator.d.ts.map +0 -1
- package/dist/config/config-validator.js +0 -112
- package/dist/config/config-validator.js.map +0 -1
- package/dist/config/config.schema.json +0 -678
- package/dist/config/config.types.d.ts +0 -574
- package/dist/config/config.types.d.ts.map +0 -1
- package/dist/config/config.types.js +0 -4
- package/dist/config/config.types.js.map +0 -1
- package/dist/config/configuration-error.d.ts +0 -17
- package/dist/config/configuration-error.d.ts.map +0 -1
- package/dist/config/configuration-error.js +0 -36
- package/dist/config/configuration-error.js.map +0 -1
- package/dist/config/environment-loader.d.ts +0 -98
- package/dist/config/environment-loader.d.ts.map +0 -1
- package/dist/config/environment-loader.js +0 -229
- package/dist/config/environment-loader.js.map +0 -1
- package/dist/config/environment-validator.d.ts +0 -22
- package/dist/config/environment-validator.d.ts.map +0 -1
- package/dist/config/environment-validator.js +0 -50
- package/dist/config/environment-validator.js.map +0 -1
- package/dist/config/platform-types.d.ts +0 -26
- package/dist/config/platform-types.d.ts.map +0 -1
- package/dist/config/platform-types.js +0 -28
- package/dist/config/platform-types.js.map +0 -1
- package/dist/config/project-discovery.d.ts +0 -35
- package/dist/config/project-discovery.d.ts.map +0 -1
- package/dist/config/project-discovery.js +0 -99
- package/dist/config/project-discovery.js.map +0 -1
- package/dist/creation-methods.d.ts +0 -19
- package/dist/creation-methods.d.ts.map +0 -1
- package/dist/creation-methods.js +0 -18
- package/dist/creation-methods.js.map +0 -1
- package/dist/crypto.d.ts +0 -32
- package/dist/crypto.d.ts.map +0 -1
- package/dist/crypto.js +0 -52
- package/dist/crypto.js.map +0 -1
- package/dist/did-utils.d.ts +0 -51
- package/dist/did-utils.d.ts.map +0 -1
- package/dist/did-utils.js +0 -62
- package/dist/did-utils.js.map +0 -1
- package/dist/errors.d.ts +0 -51
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -89
- package/dist/errors.js.map +0 -1
- package/dist/events.d.ts +0 -223
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -45
- package/dist/events.js.map +0 -1
- package/dist/graph.d.ts +0 -31
- package/dist/graph.d.ts.map +0 -1
- package/dist/graph.js +0 -6
- package/dist/graph.js.map +0 -1
- package/dist/http-client.d.ts +0 -32
- package/dist/http-client.d.ts.map +0 -1
- package/dist/http-client.js +0 -56
- package/dist/http-client.js.map +0 -1
- package/dist/identifiers.d.ts +0 -24
- package/dist/identifiers.d.ts.map +0 -1
- package/dist/identifiers.js +0 -40
- package/dist/identifiers.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/resource-types.d.ts +0 -15
- package/dist/resource-types.d.ts.map +0 -1
- package/dist/resource-types.js +0 -6
- package/dist/resource-types.js.map +0 -1
- package/dist/type-guards.d.ts +0 -44
- package/dist/type-guards.d.ts.map +0 -1
- package/dist/type-guards.js +0 -76
- package/dist/type-guards.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,80 +1,1457 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
1
|
+
import { createHash, randomBytes } from 'crypto';
|
|
2
|
+
import { getAnnotationExactText, getEntityTypes } from '@semiont/api-client';
|
|
3
|
+
import * as fs2 from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import Ajv from 'ajv';
|
|
6
|
+
import addFormats from 'ajv-formats';
|
|
7
|
+
|
|
8
|
+
// src/creation-methods.ts
|
|
9
|
+
var CREATION_METHODS = {
|
|
10
|
+
API: "api",
|
|
11
|
+
UPLOAD: "upload",
|
|
12
|
+
UI: "ui",
|
|
13
|
+
REFERENCE: "reference",
|
|
14
|
+
CLONE: "clone",
|
|
15
|
+
GENERATED: "generated"
|
|
21
16
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
17
|
+
|
|
18
|
+
// src/identifiers.ts
|
|
19
|
+
function isResourceId(value) {
|
|
20
|
+
return !value.includes("/");
|
|
21
|
+
}
|
|
22
|
+
function isAnnotationId(value) {
|
|
23
|
+
return !value.includes("/");
|
|
24
|
+
}
|
|
25
|
+
function resourceId(id) {
|
|
26
|
+
if (id.includes("/")) {
|
|
27
|
+
throw new TypeError(`Expected ResourceId, got URI: ${id}`);
|
|
28
|
+
}
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
function annotationId(id) {
|
|
32
|
+
if (id.includes("/")) {
|
|
33
|
+
throw new TypeError(`Expected AnnotationId, got URI: ${id}`);
|
|
34
|
+
}
|
|
35
|
+
return id;
|
|
36
|
+
}
|
|
37
|
+
function userId(id) {
|
|
38
|
+
return id;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/events.ts
|
|
42
|
+
function isResourceEvent(event) {
|
|
43
|
+
return event && typeof event.id === "string" && typeof event.timestamp === "string" && (event.resourceId === void 0 || typeof event.resourceId === "string") && // resourceId now optional
|
|
44
|
+
typeof event.type === "string" && event.type.includes(".");
|
|
45
|
+
}
|
|
46
|
+
function isSystemEvent(event) {
|
|
47
|
+
return event.type === "entitytype.added";
|
|
48
|
+
}
|
|
49
|
+
function isResourceScopedEvent(event) {
|
|
50
|
+
return !isSystemEvent(event);
|
|
51
|
+
}
|
|
52
|
+
function getEventType(event) {
|
|
53
|
+
return event.type;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/annotation-utils.ts
|
|
57
|
+
function bodyItemsMatch(item1, item2) {
|
|
58
|
+
if (item1.type !== item2.type) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (item1.purpose !== item2.purpose) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (item1.type === "TextualBody" && item2.type === "TextualBody") {
|
|
65
|
+
return item1.value === item2.value;
|
|
66
|
+
}
|
|
67
|
+
if (item1.type === "SpecificResource" && item2.type === "SpecificResource") {
|
|
68
|
+
return item1.source === item2.source;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
function findBodyItem(body, targetItem) {
|
|
73
|
+
if (!Array.isArray(body)) {
|
|
74
|
+
return -1;
|
|
75
|
+
}
|
|
76
|
+
for (let i = 0; i < body.length; i++) {
|
|
77
|
+
const item = body[i];
|
|
78
|
+
if (typeof item === "object" && item !== null && "type" in item && "purpose" in item) {
|
|
79
|
+
const itemType = item.type;
|
|
80
|
+
const itemPurpose = item.purpose;
|
|
81
|
+
if (itemType !== targetItem.type || itemPurpose !== targetItem.purpose) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (targetItem.type === "TextualBody" && "value" in item) {
|
|
85
|
+
const itemValue = item.value;
|
|
86
|
+
if (itemValue === targetItem.value) {
|
|
87
|
+
return i;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (targetItem.type === "SpecificResource" && "source" in item) {
|
|
91
|
+
const itemSource = item.source;
|
|
92
|
+
if (itemSource === targetItem.source) {
|
|
93
|
+
return i;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return -1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/type-guards.ts
|
|
102
|
+
function isString(value) {
|
|
103
|
+
return typeof value === "string";
|
|
104
|
+
}
|
|
105
|
+
function isNumber(value) {
|
|
106
|
+
return typeof value === "number" && !isNaN(value);
|
|
107
|
+
}
|
|
108
|
+
function isObject(value) {
|
|
109
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
110
|
+
}
|
|
111
|
+
function isArray(value) {
|
|
112
|
+
return Array.isArray(value);
|
|
113
|
+
}
|
|
114
|
+
function isBoolean(value) {
|
|
115
|
+
return typeof value === "boolean";
|
|
116
|
+
}
|
|
117
|
+
function isFunction(value) {
|
|
118
|
+
return typeof value === "function";
|
|
119
|
+
}
|
|
120
|
+
function isNull(value) {
|
|
121
|
+
return value === null;
|
|
122
|
+
}
|
|
123
|
+
function isUndefined(value) {
|
|
124
|
+
return value === void 0;
|
|
125
|
+
}
|
|
126
|
+
function isNullish(value) {
|
|
127
|
+
return value === null || value === void 0;
|
|
128
|
+
}
|
|
129
|
+
function isDefined(value) {
|
|
130
|
+
return value !== null && value !== void 0;
|
|
131
|
+
}
|
|
132
|
+
function calculateChecksum(content) {
|
|
133
|
+
const hash = createHash("sha256");
|
|
134
|
+
hash.update(content);
|
|
135
|
+
return hash.digest("hex");
|
|
136
|
+
}
|
|
137
|
+
function verifyChecksum(content, checksum) {
|
|
138
|
+
return calculateChecksum(content) === checksum;
|
|
139
|
+
}
|
|
140
|
+
function generateId() {
|
|
141
|
+
return randomBytes(6).toString("hex");
|
|
142
|
+
}
|
|
143
|
+
function generateUuid() {
|
|
144
|
+
return randomBytes(16).toString("hex");
|
|
145
|
+
}
|
|
146
|
+
function generateToken(bytes = 32) {
|
|
147
|
+
return randomBytes(bytes).toString("base64url");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/errors.ts
|
|
151
|
+
var SemiontError = class extends Error {
|
|
152
|
+
constructor(message, code, details) {
|
|
153
|
+
super(message);
|
|
154
|
+
this.code = code;
|
|
155
|
+
this.details = details;
|
|
156
|
+
this.name = "SemiontError";
|
|
157
|
+
Error.captureStackTrace(this, this.constructor);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var ValidationError = class extends SemiontError {
|
|
161
|
+
constructor(message, details) {
|
|
162
|
+
super(message, "VALIDATION_ERROR", details);
|
|
163
|
+
this.name = "ValidationError";
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var ScriptError = class extends SemiontError {
|
|
167
|
+
constructor(message, code = "SCRIPT_ERROR", details) {
|
|
168
|
+
super(message, code, details);
|
|
169
|
+
this.name = "ScriptError";
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
var NotFoundError = class extends SemiontError {
|
|
173
|
+
constructor(resource, id) {
|
|
174
|
+
const message = id ? `${resource} with id '${id}' not found` : `${resource} not found`;
|
|
175
|
+
super(message, "NOT_FOUND", { resource, id });
|
|
176
|
+
this.name = "NotFoundError";
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
var UnauthorizedError = class extends SemiontError {
|
|
180
|
+
constructor(message = "Unauthorized", details) {
|
|
181
|
+
super(message, "UNAUTHORIZED", details);
|
|
182
|
+
this.name = "UnauthorizedError";
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
var ConflictError = class extends SemiontError {
|
|
186
|
+
constructor(message, details) {
|
|
187
|
+
super(message, "CONFLICT", details);
|
|
188
|
+
this.name = "ConflictError";
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var APIError = class extends Error {
|
|
192
|
+
constructor(status, data, message) {
|
|
193
|
+
super(message || `API Error: ${status}`);
|
|
194
|
+
this.status = status;
|
|
195
|
+
this.data = data;
|
|
196
|
+
this.name = "APIError";
|
|
197
|
+
Error.captureStackTrace(this, this.constructor);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// src/http-client.ts
|
|
202
|
+
async function fetchAPI(endpoint, options = {}, token, baseUrl = "") {
|
|
203
|
+
const headers = {
|
|
204
|
+
"Content-Type": "application/json",
|
|
205
|
+
...options.headers || {}
|
|
206
|
+
};
|
|
207
|
+
if (token) {
|
|
208
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
209
|
+
}
|
|
210
|
+
const url = baseUrl ? `${baseUrl}${endpoint}` : endpoint;
|
|
211
|
+
const response = await fetch(url, {
|
|
212
|
+
...options,
|
|
213
|
+
headers
|
|
214
|
+
});
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
const errorData = await response.json().catch(() => ({}));
|
|
217
|
+
throw new APIError(response.status, errorData, errorData.message);
|
|
218
|
+
}
|
|
219
|
+
if (response.status === 204 || response.headers.get("content-length") === "0") {
|
|
220
|
+
return {};
|
|
221
|
+
}
|
|
222
|
+
return response.json();
|
|
223
|
+
}
|
|
224
|
+
function createFetchAPI(baseUrl) {
|
|
225
|
+
return function(endpoint, options = {}, token) {
|
|
226
|
+
return fetchAPI(endpoint, options, token, baseUrl);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function formatEventType(type, t) {
|
|
230
|
+
switch (type) {
|
|
231
|
+
case "resource.created":
|
|
232
|
+
return t("resourceCreated");
|
|
233
|
+
case "resource.cloned":
|
|
234
|
+
return t("resourceCloned");
|
|
235
|
+
case "resource.archived":
|
|
236
|
+
return t("resourceArchived");
|
|
237
|
+
case "resource.unarchived":
|
|
238
|
+
return t("resourceUnarchived");
|
|
239
|
+
case "annotation.added":
|
|
240
|
+
return t("annotationAdded");
|
|
241
|
+
case "annotation.removed":
|
|
242
|
+
return t("annotationRemoved");
|
|
243
|
+
case "annotation.body.updated":
|
|
244
|
+
return t("annotationBodyUpdated");
|
|
245
|
+
case "entitytag.added":
|
|
246
|
+
return t("entitytagAdded");
|
|
247
|
+
case "entitytag.removed":
|
|
248
|
+
return t("entitytagRemoved");
|
|
249
|
+
case "entitytype.added":
|
|
250
|
+
return t("entitytypeAdded");
|
|
251
|
+
case "job.started":
|
|
252
|
+
return t("jobStarted");
|
|
253
|
+
case "job.progress":
|
|
254
|
+
return t("jobProgress");
|
|
255
|
+
case "job.completed":
|
|
256
|
+
return t("jobCompleted");
|
|
257
|
+
case "job.failed":
|
|
258
|
+
return t("jobFailed");
|
|
259
|
+
default:
|
|
260
|
+
const _exhaustiveCheck = type;
|
|
261
|
+
return _exhaustiveCheck;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function getMotivationEmoji(motivation) {
|
|
265
|
+
switch (motivation) {
|
|
266
|
+
case "highlighting":
|
|
267
|
+
return "\u{1F7E1}";
|
|
268
|
+
case "linking":
|
|
269
|
+
return "\u{1F535}";
|
|
270
|
+
case "assessing":
|
|
271
|
+
return "\u{1F534}";
|
|
272
|
+
case "bookmarking":
|
|
273
|
+
return "\u{1F516}";
|
|
274
|
+
case "commenting":
|
|
275
|
+
return "\u{1F4AC}";
|
|
276
|
+
case "tagging":
|
|
277
|
+
return "\u{1F3F7}\uFE0F";
|
|
278
|
+
default:
|
|
279
|
+
return "\u{1F4DD}";
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function getEventEmoji(type, event) {
|
|
283
|
+
switch (type) {
|
|
284
|
+
case "resource.created":
|
|
285
|
+
case "resource.cloned":
|
|
286
|
+
case "resource.archived":
|
|
287
|
+
case "resource.unarchived":
|
|
288
|
+
return "\u{1F4C4}";
|
|
289
|
+
case "annotation.added":
|
|
290
|
+
if (event) {
|
|
291
|
+
const payload = event.event.payload;
|
|
292
|
+
return getMotivationEmoji(payload.annotation.motivation);
|
|
293
|
+
}
|
|
294
|
+
return "\u{1F4DD}";
|
|
295
|
+
case "annotation.removed":
|
|
296
|
+
return "\u{1F5D1}\uFE0F";
|
|
297
|
+
case "annotation.body.updated":
|
|
298
|
+
return "\u270F\uFE0F";
|
|
299
|
+
case "entitytag.added":
|
|
300
|
+
case "entitytag.removed":
|
|
301
|
+
return "\u{1F3F7}\uFE0F";
|
|
302
|
+
case "entitytype.added":
|
|
303
|
+
return "\u{1F3F7}\uFE0F";
|
|
304
|
+
// Same emoji as entitytag (global entity type collection)
|
|
305
|
+
case "job.started":
|
|
306
|
+
return "\u25B6\uFE0F";
|
|
307
|
+
case "job.progress":
|
|
308
|
+
return "\u23F3";
|
|
309
|
+
case "job.completed":
|
|
310
|
+
return "\u2705";
|
|
311
|
+
case "job.failed":
|
|
312
|
+
return "\u274C";
|
|
313
|
+
default:
|
|
314
|
+
const _exhaustiveCheck = type;
|
|
315
|
+
return _exhaustiveCheck;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function formatRelativeTime(timestamp, t) {
|
|
319
|
+
const date = new Date(timestamp);
|
|
320
|
+
const now = /* @__PURE__ */ new Date();
|
|
321
|
+
const diffMs = now.getTime() - date.getTime();
|
|
322
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
323
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
324
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
325
|
+
if (diffMins < 1) return t("justNow");
|
|
326
|
+
if (diffMins < 60) return t("minutesAgo", { count: diffMins });
|
|
327
|
+
if (diffHours < 24) return t("hoursAgo", { count: diffHours });
|
|
328
|
+
if (diffDays < 7) return t("daysAgo", { count: diffDays });
|
|
329
|
+
return date.toLocaleDateString();
|
|
330
|
+
}
|
|
331
|
+
function truncateText(text, maxLength = 50) {
|
|
332
|
+
const trimmed = text.trim();
|
|
333
|
+
return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + "..." : trimmed;
|
|
334
|
+
}
|
|
335
|
+
function getEventDisplayContent(event, _references, _highlights, allEvents) {
|
|
336
|
+
const eventData = event.event;
|
|
337
|
+
switch (eventData.type) {
|
|
338
|
+
case "resource.created":
|
|
339
|
+
case "resource.cloned": {
|
|
340
|
+
const payload = eventData.payload;
|
|
341
|
+
return { exact: payload.name, isQuoted: false, isTag: false };
|
|
342
|
+
}
|
|
343
|
+
case "annotation.body.updated": {
|
|
344
|
+
const payload = eventData.payload;
|
|
345
|
+
const addedEvent = allEvents.find(
|
|
346
|
+
(e) => e.event.type === "annotation.added" && e.event.payload.annotation.id === payload.annotationId
|
|
347
|
+
);
|
|
348
|
+
if (addedEvent) {
|
|
349
|
+
const addedPayload = addedEvent.event.payload;
|
|
350
|
+
return { exact: truncateText(getAnnotationExactText(addedPayload.annotation)), isQuoted: true, isTag: false };
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
case "annotation.removed": {
|
|
355
|
+
const payload = eventData.payload;
|
|
356
|
+
const addedEvent = allEvents.find(
|
|
357
|
+
(e) => e.event.type === "annotation.added" && e.event.payload.annotation.id === payload.annotationId
|
|
358
|
+
);
|
|
359
|
+
if (addedEvent) {
|
|
360
|
+
const addedPayload = addedEvent.event.payload;
|
|
361
|
+
return { exact: truncateText(getAnnotationExactText(addedPayload.annotation)), isQuoted: true, isTag: false };
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
case "annotation.added": {
|
|
366
|
+
const payload = eventData.payload;
|
|
367
|
+
return { exact: truncateText(getAnnotationExactText(payload.annotation)), isQuoted: true, isTag: false };
|
|
368
|
+
}
|
|
369
|
+
case "entitytag.added":
|
|
370
|
+
case "entitytag.removed": {
|
|
371
|
+
const payload = eventData.payload;
|
|
372
|
+
return { exact: payload.entityType, isQuoted: false, isTag: true };
|
|
373
|
+
}
|
|
374
|
+
default:
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function getEventEntityTypes(event) {
|
|
379
|
+
const eventData = event.event;
|
|
380
|
+
if (eventData.type === "annotation.added") {
|
|
381
|
+
const payload = eventData.payload;
|
|
382
|
+
return getEntityTypes(payload.annotation);
|
|
383
|
+
}
|
|
384
|
+
return [];
|
|
385
|
+
}
|
|
386
|
+
function formatUserId(userId2) {
|
|
387
|
+
if (userId2.startsWith("did:web:")) {
|
|
388
|
+
const parts = userId2.split(":");
|
|
389
|
+
if (parts.length >= 5) {
|
|
390
|
+
const domain = parts[2];
|
|
391
|
+
const username2 = parts[parts.length - 1];
|
|
392
|
+
return `${username2}@${domain}`;
|
|
393
|
+
}
|
|
394
|
+
const username = parts[parts.length - 1];
|
|
395
|
+
return username || userId2.substring(0, 8);
|
|
396
|
+
}
|
|
397
|
+
return userId2.substring(0, 8);
|
|
398
|
+
}
|
|
399
|
+
function getResourceCreationDetails(event) {
|
|
400
|
+
const eventData = event.event;
|
|
401
|
+
if (eventData.type === "resource.created") {
|
|
402
|
+
const payload = eventData.payload;
|
|
403
|
+
return {
|
|
404
|
+
type: "created",
|
|
405
|
+
userId: formatUserId(eventData.userId),
|
|
406
|
+
method: payload.creationMethod
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if (eventData.type === "resource.cloned") {
|
|
410
|
+
const payload = eventData.payload;
|
|
411
|
+
return {
|
|
412
|
+
type: "cloned",
|
|
413
|
+
userId: formatUserId(eventData.userId),
|
|
414
|
+
method: payload.creationMethod,
|
|
415
|
+
sourceDocId: payload.parentResourceId
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
function getAnnotationIdFromEvent(event) {
|
|
421
|
+
const eventData = event.event;
|
|
422
|
+
switch (eventData.type) {
|
|
423
|
+
case "annotation.added": {
|
|
424
|
+
const payload = eventData.payload;
|
|
425
|
+
return payload.annotation.id;
|
|
426
|
+
}
|
|
427
|
+
case "annotation.removed":
|
|
428
|
+
case "annotation.body.updated": {
|
|
429
|
+
const payload = eventData.payload;
|
|
430
|
+
return payload.annotationId;
|
|
431
|
+
}
|
|
432
|
+
default:
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function isEventRelatedToAnnotation(event, annotationId2) {
|
|
437
|
+
const eventAnnotationId = getAnnotationIdFromEvent(event);
|
|
438
|
+
return eventAnnotationId === annotationId2;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// src/did-utils.ts
|
|
442
|
+
function userToDid(user) {
|
|
443
|
+
return `did:web:${user.domain}:users:${user.id}`;
|
|
444
|
+
}
|
|
445
|
+
function userToAgent(user) {
|
|
446
|
+
return {
|
|
447
|
+
type: "Person",
|
|
448
|
+
id: userToDid(user),
|
|
449
|
+
name: user.name || user.email
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function didToAgent(did) {
|
|
453
|
+
const parts = did.split(":");
|
|
454
|
+
const userId2 = parts[parts.length - 1] || "unknown";
|
|
455
|
+
return {
|
|
456
|
+
type: "Person",
|
|
457
|
+
id: did,
|
|
458
|
+
name: userId2
|
|
459
|
+
// Use user ID as name since we don't have full user data
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// src/config/configuration-error.ts
|
|
464
|
+
var ConfigurationError = class extends Error {
|
|
465
|
+
constructor(message, environment, suggestion, cause) {
|
|
466
|
+
super(message);
|
|
467
|
+
this.environment = environment;
|
|
468
|
+
this.suggestion = suggestion;
|
|
469
|
+
this.name = "ConfigurationError";
|
|
470
|
+
this.cause = cause;
|
|
471
|
+
}
|
|
472
|
+
cause;
|
|
473
|
+
/**
|
|
474
|
+
* Format the error nicely for CLI output
|
|
475
|
+
*/
|
|
476
|
+
toString() {
|
|
477
|
+
let output = `\u274C ${this.message}`;
|
|
478
|
+
if (this.environment) {
|
|
479
|
+
output += `
|
|
480
|
+
Environment: ${this.environment}`;
|
|
481
|
+
}
|
|
482
|
+
if (this.suggestion) {
|
|
483
|
+
output += `
|
|
484
|
+
\u{1F4A1} Suggestion: ${this.suggestion}`;
|
|
485
|
+
}
|
|
486
|
+
return output;
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
function findProjectRoot() {
|
|
490
|
+
const root = process.env.SEMIONT_ROOT;
|
|
491
|
+
if (!root) {
|
|
492
|
+
throw new ConfigurationError(
|
|
493
|
+
"SEMIONT_ROOT environment variable is not set",
|
|
494
|
+
void 0,
|
|
495
|
+
"Set SEMIONT_ROOT to your project directory, or use the semiont CLI which sets it automatically"
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
if (!fs2.existsSync(root)) {
|
|
499
|
+
throw new ConfigurationError(
|
|
500
|
+
`SEMIONT_ROOT points to non-existent directory: ${root}`,
|
|
501
|
+
void 0,
|
|
502
|
+
"Check that SEMIONT_ROOT environment variable is set correctly"
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
if (!isProjectRoot(root)) {
|
|
506
|
+
throw new ConfigurationError(
|
|
507
|
+
`SEMIONT_ROOT does not point to a valid Semiont project: ${root}`,
|
|
508
|
+
void 0,
|
|
509
|
+
"Ensure SEMIONT_ROOT points to a directory containing semiont.json or environments/"
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
return root;
|
|
513
|
+
}
|
|
514
|
+
function isProjectRoot(projectPath) {
|
|
515
|
+
return fs2.existsSync(path.join(projectPath, "semiont.json")) || fs2.existsSync(path.join(projectPath, "environments"));
|
|
516
|
+
}
|
|
517
|
+
function getEnvironmentsPath(projectRoot) {
|
|
518
|
+
const root = projectRoot || findProjectRoot();
|
|
519
|
+
return path.join(root, "environments");
|
|
520
|
+
}
|
|
521
|
+
function getSemiontConfigPath(projectRoot) {
|
|
522
|
+
const root = projectRoot || findProjectRoot();
|
|
523
|
+
return path.join(root, "semiont.json");
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// src/config/config.schema.json
|
|
527
|
+
var config_schema_default = {
|
|
528
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
529
|
+
$id: "https://semiont.org/schemas/config.json",
|
|
530
|
+
definitions: {
|
|
531
|
+
PlatformType: {
|
|
532
|
+
type: "string",
|
|
533
|
+
enum: ["posix", "container", "aws", "external"]
|
|
534
|
+
},
|
|
535
|
+
ServicePlatformConfig: {
|
|
536
|
+
type: "object",
|
|
537
|
+
properties: {
|
|
538
|
+
type: { $ref: "#/definitions/PlatformType" }
|
|
539
|
+
},
|
|
540
|
+
required: ["type"]
|
|
541
|
+
},
|
|
542
|
+
ResourceRequirements: {
|
|
543
|
+
type: "object",
|
|
544
|
+
properties: {
|
|
545
|
+
cpu: { type: "string" },
|
|
546
|
+
memory: { type: "string" },
|
|
547
|
+
gpu: { type: "integer" },
|
|
548
|
+
gpus: { type: "integer" },
|
|
549
|
+
replicas: { type: "integer" },
|
|
550
|
+
ephemeralStorage: { type: "string" },
|
|
551
|
+
memoryReservation: { type: "string" }
|
|
552
|
+
},
|
|
553
|
+
additionalProperties: false
|
|
554
|
+
},
|
|
555
|
+
SecurityRequirements: {
|
|
556
|
+
type: "object",
|
|
557
|
+
properties: {
|
|
558
|
+
readOnlyRootFilesystem: { type: "boolean" },
|
|
559
|
+
runAsNonRoot: { type: "boolean" },
|
|
560
|
+
runAsUser: { type: "integer" },
|
|
561
|
+
runAsGroup: { type: "integer" },
|
|
562
|
+
capabilities: {
|
|
563
|
+
oneOf: [
|
|
564
|
+
{ type: "array", items: { type: "string" } },
|
|
565
|
+
{
|
|
566
|
+
type: "object",
|
|
567
|
+
properties: {
|
|
568
|
+
add: { type: "array", items: { type: "string" } },
|
|
569
|
+
drop: { type: "array", items: { type: "string" } }
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
]
|
|
573
|
+
},
|
|
574
|
+
privileged: { type: "boolean" },
|
|
575
|
+
allowPrivilegeEscalation: { type: "boolean" }
|
|
576
|
+
},
|
|
577
|
+
additionalProperties: false
|
|
578
|
+
},
|
|
579
|
+
BuildRequirements: {
|
|
580
|
+
type: "object",
|
|
581
|
+
properties: {
|
|
582
|
+
dockerfile: { type: "string" },
|
|
583
|
+
buildContext: { type: "string" },
|
|
584
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
585
|
+
buildTarget: { type: "string" },
|
|
586
|
+
prebuilt: { type: "boolean" },
|
|
587
|
+
noCache: { type: "boolean" }
|
|
588
|
+
},
|
|
589
|
+
additionalProperties: false
|
|
590
|
+
},
|
|
591
|
+
BackendServiceConfig: {
|
|
592
|
+
type: "object",
|
|
593
|
+
properties: {
|
|
594
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
595
|
+
devMode: { type: "boolean" },
|
|
596
|
+
command: { type: "string" },
|
|
597
|
+
port: { type: "integer" },
|
|
598
|
+
publicURL: { type: "string" },
|
|
599
|
+
corsOrigin: { type: "string" },
|
|
600
|
+
image: { type: "string" },
|
|
601
|
+
cpu: { type: "string" },
|
|
602
|
+
memory: { type: "string" },
|
|
603
|
+
semiontRepo: { type: "string" },
|
|
604
|
+
databaseUrl: { type: "string" },
|
|
605
|
+
projectRoot: { type: "string" },
|
|
606
|
+
timeout: { type: "integer" },
|
|
607
|
+
wait: { type: "integer" },
|
|
608
|
+
logsEndpoint: { type: "string" },
|
|
609
|
+
tag: { type: "string" },
|
|
610
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
611
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
612
|
+
build: {
|
|
613
|
+
oneOf: [
|
|
614
|
+
{ type: "boolean" },
|
|
615
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
616
|
+
]
|
|
617
|
+
},
|
|
618
|
+
dockerfile: { type: "string" },
|
|
619
|
+
buildContext: { type: "string" },
|
|
620
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
621
|
+
buildTarget: { type: "string" },
|
|
622
|
+
prebuilt: { type: "boolean" },
|
|
623
|
+
noCache: { type: "boolean" },
|
|
624
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
625
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
626
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
627
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
628
|
+
externalDependencies: {
|
|
629
|
+
type: "array",
|
|
630
|
+
items: {
|
|
631
|
+
oneOf: [
|
|
632
|
+
{ type: "string" },
|
|
633
|
+
{
|
|
634
|
+
type: "object",
|
|
635
|
+
properties: {
|
|
636
|
+
name: { type: "string" },
|
|
637
|
+
url: { type: "string" },
|
|
638
|
+
required: { type: "boolean" },
|
|
639
|
+
healthCheck: { type: "string" }
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
redisUrl: { type: "string" },
|
|
646
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
647
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
648
|
+
},
|
|
649
|
+
required: ["platform", "port", "publicURL", "corsOrigin"],
|
|
650
|
+
additionalProperties: false
|
|
651
|
+
},
|
|
652
|
+
FrontendServiceConfig: {
|
|
653
|
+
type: "object",
|
|
654
|
+
properties: {
|
|
655
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
656
|
+
devMode: { type: "boolean" },
|
|
657
|
+
command: { type: "string" },
|
|
658
|
+
port: { type: "integer" },
|
|
659
|
+
url: { type: "string" },
|
|
660
|
+
siteName: { type: "string" },
|
|
661
|
+
image: { type: "string" },
|
|
662
|
+
semiontRepo: { type: "string" },
|
|
663
|
+
projectRoot: { type: "string" },
|
|
664
|
+
databaseUrl: { type: "string" },
|
|
665
|
+
timeout: { type: "integer" },
|
|
666
|
+
wait: { type: "integer" },
|
|
667
|
+
logsEndpoint: { type: "string" },
|
|
668
|
+
tag: { type: "string" },
|
|
669
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
670
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
671
|
+
build: {
|
|
672
|
+
oneOf: [
|
|
673
|
+
{ type: "boolean" },
|
|
674
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
675
|
+
]
|
|
676
|
+
},
|
|
677
|
+
dockerfile: { type: "string" },
|
|
678
|
+
buildContext: { type: "string" },
|
|
679
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
680
|
+
buildTarget: { type: "string" },
|
|
681
|
+
prebuilt: { type: "boolean" },
|
|
682
|
+
noCache: { type: "boolean" },
|
|
683
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
684
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
685
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
686
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
687
|
+
externalDependencies: {
|
|
688
|
+
type: "array",
|
|
689
|
+
items: {
|
|
690
|
+
oneOf: [
|
|
691
|
+
{ type: "string" },
|
|
692
|
+
{
|
|
693
|
+
type: "object",
|
|
694
|
+
properties: {
|
|
695
|
+
name: { type: "string" },
|
|
696
|
+
url: { type: "string" },
|
|
697
|
+
required: { type: "boolean" },
|
|
698
|
+
healthCheck: { type: "string" }
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
]
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
705
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
706
|
+
},
|
|
707
|
+
required: ["platform", "port", "url", "siteName"],
|
|
708
|
+
additionalProperties: false
|
|
709
|
+
},
|
|
710
|
+
DatabaseServiceConfig: {
|
|
711
|
+
type: "object",
|
|
712
|
+
properties: {
|
|
713
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
714
|
+
type: { type: "string" },
|
|
715
|
+
name: { type: "string" },
|
|
716
|
+
host: { type: "string" },
|
|
717
|
+
port: { type: "integer" },
|
|
718
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
719
|
+
env: { type: "object", additionalProperties: { type: "string" } },
|
|
720
|
+
description: { type: "string" },
|
|
721
|
+
command: { type: "string" },
|
|
722
|
+
image: { type: "string" },
|
|
723
|
+
user: { type: "string" },
|
|
724
|
+
username: { type: "string" },
|
|
725
|
+
password: { type: "string" },
|
|
726
|
+
database: { type: "string" },
|
|
727
|
+
storageSize: { type: "string" },
|
|
728
|
+
timeout: { type: "integer" },
|
|
729
|
+
wait: { type: "integer" },
|
|
730
|
+
logsEndpoint: { type: "string" },
|
|
731
|
+
tag: { type: "string" },
|
|
732
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
733
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
734
|
+
build: {
|
|
735
|
+
oneOf: [
|
|
736
|
+
{ type: "boolean" },
|
|
737
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
738
|
+
]
|
|
739
|
+
},
|
|
740
|
+
dockerfile: { type: "string" },
|
|
741
|
+
buildContext: { type: "string" },
|
|
742
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
743
|
+
buildTarget: { type: "string" },
|
|
744
|
+
prebuilt: { type: "boolean" },
|
|
745
|
+
noCache: { type: "boolean" },
|
|
746
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
747
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
748
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
749
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
750
|
+
externalDependencies: {
|
|
751
|
+
type: "array",
|
|
752
|
+
items: {
|
|
753
|
+
oneOf: [
|
|
754
|
+
{ type: "string" },
|
|
755
|
+
{
|
|
756
|
+
type: "object",
|
|
757
|
+
properties: {
|
|
758
|
+
name: { type: "string" },
|
|
759
|
+
url: { type: "string" },
|
|
760
|
+
required: { type: "boolean" },
|
|
761
|
+
healthCheck: { type: "string" }
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
]
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
},
|
|
768
|
+
required: ["platform", "type", "host", "port"],
|
|
769
|
+
additionalProperties: false
|
|
770
|
+
},
|
|
771
|
+
GraphDatabaseType: {
|
|
772
|
+
type: "string",
|
|
773
|
+
enum: ["neo4j", "janusgraph", "neptune", "memory"]
|
|
774
|
+
},
|
|
775
|
+
GraphServiceConfig: {
|
|
776
|
+
type: "object",
|
|
777
|
+
properties: {
|
|
778
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
779
|
+
type: { $ref: "#/definitions/GraphDatabaseType" },
|
|
780
|
+
name: { type: "string" },
|
|
781
|
+
uri: { type: "string" },
|
|
782
|
+
url: { type: "string" },
|
|
783
|
+
username: { type: "string" },
|
|
784
|
+
password: { type: "string" },
|
|
785
|
+
database: { type: "string" },
|
|
786
|
+
host: { type: "string" },
|
|
787
|
+
port: { type: "integer" },
|
|
788
|
+
storage: { type: "string" },
|
|
789
|
+
index: { type: "string" },
|
|
790
|
+
endpoint: { type: "string" },
|
|
791
|
+
region: { type: "string" },
|
|
792
|
+
command: { type: "string" },
|
|
793
|
+
image: { type: "string" },
|
|
794
|
+
janusgraphVersion: { type: "string" },
|
|
795
|
+
javaOptions: { type: "string" },
|
|
796
|
+
heapSize: { type: "string" },
|
|
797
|
+
pageCacheSize: { type: "string" },
|
|
798
|
+
noAuth: { type: "boolean" },
|
|
799
|
+
dataPath: { type: "string" },
|
|
800
|
+
timeout: { type: "integer" },
|
|
801
|
+
wait: { type: "integer" },
|
|
802
|
+
logsEndpoint: { type: "string" },
|
|
803
|
+
tag: { type: "string" },
|
|
804
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
805
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
806
|
+
build: {
|
|
807
|
+
oneOf: [
|
|
808
|
+
{ type: "boolean" },
|
|
809
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
810
|
+
]
|
|
811
|
+
},
|
|
812
|
+
dockerfile: { type: "string" },
|
|
813
|
+
buildContext: { type: "string" },
|
|
814
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
815
|
+
buildTarget: { type: "string" },
|
|
816
|
+
prebuilt: { type: "boolean" },
|
|
817
|
+
noCache: { type: "boolean" },
|
|
818
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
819
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
820
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
821
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
822
|
+
externalDependencies: {
|
|
823
|
+
type: "array",
|
|
824
|
+
items: {
|
|
825
|
+
oneOf: [
|
|
826
|
+
{ type: "string" },
|
|
827
|
+
{
|
|
828
|
+
type: "object",
|
|
829
|
+
properties: {
|
|
830
|
+
name: { type: "string" },
|
|
831
|
+
url: { type: "string" },
|
|
832
|
+
required: { type: "boolean" },
|
|
833
|
+
healthCheck: { type: "string" }
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
]
|
|
837
|
+
}
|
|
838
|
+
},
|
|
839
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
840
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
841
|
+
},
|
|
842
|
+
required: ["platform", "type", "uri", "username", "password", "database"],
|
|
843
|
+
additionalProperties: false
|
|
844
|
+
},
|
|
845
|
+
FilesystemServiceConfig: {
|
|
846
|
+
type: "object",
|
|
847
|
+
properties: {
|
|
848
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
849
|
+
path: { type: "string" },
|
|
850
|
+
description: { type: "string" },
|
|
851
|
+
command: { type: "string" },
|
|
852
|
+
image: { type: "string" },
|
|
853
|
+
port: { type: "integer" },
|
|
854
|
+
timeout: { type: "integer" },
|
|
855
|
+
wait: { type: "integer" },
|
|
856
|
+
logsEndpoint: { type: "string" },
|
|
857
|
+
tag: { type: "string" },
|
|
858
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
859
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
860
|
+
build: {
|
|
861
|
+
oneOf: [
|
|
862
|
+
{ type: "boolean" },
|
|
863
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
864
|
+
]
|
|
865
|
+
},
|
|
866
|
+
dockerfile: { type: "string" },
|
|
867
|
+
buildContext: { type: "string" },
|
|
868
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
869
|
+
buildTarget: { type: "string" },
|
|
870
|
+
prebuilt: { type: "boolean" },
|
|
871
|
+
noCache: { type: "boolean" },
|
|
872
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
873
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
874
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
875
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
876
|
+
externalDependencies: {
|
|
877
|
+
type: "array",
|
|
878
|
+
items: {
|
|
879
|
+
oneOf: [
|
|
880
|
+
{ type: "string" },
|
|
881
|
+
{
|
|
882
|
+
type: "object",
|
|
883
|
+
properties: {
|
|
884
|
+
name: { type: "string" },
|
|
885
|
+
url: { type: "string" },
|
|
886
|
+
required: { type: "boolean" },
|
|
887
|
+
healthCheck: { type: "string" }
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
]
|
|
891
|
+
}
|
|
892
|
+
},
|
|
893
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
894
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
895
|
+
},
|
|
896
|
+
required: ["platform", "path"],
|
|
897
|
+
additionalProperties: false
|
|
898
|
+
},
|
|
899
|
+
InferenceServiceConfig: {
|
|
900
|
+
type: "object",
|
|
901
|
+
properties: {
|
|
902
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
903
|
+
type: { type: "string" },
|
|
904
|
+
model: { type: "string" },
|
|
905
|
+
maxTokens: { type: "integer" },
|
|
906
|
+
endpoint: { type: "string" },
|
|
907
|
+
baseURL: { type: "string" },
|
|
908
|
+
apiKey: { type: "string" },
|
|
909
|
+
command: { type: "string" },
|
|
910
|
+
image: { type: "string" },
|
|
911
|
+
port: { type: "integer" },
|
|
912
|
+
organization: { type: "string" },
|
|
913
|
+
timeout: { type: "integer" },
|
|
914
|
+
wait: { type: "integer" },
|
|
915
|
+
logsEndpoint: { type: "string" },
|
|
916
|
+
tag: { type: "string" },
|
|
917
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
918
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
919
|
+
build: {
|
|
920
|
+
oneOf: [
|
|
921
|
+
{ type: "boolean" },
|
|
922
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
923
|
+
]
|
|
924
|
+
},
|
|
925
|
+
dockerfile: { type: "string" },
|
|
926
|
+
buildContext: { type: "string" },
|
|
927
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
928
|
+
buildTarget: { type: "string" },
|
|
929
|
+
prebuilt: { type: "boolean" },
|
|
930
|
+
noCache: { type: "boolean" },
|
|
931
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
932
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
933
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
934
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
935
|
+
externalDependencies: {
|
|
936
|
+
type: "array",
|
|
937
|
+
items: {
|
|
938
|
+
oneOf: [
|
|
939
|
+
{ type: "string" },
|
|
940
|
+
{
|
|
941
|
+
type: "object",
|
|
942
|
+
properties: {
|
|
943
|
+
name: { type: "string" },
|
|
944
|
+
url: { type: "string" },
|
|
945
|
+
required: { type: "boolean" },
|
|
946
|
+
healthCheck: { type: "string" }
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
]
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
953
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
954
|
+
},
|
|
955
|
+
required: ["platform", "type", "apiKey"],
|
|
956
|
+
additionalProperties: false
|
|
957
|
+
},
|
|
958
|
+
McpServiceConfig: {
|
|
959
|
+
type: "object",
|
|
960
|
+
properties: {
|
|
961
|
+
platform: { $ref: "#/definitions/ServicePlatformConfig" },
|
|
962
|
+
command: { type: "string" },
|
|
963
|
+
image: { type: "string" },
|
|
964
|
+
port: { type: "integer" },
|
|
965
|
+
dependsOn: { type: "array", items: { type: "string" } },
|
|
966
|
+
timeout: { type: "integer" },
|
|
967
|
+
wait: { type: "integer" },
|
|
968
|
+
logsEndpoint: { type: "string" },
|
|
969
|
+
tag: { type: "string" },
|
|
970
|
+
resources: { $ref: "#/definitions/ResourceRequirements" },
|
|
971
|
+
security: { $ref: "#/definitions/SecurityRequirements" },
|
|
972
|
+
build: {
|
|
973
|
+
oneOf: [
|
|
974
|
+
{ type: "boolean" },
|
|
975
|
+
{ $ref: "#/definitions/BuildRequirements" }
|
|
976
|
+
]
|
|
977
|
+
},
|
|
978
|
+
dockerfile: { type: "string" },
|
|
979
|
+
buildContext: { type: "string" },
|
|
980
|
+
buildArgs: { type: "object", additionalProperties: { type: "string" } },
|
|
981
|
+
buildTarget: { type: "string" },
|
|
982
|
+
prebuilt: { type: "boolean" },
|
|
983
|
+
noCache: { type: "boolean" },
|
|
984
|
+
secrets: { type: "array", items: { type: "string" } },
|
|
985
|
+
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
986
|
+
annotations: { type: "object", additionalProperties: { type: "string" } },
|
|
987
|
+
dependencies: { type: "array", items: { type: "string" } },
|
|
988
|
+
externalDependencies: {
|
|
989
|
+
type: "array",
|
|
990
|
+
items: {
|
|
991
|
+
oneOf: [
|
|
992
|
+
{ type: "string" },
|
|
993
|
+
{
|
|
994
|
+
type: "object",
|
|
995
|
+
properties: {
|
|
996
|
+
name: { type: "string" },
|
|
997
|
+
url: { type: "string" },
|
|
998
|
+
required: { type: "boolean" },
|
|
999
|
+
healthCheck: { type: "string" }
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
environment: { type: "object", additionalProperties: { type: "string" } },
|
|
1006
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
1007
|
+
},
|
|
1008
|
+
required: ["platform"],
|
|
1009
|
+
additionalProperties: false
|
|
1010
|
+
},
|
|
1011
|
+
ServicesConfig: {
|
|
1012
|
+
type: "object",
|
|
1013
|
+
properties: {
|
|
1014
|
+
backend: { $ref: "#/definitions/BackendServiceConfig" },
|
|
1015
|
+
frontend: { $ref: "#/definitions/FrontendServiceConfig" },
|
|
1016
|
+
database: { $ref: "#/definitions/DatabaseServiceConfig" },
|
|
1017
|
+
graph: { $ref: "#/definitions/GraphServiceConfig" },
|
|
1018
|
+
filesystem: { $ref: "#/definitions/FilesystemServiceConfig" },
|
|
1019
|
+
inference: { $ref: "#/definitions/InferenceServiceConfig" },
|
|
1020
|
+
mcp: { $ref: "#/definitions/McpServiceConfig" }
|
|
1021
|
+
},
|
|
1022
|
+
additionalProperties: true
|
|
1023
|
+
},
|
|
1024
|
+
SiteConfig: {
|
|
1025
|
+
type: "object",
|
|
1026
|
+
properties: {
|
|
1027
|
+
siteName: {
|
|
1028
|
+
type: "string",
|
|
1029
|
+
minLength: 1,
|
|
1030
|
+
description: "Display name for the site"
|
|
1031
|
+
},
|
|
1032
|
+
domain: {
|
|
1033
|
+
type: "string",
|
|
1034
|
+
minLength: 1,
|
|
1035
|
+
description: "Primary domain for the site"
|
|
1036
|
+
},
|
|
1037
|
+
adminEmail: {
|
|
1038
|
+
type: "string",
|
|
1039
|
+
format: "email",
|
|
1040
|
+
description: "Administrator email address"
|
|
1041
|
+
},
|
|
1042
|
+
supportEmail: {
|
|
1043
|
+
type: "string",
|
|
1044
|
+
format: "email",
|
|
1045
|
+
description: "Support email address (optional)"
|
|
1046
|
+
},
|
|
1047
|
+
oauthAllowedDomains: {
|
|
1048
|
+
type: "array",
|
|
1049
|
+
items: {
|
|
1050
|
+
type: "string"
|
|
1051
|
+
},
|
|
1052
|
+
minItems: 1,
|
|
1053
|
+
description: "Email domains allowed for OAuth authentication"
|
|
1054
|
+
}
|
|
1055
|
+
},
|
|
1056
|
+
required: ["domain"],
|
|
1057
|
+
additionalProperties: false
|
|
1058
|
+
},
|
|
1059
|
+
AppConfig: {
|
|
1060
|
+
type: "object",
|
|
1061
|
+
properties: {
|
|
1062
|
+
features: {
|
|
1063
|
+
type: "object",
|
|
1064
|
+
properties: {
|
|
1065
|
+
enableAnalytics: { type: "boolean" },
|
|
1066
|
+
enableMaintenanceMode: { type: "boolean" },
|
|
1067
|
+
enableDebugLogging: { type: "boolean" }
|
|
1068
|
+
},
|
|
1069
|
+
additionalProperties: false
|
|
1070
|
+
},
|
|
1071
|
+
security: {
|
|
1072
|
+
type: "object",
|
|
1073
|
+
properties: {
|
|
1074
|
+
sessionTimeout: {
|
|
1075
|
+
type: "integer",
|
|
1076
|
+
minimum: 60,
|
|
1077
|
+
description: "Session timeout in seconds"
|
|
1078
|
+
},
|
|
1079
|
+
maxLoginAttempts: {
|
|
1080
|
+
type: "integer",
|
|
1081
|
+
minimum: 1,
|
|
1082
|
+
description: "Maximum failed login attempts before lockout"
|
|
1083
|
+
},
|
|
1084
|
+
corsAllowedOrigins: {
|
|
1085
|
+
type: "array",
|
|
1086
|
+
items: { type: "string" }
|
|
1087
|
+
},
|
|
1088
|
+
enableLocalAuth: {
|
|
1089
|
+
type: "boolean",
|
|
1090
|
+
description: "Enable local username/password authentication"
|
|
1091
|
+
},
|
|
1092
|
+
jwtSecret: {
|
|
1093
|
+
type: "string",
|
|
1094
|
+
minLength: 32,
|
|
1095
|
+
description: "JWT signing secret (base64 encoded, 32+ bytes)"
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
additionalProperties: false
|
|
1099
|
+
},
|
|
1100
|
+
performance: {
|
|
1101
|
+
type: "object",
|
|
1102
|
+
properties: {
|
|
1103
|
+
enableCaching: { type: "boolean" },
|
|
1104
|
+
cacheTimeout: {
|
|
1105
|
+
type: "integer",
|
|
1106
|
+
minimum: 0,
|
|
1107
|
+
description: "Cache timeout in seconds"
|
|
1108
|
+
},
|
|
1109
|
+
maxRequestSize: {
|
|
1110
|
+
type: "string",
|
|
1111
|
+
pattern: "^[0-9]+(kb|mb|gb)$",
|
|
1112
|
+
description: "Maximum request size (e.g., '10mb')"
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
1115
|
+
additionalProperties: false
|
|
1116
|
+
}
|
|
1117
|
+
},
|
|
1118
|
+
additionalProperties: false
|
|
1119
|
+
},
|
|
1120
|
+
EnvironmentConfig: {
|
|
1121
|
+
type: "object",
|
|
1122
|
+
properties: {
|
|
1123
|
+
_comment: {
|
|
1124
|
+
type: "string",
|
|
1125
|
+
description: "Optional comment for documentation"
|
|
1126
|
+
},
|
|
1127
|
+
_metadata: {
|
|
1128
|
+
type: "object",
|
|
1129
|
+
properties: {
|
|
1130
|
+
environment: { type: "string" },
|
|
1131
|
+
projectRoot: { type: "string" }
|
|
1132
|
+
},
|
|
1133
|
+
required: ["environment", "projectRoot"]
|
|
1134
|
+
},
|
|
1135
|
+
name: {
|
|
1136
|
+
type: "string",
|
|
1137
|
+
description: "Environment name"
|
|
1138
|
+
},
|
|
1139
|
+
platform: {
|
|
1140
|
+
type: "object",
|
|
1141
|
+
properties: {
|
|
1142
|
+
default: { $ref: "#/definitions/PlatformType" }
|
|
1143
|
+
}
|
|
1144
|
+
},
|
|
1145
|
+
services: {
|
|
1146
|
+
$ref: "#/definitions/ServicesConfig"
|
|
1147
|
+
},
|
|
1148
|
+
site: {
|
|
1149
|
+
$ref: "#/definitions/SiteConfig"
|
|
1150
|
+
},
|
|
1151
|
+
app: {
|
|
1152
|
+
$ref: "#/definitions/AppConfig"
|
|
1153
|
+
},
|
|
1154
|
+
env: {
|
|
1155
|
+
type: "object",
|
|
1156
|
+
properties: {
|
|
1157
|
+
NODE_ENV: {
|
|
1158
|
+
type: "string",
|
|
1159
|
+
enum: ["development", "production", "test"]
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
additionalProperties: true
|
|
1163
|
+
},
|
|
1164
|
+
deployment: {
|
|
1165
|
+
type: "object",
|
|
1166
|
+
properties: {
|
|
1167
|
+
imageTagStrategy: {
|
|
1168
|
+
type: "string",
|
|
1169
|
+
enum: ["mutable", "immutable", "git-hash"]
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
required: ["services"],
|
|
1175
|
+
additionalProperties: false
|
|
1176
|
+
},
|
|
1177
|
+
SemiontConfig: {
|
|
1178
|
+
type: "object",
|
|
1179
|
+
properties: {
|
|
1180
|
+
version: {
|
|
1181
|
+
type: "string",
|
|
1182
|
+
pattern: "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
1183
|
+
description: "Config file version (semver)"
|
|
1184
|
+
},
|
|
1185
|
+
project: {
|
|
1186
|
+
type: "string",
|
|
1187
|
+
minLength: 1,
|
|
1188
|
+
description: "Project name"
|
|
1189
|
+
},
|
|
1190
|
+
site: {
|
|
1191
|
+
$ref: "#/definitions/SiteConfig"
|
|
1192
|
+
},
|
|
1193
|
+
app: {
|
|
1194
|
+
$ref: "#/definitions/AppConfig"
|
|
1195
|
+
},
|
|
1196
|
+
services: {
|
|
1197
|
+
$ref: "#/definitions/ServicesConfig"
|
|
1198
|
+
}
|
|
1199
|
+
},
|
|
1200
|
+
required: ["version", "project", "site"],
|
|
1201
|
+
additionalProperties: false
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
// src/config/config-validator.ts
|
|
1207
|
+
var ajv = new Ajv({
|
|
1208
|
+
allErrors: true,
|
|
1209
|
+
// Return all errors, not just the first one
|
|
1210
|
+
coerceTypes: true,
|
|
1211
|
+
// Coerce types (e.g., "123" -> 123)
|
|
1212
|
+
removeAdditional: false,
|
|
1213
|
+
// Don't remove additional properties
|
|
1214
|
+
useDefaults: true,
|
|
1215
|
+
// Apply default values from schema
|
|
1216
|
+
strict: false
|
|
1217
|
+
});
|
|
1218
|
+
addFormats(ajv);
|
|
1219
|
+
ajv.addSchema(config_schema_default, "config");
|
|
1220
|
+
function validateSemiontConfig(data) {
|
|
1221
|
+
const validate = ajv.getSchema("config#/definitions/SemiontConfig");
|
|
1222
|
+
if (!validate) {
|
|
1223
|
+
throw new Error("SemiontConfig schema not found");
|
|
1224
|
+
}
|
|
1225
|
+
const valid = validate(data);
|
|
1226
|
+
if (!valid) {
|
|
1227
|
+
return {
|
|
1228
|
+
valid: false,
|
|
1229
|
+
errors: validate.errors || null,
|
|
1230
|
+
errorMessage: formatErrors(validate.errors || [])
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
return { valid: true, errors: null };
|
|
1234
|
+
}
|
|
1235
|
+
function validateEnvironmentConfig(data) {
|
|
1236
|
+
const validate = ajv.getSchema("config#/definitions/EnvironmentConfig");
|
|
1237
|
+
if (!validate) {
|
|
1238
|
+
throw new Error("EnvironmentConfig schema not found");
|
|
1239
|
+
}
|
|
1240
|
+
const valid = validate(data);
|
|
1241
|
+
if (!valid) {
|
|
1242
|
+
return {
|
|
1243
|
+
valid: false,
|
|
1244
|
+
errors: validate.errors || null,
|
|
1245
|
+
errorMessage: formatErrors(validate.errors || [])
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
return { valid: true, errors: null };
|
|
1249
|
+
}
|
|
1250
|
+
function validateSiteConfig(data) {
|
|
1251
|
+
const validate = ajv.getSchema("config#/definitions/SiteConfig");
|
|
1252
|
+
if (!validate) {
|
|
1253
|
+
throw new Error("SiteConfig schema not found");
|
|
1254
|
+
}
|
|
1255
|
+
const valid = validate(data);
|
|
1256
|
+
if (!valid) {
|
|
1257
|
+
return {
|
|
1258
|
+
valid: false,
|
|
1259
|
+
errors: validate.errors || null,
|
|
1260
|
+
errorMessage: formatErrors(validate.errors || [])
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
return { valid: true, errors: null };
|
|
1264
|
+
}
|
|
1265
|
+
function formatErrors(errors) {
|
|
1266
|
+
if (errors.length === 0) return "Validation failed";
|
|
1267
|
+
const messages = errors.map((err) => {
|
|
1268
|
+
const path3 = err.instancePath || "root";
|
|
1269
|
+
const message = err.message || "validation error";
|
|
1270
|
+
if (err.keyword === "required" && "missingProperty" in err.params) {
|
|
1271
|
+
return `Missing required property: ${err.params.missingProperty}`;
|
|
1272
|
+
}
|
|
1273
|
+
if (err.keyword === "type" && "type" in err.params) {
|
|
1274
|
+
return `${path3}: ${message} (expected ${err.params.type})`;
|
|
1275
|
+
}
|
|
1276
|
+
if (err.keyword === "enum" && "allowedValues" in err.params) {
|
|
1277
|
+
return `${path3}: must be one of [${err.params.allowedValues.join(", ")}]`;
|
|
1278
|
+
}
|
|
1279
|
+
if (err.keyword === "format") {
|
|
1280
|
+
return `${path3}: invalid format (${message})`;
|
|
1281
|
+
}
|
|
1282
|
+
if (err.keyword === "minLength" || err.keyword === "minItems") {
|
|
1283
|
+
return `${path3}: ${message}`;
|
|
1284
|
+
}
|
|
1285
|
+
return `${path3}: ${message}`;
|
|
1286
|
+
});
|
|
1287
|
+
return messages.join("; ");
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
// src/config/environment-loader.ts
|
|
1291
|
+
function deepMerge(target, ...sources) {
|
|
1292
|
+
if (!sources.length) return target;
|
|
1293
|
+
const source = sources.shift();
|
|
1294
|
+
if (isObject(target) && isObject(source)) {
|
|
1295
|
+
for (const key in source) {
|
|
1296
|
+
if (isObject(source[key])) {
|
|
1297
|
+
if (!target[key]) Object.assign(target, { [key]: {} });
|
|
1298
|
+
deepMerge(target[key], source[key]);
|
|
1299
|
+
} else {
|
|
1300
|
+
Object.assign(target, { [key]: source[key] });
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
return deepMerge(target, ...sources);
|
|
1305
|
+
}
|
|
1306
|
+
function resolveEnvVars(obj) {
|
|
1307
|
+
if (typeof obj === "string") {
|
|
1308
|
+
return obj.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
1309
|
+
return process.env[varName] || match;
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
if (Array.isArray(obj)) {
|
|
1313
|
+
return obj.map((item) => resolveEnvVars(item));
|
|
1314
|
+
}
|
|
1315
|
+
if (obj && typeof obj === "object") {
|
|
1316
|
+
const resolved = {};
|
|
1317
|
+
for (const key in obj) {
|
|
1318
|
+
resolved[key] = resolveEnvVars(obj[key]);
|
|
1319
|
+
}
|
|
1320
|
+
return resolved;
|
|
1321
|
+
}
|
|
1322
|
+
return obj;
|
|
1323
|
+
}
|
|
1324
|
+
function loadEnvironmentConfig(projectRoot, environment) {
|
|
1325
|
+
try {
|
|
1326
|
+
const baseConfigPath = path.join(projectRoot, "semiont.json");
|
|
1327
|
+
let baseConfig = {};
|
|
1328
|
+
if (fs2.existsSync(baseConfigPath)) {
|
|
1329
|
+
const baseContent = fs2.readFileSync(baseConfigPath, "utf-8");
|
|
1330
|
+
baseConfig = JSON.parse(baseContent);
|
|
1331
|
+
}
|
|
1332
|
+
const envPath = path.join(projectRoot, "environments", `${environment}.json`);
|
|
1333
|
+
if (!fs2.existsSync(envPath)) {
|
|
1334
|
+
throw new ConfigurationError(
|
|
1335
|
+
`Environment configuration missing: ${envPath}`,
|
|
1336
|
+
environment,
|
|
1337
|
+
`Create the configuration file or use: semiont init`
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
const envContent = fs2.readFileSync(envPath, "utf-8");
|
|
1341
|
+
const envConfig = JSON.parse(envContent);
|
|
1342
|
+
const merged = deepMerge(
|
|
1343
|
+
{},
|
|
1344
|
+
{ site: baseConfig.site },
|
|
1345
|
+
// Site config from semiont.json
|
|
1346
|
+
baseConfig.defaults || {},
|
|
1347
|
+
// Default config from semiont.json
|
|
1348
|
+
envConfig
|
|
1349
|
+
// Environment-specific overrides
|
|
1350
|
+
);
|
|
1351
|
+
const resolved = resolveEnvVars(merged);
|
|
1352
|
+
if (!resolved.services) {
|
|
1353
|
+
resolved.services = {};
|
|
1354
|
+
}
|
|
1355
|
+
if (resolved.env?.NODE_ENV) {
|
|
1356
|
+
const validNodeEnv = ["development", "production", "test"];
|
|
1357
|
+
if (!validNodeEnv.includes(resolved.env.NODE_ENV)) {
|
|
1358
|
+
throw new ConfigurationError(
|
|
1359
|
+
`Invalid NODE_ENV value: ${resolved.env.NODE_ENV}`,
|
|
1360
|
+
environment,
|
|
1361
|
+
`NODE_ENV must be one of: ${validNodeEnv.join(", ")}`
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
const configWithMetadata = {
|
|
1366
|
+
...resolved,
|
|
1367
|
+
_metadata: {
|
|
1368
|
+
environment,
|
|
1369
|
+
projectRoot
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
const validationResult = validateEnvironmentConfig(configWithMetadata);
|
|
1373
|
+
if (!validationResult.valid) {
|
|
1374
|
+
throw new ConfigurationError(
|
|
1375
|
+
`Invalid environment configuration: ${validationResult.errorMessage}`,
|
|
1376
|
+
environment,
|
|
1377
|
+
`Fix the validation errors in your environments/${environment}.json file`
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
return configWithMetadata;
|
|
1381
|
+
} catch (error) {
|
|
1382
|
+
if (error instanceof ConfigurationError) {
|
|
1383
|
+
throw error;
|
|
1384
|
+
}
|
|
1385
|
+
if (error instanceof SyntaxError && error.message.includes("JSON")) {
|
|
1386
|
+
throw new ConfigurationError(
|
|
1387
|
+
`Invalid JSON syntax in configuration file`,
|
|
1388
|
+
environment,
|
|
1389
|
+
`Check for missing commas, quotes, or brackets. Use a JSON validator to verify syntax.`
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1393
|
+
throw new ConfigurationError(
|
|
1394
|
+
`Failed to load environment configuration: ${message}`,
|
|
1395
|
+
environment,
|
|
1396
|
+
`Check the configuration files exist and are valid JSON`
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
function getNodeEnvForEnvironment(config) {
|
|
1401
|
+
const nodeEnv = config.env?.NODE_ENV;
|
|
1402
|
+
return nodeEnv || "development";
|
|
1403
|
+
}
|
|
1404
|
+
function getAvailableEnvironments() {
|
|
1405
|
+
try {
|
|
1406
|
+
const projectRoot = findProjectRoot();
|
|
1407
|
+
const configDir = path.join(projectRoot, "environments");
|
|
1408
|
+
if (!fs2.existsSync(configDir)) {
|
|
1409
|
+
return [];
|
|
1410
|
+
}
|
|
1411
|
+
return fs2.readdirSync(configDir).filter((file) => file.endsWith(".json")).map((file) => path.basename(file, ".json")).sort();
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
return [];
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
// src/config/environment-validator.ts
|
|
1418
|
+
function isValidEnvironment(value) {
|
|
1419
|
+
if (!value) return false;
|
|
1420
|
+
return getAvailableEnvironments().includes(value);
|
|
1421
|
+
}
|
|
1422
|
+
function parseEnvironment(value) {
|
|
1423
|
+
if (!value) {
|
|
1424
|
+
throw new Error("Environment is required");
|
|
1425
|
+
}
|
|
1426
|
+
if (!isValidEnvironment(value)) {
|
|
1427
|
+
const availableEnvs = getAvailableEnvironments();
|
|
1428
|
+
throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvs.join(", ")}`);
|
|
1429
|
+
}
|
|
1430
|
+
return value;
|
|
1431
|
+
}
|
|
1432
|
+
function validateEnvironment(value) {
|
|
1433
|
+
if (!value) {
|
|
1434
|
+
throw new Error("Environment is required");
|
|
1435
|
+
}
|
|
1436
|
+
if (!isValidEnvironment(value)) {
|
|
1437
|
+
const availableEnvs = getAvailableEnvironments();
|
|
1438
|
+
throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvs.join(", ")}`);
|
|
1439
|
+
}
|
|
1440
|
+
return value;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// src/config/platform-types.ts
|
|
1444
|
+
function isValidPlatformType(value) {
|
|
1445
|
+
return ["aws", "container", "posix", "external"].includes(value);
|
|
1446
|
+
}
|
|
1447
|
+
function getAllPlatformTypes() {
|
|
1448
|
+
return ["aws", "container", "posix", "external"];
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// src/index.ts
|
|
1452
|
+
var CORE_TYPES_VERSION = "0.1.0";
|
|
1453
|
+
var SDK_VERSION = "0.1.0";
|
|
1454
|
+
|
|
1455
|
+
export { APIError, CORE_TYPES_VERSION, CREATION_METHODS, ConfigurationError, ConflictError, NotFoundError, SDK_VERSION, ScriptError, SemiontError, UnauthorizedError, ValidationError, annotationId, bodyItemsMatch, calculateChecksum, createFetchAPI, didToAgent, fetchAPI, findBodyItem, findProjectRoot, formatEventType, formatRelativeTime, generateId, generateToken, generateUuid, getAllPlatformTypes, getAnnotationIdFromEvent, getAvailableEnvironments, getEnvironmentsPath, getEventDisplayContent, getEventEmoji, getEventEntityTypes, getEventType, getNodeEnvForEnvironment, getResourceCreationDetails, getSemiontConfigPath, isAnnotationId, isArray, isBoolean, isDefined, isEventRelatedToAnnotation, isFunction, isNull, isNullish, isNumber, isObject, isProjectRoot, isResourceEvent, isResourceId, isResourceScopedEvent, isString, isSystemEvent, isUndefined, isValidEnvironment, isValidPlatformType, loadEnvironmentConfig, parseEnvironment, resourceId, userId, userToAgent, userToDid, validateEnvironment, validateEnvironmentConfig, validateSemiontConfig, validateSiteConfig, verifyChecksum };
|
|
1456
|
+
//# sourceMappingURL=index.js.map
|
|
80
1457
|
//# sourceMappingURL=index.js.map
|