diff --git a/.editorconfig b/.editorconfig index 383d55b..dbb8cd3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,7 +2,7 @@ root = true [*] indent_style = space -indent_size = 4 +indent_size = 2 charset = utf-8 trim_trailing_whitespace = false insert_final_newline = false diff --git a/package-lock.json b/package-lock.json index 022a077..9a730d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,23 @@ "js-tokens": "^4.0.0" } }, + "@babel/runtime": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + } + } + }, "@hapi/bourne": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", @@ -65,6 +82,59 @@ "safe-buffer": "^5.1.2" } }, + "@redux-saga/core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.1.1.tgz", + "integrity": "sha512-WKXfj2cYkP0eh74dE1ueMjVDoGJIkppXiMFgx0buVRkXENeZmRxIjM4lh9LEWWFqay7I/Qkw7+cMossa7xXoAQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.0", + "@redux-saga/deferred": "^1.1.0", + "@redux-saga/delay-p": "^1.1.0", + "@redux-saga/is": "^1.1.0", + "@redux-saga/symbols": "^1.1.0", + "@redux-saga/types": "^1.1.0", + "redux": "^4.0.4", + "typescript-tuple": "^2.2.1" + } + }, + "@redux-saga/deferred": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redux-saga/deferred/-/deferred-1.1.0.tgz", + "integrity": "sha512-wOCJCby3hx14bvrEeFLJ1JJTjJdXDJyC+B3JQ6eiqgzNghylbf969lIYmS2Arf2QuALfUtRBNPXBIMDKG9km4g==", + "dev": true + }, + "@redux-saga/delay-p": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redux-saga/delay-p/-/delay-p-1.1.0.tgz", + "integrity": "sha512-BcRwXs20kKjgiYEwZARkpVoRIe/hHftW3iwPhdeW4/jPyR9gLv/vG8VsJMF5NDEch+/w/mJtdgSubq+wtOS47g==", + "dev": true, + "requires": { + "@redux-saga/symbols": "^1.1.0" + } + }, + "@redux-saga/is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redux-saga/is/-/is-1.1.0.tgz", + "integrity": "sha512-0uFXWGSvDCfNBdROHwEVixNhFbI3S+UGBQfcPXQiYL+CjIjyR3DTg2Z+NFH9xzP+H4Oh/yGtTHDhC0GxYp7HQQ==", + "dev": true, + "requires": { + "@redux-saga/symbols": "^1.1.0", + "@redux-saga/types": "^1.1.0" + } + }, + "@redux-saga/symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redux-saga/symbols/-/symbols-1.1.0.tgz", + "integrity": "sha512-Fzw1wV3j4hbac3MYmgNE18Z53URmQZeilTHZLF7Lm4SQ1jG4fcU47v2kElsEbQXUSaFqj+uJqdRzmDGNb6pRwQ==", + "dev": true + }, + "@redux-saga/types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redux-saga/types/-/types-1.1.0.tgz", + "integrity": "sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg==", + "dev": true + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -170,6 +240,22 @@ "@types/express": "*" } }, + "@types/history": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.3.tgz", + "integrity": "sha512-cS5owqtwzLN5kY+l+KgKdRJ/Cee8tlmQoGQuIE9tWnSmS3JMKzmxo2HIAk2wODMifGwO20d62xZQLYz+RLfXmw==", + "dev": true + }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.2.tgz", @@ -254,6 +340,12 @@ "integrity": "sha512-eAdu+NW1IkCdmp85SnhyKha+OOREQMT9lXaoICQxa7bhSauRiLzu3WSNt9Mf2piuJvWeXF/G0hGWHr63xNpIRA==", "dev": true }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, "@types/pug": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz", @@ -265,6 +357,58 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, + "@types/react": { + "version": "16.9.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.9.tgz", + "integrity": "sha512-L+AudFJkDukk+ukInYvpoAPyJK5q1GanFOINOJnM0w6tUgITuWvJ4jyoBPFL7z4/L8hGLd+K/6xR5uUjXu0vVg==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/react-dom": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.2.tgz", + "integrity": "sha512-hgPbBoI1aTSTvZwo8HYw35UaTldW6n2ETLvHAcfcg1FaOuBV3olmyCe5eMpx2WybWMBPv0MdU2t5GOcQhP+3zA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-redux": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.5.tgz", + "integrity": "sha512-ZoNGQMDxh5ENY7PzU7MVonxDzS1l/EWiy8nUhDqxFqUZn4ovboCyvk4Djf68x6COb7vhGTKjyjxHxtFdAA5sUA==", + "dev": true, + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, + "@types/react-router": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.2.tgz", + "integrity": "sha512-euC3SiwDg3NcjFdNmFL8uVuAFTpZJm0WMFUw+4eXMUnxa7M9RGFEG0szt0z+/Zgk4G2k9JBFhaEnY64RBiFmuw==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react-router-dom": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.0.tgz", + "integrity": "sha512-YCh8r71pL5p8qDwQf59IU13hFy/41fDQG/GeOI3y+xmD4o0w3vEPxE8uBe+dvOgMoDl0W1WUZsWH0pxc1mcZyQ==", + "dev": true, + "requires": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, "@types/serve-static": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", @@ -369,41 +513,6 @@ "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", "dev": true }, - "@vue/component-compiler-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.0.0.tgz", - "integrity": "sha512-am+04/0UX7ektcmvhYmrf84BDVAD8afFOf4asZjN84q8xzxFclbk5x0MtxuKGfp+zjN5WWPJn3fjFAWtDdIGSw==", - "dev": true, - "requires": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.14", - "postcss-selector-parser": "^5.0.0", - "prettier": "1.16.3", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -1464,15 +1573,6 @@ "date-now": "^0.1.4" } }, - "consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "dev": true, - "requires": { - "bluebird": "^3.1.1" - } - }, "constantinople": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", @@ -1683,10 +1783,10 @@ } } }, - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "csstype": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", + "integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==", "dev": true }, "csurf": { @@ -1758,12 +1858,6 @@ "meow": "^3.3.0" } }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, "debounce": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", @@ -3279,6 +3373,12 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3335,12 +3435,6 @@ "safe-buffer": "^5.0.1" } }, - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -3351,12 +3445,6 @@ "minimalistic-assert": "^1.0.1" } }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, "helmet": { "version": "3.21.2", "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.2.tgz", @@ -3407,6 +3495,20 @@ "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3418,6 +3520,15 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "dev": true, + "requires": { + "react-is": "^16.7.0" + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -3576,6 +3687,15 @@ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -3915,6 +4035,15 @@ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -4115,15 +4244,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -4192,6 +4312,17 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mini-create-react-context": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz", + "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.0", + "gud": "^1.0.0", + "tiny-warning": "^1.0.2" + } + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -5060,17 +5191,6 @@ "postcss": "^7.0.6" } }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dev": true, - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "postcss-value-parser": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz", @@ -5100,12 +5220,6 @@ "xtend": "^4.0.0" } }, - "prettier": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", - "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", - "dev": true - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -5132,6 +5246,17 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -5147,12 +5272,6 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -5396,6 +5515,99 @@ } } }, + "react": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz", + "integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.11.0.tgz", + "integrity": "sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.17.0" + } + }, + "react-is": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", + "integrity": "sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==", + "dev": true + }, + "react-redux": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.1.tgz", + "integrity": "sha512-QsW0vcmVVdNQzEkrgzh2W3Ksvr8cqpAv5FhEk7tNEft+5pp7rXxAudTz3VOPawRkLIepItpkEIyLcN/VVXzjTg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.9.0" + } + }, + "react-router": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz", + "integrity": "sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.3.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "react-router-dom": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.2.tgz", + "integrity": "sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.1.2", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -5475,6 +5687,25 @@ "strip-indent": "^1.0.1" } }, + "redux": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", + "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "redux-saga": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.1.1.tgz", + "integrity": "sha512-guSnGJ/uEF8yL8Mn4aNa7HxRGCpVUALCkec9iTTD0fOhQqkF6bRQkBLeS+7/cAH3nFnr299bi/DOurTi1apcCA==", + "dev": true, + "requires": { + "@redux-saga/core": "^1.1.1" + } + }, "referrer-policy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", @@ -5577,6 +5808,12 @@ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -5649,6 +5886,16 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "scheduler": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", + "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -6211,6 +6458,12 @@ "has-flag": "^3.0.0" } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -6305,6 +6558,18 @@ "next-tick": "1" } }, + "tiny-invariant": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz", + "integrity": "sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==", + "dev": true + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "dev": true + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -6466,11 +6731,6 @@ "tsconfig": "^7.0.0" } }, - "ts-vue-plugin": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ts-vue-plugin/-/ts-vue-plugin-0.1.2.tgz", - "integrity": "sha512-Vj1ErgEuXDvb4eEEJVHLcGEK6GMF5OF+YONjFFiWPoalQe9uh/KXACc6ZhiDFvqF47q/Iv0xyLQYEQ0qQxSG0w==" - }, "tsconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", @@ -6601,6 +6861,30 @@ "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", "dev": true }, + "typescript-compare": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", + "integrity": "sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA==", + "dev": true, + "requires": { + "typescript-logic": "^0.0.0" + } + }, + "typescript-logic": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz", + "integrity": "sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q==", + "dev": true + }, + "typescript-tuple": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz", + "integrity": "sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q==", + "dev": true, + "requires": { + "typescript-compare": "^0.0.2" + } + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", @@ -6826,6 +7110,12 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6842,57 +7132,6 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" }, - "vue": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", - "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==", - "dev": true - }, - "vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", - "dev": true - }, - "vue-loader": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.1.tgz", - "integrity": "sha512-fwIKtA23Pl/rqfYP5TSGK7gkEuLhoTvRYW+TU7ER3q9GpNLt/PjG5NLv3XHRDiTg7OPM1JcckBgds+VnAc+HbA==", - "dev": true, - "requires": { - "@vue/component-compiler-utils": "^3.0.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - } - }, - "vue-style-loader": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", - "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", - "dev": true, - "requires": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "vue-template-compiler": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", - "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==", - "dev": true, - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", - "dev": true - }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/package.json b/package.json index ef76162..a8daeea 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "pg-promise": "^9.3.3", "pino": "^5.13.5", "pug": "^2.0.4", - "ts-vue-plugin": "^0.1.2", "tweetnacl": "^1.0.1", "tweetnacl-util": "^0.15.0", "yargs": "^14.2.0" @@ -50,11 +49,23 @@ "@types/node": "^12.11.2", "@types/pg": "^7.11.2", "@types/pino": "^5.8.12", + "@types/react": "^16.9.9", + "@types/react-dom": "^16.9.2", + "@types/react-redux": "^7.1.5", + "@types/react-router": "^5.1.2", + "@types/react-router-dom": "^5.1.0", "@types/webpack-dev-middleware": "^2.0.3", "@types/yargs": "^13.0.3", "css-loader": "^3.2.0", "pg-monitor": "^1.3.1", "pino-pretty": "^3.2.2", + "react": "^16.11.0", + "react-dom": "^16.11.0", + "react-redux": "^7.1.1", + "react-router": "^5.1.2", + "react-router-dom": "^5.1.2", + "redux": "^4.0.4", + "redux-saga": "^1.1.1", "ts-loader": "^6.2.0", "ts-node": "^8.4.1", "ts-node-dev": "^1.0.0-pre.43", @@ -62,9 +73,6 @@ "tslint": "^5.20.0", "tslint-config-prettier": "^1.18.0", "typescript": "^3.6.4", - "vue": "^2.6.10", - "vue-loader": "^15.7.1", - "vue-template-compiler": "^2.6.10", "webpack": "^4.41.2", "webpack-cli": "^3.3.9", "webpack-dev-middleware": "^3.7.2" diff --git a/src/frontend/App.vue b/src/frontend/App.vue deleted file mode 100644 index 3402ec9..0000000 --- a/src/frontend/App.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/src/frontend/api/tasks.ts b/src/frontend/api/tasks.ts new file mode 100644 index 0000000..8820429 --- /dev/null +++ b/src/frontend/api/tasks.ts @@ -0,0 +1,34 @@ +import { DateTime } from "luxon"; + +export interface Task { + id: number; + name: string; + due: DateTime; +} + +const tasks: Task[] = [...Array(5).keys()].map(n => ({ + id: n, + name: `Task ${n}`, + due: DateTime.local().plus({ weeks: n }) +})); + +export const getTasks = async (): Promise => + new Promise((resolve, reject) => + setTimeout(() => resolve(tasks), 3000) + ); + +export const schedule = async (task: Omit): Promise => + new Promise((resolve, reject) => + setTimeout(() => { + const id = Math.max(...tasks.map(t => t.id)) + 1; + tasks[id] = { ...task, id }; + resolve(tasks[id]); + }, 3000) + ); + +export const unschedule = async (taskId: number): Promise => + new Promise((resolve, reject) => + setTimeout(() => { + delete tasks[taskId]; + }, 3000) + ); diff --git a/src/frontend/components/App.tsx b/src/frontend/components/App.tsx new file mode 100644 index 0000000..c7f0c6d --- /dev/null +++ b/src/frontend/components/App.tsx @@ -0,0 +1,25 @@ +import * as React from "react"; +import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom"; +import TaskList from "./TaskList"; + +export default () => +
+ + + + + About things, yay! + + + + + +
+
+ diff --git a/src/frontend/components/TaskList.tsx b/src/frontend/components/TaskList.tsx new file mode 100644 index 0000000..9222f6d --- /dev/null +++ b/src/frontend/components/TaskList.tsx @@ -0,0 +1,36 @@ +import { AppState } from "@kredens/frontend/store"; +import { deleteTask, scheduleTask } from "@kredens/frontend/store/tasks/actions"; +import { Task, TaskScheduleType } from "@kredens/frontend/store/tasks/types"; +import React, { useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; + +export default () => { + const [taskName, setTaskName] = useState(""); + const tasks = useSelector(state => state.tasks.items); + const dispatch = useDispatch(); + + const onTaskAddClick = () => { + dispatch(scheduleTask(Math.random().toString(36), { + name: taskName, + schedule: { type: TaskScheduleType.Plain } + })) + }; + + const onTaskDeleteClick = (id: string) => { + dispatch(deleteTask(id)) + }; + + return ( + <> +
    + { + Object.entries(tasks).map(([id, task]) => ( +
  • {task.name}
  • + )) + } +
+ setTaskName(ev.target.value)} /> + + + ); +} diff --git a/src/frontend/index.ts b/src/frontend/index.tsx similarity index 66% rename from src/frontend/index.ts rename to src/frontend/index.tsx index efd269c..0d87c17 100644 --- a/src/frontend/index.ts +++ b/src/frontend/index.tsx @@ -13,19 +13,19 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import Vue from "vue"; -import App from "./App.vue"; +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { Provider } from "react-redux"; +import App from "./components/App"; +import configureStore from "./store"; -export const app = new Vue({ - components: { - App - }, - el: "#body", - render(createElement) { - return createElement(App, { - props: { - message: "blab" - } - }); - } -}); + +const store = configureStore(); + +const Root = () => ( + + + +); + +ReactDOM.render(, document.getElementById("body")); diff --git a/src/frontend/store/index.ts b/src/frontend/store/index.ts new file mode 100644 index 0000000..20b96d4 --- /dev/null +++ b/src/frontend/store/index.ts @@ -0,0 +1,14 @@ +import { combineReducers, createStore } from "redux"; +import { tasksReducer } from "./tasks/reducers"; + +const rootReducer = combineReducers({ + tasks: tasksReducer +}); + +export type AppState = ReturnType; + +export default function configureStore() { + const store = createStore(rootReducer); + + return store; +} diff --git a/src/frontend/store/tasks/actions.ts b/src/frontend/store/tasks/actions.ts new file mode 100644 index 0000000..0fe0435 --- /dev/null +++ b/src/frontend/store/tasks/actions.ts @@ -0,0 +1,16 @@ +import { Task, TasksAction, TasksActionType } from "./types"; + +export function scheduleTask(id: string, task: Task): TasksActionType { + return { + type: TasksAction.SCHEDULE_TASK, + id, + task + }; +} + +export function deleteTask(id: string): TasksActionType { + return { + type: TasksAction.DELETE_TASK, + id + }; +} diff --git a/src/frontend/store/tasks/reducers.ts b/src/frontend/store/tasks/reducers.ts new file mode 100644 index 0000000..118ce7b --- /dev/null +++ b/src/frontend/store/tasks/reducers.ts @@ -0,0 +1,31 @@ +import { TasksAction, TasksActionType, TasksState } from "./types"; + +const initialState: TasksState = { + items: {} +}; + +export function tasksReducer( + state = initialState, + action?: TasksActionType +): TasksState { + switch (action.type) { + case TasksAction.SCHEDULE_TASK: + return { + ...state, + items: { + ...state.items, + [action.id]: action.task + } + }; + case TasksAction.DELETE_TASK: + return { + ...state, + items: Object.entries(state.items) + .filter(([key]) => key !== action.id) + .reduce((res, [key, task]) => ({ ...res, [key]: task }), {}) + }; + default: { + return state; + } + } +} diff --git a/src/frontend/store/tasks/types.ts b/src/frontend/store/tasks/types.ts new file mode 100644 index 0000000..1ace47d --- /dev/null +++ b/src/frontend/store/tasks/types.ts @@ -0,0 +1,44 @@ +export enum TaskScheduleType { + Once, + Plain +} + +export interface TaskScheduleOnce { + type: TaskScheduleType.Once; + due: string; +} + +export interface TaskSchedulePlain { + type: TaskScheduleType.Plain; +} + +export type TaskSchedule = TaskScheduleOnce | TaskSchedulePlain; + +export interface Task { + name: string; + schedule: TaskSchedule; +} + +export interface TasksState { + items: { + [key: string]: Task; + }; +} + +export enum TasksAction { + SCHEDULE_TASK = "SCHEDULE_TASK", + DELETE_TASK = "DELETE_TASK" +} + +interface ScheduleTaskAction { + type: typeof TasksAction.SCHEDULE_TASK; + id: string; + task: Task; +} + +interface DeleteTaskAction { + type: typeof TasksAction.DELETE_TASK; + id: string; +} + +export type TasksActionType = ScheduleTaskAction | DeleteTaskAction; diff --git a/src/frontend/tslint.json b/src/frontend/tslint.json index 4555a9d..e5414e7 100644 --- a/src/frontend/tslint.json +++ b/src/frontend/tslint.json @@ -1,6 +1,6 @@ { "extends": "../../tslint.json", "rules": { - "no-implicit-dependencies": [true, "dev"] + "no-implicit-dependencies": [true, "dev", ["@kredens/frontend"]] } } \ No newline at end of file diff --git a/src/frontend/vue-shim.d.ts b/src/frontend/vue-shim.d.ts deleted file mode 100644 index cdcc639..0000000 --- a/src/frontend/vue-shim.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2019 ModZero -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -declare module "*.vue" { - import Vue from "vue"; - export default Vue; -} diff --git a/src/routes/index.ts b/src/routes/index.ts index e858234..d1b9294 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -17,9 +17,9 @@ import express from "express"; import authRouter from "./auth"; import homeRouter from "./home"; -const router = express.Router(); +const router = express.Router({ strict: true }); -router.use("/", homeRouter); -router.use("/auth", authRouter); +router.use("/auth$", authRouter); +router.use("/*", homeRouter); export default router; diff --git a/tsconfig.json b/tsconfig.json index 9e56bba..6e3b42c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,8 @@ "sourceMap": true, "outDir": "./dist", "moduleResolution": "node", + "jsx": "react", + "noImplicitThis": true, "baseUrl": "./src", "paths": { "@kredens/*": [ diff --git a/tslint.json b/tslint.json index fb6c578..821e80c 100644 --- a/tslint.json +++ b/tslint.json @@ -11,7 +11,7 @@ "vue-loader/lib/plugin", "@kredens" ], - "no-implicit-dependencies": [true, ["@kredens"]], + "no-implicit-dependencies": [true, ["@kredens", "@kredens/frontend"]], "object-literal-sort-keys": [true, "match-declaration-order-only", "shorthand-first"], "max-classes-per-file": false }, diff --git a/webpack.config.ts b/webpack.config.ts index 48ab253..81c7715 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -1,33 +1,29 @@ import path from "path"; -import VueLoaderPlugin from "vue-loader/lib/plugin"; // tslint:disable-line:no-implicit-dependencies import webpack from "webpack"; // tslint:disable-line:no-implicit-dependencies const config: webpack.Configuration = { - devtool: "inline-source-map", - entry: "./src/frontend/index.ts", mode: "development", - module: { - rules: [ - { - exclude: /node_modules/, - loader: "ts-loader", - options: { appendTsSuffixTo: [/\.vue$/] }, - test: /\.ts?$/ - }, - { - loader: "vue-loader", - test: /.vue$/ - } - ] - }, + entry: "./src/frontend/index.tsx", + devtool: "inline-source-map", output: { filename: "[name].bundle.js", path: path.resolve(__dirname, "dist"), publicPath: "/assets/" }, - plugins: [new VueLoaderPlugin()], + module: { + rules: [ + { + exclude: /node_modules/, + loader: "ts-loader", + test: /\.tsx?$/ + } + ] + }, resolve: { - extensions: [".ts", ".js"] + extensions: [".ts", ".tsx", ".js"], + alias: { + "@kredens": path.resolve(__dirname, "src/") + } } };