Skip to content

Commit dbef54a

Browse files
committed
⚡️ init
0 parents  commit dbef54a

10 files changed

+2848
-0
lines changed

.editorconfig

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[*]
2+
charset = utf-8
3+
end_of_line = lf
4+
insert_final_newline = true
5+
indent_style = space
6+
tab_width = 2
7+
continuation_indent_size = 4
8+
trim_trailing_whitespace = true

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.dist

package.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "netlify-local",
3+
"version": "0.0.0",
4+
"description": "Local Netlify service emulation",
5+
"main": ".dist/index.js",
6+
"repository": "https://github.com/8eecf0d2/netlify-local.git",
7+
"author": "8eecf0d2 <[email protected]>",
8+
"license": "ISC",
9+
"scripts": {
10+
"watch": "tsc --project ./tsconfig.json --watch",
11+
"build": "tsc --project ./tsconfig.json"
12+
},
13+
"devDependencies": {
14+
"@types/body-parser": "^1.17.0",
15+
"@types/commander": "^2.12.2",
16+
"@types/express": "^4.16.0",
17+
"@types/node": "^10.11.7",
18+
"@types/webpack": "^4.4.16"
19+
},
20+
"dependencies": {
21+
"body-parser": "^1.18.3",
22+
"commander": "^2.19.0",
23+
"express": "^4.16.4",
24+
"toml": "^2.3.3",
25+
"webpack": "^4.20.2"
26+
}
27+
}

src/ts/cli.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import * as program from "commander";
4+
import * as toml from "toml";
5+
6+
import { Netlify } from "./netlify";
7+
import { Server } from "./server";
8+
import { Webpack } from "./webpack";
9+
10+
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
11+
12+
program.version(packageJson.version);
13+
14+
program
15+
.option("-n --netlify <path>", "path to `netlify.toml` file (default `./netlify.toml`")
16+
.option("-w --webpack <path>", "path to webpack config file (default `./webpack.config.js`")
17+
.option("-p --port <port>", "port to serve from (default: 9000)")
18+
19+
program
20+
.command("serve")
21+
.description("serve and rebuild files on change")
22+
.action(() => {
23+
const webpackConfig = program.webpack ? require(path.join(process.cwd(), program.webpack)) : false;
24+
const netlifyConfig = toml.parse(fs.readFileSync(path.join(process.cwd(), program.netlify), "utf8"));
25+
26+
if(webpackConfig) {
27+
const webpack = new Webpack(webpackConfig);
28+
webpack.watch();
29+
}
30+
31+
const server = new Server(netlifyConfig, program.port || 9000);
32+
server.listen();
33+
});
34+
35+
program.parse(process.argv);

src/ts/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env node
2+
3+
import "./cli";

src/ts/netlify.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export namespace Netlify {
2+
export interface Config {
3+
build: {
4+
base?: string;
5+
publish: string;
6+
functions: string;
7+
command: string;
8+
}
9+
context: any;
10+
redirects: Netlify.Redirect[];
11+
}
12+
export interface Redirect {
13+
from: string;
14+
to: string;
15+
}
16+
}

src/ts/server.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as path from "path";
2+
import * as express from "express";
3+
import * as bodyParser from "body-parser";
4+
import * as serveStatic from "serve-static";
5+
6+
import { Netlify } from "./netlify";
7+
8+
export class Server {
9+
public express: express.Express;
10+
public paths: Server.Paths;
11+
12+
constructor(
13+
private netlifyConfig: Netlify.Config,
14+
private port: number,
15+
) {
16+
this.initialize();
17+
}
18+
19+
public initialize (): void {
20+
this.paths = {
21+
static: path.join(process.cwd(), this.netlifyConfig.build.publish),
22+
lambda: path.join(process.cwd(), this.netlifyConfig.build.functions),
23+
}
24+
this.express = express();
25+
this.express.use(bodyParser.raw());
26+
this.express.use(bodyParser.text({type: "*/*"}));
27+
this.express.use(serveStatic(this.paths.static))
28+
this.routeLambdas();
29+
this.routeRedirects();
30+
}
31+
32+
private routeRedirects (): void {
33+
for(const redirect of this.netlifyConfig.redirects) {
34+
this.handleRedirect(redirect.from, redirect.to);
35+
}
36+
}
37+
38+
public handleRedirect(from: string, to: string): void {
39+
this.express.get(from, (request, response, next) => {
40+
return response.status(200).sendFile(path.join(this.paths.static, to));
41+
});
42+
}
43+
44+
private routeLambdas (): void {
45+
this.express.all("/.netlify/functions/*", this.handleLambda());
46+
}
47+
48+
private handleLambda (): express.Handler {
49+
return (request, response, next) => {
50+
response.status(200).json("lambda!");
51+
}
52+
}
53+
54+
public listen (): void {
55+
this.express.listen(this.port, (error: Error) => {
56+
if (error) {
57+
console.error("netlify-local: unable to start server");
58+
console.error(error);
59+
process.exit(1);
60+
}
61+
62+
console.log(`netlify-local: server up on port ${this.port}`);
63+
});
64+
}
65+
}
66+
67+
export namespace Server {
68+
export interface Paths {
69+
static: string;
70+
lambda: string;
71+
}
72+
}

src/ts/webpack.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as webpack from "webpack";
2+
3+
export class Webpack {
4+
private compiler: webpack.Compiler;
5+
6+
constructor(
7+
private config: Webpack.Config,
8+
) {
9+
this.initialize();
10+
}
11+
12+
public initialize (): void {
13+
this.compiler = webpack(this.config);
14+
}
15+
16+
public watch (): void {
17+
this.compiler.watch({}, () => {
18+
console.log("netlify-local: webpack build changed")
19+
});
20+
}
21+
}
22+
23+
export namespace Webpack {
24+
export type Config = any;
25+
}

tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true,
4+
"emitDecoratorMetadata": true,
5+
"module": "commonjs",
6+
"target": "es5",
7+
"noImplicitAny": true,
8+
"sourceMap": true,
9+
"declaration": true,
10+
"declarationDir": ".dist",
11+
"outDir": ".dist",
12+
"lib": [ "ES2015", "ES2017" ]
13+
},
14+
"include": [ "src/ts/**/*.ts" ],
15+
"exclude": [ "node_modules" ]
16+
}

0 commit comments

Comments
 (0)