@cristianormazabal/triton-core 0.1.11 → 0.1.13

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.
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Theme Discovery Utility — src/theme/discover.ts
3
+ *
4
+ * Scans directories for `.triton-theme.json` files, validates them, resolves
5
+ * them over their declared base preset, and returns a name→ResolvedTheme
6
+ * registry.
7
+ *
8
+ * ⚠️ This module performs filesystem I/O (node:fs / node:path).
9
+ * It MUST NOT be imported from src/index.ts or src/frontend/index.ts.
10
+ * Hosts (VS Code extension, triton-latex CLI) consume it by relative path:
11
+ * import { discoverThemes } from '../../src/theme/discover.js'
12
+ */
13
+ import type { ResolvedTheme } from '../contracts/theme.js';
14
+ import { type Result } from '../contracts/result.js';
15
+ export interface ThemeDiscoveryResult {
16
+ /** Resolved themes keyed by name (declared `name` field or filename-derived). */
17
+ readonly themes: ReadonlyMap<string, ResolvedTheme>;
18
+ /** Human-readable warnings for skipped/invalid files. Never throws. */
19
+ readonly warnings: readonly string[];
20
+ }
21
+ /**
22
+ * Load, validate, and resolve a single `.triton-theme.json` file.
23
+ *
24
+ * Returns ok(ResolvedTheme) on success, err(...) on any failure.
25
+ * Never throws.
26
+ */
27
+ export declare function loadThemeFile(filePath: string): Result<ResolvedTheme>;
28
+ /**
29
+ * Scan `dir` for all `.triton-theme.json` files, load and resolve each one,
30
+ * and return a name→ResolvedTheme map plus any warnings for skipped files.
31
+ *
32
+ * Rules (Cristian's decisions):
33
+ * - Name = the theme's `name` field if present; else derived from filename.
34
+ * - Derived name must satisfy slug rule; if not → warning + skipped.
35
+ * - If name is a built-in preset name → warning + skipped (no shadowing).
36
+ * - Duplicate custom name within same dir → last wins + warning.
37
+ * - Errors (bad JSON, validation failure) → warning + skipped. Never throws.
38
+ */
39
+ export declare function discoverThemes(dir: string): ThemeDiscoveryResult;
40
+ /**
41
+ * Walk up from `startDir` looking for a `.triton/themes/` directory.
42
+ * Returns its absolute path when found, or undefined if not found.
43
+ *
44
+ * Stops at the filesystem root or after 10 levels (infinite-loop guard).
45
+ */
46
+ export declare function findTritonThemesDir(startDir: string): string | undefined;
47
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../../../src/theme/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAO9D,MAAM,WAAW,oBAAoB;IACnC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpD,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAcD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,CAkCrE;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAuDhE;AAiBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBxE"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Theme Discovery Utility — src/theme/discover.ts
3
+ *
4
+ * Scans directories for `.triton-theme.json` files, validates them, resolves
5
+ * them over their declared base preset, and returns a name→ResolvedTheme
6
+ * registry.
7
+ *
8
+ * ⚠️ This module performs filesystem I/O (node:fs / node:path).
9
+ * It MUST NOT be imported from src/index.ts or src/frontend/index.ts.
10
+ * Hosts (VS Code extension, triton-latex CLI) consume it by relative path:
11
+ * import { discoverThemes } from '../../src/theme/discover.js'
12
+ */
13
+ import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
14
+ import { join, basename, resolve } from 'node:path';
15
+ import { ok, err } from '../contracts/result.js';
16
+ import { validateThemeInput, isBuiltinThemeName } from './validate.js';
17
+ import { resolveTheme } from './resolver.js';
18
+ import { getThemePreset } from './preset.js';
19
+ // ─── Name derivation ──────────────────────────────────────────────────────────
20
+ const THEME_SUFFIX = '.triton-theme.json';
21
+ const SLUG = /^[a-z0-9-]+$/;
22
+ /** Strip `.triton-theme.json` from a filename to derive a theme name. */
23
+ function deriveNameFromFilename(filename) {
24
+ return basename(filename, THEME_SUFFIX);
25
+ }
26
+ // ─── loadThemeFile ────────────────────────────────────────────────────────────
27
+ /**
28
+ * Load, validate, and resolve a single `.triton-theme.json` file.
29
+ *
30
+ * Returns ok(ResolvedTheme) on success, err(...) on any failure.
31
+ * Never throws.
32
+ */
33
+ export function loadThemeFile(filePath) {
34
+ // 1. Read file
35
+ let raw;
36
+ try {
37
+ raw = readFileSync(filePath, 'utf8');
38
+ }
39
+ catch (cause) {
40
+ return err('THEME_VALIDATION_ERROR', `Cannot read theme file "${filePath}": ${String(cause)}`, cause);
41
+ }
42
+ // 2. Parse JSON
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(raw);
46
+ }
47
+ catch (cause) {
48
+ return err('THEME_VALIDATION_ERROR', `Invalid JSON in theme file "${filePath}": ${String(cause)}`, cause);
49
+ }
50
+ // 3. Validate against ThemeInput schema (strict — unknown keys are errors)
51
+ const validated = validateThemeInput(parsed);
52
+ if (!validated.ok) {
53
+ return err('THEME_VALIDATION_ERROR', `Theme file "${filePath}" failed validation: ${validated.error.message}`, validated.error);
54
+ }
55
+ // 4. Resolve over declared base (or 'default' if absent)
56
+ const input = validated.value;
57
+ const baseName = parsed['base'] ?? 'default';
58
+ const base = getThemePreset(baseName);
59
+ const resolved = resolveTheme(input, base);
60
+ return ok(resolved);
61
+ }
62
+ // ─── discoverThemes ───────────────────────────────────────────────────────────
63
+ /**
64
+ * Scan `dir` for all `.triton-theme.json` files, load and resolve each one,
65
+ * and return a name→ResolvedTheme map plus any warnings for skipped files.
66
+ *
67
+ * Rules (Cristian's decisions):
68
+ * - Name = the theme's `name` field if present; else derived from filename.
69
+ * - Derived name must satisfy slug rule; if not → warning + skipped.
70
+ * - If name is a built-in preset name → warning + skipped (no shadowing).
71
+ * - Duplicate custom name within same dir → last wins + warning.
72
+ * - Errors (bad JSON, validation failure) → warning + skipped. Never throws.
73
+ */
74
+ export function discoverThemes(dir) {
75
+ const themes = new Map();
76
+ const warnings = [];
77
+ // Gracefully handle missing / unreadable directory
78
+ let entries;
79
+ try {
80
+ entries = readdirSync(dir);
81
+ }
82
+ catch (cause) {
83
+ warnings.push(`Cannot read themes directory "${dir}": ${String(cause)}`);
84
+ return { themes, warnings };
85
+ }
86
+ const themeFiles = entries.filter(e => e.endsWith(THEME_SUFFIX));
87
+ for (const filename of themeFiles) {
88
+ const filePath = join(dir, filename);
89
+ // Load + validate + resolve
90
+ const result = loadThemeFile(filePath);
91
+ if (!result.ok) {
92
+ warnings.push(result.error.message);
93
+ continue;
94
+ }
95
+ const resolved = result.value;
96
+ // Determine registered name:
97
+ // - declared `name` field in the file → use it (already validated as a slug)
98
+ // - no `name` field → derive from filename
99
+ // We re-read the raw name field here rather than relying on resolved.name,
100
+ // because resolveTheme always fills name from the base preset when absent.
101
+ const name = extractNameFromFile(filePath) ?? deriveNameFromFilename(filename);
102
+ // Validate slug rule on derived name
103
+ if (!SLUG.test(name)) {
104
+ warnings.push(`Theme file "${filename}": derived name "${name}" is not a valid slug (^[a-z0-9-]+$); skipped`);
105
+ continue;
106
+ }
107
+ // Built-in collision check
108
+ if (isBuiltinThemeName(name)) {
109
+ warnings.push(`Theme "${name}" shadows a built-in preset; skipped`);
110
+ continue;
111
+ }
112
+ // Duplicate within same dir → last wins + warning
113
+ if (themes.has(name)) {
114
+ warnings.push(`Duplicate theme name "${name}": "${filename}" overrides an earlier definition`);
115
+ }
116
+ themes.set(name, resolved);
117
+ }
118
+ return { themes, warnings };
119
+ }
120
+ // ─── extractNameFromFile ──────────────────────────────────────────────────────
121
+ /** Read the `name` field directly from the raw JSON (returns null if absent or unreadable). */
122
+ function extractNameFromFile(filePath) {
123
+ try {
124
+ const raw = readFileSync(filePath, 'utf8');
125
+ const parsed = JSON.parse(raw);
126
+ return typeof parsed['name'] === 'string' ? parsed['name'] : null;
127
+ }
128
+ catch {
129
+ return null;
130
+ }
131
+ }
132
+ // ─── findTritonThemesDir ──────────────────────────────────────────────────────
133
+ /**
134
+ * Walk up from `startDir` looking for a `.triton/themes/` directory.
135
+ * Returns its absolute path when found, or undefined if not found.
136
+ *
137
+ * Stops at the filesystem root or after 10 levels (infinite-loop guard).
138
+ */
139
+ export function findTritonThemesDir(startDir) {
140
+ const MAX_LEVELS = 10;
141
+ let current = resolve(startDir);
142
+ for (let level = 0; level < MAX_LEVELS; level++) {
143
+ const candidate = join(current, '.triton', 'themes');
144
+ try {
145
+ if (existsSync(candidate) && statSync(candidate).isDirectory()) {
146
+ return candidate;
147
+ }
148
+ }
149
+ catch {
150
+ // permission error or similar — keep walking up
151
+ }
152
+ const parent = resolve(join(current, '..'));
153
+ if (parent === current)
154
+ break; // filesystem root
155
+ current = parent;
156
+ }
157
+ return undefined;
158
+ }
159
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../../src/theme/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * validateThemeInput
3
+ *
4
+ * Pure validator for external `.triton-theme.json` files. No file or network
5
+ * I/O — only validates an already-parsed JSON value against the ThemeInput
6
+ * contract. Returns a Result so callers never need try/catch.
7
+ *
8
+ * Policy (Cristian's decision): unknown keys at any level are a HARD ERROR,
9
+ * not a warning. This catches typos early and keeps the schema unambiguous.
10
+ */
11
+ import type { ThemeInput } from '../contracts/theme.js';
12
+ import { type Result } from '../contracts/result.js';
13
+ /** Returns true iff `name` is one of the built-in preset names. */
14
+ export declare function isBuiltinThemeName(name: string): boolean;
15
+ /**
16
+ * Validate an unknown value against the ThemeInput contract.
17
+ *
18
+ * Pure and synchronous — never throws, never reads files.
19
+ * Returns ok(ThemeInput) on success, err(...) on any violation.
20
+ */
21
+ export declare function validateThemeInput(json: unknown): Result<ThemeInput>;
22
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/theme/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAK9D,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAwKD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAiEpE"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * validateThemeInput
3
+ *
4
+ * Pure validator for external `.triton-theme.json` files. No file or network
5
+ * I/O — only validates an already-parsed JSON value against the ThemeInput
6
+ * contract. Returns a Result so callers never need try/catch.
7
+ *
8
+ * Policy (Cristian's decision): unknown keys at any level are a HARD ERROR,
9
+ * not a warning. This catches typos early and keeps the schema unambiguous.
10
+ */
11
+ import { ok, err } from '../contracts/result.js';
12
+ import { themePresetNames } from './preset.js';
13
+ // ─── isBuiltinThemeName ───────────────────────────────────────────────────────
14
+ /** Returns true iff `name` is one of the built-in preset names. */
15
+ export function isBuiltinThemeName(name) {
16
+ return themePresetNames.includes(name);
17
+ }
18
+ // ─── Known key sets ───────────────────────────────────────────────────────────
19
+ const TOP_LEVEL_KEYS = new Set([
20
+ 'name', 'base', 'palette', 'typography', 'spacing', 'edges', 'panel',
21
+ ]);
22
+ const PALETTE_KEYS = new Set([
23
+ 'primary', 'secondary', 'background', 'surface', 'border',
24
+ 'text', 'textMuted', 'success', 'warning', 'error',
25
+ ]);
26
+ const TYPOGRAPHY_KEYS = new Set([
27
+ 'fontFamily', 'monoFamily', 'baseFontSize', 'titleFontSize', 'smallFontSize', 'lineHeight',
28
+ ]);
29
+ const SPACING_KEYS = new Set([
30
+ 'unit', 'nodePadding', 'nodeGap', 'diagramMargin',
31
+ ]);
32
+ const EDGES_KEYS = new Set([
33
+ 'strokeWidth', 'arrowSize', 'labelFontSize', 'curveTension',
34
+ ]);
35
+ const PANEL_KEYS = new Set([
36
+ 'titleAlign', 'titlePosition', 'titleChrome',
37
+ ]);
38
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
39
+ const HEX_COLOR = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
40
+ const SLUG = /^[a-z0-9-]+$/;
41
+ const CSS_INJECTION = /url\s*\(|expression\s*\(/i;
42
+ function isPlainObject(v) {
43
+ return v !== null && typeof v === 'object' && !Array.isArray(v);
44
+ }
45
+ function fail(message) {
46
+ return err('THEME_VALIDATION_ERROR', message);
47
+ }
48
+ // ─── Group validators ─────────────────────────────────────────────────────────
49
+ function validatePalette(obj) {
50
+ if (!isPlainObject(obj))
51
+ return fail('"palette" must be a plain object');
52
+ for (const key of Object.keys(obj)) {
53
+ if (!PALETTE_KEYS.has(key))
54
+ return fail(`Unknown key in palette: "${key}"`);
55
+ }
56
+ for (const key of Object.keys(obj)) {
57
+ const val = obj[key];
58
+ if (typeof val !== 'string' || !HEX_COLOR.test(val)) {
59
+ return fail(`palette.${key} must be a CSS hex color (e.g. "#RGB" or "#RRGGBB"), got ${JSON.stringify(val)}`);
60
+ }
61
+ }
62
+ return ok(obj);
63
+ }
64
+ function validateTypography(obj) {
65
+ if (!isPlainObject(obj))
66
+ return fail('"typography" must be a plain object');
67
+ for (const key of Object.keys(obj)) {
68
+ if (!TYPOGRAPHY_KEYS.has(key))
69
+ return fail(`Unknown key in typography: "${key}"`);
70
+ }
71
+ const stringFields = ['fontFamily', 'monoFamily'];
72
+ for (const key of stringFields) {
73
+ if (key in obj) {
74
+ const val = obj[key];
75
+ if (typeof val !== 'string')
76
+ return fail(`typography.${key} must be a string`);
77
+ if (CSS_INJECTION.test(val))
78
+ return fail(`typography.${key} contains disallowed CSS expression`);
79
+ }
80
+ }
81
+ const positiveFields = ['baseFontSize', 'titleFontSize', 'smallFontSize', 'lineHeight'];
82
+ for (const key of positiveFields) {
83
+ if (key in obj) {
84
+ const val = obj[key];
85
+ if (typeof val !== 'number' || val <= 0) {
86
+ return fail(`typography.${key} must be a positive number, got ${JSON.stringify(val)}`);
87
+ }
88
+ }
89
+ }
90
+ return ok(obj);
91
+ }
92
+ function validateSpacing(obj) {
93
+ if (!isPlainObject(obj))
94
+ return fail('"spacing" must be a plain object');
95
+ for (const key of Object.keys(obj)) {
96
+ if (!SPACING_KEYS.has(key))
97
+ return fail(`Unknown key in spacing: "${key}"`);
98
+ }
99
+ for (const key of Object.keys(obj)) {
100
+ const val = obj[key];
101
+ if (typeof val !== 'number' || val < 0) {
102
+ return fail(`spacing.${key} must be a non-negative number, got ${JSON.stringify(val)}`);
103
+ }
104
+ }
105
+ return ok(obj);
106
+ }
107
+ function validateEdges(obj) {
108
+ if (!isPlainObject(obj))
109
+ return fail('"edges" must be a plain object');
110
+ for (const key of Object.keys(obj)) {
111
+ if (!EDGES_KEYS.has(key))
112
+ return fail(`Unknown key in edges: "${key}"`);
113
+ }
114
+ const nonNegativeFields = ['strokeWidth', 'arrowSize', 'labelFontSize'];
115
+ for (const key of nonNegativeFields) {
116
+ if (key in obj) {
117
+ const val = obj[key];
118
+ if (typeof val !== 'number' || val < 0) {
119
+ return fail(`edges.${key} must be a non-negative number, got ${JSON.stringify(val)}`);
120
+ }
121
+ }
122
+ }
123
+ if ('curveTension' in obj) {
124
+ const val = obj['curveTension'];
125
+ if (typeof val !== 'number' || val < 0 || val > 1) {
126
+ return fail(`edges.curveTension must be a number between 0 and 1, got ${JSON.stringify(val)}`);
127
+ }
128
+ }
129
+ return ok(obj);
130
+ }
131
+ function validatePanel(obj) {
132
+ if (!isPlainObject(obj))
133
+ return fail('"panel" must be a plain object');
134
+ for (const key of Object.keys(obj)) {
135
+ if (!PANEL_KEYS.has(key))
136
+ return fail(`Unknown key in panel: "${key}"`);
137
+ }
138
+ if ('titleAlign' in obj) {
139
+ const val = obj['titleAlign'];
140
+ if (val !== 'left' && val !== 'center' && val !== 'right') {
141
+ return fail(`panel.titleAlign must be "left", "center", or "right", got ${JSON.stringify(val)}`);
142
+ }
143
+ }
144
+ if ('titlePosition' in obj) {
145
+ const val = obj['titlePosition'];
146
+ if (val !== 'inside' && val !== 'on-border' && val !== 'above') {
147
+ return fail(`panel.titlePosition must be "inside", "on-border", or "above", got ${JSON.stringify(val)}`);
148
+ }
149
+ }
150
+ if ('titleChrome' in obj) {
151
+ const val = obj['titleChrome'];
152
+ if (val !== 'none' && val !== 'box' && val !== 'pill') {
153
+ return fail(`panel.titleChrome must be "none", "box", or "pill", got ${JSON.stringify(val)}`);
154
+ }
155
+ }
156
+ return ok(obj);
157
+ }
158
+ // ─── Main validator ───────────────────────────────────────────────────────────
159
+ /**
160
+ * Validate an unknown value against the ThemeInput contract.
161
+ *
162
+ * Pure and synchronous — never throws, never reads files.
163
+ * Returns ok(ThemeInput) on success, err(...) on any violation.
164
+ */
165
+ export function validateThemeInput(json) {
166
+ if (!isPlainObject(json)) {
167
+ return fail(`ThemeInput must be a non-null plain object, got ${json === null ? 'null' : Array.isArray(json) ? 'array' : typeof json}`);
168
+ }
169
+ // Strict unknown-key check at top level
170
+ for (const key of Object.keys(json)) {
171
+ if (!TOP_LEVEL_KEYS.has(key))
172
+ return fail(`Unknown top-level key: "${key}"`);
173
+ }
174
+ const result = {};
175
+ // name
176
+ if ('name' in json) {
177
+ const v = json['name'];
178
+ if (typeof v !== 'string')
179
+ return fail(`"name" must be a string, got ${JSON.stringify(v)}`);
180
+ if (v.length < 1 || v.length > 64)
181
+ return fail(`"name" must be 1–64 characters, got length ${v.length}`);
182
+ if (!SLUG.test(v))
183
+ return fail(`"name" must match ^[a-z0-9-]+$, got ${JSON.stringify(v)}`);
184
+ result['name'] = v;
185
+ }
186
+ // base
187
+ if ('base' in json) {
188
+ const v = json['base'];
189
+ if (typeof v !== 'string')
190
+ return fail(`"base" must be a string, got ${JSON.stringify(v)}`);
191
+ if (!isBuiltinThemeName(v))
192
+ return fail(`"base" must be a built-in preset name; "${v}" is not recognised`);
193
+ result['base'] = v;
194
+ }
195
+ // palette
196
+ if ('palette' in json) {
197
+ const r = validatePalette(json['palette']);
198
+ if (!r.ok)
199
+ return r;
200
+ result['palette'] = r.value;
201
+ }
202
+ // typography
203
+ if ('typography' in json) {
204
+ const r = validateTypography(json['typography']);
205
+ if (!r.ok)
206
+ return r;
207
+ result['typography'] = r.value;
208
+ }
209
+ // spacing
210
+ if ('spacing' in json) {
211
+ const r = validateSpacing(json['spacing']);
212
+ if (!r.ok)
213
+ return r;
214
+ result['spacing'] = r.value;
215
+ }
216
+ // edges
217
+ if ('edges' in json) {
218
+ const r = validateEdges(json['edges']);
219
+ if (!r.ok)
220
+ return r;
221
+ result['edges'] = r.value;
222
+ }
223
+ // panel
224
+ if ('panel' in json) {
225
+ const r = validatePanel(json['panel']);
226
+ if (!r.ok)
227
+ return r;
228
+ result['panel'] = r.value;
229
+ }
230
+ return ok(result);
231
+ }
232
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/theme/validate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cristianormazabal/triton-core",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Triton diagram compiler — deterministic SVG rendering for 50+ diagram types (Mermaid-compatible, trees, data structures, posters).",
5
5
  "type": "module",
6
6
  "license": "MIT",