manner.js 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.nvmrc +1 -0
  2. package/babel.config.json +26 -0
  3. package/dist/index.js +13 -0
  4. package/gulpfile.babel.js +10 -0
  5. package/package.json +6 -2
  6. package/scripts/index.js +14 -0
  7. package/packages/client/package.json +0 -36
  8. package/packages/client/postcss.config.js +0 -6
  9. package/packages/client/src/class/Dimmer.js +0 -19
  10. package/packages/client/src/class/Emitter.js +0 -36
  11. package/packages/client/src/component/Router/index.js +0 -88
  12. package/packages/client/src/component/Router/index.module.css +0 -2
  13. package/packages/client/src/component/UpdateConfirm/index.js +0 -61
  14. package/packages/client/src/component/UpdateConfirm/index.module.css +0 -40
  15. package/packages/client/src/component/WebApp/index.js +0 -42
  16. package/packages/client/src/index.js +0 -6
  17. package/packages/client/src/lib/checkUpdate.js +0 -9
  18. package/packages/client/src/lib/clearCookie.js +0 -16
  19. package/packages/client/src/lib/filterNamespace.js +0 -9
  20. package/packages/client/src/lib/formateLocation.js +0 -8
  21. package/packages/client/src/lib/readCookie.js +0 -32
  22. package/packages/client/src/lib/setCookie.js +0 -19
  23. package/packages/client/src/lib/template/locationTemplate/index.js +0 -14
  24. package/packages/client/src/lib/template/locationTemplate/index.module.css +0 -4
  25. package/packages/client/src/obj/location.js +0 -3
  26. package/packages/client/src/page/NotFound/index.js +0 -21
  27. package/packages/client/src/page/NotFound/index.module.css +0 -28
  28. package/packages/client/webpack.config.dev.js +0 -62
  29. package/packages/client/webpack.config.pro.js +0 -47
  30. package/packages/server/package.json +0 -19
  31. package/packages/server/src/class/CommonHttp.js +0 -64
  32. package/packages/server/src/index.js +0 -2
  33. package/packages/server/src/lib/cacheOutput.js +0 -36
  34. package/packages/server/src/lib/compressOutput.js +0 -40
  35. package/packages/server/src/lib/filterNamespace.js +0 -11
  36. package/packages/server/src/lib/formateHttpDate.js +0 -5
  37. package/packages/server/src/lib/formateHttpKey.js +0 -5
  38. package/packages/server/src/lib/parseHttpDate.js +0 -3
  39. package/packages/server/src/lib/parseOption.js +0 -66
  40. package/packages/server/src/lib/readCookie.js +0 -21
  41. package/packages/server/test/CommonHttp.test.js +0 -18
  42. package/packages/server/test/parseOption.test.js +0 -9
  43. /package/{packages/client/dist → client}/32.index.js +0 -0
  44. /package/{packages/client/dist → client}/index.js +0 -0
  45. /package/{packages/client/dist → client}/index.js.LICENSE.txt +0 -0
  46. /package/{packages/server/dist → server}/class/CommonHttp.js +0 -0
  47. /package/{packages/server/dist → server}/index.js +0 -0
  48. /package/{packages/server/dist → server}/lib/cacheOutput.js +0 -0
  49. /package/{packages/server/dist → server}/lib/compressOutput.js +0 -0
  50. /package/{packages/server/dist → server}/lib/filterNamespace.js +0 -0
  51. /package/{packages/server/dist → server}/lib/formateHttpDate.js +0 -0
  52. /package/{packages/server/dist → server}/lib/formateHttpKey.js +0 -0
  53. /package/{packages/server/dist → server}/lib/parseHttpDate.js +0 -0
  54. /package/{packages/server/dist → server}/lib/parseOption.js +0 -0
  55. /package/{packages/server/dist → server}/lib/readCookie.js +0 -0
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ v21.6.2
@@ -0,0 +1,26 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ "targets": {
7
+ "node": "current"
8
+ }
9
+ },
10
+ "@babel/preset-react"
11
+ ],
12
+ ],
13
+ "plugins": [
14
+ [
15
+ "babel-plugin-root-import",
16
+ {
17
+ "paths": [
18
+ {
19
+ "rootPathSuffix": "./src",
20
+ "rootPathPrefix": "~/"
21
+ },
22
+ ]
23
+ }
24
+ ]
25
+ ],
26
+ }
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _path = _interopRequireDefault(require("path"));
4
+ var _fs = require("fs");
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+ const packagePath = _path.default.resolve('.', 'packages');
7
+ const currentPath = _path.default.resolve('.');
8
+ (0, _fs.cpSync)(_path.default.join(packagePath, 'client', 'dist'), _path.default.join(currentPath, 'client'), {
9
+ recursive: true
10
+ });
11
+ (0, _fs.cpSync)(_path.default.join(packagePath, 'server', 'dist'), _path.default.join(currentPath, 'server'), {
12
+ recursive: true
13
+ });
@@ -0,0 +1,10 @@
1
+ import { parallel, series, src, dest, } from 'gulp';
2
+ import babel from 'gulp-babel';
3
+
4
+ function buildScript() {
5
+ return src('scripts/**/*')
6
+ .pipe(babel())
7
+ .pipe(dest('dist'));
8
+ }
9
+
10
+ exports.build = buildScript;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "manner.js",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Frontend mode project.",
5
5
  "repository": "git@github.com:leobrad/mode.git",
