commit bbb19375cf48a6dc6e1b854a991e01536805fcdf Author: abearxiong Date: Sat Dec 7 18:41:10 2024 +0800 初始化概念 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..2957d45 --- /dev/null +++ b/.npmrc @@ -0,0 +1,4 @@ +//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} +@abearxiong:registry=https://npm.pkg.github.com +//registry.npmjs.org/:_authToken=${NPM_TOKEN} +@kevisual:registry=https://npm.xiongxiao.me \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad9094e --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# vivid + +用户的连接配置base模块和js模块。 + +js模块被base模块包裹,如果请求的是html的内容,默认给予html界面的包裹内容,如果不是,则使用js的模块。 + + +## 查询条件 + +1. 路径appId去绝对定位,应用模块。 + +2. 根据path去查询内容,如果path是登陆用户,而且配置了自己请求的内容,则找用户自己配置的path的内容。 + +第二查询公共模块的path的路径的内容,如果两者都没有,返回会空的数据。 + +3. HTML和JS的内容设置缓存。 diff --git a/package.json b/package.json new file mode 100644 index 0000000..eb6d58e --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "vivid", + "version": "0.0.1", + "description": "", + "main": "index.js", + "scripts": { + "dev": "tsx src/index.ts" + }, + "keywords": [], + "author": "abearxiong ", + "license": "MIT", + "type": "module", + "packageManager": "pnpm@9.14.4+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab", + "devDependencies": { + "@kevisual/query": "0.0.7-alpha.3", + "@kevisual/router": "0.0.6-alpha-2", + "@kevisual/types": "^0.0.2", + "@kevisual/use-config": "^1.0.7", + "@types/node": "^22.10.1", + "ioredis": "^5.4.1", + "pg": "^8.13.1", + "sequelize": "^6.37.5", + "typescript": "^5.7.2" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..f683273 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,461 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@kevisual/query': + specifier: 0.0.7-alpha.3 + version: 0.0.7-alpha.3 + '@kevisual/router': + specifier: 0.0.6-alpha-2 + version: 0.0.6-alpha-2 + '@kevisual/types': + specifier: ^0.0.2 + version: 0.0.2 + '@kevisual/use-config': + specifier: ^1.0.7 + version: 1.0.7 + '@types/node': + specifier: ^22.10.1 + version: 22.10.1 + ioredis: + specifier: ^5.4.1 + version: 5.4.1 + pg: + specifier: ^8.13.1 + version: 8.13.1 + sequelize: + specifier: ^6.37.5 + version: 6.37.5(pg@8.13.1) + typescript: + specifier: ^5.7.2 + version: 5.7.2 + +packages: + + '@ioredis/commands@1.2.0': + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + + '@kevisual/query@0.0.7-alpha.3': + resolution: {integrity: sha512-zNTIbyU87dlp8ZeLvPoc1ou7cZCL60to4xptyMD3VKsldL/dDSAMf7JWwUivNiq9lRxk9KVEZA7YX558mzeQcw==} + + '@kevisual/router@0.0.6-alpha-2': + resolution: {integrity: sha512-P9rarSQG0tp8L3GSgivYZQ//SugEt6/YCzNE8087KsRIdF1g0v8rXGfi1G3b8cXRz/ip79Lb+caU7LsoAQhmOQ==} + + '@kevisual/types@0.0.2': + resolution: {integrity: sha512-x2vknoYXPRXIeAI37RdYUy45vocaq3enZnfat6afrnLDOxq9qNDPKYjAZ2ik7oJ0vuKb4LPtFBsPbfHieBHOQg==} + + '@kevisual/use-config@1.0.7': + resolution: {integrity: sha512-Ft1NICwj4NonnAnmEUMlh3tWi1GTcEtWaybg6Kv0j3+ZSp6d1v1HEXmiZvotGHkCQm6X8JSYdOeqILjOZYpERg==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + + '@types/node@22.10.1': + resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + + '@types/validator@13.12.2': + resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + dottie@2.0.6: + resolution: {integrity: sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==} + + inflection@1.13.4: + resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} + engines: {'0': node >= 0.4.0} + + ioredis@5.4.1: + resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==} + engines: {node: '>=12.22.0'} + + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + moment-timezone@0.5.46: + resolution: {integrity: sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + + pg-cloudflare@1.1.1: + resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + + pg-connection-string@2.7.0: + resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.7.0: + resolution: {integrity: sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.7.0: + resolution: {integrity: sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.13.1: + resolution: {integrity: sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + retry-as-promised@7.0.4: + resolution: {integrity: sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==} + + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + sequelize-pool@7.1.0: + resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} + engines: {node: '>= 10.0.0'} + + sequelize@6.37.5: + resolution: {integrity: sha512-10WA4poUb3XWnUROThqL2Apq9C2NhyV1xHPMZuybNMCucDsbbFuKg51jhmyvvAUyUqCiimwTZamc3AHhMoBr2Q==} + engines: {node: '>=10.0.0'} + peerDependencies: + ibm_db: '*' + mariadb: '*' + mysql2: '*' + oracledb: '*' + pg: '*' + pg-hstore: '*' + snowflake-sdk: '*' + sqlite3: '*' + tedious: '*' + peerDependenciesMeta: + ibm_db: + optional: true + mariadb: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-hstore: + optional: true + snowflake-sdk: + optional: true + sqlite3: + optional: true + tedious: + optional: true + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + toposort-class@1.0.1: + resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + + wkx@0.5.0: + resolution: {integrity: sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + +snapshots: + + '@ioredis/commands@1.2.0': {} + + '@kevisual/query@0.0.7-alpha.3': {} + + '@kevisual/router@0.0.6-alpha-2': + dependencies: + path-to-regexp: 8.2.0 + selfsigned: 2.4.1 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@kevisual/types@0.0.2': {} + + '@kevisual/use-config@1.0.7': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/ms@0.7.34': {} + + '@types/node-forge@1.3.11': + dependencies: + '@types/node': 22.10.1 + + '@types/node@22.10.1': + dependencies: + undici-types: 6.20.0 + + '@types/validator@13.12.2': {} + + cluster-key-slot@1.1.2: {} + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + denque@2.1.0: {} + + dottie@2.0.6: {} + + inflection@1.13.4: {} + + ioredis@5.4.1: + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.4.0 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + lodash.defaults@4.2.0: {} + + lodash.isarguments@3.1.0: {} + + lodash@4.17.21: {} + + moment-timezone@0.5.46: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + ms@2.1.3: {} + + node-forge@1.3.1: {} + + path-to-regexp@8.2.0: {} + + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.7.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.7.0(pg@8.13.1): + dependencies: + pg: 8.13.1 + + pg-protocol@1.7.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.13.1: + dependencies: + pg-connection-string: 2.7.0 + pg-pool: 3.7.0(pg@8.13.1) + pg-protocol: 1.7.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + retry-as-promised@7.0.4: {} + + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + + semver@7.6.3: {} + + sequelize-pool@7.1.0: {} + + sequelize@6.37.5(pg@8.13.1): + dependencies: + '@types/debug': 4.1.12 + '@types/validator': 13.12.2 + debug: 4.4.0 + dottie: 2.0.6 + inflection: 1.13.4 + lodash: 4.17.21 + moment: 2.30.1 + moment-timezone: 0.5.46 + pg-connection-string: 2.7.0 + retry-as-promised: 7.0.4 + semver: 7.6.3 + sequelize-pool: 7.1.0 + toposort-class: 1.0.1 + uuid: 8.3.2 + validator: 13.12.0 + wkx: 0.5.0 + optionalDependencies: + pg: 8.13.1 + transitivePeerDependencies: + - supports-color + + split2@4.2.0: {} + + standard-as-callback@2.1.0: {} + + toposort-class@1.0.1: {} + + typescript@5.7.2: {} + + undici-types@6.20.0: {} + + uuid@8.3.2: {} + + validator@13.12.0: {} + + wkx@0.5.0: + dependencies: + '@types/node': 22.10.1 + + ws@8.18.0: {} + + xtend@4.0.2: {} diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..7baafdf --- /dev/null +++ b/src/app.ts @@ -0,0 +1,47 @@ +import http from 'http'; +import { Vivid } from './lib/vivid'; + +const server = http.createServer((req: http.IncomingMessage, res) => { + const { url, method } = req; + if (!url) { + res.statusCode = 400; + res.end('Invalid request'); + return; + } + + const request = new URL(url, `http://127.0.0.1`); + const { pathname } = request; + if (pathname === '/favicon.ico') { + return; + } + if (pathname.startsWith('/api')) { + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify({ message: 'Hello World' })); + return; + } + // + if (method !== 'GET') { + res.statusCode = 405; + res.end('Method not allowed'); + return; + } + const vivid = new Vivid(); + const accept = req.headers['accept']; + if (accept && accept.includes('text/html')) { + res.setHeader('Content-Type', 'text/html'); + res.end(vivid.getHTML()); + return; + } + if (accept && accept.includes('application/json')) { + res.setHeader('Content-Type', 'application/javascript'); + res.end(`console.log(new Date())`); + return; + } + res.statusCode = 406; + res.end('Not Acceptable'); +}); + +const port = 3006; +server.listen(port, () => { + console.log(`Server is running on http://localhost:${port}`); +}); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..2ab5323 --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +import './app.ts'; diff --git a/src/lib/html-wrapper.ts b/src/lib/html-wrapper.ts new file mode 100644 index 0000000..0762776 --- /dev/null +++ b/src/lib/html-wrapper.ts @@ -0,0 +1,47 @@ +const baseMeta = [ + { id: 'chatset', meta: 'charset="UTF-8"' }, + { id: 'keywords', meta: 'name="keywords" content="vivid, kevisual, envision, micro-app"' }, + { id: 'viewport', meta: 'name="viewport" content="width=device-width, initial-scale=1.0"' }, + { id: 'author', meta: 'name="author" content="kevisual"' }, + { id: 'description', meta: 'name="description" content="A micro-app framework"' }, +]; +class HTMLWrapper { + metaEl: { id: string; meta: string }[] = []; + title: string; + version: string; + lang: string = 'zh-CN'; // Default value + content: string; + constructor() { + this.metaEl = baseMeta; + console.log('HTMLWrapper constructor'); + } + setContent(content: string) { + this.content = content; + } +} + +const getHTMLWrapper = (htmlWrapper: HTMLWrapper) => { + const { version, lang, title, content } = htmlWrapper; + const metaEl = htmlWrapper.metaEl || []; + const metaStr = metaEl + .map((meta) => { + return ``; + }) + .join('\n'); + + return ` + + + ${metaStr} + + ${title} + + +
+
+ + ${content} + + `; +}; diff --git a/src/lib/vivid.ts b/src/lib/vivid.ts new file mode 100644 index 0000000..ea6e286 --- /dev/null +++ b/src/lib/vivid.ts @@ -0,0 +1,26 @@ +export class Vivid { + pathname: string; + constructor() { + console.log('Vivid constructor'); + } + getContent() { + return 'Hello World'; + } + getHTML() { + return ` + + + + + + Vivid + + +
+ ${this.getContent()} +
+ + + `; + } +}