poops 1.0.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.
package/poops.js ADDED
@@ -0,0 +1,452 @@
1
+ #!/usr/bin/env node
2
+
3
+ const autoprefixer = require('autoprefixer')
4
+ const { build } = require('esbuild')
5
+ const chokidar = require('chokidar')
6
+ const connect = require('connect')
7
+ const cssnano = require('cssnano')
8
+ const deepmerge = require('deepmerge')
9
+ const fs = require('node:fs')
10
+ const http = require('node:http')
11
+ const livereload = require('livereload')
12
+ const path = require('node:path')
13
+ const { pathToFileURL } = require('node:url')
14
+ const postcss = require('postcss')
15
+ const sass = require('sass')
16
+ const serveStatic = require('serve-static')
17
+ const Terser = require('terser')
18
+
19
+ const cwd = process.cwd() // Current Working Directory
20
+ const pkg = require('./package.json')
21
+ const args = process.argv.slice(2)
22
+
23
+ let defaultConfigPath = 'poop.json'
24
+
25
+ if (args.length) {
26
+ defaultConfigPath = args[0]
27
+ }
28
+
29
+ // Helpers
30
+
31
+ class Style {
32
+ reset = '\x1b[0m'
33
+ bold = '\x1b[1m'
34
+ dim = '\x1b[2m'
35
+ italic = '\x1b[3m'
36
+ underline = '\x1b[4m'
37
+ blink = '\x1b[5m'
38
+ inverse = '\x1b[7m'
39
+ hidden = '\x1b[8m'
40
+ strikethrough = '\x1b[9m'
41
+ black = '\x1b[30m'
42
+ red = '\x1b[31m'
43
+ redBright = '\x1b[91m'
44
+ green = '\x1b[32m'
45
+ greenBright = '\x1b[92m'
46
+ yellow = '\x1b[33m'
47
+ yellowBright = '\x1b[93m'
48
+ blue = '\x1b[34m'
49
+ blueBright = '\x1b[94m'
50
+ magenta = '\x1b[35m'
51
+ magentaBright = '\x1b[95m'
52
+ cyan = '\x1b[36m'
53
+ cyanBright = '\x1b[96m'
54
+ white = '\x1b[37m'
55
+ whiteBright = '\x1b[97m'
56
+ gray = '\x1b[90m'
57
+ bgBlack = '\x1b[40m'
58
+ bgRed = '\x1b[41m'
59
+ bgRedBright = '\x1b[101m'
60
+ bgGreen = '\x1b[42m'
61
+ bgGreenBright = '\x1b[102m'
62
+ bgYellow = '\x1b[43m'
63
+ bgYellowBright = '\x1b[103m'
64
+ bgBlue = '\x1b[44m'
65
+ bgBlueBright = '\x1b[104m'
66
+ bgMagenta = '\x1b[45m'
67
+ bgMagentaBright = '\x1b[105m'
68
+ bgCyan = '\x1b[46m'
69
+ bgCyanBright = '\x1b[106m'
70
+ bgWhite = '\x1b[47m'
71
+ bgWhiteBright = '\x1b[107m'
72
+ bgGray = '\x1b[100m'
73
+ bell = '\x07'
74
+
75
+ hexToRgb(hex) {
76
+ const sanitizedHex = hex.replace('#', '')
77
+ const red = parseInt(sanitizedHex.substring(0, 2), 16)
78
+ const green = parseInt(sanitizedHex.substring(2, 4), 16)
79
+ const blue = parseInt(sanitizedHex.substring(4, 6), 16)
80
+
81
+ return [red, green, blue]
82
+ }
83
+
84
+ terminalColorIndex(red, green, blue) {
85
+ return 16 +
86
+ Math.round(red / 255 * 5) * 36 +
87
+ Math.round(green / 255 * 5) * 6 +
88
+ Math.round(blue / 255 * 5)
89
+ }
90
+
91
+ color(hex) {
92
+ const [red, green, blue] = this.hexToRgb(hex)
93
+
94
+ return `\x1b[38;5;${this.terminalColorIndex(red, green, blue)}m`
95
+ }
96
+
97
+ background(hex) {
98
+ const [red, green, blue] = this.hexToRgb(hex)
99
+
100
+ return `\x1b[48;5;${this.terminalColorIndex(red, green, blue)}m`
101
+ }
102
+ }
103
+
104
+ function pathExists() {
105
+ return fs.existsSync(path.join(...arguments))
106
+ }
107
+
108
+ function pathIsDirectory() {
109
+ return fs.lstatSync(path.join(...arguments)).isDirectory()
110
+ }
111
+
112
+ function mkPath(filePath) {
113
+ const dirPath = path.dirname(filePath)
114
+ if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath, { recursive: true })
115
+ }
116
+
117
+ function pathForFile(filePath) {
118
+ return /\./.test(path.basename(filePath))
119
+ }
120
+
121
+ function insertMinSuffix(filePath) {
122
+ const { name, ext } = path.parse(filePath)
123
+ return path.join(path.dirname(filePath), `${name}.min${ext}`)
124
+ }
125
+
126
+ function buildStyleOutputFilePath(inputPath, outputPath) {
127
+ if (pathForFile(outputPath)) return outputPath
128
+ const { name } = path.parse(inputPath)
129
+ return path.join(path.join(outputPath, `${name}.css`))
130
+ }
131
+
132
+ function buildScriptOutputFilePath(inputPath, outputPath) {
133
+ if (pathForFile(outputPath)) return outputPath
134
+ const { name, ext } = path.parse(inputPath)
135
+ return path.join(path.join(outputPath, `${name}${ext.replace('t', 'j')}`))
136
+ }
137
+
138
+ function fillBannerTemplate(template, packagesPath) {
139
+ packagesPath = packagesPath || cwd
140
+ const packagesFilePath = path.join(packagesPath, 'package.json')
141
+ if (!pathExists(packagesFilePath)) return template
142
+ const pkg = require(packagesFilePath)
143
+ const { name, version, homepage, description, license, author } = pkg
144
+ const year = new Date().getFullYear()
145
+
146
+ return template
147
+ .replace(/{{\s?name\s?}}/g, name)
148
+ .replace(/{{\s?version\s?}}/g, version)
149
+ .replace(/{{\s?homepage\s?}}/g, homepage)
150
+ .replace(/{{\s?description\s?}}/g, description)
151
+ .replace(/{{\s?author\s?}}/g, author)
152
+ .replace(/{{\s?license\s?}}/g, license)
153
+ .replace(/{{\s?year\s?}}/g, year)
154
+ }
155
+
156
+ function buildTime(start, end) {
157
+ const time = Math.round(end - start)
158
+ if (time < 1000) return `${time}ms`
159
+ if (time < 60 * 1000) return `${(time / 1000).toFixed(0)}s ${time % 1000}ms`
160
+ return `${(time / 1000 / 60).toFixed(0)}m ${((time / 1000) % 60).toFixed(0)}s ${time % 1000}ms`
161
+ }
162
+
163
+ const style = new Style()
164
+
165
+ // CLI Header
166
+ console.log(`\n${style.color('#8b4513')}💩 Poop — v${pkg.version}
167
+ ----------------${style.reset + style.bell}\n`)
168
+
169
+ const configPath = path.join(cwd, defaultConfigPath)
170
+
171
+ // Check if poop.json exists
172
+ if (!pathExists(configPath)) {
173
+ console.log(`${style.redBright + style.bold}[error]${style.reset} \`${style.underline}${defaultConfigPath}${style.reset}\` not found.
174
+ ${style.dim}Configuration file \`${style.underline}${defaultConfigPath}${style.reset}${style.dim}\` not found in your working directory: ${style.underline}${cwd}${style.reset}\n
175
+ ${style.dim}Please specify another file path or create a \`poop.js\` file in your working directory and try again.\n
176
+ ${style.dim}For information on the structure of the configuration file, please visit: \n${style.underline}https://stamat.github.io/poop${style.reset}\n`)
177
+ process.exit(1)
178
+ }
179
+
180
+ // Load poop.json
181
+ const config = require(configPath)
182
+ const banner = config.banner ? fillBannerTemplate(config.banner) : null
183
+
184
+ if (config.watch) {
185
+ config.watch = Array.isArray(config.watch) ? config.watch : [config.watch]
186
+ }
187
+
188
+ if (config.includePaths) {
189
+ config.includePaths = Array.isArray(config.includePaths) ? config.includePaths : [config.includePaths]
190
+ } else {
191
+ config.includePaths = ['node_modules']
192
+ }
193
+
194
+ // Start the webserver
195
+ if (config.serve) {
196
+ const app = connect()
197
+
198
+ if (config.serve.base && pathExists(cwd, config.serve.base)) {
199
+ app.use(serveStatic(path.join(cwd, config.serve.base)))
200
+ } else {
201
+ app.use(serveStatic(cwd))
202
+ }
203
+
204
+ const port = config.serve.port ? parseInt(config.serve.port, 10) : 4040
205
+ http.createServer(app).listen(port, () => {
206
+ console.log(`${style.cyanBright + style.bold}[info]${style.reset} ${style.dim}🌍 Local server:${style.reset} ${style.italic + style.underline}http://localhost:${port}${style.reset}`)
207
+ poop()
208
+ })
209
+ } else {
210
+ poop()
211
+ }
212
+
213
+ // SCSS/SASS Compiler
214
+ function tryToFindFile(filePath, extensions) {
215
+ const fileExt = extensions.find(ext => fs.existsSync(`${filePath}.${ext}`))
216
+ if (fileExt) {
217
+ return `${filePath}.${fileExt}`
218
+ }
219
+ return null
220
+ }
221
+
222
+ function sassPathResolver(url, resolvePath) {
223
+ if (fs.existsSync(url)) return new URL(url)
224
+ const resolvedPath = pathToFileURL(resolvePath)
225
+ if (!fs.existsSync(resolvedPath.pathname)) return null
226
+ const importPath = path.relative(cwd, path.join(resolvedPath.pathname, url))
227
+
228
+ if (!fs.existsSync(importPath)) {
229
+ const correctFile = tryToFindFile(importPath, ['sass', 'scss', 'css'])
230
+ if (correctFile) return new URL(correctFile, resolvedPath)
231
+ }
232
+
233
+ if (pathIsDirectory(importPath) && !pathExists(importPath, 'index.sass') && !pathExists(importPath, 'index.scss')) {
234
+ const correctFile = tryToFindFile(importPath, ['sass', 'scss', 'css'])
235
+ if (correctFile) return new URL(correctFile, resolvedPath)
236
+
237
+ if (!pathExists(importPath, 'package.json')) return null
238
+
239
+ const pkg = require(path.join(importPath, 'package.json'))
240
+
241
+ if (pkg.sass) return new URL(path.join(importPath, pkg.sass), resolvedPath)
242
+ if (pkg.css) return new URL(path.join(importPath, pkg.css), resolvedPath)
243
+
244
+ const basename = path.basename(pkg.main)
245
+ if (pkg.main && /(\.sass|\.scss|\.css)$/i.test(basename)) return new URL(path.join(importPath, pkg.main), resolvedPath)
246
+ return null
247
+ }
248
+
249
+ return new URL(importPath, resolvedPath)
250
+ }
251
+
252
+ function compileStyles() {
253
+ if (!config.styles) return
254
+ config.styles = Array.isArray(config.styles) ? config.styles : [config.styles]
255
+ for (const styleEntry of config.styles) {
256
+ if (styleEntry.in && styleEntry.out && pathExists(styleEntry.in)) {
257
+ mkPath(styleEntry.out)
258
+ compileStylesEntry(styleEntry.in, styleEntry.out, styleEntry.options)
259
+ }
260
+ }
261
+ }
262
+
263
+ function compileStylesEntry(infilePath, outfilePath, options = {}) {
264
+ const opts = {
265
+ sourceMap: false,
266
+ sourceMapIncludeSources: false,
267
+ importers: [{
268
+ // Resolve `includePaths`.
269
+ findFileUrl(url) {
270
+ for (const includePath of config.includePaths) {
271
+ const resolvedPath = sassPathResolver(url, includePath)
272
+ if (resolvedPath) return resolvedPath
273
+ }
274
+ return null
275
+ }
276
+ }]
277
+ }
278
+
279
+ if (options.sourcemap) {
280
+ opts.sourceMap = options.sourcemap
281
+ opts.sourceMapIncludeSources = options.sourcemap
282
+ }
283
+
284
+ outfilePath = buildStyleOutputFilePath(infilePath, outfilePath, options)
285
+
286
+ const cssStart = performance.now()
287
+ const compiledSass = sass.compile(infilePath, opts)
288
+ const mapsrc = options.sourcemap ? `\n/*# sourceMappingURL=${path.basename(outfilePath)}.map */` : ''
289
+ if (banner) compiledSass.css = banner + '\n' + compiledSass.css
290
+ fs.writeFileSync(outfilePath, compiledSass.css + mapsrc)
291
+ const cssEnd = performance.now()
292
+ if (!options.justMinified) console.log(`${style.magentaBright + style.bold}[style]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${outfilePath}${style.reset} ${style.greenBright}(${buildTime(cssStart, cssEnd)})${style.reset}`)
293
+
294
+ if (compiledSass.sourceMap) {
295
+ if (banner) compiledSass.sourceMap.mappings = ';' + compiledSass.sourceMap.mappings
296
+ fs.writeFileSync(`${outfilePath}.map`, JSON.stringify(compiledSass.sourceMap))
297
+ console.log(`${style.magentaBright + style.bold}[style]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${outfilePath}.map${style.reset}`)
298
+ }
299
+
300
+ const cssMinStart = performance.now()
301
+ const minPath = insertMinSuffix(outfilePath)
302
+ if (options.minify) {
303
+ postcss([autoprefixer, cssnano]).process(compiledSass.css, {
304
+ from: outfilePath,
305
+ to: minPath
306
+ }).then(result => {
307
+ if (banner) result.css = banner + '\n' + result.css
308
+ fs.writeFileSync(minPath, result.css)
309
+ const cssMinEnd = performance.now()
310
+ console.log(`${style.magentaBright + style.bold}[style]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${minPath}${style.reset} ${style.greenBright}(${buildTime(cssMinStart, cssMinEnd)})${style.reset}`)
311
+ }).catch((error) => {
312
+ console.log(`${style.redBright + style.bold}[error]${style.reset} Error occurred during CSS minification: ${style.dim}${error}${style.reset}`)
313
+ })
314
+
315
+ if (options.justMinified) {
316
+ fs.unlinkSync(outfilePath)
317
+ }
318
+ } else {
319
+ fs.unlinkSync(minPath)
320
+ }
321
+ }
322
+
323
+ // JS/TS Compiler
324
+ function compileScripts() {
325
+ if (!config.scripts) return
326
+ config.scripts = Array.isArray(config.scripts) ? config.scripts : [config.scripts]
327
+ for (const scriptEntry of config.scripts) {
328
+ if (scriptEntry.in && scriptEntry.out && pathExists(scriptEntry.in)) {
329
+ mkPath(scriptEntry.out)
330
+ compileScriptsEntry(scriptEntry.in, scriptEntry.out, scriptEntry.options)
331
+ }
332
+ }
333
+ }
334
+
335
+ function compileScriptsEntry(infilePath, outfilePath, options = {}) {
336
+ if (!Array.isArray(infilePath)) infilePath = [infilePath]
337
+
338
+ const opts = {
339
+ logLevel: 'error',
340
+ entryPoints: infilePath,
341
+ bundle: true,
342
+ sourcemap: false,
343
+ minify: false,
344
+ format: 'iife',
345
+ target: 'es2019',
346
+ nodePaths: config.includePaths // Resolve `includePaths`
347
+ }
348
+
349
+ const terserOpts = {
350
+ mangle: false
351
+ }
352
+
353
+ if (banner) {
354
+ opts.banner = {
355
+ js: banner,
356
+ css: banner
357
+ }
358
+ }
359
+
360
+ if (!pathForFile(outfilePath)) {
361
+ opts.outdir = outfilePath
362
+ } else {
363
+ if (infilePath.length > 1) {
364
+ console.log(`${style.redBright + style.bold}[error]${style.reset} Cannot output multiple ${style.bold + style.underline}script${style.reset} files to a single file. Please specify an output directory path instead.`)
365
+ process.exit(1)
366
+ }
367
+ opts.outfile = outfilePath
368
+ }
369
+
370
+ if (options.format) opts.format = options.format
371
+ if (options.target) opts.target = options.target
372
+ if (options.nodePaths) opts.nodePaths = [...new Set([...opts.nodePaths, ...options.nodePaths])]
373
+ if (options.sourcemap) opts.sourcemap = options.sourcemap
374
+
375
+ if (options.mangle) terserOpts.mangle = options.mangle
376
+
377
+ delete options.mangle
378
+ deepmerge(opts, options) // ability to pass other esbuild options `node_modules/esbuild/lib/main.d.ts`
379
+
380
+ // TODO: Actually loop the build process for each entry point!!!
381
+ const esbuildStart = performance.now()
382
+ build(opts).then(() => {
383
+ const esbuildEnd = performance.now()
384
+ for (const entry of infilePath) {
385
+ const newOutFilePath = buildScriptOutputFilePath(entry, outfilePath)
386
+ const minPath = insertMinSuffix(newOutFilePath)
387
+
388
+ if (!options.justMinified) console.log(`${style.yellowBright + style.bold}[script]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${newOutFilePath}${style.reset} ${style.greenBright}(${buildTime(esbuildStart, esbuildEnd)})${style.reset}`)
389
+ if (options.sourcemap) console.log(`${style.yellowBright + style.bold}[script]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${newOutFilePath}.map${style.reset}`)
390
+
391
+ if (options.minify) {
392
+ const terserStart = performance.now()
393
+ Terser.minify(fs.readFileSync(newOutFilePath, 'utf-8'), { mangle: terserOpts.mangle }).then((result) => {
394
+ if (result.error) {
395
+ console.log(`${style.redBright + style.bold}[error]${style.reset} Error occurred during JS minification: ${style.dim}${result.error}${style.reset}`)
396
+ } else {
397
+ if (banner) result.code = banner + '\n' + result.code
398
+ fs.writeFileSync(minPath, result.code)
399
+ const terserEnd = performance.now()
400
+ console.log(`${style.yellowBright + style.bold}[script]${style.reset} ${style.dim}Compiled:${style.reset} ${style.italic + style.underline}${minPath}${style.reset} ${style.greenBright}(${buildTime(terserStart, terserEnd)})${style.reset}`)
401
+ }
402
+ })
403
+
404
+ if (options.justMinified) {
405
+ fs.unlinkSync(newOutFilePath)
406
+ }
407
+ } else {
408
+ fs.unlinkSync(minPath)
409
+ }
410
+ }
411
+ })
412
+ }
413
+
414
+ // Main function 💩
415
+ function poop() {
416
+ if (config.livereload) {
417
+ const lrExcludes = ['.git', '.svn', '.hg']
418
+
419
+ if (config.watch) {
420
+ lrExcludes.push(...config.watch)
421
+ }
422
+
423
+ if (config.includePaths) {
424
+ lrExcludes.push(...config.includePaths)
425
+ }
426
+
427
+ if (config.livereload.exclude) {
428
+ lrExcludes.push(...config.livereload.exclude)
429
+ }
430
+
431
+ const lrserver = livereload.createServer({
432
+ exclusions: [...new Set(lrExcludes)],
433
+ port: config.livereload.port || 35729
434
+ })
435
+ console.log(`${style.cyanBright + style.bold}[info]${style.reset} ${style.dim}🔃 LiveReload server:${style.reset} ${style.italic + style.underline}http://localhost:${lrserver.config.port}${style.reset}`)
436
+ lrserver.watch(cwd)
437
+ }
438
+
439
+ compileStyles()
440
+ compileScripts()
441
+
442
+ if (config.watch) {
443
+ chokidar.watch(config.watch).on('change', (file) => {
444
+ if (/(\.js|\.ts)$/i.test(file)) compileScripts()
445
+ if (/(\.sass|\.scss|\.css)$/i.test(file)) compileStyles()
446
+ })
447
+ }
448
+
449
+ if (!config.watch && !config.livereload && !config.serve) {
450
+ process.exit(1)
451
+ }
452
+ }
package/poops.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "scripts": [{
3
+ "in": "src/js/main.ts",
4
+ "out": "dist/js/scripts.js",
5
+ "options": {
6
+ "sourcemap": true,
7
+ "minify": true,
8
+ "justMinified": false,
9
+ "format": "iife",
10
+ "target": "es2019",
11
+ "mangle": true
12
+ }
13
+ }],
14
+ "styles": [{
15
+ "in": "src/scss/index.scss",
16
+ "out": "dist/css/styles.css",
17
+ "options": {
18
+ "sourcemap": true,
19
+ "minify": true,
20
+ "justMinified": false
21
+ }
22
+ }],
23
+ "banner": "/* {{ name }} v{{ version }} | {{ homepage }} | {{ license }} License */",
24
+ "serve" : {
25
+ "port": 4040,
26
+ "base": "/"
27
+ },
28
+ "livereload": true,
29
+ "watch": [
30
+ "src"
31
+ ],
32
+ "includePaths": [
33
+ "node_modules"
34
+ ]
35
+ }
package/src/js/main.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { capitalize, calculateSum, formatDate } from './scripts/utils'
2
+
3
+ // Sample TypeScript code rendered by ChatGPT-3
4
+
5
+ class Person {
6
+ private name: string;
7
+ private age: number;
8
+
9
+ constructor(name: string, age: number) {
10
+ this.name = name;
11
+ this.age = age;
12
+ }
13
+
14
+ greet(): void {
15
+ console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
16
+ }
17
+ }
18
+
19
+ // Creating an instance of the Person class
20
+ const person = new Person("Stamat", new Date().getFullYear() - 1988);
21
+
22
+ // Accessing properties and calling methods
23
+ person.greet();
24
+
25
+ console.log(capitalize('hello')); // Output: Hello
26
+ console.log(calculateSum([1, 2, 3, 4, 5])); // Output: 15
27
+
28
+ const today = new Date();
29
+ console.log(formatDate(today)); // Output: YYYY-MM-DD
@@ -0,0 +1,16 @@
1
+ // Sample TypeScript code rendered by ChatGPT-3
2
+
3
+ export function capitalize(str: string): string {
4
+ return str.charAt(0).toUpperCase() + str.slice(1);
5
+ }
6
+
7
+ export function calculateSum(numbers: number[]): number {
8
+ return numbers.reduce((acc, num) => acc + num, 0);
9
+ }
10
+
11
+ export function formatDate(date: Date): string {
12
+ const year = date.getFullYear();
13
+ const month = `${date.getMonth() + 1}`.padStart(2, '0');
14
+ const day = `${date.getDate()}`.padStart(2, '0');
15
+ return `${year}-${month}-${day}`;
16
+ }
@@ -0,0 +1,2 @@
1
+ @import 'sulphuris/src/scss/core/index.scss';
2
+ @import 'style/index.scss';
@@ -0,0 +1,27 @@
1
+ body {
2
+ background-color: #DCC8AC;
3
+ margin: 0;
4
+ padding: 0;
5
+ font-family: 'DM Sans', Helvetica, Arial, sans-serif !important;
6
+ font-size: 24px !important;
7
+ line-height: 1.5;
8
+ }
9
+
10
+ header {
11
+ text-align: center;
12
+ }
13
+
14
+ header h1 {
15
+ font-family: 'Poppins', Helvetica, Arial, sans-serif !important;
16
+ font-weight: 700 !important;
17
+ font-size: 94px;
18
+ line-height: 1;
19
+ margin: 0;
20
+ color: #824F2D;
21
+ }
22
+
23
+ #poop {
24
+ font-size: 10rem;
25
+ display: inline-block;
26
+ margin-bottom: 24px;
27
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "experimentalDecorators": true,
4
+ "target": "es2019",
5
+ "module": "es2020",
6
+ "lib": ["es2019", "dom", "dom.iterable"],
7
+ "moduleResolution": "node",
8
+ "allowSyntheticDefaultImports": true,
9
+ "allowJs": true,
10
+ "checkJs": false,
11
+ "noEmit": true,
12
+ "strict": true,
13
+ "strictPropertyInitialization": false,
14
+ "resolveJsonModule": true
15
+ }
16
+ }