mirror of
https://codeberg.org/lucida/lucida-tagger.git
synced 2026-11-09 13:07:23 -05:00
initial commit
This commit is contained in:
13
.eslintignore
Normal file
13
.eslintignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
/test.js
|
||||
18
.eslintrc.cjs
Normal file
18
.eslintrc.cjs
Normal file
@@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020
|
||||
},
|
||||
env: {
|
||||
browser: false,
|
||||
es2017: true,
|
||||
node: true
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'warn'
|
||||
}
|
||||
}
|
||||
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/package
|
||||
/config.json
|
||||
/temp
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
/test.js
|
||||
/tmp
|
||||
12
.prettierignore
Normal file
12
.prettierignore
Normal file
@@ -0,0 +1,12 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
8
.prettierrc
Normal file
8
.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"semi": false,
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"pluginSearchDirs": ["."]
|
||||
}
|
||||
54
LICENSE.md
Normal file
54
LICENSE.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# 🏳️🌈 Opinionated Queer License v1.1
|
||||
|
||||
© Copyright hazycora
|
||||
|
||||
## Permissions
|
||||
|
||||
The creators of this Work (“The Licensor”) grant permission
|
||||
to any person, group or legal entity that doesn't violate the prohibitions below (“The User”),
|
||||
to do everything with this Work that would otherwise infringe their copyright or any patent claims,
|
||||
subject to the following conditions:
|
||||
|
||||
## Obligations
|
||||
|
||||
The User must give appropriate credit to the Licensor,
|
||||
provide a copy of this license or a (clickable, if the medium allows) link to
|
||||
[oql.avris.it/license/v1.1](https://oql.avris.it/license/v1.1),
|
||||
and indicate whether and what kind of changes were made.
|
||||
The User may do so in any reasonable manner,
|
||||
but not in any way that suggests the Licensor endorses the User or their use.
|
||||
|
||||
## Prohibitions
|
||||
|
||||
No one may use this Work for prejudiced or bigoted purposes, including but not limited to:
|
||||
racism, xenophobia, queerphobia, queer exclusionism, homophobia, transphobia, enbyphobia, misogyny.
|
||||
|
||||
No one may use this Work to inflict or facilitate violence or abuse of human rights as defined in the
|
||||
[Universal Declaration of Human Rights](https://www.un.org/en/about-us/universal-declaration-of-human-rights).
|
||||
|
||||
No law enforcement, carceral institutions, immigration enforcement entities, military entities or military contractors
|
||||
may use the Work for any reason. This also applies to any individuals employed by those entities.
|
||||
|
||||
No business entity where the ratio of pay (salaried, freelance, stocks, or other benefits)
|
||||
between the highest and lowest individual in the entity is greater than 50 : 1
|
||||
may use the Work for any reason.
|
||||
|
||||
No private business run for profit with more than a thousand employees
|
||||
may use the Work for any reason.
|
||||
|
||||
Unless the User has made substantial changes to the Work,
|
||||
or uses it only as a part of a new work (eg. as a library, as a part of an anthology, etc.),
|
||||
they are prohibited from selling the Work.
|
||||
That prohibition includes processing the Work with machine learning models.
|
||||
|
||||
## Sanctions
|
||||
|
||||
If the Licensor notifies the User that they have not complied with the rules of the license,
|
||||
they can keep their license by complying within 30 days after the notice.
|
||||
If they do not do so, their license ends immediately.
|
||||
|
||||
## Warranty
|
||||
|
||||
This Work is provided “as is”, without warranty of any kind, express or implied.
|
||||
The Licensor will not be liable to anyone for any damages related to the Work or this license,
|
||||
under any kind of legal claim as far as the law allows.
|
||||
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# lucida-tagger
|
||||
|
||||
Adding tags to audio files in JS (works in-browser). Currently only supports `flac` files, but ogg vorbis is planned.
|
||||
mp3 support may be added with a 3rd party dependency.
|
||||
|
||||
lucida-tagger is made for use with lucida, so it uses its type for metadata.
|
||||
33
package.json
Normal file
33
package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "lucida-tagger",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "build/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"tsc": "tsc",
|
||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||
"format": "prettier --plugin-search-dir . --write ."
|
||||
},
|
||||
"keywords": [
|
||||
"tagging",
|
||||
"metadata",
|
||||
"audio",
|
||||
"flac",
|
||||
"vorbis"
|
||||
],
|
||||
"author": "hazycora",
|
||||
"license": "OQL",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||
"@typescript-eslint/parser": "^5.59.11",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"prettier": "^2.8.8",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucida": "2.0.0-3"
|
||||
}
|
||||
}
|
||||
1345
pnpm-lock.yaml
generated
Normal file
1345
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
198
src/containers/flac.ts
Normal file
198
src/containers/flac.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
import { CoverArtwork, Track } from 'lucida/build/types.js'
|
||||
import { concatBuffers, getUint24, setUint24, lengthAndData, uint32 } from '../utils.js'
|
||||
|
||||
interface MetadataBlock {
|
||||
type: number
|
||||
data: Uint8Array
|
||||
}
|
||||
function encodeMetadataBlocks(blocks: MetadataBlock[]) {
|
||||
return concatBuffers(
|
||||
...blocks.map((block: MetadataBlock, i: number) => {
|
||||
const data = new Uint8Array(4)
|
||||
const view = new DataView(data.buffer)
|
||||
let flags = block.type
|
||||
if (i == blocks.length - 1) flags = flags | 0b10000000
|
||||
view.setUint8(0, flags)
|
||||
setUint24(view, block.data.byteLength, 1)
|
||||
return concatBuffers(data, block.data)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
interface CommentBlockData {
|
||||
[key: string]: string[]
|
||||
}
|
||||
|
||||
interface CommentBlock {
|
||||
vendor: string
|
||||
data: CommentBlockData
|
||||
}
|
||||
|
||||
export function decodeVorbisCommentBlock(typedArray: Uint8Array): CommentBlock {
|
||||
const decoder = new TextDecoder()
|
||||
const slice = typedArray.buffer.slice(
|
||||
typedArray.byteOffset,
|
||||
typedArray.byteOffset + typedArray.byteLength
|
||||
)
|
||||
const view = new DataView(slice)
|
||||
const vendorLength = view.getUint32(0, true)
|
||||
const vendor = decoder.decode(slice.slice(4, 4 + vendorLength))
|
||||
const commentCount = view.getUint32(4 + vendorLength, true)
|
||||
let offset = 4 + vendorLength + 4
|
||||
const data: CommentBlockData = {}
|
||||
for (let i = 0; i < commentCount; i++) {
|
||||
const commentLength = view.getUint32(offset, true)
|
||||
offset += 4
|
||||
const comment = decoder.decode(slice.slice(offset, offset + commentLength)).split('=')
|
||||
if (comment.length != 2) throw new Error(`Comment doesn't have key value pair.`)
|
||||
const [key, value] = comment
|
||||
if (data[key]) {
|
||||
data[key].push(value)
|
||||
} else {
|
||||
data[key] = [value]
|
||||
}
|
||||
offset += commentLength
|
||||
}
|
||||
return {
|
||||
vendor,
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
function encodeVorbisCommentBlock(info: CommentBlock): Uint8Array {
|
||||
const commentCount = new Uint8Array(4)
|
||||
const commentCountView = new DataView(commentCount.buffer)
|
||||
commentCountView.setUint32(0, Object.values(info.data).flat().length, true)
|
||||
|
||||
return concatBuffers(
|
||||
lengthAndData(info.vendor, true),
|
||||
commentCount,
|
||||
...Object.keys(info.data)
|
||||
.map((key) => {
|
||||
return info.data[key].map((value) => [key, value].join('='))
|
||||
})
|
||||
.flat()
|
||||
.map((e) => lengthAndData(e, true))
|
||||
)
|
||||
}
|
||||
|
||||
export function decode(typedArray: Uint8Array) {
|
||||
const view = new DataView(typedArray.buffer)
|
||||
const streamMarker = view.getUint32(0)
|
||||
if (streamMarker != 0x664c6143) throw new Error('File is not a flac')
|
||||
let i = 4
|
||||
let reachedFinalMetadata = false
|
||||
const metadataBlocks = []
|
||||
while (!reachedFinalMetadata) {
|
||||
const metadataBlockFlags = view.getUint8(i)
|
||||
reachedFinalMetadata = (metadataBlockFlags & 0b10000000) > 0
|
||||
const metadataBlockType = metadataBlockFlags & 0b01111111
|
||||
i += 1
|
||||
const metadataBlockSize = getUint24(view, i)
|
||||
i += 3
|
||||
metadataBlocks.push({
|
||||
type: metadataBlockType,
|
||||
data: typedArray.slice(i, i + metadataBlockSize)
|
||||
})
|
||||
i += metadataBlockSize
|
||||
}
|
||||
const restOfData = typedArray.slice(i, typedArray.byteLength)
|
||||
|
||||
const vorbisIndex = metadataBlocks.findIndex((e) => e.type == 4)
|
||||
|
||||
const result: {
|
||||
metadataBlocks: MetadataBlock[]
|
||||
restOfData: Uint8Array
|
||||
vorbisComments?: CommentBlock
|
||||
} = {
|
||||
metadataBlocks,
|
||||
restOfData
|
||||
}
|
||||
|
||||
if (vorbisIndex) {
|
||||
result.vorbisComments = decodeVorbisCommentBlock(metadataBlocks[vorbisIndex].data)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default async function encodeTags(
|
||||
typedArray: Uint8Array,
|
||||
metadata: Track
|
||||
): Promise<Uint8Array> {
|
||||
const decodedData = decode(typedArray)
|
||||
let metadataBlocks = decodedData.metadataBlocks
|
||||
const restOfData = decodedData.restOfData
|
||||
|
||||
metadataBlocks = metadataBlocks.filter((e) => e.type == 0)
|
||||
const vorbisIndex = metadataBlocks.length
|
||||
|
||||
const commentData: CommentBlockData = {
|
||||
TITLE: [metadata.title],
|
||||
ARTIST: metadata.artists.map((artist) => artist.name)
|
||||
}
|
||||
if (metadata.isrc) commentData.ISRC = [metadata.isrc]
|
||||
if (metadata.album) {
|
||||
commentData.ALBUM = [metadata.album.title]
|
||||
if (metadata.album.releaseDate) {
|
||||
const releaseDate =
|
||||
typeof metadata.album.releaseDate == 'string'
|
||||
? new Date(metadata.album.releaseDate)
|
||||
: metadata.album.releaseDate
|
||||
const dateStr = `${releaseDate.getFullYear()}-${releaseDate.getMonth()}-${releaseDate.getDate()}`
|
||||
commentData.DATE = [dateStr]
|
||||
}
|
||||
if (metadata.album.upc) commentData.UPC = [metadata.album.upc]
|
||||
if (metadata.album.artists) commentData.ALBUM_ARTIST = metadata.album.artists.map((e) => e.name)
|
||||
}
|
||||
if (metadata.composers) commentData.COMPOSER = metadata.composers
|
||||
if (metadata.producers) commentData.PRODUCER = metadata.producers
|
||||
if (metadata.lyricists) commentData.LYRICIST = metadata.lyricists
|
||||
if (metadata.copyright) commentData.COPYRIGHT = [metadata.copyright]
|
||||
if (metadata.trackNumber) {
|
||||
commentData.TRACKNUMBER = [metadata.trackNumber.toString()]
|
||||
commentData.DISCNUMBER = [(metadata.discNumber ?? 1).toString()]
|
||||
}
|
||||
if (metadata.explicit != undefined) commentData.EXPLICIT = [metadata.explicit.toString()]
|
||||
commentData.DESCRIPTION = [`Downloaded from ${metadata.url}`]
|
||||
|
||||
metadataBlocks[vorbisIndex] = {
|
||||
type: 4,
|
||||
data: encodeVorbisCommentBlock({
|
||||
vendor: 'lucida-tagger',
|
||||
data: commentData
|
||||
})
|
||||
}
|
||||
|
||||
if (metadata.album?.coverArtwork ?? metadata.coverArtwork) {
|
||||
let coverArtwork: CoverArtwork | undefined
|
||||
if (metadata.album?.coverArtwork) {
|
||||
coverArtwork = metadata.album?.coverArtwork[metadata.album.coverArtwork.length - 1]
|
||||
} else {
|
||||
coverArtwork = metadata.coverArtwork?.[metadata.coverArtwork.length - 1]
|
||||
}
|
||||
if (!coverArtwork) throw new Error('no cover artwork despite if block (this is impossible)')
|
||||
const coverResp = await fetch(coverArtwork.url)
|
||||
const mimeType = coverResp.headers.get('content-type')?.split(';')[0]
|
||||
if (!mimeType) throw new Error('Cover artwork has no mime type')
|
||||
|
||||
metadataBlocks.push({
|
||||
type: 6,
|
||||
data: concatBuffers(
|
||||
uint32(3),
|
||||
lengthAndData(mimeType),
|
||||
uint32(0),
|
||||
uint32(coverArtwork.width),
|
||||
uint32(coverArtwork.height),
|
||||
uint32(24),
|
||||
uint32(0),
|
||||
lengthAndData(new Uint8Array(await coverResp.arrayBuffer()))
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return concatBuffers(
|
||||
new Uint8Array([0x66, 0x4c, 0x61, 0x43]),
|
||||
encodeMetadataBlocks(metadataBlocks),
|
||||
restOfData
|
||||
)
|
||||
}
|
||||
19
src/index.ts
Normal file
19
src/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Track } from 'lucida/build/types.js'
|
||||
import flac from './containers/flac.js'
|
||||
|
||||
type SupportedMimeTypes = 'audio/flac'
|
||||
|
||||
export default {
|
||||
encodeTags(
|
||||
mimeType: SupportedMimeTypes,
|
||||
typedArray: Uint8Array,
|
||||
metadata: Track
|
||||
): Promise<Uint8Array> {
|
||||
switch (mimeType) {
|
||||
case 'audio/flac':
|
||||
return flac(typedArray, metadata)
|
||||
default:
|
||||
throw new Error(`Mime type ${mimeType} not supported`)
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/utils.ts
Normal file
44
src/utils.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
export function uint32(value: number, littleEndian = false) {
|
||||
const arr = new Uint8Array(4)
|
||||
const view = new DataView(arr.buffer)
|
||||
view.setUint32(0, value, littleEndian)
|
||||
return arr
|
||||
}
|
||||
|
||||
export function lengthAndData(data: string | Uint8Array, littleEndian = false) {
|
||||
if (data.length == 0) return uint32(0)
|
||||
if (typeof data == 'string') {
|
||||
const encoder = new TextEncoder()
|
||||
const typedArray = encoder.encode(data)
|
||||
return concatBuffers(uint32(typedArray.byteLength, littleEndian), typedArray)
|
||||
}
|
||||
return concatBuffers(uint32(data.byteLength, littleEndian), data)
|
||||
}
|
||||
|
||||
function concatTwoBuffers(buffer1: Uint8Array, buffer2?: Uint8Array): Uint8Array {
|
||||
if (!buffer2) return buffer1
|
||||
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
|
||||
tmp.set(buffer1, 0)
|
||||
tmp.set(buffer2, buffer1.byteLength)
|
||||
return tmp
|
||||
}
|
||||
|
||||
export function concatBuffers(...buffers: Uint8Array[]) {
|
||||
function couples(arr: Uint8Array[]): Uint8Array[] {
|
||||
return arr
|
||||
.flatMap((_, i, a) => (i % 2 ? [] : [a.slice(i, i + 2)]))
|
||||
.map((e) => concatTwoBuffers(e[0], e[1] ?? undefined))
|
||||
}
|
||||
while (buffers.length > 1) {
|
||||
buffers = couples(buffers)
|
||||
}
|
||||
return buffers[0]
|
||||
}
|
||||
|
||||
export function getUint24(view: DataView, pos = 0) {
|
||||
return (view.getUint16(pos) << 8) + view.getUint8(pos + 2)
|
||||
}
|
||||
export function setUint24(view: DataView, val: number, pos = 0) {
|
||||
view.setUint16(pos, val >> 8)
|
||||
view.setUint8(pos + 2, val & ~4294967040) // this "magic number" masks off the first 16 bits
|
||||
}
|
||||
110
tsconfig.json
Normal file
110
tsconfig.json
Normal file
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "es6" /* Specify what module code is generated. */,
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
|
||||
// "inlineSourceMap": true /* Include sourcemap files inside the emitted JavaScript. */,
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./build" /* Specify an output folder for all emitted files. */,
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
Reference in New Issue
Block a user