chore: initial
This commit is contained in:
commit
4487e555b8
120
.gitignore
vendored
Normal file
120
.gitignore
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
/packages/*/index.js
|
||||||
|
/packages/*/index.js.map
|
||||||
|
|
22
config/.eslint.defaults.js
Normal file
22
config/.eslint.defaults.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
const config = {
|
||||||
|
globals: {
|
||||||
|
process: true,
|
||||||
|
window: true,
|
||||||
|
},
|
||||||
|
ignorePatterns: [
|
||||||
|
'/*',
|
||||||
|
'!/src',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'babel/object-curly-spacing': 'off',
|
||||||
|
'brace-style': ['error', 'stroustrup'],
|
||||||
|
'no-bitwise': ['error', {int32Hint: true}],
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-underscore-dangle': 'off',
|
||||||
|
'padded-blocks': ['error', {classes: 'always'}],
|
||||||
|
yoda: 'off',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
3
config/.eslintrc.js
Normal file
3
config/.eslintrc.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).eslintrc();
|
5
config/.mocharc.js
Normal file
5
config/.mocharc.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
process.env.NODE_ENV = process.env.NODE_ENV || 'test';
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).mocha();
|
33
config/.neutrinorc.js
Normal file
33
config/.neutrinorc.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
const airbnbBase = require('@neutrinojs/airbnb-base');
|
||||||
|
const library = require('@neutrinojs/library');
|
||||||
|
const mocha = require('@neutrinojs/mocha');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
use: [
|
||||||
|
(neutrino) => {
|
||||||
|
neutrino.options.output = '.';
|
||||||
|
},
|
||||||
|
airbnbBase({
|
||||||
|
eslint: {
|
||||||
|
cache: false,
|
||||||
|
baseConfig: require(`${__dirname}/.eslint.defaults`),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
(neutrino) => {
|
||||||
|
const {name} = neutrino.options.packageJson;
|
||||||
|
library({
|
||||||
|
clean: false,
|
||||||
|
name,
|
||||||
|
target: 'node',
|
||||||
|
})(neutrino);
|
||||||
|
},
|
||||||
|
(neutrino) => {
|
||||||
|
const options = neutrino.config.module
|
||||||
|
.rule('compile')
|
||||||
|
.use('babel')
|
||||||
|
.get('options');
|
||||||
|
options.presets[0][1].targets = {esmodules: true};
|
||||||
|
},
|
||||||
|
mocha(),
|
||||||
|
],
|
||||||
|
};
|
1
config/package/.eslintrc.js
Normal file
1
config/package/.eslintrc.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('../../config/.eslintrc');
|
0
config/package/.gitignore
vendored
Normal file
0
config/package/.gitignore
vendored
Normal file
30
config/package/package.json
Normal file
30
config/package/package.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/package",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build": "NODE_PATH=./node_modules webpack --mode production --config ../../config/webpack.config.js",
|
||||||
|
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||||
|
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||||
|
"watch": "NODE_PATH=./node_modules webpack --watch --mode development --config ../../config/webpack.config.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"index.js.map"
|
||||||
|
],
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||||
|
"@neutrinojs/library": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "^9.4.0",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
0
config/package/src/index.js
Normal file
0
config/package/src/index.js
Normal file
6
config/webpack.config.js
Normal file
6
config/webpack.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Whilst the configuration object can be modified here, the recommended way of making
|
||||||
|
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
|
||||||
|
// Neutrino's inspect feature can be used to view/export the generated configuration.
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
6
lerna.json
Normal file
6
lerna.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
"packages/*"
|
||||||
|
],
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
23
package.json
Normal file
23
package.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/monorepo",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "lerna run build",
|
||||||
|
"lint": "lerna run lint",
|
||||||
|
"test": "lerna run test",
|
||||||
|
"watch": "lerna run watch --parallel"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||||
|
"@neutrinojs/library": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"lerna": "^3.22.1",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "^9.4.0",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
1
packages/core/.eslintrc.js
Normal file
1
packages/core/.eslintrc.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('../../config/.eslintrc');
|
0
packages/core/.gitignore
vendored
Normal file
0
packages/core/.gitignore
vendored
Normal file
33
packages/core/package.json
Normal file
33
packages/core/package.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/core",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build": "NODE_PATH=./node_modules webpack --mode production --config ../../config/webpack.config.js",
|
||||||
|
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||||
|
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||||
|
"watch": "NODE_PATH=./node_modules webpack --watch --mode development --config ../../config/webpack.config.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"index.js.map"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"js-yaml": "3.14.0",
|
||||||
|
"webpack-virtual-modules": "0.3.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||||
|
"@neutrinojs/library": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "^9.4.0",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
4
packages/core/src/index.js
Normal file
4
packages/core/src/index.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export {default as readConfig} from './read-config';
|
||||||
|
export {default as Middleware} from './middleware';
|
||||||
|
export {default as Plugins} from './plugins';
|
||||||
|
export {default as WebpackPlugin} from './webpack-plugin';
|
39
packages/core/src/middleware.js
Normal file
39
packages/core/src/middleware.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
export default class Middleware {
|
||||||
|
|
||||||
|
constructor(middleware = []) {
|
||||||
|
this.middleware = middleware;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(...args) {
|
||||||
|
const fn = args.pop();
|
||||||
|
const middleware = this.middleware.concat();
|
||||||
|
const invoke = (error) => {
|
||||||
|
if (middleware.length > 0) {
|
||||||
|
const current = middleware.shift();
|
||||||
|
// Check mismatch.
|
||||||
|
if ((args.length + 2 === current.length) === !error) {
|
||||||
|
invoke(error);
|
||||||
|
}
|
||||||
|
// Invoke.
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
current(...args.concat(error ? [error] : []).concat(invoke));
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
invoke(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finish...
|
||||||
|
else if (fn) {
|
||||||
|
setTimeout(() => fn(error), 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
use(fn) {
|
||||||
|
this.middleware.push(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
packages/core/src/plugins.js
Normal file
46
packages/core/src/plugins.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
export default class Plugins {
|
||||||
|
|
||||||
|
constructor({config: {config, plugins}, modules}) {
|
||||||
|
this.config = config;
|
||||||
|
this.hooks = {};
|
||||||
|
this.modules = modules;
|
||||||
|
for (let i = 0; i < modules.length; i++) {
|
||||||
|
const {$$latus: {hooks}} = modules[i];
|
||||||
|
const keys = Object.keys(hooks);
|
||||||
|
for (let j = 0; j < keys.length; j++) {
|
||||||
|
const key = keys[j];
|
||||||
|
if (!this.hooks[key]) {
|
||||||
|
this.hooks[key] = [];
|
||||||
|
}
|
||||||
|
this.hooks[key].push({
|
||||||
|
plugin: plugins[i],
|
||||||
|
fn: hooks[key],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invokeFlat(hook, ...args) {
|
||||||
|
if (!this.hooks[hook]) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.hooks[hook].map(({fn}) => fn(...(args.concat(this))));
|
||||||
|
}
|
||||||
|
|
||||||
|
invokePlugin(hook, plugin, ...args) {
|
||||||
|
if (!this.hooks[hook]) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.hooks[hook]
|
||||||
|
.find(({plugin: candidate}) => candidate === plugin)
|
||||||
|
.fn(...(args.concat(this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
invokeReduce(hook, initial, reducer, ...args) {
|
||||||
|
if (!this.hooks[hook]) {
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
return this.hooks[hook].reduce((r, {fn}) => reducer(r, fn(...(args.concat(this)))), initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
packages/core/src/read-config.js
Normal file
8
packages/core/src/read-config.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
|
const readConfig = (path = `${process.cwd()}/latus.yml`) => (
|
||||||
|
yaml.safeLoad(fs.readFileSync(path, 'utf8'))
|
||||||
|
);
|
||||||
|
|
||||||
|
export default readConfig;
|
27
packages/core/src/webpack-plugin.js
Normal file
27
packages/core/src/webpack-plugin.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
const VirtualModulesPlugin = require('webpack-virtual-modules');
|
||||||
|
|
||||||
|
export default class WebpackPlugin {
|
||||||
|
|
||||||
|
constructor({config, plugins}) {
|
||||||
|
this.config = config;
|
||||||
|
this.plugins = plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
const body = [
|
||||||
|
'/* eslint-disable global-require, no-undef */',
|
||||||
|
'window.$$latus = {',
|
||||||
|
' config: {',
|
||||||
|
` config: ${JSON.stringify(this.config)},`,
|
||||||
|
` plugins: ${JSON.stringify(this.plugins)},`,
|
||||||
|
' },',
|
||||||
|
` modules: [\n${this.plugins.map((plugin) => ` require('${plugin}')`).join(',\n ')}\n],`,
|
||||||
|
'};',
|
||||||
|
].join('\n');
|
||||||
|
const plugin = new VirtualModulesPlugin({
|
||||||
|
'node_modules/@latus/core/virtual': body,
|
||||||
|
});
|
||||||
|
plugin.apply(compiler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
73
packages/core/test/middleware.js
Normal file
73
packages/core/test/middleware.js
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
import Middleware from '../src/middleware';
|
||||||
|
|
||||||
|
describe('@latus/core', () => {
|
||||||
|
describe('middleware', () => {
|
||||||
|
it('should construct with middleware', (done) => {
|
||||||
|
let called = false;
|
||||||
|
const middleware = new Middleware([
|
||||||
|
(next) => {
|
||||||
|
called = true;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
middleware.dispatch(() => {
|
||||||
|
expect(called).to.equal(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should pass args', (done) => {
|
||||||
|
const middleware = new Middleware([
|
||||||
|
(arg, next) => {
|
||||||
|
expect(arg).to.equal(69);
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
middleware.dispatch(69, done);
|
||||||
|
});
|
||||||
|
describe('error handling', () => {
|
||||||
|
it('should skip when necessary', (done) => {
|
||||||
|
let progress = 0;
|
||||||
|
const middleware = new Middleware([
|
||||||
|
(next) => {
|
||||||
|
progress += 1;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
(error, next) => {
|
||||||
|
throw new Error();
|
||||||
|
},
|
||||||
|
(next) => {
|
||||||
|
progress += 1;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
middleware.dispatch((error) => {
|
||||||
|
expect(error).to.equal(undefined);
|
||||||
|
expect(progress).to.equal(2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should use when necessary', (done) => {
|
||||||
|
let progress = 0;
|
||||||
|
const middleware = new Middleware([
|
||||||
|
(next) => {
|
||||||
|
progress += 1;
|
||||||
|
next(new Error());
|
||||||
|
},
|
||||||
|
(error, next) => {
|
||||||
|
next(error);
|
||||||
|
},
|
||||||
|
(next) => {
|
||||||
|
progress += 1;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
middleware.dispatch((error) => {
|
||||||
|
expect(error).to.not.equal(undefined);
|
||||||
|
expect(progress).to.equal(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
5257
packages/core/yarn.lock
Normal file
5257
packages/core/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1
packages/http/.eslintrc.js
Normal file
1
packages/http/.eslintrc.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('../../config/.eslintrc');
|
2
packages/http/.gitignore
vendored
Normal file
2
packages/http/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/client
|
||||||
|
/passport.js*
|
17
packages/http/.neutrinorc.js
Normal file
17
packages/http/.neutrinorc.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
const copy = require('@neutrinojs/copy');
|
||||||
|
|
||||||
|
const config = require('../../config/.neutrinorc');
|
||||||
|
config.options = {
|
||||||
|
mains: {
|
||||||
|
index: 'index',
|
||||||
|
passport: 'passport',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
config.use.push(copy({
|
||||||
|
patterns: ['index.js', 'index.ejs', 'latus.js'].map((path) => ({
|
||||||
|
from: `src/client/${path}`,
|
||||||
|
to: 'client',
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
module.exports = config;
|
46
packages/http/package.json
Normal file
46
packages/http/package.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "@latus/http",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build": "NODE_PATH=./node_modules webpack --mode production",
|
||||||
|
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||||
|
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||||
|
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"client",
|
||||||
|
"index.js",
|
||||||
|
"index.js.map",
|
||||||
|
"passport.js",
|
||||||
|
"passport.js.map",
|
||||||
|
"test.js",
|
||||||
|
"test.js.map"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@latus/core": "1.0.0",
|
||||||
|
"@neutrinojs/web": "^9.1.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-session": "1.17.1",
|
||||||
|
"http-proxy": "1.18.1",
|
||||||
|
"memfs": "3.2.0",
|
||||||
|
"neutrino": "9.4.0",
|
||||||
|
"passport": "0.4.1",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-dev-server": "^3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||||
|
"@neutrinojs/copy": "9.4.0",
|
||||||
|
"@neutrinojs/library": "^9.4.0",
|
||||||
|
"@neutrinojs/mocha": "^9.4.0",
|
||||||
|
"chai": "4.2.0",
|
||||||
|
"eslint": "^7",
|
||||||
|
"eslint-import-resolver-webpack": "0.13.0",
|
||||||
|
"mocha": "^8",
|
||||||
|
"neutrino": "9.4.0",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
48
packages/http/src/build/.neutrinorc.js
Normal file
48
packages/http/src/build/.neutrinorc.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const {readConfig, WebpackPlugin} = require('@latus/core');
|
||||||
|
const web = require('@neutrinojs/web');
|
||||||
|
const {DefinePlugin, EnvironmentPlugin} = require('webpack');
|
||||||
|
|
||||||
|
const {
|
||||||
|
HTTP_DEV_HOST,
|
||||||
|
HTTP_DEV_PORT,
|
||||||
|
HTTP_DEV_PUBLIC,
|
||||||
|
} = process.env;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
use: [
|
||||||
|
(neutrino) => {
|
||||||
|
const root = 'production' === neutrino.config.get('mode')
|
||||||
|
? __dirname
|
||||||
|
: `${__dirname}/../..`;
|
||||||
|
neutrino.options.root = fs.realpathSync(root);
|
||||||
|
neutrino.options.source = 'client';
|
||||||
|
neutrino.options.mains.index = 'index';
|
||||||
|
neutrino.options.output = `client`;
|
||||||
|
},
|
||||||
|
(neutrino) => {
|
||||||
|
web({
|
||||||
|
clean: false,
|
||||||
|
html: {
|
||||||
|
template: `${neutrino.options.root}/client/index.ejs`,
|
||||||
|
title: 'Latus',
|
||||||
|
},
|
||||||
|
})(neutrino);
|
||||||
|
},
|
||||||
|
(neutrino) => {
|
||||||
|
neutrino.config
|
||||||
|
.plugin('environment')
|
||||||
|
.use(EnvironmentPlugin, [{
|
||||||
|
SIDE: 'client',
|
||||||
|
}]);
|
||||||
|
if ('production' !== neutrino.config.get('mode')) {
|
||||||
|
neutrino.config.devServer
|
||||||
|
.host(HTTP_DEV_HOST)
|
||||||
|
.port(HTTP_DEV_PORT)
|
||||||
|
.public(HTTP_DEV_PUBLIC);
|
||||||
|
}
|
||||||
|
neutrino.config.node.delete('Buffer');
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
7
packages/http/src/build/webpack.config.js
Normal file
7
packages/http/src/build/webpack.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Whilst the configuration object can be modified here, the recommended way of making
|
||||||
|
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
|
||||||
|
// Neutrino's inspect feature can be used to view/export the generated configuration.
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-dynamic-require
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
15
packages/http/src/client/index.ejs
Normal file
15
packages/http/src/client/index.ejs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="<%= htmlWebpackPlugin.options.lang %>">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="icon" href="/favicon.png"/>
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
<script src="/latus.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="<%= htmlWebpackPlugin.options.appMountId %>">
|
||||||
|
<div class="debug-container"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
packages/http/src/client/index.js
Normal file
7
packages/http/src/client/index.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
const {Plugins} = require('@latus/core');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const plugins = new Plugins(window.$$latus);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
Promise.all(plugins.invokeFlat('up')).then(() => console.log('Latus up!\n'));
|
||||||
|
})();
|
2
packages/http/src/client/latus.js
Normal file
2
packages/http/src/client/latus.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// eslint-disable-next-line import/no-unresolved
|
||||||
|
import '@latus/core/virtual';
|
26
packages/http/src/index.js
Normal file
26
packages/http/src/index.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import {spawn} from 'child_process';
|
||||||
|
import {createHttpServer} from './server';
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const $$latus = {
|
||||||
|
hooks: {
|
||||||
|
build: (configs) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
if ('production' === process.env.NODE_ENV) {
|
||||||
|
// eslint-disable-next-line global-require, no-param-reassign
|
||||||
|
configs.client = require('./build/.neutrinorc');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const binary = `$(npm --prefix ${process.cwd()} bin)/webpack-dev-server`;
|
||||||
|
const config = `${__dirname}/src/build/webpack.config.js`;
|
||||||
|
const options = {
|
||||||
|
shell: true,
|
||||||
|
stdio: 'inherit',
|
||||||
|
};
|
||||||
|
process.stdout.write(`${binary} --mode development --config ${config}\n`);
|
||||||
|
spawn(`${binary} --mode development --config ${config}`, options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
up: (plugins) => createHttpServer(plugins),
|
||||||
|
},
|
||||||
|
};
|
19
packages/http/src/passport.js
Normal file
19
packages/http/src/passport.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import express from 'express';
|
||||||
|
import passport from 'passport';
|
||||||
|
|
||||||
|
import session from './session';
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const $$latus = {
|
||||||
|
hooks: {
|
||||||
|
httpServerRequestMiddleware: (plugins) => (req, res, next) => {
|
||||||
|
express.urlencoded({extended: true})(req, res, () => {
|
||||||
|
session(plugins)(req, res, () => {
|
||||||
|
passport.initialize()(req, res, () => {
|
||||||
|
passport.session()(req, res, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
117
packages/http/src/server.js
Normal file
117
packages/http/src/server.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import {createReadStream} from 'fs';
|
||||||
|
import {createServer, ServerResponse} from 'http';
|
||||||
|
import {join} from 'path';
|
||||||
|
|
||||||
|
import {readConfig, WebpackPlugin} from '@latus/core';
|
||||||
|
import express from 'express';
|
||||||
|
import httpProxy from 'http-proxy';
|
||||||
|
import {createFsFromVolume, Volume} from 'memfs';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
|
||||||
|
const {
|
||||||
|
HTTP_HOST,
|
||||||
|
HTTP_PORT,
|
||||||
|
HTTP_DEV_SCHEME,
|
||||||
|
HTTP_DEV_HOST,
|
||||||
|
HTTP_DEV_PORT,
|
||||||
|
} = process.env;
|
||||||
|
|
||||||
|
export const createHttpServer = async (plugins) => {
|
||||||
|
const app = express();
|
||||||
|
const httpServer = createServer(app);
|
||||||
|
httpServer.app = app;
|
||||||
|
// Request middleware.
|
||||||
|
const {httpServerRequestMiddleware} = plugins.config['@latus/http'];
|
||||||
|
for (let i = 0; i < httpServerRequestMiddleware.length; i++) {
|
||||||
|
app.use(
|
||||||
|
plugins.invokePlugin('httpServerRequestMiddleware', httpServerRequestMiddleware[i]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Serve latus.
|
||||||
|
app.get('/latus.js', (req, res) => {
|
||||||
|
// TODO: session/... config?
|
||||||
|
const latusConfig = readConfig();
|
||||||
|
latusConfig.config.serverPlugins = latusConfig.plugins;
|
||||||
|
latusConfig.plugins = latusConfig.config.clientPlugins;
|
||||||
|
const config = {
|
||||||
|
mode: 'production',
|
||||||
|
target: 'web',
|
||||||
|
output: {
|
||||||
|
filename: 'latus.js',
|
||||||
|
path: '/',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new WebpackPlugin(latusConfig),
|
||||||
|
],
|
||||||
|
entry: {
|
||||||
|
latus: `${__dirname}/client/latus`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const volume = new Volume();
|
||||||
|
// TODO: fs.path will be removed when some versions are bumped.
|
||||||
|
const fs = createFsFromVolume(volume);
|
||||||
|
fs.join = join;
|
||||||
|
// TODO: Need 'Vary' cache.
|
||||||
|
const compiler = webpack(config);
|
||||||
|
compiler.outputFileSystem = fs;
|
||||||
|
compiler.run((error, stats) => {
|
||||||
|
if (error) {
|
||||||
|
res.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true,
|
||||||
|
});
|
||||||
|
res.setHeader('Content-Type', 'application/javascript; charset=UTF-8');
|
||||||
|
fs.createReadStream('/latus.js').pipe(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if ('production' !== process.env.NODE_ENV) {
|
||||||
|
const proxy = httpProxy.createProxyServer({
|
||||||
|
secure: false,
|
||||||
|
target: `${HTTP_DEV_SCHEME}://${HTTP_DEV_HOST}:${HTTP_DEV_PORT}`,
|
||||||
|
});
|
||||||
|
// proxy.on('proxyRes', async (proxyRes, req, res) => {
|
||||||
|
// const buffer = await proxyRes.pipe(concat());
|
||||||
|
// if ('text/html; charset=UTF-8' === proxyRes.headers['content-type']) {
|
||||||
|
// res.end(await deliver(buffer, req, res));
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// res.setHeader('Content-Type', proxyRes.headers['content-type']);
|
||||||
|
// res.end(buffer);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
proxy.on('error', (err, req, res) => {
|
||||||
|
if (res instanceof ServerResponse) {
|
||||||
|
res.status(502).end('Bad Gateway (WDS)');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// app.get('*', (req, res) => proxy.web(req, res, {selfHandleResponse: true}));
|
||||||
|
app.get('*', (req, res) => proxy.web(req, res));
|
||||||
|
httpServer.on('upgrade', (req, socket, head) => proxy.ws(req, socket, head));
|
||||||
|
httpServer.on('close', () => proxy.close());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
app.use(express.static(join(__dirname, 'client')));
|
||||||
|
const stream = createReadStream(join(__dirname, 'client', 'index.html'));
|
||||||
|
app.get('*', async (req, res) => stream.pipe(res));
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
httpServer.listen(HTTP_PORT, HTTP_HOST, (error) => {
|
||||||
|
if (error) {
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
process.stdout.write(`HTTP server up @ ${HTTP_HOST}:${HTTP_PORT}!\n`);
|
||||||
|
return resolve(httpServer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const destroyHttpServer = (httpServer) => {
|
||||||
|
if (!httpServer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
httpServer.close();
|
||||||
|
process.stdout.write('HTTP server down!\n');
|
||||||
|
};
|
11
packages/http/src/session.js
Normal file
11
packages/http/src/session.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import session from 'express-session';
|
||||||
|
|
||||||
|
export default (plugins) => (
|
||||||
|
session({
|
||||||
|
resave: false,
|
||||||
|
sameSite: true,
|
||||||
|
saveUninitialized: false,
|
||||||
|
secret: process.env.COOKIE_SECRET || 'UNSAFE_DEV_COOKIE',
|
||||||
|
...plugins.invokeReduce('httpSessionOptions', {}, (r, o) => ({...r, ...o})),
|
||||||
|
})
|
||||||
|
);
|
6
packages/http/webpack.config.js
Normal file
6
packages/http/webpack.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// Whilst the configuration object can be modified here, the recommended way of making
|
||||||
|
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
|
||||||
|
// Neutrino's inspect feature can be used to view/export the generated configuration.
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
6957
packages/http/yarn.lock
Normal file
6957
packages/http/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
25
template/.eslint.defaults.js
Normal file
25
template/.eslint.defaults.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const config = {
|
||||||
|
globals: {
|
||||||
|
__non_webpack_require__: true,
|
||||||
|
process: true,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'babel/object-curly-spacing': 'off',
|
||||||
|
'brace-style': ['error', 'stroustrup'],
|
||||||
|
'no-bitwise': ['error', {int32Hint: true}],
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-underscore-dangle': 'off',
|
||||||
|
'padded-blocks': ['error', {classes: 'always'}],
|
||||||
|
yoda: 'off',
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
'import/resolver': {
|
||||||
|
webpack: {
|
||||||
|
config: `${__dirname}/webpack.config.js`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
3
template/.eslintrc.js
Normal file
3
template/.eslintrc.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = neutrino().eslintrc();
|
119
template/.gitignore
vendored
Normal file
119
template/.gitignore
vendored
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
/build
|
||||||
|
/latus.yml
|
58
template/.neutrinorc.js
Normal file
58
template/.neutrinorc.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
require('dotenv/config');
|
||||||
|
|
||||||
|
const airbnbBase = require('@neutrinojs/airbnb-base');
|
||||||
|
const clean = require('@neutrinojs/clean');
|
||||||
|
const mocha = require('@neutrinojs/mocha');
|
||||||
|
const node = require('@neutrinojs/node');
|
||||||
|
const {EnvironmentPlugin} = require('webpack');
|
||||||
|
const nodeExternals = require('webpack-node-externals');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
options: {
|
||||||
|
root: __dirname,
|
||||||
|
},
|
||||||
|
use: [
|
||||||
|
airbnbBase({
|
||||||
|
eslint: {
|
||||||
|
cache: false,
|
||||||
|
baseConfig: require('./.eslint.defaults'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
clean({
|
||||||
|
cleanOnceBeforeBuildPatterns: ['**/*.hot-update.*'],
|
||||||
|
}),
|
||||||
|
mocha({
|
||||||
|
spec: `src/**/*.spec.js`,
|
||||||
|
}),
|
||||||
|
node(),
|
||||||
|
(neutrino) => {
|
||||||
|
neutrino.config
|
||||||
|
.plugin('environment')
|
||||||
|
.use(EnvironmentPlugin, [{
|
||||||
|
SIDE: 'server',
|
||||||
|
}]);
|
||||||
|
if ('production' !== neutrino.config.get('mode')) {
|
||||||
|
neutrino.config
|
||||||
|
.entry('index')
|
||||||
|
.prepend('dotenv/config');
|
||||||
|
neutrino.config
|
||||||
|
.plugin('start-server')
|
||||||
|
.tap((args) => {
|
||||||
|
const options = args[0];
|
||||||
|
const inspectArg = process.argv.find((arg) => -1 !== arg.indexOf('--inspect'));
|
||||||
|
if (inspectArg) {
|
||||||
|
options.nodeArgs.push(inspectArg);
|
||||||
|
}
|
||||||
|
const profArg = process.argv.find((arg) => -1 !== arg.indexOf('--prof'));
|
||||||
|
if (profArg) {
|
||||||
|
options.nodeArgs.push(profArg);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
neutrino.config
|
||||||
|
.externals(nodeExternals({
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
7
template/latus.default.yml
Normal file
7
template/latus.default.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
plugins: [
|
||||||
|
'@latus/http',
|
||||||
|
]
|
||||||
|
|
||||||
|
config: {
|
||||||
|
'clientPlugins': [],
|
||||||
|
}
|
37
template/package.json
Normal file
37
template/package.json
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "latus",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"build:client": "SIDE=CLIENT webpack --mode production --config webpack.config.js",
|
||||||
|
"build:docker": "yarn run build:client && yarn run build:server && docker build -t cha0s6983/reddichat:latest . && docker tag cha0s6983/reddichat:latest docker.i12e.cha0s.io/cha0s6983/reddichat:latest",
|
||||||
|
"build:server": "SIDE=SERVER webpack --mode production --config webpack.config.js",
|
||||||
|
"client": "SIDE=CLIENT webpack-dev-server --mode development --config webpack.config.js",
|
||||||
|
"docker": "docker-compose -p reddichat up",
|
||||||
|
"inspect": "node ./inspect.js",
|
||||||
|
"lint": "eslint --cache --format codeframe --ext mjs,jsx,js src",
|
||||||
|
"repl": "rlwrap -C qmp socat STDIO UNIX:$(ls /tmp/reddichat-*.sock | tail -n 1)",
|
||||||
|
"server": "NODE_PRESERVE_SYMLINKS=1 webpack --watch --mode development --config webpack.config.js",
|
||||||
|
"test:client": "NODE_PRESERVE_SYMLINKS=1 SIDE=client mocha --watch",
|
||||||
|
"test:server": "NODE_PRESERVE_SYMLINKS=1 SIDE=server mocha --watch"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@latus/core": "^1.0.0",
|
||||||
|
"@latus/http": "^1.0.0",
|
||||||
|
"dotenv": "8.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@neutrinojs/airbnb-base": "^9.1.0",
|
||||||
|
"@neutrinojs/clean": "^9.1.0",
|
||||||
|
"@neutrinojs/mocha": "^9.1.0",
|
||||||
|
"@neutrinojs/node": "^9.1.0",
|
||||||
|
"babel-plugin-webpack-alias": "^2.1.2",
|
||||||
|
"eslint": "^6",
|
||||||
|
"eslint-import-resolver-webpack": "^0.12.1",
|
||||||
|
"js-yaml": "3.14.0",
|
||||||
|
"neutrino": "^9.1.0",
|
||||||
|
"source-map-support": "0.5.19",
|
||||||
|
"webpack": "^4",
|
||||||
|
"webpack-cli": "^3"
|
||||||
|
}
|
||||||
|
}
|
11
template/src/index.js
Normal file
11
template/src/index.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
const {Plugins, readConfig} = require('@latus/core');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const config = readConfig();
|
||||||
|
const plugins = new Plugins({
|
||||||
|
config,
|
||||||
|
modules: config.plugins.map((plugin) => __non_webpack_require__(plugin)),
|
||||||
|
});
|
||||||
|
await Promise.all(plugins.invokeFlat('up'));
|
||||||
|
process.stdout.write('Latus up!\n');
|
||||||
|
})();
|
24
template/webpack.config.js
Normal file
24
template/webpack.config.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Whilst the configuration object can be modified here, the recommended way of making
|
||||||
|
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
|
||||||
|
// Neutrino's inspect feature can be used to view/export the generated configuration.
|
||||||
|
const {readConfig, Plugins} = require('@latus/core');
|
||||||
|
const neutrino = require('neutrino');
|
||||||
|
|
||||||
|
module.exports = new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const config = readConfig();
|
||||||
|
const plugins = new Plugins({
|
||||||
|
config,
|
||||||
|
modules: config.plugins.map((plugin) => require(plugin)),
|
||||||
|
});
|
||||||
|
const configs = {
|
||||||
|
app: require('./.neutrinorc'),
|
||||||
|
};
|
||||||
|
plugins.invokeFlat('build', configs, config);
|
||||||
|
const webpackConfigs = Object.values(configs).map((config) => neutrino(config).webpack());
|
||||||
|
resolve(webpackConfigs);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
6825
template/yarn.lock
Normal file
6825
template/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user