@beechcms/core 0.4.0 → 0.4.2
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/auth/password-reset-token.repository.d.ts +0 -1
- package/dist/auth/password-reset-token.repository.d.ts.map +1 -1
- package/dist/automations-grammar-words.d.ts +2 -0
- package/dist/automations-grammar-words.d.ts.map +1 -0
- package/dist/automations-grammar-words.js +6 -0
- package/dist/automations.repository.interface.d.ts +19 -0
- package/dist/automations.repository.interface.d.ts.map +1 -0
- package/dist/automations.repository.interface.js +1 -0
- package/dist/automations.runner.interface.d.ts +10 -0
- package/dist/automations.runner.interface.d.ts.map +1 -0
- package/dist/automations.runner.interface.js +1 -0
- package/dist/automations.runner.stub.d.ts +5 -0
- package/dist/automations.runner.stub.d.ts.map +1 -0
- package/dist/automations.runner.stub.js +5 -0
- package/dist/automations.types.d.ts +73 -0
- package/dist/automations.types.d.ts.map +1 -0
- package/dist/automations.types.js +1 -0
- package/dist/clock.d.ts +25 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +9 -0
- package/dist/content-scan.repository.d.ts +9 -0
- package/dist/content-scan.repository.d.ts.map +1 -0
- package/dist/content-scan.repository.js +1 -0
- package/dist/engine.d.ts +24 -24
- package/dist/engine.js +22 -22
- package/dist/id-generator.d.ts +19 -0
- package/dist/id-generator.d.ts.map +1 -0
- package/dist/id-generator.js +7 -0
- package/dist/index.d.ts +27 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -3
- package/dist/notifications/notification-service.d.ts +29 -0
- package/dist/notifications/notification-service.d.ts.map +1 -0
- package/dist/notifications/notification-service.js +1 -0
- package/dist/notifications/notification.repository.d.ts +51 -0
- package/dist/notifications/notification.repository.d.ts.map +1 -0
- package/dist/notifications/notification.repository.js +10 -0
- package/dist/observability/activity-log.repository.d.ts +58 -0
- package/dist/observability/activity-log.repository.d.ts.map +1 -0
- package/dist/observability/activity-log.repository.js +1 -0
- package/dist/observability/activity-logger.d.ts +49 -0
- package/dist/observability/activity-logger.d.ts.map +1 -0
- package/dist/observability/activity-logger.js +12 -0
- package/dist/observability/analytics.repository.d.ts +37 -0
- package/dist/observability/analytics.repository.d.ts.map +1 -0
- package/dist/observability/analytics.repository.js +1 -0
- package/dist/scheduler.interface.d.ts +4 -0
- package/dist/scheduler.interface.d.ts.map +1 -0
- package/dist/scheduler.interface.js +1 -0
- package/dist/scheduler.stub.d.ts +5 -0
- package/dist/scheduler.stub.d.ts.map +1 -0
- package/dist/scheduler.stub.js +5 -0
- package/dist/search/search.repository.d.ts +45 -0
- package/dist/search/search.repository.d.ts.map +1 -0
- package/dist/search/search.repository.js +1 -0
- package/dist/seed-registry.d.ts +49 -0
- package/dist/seed-registry.d.ts.map +1 -0
- package/dist/seed-registry.js +38 -0
- package/dist/slug-utils.d.ts.map +1 -1
- package/dist/slug-utils.js +4 -3
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +7 -7
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +29 -106
- package/dist/widget/widget.repository.d.ts +113 -0
- package/dist/widget/widget.repository.d.ts.map +1 -0
- package/dist/widget/widget.repository.js +1 -0
- package/package.json +9 -3
package/dist/validation.js
CHANGED
|
@@ -227,6 +227,7 @@ function requiredAliases(seed, operation) {
|
|
|
227
227
|
}
|
|
228
228
|
function buildBranchSchema(branch, options) {
|
|
229
229
|
const nullable = options.allowNull ? z.null() : null;
|
|
230
|
+
const preprocessEmpty = (schema) => z.preprocess((val) => (val === '' || val === null ? (options.allowNull ? null : undefined) : val), schema.optional());
|
|
230
231
|
switch (branch.type) {
|
|
231
232
|
case 'text': {
|
|
232
233
|
const schema = stringSchema
|
|
@@ -265,56 +266,48 @@ function buildBranchSchema(branch, options) {
|
|
|
265
266
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
266
267
|
}
|
|
267
268
|
case 'number': {
|
|
268
|
-
const schema = finiteNumberSchema;
|
|
269
|
+
const schema = preprocessEmpty(finiteNumberSchema);
|
|
269
270
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
270
271
|
}
|
|
271
272
|
case 'boolean': {
|
|
272
|
-
const schema = booleanSchema;
|
|
273
|
+
const schema = preprocessEmpty(booleanSchema);
|
|
273
274
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
274
275
|
}
|
|
275
276
|
case 'date': {
|
|
276
|
-
const schema = stringSchema
|
|
277
|
+
const schema = preprocessEmpty(stringSchema
|
|
277
278
|
.transform((value) => sanitizePlainString(value))
|
|
278
|
-
.refine((value) => isIsoDateString(value), { message: 'Expected date(ISO)' });
|
|
279
|
+
.refine((value) => isIsoDateString(value), { message: 'Expected date(ISO)' }));
|
|
279
280
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
280
281
|
}
|
|
281
282
|
case 'json':
|
|
282
283
|
case 'tags': {
|
|
283
|
-
const schema = jsonObjectOrArraySchema;
|
|
284
|
+
const schema = preprocessEmpty(jsonObjectOrArraySchema);
|
|
284
285
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
285
286
|
}
|
|
286
287
|
case 'file': {
|
|
287
288
|
if (isAssetListBranch(branch)) {
|
|
288
|
-
const schema = z
|
|
289
|
-
.any()
|
|
289
|
+
const schema = preprocessEmpty(z.any()
|
|
290
290
|
.transform((rawValue, ctx) => {
|
|
291
291
|
const normalized = normalizeAssetListValue(rawValue);
|
|
292
292
|
if (!normalized) {
|
|
293
|
-
ctx.addIssue({
|
|
294
|
-
code: 'custom',
|
|
295
|
-
message: 'Expected url-string[]',
|
|
296
|
-
});
|
|
293
|
+
ctx.addIssue({ code: 'custom', message: 'Expected url-string[]' });
|
|
297
294
|
return z.NEVER;
|
|
298
295
|
}
|
|
299
296
|
return normalized;
|
|
300
297
|
})
|
|
301
|
-
.pipe(z.array(z.url()));
|
|
298
|
+
.pipe(z.array(z.string().url())));
|
|
302
299
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
303
300
|
}
|
|
304
|
-
const schema = z
|
|
305
|
-
.any()
|
|
301
|
+
const schema = preprocessEmpty(z.any()
|
|
306
302
|
.transform((rawValue, ctx) => {
|
|
307
303
|
const normalized = normalizeHttpUrl(rawValue);
|
|
308
304
|
if (!normalized) {
|
|
309
|
-
ctx.addIssue({
|
|
310
|
-
code: 'custom',
|
|
311
|
-
message: 'Expected url-string',
|
|
312
|
-
});
|
|
305
|
+
ctx.addIssue({ code: 'custom', message: 'Expected url-string' });
|
|
313
306
|
return z.NEVER;
|
|
314
307
|
}
|
|
315
308
|
return normalized;
|
|
316
309
|
})
|
|
317
|
-
.pipe(z.url());
|
|
310
|
+
.pipe(z.string().url()));
|
|
318
311
|
return nullable ? z.union([schema, nullable]) : schema;
|
|
319
312
|
}
|
|
320
313
|
default:
|
|
@@ -371,95 +364,21 @@ function makeDetail(field, expected, received) {
|
|
|
371
364
|
function isIsoDateString(value) {
|
|
372
365
|
if (!/^\d{4}-\d{2}-\d{2}/.test(value))
|
|
373
366
|
return false;
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
? { ok: true, value: null }
|
|
380
|
-
: { ok: false, detail: makeDetail(alias, branch.type, rawValue) };
|
|
381
|
-
}
|
|
382
|
-
switch (branch.type) {
|
|
383
|
-
case 'text': {
|
|
384
|
-
if (!stringSchema.safeParse(rawValue).success) {
|
|
385
|
-
return { ok: false, detail: makeDetail(alias, 'string', rawValue) };
|
|
386
|
-
}
|
|
387
|
-
const sanitized = sanitizePlainString(rawValue);
|
|
388
|
-
if (sanitized.length > options.maxTextLength) {
|
|
389
|
-
return { ok: false, detail: makeDetail(alias, `string(max:${options.maxTextLength})`, rawValue) };
|
|
390
|
-
}
|
|
391
|
-
return { ok: true, value: sanitized };
|
|
392
|
-
}
|
|
393
|
-
case 'richtext': {
|
|
394
|
-
const sanitized = sanitizeRichtext(rawValue);
|
|
395
|
-
if (!sanitized.valid) {
|
|
396
|
-
return { ok: false, detail: makeDetail(alias, 'richtext-json|string', rawValue) };
|
|
397
|
-
}
|
|
398
|
-
if (sanitized.size > options.maxTextLength) {
|
|
399
|
-
return {
|
|
400
|
-
ok: false,
|
|
401
|
-
detail: makeDetail(alias, `richtext(max:${options.maxTextLength})`, rawValue),
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
return { ok: true, value: sanitized.value, dangerous: sanitized.dangerous };
|
|
405
|
-
}
|
|
406
|
-
case 'number': {
|
|
407
|
-
if (!finiteNumberSchema.safeParse(rawValue).success) {
|
|
408
|
-
return { ok: false, detail: makeDetail(alias, 'number', rawValue) };
|
|
409
|
-
}
|
|
410
|
-
return { ok: true, value: rawValue };
|
|
411
|
-
}
|
|
412
|
-
case 'boolean': {
|
|
413
|
-
if (!booleanSchema.safeParse(rawValue).success) {
|
|
414
|
-
return { ok: false, detail: makeDetail(alias, 'boolean', rawValue) };
|
|
415
|
-
}
|
|
416
|
-
return { ok: true, value: rawValue };
|
|
417
|
-
}
|
|
418
|
-
case 'date': {
|
|
419
|
-
if (!stringSchema.safeParse(rawValue).success) {
|
|
420
|
-
return { ok: false, detail: makeDetail(alias, 'date(ISO)', rawValue) };
|
|
421
|
-
}
|
|
422
|
-
const value = sanitizePlainString(rawValue);
|
|
423
|
-
if (!isIsoDateString(value)) {
|
|
424
|
-
return { ok: false, detail: makeDetail(alias, 'date(ISO)', rawValue) };
|
|
425
|
-
}
|
|
426
|
-
return { ok: true, value };
|
|
427
|
-
}
|
|
428
|
-
case 'json':
|
|
429
|
-
case 'tags': {
|
|
430
|
-
const isValidJsonLike = (typeof rawValue === 'object' && rawValue !== null) || Array.isArray(rawValue);
|
|
431
|
-
if (!isValidJsonLike || typeof rawValue === 'string') {
|
|
432
|
-
return { ok: false, detail: makeDetail(alias, 'object|array', rawValue) };
|
|
433
|
-
}
|
|
434
|
-
return { ok: true, value: rawValue };
|
|
435
|
-
}
|
|
436
|
-
case 'file': {
|
|
437
|
-
if (isAssetListBranch(branch)) {
|
|
438
|
-
const listValue = normalizeAssetListValue(rawValue);
|
|
439
|
-
if (!listValue) {
|
|
440
|
-
return { ok: false, detail: makeDetail(alias, 'url-string[]', rawValue) };
|
|
441
|
-
}
|
|
442
|
-
return { ok: true, value: listValue };
|
|
443
|
-
}
|
|
444
|
-
const singleUrl = normalizeHttpUrl(rawValue);
|
|
445
|
-
if (!singleUrl) {
|
|
446
|
-
return { ok: false, detail: makeDetail(alias, 'url-string', rawValue) };
|
|
447
|
-
}
|
|
448
|
-
return { ok: true, value: singleUrl };
|
|
449
|
-
}
|
|
450
|
-
default:
|
|
451
|
-
throw new Error(`Unhandled branch type: ${branch.type}`);
|
|
452
|
-
}
|
|
367
|
+
const parsed = Date.parse(value);
|
|
368
|
+
if (Number.isNaN(parsed))
|
|
369
|
+
return false;
|
|
370
|
+
const d = new Date(parsed);
|
|
371
|
+
return d.toISOString().startsWith(value.substring(0, 10));
|
|
453
372
|
}
|
|
454
373
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
374
|
+
* Common foundation for schema-driven validation and sanitization of payloads.
|
|
375
|
+
* Used by the Public API and reusable in the Botanical Engine.
|
|
457
376
|
*
|
|
458
|
-
*
|
|
377
|
+
* Mandatory execution order at the time of writing:
|
|
459
378
|
* validate raw → hash (privacy policy) → store
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
379
|
+
* Hashing occurs AFTER validation, not before.
|
|
380
|
+
* This ensures that the validated value is the original raw value,
|
|
381
|
+
* not the digest — avoiding false failures on fields with formats (e.g., email).
|
|
463
382
|
*/
|
|
464
383
|
export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
|
|
465
384
|
const normalizedOptions = {
|
|
@@ -508,6 +427,9 @@ export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
|
|
|
508
427
|
}
|
|
509
428
|
continue;
|
|
510
429
|
}
|
|
430
|
+
if (issue.message === 'Required' && normalizedOptions.enforceRequiredFields) {
|
|
431
|
+
continue; // Let enforceRequiredFields logic below handle it properly with detailed messages
|
|
432
|
+
}
|
|
511
433
|
const field = String(issue.path[0] ?? 'payload');
|
|
512
434
|
const receivedValue = filteredPayload[field];
|
|
513
435
|
const expected = typeof issue.message === 'string' && issue.message.startsWith('Expected ')
|
|
@@ -535,7 +457,8 @@ export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
|
|
|
535
457
|
});
|
|
536
458
|
continue;
|
|
537
459
|
}
|
|
538
|
-
|
|
460
|
+
const valueToCheck = parsed.success ? data[branch.alias] : filteredPayload[branch.alias];
|
|
461
|
+
if (isMissingRequiredValue(valueToCheck)) {
|
|
539
462
|
requiredFieldsMissing.push(branch.alias);
|
|
540
463
|
details.push({
|
|
541
464
|
field: branch.alias,
|
|
@@ -564,7 +487,7 @@ export function validateAndSanitizeSeedPayload(seed, payload, options = {}) {
|
|
|
564
487
|
};
|
|
565
488
|
}
|
|
566
489
|
/**
|
|
567
|
-
*
|
|
490
|
+
* Validates content status supported by the CMS.
|
|
568
491
|
*/
|
|
569
492
|
export function isValidContentStatus(value) {
|
|
570
493
|
return statusSchema.safeParse(value).success;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { Seed } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Discriminated union describing the aggregate to compute over a content table.
|
|
4
|
+
*
|
|
5
|
+
* The widget routes accept this shape from the dashboard. Implementations are
|
|
6
|
+
* responsible for translating each variant into a safe SQL expression and must
|
|
7
|
+
* never interpolate the column or value fields without prior validation.
|
|
8
|
+
*/
|
|
9
|
+
export type AggregateFormula = {
|
|
10
|
+
op: 'count';
|
|
11
|
+
} | {
|
|
12
|
+
op: 'sum';
|
|
13
|
+
column: string;
|
|
14
|
+
} | {
|
|
15
|
+
op: 'avg';
|
|
16
|
+
column: string;
|
|
17
|
+
} | {
|
|
18
|
+
op: 'min';
|
|
19
|
+
column: string;
|
|
20
|
+
} | {
|
|
21
|
+
op: 'max';
|
|
22
|
+
column: string;
|
|
23
|
+
} | {
|
|
24
|
+
op: 'countWhere';
|
|
25
|
+
column: string;
|
|
26
|
+
value: unknown;
|
|
27
|
+
} | {
|
|
28
|
+
op: 'percentageOf';
|
|
29
|
+
numeratorColumn: string;
|
|
30
|
+
denominatorColumn: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Time range applied as a WHERE filter for widget queries.
|
|
34
|
+
*
|
|
35
|
+
* "all" means no temporal restriction. The other values bracket the most recent
|
|
36
|
+
* 7 days, 1 month, and 1 year respectively, anchored on `created_at`.
|
|
37
|
+
*/
|
|
38
|
+
export type TimeWindow = 'week' | 'month' | 'year' | 'all';
|
|
39
|
+
export interface LeaderboardEntry {
|
|
40
|
+
id: string;
|
|
41
|
+
label: string;
|
|
42
|
+
score: number | string;
|
|
43
|
+
}
|
|
44
|
+
export interface LeaderboardOptions {
|
|
45
|
+
scoreColumn: string;
|
|
46
|
+
limit: number;
|
|
47
|
+
orderDirection: 'ASC' | 'DESC';
|
|
48
|
+
}
|
|
49
|
+
export interface TimeseriesPoint {
|
|
50
|
+
label: string;
|
|
51
|
+
value: number;
|
|
52
|
+
}
|
|
53
|
+
export interface WidgetListFilter {
|
|
54
|
+
column: string;
|
|
55
|
+
op: string;
|
|
56
|
+
value: unknown;
|
|
57
|
+
}
|
|
58
|
+
export interface WidgetListOptions {
|
|
59
|
+
limit: number;
|
|
60
|
+
offset: number;
|
|
61
|
+
search?: string;
|
|
62
|
+
filters?: WidgetListFilter[];
|
|
63
|
+
orderByColumn?: string;
|
|
64
|
+
orderDirection?: 'ASC' | 'DESC';
|
|
65
|
+
}
|
|
66
|
+
export interface WidgetListResult {
|
|
67
|
+
entries: Array<Record<string, unknown>>;
|
|
68
|
+
totalCount: number;
|
|
69
|
+
}
|
|
70
|
+
export interface GrowthResult {
|
|
71
|
+
currentValue: number;
|
|
72
|
+
previousValue: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Read-only data access contract for widget routes.
|
|
76
|
+
*
|
|
77
|
+
* Implementations must validate every column alias derived from user input
|
|
78
|
+
* against the seed before composing SQL, and must bind every user-supplied
|
|
79
|
+
* value via parameterised statements. SQL keywords (ORDER direction, aggregate
|
|
80
|
+
* function names) must be selected via hardcoded branches, never interpolated.
|
|
81
|
+
*/
|
|
82
|
+
export interface IWidgetRepository {
|
|
83
|
+
/**
|
|
84
|
+
* Returns the formula result for the given time window. Always returns a
|
|
85
|
+
* number; implementations must return 0 when the query produces no rows.
|
|
86
|
+
*/
|
|
87
|
+
aggregate(seed: Seed, formula: AggregateFormula, window: TimeWindow): Promise<number>;
|
|
88
|
+
/**
|
|
89
|
+
* Evaluates the formula twice — once for the current window period and once
|
|
90
|
+
* for the equivalent previous period — to support trend calculations.
|
|
91
|
+
* Implementations must return { currentValue: 0, previousValue: 0 } on
|
|
92
|
+
* empty results.
|
|
93
|
+
*/
|
|
94
|
+
growth(seed: Seed, formula: AggregateFormula, window: TimeWindow): Promise<GrowthResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Returns entries sorted by scoreColumn, excluding nulls. label resolves
|
|
97
|
+
* from seed.displayNameAlias; falls back to id when not set.
|
|
98
|
+
*/
|
|
99
|
+
leaderboard(seed: Seed, options: LeaderboardOptions): Promise<LeaderboardEntry[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Paginated read of content entries. Filters and search are applied
|
|
102
|
+
* server-side. The caller is responsible for deserialising branch values
|
|
103
|
+
* from the raw Record.
|
|
104
|
+
*/
|
|
105
|
+
list(seed: Seed, options: WidgetListOptions): Promise<WidgetListResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Groups entries by a date bucket derived from groupColumn and aggregates
|
|
108
|
+
* the formula. Days with no entries are omitted (no zero-fill). Points are
|
|
109
|
+
* ordered ascending by label.
|
|
110
|
+
*/
|
|
111
|
+
timeseries(seed: Seed, formula: AggregateFormula, window: TimeWindow, groupColumn: string): Promise<TimeseriesPoint[]>;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=widget.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.repository.d.ts","sourceRoot":"","sources":["../../src/widget/widget.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beechcms/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -18,18 +18,24 @@
|
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"dev": "tsc -w --preserveWatchOutput",
|
|
20
20
|
"lint": "eslint .",
|
|
21
|
-
"type-check": "tsc --noEmit"
|
|
21
|
+
"type-check": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:coverage": "vitest run --coverage"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
27
|
+
"vitest": "^3.2.4"
|
|
22
28
|
},
|
|
23
29
|
"dependencies": {
|
|
24
30
|
"@tiptap/core": "^3.22.3",
|
|
25
31
|
"@tiptap/extension-highlight": "^3.22.3",
|
|
26
32
|
"@tiptap/extension-image": "^3.22.3",
|
|
27
33
|
"@tiptap/extension-link": "^3.22.3",
|
|
34
|
+
"@tiptap/extension-mathematics": "^3.22.3",
|
|
28
35
|
"@tiptap/extension-subscript": "^3.22.3",
|
|
29
36
|
"@tiptap/extension-superscript": "^3.22.3",
|
|
30
37
|
"@tiptap/extension-table": "^3.22.3",
|
|
31
38
|
"@tiptap/extension-text-align": "^3.22.3",
|
|
32
|
-
"@tiptap/extension-mathematics": "^3.22.3",
|
|
33
39
|
"@tiptap/html": "^3.22.3",
|
|
34
40
|
"@tiptap/starter-kit": "^3.22.3",
|
|
35
41
|
"katex": "^0.16.11",
|