This repository has been archived by the owner on Mar 14, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dc37ef4
Showing
10 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.pub/* | ||
pubspec.lock | ||
.packages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
library web.config; | ||
import 'dart:async' show Future; | ||
import "dart:convert" show JSON; | ||
import "package:yaml/yaml.dart" show loadYaml; | ||
import "dart:io" show File; | ||
|
||
class Config { | ||
Map<String, dynamic> rawMap; | ||
|
||
Config(this.rawMap); | ||
|
||
factory Config.json(String s){ | ||
var conf = new Config({}); | ||
conf.getFromJson(s); | ||
return conf; | ||
} | ||
|
||
factory Config.yaml(String s){ | ||
var conf = new Config({}); | ||
conf.getFromYaml(s); | ||
return conf; | ||
} | ||
|
||
factory Config.file(File f){ | ||
var conf = new Config({}); | ||
if (f.uri.toFilePath().endsWith(".json")) { | ||
conf.getFromJsonFile(f); | ||
} else { | ||
conf.getFromYamlFile(f); | ||
} | ||
return conf; | ||
} | ||
|
||
dynamic operator [](String key) => rawMap[key]; | ||
operator []=(String key, var value) => rawMap[key] = value; | ||
|
||
void getFromYaml(String s){ | ||
var r = loadYaml(s); | ||
rawMap.addAll(r); | ||
} | ||
|
||
void getFromJson(String s){ | ||
var r = JSON.decode(s); | ||
rawMap.addAll(r); | ||
} | ||
|
||
Future getFromJsonFile(File f) async{ | ||
getFromJson(await f.readAsString()); | ||
} | ||
|
||
Future getFromYamlFile(File f) async{ | ||
getFromYaml(await f.readAsString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
library web.context; | ||
import "./request.dart" show Request; | ||
|
||
|
||
dynamic value2type(String value){ | ||
switch (value) { | ||
case "true": | ||
return true; | ||
break; | ||
case "false": | ||
return value; | ||
break; | ||
} | ||
|
||
var number; | ||
try{ | ||
number = num.parse(value); | ||
} on FormatException {} | ||
|
||
if (number){ | ||
return number; | ||
} | ||
|
||
return value; | ||
} | ||
|
||
|
||
class Context{ | ||
Request request; | ||
Map<String, Function> contextCreators; | ||
|
||
Context(this.request); | ||
|
||
dynamic call(String s){ | ||
return contextCreators[s](request); | ||
} | ||
|
||
void register(String s, Function f) => contextCreators[s] = f; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
library web.layer; | ||
import "dart:async" show Future; | ||
|
||
abstract class Layer { | ||
/// This class is base of all of Layers | ||
/// [Layer.apply] must be async | ||
void apply(List args, [Map<Symbol, dynamic> namedArgs]); | ||
|
||
factory Layer(Function f){ | ||
/// Return a [FunctionalLayer] | ||
return new FunctionalLayer(f); | ||
} | ||
} | ||
|
||
|
||
class FunctionalLayer implements Layer { | ||
Function function; | ||
|
||
FunctionalLayer(this.function); | ||
|
||
Future run(List args, [Map<Symbol, dynamic> namedArgs]) async{ | ||
if (args == null) { | ||
args = []; | ||
} | ||
if (namedArgs != null) { | ||
await Function.apply(function, args, namedArgs); | ||
} else { | ||
await Function.apply(function, args); | ||
} | ||
} | ||
|
||
Future apply(List args, [Map<Symbol, dynamic> namedArgs]) async{ | ||
await this.run(args,namedArgs); | ||
} | ||
|
||
} | ||
|
||
|
||
class LayerManager { | ||
LayerChain chain; | ||
|
||
LayerManager(){ | ||
chain = new LayerChain.empty(); | ||
} | ||
|
||
LayerState createState() => chain.newState; | ||
LayerState get newState => createState(); | ||
} | ||
|
||
|
||
class LayerChain { | ||
List<Layer> list; | ||
Map<String, dynamic> global; | ||
|
||
LayerChain(this.list,[Map<String, dynamic> map]){ | ||
if (map == null) { | ||
global = <String, dynamic>{}; | ||
} | ||
} | ||
|
||
factory LayerChain.empty(){ | ||
return new LayerChain(<Layer>[]); | ||
} | ||
|
||
void add(Layer layer) => list.add(layer); | ||
|
||
void addAll(Iterable<Layer> iterable) => list.addAll(iterable); | ||
|
||
void insert(int index, Layer layer) => list.insert(index, layer); | ||
|
||
void insertAll(int startIndex, Iterable<Layer> iter) => list.insertAll( | ||
startIndex, iter | ||
); | ||
|
||
LayerState createState() => new LayerState(this); | ||
LayerState get newState => createState(); | ||
|
||
} | ||
|
||
|
||
typedef void LayerForEachHandler(Layer layer); | ||
|
||
|
||
class LayerState { | ||
LayerChain pchain; | ||
int _rawPointer; | ||
Map<String, dynamic> memories; | ||
|
||
LayerState(this.pchain){ | ||
this.memories.addAll(this.pchain.global); | ||
} | ||
|
||
Future start(List args, [Map<Symbol, dynamic> namedArgs]) async{ | ||
forEach((Layer layer) async{ | ||
await layer.apply(args,namedArgs); | ||
}); | ||
} | ||
|
||
Layer next(){ | ||
_rawPointer ++; | ||
if ((rawPointer + 1) > pchain.list.length){ | ||
return null; | ||
} | ||
return pointer; | ||
} | ||
|
||
Future forEach(LayerForEachHandler h) async{ | ||
while (true) { | ||
var layer = next(); | ||
if (layer){ | ||
await h(layer); | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
Layer get pointer => pchain.list[rawPointer]; | ||
|
||
int get rawPointer => _rawPointer; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
library web.logging; | ||
import "package:logging/logging.dart"; | ||
import "package:bwu_log/bwu_log.dart"; | ||
import "./layer.dart" show Layer; | ||
import "./request.dart" show Request; | ||
|
||
class SimpleStringFormatter implements FormatterBase<String> { | ||
String call(LogRecord r) => """[${r.loggerName}][${r.time.toIso8601String()}][${r.level.toString()}]{ | ||
${r.message} | ||
${r.error} | ||
${r.stackTrace} | ||
} | ||
"""; | ||
} | ||
|
||
|
||
final InMemoryListAppender appender = new InMemoryListAppender(new SimpleStringFormatter()); | ||
|
||
|
||
Logger getLogger(String name){ | ||
var logger = new Logger(name); | ||
appender.attachLogger(logger); | ||
return logger; | ||
} | ||
|
||
|
||
final HandlerLogger = getLogger("handler"); | ||
|
||
|
||
final Layer LoggingLayer = new Layer((Request req){ | ||
HandlerLogger.info("${req.method} ${req.path}"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
library web.plugin; | ||
import "./web.dart" show Application; | ||
|
||
abstract class Plugin{ | ||
void init(Application app); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
library web.request; | ||
import "dart:convert" show JSON; | ||
import "package:shelf/shelf.dart" as shelf; | ||
import "./layer.dart" show LayerState; | ||
import "./context.dart" show Context; | ||
import "./web.dart" show Application; | ||
import "./config.dart" show Config; | ||
import "dart:async" show Future; | ||
|
||
class Request{ | ||
shelf.Request _raw; | ||
Response _res; | ||
LayerState _state; | ||
Application _app; | ||
Context _context; | ||
|
||
Request(this._raw,this._state,this._app){ | ||
_res = new Response(this); | ||
_context = new Context(this); | ||
} | ||
|
||
shelf.Request get raw => _raw; | ||
|
||
LayerState get state => _state; | ||
|
||
Application get app => _app; | ||
|
||
Context get context => _context; | ||
|
||
Map<String, String> get headers => raw.headers; | ||
|
||
String get method => raw.method; | ||
|
||
String get mimeType => raw.mimeType; | ||
|
||
Uri get url => raw.url; | ||
|
||
Future<String> get body => raw.readAsString(); | ||
|
||
dynamic asJson() async => JSON.decode(await body); | ||
|
||
Response get response => _res; | ||
Response get res => response; | ||
|
||
Config get C => app.C; | ||
|
||
get path => raw.handlerPath; | ||
} | ||
|
||
|
||
class Response{ | ||
String body; | ||
Request request; | ||
int statusCode; | ||
Map<String, String> headers; | ||
|
||
Response(this.request); | ||
|
||
shelf.Response done(){ | ||
return new shelf.Response(statusCode, body: body,headers: headers); | ||
} | ||
|
||
void ok(var body){ | ||
statusCode = 200; | ||
this.body = preprocessBody(body); | ||
} | ||
|
||
void forbidden([var body]) => error(403,body); | ||
|
||
void notFound([var body]) => error(404,body); | ||
|
||
void error(int code, [var body]){ | ||
statusCode = code; | ||
getTargetPage(body); | ||
} | ||
|
||
Future getTargetPage([var body]) async{ | ||
if (body == null){ | ||
this.body = await request.app.getErrorPage(statusCode); | ||
} else { | ||
this.body = preprocessBody(body); | ||
} | ||
} | ||
|
||
static dynamic preprocessBody(var body){ | ||
if (body is String){ | ||
return body; | ||
} else { | ||
return JSON.encode(body); | ||
} | ||
} | ||
} |
Oops, something went wrong.