@openlearning/create-widget 1.0.1 → 1.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6dA,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCrE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAihBA,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCrE"}
package/dist/index.js CHANGED
@@ -4,12 +4,18 @@ import { fileURLToPath } from "url";
4
4
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
5
  function getTemplateFiles(projectName) {
6
6
  const camelCase = projectName.replace(/-./g, (x) => x[1].toUpperCase());
7
+ const displayTitle = projectName
8
+ .split("-")
9
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
10
+ .join(" ");
7
11
  return [
8
12
  // package.json
9
13
  {
10
14
  path: "package.json",
11
15
  content: JSON.stringify({
12
16
  name: projectName,
17
+ displayTitle: displayTitle,
18
+ description: "",
13
19
  version: "0.0.0",
14
20
  type: "module",
15
21
  scripts: {
@@ -23,13 +29,17 @@ function getTemplateFiles(projectName) {
23
29
  "react-dom": "^19.2.0",
24
30
  },
25
31
  devDependencies: {
32
+ "@tailwindcss/postcss": "^4.1.18",
26
33
  "@types/node": "^20.0.0",
27
34
  "@types/react": "^19.0.0",
28
35
  "@types/react-dom": "^19.0.0",
29
36
  "@vitejs/plugin-react": "^4.0.0",
37
+ autoprefixer: "^10.4.23",
30
38
  eslint: "^8.0.0",
31
39
  "eslint-plugin-react-hooks": "^4.6.0",
32
40
  "eslint-plugin-react-refresh": "^0.4.0",
41
+ postcss: "^8.5.6",
42
+ tailwindcss: "^4.1.18",
33
43
  typescript: "^5.7.2",
34
44
  vite: "^7.3.1",
35
45
  },
@@ -183,14 +193,20 @@ The parent window communicates via \`postMessage\` protocol.
183
193
  // src/index.css
184
194
  {
185
195
  path: "src/index.css",
186
- content: `* {
196
+ content: `@import "tailwindcss";
197
+ @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");
198
+
199
+ * {
187
200
  margin: 0;
188
201
  padding: 0;
189
202
  box-sizing: border-box;
190
203
  }
191
204
 
205
+ html {
206
+ font-family: "Open Sans", system-ui, -apple-system, sans-serif;
207
+ }
208
+
192
209
  body {
193
- font-family: system-ui, -apple-system, sans-serif;
194
210
  line-height: 1.5;
195
211
  }
196
212
  `,
@@ -259,6 +275,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
259
275
  {
260
276
  path: "src/components/LearnerView.tsx",
261
277
  content: `import React from "react";
278
+ import { Button } from "@openlearning/widget-framework";
262
279
  import type { LearnerViewProps } from "@openlearning/widget-framework";
263
280
  import type { WidgetConfig } from "../types";
264
281
 
@@ -275,10 +292,10 @@ export const LearnerView: React.FC<LearnerViewProps<WidgetConfig>> = ({
275
292
  <h1>Learner View</h1>
276
293
  <p>Implement your learner interface here.</p>
277
294
 
278
- <div style={{ marginTop: "1rem" }}>
279
- <button onClick={() => onComplete?.()}>Complete</button>
280
- <button onClick={() => onShare?.([])}>Share</button>
281
- <button onClick={() => onResize?.(400)}>Resize</button>
295
+ <div style={{ marginTop: "1rem", display: "flex", gap: "0.5rem" }}>
296
+ <Button variant="round-filled" onClick={() => onComplete?.()}>Complete</Button>
297
+ <Button variant="round-tonal" onClick={() => onShare?.([])}>Share</Button>
298
+ <Button variant="round-quiet" onClick={() => onResize?.(400)}>Resize</Button>
282
299
  </div>
283
300
  </div>
284
301
  );
@@ -289,6 +306,7 @@ export const LearnerView: React.FC<LearnerViewProps<WidgetConfig>> = ({
289
306
  {
290
307
  path: "src/components/SetupView.tsx",
291
308
  content: `import React from "react";
309
+ import { Button } from "@openlearning/widget-framework";
292
310
  import type { SetupViewProps } from "@openlearning/widget-framework";
293
311
  import type { WidgetConfig } from "../types";
294
312
 
@@ -303,9 +321,9 @@ export const SetupView: React.FC<SetupViewProps<WidgetConfig>> = ({
303
321
  <h1>Setup View</h1>
304
322
  <p>Implement your setup/configuration interface here.</p>
305
323
 
306
- <div style={{ marginTop: "1rem" }}>
307
- <button onClick={() => onChange?.(config)}>Save Configuration</button>
308
- <button onClick={() => onResize?.(400)}>Resize</button>
324
+ <div style={{ marginTop: "1rem", display: "flex", gap: "0.5rem" }}>
325
+ <Button variant="round-filled" onClick={() => onChange?.(config)}>Save Configuration</Button>
326
+ <Button variant="round-tonal" onClick={() => onResize?.(400)}>Resize</Button>
309
327
  </div>
310
328
  </div>
311
329
  );
@@ -316,6 +334,8 @@ export const SetupView: React.FC<SetupViewProps<WidgetConfig>> = ({
316
334
  {
317
335
  path: "src/entries/learner.tsx",
318
336
  content: `import { createLearnerEntry } from "@openlearning/widget-framework";
337
+ // Import Button CSS if you use the Button component
338
+ import "@openlearning/widget-framework/styles/button.css";
319
339
  import { LearnerView } from "../components/LearnerView";
320
340
  import "../index.css";
321
341
 
@@ -326,6 +346,8 @@ createLearnerEntry(LearnerView);
326
346
  {
327
347
  path: "src/entries/setup.tsx",
328
348
  content: `import { createSetupEntry } from "@openlearning/widget-framework";
349
+ // Import Button CSS if you use the Button component
350
+ import "@openlearning/widget-framework/styles/button.css";
329
351
  import { SetupView } from "../components/SetupView";
330
352
  import { DEFAULT_CONFIG } from "../data";
331
353
  import "../index.css";
@@ -340,7 +362,6 @@ createSetupEntry(SetupView, DEFAULT_CONFIG);
340
362
  <html lang="en">
341
363
  <head>
342
364
  <meta charset="UTF-8" />
343
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
344
365
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
345
366
  <title>${projectName}</title>
346
367
  </head>
@@ -383,6 +404,35 @@ createSetupEntry(SetupView, DEFAULT_CONFIG);
383
404
  <script type="module" src="./src/entries/setup.tsx"></script>
384
405
  </body>
385
406
  </html>
407
+ `,
408
+ },
409
+ // tailwind.config.js
410
+ {
411
+ path: "tailwind.config.js",
412
+ content: `/** @type {import('tailwindcss').Config} */
413
+ export default {
414
+ content: [
415
+ "./index.html",
416
+ "./learner.html",
417
+ "./setup.html",
418
+ "./src/**/*.{js,ts,jsx,tsx}",
419
+ ],
420
+ theme: {
421
+ extend: {},
422
+ },
423
+ plugins: [],
424
+ };
425
+ `,
426
+ },
427
+ // postcss.config.js
428
+ {
429
+ path: "postcss.config.js",
430
+ content: `export default {
431
+ plugins: {
432
+ "@tailwindcss/postcss": {},
433
+ autoprefixer: {},
434
+ },
435
+ };
386
436
  `,
387
437
  },
388
438
  // eslint.config.js
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openlearning/create-widget",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Create a new OpenLearning widget project with all necessary boilerplate",
6
6
  "license": "MIT",
@@ -14,6 +14,14 @@
14
14
  "import": "./dist/index.js"
15
15
  }
16
16
  },
17
+ "files": [
18
+ "bin",
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev": "tsc -w"
24
+ },
17
25
  "keywords": [
18
26
  "widget",
19
27
  "scaffold",
@@ -23,9 +31,5 @@
23
31
  "devDependencies": {
24
32
  "@types/node": "^20.0.0",
25
33
  "typescript": "^5.7.2"
26
- },
27
- "scripts": {
28
- "build": "tsc",
29
- "dev": "tsc -w"
30
34
  }
31
- }
35
+ }
package/src/index.ts DELETED
@@ -1,519 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
-
5
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
-
7
- interface TemplateFile {
8
- path: string;
9
- content: string;
10
- }
11
-
12
- function getTemplateFiles(projectName: string): TemplateFile[] {
13
- const camelCase = projectName.replace(/-./g, (x) => x[1].toUpperCase());
14
-
15
- return [
16
- // package.json
17
- {
18
- path: "package.json",
19
- content: JSON.stringify(
20
- {
21
- name: projectName,
22
- version: "0.0.0",
23
- type: "module",
24
- scripts: {
25
- dev: "vite",
26
- build: "tsc -b && vite build",
27
- preview: "vite preview",
28
- },
29
- dependencies: {
30
- "@openlearning/widget-framework": "workspace:*",
31
- react: "^19.2.0",
32
- "react-dom": "^19.2.0",
33
- },
34
- devDependencies: {
35
- "@types/node": "^20.0.0",
36
- "@types/react": "^19.0.0",
37
- "@types/react-dom": "^19.0.0",
38
- "@vitejs/plugin-react": "^4.0.0",
39
- eslint: "^8.0.0",
40
- "eslint-plugin-react-hooks": "^4.6.0",
41
- "eslint-plugin-react-refresh": "^0.4.0",
42
- typescript: "^5.7.2",
43
- vite: "^7.3.1",
44
- },
45
- },
46
- null,
47
- 2
48
- ),
49
- },
50
-
51
- // tsconfig.json
52
- {
53
- path: "tsconfig.json",
54
- content: JSON.stringify(
55
- {
56
- compilerOptions: {
57
- target: "ES2020",
58
- useDefineForClassFields: true,
59
- lib: ["ES2020", "DOM", "DOM.Iterable"],
60
- module: "ES2020",
61
- skipLibCheck: true,
62
- esModuleInterop: true,
63
- jsx: "react-jsx",
64
- noEmit: true,
65
- },
66
- include: ["src"],
67
- references: [{ path: "./tsconfig.app.json" }],
68
- },
69
- null,
70
- 2
71
- ),
72
- },
73
-
74
- // tsconfig.app.json
75
- {
76
- path: "tsconfig.app.json",
77
- content: JSON.stringify(
78
- {
79
- extends: "./tsconfig.json",
80
- compilerOptions: {
81
- outDir: "./dist",
82
- rootDir: "./src",
83
- },
84
- include: ["src"],
85
- },
86
- null,
87
- 2
88
- ),
89
- },
90
-
91
- // tsconfig.node.json
92
- {
93
- path: "tsconfig.node.json",
94
- content: JSON.stringify(
95
- {
96
- compilerOptions: {
97
- composite: true,
98
- skipLibCheck: true,
99
- module: "ES2020",
100
- moduleResolution: "bundler",
101
- allowSyntheticDefaultImports: true,
102
- },
103
- include: ["vite.config.ts"],
104
- },
105
- null,
106
- 2
107
- ),
108
- },
109
-
110
- // vite.config.ts
111
- {
112
- path: "vite.config.ts",
113
- content: `import { defineConfig } from "vite";
114
- import react from "@vitejs/plugin-react";
115
- import { resolve } from "path";
116
-
117
- export default defineConfig({
118
- base: "./",
119
- plugins: [react()],
120
- build: {
121
- rollupOptions: {
122
- input: {
123
- learner: resolve(__dirname, "learner.html"),
124
- setup: resolve(__dirname, "setup.html"),
125
- },
126
- },
127
- },
128
- });
129
- `,
130
- },
131
-
132
- // .prettierrc
133
- {
134
- path: ".prettierrc",
135
- content: JSON.stringify({
136
- semi: true,
137
- trailingComma: "es5",
138
- singleQuote: false,
139
- }),
140
- },
141
-
142
- // .gitignore
143
- {
144
- path: ".gitignore",
145
- content: `# Logs
146
- logs
147
- *.log
148
- npm-debug.log*
149
-
150
- # Dependencies
151
- node_modules
152
- dist
153
-
154
- # IDE
155
- .vscode
156
- .idea
157
- *.swp
158
- *.swo
159
-
160
- # Environment
161
- .env
162
- .env.local
163
- `,
164
- },
165
-
166
- // README.md
167
- {
168
- path: "README.md",
169
- content: `# ${projectName}
170
-
171
- A widget built with the OpenLearning widget framework.
172
-
173
- ## Setup
174
-
175
- \`\`\`bash
176
- pnpm install
177
- \`\`\`
178
-
179
- ## Development
180
-
181
- \`\`\`bash
182
- pnpm dev
183
- \`\`\`
184
-
185
- ## Build
186
-
187
- \`\`\`bash
188
- pnpm build
189
- \`\`\`
190
-
191
- ## Project Structure
192
-
193
- - \`src/components/\` - React components (LearnerView, SetupView)
194
- - \`src/entries/\` - Widget entry points
195
- - \`learner.html\` - Learner view HTML template
196
- - \`setup.html\` - Setup/admin view HTML template
197
- - \`src/types.ts\` - Widget configuration types
198
- - \`src/data.ts\` - Default configuration
199
-
200
- ## Adding the Widget to a Parent
201
-
202
- The widget exposes two HTML endpoints:
203
- - \`/learner.html\` - Learner view
204
- - \`/setup.html\` - Setup/admin view
205
-
206
- The parent window communicates via \`postMessage\` protocol.
207
- `,
208
- },
209
-
210
- // public/.gitkeep
211
- {
212
- path: "public/.gitkeep",
213
- content: "",
214
- },
215
-
216
- // src/index.css
217
- {
218
- path: "src/index.css",
219
- content: `* {
220
- margin: 0;
221
- padding: 0;
222
- box-sizing: border-box;
223
- }
224
-
225
- body {
226
- font-family: system-ui, -apple-system, sans-serif;
227
- line-height: 1.5;
228
- }
229
- `,
230
- },
231
-
232
- // src/types.ts
233
- {
234
- path: "src/types.ts",
235
- content: `import {
236
- LearnerViewProps,
237
- SetupViewProps,
238
- JSONValue,
239
- Attachment,
240
- } from "@openlearning/widget-framework";
241
-
242
- // Define your widget's configuration structure
243
- export type WidgetConfig = JSONValue;
244
-
245
- // Export framework types for use in your components
246
- export type { LearnerViewProps, SetupViewProps, JSONValue, Attachment };
247
- `,
248
- },
249
-
250
- // src/data.ts
251
- {
252
- path: "src/data.ts",
253
- content: `import { WidgetConfig } from "./types";
254
-
255
- // Default configuration for this widget
256
- export const DEFAULT_CONFIG: WidgetConfig = {
257
- // Add your default configuration here
258
- };
259
- `,
260
- },
261
-
262
- // src/DevApp.tsx
263
- {
264
- path: "src/DevApp.tsx",
265
- content: `import { DevApp as FrameworkDevApp } from "@openlearning/widget-framework";
266
- import { LearnerView } from "./components/LearnerView";
267
- import { SetupView } from "./components/SetupView";
268
- import { DEFAULT_CONFIG } from "./data";
269
-
270
- export const DevApp = () => (
271
- <FrameworkDevApp
272
- LearnerViewComponent={LearnerView}
273
- SetupViewComponent={SetupView}
274
- defaultConfig={DEFAULT_CONFIG}
275
- />
276
- );
277
- `,
278
- },
279
-
280
- // src/devMain.tsx
281
- {
282
- path: "src/devMain.tsx",
283
- content: `import React from "react";
284
- import ReactDOM from "react-dom/client";
285
- import { DevApp } from "./DevApp";
286
- import "./index.css";
287
-
288
- ReactDOM.createRoot(document.getElementById("root")!).render(
289
- <React.StrictMode>
290
- <DevApp />
291
- </React.StrictMode>
292
- );
293
- `,
294
- },
295
-
296
- // src/components/LearnerView.tsx
297
- {
298
- path: "src/components/LearnerView.tsx",
299
- content: `import React from "react";
300
- import type { LearnerViewProps } from "@openlearning/widget-framework";
301
- import type { WidgetConfig } from "../types";
302
-
303
- export const LearnerView: React.FC<LearnerViewProps<WidgetConfig>> = ({
304
- config,
305
- onComplete,
306
- onShare,
307
- onResize,
308
- onSave,
309
- onReinit,
310
- }) => {
311
- return (
312
- <div style={{ padding: "1rem" }}>
313
- <h1>Learner View</h1>
314
- <p>Implement your learner interface here.</p>
315
-
316
- <div style={{ marginTop: "1rem" }}>
317
- <button onClick={() => onComplete?.()}>Complete</button>
318
- <button onClick={() => onShare?.([])}>Share</button>
319
- <button onClick={() => onResize?.(400)}>Resize</button>
320
- </div>
321
- </div>
322
- );
323
- };
324
- `,
325
- },
326
-
327
- // src/components/SetupView.tsx
328
- {
329
- path: "src/components/SetupView.tsx",
330
- content: `import React from "react";
331
- import type { SetupViewProps } from "@openlearning/widget-framework";
332
- import type { WidgetConfig } from "../types";
333
-
334
- export const SetupView: React.FC<SetupViewProps<WidgetConfig>> = ({
335
- config,
336
- onChange,
337
- onResize,
338
- onReinit,
339
- }) => {
340
- return (
341
- <div style={{ padding: "1rem" }}>
342
- <h1>Setup View</h1>
343
- <p>Implement your setup/configuration interface here.</p>
344
-
345
- <div style={{ marginTop: "1rem" }}>
346
- <button onClick={() => onChange?.(config)}>Save Configuration</button>
347
- <button onClick={() => onResize?.(400)}>Resize</button>
348
- </div>
349
- </div>
350
- );
351
- };
352
- `,
353
- },
354
-
355
- // src/entries/learner.tsx
356
- {
357
- path: "src/entries/learner.tsx",
358
- content: `import { createLearnerEntry } from "@openlearning/widget-framework";
359
- import { LearnerView } from "../components/LearnerView";
360
- import "../index.css";
361
-
362
- createLearnerEntry(LearnerView);
363
- `,
364
- },
365
-
366
- // src/entries/setup.tsx
367
- {
368
- path: "src/entries/setup.tsx",
369
- content: `import { createSetupEntry } from "@openlearning/widget-framework";
370
- import { SetupView } from "../components/SetupView";
371
- import { DEFAULT_CONFIG } from "../data";
372
- import "../index.css";
373
-
374
- createSetupEntry(SetupView, DEFAULT_CONFIG);
375
- `,
376
- },
377
-
378
- // index.html (dev server)
379
- {
380
- path: "index.html",
381
- content: `<!doctype html>
382
- <html lang="en">
383
- <head>
384
- <meta charset="UTF-8" />
385
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
386
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
387
- <title>${projectName}</title>
388
- </head>
389
- <body>
390
- <div id="root"></div>
391
- <script type="module" src="/src/devMain.tsx"></script>
392
- </body>
393
- </html>
394
- `,
395
- },
396
-
397
- // learner.html
398
- {
399
- path: "learner.html",
400
- content: `<!doctype html>
401
- <html lang="en">
402
- <head>
403
- <meta charset="UTF-8" />
404
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
405
- <title>Learner</title>
406
- </head>
407
- <body>
408
- <div id="root"></div>
409
- <script type="module" src="./src/entries/learner.tsx"></script>
410
- </body>
411
- </html>
412
- `,
413
- },
414
-
415
- // setup.html
416
- {
417
- path: "setup.html",
418
- content: `<!doctype html>
419
- <html lang="en">
420
- <head>
421
- <meta charset="UTF-8" />
422
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
423
- <title>Setup</title>
424
- </head>
425
- <body>
426
- <div id="root"></div>
427
- <script type="module" src="./src/entries/setup.tsx"></script>
428
- </body>
429
- </html>
430
- `,
431
- },
432
-
433
- // eslint.config.js
434
- {
435
- path: "eslint.config.js",
436
- content: `import js from "@eslint/js";
437
- import globals from "globals";
438
- import react from "eslint-plugin-react/configs/recommended.js";
439
- import reactHooks from "eslint-plugin-react-hooks";
440
- import reactRefresh from "eslint-plugin-react-refresh";
441
-
442
- export default [
443
- { ignores: ["dist"] },
444
- {
445
- files: ["**/*.{js,jsx,ts,tsx}"],
446
- languageOptions: {
447
- ecmaVersion: 2020,
448
- globals: globals.browser,
449
- parserOptions: {
450
- ecmaVersion: "latest",
451
- ecmaFeatures: { jsx: true },
452
- sourceType: "module",
453
- },
454
- },
455
- settings: { react: { version: "18.3" } },
456
- plugins: {
457
- react,
458
- "react-hooks": reactHooks,
459
- "react-refresh": reactRefresh,
460
- },
461
- rules: {
462
- ...js.configs.recommended.rules,
463
- ...react.rules,
464
- ...reactHooks.configs.recommended.rules,
465
- "react/react-in-jsx-scope": "off",
466
- "react-refresh/only-export-components": [
467
- "warn",
468
- { allowConstantExport: true },
469
- ],
470
- },
471
- },
472
- ];
473
- `,
474
- },
475
- ];
476
- }
477
-
478
- export async function createWidget(projectName: string): Promise<void> {
479
- const projectDir = path.resolve(projectName);
480
-
481
- // Check if directory already exists
482
- if (fs.existsSync(projectDir)) {
483
- throw new Error(`Directory '${projectName}' already exists`);
484
- }
485
-
486
- console.log(`Creating widget project: ${projectName}`);
487
-
488
- // Create the project directory
489
- fs.mkdirSync(projectDir, { recursive: true });
490
-
491
- // Create all template files
492
- const files = getTemplateFiles(projectName);
493
-
494
- for (const file of files) {
495
- const filePath = path.join(projectDir, file.path);
496
- const dirname = path.dirname(filePath);
497
-
498
- // Create directories if they don't exist
499
- fs.mkdirSync(dirname, { recursive: true });
500
-
501
- // Write file
502
- fs.writeFileSync(filePath, file.content);
503
- console.log(` created ${file.path}`);
504
- }
505
-
506
- const nextSteps = `
507
- ✨ Widget project created!
508
-
509
- Next steps:
510
- cd ${projectName}
511
- pnpm install
512
- pnpm dev
513
-
514
- The widget is ready to customize. Edit components in:
515
- - src/components/LearnerView.tsx
516
- - src/components/SetupView.tsx
517
- `;
518
- console.log(nextSteps);
519
- }
package/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "lib": ["ES2020"],
5
- "module": "ES2020",
6
- "moduleResolution": "bundler",
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "declaration": true,
10
- "declarationMap": true,
11
- "sourceMap": true,
12
- "strict": true,
13
- "skipLibCheck": true,
14
- "esModuleInterop": true,
15
- "resolveJsonModule": true,
16
- "types": ["node"]
17
- },
18
- "include": ["src/**/*"],
19
- "exclude": ["node_modules", "dist"]
20
- }