6
6
  "author": "Leo Ely",
@@ -8,6 +8,9 @@
8
8
  "workspaces": [
9
9
  "packages/*"
10
10
  ],
11
+ "scripts": {
12
+ "build": "gulp build && node dist/index.js"
13
+ },
11
14
  "devDependencies": {
12
15
  "@babel/cli": "^7.20.7",
13
16
  "@babel/core": "^7.20.7",
@@ -31,6 +34,7 @@
31
34
  },
32
35
  "dependencies": {
33
36
  "babel-plugin-root-import": "^6.6.0",
34
- "glow.js": "^0.0.3"
37
+ "glow.js": "^0.0.3",
38
+ "gulp": "^4.0.2"
35
39
  }
36
40
  }
@@ -0,0 +1,14 @@
1
+ import path from 'path';
2
+ import { cpSync, } from 'fs';
3
+
4
+ const packagePath = path.resolve('.', 'packages');
5
+ const currentPath = path.resolve('.');
6
+
7
+ cpSync(
8
+ path.join(packagePath, 'client', 'dist'), path.join(currentPath, 'client'),
9
+ { recursive: true, },
10
+ );
11
+ cpSync(
12
+ path.join(packagePath, 'server', 'dist'), path.join(currentPath, 'server'),
13
+ { recursive: true, }
14
+ );
@@ -1,36 +0,0 @@
1
- {
2
- "name": "mode-client",
3
- "version": "0.0.1",
4
- "description": "Frontend client mode project.",
5
- "main": "dist/index.js",
6
- "repository": "https://github.com/leobrad/mode",
7
- "author": "Leo Brad",
8
- "license": "MIT",
9
- "scripts": {
10
- "dev": "webpack serve --config webpack.config.dev.js",
11
- "pro": "webpack --config webpack.config.pro.js"
12
- },
13
- "dependencies": {
14
- "react": "^18.2.0"
15
- },
16
- "devDependencies": {
17
- "@babel/cli": "^7.20.7",
18
- "@babel/core": "^7.20.7",
19
- "@babel/preset-env": "^7.20.2",
20
- "@babel/preset-react": "^7.23.3",
21
- "@babel/register": "^7.22.5",
22
- "autoprefixer": "^10.4.13",
23
- "babel-loader": "^9.1.2",
24
- "babel-plugin-root-import": "^6.6.0",
25
- "css-loader": "^6.7.3",
26
- "file-loader": "^6.2.0",
27
- "gulp-babel": "^8.0.0",
28
- "html-webpack-plugin": "^5.5.0",
29
- "postcss-loader": "^7.0.2",
30
- "style-loader": "^3.3.1",
31
- "sugarss": "^4.0.1",
32
- "webpack": "^5.75.0",
33
- "webpack-cli": "^5.0.1",
34
- "webpack-dev-server": "^4.11.1"
35
- }
36
- }
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- parser: 'sugarss',
3
- plugins: [
4
- require('autoprefixer'),
5
- ],
6
- };
@@ -1,19 +0,0 @@
1
- class Dimmer {
2
- constructor() {
3
- this.page = document.getElementById('page');
4
- }
5
-
6
- show() {
7
- const { page, } = this;
8
- page.style.backgroundColor = 'rgb(255, 255, 255)';
9
- page.style.filter = 'brightness(0.5)';
10
- }
11
-
12
- hidden() {
13
- const { page, } = this;
14
- page.style.backgroundColor = null;
15
- page.style.filter = null;
16
- }
17
- }
18
-
19
- export default Dimmer;
@@ -1,36 +0,0 @@
1
- class Emitter {
2
- constructor() {
3
- this.callbacks = {};
4
- }
5
-
6
- async send(event, data) {
7
- const { callbacks, } = this;
8
- const cbs = callbacks[event];
9
- if (Array.isArray(cbs)) {
10
- for (let i = 0; i < cbs.length; i += 1) {
11
- await cbs[i](data);
12
- }
13
- }
14
- }
15
-
16
- on(event, callback) {
17
- const { callbacks, } = this;
18
- if (callbacks[event] === undefined) {
19
- callbacks[event] = [];
20
- }
21
- callbacks[event].push(callback);
22
- }
23
-
24
- remove(event, callback) {
25
- const cbs = this.callbacks[event];
26
- if (Array.isArray(cbs)) {
27
- for (let i = 0; i < cbs.length; i += 1) {
28
- if (callback === cbs[i]) {
29
- cbs.splice(i, 1);
30
- }
31
- }
32
- }
33
- }
34
- }
35
-
36
- export default Emitter;
@@ -1,88 +0,0 @@
1
- import React from 'react';
2
- import style from './index.module.css';
3
- import WebApp from '~/component/WebApp';
4
- import location from '~/obj/location';
5
- import Emitter from '~/class/Emitter';
6
-
7
- const emitter = new Emitter();
8
-
9
- class Router extends WebApp {
10
- constructor(props) {
11
- super(props);
12
- this.route = {};
13
- this.component = {};
14
- this.state = {
15
- loading: true,
16
- location: '/',
17
- };
18
- }
19
-
20
- async componentDidMount() {
21
- await this.bindEvent();
22
- emitter.send('page' + window.location.pathname);
23
- }
24
-
25
- bindEvent() {
26
- location.onChange((location) => {
27
- this.setState({
28
- location,
29
- loading: true,
30
- });
31
- });
32
- const { bindOwnRoutes, } = this;
33
- if (typeof bindOwnRoutes === 'function') {
34
- this.addRemoteRoutes();
35
- }
36
- }
37
-
38
- addRoute(path, component) {
39
- const { route, } = this;
40
- if (route[path] === undefined) {
41
- route[path] = component;
42
- }
43
- return route[path];
44
- }
45
-
46
- async getPage(path) {
47
- const { component, } = this;
48
- if (component[path] === undefined) {
49
- const Page = this.route[path];
50
- if (Page !== undefined) {
51
- component[path] = <Page />;
52
- } else {
53
- this.setState({ loading: true, });
54
- const { NotFound, } = this.props;
55
- if (NotFound === undefined) {
56
- this.props.NotFound = await import('~/page/NotFound');
57
- }
58
- this.setState({ loading: false, });
59
- return <NotFound />;
60
- }
61
- }
62
- return component[path];
63
- }
64
-
65
- render() {
66
- const { location, minize, update, loading, } = this.state;
67
- let router;
68
- if (loading === true) {
69
- const { Loading, } = this.props;
70
- if (Loading) {
71
- router = <Loading />;
72
- } else {
73
- router = null;
74
- }
75
- } else {
76
- const { UpdateConfirm, } = this.props;
77
- const Page = this.getPage(location);
78
- router =
79
- <div id="page" className={style.page}>
80
- <Page />
81
- {update && <UpdateConfirm />}
82
- </div>;
83
- }
84
- return router;
85
- }
86
- }
87
-
88
- export default Router;
@@ -1,2 +0,0 @@
1
- .page
2
- height: 100%
@@ -1,61 +0,0 @@
1
- import React from 'react';
2
- import style from './index.module.css';
3
- import Dimmer from '~/class/Dimmer';
4
- import readCookie from '~/lib/readCookie';
5
- import filterNamespace from '~/lib/filterNamespace';
6
-
7
- class UpdateConfirm extends React.Component {
8
- constructor(props) {
9
- super(props);
10
- this.state = {
11
- display: true,
12
- };
13
- this.update = this.update.bind(this);
14
- this.close = this.close.bind(this);
15
- }
16
-
17
- update() {
18
- location.reload();
19
- this.dimmer.close();
20
- }
21
-
22
- close() {
23
- this.setState({
24
- display: false,
25
- });
26
- this.dimmer.hidden();
27
- }
28
-
29
- componentDidMount() {
30
- this.dimmer = new Dimmer();
31
- this.dimmer.show();
32
- }
33
-
34
- componentWillUnmount() {
35
- this.close();
36
- }
37
-
38
- render() {
39
- const { display, } = this.state;
40
- let confirm = null;
41
- if (display) {
42
- confirm =
43
- <div className={style.confirm}>
44
- <div className={style.title}>
45
- Detect a new version update of this webapp.Whether or not process update?
46
- </div>
47
- <div className={style.btngrp}>
48
- <button onClick={this.update} className={[style.btn, style.update].join(' ')}>
49
- update
50
- </button>
51
- <button onClick={this.close} className={[style.btn, style.ignore].join(' ')}>
52
- delay util next an minute
53
- </button>
54
- </div>
55
- </div>
56
- }
57
- return confirm;
58
- }
59
- }
60
-
61
- export default UpdateConfirm;
@@ -1,40 +0,0 @@
1
- .confirm
2
- position: absolute
3
- width: 680px
4
- top: calc(50% - 100px)
5
- left: calc(50% - 340px)
6
- padding: 15px 0px 10px 0px
7
- z-index: 2
8
- .title
9
- color: rgb(255, 255, 255)
10
- font-size: 17px
11
- padding: 0 20px 30px 20px
12
- border-bottom: 1px solid rgb(255, 255, 255)
13
- .title:before
14
- font-size: 43px
15
- content: '\f56d'
16
- margin-right: 15px
17
- .btngrp
18
- display: flex
19
- margin-top: 25px
20
- justify-content: center
21
- .btn
22
- color: rgb(0, 0, 0, 0.6)
23
- background-color: rgb(255, 255, 255)
24
- display: inline-flex
25
- font-size: 16px
26
- padding: 6.5px 10px 6.5px 10px
27
- margin: 0 100px 0 100px
28
- border: 0px
29
- border-radius: 2.5px
30
- align-items: center
31
- .btn:before
32
- border-right: 1px solid rgb(0, 0, 0, 0.6)
33
- margin-right: 8px
34
- padding-right: 8px
35
- .update:before
36
- font-size: 15px
37
- content: '\f252'
38
- .ignore:before
39
- font-size: 16px
40
- content: '\f5c8'
@@ -1,42 +0,0 @@
1
- import React from 'react';
2
- import location from '~/obj/location';
3
- import checkUpdate from '~/lib/checkUpdate';
4
-
5
- class WebApp extends React.Component {
6
- constructor(props) {
7
- super(props);
8
- this.checkUpdate = this.checkUpdate.bind(this);
9
- }
10
-
11
- dealUpdate() {
12
- const id = setInterval(this.checkUpdate, 1000 * 60 * 30);
13
- }
14
-
15
- dealHistory() {
16
- window.addEventListener('popstate', (event) => {
17
- location.to(event.currentTarget.location.pathname);
18
- });
19
- }
20
-
21
- async checkUpdate() {
22
- const response = fetch('/update/time', {
23
- method: 'POST',
24
- });
25
- const time = await response.text();
26
- const update = parseInt(time) > new Date().getTime();
27
- this.setState({
28
- update,
29
- });
30
- }
31
-
32
- async componentDidMount() {
33
- this.dealUpdate();
34
- this.dealHistory();
35
- }
36
-
37
- async componentWillUnmount() {
38
- clearInterval(this.id);
39
- }
40
- }
41
-
42
- export default WebApp;
@@ -1,6 +0,0 @@
1
- export * as Router from '~/component/Router';
2
- export * as UpdateConfirm from '~/component/UpdateConfirm';
3
- export * as WebApp from '~/component/WebApp';
4
- export * as clearCookie from '~/lib/clearCookie';
5
- export * as readCookie from '~/lib/readCookie';
6
- export * as setCookie from '~/lib/setCookie';
@@ -1,9 +0,0 @@
1
- export default async function checkUpdate() {
2
- const response = await fetch('/update/time');
3
- const time = await response.text();
4
- let ans = false;
5
- if (new Date().getTime() <= parseInt(time)) {
6
- ans = true;
7
- }
8
- return ans;
9
- }
@@ -1,16 +0,0 @@
1
- import readCookie from '~/lib/readCookie';
2
-
3
- export default function clearCookie(namespaces) {
4
- Object.keys(namespaces).forEach((n) => {
5
- if (n.expires !== undefined) {
6
- Object.keys(n).forEach((k) => {
7
- if (n === 'user') {
8
- document.cookie[n + '_' + k] = '';
9
- }
10
- window.localStorage.removeItem(n + '_' + k);
11
- });
12
- delete namespaces[n];
13
- }
14
- });
15
- return namespaces;
16
- }
@@ -1,9 +0,0 @@
1
- export default function filterNamespace(namespace) {
2
- const ans = {};
3
- Object.keys(namespace).forEach((k) => {
4
- if (k !== 'expires') {
5
- ans[k] = namespace[k];
6
- }
7
- });
8
- return ans;
9
- }
@@ -1,8 +0,0 @@
1
- import { HighLight, LocationLexer, } from 'glow.js';
2
- import locationTemplate from '~/lib/template/locationTemplate';
3
-
4
- export default function formateLocation(version) {
5
- const highLight = new HighLight();
6
- highLight.addLexer(LocationLexer);
7
- return highLight.parse(version).map((e) => locationTemplate(e));
8
- }
@@ -1,32 +0,0 @@
1
- import clearCookie from '~/lib/clearCookie';
2
-
3
- export default function readCookie() {
4
- const cookies = {};
5
- document.cookie.split(';').forEach((i) => {
6
- const [key, value] = i.split('=');
7
- cookies[key.trim()] = value;
8
- });
9
- const namespaces = {};
10
- Object.keys(cookies).forEach((k) => {
11
- const result = k.split('_');
12
- if (result.length === 2) {
13
- const [namespace, key] = result;
14
- if (namespaces[namespace] === undefined) {
15
- namespaces[namespace] = {};
16
- }
17
- namespaces[namespace][key] = cookies[k];
18
- }
19
- });
20
- for (let i = 0; i < window.localStorage.length; i += 1) {
21
- const k = window.localStorage.key(i);
22
- const result = k.split('_');
23
- if (result.length === 2) {
24
- const [namespace, key] = result;
25
- if (namespaces[namespace] === undefined) {
26
- namespaces[namespace] = {};
27
- }
28
- namespaces[namespace][key] = window.localStorage.getItem(k);
29
- }
30
- }
31
- return clearCookie(namespaces);
32
- }
@@ -1,19 +0,0 @@
1
- export default function setCookie(response) {
2
- const cookie = response.headers.get('cookie');
3
- if (cookie !== null) {
4
- if (cookie === '') {
5
- document.cookie.split(';').forEach((c) => {
6
- const [k, v] = c.split('=');
7
- const [namespace] = k.split('_');
8
- if (namespace === 'user') {
9
- document.cookie = k + '=' + v;
10
- }
11
- window.localStorage.set(k, v);
12
- });
13
- } else {
14
- cookie.split(';').forEach((c) => {
15
- document.cookie=c;
16
- });
17
- }
18
- }
19
- }
@@ -1,14 +0,0 @@
1
- import React from 'react';
2
- import style from './index.module.css';
3
-
4
- export default function locationTemplate(e) {
5
- const { type, elem, } = e;
6
- switch (type) {
7
- case '/':
8
- return <span className={style.slash}>/</span>;
9
- case 'namespace':
10
- return (
11
- <span className={style.namespace}>{elem}</span>
12
- );
13
- }
14
- }
@@ -1,4 +0,0 @@
1
- .slash
2
- color: rgb(90, 243, 90)
3
- .namespace
4
- color: rgb(45, 45, 173)
@@ -1,3 +0,0 @@
1
- const location = new Location();
2
-
3
- export default location;
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import style from './index.module.css';
3
- import formateLocation from '~/lib/formateLocation';
4
-
5
- class NotFound extends React.Component {
6
- render() {
7
- return(
8
- <div className={style.notfound}>
9
- <span className={style.earth}/>
10
- <span className={style.question}>?</span>
11
- Location
12
- <span className={style.location}>
13
- {formateLocation(location.pathname)}
14
- </span>
15
- don't exist.
16
- </div>
17
- );
18
- }
19
- }
20
-
21
- export default NotFound;
@@ -1,28 +0,0 @@
1
- .notfound
2
- font-size: 28px
3
- display: flex
4
- justify-content: center
5
- align-items: center
6
- height: 100%
7
- .question
8
- position: relative
9
- top: -40px
10
- left: -10px
11
- font-size: 40px
12
- font-weight: 500
13
- display: flex
14
- width: 40px
15
- height: 40px
16
- align-items: center
17
- justify-content: center
18
- margin-left: -10px
19
- color: rgb(255, 255, 255)
20
- background-color: rgb(243, 43, 43)
21
- .earth:before
22
- font-size: 75px
23
- content: '\f57d'
24
- background-color: rgba(0, 0, 0, 0)
25
- .location
26
- margin: 0 8px 0 8px
27
- background-color: rgb(245, 245, 245)
28
- padding: 0 6px 0 6px
@@ -1,62 +0,0 @@
1
- const path = require('path');
2
- const HtmlWebpackPlugin = require('html-webpack-plugin');
3
-
4
- module.exports = {
5
- mode: 'development',
6
- entry: {
7
- main: './src/index.js',
8
- },
9
- output: {
10
- filename: '[name].bundle.js',
11
- path: path.resolve(__dirname, 'static'),
12
- },
13
- plugins: [
14
- new HtmlWebpackPlugin({
15
- minify: true,
16
- template: './src/html/index.html',
17
- }),
18
- ],
19
- devServer: {
20
- compress: true,
21
- port: 9000,
22
- proxy: {
23
- '/api': 'http://localhost:3005'
24
- },
25
- },
26
- module: {
27
- rules: [
28
- {
29
- test: /\.js$/,
30
- exclude: [
31
- /node_modules/,
32
- ],
33
- use: {
34
- loader: 'babel-loader',
35
- }
36
- },
37
- {
38
- test: /\.css$/i,
39
- use: [
40
- 'style-loader',
41
- {
42
- loader: 'css-loader',
43
- options: {
44
- modules: {
45
- auto: /\.module\.css$/
46
- },
47
- },
48
- },
49
- 'postcss-loader',
50
- ]
51
- },
52
- {
53
- test: /\.(png|jpe?g|gif|svg)$/,
54
- use: [
55
- {
56
- loader: 'file-loader',
57
- }
58
- ]
59
- },
60
- ],
61
- },
62
- };
@@ -1,47 +0,0 @@
1
- const path = require('path');
2
- const HtmlWebpackPlugin = require('html-webpack-plugin');
3
-
4
- module.exports = {
5
- mode: 'production',
6
- entry: {
7
- main: './src/index.js',
8
- },
9
- output: {
10
- filename: 'index.js',
11
- path: path.resolve(__dirname, 'dist'),
12
- },
13
- module: {
14
- rules: [
15
- {
16
- test: /\.js$/,
17
- exclude: /node_modules/,
18
- use: {
19
- loader: 'babel-loader',
20
- }
21
- },
22
- {
23
- test: /\.css$/i,
24
- use: [
25
- 'style-loader',
26
- {
27
- loader: 'css-loader',
28
- options: {
29
- modules: {
30
- auto: /\.module\.css$/
31
- },
32
- },
33
- },
34
- 'postcss-loader',
35
- ]
36
- },
37
- {
38
- test: /\.(png|jpe?g|gif|svg)$/,
39
- use: [
40
- {
41
- loader: 'file-loader',
42
- }
43
- ]
44
- },
45
- ],
46
- },
47
- };
@@ -1,19 +0,0 @@
1
- {
2
- "name": "mode-server",
3
- "version": "0.0.1",
4
- "description": "Frontend mode server package.",
5
- "main": "dist/index.js",
6
- "repository": "https://github.com/leobrad/mode",
7
- "author": "Leo Ely",
8
- "license": "MIT",
9
- "scripts": {
10
- "build": "../../node_modules/.bin/babel src --out-dir dist",
11
- "test": "jest"
12
- },
13
- "devDependencies": {
14
- "jest": "^29.7.0"
15
- },
16
- "dependencies": {
17
- "node-fetch": "2"
18
- }
19
- }
@@ -1,64 +0,0 @@
1
- import cacheOutput from '~/lib/cacheOutput';
2
- import formateHttpKey from '~/lib/formateHttpKey';
3
- import filterNamespace from '~/lib/filterNamespace';
4
-
5
- function getLists(list) {
6
- return list.join('|');
7
- }
8
-
9
- class CommonHttp {
10
- constructor(options) {
11
- this.time = new Date().getTime();
12
- const { fonts, } = options;
13
- if (options.fonts === undefined) {
14
- options.fonts = [];
15
- }
16
- this.options = options;
17
- this.regexp = new RegExp(`\.(${getLists(options.fonts.concat(['html, ico', 'js']))})$`);
18
- }
19
-
20
- async process(req, res) {
21
- try {
22
- const { url, } = req;
23
- if (url === '/update/time') {
24
- const { time, } = this;
25
- res.end(time);
26
- } else if (this.regexp.test(url)) {
27
- cacheOutput(req, res, restPath,
28
- fs.readFileSync(path.resolve('static', restPath)),
29
- parseInt(fs.statSync(path.resolve('static', restPath)).mtimeMs),
30
- );
31
- } else if (url.substring(0, 4) === '/api') {
32
- const body = await new Promise((resolve, reject) => {
33
- req.on('data', (data) => {
34
- resolve(data.toString());
35
- });
36
- });
37
- const {
38
- location,
39
- } = this.options;
40
- const response = await fetch(location + url, {
41
- method: 'POST',
42
- body,
43
- });
44
- for (const k of response.headers.keys()) {
45
- res.setHeader(formateHttpKey(k), response.headers.get(k));
46
- }
47
- const data = await response.text();
48
- res.end(JSON.stringify(data));
49
- }
50
- } catch (e) {
51
- const {
52
- develope,
53
- } = this.options;
54
- if (develope === true) {
55
- throw e;
56
- } else {
57
- res.writeHead(500);
58
- res.end();
59
- }
60
- }
61
- }
62
- }
63
-
64
- export default CommonHttp;
@@ -1,2 +0,0 @@
1
- export * as CommonHttp from '~/class/CommonHttp';
2
- export * as parseOption from '~/lib/parseOption';
@@ -1,36 +0,0 @@
1
- import compressOutput from '~/lib/compressOutput';
2
- import formateHttpDate from '~/lib/formateHttpDate';
3
- import parseHttpDate from '~/lib/parseHttpDate';
4
-
5
- const output = {
6
- modify: {},
7
- file: {},
8
- };
9
-
10
- export default function cacheOutput(req, res, path, file, ms) {
11
- let ifModifiedSince = req.headers['If-Modified-Since'];
12
- if (ifModifiedSince === undefined) {
13
- if (output.modify[path] === undefined) {
14
- output.modify[path] = new Date(ms).toString();
15
- }
16
- if (output.file[path] === undefined) {
17
- output.file[path] = file;
18
- }
19
- res.setHeader('Last-Modified', formateHttpDate(output.modify[path]));
20
- compressOutput(req, res, output.file[path], path);
21
- } else {
22
- if (output.modify[path] === undefined) {
23
- output.modify[path] = new Date(ms).toString();
24
- }
25
- if (parseDateString(new Date().toString()) < parseDateString(output.modify[path])) {
26
- if (output.file[path] === undefined) {
27
- output.file[path] = file;
28
- }
29
- res.setHeader('Last-Modified', formateHttpDate(output.modify[path]));
30
- compressOutput(req, res, output.file[path], path);
31
- } else {
32
- res.writeHead(304);
33
- res.end();
34
- }
35
- }
36
- }
@@ -1,40 +0,0 @@
1
- import zlib from 'zlib';
2
- import { pipeline, } from 'stream';
3
-
4
- const output = {
5
- compress: {},
6
- raw: {},
7
- };
8
-
9
- function onError(err) {
10
- if (err) {
11
- console.error('An error occurred:', err);
12
- process.exitCode = 1;
13
- }
14
- }
15
-
16
- function dealCompress(data, path, res) {
17
- if (cache.compress[path] === undefined) {
18
- output.compress[path] = data;
19
- }
20
- res.end(output.compress[path]);
21
- }
22
-
23
- function directDeal(data, path, res) {
24
- if (output.raw[path] === undefined) {
25
- output.compress[path] = data;
26
- }
27
- res.end(output.raw[path]);
28
- }
29
-
30
- export default function compressOutput(req, res, buffer, path) {
31
- res.setHeader('Vary', 'Accept-Encoding');
32
- let acceptEncoding = req.headers['accept-encoding'];
33
- if (/gzip/.test(acceptEncoding)) {
34
- res.writeHead(200, { 'Content-Encoding': 'gzip' });
35
- dealCompress(zlib.gzipSync(buffer), path, res);
36
- } else {
37
- res.writeHead(200, {});
38
- dealDirect(buffer, path, res);
39
- }
40
- }
@@ -1,11 +0,0 @@
1
- export default function filterNamespace(namespace) {
2
- const ans = {};
3
- if (typeof namespace === 'object') {
4
- Object.keys(namespace).forEach((k) => {
5
- if (k !== 'expires') {
6
- ans[k] = namespace[k];
7
- }
8
- });
9
- }
10
- return ans;
11
- }
@@ -1,5 +0,0 @@
1
- export default function formateHttpDate(date) {
2
- let [week, month, day, year, time, zone] = date.toString().split(' ');
3
- zone = zone.split('+')[0];
4
- return month + ', ' + day + ' ' + month + ' ' + year + ' ' + time + ' ' + zone;
5
- }
@@ -1,5 +0,0 @@
1
- export default function formateHttpKey(key) {
2
- return key.split('-').map((v) => {
3
- return v.substring(0, 1).toUpperCase() + v.substring(1, v.length);
4
- }).join('-');
5
- }
@@ -1,3 +0,0 @@
1
- export default function parseHttpDate(dateString) {
2
- return new Date(httpDate).getTime();
3
- }
@@ -1,66 +0,0 @@
1
- function isOption(string) {
2
- let ans = true;
3
- if (typeof string === 'string') {
4
- let i = 0;
5
- for (i = 0; i < 1; i += 1) {
6
- if (string.charAt(i) === '-') {
7
- break;
8
- }
9
- }
10
- if (i === 0) {
11
- ans = false;
12
- }
13
- } else {
14
- ans = false;
15
- }
16
- return ans;
17
- }
18
-
19
- function transformOption(value) {
20
- let ans;
21
- const s = value.split('-');
22
- if (s.length >= 1) {
23
- ans = s.map((e, i) => {
24
- if (i === 0) {
25
- return e;
26
- } else {
27
- return e.charAt(0).toUpperCase() + e.substring(1, e.length);
28
- }
29
- });
30
- } else {
31
- ans = value;
32
- }
33
- return ans.join('');
34
- }
35
-
36
- export default function parseOption(...params) {
37
- const ans = {};
38
- for (let i = 0; i < params.length; i += 1) {
39
- const param = params[i];
40
- if (param.charAt(0) === '-') {
41
- const regexp = /^\-([a-z])$/;
42
- if (regexp.test(param)) {
43
- const [_, k] = param.match(regexp);
44
- if (isOption(params[i+1])) {
45
- ans[k] = params[i+1];
46
- i += 1;
47
- } else {
48
- ans[k] = true;
49
- }
50
- }
51
- if (param.charAt(1) === '-') {
52
- const regexp = /^\-\-([a-z\-]+)$/;
53
- if (regexp.test(param)) {
54
- const [_, k] = param.match(regexp);
55
- if (isOption(params[i+1])) {
56
- ans[transformOption(k)] = params[i+1];
57
- i += 1;
58
- } else {
59
- ans[k] = true;
60
- }
61
- }
62
- }
63
- }
64
- }
65
- return ans;
66
- }
@@ -1,21 +0,0 @@
1
- export default function readCookie(cookie) {
2
- const cookies = {};
3
- if (typeof cookie === 'string') {
4
- cookie.split(';').forEach((i) => {
5
- const [key, value] = i.split('=');
6
- cookies[key.trim()] = value;
7
- });
8
- }
9
- const namespaces = {};
10
- Object.keys(cookies).forEach((k) => {
11
- const result = k.split('_');
12
- if (result.length === 2) {
13
- const [namespace, key] = result;
14
- if (namespaces[namespace] === undefined) {
15
- namespaces[namespace] = {};
16
- }
17
- namespaces[namespace][key] = cookies[k];
18
- }
19
- });
20
- return namespaces;
21
- }
@@ -1,18 +0,0 @@
1
- import { describe, expect, test, } from '@jest/globals';
2
- import http from 'http';
3
- import fetch from 'node-fetch';
4
- import CommonHttp from '~/class/CommonHttp';
5
-
6
- beforeAll(() => {
7
- http.createServer(async (req, res) => {
8
- const commonHttp = new CommonHttp({});
9
- await commonHttp.process(req, res);
10
- res.end('result')
11
- }).listen(80);
12
- });
13
-
14
- test('[class] CommonHttp', async () => {
15
- const response = await fetch('http://localhost');
16
- const body = await response.text();
17
- expect(JSON.stringify(body)).toMatch('\"result\"');
18
- });
@@ -1,9 +0,0 @@
1
- import { describe, expect, test, } from '@jest/globals';
2
- import parseOption from '~/lib/parseOption';
3
-
4
- describe('[lib] parseOption', () => {
5
- test('command line option should parse correct.', () => {
6
- expect(parseOption('-t', 'type', '--type', 'type', '--detail-type', 'type')
7
- ).toEqual({ 't': 'type', 'type': 'type', 'detailType': 'type' });
8
- });
9
- });
File without changes
File without changes
File without changes