From 1b46749a3389c1d82be76e79ba149b9cc8b16852 Mon Sep 17 00:00:00 2001 From: Sebastien Villar Date: Tue, 30 Aug 2022 18:23:38 +0200 Subject: [PATCH] Add template --- .eslintrc.cjs | 800 ++++++++++++++++++++++++++++++++++++ .gitignore | 17 + .npmignore | 18 + .prettierrc.json | 25 ++ README.md | 1 + configs/tsconfig.cjs.json | 7 + configs/tsconfig.esm.json | 7 + configs/tsconfig.types.json | 12 + package.json | 35 ++ scripts/build.js | 111 +++++ tsconfig.json | 108 +++++ 11 files changed, 1141 insertions(+) create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .prettierrc.json create mode 100644 README.md create mode 100644 configs/tsconfig.cjs.json create mode 100644 configs/tsconfig.esm.json create mode 100644 configs/tsconfig.types.json create mode 100644 package.json create mode 100755 scripts/build.js create mode 100644 tsconfig.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..253bb59 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,800 @@ +module.exports = { + env: { + node: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:import/typescript', + ], + plugins: ['@typescript-eslint', 'import'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'es2022', + project: './tsconfig.json', + }, + overrides: [ + { + files: ['*.ts', '*.tsx'], + }, + ], + rules: { + 'import/no-unresolved': 0, + 'import/first': 'error', + 'import/no-duplicates': 'error', + 'import/order': [ + 'error', + { + groups: ['external', 'builtin', 'index', 'unknown', 'sibling', 'parent', 'internal', 'object', 'type'], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + 'import/newline-after-import': 'error', + + // ---------------------- + // Possible errors + + // disallow use of console + 'no-console': 'error', + + // disallow template literal placeholder syntax in regular strings + 'no-template-curly-in-string': 'error', + + // ---------------------- + // Best practices + + // enforces return statements in callbacks of array's methods + // http://eslint.org/docs/rules/array-callback-return + 'array-callback-return': 'error', + + // treat var statements as if they were block scoped + 'block-scoped-var': 'error', + + // require return statements to either always or never specify values + 'consistent-return': 'error', + + // specify curly brace conventions for all control statements + curly: ['error', 'multi-line'], + + // enforce default case in switch statements + 'default-case': 'error', + + // enforce default clauses in switch statements to be last + 'default-case-last': 'error', + + // enforces consistent newlines before or after dots + // http://eslint.org/docs/rules/dot-location + 'dot-location': ['error', 'property'], + + // encourages use of dot notation whenever possible + 'dot-notation': ['error', {allowKeywords: true}], + + // require the use of === and !== + // http://eslint.org/docs/rules/eqeqeq + eqeqeq: ['error', 'always', {null: 'ignore'}], + + // make sure for-in loops have an if statement + 'guard-for-in': 'error', + + // disallow the use of alert, confirm, and prompt + 'no-alert': 'warn', + + // disallow use of arguments.caller or arguments.callee + 'no-caller': 'error', + + // disallow else after a return in an if + 'no-else-return': 'error', + + // disallow empty functions, except for standalone funcs/arrows + // http://eslint.org/docs/rules/no-empty-function + 'no-empty-function': [ + 'error', + { + allow: ['arrowFunctions', 'functions', 'methods'], + }, + ], + + // disallow use of eval() + 'no-eval': 'error', + + // disallow adding to native types + 'no-extend-native': 'error', + + // disallow unnecessary function binding + 'no-extra-bind': 'error', + + // disallow Unnecessary Labels + // http://eslint.org/docs/rules/no-extra-label + 'no-extra-label': 'error', + + // disallow the use of leading or trailing decimal points in numeric literals + 'no-floating-decimal': 'error', + + // disallow use of eval()-like methods + 'no-implied-eval': 'error', + + // disallow usage of __iterator__ property + 'no-iterator': 'error', + + // disallow use of labels for anything other then loops and switches + 'no-labels': [ + 'error', + { + allowLoop: false, + allowSwitch: false, + }, + ], + + // disallow unnecessary nested blocks + 'no-lone-blocks': 'error', + + // disallow creation of functions within loops + 'no-loop-func': 'error', + + // disallow use of multiple spaces + 'no-multi-spaces': 'error', + + // disallow use of multiline strings + 'no-multi-str': 'error', + + // disallow use of new operator when not part of the assignment or comparison + 'no-new': 'error', + + // disallow use of new operator for Function object + 'no-new-func': 'error', + + // disallows creating new instances of String, Number, and Boolean + 'no-new-wrappers': 'error', + + // disallow use of octal escape sequences in string literals, such as + // var foo = 'Copyright \251'; + 'no-octal-escape': 'error', + + // disallow reassignment of function parameters + // disallow parameter object manipulation except for specific exclusions + // rule: http://eslint.org/docs/rules/no-param-reassign.html + 'no-param-reassign': [ + 'error', + { + props: true, + ignorePropertyModificationsFor: [ + 'acc', // for reduce accumulators + 'e', // for e.returnvalue + 'ctx', // for Koa routing + 'req', // for Express requests + 'request', // for Express requests + 'res', // for Express responses + 'response', // for Express responses + '$scope', // for Angular 1 scopes + ], + }, + ], + + // disallow usage of __proto__ property + 'no-proto': 'error', + + // disallow certain object properties + // http://eslint.org/docs/rules/no-restricted-properties + 'no-restricted-properties': [ + 'error', + { + object: 'arguments', + property: 'callee', + message: 'arguments.callee is deprecated', + }, + { + property: '__defineGetter__', + message: 'Please use Object.defineProperty instead.', + }, + { + property: '__defineSetter__', + message: 'Please use Object.defineProperty instead.', + }, + { + object: 'Math', + property: 'pow', + message: 'Use the exponentiation operator (**) instead.', + }, + ], + + // disallow use of assignment in return statement + 'no-return-assign': 'error', + + // disallow redundant `return await` + 'no-return-await': 'error', + + // disallow use of `javascript:` urls. + 'no-script-url': 'error', + + // disallow comparisons where both sides are exactly the same + 'no-self-compare': 'error', + + // disallow use of comma operator + 'no-sequences': 'error', + + // restrict what can be thrown as an exception + 'no-throw-literal': 'error', + + // disallow useless string concatenation + // http://eslint.org/docs/rules/no-useless-concat + 'no-useless-concat': 'error', + + // disallow redundant return; keywords + // http://eslint.org/docs/rules/no-useless-return + 'no-useless-return': 'error', + + // disallow use of void operator + // http://eslint.org/docs/rules/no-void + 'no-void': 'error', + + // require use of the second argument for parseInt() + radix: 'error', + + // requires to declare all vars on top of their containing scope + 'vars-on-top': 'error', + + // require immediate function invocation to be wrapped in parentheses + // http://eslint.org/docs/rules/wrap-iife.html + 'wrap-iife': ['error', 'outside', {functionPrototypeMethods: false}], + + // require or disallow Yoda conditions + yoda: 'error', + + // ---------------------- + // Variables + + // disallow labels that share a name with a variable + // http://eslint.org/docs/rules/no-label-var + 'no-label-var': 'error', + + // disallow use of undefined when initializing variables + 'no-undef-init': 'error', + + // disallow use of variables before they are defined + 'no-use-before-define': 'off', + + // ---------------------- + // Stylistic issues + + // enforce spacing inside array brackets + 'array-bracket-spacing': ['error', 'never'], + + // enforce spacing inside single-line blocks + // http://eslint.org/docs/rules/block-spacing + 'block-spacing': ['error', 'always'], + + // enforce one true brace style + 'brace-style': [ + 'error', + '1tbs', + { + allowSingleLine: true, + }, + ], + + // require camel case names + camelcase: [ + 'error', + { + properties: 'never', + }, + ], + + // require trailing commas in multiline object literals + 'comma-dangle': [ + 'error', + { + arrays: 'always-multiline', + objects: 'always-multiline', + imports: 'always-multiline', + exports: 'always-multiline', + functions: 'always-multiline', + }, + ], + + // enforce one true comma style + 'comma-style': ['error', 'last'], + + // disallow padding inside computed properties + 'computed-property-spacing': ['error', 'never'], + + // enforce newline at the end of file, with no multiple empty lines + 'eol-last': ['error', 'always'], + + // enforce spacing between functions and their invocations + // http://eslint.org/docs/rules/func-call-spacing + 'func-call-spacing': ['error', 'never'], + + // require function expressions to have a name + // http://eslint.org/docs/rules/func-names + 'func-names': 'warn', + + // specify whether double or single quotes should be used in JSX attributes + // http://eslint.org/docs/rules/jsx-quotes + 'jsx-quotes': ['error', 'prefer-double'], + + // enforces spacing between keys and values in object literal properties + 'key-spacing': [ + 'error', + { + beforeColon: false, + afterColon: true, + }, + ], + + // disallow mixed 'LF' and 'CRLF' as linebreaks + // http://eslint.org/docs/rules/linebreak-style + 'linebreak-style': ['off', 'unix'], + + // require a capital letter for constructors + 'new-cap': [ + 'error', + { + newIsCap: true, + newIsCapExceptions: [], + capIsNew: false, + capIsNewExceptions: ['Immutable.Map', 'Immutable.Set', 'Immutable.List'], + }, + ], + + // disallow the omission of parentheses when invoking a constructor with no arguments + // http://eslint.org/docs/rules/new-parens + 'new-parens': 'error', + + // enforces new line after each method call in the chain to make it + // more readable and easy to maintain + // http://eslint.org/docs/rules/newline-per-chained-call + 'newline-per-chained-call': [ + 'error', + { + ignoreChainWithDepth: 4, + }, + ], + + // disallow use of the Array constructor + 'no-array-constructor': 'error', + + // disallow use of bitwise operators + // http://eslint.org/docs/rules/no-bitwise + 'no-bitwise': 'error', + + // disallow if as the only statement in an else block + // http://eslint.org/docs/rules/no-lonely-if + 'no-lonely-if': 'error', + + // disallow use of chained assignment expressions + // http://eslint.org/docs/rules/no-multi-assign + 'no-multi-assign': ['error'], + + // disallow multiple empty lines and only one newline at the end + 'no-multiple-empty-lines': [ + 'error', + { + max: 1, + maxEOF: 1, + }, + ], + + // disallow nested ternary expressions + 'no-nested-ternary': 'error', + + // disallow use of the Object constructor + 'no-new-object': 'error', + + // disallow certain syntax forms + // http://eslint.org/docs/rules/no-restricted-syntax + 'no-restricted-syntax': [ + 'error', + { + selector: 'ForInStatement', + message: + 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.', + }, + { + selector: 'ForOfStatement', + message: + 'iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.', + }, + { + selector: 'LabeledStatement', + message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.', + }, + { + selector: 'WithStatement', + message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', + }, + // These next 2 selectors combine force switchImpossibleCase to be the first statement of a switch default case + { + selector: + 'SwitchStatement > SwitchCase[test=null] > BlockStatement:first-child > :first-child:not(ExpressionStatement[expression.callee.name="switchImpossibleCase"])', + message: '`switchImpossibleCase` should be the first statement of a switch default case - or disable rule if all cases cannot be enumerated', + }, + { + selector: + 'SwitchStatement > SwitchCase[test=null] > :first-child:not(:matches(BlockStatement, ExpressionStatement[expression.callee.name="switchImpossibleCase"]))', + message: '`switchImpossibleCase` should be the first statement of a switch default case - or disable rule if all cases cannot be enumerated', + }, + ], + + // disallow tab characters entirely + 'no-tabs': 'error', + + // disallow trailing whitespace at the end of lines + 'no-trailing-spaces': 'error', + + // disallow dangling underscores in identifiers + 'no-underscore-dangle': [ + 'error', + { + allowAfterThis: false, + }, + ], + + // disallow the use of Boolean literals in conditional expressions + // also, prefer `a || b` over `a ? a : b` + // http://eslint.org/docs/rules/no-unneeded-ternary + 'no-unneeded-ternary': [ + 'error', + { + defaultAssignment: false, + }, + ], + + // disallow whitespace before properties + // http://eslint.org/docs/rules/no-whitespace-before-property + 'no-whitespace-before-property': 'error', + + // require padding inside curly braces + 'object-curly-spacing': ['error', 'never'], + + // enforce "same line" or "multiple line" on object properties. + // http://eslint.org/docs/rules/object-property-newline + 'object-property-newline': [ + 'error', + { + allowMultiplePropertiesPerLine: true, + }, + ], + + // allow just one var statement per function + 'one-var': ['error', 'never'], + + // require a newline around variable declaration + // http://eslint.org/docs/rules/one-var-declaration-per-line + 'one-var-declaration-per-line': ['error', 'always'], + + // require assignment operator shorthand where possible or prohibit it entirely + // http://eslint.org/docs/rules/operator-assignment + 'operator-assignment': ['error', 'always'], + + // enforce padding within blocks + 'padded-blocks': ['error', 'never'], + + // require quotes around object literal property names + // http://eslint.org/docs/rules/quote-props.html + 'quote-props': [ + 'error', + 'as-needed', + { + keywords: false, + unnecessary: true, + numbers: true, + }, + ], + + // specify whether double or single quotes should be used + quotes: [ + 'error', + 'single', + { + avoidEscape: true, + }, + ], + + // require or disallow use of semicolons instead of ASI + semi: ['error', 'always'], + + // enforce spacing before and after semicolons + 'semi-spacing': [ + 'error', + { + before: false, + after: true, + }, + ], + + // require or disallow space before blocks + 'space-before-blocks': 'error', + + // require or disallow space before function opening parenthesis + // http://eslint.org/docs/rules/space-before-function-paren + 'space-before-function-paren': [ + 'error', + { + anonymous: 'always', + named: 'never', + asyncArrow: 'always', + }, + ], + + // require or disallow spaces inside parentheses + 'space-in-parens': ['error', 'never'], + + // require spaces around operators + 'space-infix-ops': 'error', + + // Require or disallow spaces before/after unary operators + // http://eslint.org/docs/rules/space-unary-ops + 'space-unary-ops': [ + 'error', + { + words: true, + nonwords: false, + overrides: {}, + }, + ], + + // require or disallow a space immediately following the // or /* in a comment + // http://eslint.org/docs/rules/spaced-comment + 'spaced-comment': [ + 'error', + 'always', + { + line: { + exceptions: ['-', '+'], + markers: ['=', '!'], // space here to support sprockets directives + }, + block: { + exceptions: ['-', '+'], + markers: ['=', '!'], // space here to support sprockets directives + balanced: false, + }, + }, + ], + + // require or disallow the Unicode Byte Order Mark + // http://eslint.org/docs/rules/unicode-bom + 'unicode-bom': ['error', 'never'], + + // ---------------------- + // ECMAScript 6 + + // require parens in arrow function arguments + // http://eslint.org/docs/rules/arrow-parens + 'arrow-parens': [ + 'error', + 'always', + { + requireForBlockBody: true, + }, + ], + + // require space before/after arrow function's arrow + // http://eslint.org/docs/rules/arrow-spacing + 'arrow-spacing': [ + 'error', + { + before: true, + after: true, + }, + ], + + // enforce no spacing around the * in generator functions (it's not supported by prettier) + // http://eslint.org/docs/rules/generator-star-spacing + 'generator-star-spacing': [ + 'error', + { + before: false, + after: false, + }, + ], + + // disallow arrow functions where they could be confused with comparisons + // http://eslint.org/docs/rules/no-confusing-arrow + 'no-confusing-arrow': [ + 'error', + { + allowParens: true, + }, + ], + + // disallow useless computed property keys + // http://eslint.org/docs/rules/no-useless-computed-key + 'no-useless-computed-key': 'error', + + // disallow unnecessary constructor + // http://eslint.org/docs/rules/no-useless-constructor + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', + + // disallow renaming import, export, and destructured assignments to the same name + // http://eslint.org/docs/rules/no-useless-rename + 'no-useless-rename': [ + 'error', + { + ignoreDestructuring: false, + ignoreImport: false, + ignoreExport: false, + }, + ], + + // require let or const instead of var + 'no-var': 'error', + + // require method and property shorthand syntax for object literals + // http://eslint.org/docs/rules/object-shorthand + 'object-shorthand': [ + 'error', + 'always', + { + ignoreConstructors: false, + avoidQuotes: true, + }, + ], + + // suggest using arrow functions as callbacks + 'prefer-arrow-callback': [ + 'error', + { + allowNamedFunctions: false, + allowUnboundThis: true, + }, + ], + + // suggest using of const declaration for variables that are never modified after declared + 'prefer-const': 'off', + + // disallow parseInt() in favor of binary, octal, and hexadecimal literals + // http://eslint.org/docs/rules/prefer-numeric-literals + 'prefer-numeric-literals': 'error', + + // use rest parameters instead of arguments + // http://eslint.org/docs/rules/prefer-rest-params + 'prefer-rest-params': 'error', + + // suggest using the spread operator instead of .apply() + // http://eslint.org/docs/rules/prefer-spread + 'prefer-spread': 'error', + + // suggest using template literals instead of string concatenation + // http://eslint.org/docs/rules/prefer-template + 'prefer-template': 'error', + + // enforce spacing between object rest-spread + // http://eslint.org/docs/rules/rest-spread-spacing + 'rest-spread-spacing': ['error', 'never'], + + // require a Symbol description + // http://eslint.org/docs/rules/symbol-description + 'symbol-description': 'error', + + // enforce usage of spacing in template strings + // http://eslint.org/docs/rules/template-curly-spacing + 'template-curly-spacing': 'error', + + // enforce spacing around the * in yield* expressions + // http://eslint.org/docs/rules/yield-star-spacing + 'yield-star-spacing': ['error', 'after'], + + // ---------------------- + // Deprecated + + // require or disallow newlines around directives + // http://eslint.org/docs/rules/lines-around-directive + 'lines-around-directive': [ + 'error', + { + before: 'always', + after: 'always', + }, + ], + + // disallow space between function identifier and application + 'no-spaced-func': 'error', + + // disallow using location global since we should use history + 'no-restricted-globals': ['error', 'name', 'length', 'event', 'location'], + + // ---------------------- + // Others + 'sort-imports': [ + 'error', + { + ignoreDeclarationSort: true, + ignoreCase: true, + }, + ], + + // ---------------------- + // plugin:@typescript-eslint/recommended + + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-misused-promises': 'off', + '@typescript-eslint/no-floating-promises': 'off', + + // Bans // @ts- comments from being used or requires descriptions after directive + '@typescript-eslint/ban-ts-comment': 'off', + + // Bans specific types from being used + '@typescript-eslint/ban-types': 'off', + + // Require explicit return and argument types on exported functions' and classes' public class methods + '@typescript-eslint/explicit-module-boundary-types': 'off', + + // Disallow empty functions + '@typescript-eslint/no-empty-function': 'off', + + // Disallow the declaration of empty interfaces + '@typescript-eslint/no-empty-interface': 'off', + + // Disallow usage of the any type + '@typescript-eslint/no-explicit-any': 'off', + + // Disallow extra non-null assertion + '@typescript-eslint/no-extra-non-null-assertion': 'off', + + // Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean + '@typescript-eslint/no-inferrable-types': 'off', + + // Disallow the use of custom TypeScript modules and namespaces + '@typescript-eslint/no-namespace': 'off', + + // Disallows using a non-null assertion after an optional chain expression + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + + // Disallows non-null assertions using the ! postfix operator + '@typescript-eslint/no-non-null-assertion': 'off', + + // Disallow unused variables + '@typescript-eslint/no-unused-vars': [ + 'error', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'none', + ignoreRestSiblings: true, + }, + ], + + // Disallows the use of require statements except in import statements + '@typescript-eslint/no-var-requires': 'off', + + // Prefer usage of as const over literal type + '@typescript-eslint/prefer-as-const': 'off', + + // ---------------------- + // Extension Rules + + // disallow usage of expressions in statement position + '@typescript-eslint/no-unused-expressions': [ + 'error', + { + allowShortCircuit: true, + allowTernary: false, + allowTaggedTemplates: false, + }, + ], + + // Disallow variable declarations from shadowing variables declared in the outer scope. + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': [ + 'error', + { + ignoreFunctionTypeParameterNameValueShadow: true, + }, + ], + + // Enforces consistent spacing before and after commas. + 'comma-spacing': 'off', + '@typescript-eslint/comma-spacing': ['error'], + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be52416 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.idea/ +.DS_Store +node_modules/ +npm-debug.log.* +yarn-error.log +dist/ +.env +.vscode/* + +## MacOS +.DS_Store + +## User settings +xcuserdata/ + +## Config +*.xcconfig diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..ed2b822 --- /dev/null +++ b/.npmignore @@ -0,0 +1,18 @@ +# Same as .gitignore but does not ignore the dist folder + +.idea/ +.DS_Store +node_modules/ +npm-debug.log.* +yarn-error.log +.env +.vscode/* + +## MacOS +.DS_Store + +## User settings +xcuserdata/ + +## Config +*.xcconfig diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..243501c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,25 @@ +{ + "tabWidth": 2, + "printWidth": 160, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": false, + "trailingComma": "all", + "bracketSpacing": false, + "jsxBracketSameLine": false, + "arrowParens": "always", + "overrides": [ + { + "files": ".prettierrc", + "options": { + "parser": "json" + } + }, + { + "files": "*.ejs", + "options": { + "parser": "html" + } + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..79a8ff4 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Height CLI \ No newline at end of file diff --git a/configs/tsconfig.cjs.json b/configs/tsconfig.cjs.json new file mode 100644 index 0000000..295af71 --- /dev/null +++ b/configs/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "module": "commonjs", + "outDir": "../dist/cjs" + } +} diff --git a/configs/tsconfig.esm.json b/configs/tsconfig.esm.json new file mode 100644 index 0000000..9fd01eb --- /dev/null +++ b/configs/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "module": "ESNext", + "outDir": "../dist/esm" + } +} diff --git a/configs/tsconfig.types.json b/configs/tsconfig.types.json new file mode 100644 index 0000000..a645ede --- /dev/null +++ b/configs/tsconfig.types.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "../dist/types", + }, + "tsc-alias": { + "verbose": false, + "resolveFullPaths": true, + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..24f7494 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "@heightapp/cli", + "version": "1.0.0", + "description": "", + "type": "module", + "engines": { + "node": ">=16.0.0" + }, + "bin": { + "height": "dist/esm/cli.js" + }, + "scripts": { + "build": "NODE_ENV=production ./scripts/build.js --esm", + "dev": "NODE_ENV=development ./scripts/build.js --esm && node dist/esm/cli.js", + "debug": "HEIGHT_DEBUG=true npm run dev", + "lint": "eslint ./src", + "prepare": "npm run build" + }, + "repository": "git+https://github.com/heightapp/cli.git", + "author": "Height", + "license": "MIT", + "bugs": { + "url": "https://github.com/heightapp/cli/issues" + }, + "homepage": "https://github.com/heightapp/cli#readme", + "devDependencies": { + "@types/node": "^18.6.2", + "@typescript-eslint/eslint-plugin": "^5.31.0", + "@typescript-eslint/parser": "^5.31.0", + "esbuild": "^0.14.53", + "eslint": "^8.20.0", + "eslint-plugin-import": "^2.26.0", + "typescript": "^4.7.4" + }, +} diff --git a/scripts/build.js b/scripts/build.js new file mode 100755 index 0000000..5db647a --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,111 @@ +#! /usr/bin/env node + +import {exec as execSync} from 'child_process'; +import esbuild from 'esbuild'; +import fs from 'fs'; +import yargs from 'yargs/yargs'; +import {hideBin} from 'yargs/helpers'; +import util from 'util'; +import path from 'path'; + +const exec = util.promisify(execSync); + +const args = yargs(hideBin(process.argv)) + .option('esm', { + describe: 'Generate esm bundle', + type: 'boolean', + }) + .option('cjs', { + describe: 'Generate cjs bundel', + type: 'boolean', + }) + .option('types', { + describe: 'Generate types', + type: 'boolean', + }).argv; + +const entryPoints = ['src/cli.ts', 'src/watch.ts']; + +const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf-8')); +const external = Object.keys({ + ...(packageJson.dependencies || {}), + ...(packageJson.devDependencies || {}), + ...(packageJson.peerDependencies || {}), + ...(packageJson.optionalDependencies || {}), +}); + +const cleanup = () => { + fs.rmSync('./dist', {recursive: true, force: true}); +}; + +const outDirFromConfig = (configPath) => { + const config = JSON.parse(fs.readFileSync(configPath, {encoding: 'utf-8'})); + const outDir = config.compilerOptions.outDir; + return path.resolve('./config', outDir); +}; + +// Define node env statically since we want this to be part of the build +// and not depend on the user's environment. +const define = { + 'process.env.NODE_ENV': `"${process.env.NODE_ENV ?? 'development'}"`, + 'process.env.HEIGHT_DEBUG': `${process.env.HEIGHT_DEBUG ?? 'false'}`, +}; + +const build = async () => { + // Remove the directory before building or moving files fails on Windows (does not override) + cleanup(); + + try { + const config = { + entryPoints, + bundle: true, + external, + platform: 'node', + treeShaking: true, + define, + }; + + const promises = []; + + // Build ESM + if (args.esm) { + const tsconfig = 'configs/tsconfig.esm.json'; + const outdir = outDirFromConfig(tsconfig); + promises.push( + esbuild.build({ + ...config, + outdir, + format: 'esm', + tsconfig, + }), + ); + } + + // Build CJS + if (args.cjs) { + const tsconfig = 'configs/tsconfig.cjs.json'; + const outdir = outDirFromConfig(tsconfig); + promises.push( + esbuild.build({ + ...config, + outdir, + format: 'cjs', + tsconfig, + }), + ); + } + + // Build types + if (args.types) { + const tsconfig = './configs/tsconfig.types.json'; + promises.push(exec(`tsc --project ${tsconfig} && tsc-alias --project ${tsconfig}`)); + } + + await Promise.all(promises); + } catch (e) { + console.error(e.message); + process.exit(1); + } +}; + +build(); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2857086 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,108 @@ +{ + "include": ["./src", "./.eslintrc.cjs"], + "tsc-alias": { + "verbose": false, + "resolveFullPaths": true + }, + "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": "ES2022" /* 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 TC39 stage 2 draft 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": "esnext" /* 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": "./src/" /* 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. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''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. */ + // "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": "./dist/", /* 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. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "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. */ + "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. */ + } +}