@archiva/archiva-nextjs 0.2.94 → 0.3.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/dist/chunk-5ZJUGBTU.mjs +281 -0
- package/dist/chunk-LOKBGU6S.mjs +88 -0
- package/dist/index-DfJ2Gf0Y.d.mts +148 -0
- package/dist/index-DfJ2Gf0Y.d.ts +148 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -2
- package/dist/index.mjs +2 -2
- package/dist/react/client.js +14 -4
- package/dist/react/client.mjs +7 -4
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +22 -2
- package/dist/server/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeAuditEventItem
|
|
3
|
+
} from "./chunk-LOKBGU6S.mjs";
|
|
4
|
+
|
|
5
|
+
// src/types.ts
|
|
6
|
+
var ArchivaError = class extends Error {
|
|
7
|
+
constructor(params) {
|
|
8
|
+
super(params.message);
|
|
9
|
+
this.statusCode = params.statusCode;
|
|
10
|
+
this.code = params.code;
|
|
11
|
+
this.retryAfterSeconds = params.retryAfterSeconds;
|
|
12
|
+
this.details = params.details;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/client.ts
|
|
17
|
+
var DEFAULT_BASE_URL = "https://api.archiva.app";
|
|
18
|
+
function buildHeaders(apiKey, overrides) {
|
|
19
|
+
const headers = new Headers(overrides);
|
|
20
|
+
headers.set("X-Project-Key", apiKey);
|
|
21
|
+
return headers;
|
|
22
|
+
}
|
|
23
|
+
async function parseError(response) {
|
|
24
|
+
const retryAfterHeader = response.headers.get("Retry-After");
|
|
25
|
+
const retryAfterSeconds = retryAfterHeader ? Number(retryAfterHeader) : void 0;
|
|
26
|
+
let payload = void 0;
|
|
27
|
+
try {
|
|
28
|
+
payload = await response.json();
|
|
29
|
+
} catch {
|
|
30
|
+
payload = void 0;
|
|
31
|
+
}
|
|
32
|
+
const errorMessage = typeof payload === "object" && payload !== null && "error" in payload ? String(payload.error) : response.statusText;
|
|
33
|
+
let code = "HTTP_ERROR";
|
|
34
|
+
if (response.status === 401) {
|
|
35
|
+
code = "UNAUTHORIZED";
|
|
36
|
+
} else if (response.status === 403) {
|
|
37
|
+
code = "FORBIDDEN";
|
|
38
|
+
} else if (response.status === 413) {
|
|
39
|
+
code = "PAYLOAD_TOO_LARGE";
|
|
40
|
+
} else if (response.status === 429) {
|
|
41
|
+
code = "RATE_LIMITED";
|
|
42
|
+
} else if (response.status === 409) {
|
|
43
|
+
code = "IDEMPOTENCY_CONFLICT";
|
|
44
|
+
}
|
|
45
|
+
throw new ArchivaError({
|
|
46
|
+
statusCode: response.status,
|
|
47
|
+
code,
|
|
48
|
+
message: errorMessage,
|
|
49
|
+
retryAfterSeconds,
|
|
50
|
+
details: payload
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function createRequestId() {
|
|
54
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
55
|
+
return crypto.randomUUID();
|
|
56
|
+
}
|
|
57
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
58
|
+
}
|
|
59
|
+
function createIdempotencyKey() {
|
|
60
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
61
|
+
return `idem_${crypto.randomUUID()}`;
|
|
62
|
+
}
|
|
63
|
+
return `idem_${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
64
|
+
}
|
|
65
|
+
async function loadEvents(apiKey, params, baseUrl = DEFAULT_BASE_URL) {
|
|
66
|
+
const url = new URL(`${baseUrl}/api/events`);
|
|
67
|
+
if (params.entityId) {
|
|
68
|
+
url.searchParams.set("entityId", params.entityId);
|
|
69
|
+
}
|
|
70
|
+
if (params.actorId) {
|
|
71
|
+
url.searchParams.set("actorId", params.actorId);
|
|
72
|
+
}
|
|
73
|
+
if (params.entityType) {
|
|
74
|
+
url.searchParams.set("entityType", params.entityType);
|
|
75
|
+
}
|
|
76
|
+
if (params.actorType) {
|
|
77
|
+
if (Array.isArray(params.actorType)) {
|
|
78
|
+
url.searchParams.set("actorType", params.actorType.join(","));
|
|
79
|
+
} else {
|
|
80
|
+
url.searchParams.set("actorType", params.actorType);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (params.tenantId) {
|
|
84
|
+
url.searchParams.set("tenantId", params.tenantId);
|
|
85
|
+
}
|
|
86
|
+
if (params.actionKey) {
|
|
87
|
+
url.searchParams.set("actionKey", params.actionKey);
|
|
88
|
+
}
|
|
89
|
+
if (params.q) {
|
|
90
|
+
url.searchParams.set("q", params.q);
|
|
91
|
+
}
|
|
92
|
+
if (params.limit) {
|
|
93
|
+
url.searchParams.set("limit", String(params.limit));
|
|
94
|
+
}
|
|
95
|
+
if (params.cursor) {
|
|
96
|
+
url.searchParams.set("cursor", params.cursor);
|
|
97
|
+
}
|
|
98
|
+
const response = await fetch(url.toString(), {
|
|
99
|
+
headers: buildHeaders(apiKey)
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
await parseError(response);
|
|
103
|
+
}
|
|
104
|
+
const payload = await response.json();
|
|
105
|
+
if (!payload || typeof payload !== "object" || !Array.isArray(payload.items)) {
|
|
106
|
+
throw new ArchivaError({
|
|
107
|
+
statusCode: response.status,
|
|
108
|
+
code: "HTTP_ERROR",
|
|
109
|
+
message: "Invalid response format",
|
|
110
|
+
details: payload
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const items = payload.items.map((item) => {
|
|
114
|
+
if (typeof item !== "object" || item === null) {
|
|
115
|
+
throw new ArchivaError({
|
|
116
|
+
statusCode: response.status,
|
|
117
|
+
code: "HTTP_ERROR",
|
|
118
|
+
message: "Invalid item format in response",
|
|
119
|
+
details: item
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return normalizeAuditEventItem(item);
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
items,
|
|
126
|
+
nextCursor: typeof payload.nextCursor === "string" ? payload.nextCursor : void 0
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async function createEvent(apiKey, event, options, baseUrl = DEFAULT_BASE_URL) {
|
|
130
|
+
const idempotencyKey = options?.idempotencyKey ?? createIdempotencyKey();
|
|
131
|
+
const requestId = options?.requestId ?? createRequestId();
|
|
132
|
+
const headers = buildHeaders(apiKey, {
|
|
133
|
+
"Content-Type": "application/json",
|
|
134
|
+
"Idempotency-Key": idempotencyKey,
|
|
135
|
+
"X-Request-Id": requestId
|
|
136
|
+
});
|
|
137
|
+
const response = await fetch(`${baseUrl}/api/ingest/event`, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers,
|
|
140
|
+
body: JSON.stringify(event)
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
await parseError(response);
|
|
144
|
+
}
|
|
145
|
+
const payload = await response.json();
|
|
146
|
+
if (!payload || typeof payload !== "object" || typeof payload.eventId !== "string") {
|
|
147
|
+
throw new ArchivaError({
|
|
148
|
+
statusCode: response.status,
|
|
149
|
+
code: "HTTP_ERROR",
|
|
150
|
+
message: "Invalid response format",
|
|
151
|
+
details: payload
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
eventId: payload.eventId,
|
|
156
|
+
replayed: response.status === 200
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
async function createEvents(apiKey, events, options, baseUrl = DEFAULT_BASE_URL) {
|
|
160
|
+
const results = await Promise.all(
|
|
161
|
+
events.map(
|
|
162
|
+
(event, index) => createEvent(
|
|
163
|
+
apiKey,
|
|
164
|
+
event,
|
|
165
|
+
{
|
|
166
|
+
...options,
|
|
167
|
+
idempotencyKey: options?.idempotencyKey ? `${options.idempotencyKey}_${index}` : void 0
|
|
168
|
+
},
|
|
169
|
+
baseUrl
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
);
|
|
173
|
+
return {
|
|
174
|
+
eventIds: results.map((r) => r.eventId)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/actions.ts
|
|
179
|
+
var DEFAULT_BASE_URL2 = "https://api.archiva.app";
|
|
180
|
+
function getApiKey(apiKey) {
|
|
181
|
+
const resolvedKey = apiKey || process.env.ARCHIVA_SECRET_KEY;
|
|
182
|
+
if (!resolvedKey) {
|
|
183
|
+
throw new Error("ARCHIVA_SECRET_KEY environment variable is required, or provide apiKey prop to ArchivaProvider");
|
|
184
|
+
}
|
|
185
|
+
return resolvedKey;
|
|
186
|
+
}
|
|
187
|
+
async function loadEvents2(params, apiKey) {
|
|
188
|
+
const resolvedApiKey = getApiKey(apiKey);
|
|
189
|
+
return loadEvents(resolvedApiKey, params, DEFAULT_BASE_URL2);
|
|
190
|
+
}
|
|
191
|
+
async function createEvent2(event, options, apiKey) {
|
|
192
|
+
const resolvedApiKey = getApiKey(apiKey);
|
|
193
|
+
return createEvent(resolvedApiKey, event, options, DEFAULT_BASE_URL2);
|
|
194
|
+
}
|
|
195
|
+
async function createEvents2(events, options, apiKey) {
|
|
196
|
+
const resolvedApiKey = getApiKey(apiKey);
|
|
197
|
+
return createEvents(resolvedApiKey, events, options, DEFAULT_BASE_URL2);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/server/frontendTokens.ts
|
|
201
|
+
import "server-only";
|
|
202
|
+
var DEFAULT_API_BASE_URL = "https://api.archiva.app";
|
|
203
|
+
async function createFrontendTokenGET(projectId, apiBaseUrl = DEFAULT_API_BASE_URL) {
|
|
204
|
+
const secretKey = process.env.ARCHIVA_SECRET_KEY;
|
|
205
|
+
if (!secretKey || secretKey.trim().length === 0) {
|
|
206
|
+
const exists = process.env.ARCHIVA_SECRET_KEY !== void 0;
|
|
207
|
+
throw new Error(
|
|
208
|
+
`ARCHIVA_SECRET_KEY environment variable is ${exists ? "empty" : "not configured"}. Please set it in your .env.local file (or .env) with a valid value and restart your Next.js dev server. The variable must be in the project root directory and must not be empty.`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const keyPrefix = secretKey.substring(0, 10);
|
|
212
|
+
console.log("[Archiva] Using API key prefix:", keyPrefix + "...", "Length:", secretKey.length);
|
|
213
|
+
const url = new URL(`${apiBaseUrl}/api/v1/frontend-tokens`);
|
|
214
|
+
const response = await fetch(url.toString(), {
|
|
215
|
+
method: "POST",
|
|
216
|
+
headers: {
|
|
217
|
+
"Content-Type": "application/json",
|
|
218
|
+
"Authorization": `Bearer ${secretKey}`
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify({
|
|
221
|
+
scopes: ["timeline:read"],
|
|
222
|
+
...projectId && { projectId }
|
|
223
|
+
})
|
|
224
|
+
});
|
|
225
|
+
if (!response.ok) {
|
|
226
|
+
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
227
|
+
const errorMessage = error.error || `Failed to fetch frontend token: ${response.status}`;
|
|
228
|
+
if (errorMessage.includes("ARCHIVA_SECRET_KEY") || response.status === 401 || response.status === 403) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
`Archiva API authentication failed. Check that your ARCHIVA_SECRET_KEY is valid and has the correct permissions. API error: ${errorMessage}`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
throw new Error(errorMessage);
|
|
234
|
+
}
|
|
235
|
+
const data = await response.json();
|
|
236
|
+
if (!data.token || typeof data.expiresAt !== "number") {
|
|
237
|
+
throw new Error("Invalid token response format");
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
token: data.token,
|
|
241
|
+
expiresAt: data.expiresAt
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/server/handlers/createFrontendTokenRoute.ts
|
|
246
|
+
import "server-only";
|
|
247
|
+
import { NextResponse } from "next/server";
|
|
248
|
+
var DEFAULT_API_BASE_URL2 = "https://api.archiva.app";
|
|
249
|
+
function createFrontendTokenRoute(options) {
|
|
250
|
+
return async function GET2(request) {
|
|
251
|
+
try {
|
|
252
|
+
const searchParams = request.nextUrl.searchParams;
|
|
253
|
+
const projectId = searchParams.get("projectId") || void 0;
|
|
254
|
+
const apiBaseUrl = options?.apiBaseUrl || DEFAULT_API_BASE_URL2;
|
|
255
|
+
const tokenResponse = await createFrontendTokenGET(projectId, apiBaseUrl);
|
|
256
|
+
return NextResponse.json(tokenResponse);
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error("Error fetching frontend token:", error);
|
|
259
|
+
const message = error instanceof Error ? error.message : "Internal server error";
|
|
260
|
+
const statusCode = message.includes("ARCHIVA_SECRET_KEY") ? 500 : 500;
|
|
261
|
+
return NextResponse.json(
|
|
262
|
+
{ error: message },
|
|
263
|
+
{ status: statusCode }
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
async function GET(request) {
|
|
269
|
+
const handler = createFrontendTokenRoute();
|
|
270
|
+
return handler(request);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export {
|
|
274
|
+
ArchivaError,
|
|
275
|
+
loadEvents2 as loadEvents,
|
|
276
|
+
createEvent2 as createEvent,
|
|
277
|
+
createEvents2 as createEvents,
|
|
278
|
+
createFrontendTokenGET,
|
|
279
|
+
createFrontendTokenRoute,
|
|
280
|
+
GET
|
|
281
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/eventNormalizer.ts
|
|
2
|
+
var coerceString = (value) => {
|
|
3
|
+
if (value === null || value === void 0) {
|
|
4
|
+
return void 0;
|
|
5
|
+
}
|
|
6
|
+
if (typeof value === "string") {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
10
|
+
return String(value);
|
|
11
|
+
}
|
|
12
|
+
return void 0;
|
|
13
|
+
};
|
|
14
|
+
var coerceNullableString = (value) => {
|
|
15
|
+
if (value === null || value === void 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === "string") {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
22
|
+
return String(value);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
|
+
var coerceActorType = (value) => {
|
|
27
|
+
if (typeof value !== "string") {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
const normalized = value.toLowerCase();
|
|
31
|
+
if (normalized === "user" || normalized === "service" || normalized === "system") {
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
return void 0;
|
|
35
|
+
};
|
|
36
|
+
var getActorValue = (event, actorRecord, keys) => {
|
|
37
|
+
for (const key of keys) {
|
|
38
|
+
if (Object.prototype.hasOwnProperty.call(event, key)) {
|
|
39
|
+
return event[key];
|
|
40
|
+
}
|
|
41
|
+
if (actorRecord && Object.prototype.hasOwnProperty.call(actorRecord, key)) {
|
|
42
|
+
return actorRecord[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return void 0;
|
|
46
|
+
};
|
|
47
|
+
var normalizeAuditEventItem = (event) => {
|
|
48
|
+
const actorRecord = typeof event.actor === "object" && event.actor !== null ? event.actor : void 0;
|
|
49
|
+
const actorDisplayValue = getActorValue(event, actorRecord, [
|
|
50
|
+
"actorDisplay",
|
|
51
|
+
"actor_display",
|
|
52
|
+
"display",
|
|
53
|
+
"display_name",
|
|
54
|
+
"name"
|
|
55
|
+
]);
|
|
56
|
+
const actorTypeValue = getActorValue(event, actorRecord, [
|
|
57
|
+
"actorType",
|
|
58
|
+
"actor_type",
|
|
59
|
+
"type"
|
|
60
|
+
]);
|
|
61
|
+
const actorIdValue = getActorValue(event, actorRecord, [
|
|
62
|
+
"actorId",
|
|
63
|
+
"actor_id",
|
|
64
|
+
"id"
|
|
65
|
+
]);
|
|
66
|
+
const actionKeyValue = coerceString(event.actionKey ?? event.action_key ?? event.action);
|
|
67
|
+
const actionDescriptionValue = coerceString(event.actionDescription ?? event.action_description);
|
|
68
|
+
const tenantIdValue = coerceString(event.tenantId ?? event.tenant_id);
|
|
69
|
+
return {
|
|
70
|
+
id: coerceString(event.id) ?? "",
|
|
71
|
+
receivedAt: coerceString(event.receivedAt ?? event.received_at) ?? "",
|
|
72
|
+
actionKey: actionKeyValue ?? "",
|
|
73
|
+
actionDescription: actionDescriptionValue ?? void 0,
|
|
74
|
+
tenantId: tenantIdValue ?? void 0,
|
|
75
|
+
// Legacy support: include action for backward compatibility
|
|
76
|
+
action: actionKeyValue ?? "",
|
|
77
|
+
entityType: coerceString(event.entityType ?? event.entity_type) ?? "",
|
|
78
|
+
entityId: coerceString(event.entityId ?? event.entity_id) ?? "",
|
|
79
|
+
actorId: coerceNullableString(actorIdValue),
|
|
80
|
+
actorType: coerceActorType(actorTypeValue),
|
|
81
|
+
actorDisplay: coerceString(actorDisplayValue) ?? "",
|
|
82
|
+
source: coerceNullableString(event.source)
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export {
|
|
87
|
+
normalizeAuditEventItem
|
|
88
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
type EventChange = {
|
|
4
|
+
op: "set" | "unset" | "add" | "remove" | "replace" | string;
|
|
5
|
+
path: string;
|
|
6
|
+
before?: unknown;
|
|
7
|
+
after?: unknown;
|
|
8
|
+
};
|
|
9
|
+
type CreateEventInput = {
|
|
10
|
+
actionKey?: string;
|
|
11
|
+
actionDescription?: string;
|
|
12
|
+
tenantId?: string;
|
|
13
|
+
action?: string;
|
|
14
|
+
entityType: string;
|
|
15
|
+
entityId: string;
|
|
16
|
+
actorType?: string;
|
|
17
|
+
actorId?: string;
|
|
18
|
+
actorDisplay?: string;
|
|
19
|
+
occurredAt?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
context?: Record<string, unknown>;
|
|
22
|
+
changes?: EventChange[];
|
|
23
|
+
};
|
|
24
|
+
type CreateEventOptions = {
|
|
25
|
+
idempotencyKey?: string;
|
|
26
|
+
requestId?: string;
|
|
27
|
+
};
|
|
28
|
+
type AuditEventListItem = {
|
|
29
|
+
id: string;
|
|
30
|
+
receivedAt: string;
|
|
31
|
+
actionKey: string;
|
|
32
|
+
actionDescription?: string;
|
|
33
|
+
tenantId?: string;
|
|
34
|
+
action?: string;
|
|
35
|
+
entityType: string;
|
|
36
|
+
entityId: string;
|
|
37
|
+
actorId: string | null;
|
|
38
|
+
actorType?: 'user' | 'service' | 'system';
|
|
39
|
+
actorDisplay: string;
|
|
40
|
+
source: string | null;
|
|
41
|
+
};
|
|
42
|
+
type PageResult<T> = {
|
|
43
|
+
items: T[];
|
|
44
|
+
nextCursor?: string;
|
|
45
|
+
};
|
|
46
|
+
type LoadEventsParams = {
|
|
47
|
+
entityId?: string;
|
|
48
|
+
actorId?: string;
|
|
49
|
+
entityType?: string;
|
|
50
|
+
actorType?: 'user' | 'service' | 'system' | ('user' | 'service' | 'system')[];
|
|
51
|
+
tenantId?: string;
|
|
52
|
+
actionKey?: string;
|
|
53
|
+
q?: string;
|
|
54
|
+
limit?: number;
|
|
55
|
+
cursor?: string;
|
|
56
|
+
};
|
|
57
|
+
declare class ArchivaError extends Error {
|
|
58
|
+
statusCode: number;
|
|
59
|
+
code: "UNAUTHORIZED" | "FORBIDDEN" | "PAYLOAD_TOO_LARGE" | "RATE_LIMITED" | "IDEMPOTENCY_CONFLICT" | "HTTP_ERROR";
|
|
60
|
+
retryAfterSeconds?: number;
|
|
61
|
+
details?: unknown;
|
|
62
|
+
constructor(params: {
|
|
63
|
+
statusCode: number;
|
|
64
|
+
code: "UNAUTHORIZED" | "FORBIDDEN" | "PAYLOAD_TOO_LARGE" | "RATE_LIMITED" | "IDEMPOTENCY_CONFLICT" | "HTTP_ERROR";
|
|
65
|
+
message: string;
|
|
66
|
+
retryAfterSeconds?: number;
|
|
67
|
+
details?: unknown;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Server action to load audit events
|
|
73
|
+
*
|
|
74
|
+
* @param params - Query parameters for filtering events
|
|
75
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
76
|
+
* @returns Paginated list of audit events
|
|
77
|
+
*/
|
|
78
|
+
declare function loadEvents(params: LoadEventsParams, apiKey?: string): Promise<PageResult<AuditEventListItem>>;
|
|
79
|
+
/**
|
|
80
|
+
* Server action to create a single audit event
|
|
81
|
+
*
|
|
82
|
+
* @param event - Event data to create
|
|
83
|
+
* @param options - Optional idempotency and request ID options
|
|
84
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
85
|
+
* @returns Created event ID and replay status
|
|
86
|
+
*/
|
|
87
|
+
declare function createEvent(event: CreateEventInput, options?: CreateEventOptions, apiKey?: string): Promise<{
|
|
88
|
+
eventId: string;
|
|
89
|
+
replayed: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Server action to create multiple audit events (bulk)
|
|
93
|
+
*
|
|
94
|
+
* @param events - Array of events to create
|
|
95
|
+
* @param options - Optional idempotency and request ID options
|
|
96
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
97
|
+
* @returns Array of created event IDs
|
|
98
|
+
*/
|
|
99
|
+
declare function createEvents(events: CreateEventInput[], options?: CreateEventOptions, apiKey?: string): Promise<{
|
|
100
|
+
eventIds: string[];
|
|
101
|
+
}>;
|
|
102
|
+
|
|
103
|
+
interface FrontendTokenResponse {
|
|
104
|
+
token: string;
|
|
105
|
+
expiresAt: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Fetches a frontend token from the Archiva API
|
|
109
|
+
*
|
|
110
|
+
* @param projectId - Optional project ID for scoping
|
|
111
|
+
* @param apiBaseUrl - Archiva API base URL (defaults to https://api.archiva.app)
|
|
112
|
+
* @returns Frontend token response
|
|
113
|
+
*/
|
|
114
|
+
declare function createFrontendTokenGET(projectId?: string, apiBaseUrl?: string): Promise<FrontendTokenResponse>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Next.js route handler for GET /api/archiva/frontend-token
|
|
118
|
+
*
|
|
119
|
+
* This handler can be used in the host app's route file:
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* // app/api/archiva/frontend-token/route.ts
|
|
123
|
+
* export { GET } from '@archiva/archiva-nextjs/server';
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* Or with custom configuration:
|
|
127
|
+
*
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { createFrontendTokenRoute } from '@archiva/archiva-nextjs/server';
|
|
130
|
+
*
|
|
131
|
+
* export const GET = createFrontendTokenRoute({
|
|
132
|
+
* apiBaseUrl: process.env.ARCHIVA_API_URL,
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function createFrontendTokenRoute(options?: {
|
|
137
|
+
apiBaseUrl?: string;
|
|
138
|
+
}): (request: NextRequest) => Promise<NextResponse<FrontendTokenResponse> | NextResponse<{
|
|
139
|
+
error: string;
|
|
140
|
+
}>>;
|
|
141
|
+
/**
|
|
142
|
+
* Default GET handler (for direct export)
|
|
143
|
+
*/
|
|
144
|
+
declare function GET(request: NextRequest): Promise<NextResponse<FrontendTokenResponse> | NextResponse<{
|
|
145
|
+
error: string;
|
|
146
|
+
}>>;
|
|
147
|
+
|
|
148
|
+
export { ArchivaError as A, type CreateEventInput as C, type EventChange as E, type FrontendTokenResponse as F, GET as G, type LoadEventsParams as L, type PageResult as P, createEvents as a, createFrontendTokenGET as b, createEvent as c, createFrontendTokenRoute as d, type CreateEventOptions as e, type AuditEventListItem as f, loadEvents as l };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
type EventChange = {
|
|
4
|
+
op: "set" | "unset" | "add" | "remove" | "replace" | string;
|
|
5
|
+
path: string;
|
|
6
|
+
before?: unknown;
|
|
7
|
+
after?: unknown;
|
|
8
|
+
};
|
|
9
|
+
type CreateEventInput = {
|
|
10
|
+
actionKey?: string;
|
|
11
|
+
actionDescription?: string;
|
|
12
|
+
tenantId?: string;
|
|
13
|
+
action?: string;
|
|
14
|
+
entityType: string;
|
|
15
|
+
entityId: string;
|
|
16
|
+
actorType?: string;
|
|
17
|
+
actorId?: string;
|
|
18
|
+
actorDisplay?: string;
|
|
19
|
+
occurredAt?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
context?: Record<string, unknown>;
|
|
22
|
+
changes?: EventChange[];
|
|
23
|
+
};
|
|
24
|
+
type CreateEventOptions = {
|
|
25
|
+
idempotencyKey?: string;
|
|
26
|
+
requestId?: string;
|
|
27
|
+
};
|
|
28
|
+
type AuditEventListItem = {
|
|
29
|
+
id: string;
|
|
30
|
+
receivedAt: string;
|
|
31
|
+
actionKey: string;
|
|
32
|
+
actionDescription?: string;
|
|
33
|
+
tenantId?: string;
|
|
34
|
+
action?: string;
|
|
35
|
+
entityType: string;
|
|
36
|
+
entityId: string;
|
|
37
|
+
actorId: string | null;
|
|
38
|
+
actorType?: 'user' | 'service' | 'system';
|
|
39
|
+
actorDisplay: string;
|
|
40
|
+
source: string | null;
|
|
41
|
+
};
|
|
42
|
+
type PageResult<T> = {
|
|
43
|
+
items: T[];
|
|
44
|
+
nextCursor?: string;
|
|
45
|
+
};
|
|
46
|
+
type LoadEventsParams = {
|
|
47
|
+
entityId?: string;
|
|
48
|
+
actorId?: string;
|
|
49
|
+
entityType?: string;
|
|
50
|
+
actorType?: 'user' | 'service' | 'system' | ('user' | 'service' | 'system')[];
|
|
51
|
+
tenantId?: string;
|
|
52
|
+
actionKey?: string;
|
|
53
|
+
q?: string;
|
|
54
|
+
limit?: number;
|
|
55
|
+
cursor?: string;
|
|
56
|
+
};
|
|
57
|
+
declare class ArchivaError extends Error {
|
|
58
|
+
statusCode: number;
|
|
59
|
+
code: "UNAUTHORIZED" | "FORBIDDEN" | "PAYLOAD_TOO_LARGE" | "RATE_LIMITED" | "IDEMPOTENCY_CONFLICT" | "HTTP_ERROR";
|
|
60
|
+
retryAfterSeconds?: number;
|
|
61
|
+
details?: unknown;
|
|
62
|
+
constructor(params: {
|
|
63
|
+
statusCode: number;
|
|
64
|
+
code: "UNAUTHORIZED" | "FORBIDDEN" | "PAYLOAD_TOO_LARGE" | "RATE_LIMITED" | "IDEMPOTENCY_CONFLICT" | "HTTP_ERROR";
|
|
65
|
+
message: string;
|
|
66
|
+
retryAfterSeconds?: number;
|
|
67
|
+
details?: unknown;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Server action to load audit events
|
|
73
|
+
*
|
|
74
|
+
* @param params - Query parameters for filtering events
|
|
75
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
76
|
+
* @returns Paginated list of audit events
|
|
77
|
+
*/
|
|
78
|
+
declare function loadEvents(params: LoadEventsParams, apiKey?: string): Promise<PageResult<AuditEventListItem>>;
|
|
79
|
+
/**
|
|
80
|
+
* Server action to create a single audit event
|
|
81
|
+
*
|
|
82
|
+
* @param event - Event data to create
|
|
83
|
+
* @param options - Optional idempotency and request ID options
|
|
84
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
85
|
+
* @returns Created event ID and replay status
|
|
86
|
+
*/
|
|
87
|
+
declare function createEvent(event: CreateEventInput, options?: CreateEventOptions, apiKey?: string): Promise<{
|
|
88
|
+
eventId: string;
|
|
89
|
+
replayed: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Server action to create multiple audit events (bulk)
|
|
93
|
+
*
|
|
94
|
+
* @param events - Array of events to create
|
|
95
|
+
* @param options - Optional idempotency and request ID options
|
|
96
|
+
* @param apiKey - Optional API key (otherwise uses ARCHIVA_SECRET_KEY env var)
|
|
97
|
+
* @returns Array of created event IDs
|
|
98
|
+
*/
|
|
99
|
+
declare function createEvents(events: CreateEventInput[], options?: CreateEventOptions, apiKey?: string): Promise<{
|
|
100
|
+
eventIds: string[];
|
|
101
|
+
}>;
|
|
102
|
+
|
|
103
|
+
interface FrontendTokenResponse {
|
|
104
|
+
token: string;
|
|
105
|
+
expiresAt: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Fetches a frontend token from the Archiva API
|
|
109
|
+
*
|
|
110
|
+
* @param projectId - Optional project ID for scoping
|
|
111
|
+
* @param apiBaseUrl - Archiva API base URL (defaults to https://api.archiva.app)
|
|
112
|
+
* @returns Frontend token response
|
|
113
|
+
*/
|
|
114
|
+
declare function createFrontendTokenGET(projectId?: string, apiBaseUrl?: string): Promise<FrontendTokenResponse>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Next.js route handler for GET /api/archiva/frontend-token
|
|
118
|
+
*
|
|
119
|
+
* This handler can be used in the host app's route file:
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* // app/api/archiva/frontend-token/route.ts
|
|
123
|
+
* export { GET } from '@archiva/archiva-nextjs/server';
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* Or with custom configuration:
|
|
127
|
+
*
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { createFrontendTokenRoute } from '@archiva/archiva-nextjs/server';
|
|
130
|
+
*
|
|
131
|
+
* export const GET = createFrontendTokenRoute({
|
|
132
|
+
* apiBaseUrl: process.env.ARCHIVA_API_URL,
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function createFrontendTokenRoute(options?: {
|
|
137
|
+
apiBaseUrl?: string;
|
|
138
|
+
}): (request: NextRequest) => Promise<NextResponse<FrontendTokenResponse> | NextResponse<{
|
|
139
|
+
error: string;
|
|
140
|
+
}>>;
|
|
141
|
+
/**
|
|
142
|
+
* Default GET handler (for direct export)
|
|
143
|
+
*/
|
|
144
|
+
declare function GET(request: NextRequest): Promise<NextResponse<FrontendTokenResponse> | NextResponse<{
|
|
145
|
+
error: string;
|
|
146
|
+
}>>;
|
|
147
|
+
|
|
148
|
+
export { ArchivaError as A, type CreateEventInput as C, type EventChange as E, type FrontendTokenResponse as F, GET as G, type LoadEventsParams as L, type PageResult as P, createEvents as a, createFrontendTokenGET as b, createEvent as c, createFrontendTokenRoute as d, type CreateEventOptions as e, type AuditEventListItem as f, loadEvents as l };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ArchivaProvider, ArchivaProviderProps } from './react/index.mjs';
|
|
2
|
-
export { A as ArchivaError, f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, E as EventChange, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from './index-
|
|
2
|
+
export { A as ArchivaError, f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, E as EventChange, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from './index-DfJ2Gf0Y.mjs';
|
|
3
3
|
import 'react/jsx-runtime';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'next/server';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ArchivaProvider, ArchivaProviderProps } from './react/index.js';
|
|
2
|
-
export { A as ArchivaError, f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, E as EventChange, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from './index-
|
|
2
|
+
export { A as ArchivaError, f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, E as EventChange, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from './index-DfJ2Gf0Y.js';
|
|
3
3
|
import 'react/jsx-runtime';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'next/server';
|
package/dist/index.js
CHANGED
|
@@ -304,10 +304,17 @@ var normalizeAuditEventItem = (event) => {
|
|
|
304
304
|
"actor_id",
|
|
305
305
|
"id"
|
|
306
306
|
]);
|
|
307
|
+
const actionKeyValue = coerceString(event.actionKey ?? event.action_key ?? event.action);
|
|
308
|
+
const actionDescriptionValue = coerceString(event.actionDescription ?? event.action_description);
|
|
309
|
+
const tenantIdValue = coerceString(event.tenantId ?? event.tenant_id);
|
|
307
310
|
return {
|
|
308
311
|
id: coerceString(event.id) ?? "",
|
|
309
312
|
receivedAt: coerceString(event.receivedAt ?? event.received_at) ?? "",
|
|
310
|
-
|
|
313
|
+
actionKey: actionKeyValue ?? "",
|
|
314
|
+
actionDescription: actionDescriptionValue ?? void 0,
|
|
315
|
+
tenantId: tenantIdValue ?? void 0,
|
|
316
|
+
// Legacy support: include action for backward compatibility
|
|
317
|
+
action: actionKeyValue ?? "",
|
|
311
318
|
entityType: coerceString(event.entityType ?? event.entity_type) ?? "",
|
|
312
319
|
entityId: coerceString(event.entityId ?? event.entity_id) ?? "",
|
|
313
320
|
actorId: coerceNullableString(actorIdValue),
|
|
@@ -378,7 +385,20 @@ async function loadEvents(apiKey, params, baseUrl = DEFAULT_BASE_URL) {
|
|
|
378
385
|
url.searchParams.set("entityType", params.entityType);
|
|
379
386
|
}
|
|
380
387
|
if (params.actorType) {
|
|
381
|
-
|
|
388
|
+
if (Array.isArray(params.actorType)) {
|
|
389
|
+
url.searchParams.set("actorType", params.actorType.join(","));
|
|
390
|
+
} else {
|
|
391
|
+
url.searchParams.set("actorType", params.actorType);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (params.tenantId) {
|
|
395
|
+
url.searchParams.set("tenantId", params.tenantId);
|
|
396
|
+
}
|
|
397
|
+
if (params.actionKey) {
|
|
398
|
+
url.searchParams.set("actionKey", params.actionKey);
|
|
399
|
+
}
|
|
400
|
+
if (params.q) {
|
|
401
|
+
url.searchParams.set("q", params.q);
|
|
382
402
|
}
|
|
383
403
|
if (params.limit) {
|
|
384
404
|
url.searchParams.set("limit", String(params.limit));
|
package/dist/index.mjs
CHANGED
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
createFrontendTokenGET,
|
|
10
10
|
createFrontendTokenRoute,
|
|
11
11
|
loadEvents
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-5ZJUGBTU.mjs";
|
|
13
|
+
import "./chunk-LOKBGU6S.mjs";
|
|
14
14
|
export {
|
|
15
15
|
ArchivaError,
|
|
16
16
|
ArchivaProvider,
|
package/dist/react/client.js
CHANGED
|
@@ -121,10 +121,17 @@ var normalizeAuditEventItem = (event) => {
|
|
|
121
121
|
"actor_id",
|
|
122
122
|
"id"
|
|
123
123
|
]);
|
|
124
|
+
const actionKeyValue = coerceString(event.actionKey ?? event.action_key ?? event.action);
|
|
125
|
+
const actionDescriptionValue = coerceString(event.actionDescription ?? event.action_description);
|
|
126
|
+
const tenantIdValue = coerceString(event.tenantId ?? event.tenant_id);
|
|
124
127
|
return {
|
|
125
128
|
id: coerceString(event.id) ?? "",
|
|
126
129
|
receivedAt: coerceString(event.receivedAt ?? event.received_at) ?? "",
|
|
127
|
-
|
|
130
|
+
actionKey: actionKeyValue ?? "",
|
|
131
|
+
actionDescription: actionDescriptionValue ?? void 0,
|
|
132
|
+
tenantId: tenantIdValue ?? void 0,
|
|
133
|
+
// Legacy support: include action for backward compatibility
|
|
134
|
+
action: actionKeyValue ?? "",
|
|
128
135
|
entityType: coerceString(event.entityType ?? event.entity_type) ?? "",
|
|
129
136
|
entityId: coerceString(event.entityId ?? event.entity_id) ?? "",
|
|
130
137
|
actorId: coerceNullableString(actorIdValue),
|
|
@@ -196,7 +203,8 @@ var CloudCogIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime2.js
|
|
|
196
203
|
}
|
|
197
204
|
);
|
|
198
205
|
function eventToTimelineItem(event, getActorAvatar) {
|
|
199
|
-
const
|
|
206
|
+
const actionValue = event.actionKey || event.action || "";
|
|
207
|
+
const action = actionValue.charAt(0).toUpperCase() + actionValue.slice(1);
|
|
200
208
|
const description = action;
|
|
201
209
|
const actorId = event.actorId || "unknown";
|
|
202
210
|
const userName = actorId.includes(":") ? actorId.split(":")[1] || actorId : actorId;
|
|
@@ -259,7 +267,8 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
259
267
|
url.searchParams.set("entityType", params.entityType);
|
|
260
268
|
}
|
|
261
269
|
if (params.actorType) {
|
|
262
|
-
|
|
270
|
+
const actorTypeValue = Array.isArray(params.actorType) ? params.actorType.join(",") : params.actorType;
|
|
271
|
+
url.searchParams.set("actorType", actorTypeValue);
|
|
263
272
|
}
|
|
264
273
|
if (params.limit) {
|
|
265
274
|
url.searchParams.set("limit", String(params.limit));
|
|
@@ -418,7 +427,8 @@ function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
|
418
427
|
}
|
|
419
428
|
const query = searchQuery.toLowerCase();
|
|
420
429
|
return filtered.filter((event) => {
|
|
421
|
-
|
|
430
|
+
const actionValue = (event.actionKey || event.action || "").toLowerCase();
|
|
431
|
+
return actionValue.includes(query) || event.entityType.toLowerCase().includes(query) || event.entityId.toLowerCase().includes(query) || event.actorId && event.actorId.toLowerCase().includes(query) || event.source && event.source.toLowerCase().includes(query) || event.actorDisplay && event.actorDisplay.toLowerCase().includes(query);
|
|
422
432
|
});
|
|
423
433
|
}
|
|
424
434
|
function Timeline({
|
package/dist/react/client.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
normalizeAuditEventItem
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-LOKBGU6S.mjs";
|
|
5
5
|
import {
|
|
6
6
|
useArchivaContext
|
|
7
7
|
} from "../chunk-H4TGL57C.mjs";
|
|
@@ -76,7 +76,8 @@ var CloudCogIcon = ({ className }) => /* @__PURE__ */ jsxs(
|
|
|
76
76
|
}
|
|
77
77
|
);
|
|
78
78
|
function eventToTimelineItem(event, getActorAvatar) {
|
|
79
|
-
const
|
|
79
|
+
const actionValue = event.actionKey || event.action || "";
|
|
80
|
+
const action = actionValue.charAt(0).toUpperCase() + actionValue.slice(1);
|
|
80
81
|
const description = action;
|
|
81
82
|
const actorId = event.actorId || "unknown";
|
|
82
83
|
const userName = actorId.includes(":") ? actorId.split(":")[1] || actorId : actorId;
|
|
@@ -139,7 +140,8 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
139
140
|
url.searchParams.set("entityType", params.entityType);
|
|
140
141
|
}
|
|
141
142
|
if (params.actorType) {
|
|
142
|
-
|
|
143
|
+
const actorTypeValue = Array.isArray(params.actorType) ? params.actorType.join(",") : params.actorType;
|
|
144
|
+
url.searchParams.set("actorType", actorTypeValue);
|
|
143
145
|
}
|
|
144
146
|
if (params.limit) {
|
|
145
147
|
url.searchParams.set("limit", String(params.limit));
|
|
@@ -298,7 +300,8 @@ function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
|
298
300
|
}
|
|
299
301
|
const query = searchQuery.toLowerCase();
|
|
300
302
|
return filtered.filter((event) => {
|
|
301
|
-
|
|
303
|
+
const actionValue = (event.actionKey || event.action || "").toLowerCase();
|
|
304
|
+
return actionValue.includes(query) || event.entityType.toLowerCase().includes(query) || event.entityId.toLowerCase().includes(query) || event.actorId && event.actorId.toLowerCase().includes(query) || event.source && event.source.toLowerCase().includes(query) || event.actorDisplay && event.actorDisplay.toLowerCase().includes(query);
|
|
302
305
|
});
|
|
303
306
|
}
|
|
304
307
|
function Timeline({
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from '../index-
|
|
1
|
+
export { f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from '../index-DfJ2Gf0Y.mjs';
|
|
2
2
|
import 'next/server';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from '../index-
|
|
1
|
+
export { f as AuditEventListItem, C as CreateEventInput, e as CreateEventOptions, F as FrontendTokenResponse, G as GET, L as LoadEventsParams, P as PageResult, c as createEvent, a as createEvents, b as createFrontendTokenGET, d as createFrontendTokenRoute, l as loadEvents } from '../index-DfJ2Gf0Y.js';
|
|
2
2
|
import 'next/server';
|
package/dist/server/index.js
CHANGED
|
@@ -178,10 +178,17 @@ var normalizeAuditEventItem = (event) => {
|
|
|
178
178
|
"actor_id",
|
|
179
179
|
"id"
|
|
180
180
|
]);
|
|
181
|
+
const actionKeyValue = coerceString(event.actionKey ?? event.action_key ?? event.action);
|
|
182
|
+
const actionDescriptionValue = coerceString(event.actionDescription ?? event.action_description);
|
|
183
|
+
const tenantIdValue = coerceString(event.tenantId ?? event.tenant_id);
|
|
181
184
|
return {
|
|
182
185
|
id: coerceString(event.id) ?? "",
|
|
183
186
|
receivedAt: coerceString(event.receivedAt ?? event.received_at) ?? "",
|
|
184
|
-
|
|
187
|
+
actionKey: actionKeyValue ?? "",
|
|
188
|
+
actionDescription: actionDescriptionValue ?? void 0,
|
|
189
|
+
tenantId: tenantIdValue ?? void 0,
|
|
190
|
+
// Legacy support: include action for backward compatibility
|
|
191
|
+
action: actionKeyValue ?? "",
|
|
185
192
|
entityType: coerceString(event.entityType ?? event.entity_type) ?? "",
|
|
186
193
|
entityId: coerceString(event.entityId ?? event.entity_id) ?? "",
|
|
187
194
|
actorId: coerceNullableString(actorIdValue),
|
|
@@ -252,7 +259,20 @@ async function loadEvents(apiKey, params, baseUrl = DEFAULT_BASE_URL) {
|
|
|
252
259
|
url.searchParams.set("entityType", params.entityType);
|
|
253
260
|
}
|
|
254
261
|
if (params.actorType) {
|
|
255
|
-
|
|
262
|
+
if (Array.isArray(params.actorType)) {
|
|
263
|
+
url.searchParams.set("actorType", params.actorType.join(","));
|
|
264
|
+
} else {
|
|
265
|
+
url.searchParams.set("actorType", params.actorType);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (params.tenantId) {
|
|
269
|
+
url.searchParams.set("tenantId", params.tenantId);
|
|
270
|
+
}
|
|
271
|
+
if (params.actionKey) {
|
|
272
|
+
url.searchParams.set("actionKey", params.actionKey);
|
|
273
|
+
}
|
|
274
|
+
if (params.q) {
|
|
275
|
+
url.searchParams.set("q", params.q);
|
|
256
276
|
}
|
|
257
277
|
if (params.limit) {
|
|
258
278
|
url.searchParams.set("limit", String(params.limit));
|
package/dist/server/index.mjs
CHANGED