@codependix/file-imports 0.0.0-stage → 0.0.4

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,461 @@
1
+ import { Injectable as e, Module as t } from "@nestjs/common";
2
+ import { existsSync as n, readFileSync as r, readdirSync as i } from "node:fs";
3
+ import a from "node:path";
4
+ import o from "typescript";
5
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/file-imports-workspace-graph/file-imports-workspace-graph.constants.ts
6
+ var s = "_This workspace has no internal file imports, in any project._", c = "graph LR";
7
+ //#endregion
8
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
9
+ function l(e, t) {
10
+ if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
11
+ }
12
+ //#endregion
13
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
14
+ function u(e, t, n, r) {
15
+ var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
16
+ if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
17
+ else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
18
+ return i > 3 && a && Object.defineProperty(t, n, a), a;
19
+ }
20
+ //#endregion
21
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/file-imports-workspace-graph/file-imports-workspace-graph.service.ts
22
+ var d = class {
23
+ constructor() {}
24
+ compareEdges(e, t) {
25
+ return e.source.localeCompare(t.source) || e.target.localeCompare(t.target);
26
+ }
27
+ qualifyFileName(e, t) {
28
+ return `${e}/${t}`;
29
+ }
30
+ renderNode(e) {
31
+ return ` ${this.toNodeIdentifier(e)}["${e}"]`;
32
+ }
33
+ sortNames(e) {
34
+ return [...e].toSorted((e, t) => e.localeCompare(t));
35
+ }
36
+ toNodeIdentifier(e) {
37
+ return `file_${e.replaceAll(/[^\dA-Za-z]/gu, "_")}`;
38
+ }
39
+ buildWorkspaceGraph(e) {
40
+ let t = [...e.typescriptGraphs, ...e.pythonGraphs], n = this.sortNames(t.flatMap((e) => e.fileNames.map((t) => this.qualifyFileName(e.projectName, t))));
41
+ return {
42
+ edges: t.flatMap((e) => e.edges.map((t) => ({
43
+ source: this.qualifyFileName(e.projectName, t.source),
44
+ target: this.qualifyFileName(e.projectName, t.target)
45
+ }))).toSorted((e, t) => this.compareEdges(e, t)),
46
+ fileNames: n
47
+ };
48
+ }
49
+ renderMermaid(e) {
50
+ return e.edges.length === 0 ? s : [
51
+ "```mermaid",
52
+ c,
53
+ ...e.fileNames.map((e) => this.renderNode(e)),
54
+ ...e.edges.map((e) => ` ${this.toNodeIdentifier(e.source)} --> ${this.toNodeIdentifier(e.target)}`),
55
+ "```"
56
+ ].join("\n");
57
+ }
58
+ };
59
+ d = u([e(), l("design:paramtypes", [])], d);
60
+ //#endregion
61
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/file-imports-workspace-graph/file-imports-workspace-graph.module.ts
62
+ var f = class {};
63
+ f = u([t({
64
+ controllers: [],
65
+ exports: [d],
66
+ imports: [],
67
+ providers: [d]
68
+ })], f);
69
+ //#endregion
70
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/python/python-import-parser.constants.ts
71
+ var p = /^from\s+(?<dots>\.*)(?<modulePath>[\w.]*)\s+import\s+.+$/u, m = /^import\s+(?<specifiers>.+)$/u, h = /^(?<modulePath>[\w.]+)/u, g = /^(?:from|import)\b/u, _ = class {
72
+ constructor() {}
73
+ collectStatement(e, t) {
74
+ let n = 0, r = [], i = t;
75
+ for (;;) {
76
+ /* v8 ignore next -- index only ever advances past the last checked
77
+ bound right before the loop breaks, so it is always in range here */
78
+ let t = this.stripComment(e[i] ?? "");
79
+ n += this.countCharacter(t, "(") - this.countCharacter(t, ")");
80
+ let a = t.trimEnd().endsWith("\\"), o = a ? t.trimEnd().slice(0, -1) : t;
81
+ if (r.push(o.trim()), i += 1, n <= 0 && !a || i >= e.length) break;
82
+ }
83
+ return {
84
+ nextIndex: i,
85
+ statement: r.join(" ")
86
+ };
87
+ }
88
+ countCharacter(e, t) {
89
+ return e.split(t).length - 1;
90
+ }
91
+ isTopLevelImportStart(e) {
92
+ return this.measureIndent(e) === 0 && g.test(this.stripComment(e).trim());
93
+ }
94
+ measureIndent(e) {
95
+ return e.length - e.trimStart().length;
96
+ }
97
+ parseFromStatement(e) {
98
+ let t = p.exec(e);
99
+ if (t?.groups === void 0) return [];
100
+ /* v8 ignore next 2 -- both named groups always participate in a
101
+ successful match, even as an empty string, so they are never undefined */
102
+ let n = t.groups.dots ?? "", r = t.groups.modulePath ?? "";
103
+ return [{
104
+ level: n.length,
105
+ modulePath: r
106
+ }];
107
+ }
108
+ parseImportStatement(e) {
109
+ let t = m.exec(e);
110
+ return t?.groups === void 0 ? [] : (t.groups.specifiers ?? "").split(",").map((e) => h.exec(e.trim())?.groups?.modulePath).filter((e) => e !== void 0).map((e) => ({
111
+ level: 0,
112
+ modulePath: e
113
+ }));
114
+ }
115
+ parseStatement(e) {
116
+ return e.startsWith("from") ? this.parseFromStatement(e) : this.parseImportStatement(e);
117
+ }
118
+ stripComment(e) {
119
+ let t;
120
+ for (let n = 0; n < e.length; n += 1) {
121
+ let r = e[n];
122
+ if (t !== void 0) {
123
+ r === t && e[n - 1] !== "\\" && (t = void 0);
124
+ continue;
125
+ }
126
+ if (r === "'" || r === "\"") {
127
+ t = r;
128
+ continue;
129
+ }
130
+ if (r === "#") return e.slice(0, n);
131
+ }
132
+ return e;
133
+ }
134
+ parseImportSpecifiers(e) {
135
+ let t = e.split("\n"), n = [], r = 0;
136
+ for (; r < t.length;) {
137
+ /* v8 ignore next -- the loop condition already guards index in range */
138
+ let e = t[r] ?? "";
139
+ if (!this.isTopLevelImportStart(e)) {
140
+ r += 1;
141
+ continue;
142
+ }
143
+ let { nextIndex: i, statement: a } = this.collectStatement(t, r);
144
+ n.push(...this.parseStatement(a)), r = i;
145
+ }
146
+ return n;
147
+ }
148
+ };
149
+ _ = u([e(), l("design:paramtypes", [])], _);
150
+ //#endregion
151
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/python/python.constants.ts
152
+ var v = "__init__.py", y = "graph LR", b = "_This project has no internal file imports._", x = /* @__PURE__ */ new Set([
153
+ ".git",
154
+ ".mypy_cache",
155
+ ".pytest_cache",
156
+ ".ruff_cache",
157
+ ".venv",
158
+ "__pycache__",
159
+ "node_modules"
160
+ ]), S = "language:python", C = class {
161
+ constructor() {}
162
+ listSourceFilesInDirectory(e) {
163
+ let t = [];
164
+ for (let n of i(e, { withFileTypes: !0 })) {
165
+ let r = a.join(e, n.name);
166
+ if (n.isDirectory()) {
167
+ if (x.has(n.name)) continue;
168
+ t.push(...this.listSourceFilesInDirectory(r));
169
+ } else n.name.endsWith(".py") && t.push(r);
170
+ }
171
+ return t;
172
+ }
173
+ describeProject(e, t) {
174
+ return {
175
+ absoluteRoot: e,
176
+ name: t
177
+ };
178
+ }
179
+ discoverProjects(e) {
180
+ return e.filter((e) => this.isPythonProject(e)).map((e) => this.describeProject(e.absoluteRoot, e.name));
181
+ }
182
+ isPythonProject(e) {
183
+ return e.tags.includes(S);
184
+ }
185
+ listSourceFileNames(e) {
186
+ return this.listSourceFilesInDirectory(e.absoluteRoot).toSorted((e, t) => e.localeCompare(t));
187
+ }
188
+ };
189
+ C = u([e(), l("design:paramtypes", [])], C);
190
+ //#endregion
191
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/python/python-import-graph.service.ts
192
+ var w = class {
193
+ pythonImportParserService;
194
+ pythonProjectService;
195
+ constructor(e, t) {
196
+ this.pythonImportParserService = e, this.pythonProjectService = t;
197
+ }
198
+ ascendDirectories(e, t) {
199
+ let n = e;
200
+ for (let e = 0; e < t; e += 1) n = a.dirname(n);
201
+ return n;
202
+ }
203
+ collectEdgesForFile(e) {
204
+ let { ownedFileNames: t, project: n, sourceFileName: i } = e, a = this.pythonImportParserService.parseImportSpecifiers(r(i, "utf8")), o = [];
205
+ for (let e of a) {
206
+ let r = this.resolveSpecifierPath({
207
+ containingFileName: i,
208
+ project: n,
209
+ specifier: e
210
+ });
211
+ r !== void 0 && t.has(r) && r !== i && o.push({
212
+ source: this.toRelativePath(n, i),
213
+ target: this.toRelativePath(n, r)
214
+ });
215
+ }
216
+ return o;
217
+ }
218
+ compareEdges(e, t) {
219
+ return e.source.localeCompare(t.source) || e.target.localeCompare(t.target);
220
+ }
221
+ dedupeEdges(e) {
222
+ let t = /* @__PURE__ */ new Map();
223
+ for (let n of e) t.set(`${n.source}->${n.target}`, n);
224
+ return [...t.values()].toSorted((e, t) => this.compareEdges(e, t));
225
+ }
226
+ renderNode(e) {
227
+ return ` ${this.toNodeIdentifier(e)}["${e}"]`;
228
+ }
229
+ resolveSpecifierPath(e) {
230
+ let { containingFileName: t, project: r, specifier: i } = e, o = i.level === 0 ? r.absoluteRoot : this.ascendDirectories(a.dirname(t), i.level - 1), s = i.modulePath.length === 0 ? [] : i.modulePath.split("."), c = a.join(o, ...s);
231
+ if (s.length > 0) {
232
+ let e = `${c}.py`;
233
+ if (n(e)) return e;
234
+ }
235
+ let l = a.join(c, v);
236
+ return n(l) ? l : void 0;
237
+ }
238
+ toNodeIdentifier(e) {
239
+ return `file_${e.replaceAll(/[^\dA-Za-z]/gu, "_")}`;
240
+ }
241
+ toRelativePath(e, t) {
242
+ return a.relative(e.absoluteRoot, t).split(a.sep).join("/");
243
+ }
244
+ buildGraph(e) {
245
+ let t = this.pythonProjectService.listSourceFileNames(e), n = new Set(t), r = this.dedupeEdges(t.flatMap((t) => this.collectEdgesForFile({
246
+ ownedFileNames: n,
247
+ project: e,
248
+ sourceFileName: t
249
+ }))), i = new Set(r.flatMap((e) => [e.source, e.target])), a = t.map((t) => this.toRelativePath(e, t)).toSorted((e, t) => e.localeCompare(t));
250
+ return {
251
+ edges: r,
252
+ fileNames: a,
253
+ isolatedFileNames: a.filter((e) => !i.has(e)),
254
+ projectName: e.name
255
+ };
256
+ }
257
+ renderMermaid(e) {
258
+ return e.edges.length === 0 ? b : [
259
+ "```mermaid",
260
+ y,
261
+ ...e.fileNames.map((e) => this.renderNode(e)),
262
+ ...e.edges.map((e) => ` ${this.toNodeIdentifier(e.source)} --> ${this.toNodeIdentifier(e.target)}`),
263
+ "```"
264
+ ].join("\n");
265
+ }
266
+ };
267
+ w = u([e(), l("design:paramtypes", [_ === void 0 ? Object : _, C === void 0 ? Object : C])], w);
268
+ //#endregion
269
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/python/python.service.ts
270
+ var T = class {
271
+ pythonImportGraphService;
272
+ pythonProjectService;
273
+ constructor(e, t) {
274
+ this.pythonImportGraphService = e, this.pythonProjectService = t;
275
+ }
276
+ buildGraph(e) {
277
+ return this.pythonImportGraphService.buildGraph(e);
278
+ }
279
+ discoverProjects(e) {
280
+ return this.pythonProjectService.discoverProjects(e);
281
+ }
282
+ renderMermaid(e) {
283
+ return this.pythonImportGraphService.renderMermaid(e);
284
+ }
285
+ };
286
+ T = u([e(), l("design:paramtypes", [w === void 0 ? Object : w, C === void 0 ? Object : C])], T);
287
+ //#endregion
288
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/python/python.module.ts
289
+ var E = class {};
290
+ E = u([t({
291
+ controllers: [],
292
+ exports: [T],
293
+ imports: [],
294
+ providers: [
295
+ w,
296
+ _,
297
+ C,
298
+ T
299
+ ]
300
+ })], E);
301
+ //#endregion
302
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/typescript/typescript.constants.ts
303
+ var D = ".d.ts", O = "graph LR", k = "_This project has no internal file imports._", A = "tsconfig.json", j = class extends Error {
304
+ constructor(e) {
305
+ super(`Could not read ${e.configurationPath}: ${e.messages.join("; ")}`), this.name = "TypescriptProjectConfigurationError";
306
+ }
307
+ }, M = class {
308
+ constructor() {}
309
+ parseConfiguration(e) {
310
+ let t = o.readJsonConfigFile(e.tsconfigPath, (e) => o.sys.readFile(e)), n = o.parseJsonSourceFileConfigFileContent(t, o.sys, a.dirname(e.tsconfigPath), void 0, e.tsconfigPath);
311
+ if (n.errors.length > 0) throw new j({
312
+ configurationPath: e.tsconfigPath,
313
+ messages: n.errors.map((e) => o.flattenDiagnosticMessageText(e.messageText, " "))
314
+ });
315
+ return n;
316
+ }
317
+ buildProgram(e) {
318
+ let t = this.parseConfiguration(e), n = o.createCompilerHost(t.options, !0), r = o.createProgram({
319
+ host: n,
320
+ options: t.options,
321
+ rootNames: t.fileNames
322
+ });
323
+ return {
324
+ host: n,
325
+ options: t.options,
326
+ program: r,
327
+ project: e
328
+ };
329
+ }
330
+ describeProject(e, t) {
331
+ return {
332
+ absoluteRoot: e,
333
+ name: t,
334
+ tsconfigPath: a.join(e, A)
335
+ };
336
+ }
337
+ discoverProjects(e) {
338
+ return e.filter((e) => n(a.join(e.absoluteRoot, A))).map((e) => this.describeProject(e.absoluteRoot, e.name));
339
+ }
340
+ toRealPath(e) {
341
+ return o.sys.realpath === void 0 ? e : o.sys.realpath(e);
342
+ }
343
+ };
344
+ M = u([e(), l("design:paramtypes", [])], M);
345
+ //#endregion
346
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/typescript/typescript-import-graph.service.ts
347
+ var N = class {
348
+ typescriptProjectService;
349
+ constructor(e) {
350
+ this.typescriptProjectService = e;
351
+ }
352
+ collectEdgesForFile(e) {
353
+ let { ownedFileNames: t, projectProgram: n, sourceFileName: r } = e, i = n.program.getSourceFile(r);
354
+ /* v8 ignore next -- sourceFileName always comes from this same program's
355
+ own root file names, so the program always has a source file for it */
356
+ if (i === void 0) return [];
357
+ let a = [];
358
+ for (let e of i.statements) {
359
+ /* v8 ignore next -- an ImportDeclaration's moduleSpecifier is always a
360
+ string literal by grammar; the guard only narrows the type */
361
+ if (!o.isImportDeclaration(e) || !o.isStringLiteral(e.moduleSpecifier)) continue;
362
+ let i = this.resolveImportTarget({
363
+ containingFileName: r,
364
+ projectProgram: n,
365
+ specifier: e.moduleSpecifier.text
366
+ });
367
+ i !== void 0 && t.has(i) && i !== r && a.push({
368
+ source: this.toRelativePath(n, r),
369
+ target: this.toRelativePath(n, i)
370
+ });
371
+ }
372
+ return a;
373
+ }
374
+ compareEdges(e, t) {
375
+ return e.source.localeCompare(t.source) || e.target.localeCompare(t.target);
376
+ }
377
+ dedupeEdges(e) {
378
+ let t = /* @__PURE__ */ new Map();
379
+ for (let n of e) t.set(`${n.source}->${n.target}`, n);
380
+ return [...t.values()].toSorted((e, t) => this.compareEdges(e, t));
381
+ }
382
+ listOwnedSourceFileNames(e) {
383
+ return [...this.resolveOwnedFileNames(e)].filter((e) => !e.endsWith(D)).toSorted((e, t) => e.localeCompare(t));
384
+ }
385
+ renderNode(e) {
386
+ return ` ${this.toNodeIdentifier(e)}["${e}"]`;
387
+ }
388
+ resolveImportTarget(e) {
389
+ let { containingFileName: t, projectProgram: n, specifier: r } = e, i = o.resolveModuleName(r, t, n.options, n.host).resolvedModule?.resolvedFileName;
390
+ return i === void 0 ? void 0 : this.typescriptProjectService.toRealPath(i);
391
+ }
392
+ resolveOwnedFileNames(e) {
393
+ return new Set(e.program.getRootFileNames().map((e) => this.typescriptProjectService.toRealPath(e)));
394
+ }
395
+ toNodeIdentifier(e) {
396
+ return `file_${e.replaceAll(/[^\dA-Za-z]/gu, "_")}`;
397
+ }
398
+ toRelativePath(e, t) {
399
+ return a.relative(e.project.absoluteRoot, t).split(a.sep).join("/");
400
+ }
401
+ buildGraph(e) {
402
+ let t = this.resolveOwnedFileNames(e), n = this.listOwnedSourceFileNames(e), r = this.dedupeEdges(n.flatMap((n) => this.collectEdgesForFile({
403
+ ownedFileNames: t,
404
+ projectProgram: e,
405
+ sourceFileName: n
406
+ }))), i = new Set(r.flatMap((e) => [e.source, e.target])), a = n.map((t) => this.toRelativePath(e, t)).toSorted((e, t) => e.localeCompare(t));
407
+ return {
408
+ edges: r,
409
+ fileNames: a,
410
+ isolatedFileNames: a.filter((e) => !i.has(e)),
411
+ projectName: e.project.name
412
+ };
413
+ }
414
+ renderMermaid(e) {
415
+ return e.edges.length === 0 ? k : [
416
+ "```mermaid",
417
+ O,
418
+ ...e.fileNames.map((e) => this.renderNode(e)),
419
+ ...e.edges.map((e) => ` ${this.toNodeIdentifier(e.source)} --> ${this.toNodeIdentifier(e.target)}`),
420
+ "```"
421
+ ].join("\n");
422
+ }
423
+ };
424
+ N = u([e(), l("design:paramtypes", [M === void 0 ? Object : M])], N);
425
+ //#endregion
426
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/typescript/typescript.service.ts
427
+ var P = class {
428
+ typescriptImportGraphService;
429
+ typescriptProjectService;
430
+ constructor(e, t) {
431
+ this.typescriptImportGraphService = e, this.typescriptProjectService = t;
432
+ }
433
+ buildGraph(e) {
434
+ return this.typescriptImportGraphService.buildGraph(e);
435
+ }
436
+ buildProgram(e) {
437
+ return this.typescriptProjectService.buildProgram(e);
438
+ }
439
+ discoverProjects(e) {
440
+ return this.typescriptProjectService.discoverProjects(e);
441
+ }
442
+ renderMermaid(e) {
443
+ return this.typescriptImportGraphService.renderMermaid(e);
444
+ }
445
+ };
446
+ P = u([e(), l("design:paramtypes", [N === void 0 ? Object : N, M === void 0 ? Object : M])], P);
447
+ //#endregion
448
+ //#region packages/ic-suite/codependix/codependix-file-imports/src/modules/typescript/typescript.module.ts
449
+ var F = class {};
450
+ F = u([t({
451
+ controllers: [],
452
+ exports: [P],
453
+ imports: [],
454
+ providers: [
455
+ N,
456
+ M,
457
+ P
458
+ ]
459
+ })], F);
460
+ //#endregion
461
+ export { c as FILE_IMPORTS_WORKSPACE_GRAPH_MERMAID_HEADER, s as FILE_IMPORTS_WORKSPACE_GRAPH_UNCONNECTED, f as FileImportsWorkspaceGraphModule, d as FileImportsWorkspaceGraphService, w as PythonImportGraphService, _ as PythonImportParserService, E as PythonModule, C as PythonProjectService, T as PythonService, N as TypescriptImportGraphService, F as TypescriptModule, M as TypescriptProjectService, P as TypescriptService };
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
+ "author": "Jimmy Paolini",
3
+ "bugs": {
4
+ "url": "https://github.com/organizzolini/codebase/issues"
5
+ },
6
+ "dependencies": {
7
+ "@nestjs/common": "^11.1.21 || ^12.0.1",
8
+ "reflect-metadata": "^0.2.2"
9
+ },
10
+ "description": "TypeScript and JavaScript file-level import graph extraction and circularity detection for Codependix",
11
+ "devDependencies": {
12
+ "@golevelup/ts-vitest": "^4.0.0",
13
+ "@nestjs/testing": "^12.0.1",
14
+ "@nx/eslint-plugin": "^23.0.0",
15
+ "@swc/helpers": "^0.5.21",
16
+ "@types/node": "^26.5.1",
17
+ "@vitest/coverage-v8": "^5.0.0",
18
+ "typescript": "^6.0.3",
19
+ "vitest": "^5.0.0"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/src/index.d.ts",
24
+ "default": "./dist/src/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "CHANGELOG.md",
30
+ "dist",
31
+ "LICENSE",
32
+ "README.md"
33
+ ],
34
+ "homepage": "https://github.com/organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-file-imports#readme",
35
+ "keywords": [
36
+ "circular-dependency",
37
+ "codependix",
38
+ "file-dependencies",
39
+ "import-graph",
40
+ "typescript"
41
+ ],
42
+ "license": "MIT",
43
+ "main": "./dist/src/index.js",
2
44
  "name": "@codependix/file-imports",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
45
+ "peerDependencies": {
46
+ "typescript": "^6.0.3"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public",
50
+ "registry": "https://registry.npmjs.org"
51
+ },
52
+ "repository": {
53
+ "directory": "packages/ic-suite/codependix/codependix-file-imports",
54
+ "type": "git",
55
+ "url": "git+https://github.com/organizzolini/codebase.git"
56
+ },
57
+ "type": "module",
58
+ "typeCoverage": {
59
+ "atLeast": 100,
60
+ "strict": true
61
+ },
62
+ "types": "./dist/src/index.d.ts",
63
+ "version": "0.0.4"
6
64
  }