aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-10-10 20:56:26 +0000
committers-ol <s-ol@users.noreply.github.com>2019-10-10 20:56:26 +0000
commitb36a1a6c61a6e8bff156ce4e2dc66fe8ed8cd95e (patch)
tree451395b406007bbc184059a80f1381dd42a456b9
parentserve from root/ in docker (diff)
downloadmmm-b36a1a6c61a6e8bff156ce4e2dc66fe8ed8cd95e.tar.gz
mmm-b36a1a6c61a6e8bff156ce4e2dc66fe8ed8cd95e.zip
?index and ?tree as real facets with typecasting to application/json
-rw-r--r--build/server.moon71
-rw-r--r--mmm/mmmfs/conversion.moon18
-rw-r--r--mmm/mmmfs/converts.moon24
-rw-r--r--mmm/mmmfs/fileder.moon10
4 files changed, 82 insertions, 41 deletions
diff --git a/build/server.moon b/build/server.moon
index ca08874..df18472 100644
--- a/build/server.moon
+++ b/build/server.moon
@@ -10,6 +10,7 @@ add '?/init.server'
require 'mmm'
import Key, dir_base, load_tree from require 'mmm.mmmfs.fileder'
+import convert from require 'mmm.mmmfs.conversion'
import get_store from require 'mmm.mmmfs.stores'
import decodeURI from require 'http.util'
@@ -17,22 +18,6 @@ lfs = require 'lfs'
server = require 'http.server'
headers = require 'http.headers'
-tojson = (obj) ->
- switch type obj
- when 'string'
- string.format '%q', obj
- when 'table'
- if obj[1] or not next obj
- "[#{table.concat [tojson c for c in *obj], ','}]"
- else
- "{#{table.concat ["#{tojson k}: #{tojson v}" for k,v in pairs obj], ', '}}"
- when 'number'
- tostring obj
- when 'boolean'
- tostring obj
- when nil
- 'null'
-
class Server
new: (@store, opts={}) =>
opts = {k,v for k,v in pairs opts}
@@ -52,27 +37,31 @@ class Server
handle: (method, path, facet) =>
fileder = load_tree @store, path -- @tree\walk path
+
+ if not fileder
+ -- fileder not found
+ 404, "fileder '#{path}' not found"
+
switch method
when 'GET', 'HEAD'
- if fileder and facet
- -- fileder and facet given
- if not fileder\has_facet facet.name
- return 404, "facet '#{facet.name}' not found in fileder '#{path}'"
-
- val = fileder\get facet
- if val
- 200, val
+ val = switch facet.name
+ when '?index', '?tree'
+ -- serve fileder index
+ -- '?index': one level deep
+ -- '?tree': recursively
+ index = fileder\get_index facet.name == '?tree'
+ convert 'table', facet.type, index
else
- 406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
- elseif fileder
- -- no facet given
- facets = [{k.name, k.type} for k,v in pairs fileder.facets]
- children = [f.path for f in *fileder.children]
- contents = tojson :facets, :children
- 200, contents
+ -- fileder and facet given
+ if not fileder\has_facet facet.name
+ return 404, "facet '#{facet.name}' not found in fileder '#{path}'"
+
+ fileder\get facet
+
+ if val
+ 200, val
else
- -- fileder not found
- 404, "fileder '#{path}' not found"
+ 406, "cant convert facet '#{facet.name}' to '#{facet.type}'"
else
501, "not implemented"
@@ -86,14 +75,15 @@ class Server
path_facet or= path
path, facet = path_facet\match '(.*)/([^/]*)'
- if facet ~= '?index'
- type or= 'text/html'
- type = type\match '%s*(.*)'
- facet = Key facet, type
- else
- facet = nil
+ type or= 'text/html'
+ type = type\match '%s*(.*)'
+ facet = Key facet, type
- status, body = @handle method, path, facet
+ ok, status, body = pcall @.handle, @, method, path, facet
+ if not ok
+ warn status, body
+ body = "Internal Server Error: #{status}"
+ status = 500
res = headers.new!
response_type = if status > 299 then 'text/plain'
@@ -109,7 +99,6 @@ class Server
error: (sv, ctx, op, err, errno) =>
msg = "#{op} on #{tostring ctx} failed"
msg = "#{msg}: #{err}" if err
- print msg
-- usage:
-- moon server.moon [STORE] [host] [port]
diff --git a/mmm/mmmfs/conversion.moon b/mmm/mmmfs/conversion.moon
index 2c68dcc..31cbf5e 100644
--- a/mmm/mmmfs/conversion.moon
+++ b/mmm/mmmfs/conversion.moon
@@ -55,8 +55,26 @@ apply_conversions = (conversions, value, ...) ->
value
+-- find and apply a conversion path from 'have' to 'want'
+-- * have - start type string or list of type strings
+-- * want - stop type pattern
+-- * value - value or map from have-types to values
+-- returns converted value
+convert = (have, want, value, ...) ->
+ conversions, start = get_conversions want, have
+
+ if not conversions
+ warn "couldn't convert from '#{have}' to '#{want}'"
+ return
+
+ if 'string' ~= type have
+ value = value[start]
+
+ apply_conversions conversions, value, ...
+
{
:converts
:get_conversions
:apply_conversions
+ :convert
}
diff --git a/mmm/mmmfs/converts.moon b/mmm/mmmfs/converts.moon
index c3f0522..823033e 100644
--- a/mmm/mmmfs/converts.moon
+++ b/mmm/mmmfs/converts.moon
@@ -211,6 +211,30 @@ converts = {
out: 'URL -> %1',
transform: (_, fileder, key) => "#{fileder.path}/#{key.name}:#{@from}"
},
+ {
+ inp: 'table',
+ out: 'application/json',
+ transform: do
+ tojson = (obj) ->
+ switch type obj
+ when 'string'
+ string.format '%q', obj
+ when 'table'
+ if obj[1] or not next obj
+ "[#{table.concat [tojson c for c in *obj], ','}]"
+ else
+ "{#{table.concat ["#{tojson k}: #{tojson v}" for k,v in pairs obj], ', '}}"
+ when 'number'
+ tostring obj
+ when 'boolean'
+ tostring obj
+ when 'nil'
+ 'null'
+ else
+ error "unknown type '#{type obj}'"
+
+ (val) => tojson val
+ }
}
if MODE == 'SERVER'
diff --git a/mmm/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon
index 3e5c49f..a0e4f2b 100644
--- a/mmm/mmmfs/fileder.moon
+++ b/mmm/mmmfs/fileder.moon
@@ -122,6 +122,16 @@ class Fileder
[name for name in pairs names]
+ get_index: (recursive=false) =>
+ {
+ path: @path
+ facets: [{k.name, k.type} for k,v in pairs @facets]
+ children: if recursive
+ [child\get_index true for child in *@children]
+ else
+ [{ :path } for { :path } in *@children]
+ }
+
-- check whether a facet is directly available
-- when passing a Key, set type to false to check for name only
has: (...) =>