From b35e4e36e2212a5afc321dd9ee1276ad2e401036 Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Mon, 14 Oct 2019 23:42:43 +0300 Subject: [PATCH] unstable typescript --- .babelrc | 17 -- next-env.d.ts | 2 + package-lock.json | 356 +++++++++++++++++++++++++-- package.json | 9 +- pages/api/articles/index.js | 15 +- pages/api/pages/index.js | 3 - pages/{index.jsx => index.tsx} | 0 server.tsconfig.json | 14 ++ src/api/{articles.js => articles.ts} | 0 src/core/Article.js | 117 --------- src/core/Article.ts | 136 ++++++++++ src/core/{Data.js => Data.ts} | 4 +- src/core/Page.js | 93 ------- src/core/Page.ts | 102 ++++++++ src/core/{db.js => db.ts} | 13 +- src/lib/{store.js => store.ts} | 10 +- src/middlewares/withCollection.js | 7 +- src/{server.js => server.ts} | 17 +- tsconfig.json | 29 +++ 19 files changed, 658 insertions(+), 286 deletions(-) delete mode 100644 .babelrc create mode 100644 next-env.d.ts rename pages/{index.jsx => index.tsx} (100%) create mode 100644 server.tsconfig.json rename src/api/{articles.js => articles.ts} (100%) delete mode 100644 src/core/Article.js create mode 100644 src/core/Article.ts rename src/core/{Data.js => Data.ts} (88%) delete mode 100644 src/core/Page.js create mode 100644 src/core/Page.ts rename src/core/{db.js => db.ts} (86%) rename src/lib/{store.js => store.ts} (52%) rename src/{server.js => server.ts} (76%) create mode 100644 tsconfig.json diff --git a/.babelrc b/.babelrc deleted file mode 100644 index de974502..00000000 --- a/.babelrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "presets": [ - [ - "env", - { - "targets": { - "node": "8.5.0" - } - } - ] - ], - "plugins": [ - "transform-react-jsx", - "@babel/plugin-proposal-object-rest-spread", - "transform-class-properties" - ] -} \ No newline at end of file diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 00000000..7b7aa2c7 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/package-lock.json b/package-lock.json index f53f6aa5..06f00aac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1529,27 +1529,124 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz", - "integrity": "sha512-r4zJOMbKY5puETm8+cIpaa0RQZG/sSASW1u0pj8qYklcERgVIbxVbP2wyJA7zI1//h7lEagQmXi9IL9iI5rfsA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz", + "integrity": "sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.5.0", + "@babel/helper-create-class-features-plugin": "^7.6.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-typescript": "^7.2.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", + "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "requires": { + "@babel/types": "^7.6.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, "@babel/helper-create-class-features-plugin": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz", - "integrity": "sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", + "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", "requires": { "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", "@babel/helper-optimise-call-expression": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-replace-supers": "^7.5.5", "@babel/helper-split-export-declaration": "^7.4.4" } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "requires": { + "@babel/types": "^7.5.5" + } + }, + "@babel/helper-replace-supers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.5.5", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } + }, + "@babel/parser": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", + "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==" + }, + "@babel/traverse": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.3", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" } } }, @@ -1720,12 +1817,13 @@ } }, "@babel/preset-typescript": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz", - "integrity": "sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.6.0.tgz", + "integrity": "sha512-4xKw3tTcCm0qApyT6PqM9qniseCE79xGHiUnNdKGdxNsGUc2X7WwZybqIpnTmoukg3nhPceI5KPNzNqLNeIJww==", + "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-typescript": "^7.3.2" + "@babel/plugin-transform-typescript": "^7.6.0" } }, "@babel/register": { @@ -1862,12 +1960,162 @@ } } }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", + "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cookies": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz", + "integrity": "sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", + "integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.9", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz", + "integrity": "sha512-GqpaVWR0DM8FnRUJYKlWgyARoBUAVfRIeVDZQKOttLFp5SmhhF9YFIYeTPwMd/AXfxlP7xVO2dj1fGu0Q+krKQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/http-assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", + "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==", + "dev": true + }, + "@types/keygrip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", + "integrity": "sha1-/1QEYtL7TQqIRBzq8n0oewHD2Hg=", + "dev": true + }, + "@types/koa": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.0.50.tgz", + "integrity": "sha512-TcgOD2lh0EISSadAk1DOBYw7kNoY9XdeB3vEMOKiDDaTMYm+V54nyPsU7Ulb/htb5OBIR79RgTeCWntCcophLw==", + "dev": true, + "requires": { + "@types/accepts": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "@types/koa-compose": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.4.tgz", + "integrity": "sha512-ioou0rxkuWL+yBQYsHUQAzRTfVxAg8Y2VfMftU+Y3RA03/MzuFL0x/M2sXXj3PkfnENbHsjeHR1aMdezLYpTeA==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-route": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/koa-route/-/koa-route-3.2.4.tgz", + "integrity": "sha512-jB4I4/HppiHiSFMqQvMC2Px5Zm8CExA7Bw7xW+o60xh4v0LrNTfKV7LMCGuJNRuUuTTiRcJvF1rbq5mINgQ1UQ==", + "dev": true, + "requires": { + "@types/koa": "*", + "path-to-regexp": "^1.7.0" + } + }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", + "dev": true + }, + "@types/node": { + "version": "12.7.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz", + "integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==", + "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/q": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", "dev": true }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/react": { + "version": "16.9.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.5.tgz", + "integrity": "sha512-jQ12VMiFOWYlp+j66dghOWcmDDwhca0bnlcTxS4Qz/fh5gi6wpaZDthPEu/Gc/YlAuO87vbiUXL8qKstFvuOaA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -2282,6 +2530,12 @@ "readable-stream": "^2.0.6" } }, + "arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, "argparse": { "version": "1.0.9", "resolved": "http://storage.mds.yandex.net/get-npm/69187/argparse-1.0.9.tgz", @@ -2559,9 +2813,9 @@ }, "dependencies": { "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" } } }, @@ -5235,6 +5489,12 @@ } } }, + "csstype": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz", + "integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==", + "dev": true + }, "currently-unhandled": { "version": "0.4.1", "resolved": "http://storage.mds.yandex.net/get-npm/38095/currently-unhandled-0.4.1.tgz", @@ -8415,6 +8675,12 @@ } } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "mamacro": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", @@ -9346,6 +9612,15 @@ "worker-farm": "1.7.0" }, "dependencies": { + "@babel/preset-typescript": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz", + "integrity": "sha512-mzMVuIP4lqtn4du2ynEfdO0+RYcslwrZiJHXu4MGaC1ctJiW2fyaeDrtjJGs7R/KebZ1sgowcIoWf4uRpEfKEg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.3.2" + } + }, "acorn": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz", @@ -15541,6 +15816,43 @@ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", "dev": true }, + "ts-node": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", + "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "dependencies": { + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", @@ -15594,6 +15906,12 @@ "resolved": "http://storage.mds.yandex.net/get-npm/35308/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "dev": true + }, "ua-parser-js": { "version": "0.7.14", "resolved": "http://storage.mds.yandex.net/get-npm/66641/ua-parser-js-0.7.14.tgz", @@ -16617,6 +16935,12 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package.json b/package.json index 60c7800a..069a7dd7 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "main": "src/bin/www.js", "scripts": { "start": "NODE_ENV=production node src/server.js", - "dev": "node src/server.js", + "dev": "ts-node --project server.tsconfig.json src/server.ts", "build": "next build && next export -o dist && npm run sitemap && npm run feed && npm run robots-txt", "robots-txt": "node scripts/robots-txt.js", "sitemap": "node scripts/sitemap.js", @@ -54,7 +54,12 @@ "@babel/plugin-proposal-object-rest-spread": "^7.4.4", "@babel/polyfill": "^7.0.0-beta.47", "@babel/preset-env": "^7.4.5", + "@babel/preset-typescript": "^7.6.0", "@babel/register": "^7.0.0-beta.47", + "@types/koa": "^2.0.50", + "@types/koa-route": "^3.2.4", + "@types/node": "^12.7.12", + "@types/react": "^16.9.5", "@zeit/next-css": "^1.0.1", "@zeit/next-sass": "^1.0.1", "autoprefixer": "^6.3.6", @@ -73,6 +78,8 @@ "mocha": "^6.1.4", "node-sass": "^4.12.0", "should": "^8.2.2", + "ts-node": "^8.4.1", + "typescript": "^3.6.4", "webpack": "^4.32.2" } } diff --git a/pages/api/articles/index.js b/pages/api/articles/index.js index 35347033..4a14b725 100644 --- a/pages/api/articles/index.js +++ b/pages/api/articles/index.js @@ -1,15 +1,14 @@ -import { connect } from '../../../src/core/db' -import { findArticles } from '../../../src/api/articles' +// import { findArticles } from '../../../src/api/articles' import { withMiddleware } from '../../../src/middlewares/withMiddleware' +import Article from '../../../src/core/Article' export default withMiddleware(async (req, res) => { - await connect() + // const { query } = req + // const page = parseInt(query.page) + // const pageSize = parseInt(query.pageSize) - const { query } = req - const page = parseInt(query.page) - const pageSize = parseInt(query.pageSize) - - const data = await findArticles(page, pageSize) + // const data = await findArticles(page, pageSize) + const data = await Article.find({}) if (data) { res.json(data) diff --git a/pages/api/pages/index.js b/pages/api/pages/index.js index 2977f0d2..05950b09 100644 --- a/pages/api/pages/index.js +++ b/pages/api/pages/index.js @@ -1,10 +1,7 @@ -import { connect } from '../../../src/core/db' import Page from '../../../src/core/Page' import { withMiddleware } from '../../../src/middlewares/withMiddleware' export default withMiddleware(async (req, res) => { - await connect() - const items = await Page.find({}) if (items) { diff --git a/pages/index.jsx b/pages/index.tsx similarity index 100% rename from pages/index.jsx rename to pages/index.tsx diff --git a/server.tsconfig.json b/server.tsconfig.json new file mode 100644 index 00000000..22bafc4f --- /dev/null +++ b/server.tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "noEmitOnError": false, + "target": "es5", + "module": "commonjs", + "jsx": "preserve", + "outDir": "./build", + "strict": false, + "esModuleInterop": true + }, + "include": [ + "src/**/*.ts" + ] +} \ No newline at end of file diff --git a/src/api/articles.js b/src/api/articles.ts similarity index 100% rename from src/api/articles.js rename to src/api/articles.ts diff --git a/src/core/Article.js b/src/core/Article.js deleted file mode 100644 index 7336dc91..00000000 --- a/src/core/Article.js +++ /dev/null @@ -1,117 +0,0 @@ -const Data = require('./Data') -const Image = require('./Image') -const Config = require('./Config') -const {find, findOne, total} = require('../lib/store') - -const store = () => Data.getStore(Article) - -function make(C) { - return x => new C(x) -} - -class Article { - static async find(query, options = {}) { - const items = await find(store(), query, options) - - return Promise.all(items.map(processArticle)) - } - - static async findById(id) { - const item = await findOne(store(), {id}) - - return !item - ? null - : processArticle(item) - } - - static async total(query = {}) { - return total(store(), query) - } - - static async findPinned() { - const now = new Date() - const query = {until: {$gte: now}} - - return Article.find(query, { - sort: {date: -1}, - }) - } - - constructor(data) { - this.id = data.id - this.images = data.images - this.post = data.post - this.folder = data.folder - this.date = data.date - this.title = data.title - this.until = data.until - this.tags = (data.tags || []).map(make(Tag)) - this.content = data.content - this.hash = data.hash - this.type = data.type - this.origin = data.origin - this.file = data.file - this.version = data.version - this.preview = data.preview - - this.url = `/article/${this.id}` - } - - plain() { - return { - id: this.id, - images: this.images, - post: this.post, - folder: this.folder, - date: this.date, - title: this.title, - until: this.until, - tags: this.tags, - content: this.content, - hash: this.hash, - type: this.type, - origin: this.origin, - file: this.file, - version: this.version, - preview: this.preview, - url: this.url, - } - } -} - -class Tag { - constructor(tag) { - this.name = tag; - } -} - -const previewFromImage = (imgs = []) => imgs.length - ? imgs[0] - : null - -async function resolveDefaultPreview() { - const config = await Config.findConfig() - if (!config) return null - - return Image.findByFile(config.articleCardDefaultPreview) -} - -async function processArticle(article) { - let preview = null - const previewId = article.preview - ? article.preview - : previewFromImage(article.images) - - if (previewId) { - preview = await Image.findById(previewId) - } else { - preview = await resolveDefaultPreview() - } - - return new Article({ - ...article, - preview, - }) -} - -module.exports = Article diff --git a/src/core/Article.ts b/src/core/Article.ts new file mode 100644 index 00000000..8f749d03 --- /dev/null +++ b/src/core/Article.ts @@ -0,0 +1,136 @@ +import Data from './Data' +import Image from './Image' +import Config from './Config' +import { findOne, total } from '../lib/store' +import * as libStore from '../lib/store' + +const store = () => Data.getStore(Article) + +function make(C) { + return x => new C(x) +} + +export default class Article { + static async find(query, options = {}): Promise { + return [] + // const items = await libStore.find(store(), query, options as any) + + // return Promise.all(items.map(processArticle)) + } + + static async findById(id) { + const item = await findOne(store(), { id }) + + return !item + ? null + : processArticle(item) + } + + static async total(query = {}) { + return total(store(), query) + } + + static async findPinned() { + const now = new Date() + const query = { until: { $gte: now } } + + return Article.find(query, { + sort: { date: -1 }, + }) + } + + public id: any + public images: any + public post: any + public folder: any + public date: any + public title: any + public until: any + public tags: any + public content: any + public hash: any + public type: any + public origin: any + public file: any + public version: any + public preview: any + public url: any + + constructor(data) { + this.id = data.id + this.images = data.images + this.post = data.post + this.folder = data.folder + this.date = data.date + this.title = data.title + this.until = data.until + this.tags = (data.tags || []).map(make(Tag)) + this.content = data.content + this.hash = data.hash + this.type = data.type + this.origin = data.origin + this.file = data.file + this.version = data.version + this.preview = data.preview + + this.url = `/article/${this.id}` + } + + plain() { + return { + id: this.id, + images: this.images, + post: this.post, + folder: this.folder, + date: this.date, + title: this.title, + until: this.until, + tags: this.tags, + content: this.content, + hash: this.hash, + type: this.type, + origin: this.origin, + file: this.file, + version: this.version, + preview: this.preview, + url: this.url, + } + } +} + +class Tag { + public name: string + + constructor(tag) { + this.name = tag; + } +} + +const previewFromImage = (imgs = []) => imgs.length + ? imgs[0] + : null + +async function resolveDefaultPreview() { + const config = await Config.findConfig() + if (!config) return null + + return Image.findByFile(config.articleCardDefaultPreview) +} + +async function processArticle(article) { + let preview = null + const previewId = article.preview + ? article.preview + : previewFromImage(article.images) + + if (previewId) { + preview = await Image.findById(previewId) + } else { + preview = await resolveDefaultPreview() + } + + return new Article({ + ...article, + preview, + }) +} diff --git a/src/core/Data.js b/src/core/Data.ts similarity index 88% rename from src/core/Data.js rename to src/core/Data.ts index 70388deb..97c44f88 100644 --- a/src/core/Data.js +++ b/src/core/Data.ts @@ -2,7 +2,7 @@ const db = require('./db') const store = new Map() -class Data { +export default class Data { static setStore(Class, collection) { store.set(Class, collection) } @@ -15,5 +15,3 @@ class Data { return db.collection(name) } } - -module.exports = Data diff --git a/src/core/Page.js b/src/core/Page.js deleted file mode 100644 index 388800a9..00000000 --- a/src/core/Page.js +++ /dev/null @@ -1,93 +0,0 @@ -const Data = require('./Data') -const Image = require('./Image') -const Config = require('./Config') -const {find, findOne, total} = require('../lib/store') - -const store = () => Data.getStore(Page) - -class Page { - static async find(query, options = {}) { - const items = await find(store(), query, options) - - return Promise.all(items.map(processPage)) - } - - static async findById(id) { - const item = await findOne(store(), {id}) - - return !item - ? null - : processPage(item) - } - - static async findByUrl(url) { - const item = await findOne(store(), {url}) - - return !item - ? null - : processPage(item) - } - - static async total(query = {}) { - return total(store(), query) - } - - constructor(data) { - this.id = data.id - this.hash = data.hash - this.file = data.file - this.url = data.url - this.content = data.content - this.title = data.title - this.data = data.data - this.images = data.images - this.documents = data.documents - this.preview = data.preview - } - - plain() { - return { - id: this.id, - images: this.images, - documents: this.documents, - data: this.data, - title: this.title, - content: this.content, - hash: this.hash, - file: this.file, - preview: this.preview, - url: this.url, - } - } -} - -const previewFromImage = (imgs = []) => imgs.length - ? imgs[0] - : null - -async function resolveDefaultPreview() { - const config = await Config.findConfig() - if (!config) return null - - return Image.findByFile(config.articleCardDefaultPreview) -} - -async function processPage(article) { - let preview = null - const previewId = article.preview - ? article.preview - : previewFromImage(article.images) - - if (previewId) { - preview = await Image.findById(previewId) - } else { - preview = await resolveDefaultPreview() - } - - return new Page({ - ...article, - preview, - }) -} - -module.exports = Page diff --git a/src/core/Page.ts b/src/core/Page.ts new file mode 100644 index 00000000..4505bcc1 --- /dev/null +++ b/src/core/Page.ts @@ -0,0 +1,102 @@ +import Data from './Data' +import { find as storeFind, findOne, total } from '../lib/store' +const Image = require('./Image') +const Config = require('./Config') + +const store = () => Data.getStore(Page) + +export default class Page { + static async find(query, options = {}): Promise { + const items = await storeFind(store(), query, options as any) + + return Promise.all(items.map(processPage)) + } + + static async findById(id) { + const item = await findOne(store(), { id }) + + return !item + ? null + : processPage(item) + } + + static async findByUrl(url) { + const item = await findOne(store(), { url }) + + return !item + ? null + : processPage(item) + } + + static async total(query = {}) { + return total(store(), query) + } + + public id: any + public hash: any + public file: any + public url: string + public content: any + public title: any + public data: any + public images: any + public documents: any + public preview: any + + constructor(data) { + this.id = data.id + this.hash = data.hash + this.file = data.file + this.url = data.url + this.content = data.content + this.title = data.title + this.data = data.data + this.images = data.images + this.documents = data.documents + this.preview = data.preview + } + + plain() { + return { + id: this.id, + images: this.images, + documents: this.documents, + data: this.data, + title: this.title, + content: this.content, + hash: this.hash, + file: this.file, + preview: this.preview, + url: this.url, + } + } +} + +const previewFromImage = (imgs = []) => imgs.length + ? imgs[0] + : null + +async function resolveDefaultPreview() { + const config = await Config.findConfig() + if (!config) return null + + return Image.findByFile(config.articleCardDefaultPreview) +} + +async function processPage(article) { + let preview = null + const previewId = article.preview + ? article.preview + : previewFromImage(article.images) + + if (previewId) { + preview = await Image.findById(previewId) + } else { + preview = await resolveDefaultPreview() + } + + return new Page({ + ...article, + preview, + }) +} diff --git a/src/core/db.js b/src/core/db.ts similarity index 86% rename from src/core/db.js rename to src/core/db.ts index 1b5d8c1f..40adf502 100644 --- a/src/core/db.js +++ b/src/core/db.ts @@ -1,4 +1,4 @@ -const Data = require('./Data') +import Data from './Data' const Page = require('./Page') const Article = require('./Article') const Album = require('./Album') @@ -12,7 +12,7 @@ const { MongoClient, ObjectId } = require('mongodb') var db -async function connect() { +export async function connect() { if (db) { return db } @@ -22,11 +22,11 @@ async function connect() { return db } -function collection(name) { +export function collection(name) { return db.collection(name) } -function id(i) { +export function id(i) { if (typeof i === 'string') return ObjectId(i) else if (i instanceof ObjectId) return i else if (i instanceof Object) return '_id' in i ? ObjectId(i._id) : null @@ -45,8 +45,3 @@ function init(db) { return db } - -exports.connect = connect -exports.collection = collection -exports.c = collection -exports.id = id \ No newline at end of file diff --git a/src/lib/store.js b/src/lib/store.ts similarity index 52% rename from src/lib/store.js rename to src/lib/store.ts index 1b06b64e..309848bd 100644 --- a/src/lib/store.js +++ b/src/lib/store.ts @@ -1,4 +1,4 @@ -async function find(collection, query, {sort, skip, limit}) { +export async function find(collection, query, {sort, skip, limit}) { const cursor = collection.find(query) if (sort) cursor.sort(sort) @@ -8,16 +8,12 @@ async function find(collection, query, {sort, skip, limit}) { return cursor.toArray() } -async function findOne(collection, query) { +export async function findOne(collection, query) { return collection.findOne(query) } -async function total(collection, query) { +export async function total(collection, query) { return collection .find(query) .count() } - -exports.find = find -exports.findOne = findOne -exports.total = total diff --git a/src/middlewares/withCollection.js b/src/middlewares/withCollection.js index a877152d..0fcd5b57 100644 --- a/src/middlewares/withCollection.js +++ b/src/middlewares/withCollection.js @@ -1,14 +1,13 @@ // import { MongoClient } from 'mongodb'; // const { connect, collection } = require('../../src/core/db') -// import {collection, connect} from '../core/db' -const core = require('../core/db') +import {collection, connect} from '../core/db' // const client = new MongoClient(process.env.MONGODB_URI, { useNewUrlParser: true }); export const withCollection = handler => async (req, res) => { - await core.connect() + await connect() - req.collection = core.collection + req.collection = collection // if (!client.isConnected()) { // return client.connect().then(() => { diff --git a/src/server.js b/src/server.ts similarity index 76% rename from src/server.js rename to src/server.ts index 407f1411..70b9c687 100644 --- a/src/server.js +++ b/src/server.ts @@ -1,8 +1,8 @@ -const Koa = require('koa') -const next = require('next') -const { get } = require('koa-route') -const { connect } = require('./core/db') -const Page = require('./core/Page') +import Koa from 'koa' +import next from 'next' +import { get } from 'koa-route' +import { connect } from './core/db' +import Page from './core/Page' const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) @@ -18,8 +18,9 @@ app.prepare().then(async () => { process.exit(1) } - const pages = await Page.find({}) - const pagesUrls = pages.map(x => x.url) + // const pages = await Page.find({}) + // const pagesUrls = pages.map(x => x.url) + const pagesUrls = [] const server = new Koa() server.use(async (ctx, next) => { @@ -29,7 +30,7 @@ app.prepare().then(async () => { server.use(get('*', async ctx => { const url = ctx.req.url - + if (pagesUrls.includes(url)) { await app.render(ctx.req, ctx.res, '/next', ctx.query) } else { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..48ca14af --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "exclude": [ + "node_modules" + ], + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx" + ] +}