@echovisionlab/geul-event 0.1.0
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/LICENSE.md +6 -0
- package/README.md +6 -0
- package/dist/index.js +358 -0
- package/package.json +51 -0
- package/src/block_catalog.test.ts +1164 -0
- package/src/campaign-create-target-contract.test.ts +36 -0
- package/src/collaboration-locale-value-changes.test.ts +51 -0
- package/src/content-entity-type.test.ts +74 -0
- package/src/event-model.test.ts +125 -0
- package/src/form-locale-catalog.test.ts +67 -0
- package/src/generated.ts +59 -0
- package/src/index.ts +86 -0
- package/src/interactive-mutation.test.ts +287 -0
- package/src/interactive-mutation.ts +136 -0
- package/src/pgmq.test.ts +80 -0
- package/src/pgmq.ts +216 -0
- package/src/proto-helpers.test.ts +103 -0
- package/src/proto-helpers.ts +62 -0
- package/src/spicedb-policy.test.ts +226 -0
- package/src/translation-source.test.ts +28 -0
- package/src/translation-source.ts +15 -0
- package/src/user-delete-identity-mode.test.ts +34 -0
package/LICENSE.md
ADDED
package/README.md
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
// src/generated.ts
|
|
2
|
+
var Signals = {
|
|
3
|
+
transcodeProgress: "transcode.progress",
|
|
4
|
+
transcodeCancel: "transcode.cancel",
|
|
5
|
+
waveformProgress: "waveform.progress",
|
|
6
|
+
waveformCancel: "waveform.cancel",
|
|
7
|
+
meshOptimizationProgress: "mesh.optimization.progress",
|
|
8
|
+
mediaProcessingLifecycle: "media.processing.lifecycle",
|
|
9
|
+
ogLifecycle: "og.lifecycle",
|
|
10
|
+
mailAdapterChanged: "mail_adapter.changed",
|
|
11
|
+
contentUpdated: "content.updated",
|
|
12
|
+
fileIngest: "file.ingest",
|
|
13
|
+
translationLifecycle: "translation.lifecycle"
|
|
14
|
+
};
|
|
15
|
+
var Queues = {
|
|
16
|
+
ogGenerate: "og.generate",
|
|
17
|
+
transcoderAudio: "transcoder.audio",
|
|
18
|
+
transcoderVideo: "transcoder.video",
|
|
19
|
+
waveformGenerate: "waveform.generate",
|
|
20
|
+
assetOptimizerMesh: "asset_optimizer.mesh",
|
|
21
|
+
fileDelete: "file.delete",
|
|
22
|
+
emailSend: "email.send",
|
|
23
|
+
emailAuth: "email.auth",
|
|
24
|
+
emailCampaign: "email.campaign",
|
|
25
|
+
userDeleteIdentity: "user.delete.identity",
|
|
26
|
+
userDeleteAvatar: "user.delete.avatar",
|
|
27
|
+
aiMetadataGenerate: "ai.metadata.generate",
|
|
28
|
+
translationGenerate: "translation.generate",
|
|
29
|
+
transcodeResult: "transcode.result",
|
|
30
|
+
waveformResult: "waveform.result",
|
|
31
|
+
meshOptimizationResult: "mesh.optimization.result",
|
|
32
|
+
releaseTrackOriginalAudioProjection: "release.track_original_audio.projection"
|
|
33
|
+
};
|
|
34
|
+
var FileIngestSignalTypes = {
|
|
35
|
+
upload: "upload",
|
|
36
|
+
download: "download",
|
|
37
|
+
finalized: "finalized",
|
|
38
|
+
attached: "attached",
|
|
39
|
+
failed: "failed"
|
|
40
|
+
};
|
|
41
|
+
var ContentType = {
|
|
42
|
+
protobuf: "application/x-protobuf",
|
|
43
|
+
json: "application/json"
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/pgmq.ts
|
|
47
|
+
var PGMQ_ENVELOPE_SCHEMA_VERSION = 1;
|
|
48
|
+
function encodeBase64(payload) {
|
|
49
|
+
return Buffer.from(payload).toString("base64");
|
|
50
|
+
}
|
|
51
|
+
function decodeBase64(payload) {
|
|
52
|
+
return new Uint8Array(Buffer.from(payload, "base64"));
|
|
53
|
+
}
|
|
54
|
+
function createPgmqEnvelope(input) {
|
|
55
|
+
const envelope = {
|
|
56
|
+
message_id: input.messageId,
|
|
57
|
+
message_type: input.messageType,
|
|
58
|
+
schema_version: PGMQ_ENVELOPE_SCHEMA_VERSION,
|
|
59
|
+
created_at: (input.createdAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
60
|
+
payload_base64: encodeBase64(input.payload),
|
|
61
|
+
...input.correlationId ? { correlation_id: input.correlationId } : {},
|
|
62
|
+
...input.causationId ? { causation_id: input.causationId } : {}
|
|
63
|
+
};
|
|
64
|
+
assertPgmqEnvelope(envelope);
|
|
65
|
+
return envelope;
|
|
66
|
+
}
|
|
67
|
+
function assertPgmqEnvelope(value) {
|
|
68
|
+
if (!value || typeof value !== "object") {
|
|
69
|
+
throw new Error("PGMQ envelope must be an object");
|
|
70
|
+
}
|
|
71
|
+
const envelope = value;
|
|
72
|
+
if (!envelope.message_id || typeof envelope.message_id !== "string") {
|
|
73
|
+
throw new Error("PGMQ envelope message_id is required");
|
|
74
|
+
}
|
|
75
|
+
if (!envelope.message_type || typeof envelope.message_type !== "string") {
|
|
76
|
+
throw new Error("PGMQ envelope message_type is required");
|
|
77
|
+
}
|
|
78
|
+
if (envelope.schema_version !== PGMQ_ENVELOPE_SCHEMA_VERSION) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Unsupported PGMQ envelope schema ${envelope.schema_version}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (typeof envelope.created_at !== "string" || Number.isNaN(Date.parse(envelope.created_at))) {
|
|
84
|
+
throw new Error("PGMQ envelope created_at must be an ISO timestamp");
|
|
85
|
+
}
|
|
86
|
+
if (typeof envelope.payload_base64 !== "string") {
|
|
87
|
+
throw new Error("PGMQ envelope payload_base64 is required");
|
|
88
|
+
}
|
|
89
|
+
const normalized = Buffer.from(envelope.payload_base64, "base64").toString(
|
|
90
|
+
"base64"
|
|
91
|
+
);
|
|
92
|
+
if (normalized !== envelope.payload_base64) {
|
|
93
|
+
throw new Error("PGMQ envelope payload_base64 is invalid");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function pgmqEnvelopePayload(envelope) {
|
|
97
|
+
assertPgmqEnvelope(envelope);
|
|
98
|
+
return decodeBase64(envelope.payload_base64);
|
|
99
|
+
}
|
|
100
|
+
var PgmqClient = class {
|
|
101
|
+
async enqueue(executor, queue, envelope, options = {}) {
|
|
102
|
+
assertPgmqEnvelope(envelope);
|
|
103
|
+
if (!queue) throw new Error("PGMQ queue is required");
|
|
104
|
+
const delaySeconds = Math.max(0, Math.trunc(options.delaySeconds ?? 0));
|
|
105
|
+
const result = await executor.query(
|
|
106
|
+
"SELECT pgmq.send($1, $2::jsonb, $3::jsonb, $4::integer) AS msg_id",
|
|
107
|
+
[queue, envelope, options.headers ?? {}, delaySeconds]
|
|
108
|
+
);
|
|
109
|
+
const row = result.rows[0];
|
|
110
|
+
if (!row) throw new Error(`PGMQ send returned no message for ${queue}`);
|
|
111
|
+
return BigInt(row.msg_id);
|
|
112
|
+
}
|
|
113
|
+
async read(executor, queue, options) {
|
|
114
|
+
if (!queue) throw new Error("PGMQ queue is required");
|
|
115
|
+
const visibilityTimeoutSeconds = Math.trunc(
|
|
116
|
+
options.visibilityTimeoutSeconds
|
|
117
|
+
);
|
|
118
|
+
const batch = Math.trunc(options.batch ?? 1);
|
|
119
|
+
if (visibilityTimeoutSeconds <= 0) {
|
|
120
|
+
throw new Error("PGMQ visibility timeout must be positive");
|
|
121
|
+
}
|
|
122
|
+
if (batch <= 0) throw new Error("PGMQ batch must be positive");
|
|
123
|
+
const result = await executor.query(
|
|
124
|
+
"SELECT msg_id, read_ct, enqueued_at, vt, message, headers FROM pgmq.read($1, $2::integer, $3::integer, '{}'::jsonb)",
|
|
125
|
+
[queue, visibilityTimeoutSeconds, batch]
|
|
126
|
+
);
|
|
127
|
+
return result.rows.map((row) => {
|
|
128
|
+
const message = {
|
|
129
|
+
transportId: BigInt(row.msg_id),
|
|
130
|
+
readCount: row.read_ct,
|
|
131
|
+
enqueuedAt: new Date(row.enqueued_at),
|
|
132
|
+
visibleAt: new Date(row.vt),
|
|
133
|
+
headers: row.headers ?? {}
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
assertPgmqEnvelope(row.message);
|
|
137
|
+
return { ...message, envelope: row.message };
|
|
138
|
+
} catch (error) {
|
|
139
|
+
return {
|
|
140
|
+
...message,
|
|
141
|
+
contractError: error instanceof Error ? error.message : "Invalid PGMQ envelope"
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async complete(executor, queue, transportId) {
|
|
147
|
+
await this.booleanOperation(executor, "delete", queue, transportId);
|
|
148
|
+
}
|
|
149
|
+
async retry(executor, queue, transportId, delaySeconds) {
|
|
150
|
+
const result = await executor.query(
|
|
151
|
+
"SELECT msg_id FROM pgmq.set_vt($1, $2::bigint, $3::integer)",
|
|
152
|
+
[queue, transportId.toString(), Math.max(0, Math.trunc(delaySeconds))]
|
|
153
|
+
);
|
|
154
|
+
if (BigInt(result.rows[0]?.msg_id ?? -1) !== transportId) {
|
|
155
|
+
throw new Error(`PGMQ retry did not update ${queue}/${transportId}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async deadLetter(executor, queue, transportId) {
|
|
159
|
+
await this.booleanOperation(executor, "archive", queue, transportId);
|
|
160
|
+
}
|
|
161
|
+
async booleanOperation(executor, operation, queue, transportId) {
|
|
162
|
+
const result = await executor.query(
|
|
163
|
+
`SELECT pgmq.${operation}($1, $2::bigint) AS succeeded`,
|
|
164
|
+
[queue, transportId.toString()]
|
|
165
|
+
);
|
|
166
|
+
if (result.rows[0]?.succeeded !== true) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`PGMQ ${operation} did not update ${queue}/${transportId}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// src/interactive-mutation.ts
|
|
175
|
+
import { AIDocumentDomain } from "@echovisionlab/geul-proto/secure/ai_pb.ts";
|
|
176
|
+
import {
|
|
177
|
+
InteractiveAIDocumentMutationOrigin
|
|
178
|
+
} from "@echovisionlab/geul-proto/intra/collaboration_pb.ts";
|
|
179
|
+
var activeDocumentDomains = new Set(
|
|
180
|
+
Object.values(AIDocumentDomain).filter(
|
|
181
|
+
(value) => typeof value === "number" && value !== AIDocumentDomain.AI_DOCUMENT_DOMAIN_UNSPECIFIED
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
function requireNonBlank(value, name) {
|
|
185
|
+
if (value.trim() === "") {
|
|
186
|
+
throw new Error(`interactive AI document mutation ${name} is required`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function assertRelayInteractiveAIDocumentMutationRequest(event) {
|
|
190
|
+
requireNonBlank(event.mutationId, "id");
|
|
191
|
+
switch (event.origin) {
|
|
192
|
+
case InteractiveAIDocumentMutationOrigin.INTERACTIVE_AI_DOCUMENT_MUTATION_ORIGIN_IN_EDITOR_AI:
|
|
193
|
+
case InteractiveAIDocumentMutationOrigin.INTERACTIVE_AI_DOCUMENT_MUTATION_ORIGIN_MCP:
|
|
194
|
+
break;
|
|
195
|
+
case InteractiveAIDocumentMutationOrigin.INTERACTIVE_AI_DOCUMENT_MUTATION_ORIGIN_UNSPECIFIED:
|
|
196
|
+
default:
|
|
197
|
+
throw new Error(
|
|
198
|
+
`unsupported interactive AI document mutation origin: ${event.origin}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
if (event.document === void 0) {
|
|
202
|
+
throw new Error("interactive AI document mutation document is required");
|
|
203
|
+
}
|
|
204
|
+
if (!activeDocumentDomains.has(event.document.domain)) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
`unsupported interactive AI document mutation domain: ${event.document.domain}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
requireNonBlank(event.document.reference, "reference");
|
|
210
|
+
if (event.locale === void 0) {
|
|
211
|
+
throw new Error("interactive AI document mutation locale is required");
|
|
212
|
+
}
|
|
213
|
+
requireNonBlank(event.locale.code, "locale");
|
|
214
|
+
requireNonBlank(event.expectedDocumentRevision, "expected document revision");
|
|
215
|
+
requireNonBlank(event.acceptedDocumentRevision, "accepted document revision");
|
|
216
|
+
if (event.operations.length === 0) {
|
|
217
|
+
throw new Error("interactive AI document mutation operations are required");
|
|
218
|
+
}
|
|
219
|
+
event.operations.forEach((operation, index) => {
|
|
220
|
+
if (operation.operation.case === void 0) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
`interactive AI document mutation operation ${index} is required`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
if (event.operations.length !== 1 && event.operations.some(
|
|
227
|
+
(operation) => operation.operation.case === "createTranslation" || operation.operation.case === "deleteTranslation"
|
|
228
|
+
)) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
"interactive AI document mutation locale lifecycle operation must be exclusive"
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
if (event.expectedTargetRevision !== void 0) {
|
|
234
|
+
requireNonBlank(event.expectedTargetRevision, "expected target revision");
|
|
235
|
+
}
|
|
236
|
+
if (event.acceptedTargetRevision !== void 0) {
|
|
237
|
+
requireNonBlank(event.acceptedTargetRevision, "accepted target revision");
|
|
238
|
+
}
|
|
239
|
+
const isTargetMutation = event.expectedTargetRevision !== void 0 || event.acceptedTargetRevision !== void 0;
|
|
240
|
+
if (isTargetMutation) {
|
|
241
|
+
if (event.acceptedDocumentRevision !== event.expectedDocumentRevision) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
"interactive AI document target mutation must preserve the document revision"
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
if (event.expectedTargetRevision === void 0 && event.acceptedTargetRevision === void 0 && event.acceptedDocumentRevision === event.expectedDocumentRevision) {
|
|
248
|
+
throw new Error(
|
|
249
|
+
"interactive AI document source mutation must advance the document revision"
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const onlyOperation = event.operations.length === 1 ? event.operations[0] : void 0;
|
|
254
|
+
if (onlyOperation?.operation.case === "createTranslation") {
|
|
255
|
+
if (event.expectedTargetRevision !== void 0 || event.acceptedTargetRevision === void 0) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
"interactive AI document mutation create translation revisions are invalid"
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
} else if (onlyOperation?.operation.case === "deleteTranslation") {
|
|
261
|
+
if (event.expectedTargetRevision === void 0 || event.acceptedTargetRevision !== void 0) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
"interactive AI document mutation delete translation revisions are invalid"
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
} else if (event.expectedTargetRevision !== void 0 && event.acceptedTargetRevision === void 0) {
|
|
267
|
+
throw new Error(
|
|
268
|
+
"interactive AI document mutation target revision cannot disappear"
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
requireNonBlank(event.actorMemberId, "actor member id");
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/index.ts
|
|
275
|
+
import {
|
|
276
|
+
InternalOgService,
|
|
277
|
+
OgGenerationClaimResult
|
|
278
|
+
} from "@echovisionlab/geul-proto/intra/og_pb.ts";
|
|
279
|
+
|
|
280
|
+
// src/proto-helpers.ts
|
|
281
|
+
import { fromBinary } from "@bufbuild/protobuf";
|
|
282
|
+
import {
|
|
283
|
+
AssetDisposition,
|
|
284
|
+
MediaProcessingStatus
|
|
285
|
+
} from "@echovisionlab/geul-proto/common/media_pb.ts";
|
|
286
|
+
import {
|
|
287
|
+
FileIngestAttachedEventSchema,
|
|
288
|
+
FileIngestDownloadEventSchema,
|
|
289
|
+
FileIngestFailedEventSchema,
|
|
290
|
+
FileIngestFailureReason,
|
|
291
|
+
FileIngestFinalizedEventSchema,
|
|
292
|
+
FileIngestIdentitySchema,
|
|
293
|
+
FileIngestMediaKind,
|
|
294
|
+
FileIngestSource,
|
|
295
|
+
FileIngestUploadEventSchema,
|
|
296
|
+
MediaProcessingLifecycleEventSchema,
|
|
297
|
+
MeshOptimizationResultEventSchema,
|
|
298
|
+
OgEntityType,
|
|
299
|
+
OgGenerationJobSchema,
|
|
300
|
+
OgGenerationLifecycleEventSchema,
|
|
301
|
+
OgGenerationStatus,
|
|
302
|
+
OgGenerationTargetSchema,
|
|
303
|
+
TranscodeCompleteEventSchema,
|
|
304
|
+
TranscodeEntityType,
|
|
305
|
+
TranslationLifecycleEventSchema,
|
|
306
|
+
WaveformResultEventSchema
|
|
307
|
+
} from "@echovisionlab/geul-proto/secure/events_pb.ts";
|
|
308
|
+
function deserializeProto(schema, data) {
|
|
309
|
+
return fromBinary(schema, data);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/translation-source.ts
|
|
313
|
+
function assertTranslationJobRequestArtifact(job) {
|
|
314
|
+
if (job.target === void 0) {
|
|
315
|
+
throw new Error("translation job target is required");
|
|
316
|
+
}
|
|
317
|
+
if (job.requestArtifactDigest.trim().length === 0) {
|
|
318
|
+
throw new Error("translation job request artifact digest is required");
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
export {
|
|
322
|
+
AssetDisposition,
|
|
323
|
+
ContentType,
|
|
324
|
+
FileIngestAttachedEventSchema,
|
|
325
|
+
FileIngestDownloadEventSchema,
|
|
326
|
+
FileIngestFailedEventSchema,
|
|
327
|
+
FileIngestFailureReason,
|
|
328
|
+
FileIngestFinalizedEventSchema,
|
|
329
|
+
FileIngestIdentitySchema,
|
|
330
|
+
FileIngestMediaKind,
|
|
331
|
+
FileIngestSignalTypes,
|
|
332
|
+
FileIngestSource,
|
|
333
|
+
FileIngestUploadEventSchema,
|
|
334
|
+
InternalOgService,
|
|
335
|
+
MediaProcessingLifecycleEventSchema,
|
|
336
|
+
MediaProcessingStatus,
|
|
337
|
+
MeshOptimizationResultEventSchema,
|
|
338
|
+
OgEntityType,
|
|
339
|
+
OgGenerationClaimResult,
|
|
340
|
+
OgGenerationJobSchema,
|
|
341
|
+
OgGenerationLifecycleEventSchema,
|
|
342
|
+
OgGenerationStatus,
|
|
343
|
+
OgGenerationTargetSchema,
|
|
344
|
+
PGMQ_ENVELOPE_SCHEMA_VERSION,
|
|
345
|
+
PgmqClient,
|
|
346
|
+
Queues,
|
|
347
|
+
Signals,
|
|
348
|
+
TranscodeCompleteEventSchema,
|
|
349
|
+
TranscodeEntityType,
|
|
350
|
+
TranslationLifecycleEventSchema,
|
|
351
|
+
WaveformResultEventSchema,
|
|
352
|
+
assertPgmqEnvelope,
|
|
353
|
+
assertRelayInteractiveAIDocumentMutationRequest,
|
|
354
|
+
assertTranslationJobRequestArtifact,
|
|
355
|
+
createPgmqEnvelope,
|
|
356
|
+
deserializeProto,
|
|
357
|
+
pgmqEnvelopePayload
|
|
358
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@echovisionlab/geul-event",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsup",
|
|
8
|
+
"test": "vitest run",
|
|
9
|
+
"test:coverage": "vitest run --coverage",
|
|
10
|
+
"typecheck": "tsc --noEmit",
|
|
11
|
+
"lint": "eslint --cache .",
|
|
12
|
+
"lint-fix": "eslint --cache . --fix"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./src/index.ts",
|
|
17
|
+
"types": "./src/index.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@bufbuild/protobuf": "^2.14.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@echovisionlab/geul-proto": "^0.1.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@echovisionlab/geul-proto": "workspace:*",
|
|
32
|
+
"@types/node": "^24.13.3",
|
|
33
|
+
"@typescript/native": "npm:typescript@7.0.2",
|
|
34
|
+
"eslint": "^10.8.1",
|
|
35
|
+
"tsup": "^8.5.1",
|
|
36
|
+
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
37
|
+
"typescript-eslint": "^8.67.0"
|
|
38
|
+
},
|
|
39
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/echovisionlab/geul-event-contracts.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/echovisionlab/geul-event-contracts#readme",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/echovisionlab/geul-event-contracts/issues"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|