weifuwu 0.18.9 → 0.18.11

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/index.js CHANGED
@@ -5130,7 +5130,7 @@ function ensureCertificates(config) {
5130
5130
  import { createOpenAI as createOpenAI3 } from "@ai-sdk/openai";
5131
5131
 
5132
5132
  // opencode/rest.ts
5133
- import { join as join4 } from "node:path";
5133
+ import { join as join5 } from "node:path";
5134
5134
 
5135
5135
  // ssr.ts
5136
5136
  import { createElement } from "react";
@@ -5478,6 +5478,106 @@ function ssr(path2) {
5478
5478
  return r;
5479
5479
  }
5480
5480
 
5481
+ // tailwind.ts
5482
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "node:fs";
5483
+ import { join as join3, relative, resolve as resolve5 } from "node:path";
5484
+
5485
+ // live.ts
5486
+ import chokidar from "chokidar";
5487
+ var clients = /* @__PURE__ */ new Set();
5488
+ function broadcastReload() {
5489
+ for (const ws of clients) {
5490
+ try {
5491
+ ws.send("reload");
5492
+ } catch {
5493
+ clients.delete(ws);
5494
+ }
5495
+ }
5496
+ }
5497
+ function liveReload(opts) {
5498
+ const r = new Router();
5499
+ r.ws("/__weifuwu/livereload", {
5500
+ open(ws) {
5501
+ clients.add(ws);
5502
+ ws.on("close", () => clients.delete(ws));
5503
+ ws.on("error", () => clients.delete(ws));
5504
+ }
5505
+ });
5506
+ const watcher = chokidar.watch(opts.dirs, {
5507
+ ignored: /(^|[/\\])\.|node_modules|[/\\]\.weifuwu[/\\]/,
5508
+ ignoreInitial: true
5509
+ });
5510
+ watcher.on("change", (path2) => {
5511
+ if (!/\.tsx?$/.test(path2)) return;
5512
+ clearCompileCache();
5513
+ setTimeout(broadcastReload, 50);
5514
+ });
5515
+ r.close = () => {
5516
+ watcher.close();
5517
+ clients.clear();
5518
+ };
5519
+ return r;
5520
+ }
5521
+
5522
+ // tailwind.ts
5523
+ var isDev2 = process.env.NODE_ENV !== "production";
5524
+ var extraSources = /* @__PURE__ */ new Set();
5525
+ function tailwind(dir) {
5526
+ const cssDir = resolve5(dir);
5527
+ const cssPath = join3(cssDir, "app.css");
5528
+ let compiledCss = "";
5529
+ let twWatcher = null;
5530
+ return async (req, ctx, next) => {
5531
+ const url = new URL(req.url);
5532
+ if (!compiledCss) compiledCss = await compile(cssPath, cssDir);
5533
+ const stylePath = (ctx.mountPath || "") + "/__wfw/style.css";
5534
+ if (url.pathname === stylePath) {
5535
+ return new Response(compiledCss || "", {
5536
+ headers: { "content-type": "text/css; charset=utf-8" }
5537
+ });
5538
+ }
5539
+ ctx.compiledTailwindCss = compiledCss;
5540
+ if (isDev2 && !twWatcher) {
5541
+ twWatcher = watchFile(cssPath, () => {
5542
+ compiledCss = "";
5543
+ broadcastReload();
5544
+ });
5545
+ }
5546
+ return next(req, ctx);
5547
+ };
5548
+ }
5549
+ async function compile(cssPath, cssDir) {
5550
+ try {
5551
+ if (!existsSync3(cssPath)) {
5552
+ mkdirSync2(cssDir, { recursive: true });
5553
+ writeFileSync(cssPath, '@import "tailwindcss"\n', "utf-8");
5554
+ }
5555
+ const { default: tailwindPlugin } = await import("@tailwindcss/postcss");
5556
+ const { default: postcss } = await import("postcss");
5557
+ let src = readFileSync3(cssPath, "utf-8");
5558
+ src = `@source "./";
5559
+ ${src}`;
5560
+ for (const srcDir of extraSources) {
5561
+ const rel = relative(cssDir, srcDir) || ".";
5562
+ src = `@source "${rel.startsWith(".") ? rel : "./" + rel}";
5563
+ ${src}`;
5564
+ }
5565
+ const result = await postcss([tailwindPlugin()]).process(src, { from: cssPath });
5566
+ return result.css;
5567
+ } catch (err) {
5568
+ console.warn("Tailwind CSS processing failed:", err.message);
5569
+ return "";
5570
+ }
5571
+ }
5572
+ function watchFile(path2, onChange) {
5573
+ let watcher = null;
5574
+ import("chokidar").then((chokidar2) => {
5575
+ watcher = chokidar2.default.watch(resolve5(path2), { persistent: false });
5576
+ watcher.on("change", onChange);
5577
+ });
5578
+ return watcher;
5579
+ }
5580
+
5481
5581
  // layout.ts
5482
5582
  function layout(path2) {
5483
5583
  return async (req, ctx, next) => {
@@ -5491,7 +5591,7 @@ function layout(path2) {
5491
5591
 
5492
5592
  // opencode/session.ts
5493
5593
  import { randomUUID as randomUUID2 } from "node:crypto";
5494
- import { join as join3 } from "node:path";
5594
+ import { join as join4 } from "node:path";
5495
5595
  import { mkdir as mkdir2 } from "node:fs/promises";
5496
5596
  var sessions = pgTable("_opencode_sessions", {
5497
5597
  id: uuid("id"),
@@ -5528,7 +5628,7 @@ async function createSession(sql2, opts, cwd, mountPath) {
5528
5628
  }
5529
5629
  function computeSessionWorkspace(cwd, mountPath, sessionId) {
5530
5630
  const name = !mountPath || mountPath === "/" ? "default" : mountPath.replace(/^\//, "");
5531
- return join3(cwd, ".sessions", name, sessionId);
5631
+ return join4(cwd, ".sessions", name, sessionId);
5532
5632
  }
5533
5633
  async function getSession(sql2, id3) {
5534
5634
  const { data: rows } = await sessions.readMany(sql2, { id: id3, active: true });
@@ -5744,8 +5844,8 @@ function createBashTool(ctx) {
5744
5844
  // opencode/tools/read.ts
5745
5845
  import { tool as tool4 } from "ai";
5746
5846
  import { z as z6 } from "zod";
5747
- import { readFileSync as readFileSync3 } from "node:fs";
5748
- import { resolve as resolve5 } from "node:path";
5847
+ import { readFileSync as readFileSync4 } from "node:fs";
5848
+ import { resolve as resolve6 } from "node:path";
5749
5849
  function createReadTool(ctx) {
5750
5850
  return tool4({
5751
5851
  description: "Read file contents. Supports offset and limit for reading specific line ranges.",
@@ -5755,11 +5855,11 @@ function createReadTool(ctx) {
5755
5855
  limit: z6.number().optional().describe("Number of lines to read")
5756
5856
  }),
5757
5857
  execute: async ({ path: path2, offset, limit }) => {
5758
- const resolved = resolve5(ctx.workspace, path2);
5858
+ const resolved = resolve6(ctx.workspace, path2);
5759
5859
  if (!isPathAllowed(resolved, ctx.workspace, ctx.permissions)) {
5760
5860
  return { error: "Path not allowed", content: null, totalLines: 0 };
5761
5861
  }
5762
- const content = readFileSync3(resolved, "utf-8");
5862
+ const content = readFileSync4(resolved, "utf-8");
5763
5863
  const lines = content.split("\n");
5764
5864
  const totalLines = lines.length;
5765
5865
  if (offset !== void 0) {
@@ -5786,8 +5886,8 @@ function createReadTool(ctx) {
5786
5886
  // opencode/tools/write.ts
5787
5887
  import { tool as tool5 } from "ai";
5788
5888
  import { z as z7 } from "zod";
5789
- import { writeFileSync, mkdirSync as mkdirSync2 } from "node:fs";
5790
- import { resolve as resolve6, dirname as dirname3 } from "node:path";
5889
+ import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
5890
+ import { resolve as resolve7, dirname as dirname3 } from "node:path";
5791
5891
  function createWriteTool(ctx) {
5792
5892
  return tool5({
5793
5893
  description: "Create or overwrite a file. Parent directories are created automatically.",
@@ -5796,12 +5896,12 @@ function createWriteTool(ctx) {
5796
5896
  content: z7.string().describe("File content")
5797
5897
  }),
5798
5898
  execute: async ({ path: path2, content }) => {
5799
- const resolved = resolve6(ctx.workspace, path2);
5899
+ const resolved = resolve7(ctx.workspace, path2);
5800
5900
  if (!isPathAllowed(resolved, ctx.workspace, ctx.permissions)) {
5801
5901
  return { error: "Path not allowed" };
5802
5902
  }
5803
- mkdirSync2(dirname3(resolved), { recursive: true });
5804
- writeFileSync(resolved, content, "utf-8");
5903
+ mkdirSync3(dirname3(resolved), { recursive: true });
5904
+ writeFileSync2(resolved, content, "utf-8");
5805
5905
  return { path: path2, size: content.length };
5806
5906
  }
5807
5907
  });
@@ -5810,8 +5910,8 @@ function createWriteTool(ctx) {
5810
5910
  // opencode/tools/edit.ts
5811
5911
  import { tool as tool6 } from "ai";
5812
5912
  import { z as z8 } from "zod";
5813
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
5814
- import { resolve as resolve7 } from "node:path";
5913
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
5914
+ import { resolve as resolve8 } from "node:path";
5815
5915
  function createEditTool(ctx) {
5816
5916
  return tool6({
5817
5917
  description: "Perform exact string replacements in a file. If oldString appears multiple times, provide more surrounding context.",
@@ -5822,18 +5922,18 @@ function createEditTool(ctx) {
5822
5922
  replaceAll: z8.boolean().default(false).describe("Replace all occurrences")
5823
5923
  }),
5824
5924
  execute: async ({ path: path2, oldString, newString, replaceAll }) => {
5825
- const resolved = resolve7(ctx.workspace, path2);
5925
+ const resolved = resolve8(ctx.workspace, path2);
5826
5926
  if (!isPathAllowed(resolved, ctx.workspace, ctx.permissions)) {
5827
5927
  return { error: "Path not allowed" };
5828
5928
  }
5829
- const content = readFileSync4(resolved, "utf-8");
5929
+ const content = readFileSync5(resolved, "utf-8");
5830
5930
  if (replaceAll) {
5831
5931
  if (!content.includes(oldString)) {
5832
5932
  return { error: "oldString not found in file", replaced: 0 };
5833
5933
  }
5834
5934
  const count = content.split(oldString).length - 1;
5835
5935
  const result2 = content.replaceAll(oldString, newString);
5836
- writeFileSync2(resolved, result2, "utf-8");
5936
+ writeFileSync3(resolved, result2, "utf-8");
5837
5937
  return { path: path2, replaced: count };
5838
5938
  }
5839
5939
  const firstIdx = content.indexOf(oldString);
@@ -5845,7 +5945,7 @@ function createEditTool(ctx) {
5845
5945
  return { error: "Found multiple matches. Provide more surrounding context in oldString.", replaced: 0 };
5846
5946
  }
5847
5947
  const result = content.replace(oldString, newString);
5848
- writeFileSync2(resolved, result, "utf-8");
5948
+ writeFileSync3(resolved, result, "utf-8");
5849
5949
  return { path: path2, replaced: 1 };
5850
5950
  }
5851
5951
  });
@@ -5855,8 +5955,8 @@ function createEditTool(ctx) {
5855
5955
  import { tool as tool7 } from "ai";
5856
5956
  import { z as z9 } from "zod";
5857
5957
  import { execFileSync } from "node:child_process";
5858
- import { resolve as resolve8 } from "node:path";
5859
- import { existsSync as existsSync3 } from "node:fs";
5958
+ import { resolve as resolve9 } from "node:path";
5959
+ import { existsSync as existsSync4 } from "node:fs";
5860
5960
  function createGrepTool(ctx) {
5861
5961
  return tool7({
5862
5962
  description: "Search file contents using regex. Supports file type filtering and context lines.",
@@ -5867,10 +5967,10 @@ function createGrepTool(ctx) {
5867
5967
  context: z9.number().default(0).describe("Number of context lines before and after each match")
5868
5968
  }),
5869
5969
  execute: async ({ pattern, include, path: path2, context }) => {
5870
- const searchDir = path2 ? resolve8(ctx.workspace, path2) : ctx.workspace;
5970
+ const searchDir = path2 ? resolve9(ctx.workspace, path2) : ctx.workspace;
5871
5971
  try {
5872
5972
  let stdout;
5873
- if (existsSync3("/usr/bin/rg") || existsSync3("/usr/local/bin/rg")) {
5973
+ if (existsSync4("/usr/bin/rg") || existsSync4("/usr/local/bin/rg")) {
5874
5974
  const args = ["-n"];
5875
5975
  if (context > 0) args.push("-C", String(context));
5876
5976
  if (include) args.push("-g", include);
@@ -5899,7 +5999,7 @@ function createGrepTool(ctx) {
5899
5999
  import { tool as tool8 } from "ai";
5900
6000
  import { z as z10 } from "zod";
5901
6001
  import { execFileSync as execFileSync2 } from "node:child_process";
5902
- import { resolve as resolve9 } from "node:path";
6002
+ import { resolve as resolve10 } from "node:path";
5903
6003
  function createGlobTool(ctx) {
5904
6004
  return tool8({
5905
6005
  description: "Find files matching a glob pattern.",
@@ -5908,7 +6008,7 @@ function createGlobTool(ctx) {
5908
6008
  path: z10.string().optional().describe("Subdirectory relative to workspace")
5909
6009
  }),
5910
6010
  execute: async ({ pattern, path: path2 }) => {
5911
- const searchDir = path2 ? resolve9(ctx.workspace, path2) : ctx.workspace;
6011
+ const searchDir = path2 ? resolve10(ctx.workspace, path2) : ctx.workspace;
5912
6012
  try {
5913
6013
  const stdout = execFileSync2("find", [
5914
6014
  searchDir,
@@ -6124,8 +6224,9 @@ async function buildRouter4(deps) {
6124
6224
  });
6125
6225
  try {
6126
6226
  const uiDir = new URL("../opencode/ui/", import.meta.url).pathname;
6127
- router.use(layout(join4(uiDir, "layout.tsx")));
6128
- router.get("/", ssr(join4(uiDir, "page.tsx")));
6227
+ router.use(tailwind(uiDir));
6228
+ router.use(layout(join5(uiDir, "layout.tsx")));
6229
+ router.get("/", ssr(join5(uiDir, "page.tsx")));
6129
6230
  } catch (e) {
6130
6231
  console.warn("[opencode] UI not available:", e);
6131
6232
  }
@@ -6133,17 +6234,17 @@ async function buildRouter4(deps) {
6133
6234
  }
6134
6235
 
6135
6236
  // opencode/ws.ts
6136
- var clients = /* @__PURE__ */ new WeakMap();
6237
+ var clients2 = /* @__PURE__ */ new WeakMap();
6137
6238
  function createWSHandler2(deps) {
6138
6239
  const { sql: sql2, model, workspace, systemPrompt, skills, skillsRegistry, permissions, pendingQuestions } = deps;
6139
6240
  return {
6140
6241
  open(ws, ctx) {
6141
6242
  const userId = ctx.user?.id ?? 0;
6142
6243
  const mountPath = ctx.mountPath ?? "";
6143
- clients.set(ws, { userId, mountPath });
6244
+ clients2.set(ws, { userId, mountPath });
6144
6245
  },
6145
6246
  async message(ws, ctx, data) {
6146
- const client = clients.get(ws);
6247
+ const client = clients2.get(ws);
6147
6248
  if (!client) return;
6148
6249
  let msg;
6149
6250
  try {
@@ -6240,17 +6341,17 @@ function createWSHandler2(deps) {
6240
6341
  }
6241
6342
  },
6242
6343
  close(ws) {
6243
- const client = clients.get(ws);
6344
+ const client = clients2.get(ws);
6244
6345
  if (client) {
6245
6346
  client.abortController?.abort();
6246
- clients.delete(ws);
6347
+ clients2.delete(ws);
6247
6348
  }
6248
6349
  },
6249
6350
  error(ws, _ctx, _err) {
6250
- const client = clients.get(ws);
6351
+ const client = clients2.get(ws);
6251
6352
  if (client) {
6252
6353
  client.abortController?.abort();
6253
- clients.delete(ws);
6354
+ clients2.delete(ws);
6254
6355
  }
6255
6356
  }
6256
6357
  };
@@ -6260,7 +6361,7 @@ function createWSHandler2(deps) {
6260
6361
  import { readFile } from "node:fs/promises";
6261
6362
  import { glob } from "node:fs/promises";
6262
6363
  import { homedir } from "node:os";
6263
- import { resolve as resolve10 } from "node:path";
6364
+ import { resolve as resolve11 } from "node:path";
6264
6365
  import { parse as parseYaml } from "yaml";
6265
6366
  var SEARCH_DIRS = [
6266
6367
  (ws) => `${ws}/.opencode/skills`,
@@ -6298,7 +6399,7 @@ async function scanDir(dir) {
6298
6399
  try {
6299
6400
  const files = [];
6300
6401
  for await (const entry of glob("*/SKILL.md", { cwd: dir })) {
6301
- const skill = await parseSkillFile(resolve10(dir, entry));
6402
+ const skill = await parseSkillFile(resolve11(dir, entry));
6302
6403
  if (skill) files.push(skill);
6303
6404
  }
6304
6405
  return files;
@@ -6633,8 +6734,8 @@ function analytics(options) {
6633
6734
 
6634
6735
  // preferences.ts
6635
6736
  import { readFile as readFile2 } from "node:fs/promises";
6636
- import { existsSync as existsSync4 } from "node:fs";
6637
- import { join as join5, resolve as resolve11 } from "node:path";
6737
+ import { existsSync as existsSync5 } from "node:fs";
6738
+ import { join as join6, resolve as resolve12 } from "node:path";
6638
6739
  var defaults = {
6639
6740
  locale: { default: "en", cookie: "locale", fromAcceptLanguage: true },
6640
6741
  theme: { default: "system", cookie: "theme" }
@@ -6683,7 +6784,7 @@ async function handlePrefSwitch(req, value, cookieName, load) {
6683
6784
  });
6684
6785
  }
6685
6786
  function preferences(options) {
6686
- const dir = options.dir ? resolve11(options.dir) : void 0;
6787
+ const dir = options.dir ? resolve12(options.dir) : void 0;
6687
6788
  const localeOpts = { ...defaults.locale, ...options.locale };
6688
6789
  const themeOpts = { ...defaults.theme, ...options.theme };
6689
6790
  const cache2 = /* @__PURE__ */ new Map();
@@ -6695,8 +6796,8 @@ function preferences(options) {
6695
6796
  if (!validLocale(locale)) return {};
6696
6797
  const cached = cache2.get(locale);
6697
6798
  if (cached) return cached;
6698
- const filePath = join5(dir, `${locale}.json`);
6699
- if (!existsSync4(filePath)) return {};
6799
+ const filePath = join6(dir, `${locale}.json`);
6800
+ if (!existsSync5(filePath)) return {};
6700
6801
  try {
6701
6802
  const content = await readFile2(filePath, "utf-8");
6702
6803
  const data = JSON.parse(content);
@@ -8116,102 +8217,6 @@ function registerWorker(url) {
8116
8217
  };
8117
8218
  }
8118
8219
 
8119
- // live.ts
8120
- import chokidar from "chokidar";
8121
- var clients2 = /* @__PURE__ */ new Set();
8122
- function broadcastReload() {
8123
- for (const ws of clients2) {
8124
- try {
8125
- ws.send("reload");
8126
- } catch {
8127
- clients2.delete(ws);
8128
- }
8129
- }
8130
- }
8131
- function liveReload(opts) {
8132
- const r = new Router();
8133
- r.ws("/__weifuwu/livereload", {
8134
- open(ws) {
8135
- clients2.add(ws);
8136
- ws.on("close", () => clients2.delete(ws));
8137
- ws.on("error", () => clients2.delete(ws));
8138
- }
8139
- });
8140
- const watcher = chokidar.watch(opts.dirs, {
8141
- ignored: /(^|[/\\])\.|node_modules|[/\\]\.weifuwu[/\\]/,
8142
- ignoreInitial: true
8143
- });
8144
- watcher.on("change", (path2) => {
8145
- if (!/\.tsx?$/.test(path2)) return;
8146
- clearCompileCache();
8147
- setTimeout(broadcastReload, 50);
8148
- });
8149
- r.close = () => {
8150
- watcher.close();
8151
- clients2.clear();
8152
- };
8153
- return r;
8154
- }
8155
-
8156
- // tailwind.ts
8157
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
8158
- import { relative, resolve as resolve12 } from "node:path";
8159
- var isDev2 = process.env.NODE_ENV !== "production";
8160
- function tailwind(cssPath, scanDir2) {
8161
- let compiledCss = "";
8162
- let twWatcher = null;
8163
- return async (req, ctx, next) => {
8164
- const url = new URL(req.url);
8165
- if (!compiledCss) {
8166
- compiledCss = await compile(cssPath, scanDir2);
8167
- }
8168
- if (url.pathname === "/__wfw/style.css") {
8169
- return new Response(compiledCss || "", {
8170
- headers: { "content-type": "text/css; charset=utf-8" }
8171
- });
8172
- }
8173
- ctx.compiledTailwindCss = compiledCss;
8174
- if (isDev2 && !twWatcher) {
8175
- twWatcher = watchFile(cssPath, () => {
8176
- compiledCss = "";
8177
- });
8178
- }
8179
- return next(req, ctx);
8180
- };
8181
- }
8182
- async function compile(cssPath, scanDir2) {
8183
- try {
8184
- const inputFile = resolve12(cssPath);
8185
- if (!existsSync5(inputFile)) {
8186
- mkdirSync3(dirname4(inputFile), { recursive: true });
8187
- writeFileSync3(inputFile, '@import "tailwindcss"\n', "utf-8");
8188
- }
8189
- const { default: tailwindPlugin } = await import("@tailwindcss/postcss");
8190
- const { default: postcss } = await import("postcss");
8191
- let src = readFileSync5(inputFile, "utf-8");
8192
- const scanSource = scanDir2 ? relative(dirname4(inputFile), scanDir2) || "." : ".";
8193
- const sourcePath = scanSource === "." ? "./" : `./${scanSource}/`;
8194
- src = `@source "${sourcePath}";
8195
- ${src}`;
8196
- const result = await postcss([tailwindPlugin()]).process(src, { from: inputFile });
8197
- return result.css;
8198
- } catch (err) {
8199
- console.warn("Tailwind CSS processing failed:", err.message);
8200
- return "";
8201
- }
8202
- }
8203
- function dirname4(p) {
8204
- return p.substring(0, p.lastIndexOf("/")) || "/";
8205
- }
8206
- function watchFile(path2, onChange) {
8207
- let watcher = null;
8208
- import("chokidar").then((chokidar2) => {
8209
- watcher = chokidar2.default.watch(resolve12(path2), { persistent: false });
8210
- watcher.on("change", onChange);
8211
- });
8212
- return watcher;
8213
- }
8214
-
8215
8220
  // not-found.ts
8216
8221
  function notFound(path2) {
8217
8222
  return async (req, ctx) => {
package/dist/live.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Router } from './router.ts';
2
+ export declare function broadcastReload(): void;
2
3
  export declare function liveReload(opts: {
3
4
  dirs: string[];
4
5
  }): Router & {
@@ -1,2 +1,3 @@
1
1
  import type { Middleware } from './types.ts';
2
- export declare function tailwind(cssPath: string, scanDir?: string): Middleware;
2
+ export declare function addTailwindSource(dir: string): void;
3
+ export declare function tailwind(dir: string): Middleware;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weifuwu",
3
- "version": "0.18.9",
3
+ "version": "0.18.11",
4
4
  "description": "Web-standard HTTP framework for Node.js — (req, ctx) => Response",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",