+.psci
npm-debug.log
+index.json
+index.js
node_modules/
+bower_components/
+build/
+example/bundle.js
example/node_modules/
example/bower_components/
-example/dist/
example/output/
-Copyright (c) 2014 Eric Thul
+Copyright (c) 2015 Eric Thul
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
--- /dev/null
+# Module Documentation
+
+## Module PursLoader.ChildProcess
+
+#### `ChildProcess`
+
+``` purescript
+data ChildProcess :: !
+```
+
+
+#### `spawn`
+
+``` purescript
+spawn :: forall eff. String -> [String] -> Aff (cp :: ChildProcess | eff) String
+```
+
+
+
+## Module PursLoader.FS
+
+#### `FS`
+
+``` purescript
+data FS :: !
+```
+
+
+#### `readFileUtf8`
+
+``` purescript
+readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String
+```
+
+
+#### `readFileUtf8Sync`
+
+``` purescript
+readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String
+```
+
+
+
+## Module PursLoader.Glob
+
+#### `Glob`
+
+``` purescript
+data Glob :: !
+```
+
+
+#### `glob`
+
+``` purescript
+glob :: forall eff. String -> Aff (glob :: Glob | eff) [String]
+```
+
+
+
+## Module PursLoader.Loader
+
+#### `LoaderEff`
+
+``` purescript
+type LoaderEff eff a = Eff (fs :: FS, cp :: ChildProcess, glob :: Glob, loader :: Loader | eff) a
+```
+
+
+#### `loader`
+
+``` purescript
+loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit
+```
+
+
+#### `loaderFn`
+
+``` purescript
+loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit)
+```
+
+
+
+## Module PursLoader.LoaderRef
+
+#### `LoaderRef`
+
+``` purescript
+data LoaderRef
+```
+
+
+#### `Loader`
+
+``` purescript
+data Loader :: !
+```
+
+
+#### `async`
+
+``` purescript
+async :: forall eff a. LoaderRef -> Eff (loader :: Loader | eff) (Maybe Error -> a -> Eff (loader :: Loader | eff) Unit)
+```
+
+
+#### `cacheable`
+
+``` purescript
+cacheable :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
+```
+
+
+#### `clearDependencies`
+
+``` purescript
+clearDependencies :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
+```
+
+
+#### `resourcePath`
+
+``` purescript
+resourcePath :: LoaderRef -> String
+```
+
+
+#### `addDependency`
+
+``` purescript
+addDependency :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit
+```
+
+
+#### `query`
+
+``` purescript
+query :: LoaderRef -> String
+```
+
+
+
+## Module PursLoader.LoaderUtil
+
+#### `getRemainingRequest`
+
+``` purescript
+getRemainingRequest :: LoaderRef -> String
+```
+
+
+#### `parseQuery`
+
+``` purescript
+parseQuery :: String -> Foreign
+```
+
+
+
+## Module PursLoader.OS
+
+#### `eol`
+
+``` purescript
+eol :: String
+```
+
+
+
+## Module PursLoader.Options
+
+#### `isForeignOptions`
+
+``` purescript
+instance isForeignOptions :: IsForeign Options
+```
+
+
+#### `pscMakeOutputOption`
+
+``` purescript
+pscMakeOutputOption :: Foreign -> Maybe String
+```
+
+
+#### `pscMakeOptions`
+
+``` purescript
+pscMakeOptions :: Foreign -> [String]
+```
+
+
+
+## Module PursLoader.Path
+
+#### `dirname`
+
+``` purescript
+dirname :: String -> String
+```
+
+
+#### `join`
+
+``` purescript
+join :: [String] -> String
+```
+
+
+#### `relative`
+
+``` purescript
+relative :: String -> String -> String
+```
+
+
+#### `resolve`
+
+``` purescript
+resolve :: String -> String
+```
+
+
+
+
## Example
-See the [example](https://github.com/ethul/purs-loader/tree/topic/bower-components/example) directory for a complete example.
+See the [example](https://github.com/ethul/purs-loader/tree/master/example) directory for a complete example.
--- /dev/null
+{
+ "name": "purs-loader",
+ "private": true,
+ "devDependencies": {
+ "purescript-aff": "~0.9.1",
+ "purescript-exceptions": "~0.2.3",
+ "purescript-strings": "~0.4.5",
+ "purescript-maybe": "~0.2.2",
+ "purescript-foreign": "~0.4.2",
+ "purescript-foldable-traversable": "~0.3.1",
+ "purescript-tuples": "~0.3.4",
+ "purescript-maps": "~0.3.3",
+ "purescript-arrays": "~0.3.7",
+ "purescript-monad-eff": "~0.1.0"
+ }
+}
--- /dev/null
+'use strict';
+
+var pursLoader = require('PursLoader.Loader');
+
+function loader(source) {
+ var ref = this;
+ var result = pursLoader.loaderFn(ref, source);
+ return result();
+}
+
+module.exports = loader;
{
"name": "example",
- "license": "MIT",
"private": true,
- "ignore": [
- "**/.*",
- "node_modules",
- "bower_components",
- "test",
- "tests"
- ],
"devDependencies": {
"purescript-maybe": "~0.2.1"
}
"private": true,
"scripts": {
"webpack": "./node_modules/.bin/webpack",
- "run": "node dist/app.js",
- "clean": "rm -rf bower_components && rm -rf dist && rm -rf node_modules && rm -rf output"
+ "run": "node bundle.js",
+ "clean": "rm -rf bower_components && rm -rf bundle.js && rm -rf node_modules && rm -rf output"
},
"license": "MIT",
"devDependencies": {
"purs-loader": "file:../",
- "webpack": "^1.4.15"
+ "webpack": "^1.8.4"
}
}
-var test = require('purs?output=output!./Test.purs');
+var test = require('./Test');
-var foo = require('purs?output=output!./Foo.purs');
+var foo = require('./Foo');
-var baz = require('purs?output=output!./Foo/Baz.purs');
+var baz = require('./Foo/Baz');
console.log(test, foo, baz);
var path = require('path');
-module.exports = {
- entry: './src/entry',
- output: {
- path: path.join(__dirname, 'dist'),
- filename: 'app.js'
- },
- resolve: {
- modulesDirectories: [
- 'node_modules',
- 'web_modules',
- 'output'
- ]
- }
-};
+var config
+ = { entry: './src/entry'
+ , output: { path: __dirname
+ , filename: 'bundle.js'
+ }
+ , module: { loaders: [ { test: /\.purs$/, loader: 'purs-loader' } ] }
+ , resolve: { modulesDirectories: [ 'node_modules',
+ 'output'
+ ]
+ , extensions: ['', '.js', '.purs']
+ }
+ , resolveLoader: { root: path.join(__dirname, 'node_modules') }
+ }
+ ;
+
+module.exports = config;
--- /dev/null
+'use strict';
+
+var path = require('path');
+
+var gulp = require('gulp');
+
+var gutil = require('gulp-util');
+
+var plumber = require('gulp-plumber');
+
+var purescript = require('gulp-purescript');
+
+var sequence = require('run-sequence');
+
+var del = require('del');
+
+var config = { del: ['build', 'index.js']
+ , purescript: { src: [ 'bower_components/purescript-*/src/**/*.purs*'
+ , 'src/**/*.purs'
+ ]
+ , dest: 'build'
+ , docs: 'MODULE.md'
+ }
+ }
+ ;
+
+function error(e) {
+ gutil.log(gutil.colors.magenta('>>>> Error <<<<') + '\n' + e.toString().trim());
+ this.emit('end');
+}
+
+gulp.task('del', function(cb){
+ del(config.del, cb);
+});
+
+gulp.task('make', function(){
+ return gulp.src(config.purescript.src).
+ pipe(plumber()).
+ pipe(purescript.pscMake({output: config.purescript.dest})).
+ on('error', error);
+});
+
+gulp.task('psci', function(){
+ return gulp.src(config.purescript.src).
+ pipe(plumber()).
+ pipe(purescript.dotPsci()).
+ on('error', error);
+});
+
+gulp.task('docs', function(){
+ return gulp.src(config.purescript.src[1]).
+ pipe(plumber()).
+ pipe(purescript.pscDocs()).
+ on('error', error).
+ pipe(gulp.dest(config.purescript.docs));
+});
+
+gulp.task('watch', function(){
+ gulp.watch(config.purescript.src, ['make']);
+});
+
+gulp.task('default', function(callback){
+ sequence('del', 'make', ['psci', 'docs'], callback);
+});
+
+gulp.task('build', function(callback){
+ sequence('del', 'make', callback);
+});
+++ /dev/null
-var cp = require('child_process')
- , path = require('path')
- , fs = require('fs')
- , glob = require('glob')
- , lodash = require('lodash')
- , chalk = require('chalk')
- , lu = require('loader-utils')
- , cwd = process.cwd()
- , MODULE_RE = /^module\s+([\w\.]+)\s+/i
- , BOWER_PATTERN = path.join('bower_components', 'purescript-*', 'src')
- , PSC_MAKE = 'psc-make'
- , OUTPUT = 'output'
- , OPTIONS = {
- 'no-prelude': '--no-prelude',
- 'no-opts': '--no-opts',
- 'no-magic-do': '--no-magic-do',
- 'no-tco': '--no-tco',
- 'verbose-errors': '--verbose-errors',
- 'output': '--output'
- }
-;
-
-function pattern(root) {
- var as = [ BOWER_PATTERN, root ];
- return path.join('{' + as.join(',') + '}', '**', '*.purs');
-}
-
-module.exports = function(source){
- var callback = this.async()
- , request = lu.getRemainingRequest(this)
- , root = path.dirname(path.relative(cwd, request))
- , query = lu.parseQuery(this.query)
- , opts = lodash.foldl(lodash.keys(query), function(acc, k){
- var h = function(v){return acc.concat(query[k] && OPTIONS[k] ? [v] : []);}
- if (k === OUTPUT) return h(OPTIONS[k] + '=' + query[k]);
- else return h(OPTIONS[k]);
- }, [])
- ;
- glob(pattern(root), function(e, files){
- if (e !== null) callback(e);
- else {
- var cmd = cp.spawn(PSC_MAKE, opts.concat(files));
- cmd.on('close', function(e){
- if (e) callback(e);
- else {
- var result = MODULE_RE.exec(source);
- var module = result.length > 1 ? result[1] : '';
- fs.readFile(path.join(query[OUTPUT] || OUTPUT, module, 'index.js'), 'utf-8', function(e, output){
- if (e) callback(e);
- else callback(e, output);
- });
- }
- });
- cmd.stdout.on('data', function(stdout){
- console.log('Stdout from \'' + chalk.cyan(PSC_MAKE) + '\'\n' + chalk.magenta(stdout));
- });
- cmd.stderr.on('data', function(stderr){
- console.log('Stderr from \'' + chalk.cyan(PSC_MAKE) + '\'\n' + chalk.magenta(stderr));
- });
- }
- });
-};
"name": "purs-loader",
"version": "0.0.3",
"description": "PureScript loader for webpack",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "license": "MIT",
+ "repository": "ethul/purs-loader",
+ "author": {
+ "name": "Eric Thul",
+ "email": "thul.eric@gmail.com"
},
- "repository": {
- "type": "git",
- "url": "git@github.com:ethul/purs-loader.git"
+ "scripts": {
+ "build": "npm run-script build:compile && npm run-script build:package",
+ "build:compile": "gulp build",
+ "build:package": "./node_modules/.bin/webpack --progress --colors --profile --bail",
+ "build:json": "./node_modules/.bin/webpack --progress --colors --profile --bail --json > index.json",
+ "prepublish": "npm run-script build"
},
- "author": "Eric Thul",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/ethul/purs-loader/issues"
+ "files": [
+ "index.js"
+ ],
+ "devDependencies": {
+ "del": "^1.1.1",
+ "gulp": "^3.8.11",
+ "gulp-plumber": "^1.0.0",
+ "gulp-purescript": "^0.3.1",
+ "gulp-util": "^3.0.4",
+ "run-sequence": "^1.0.2",
+ "webpack": "^1.8.4"
},
- "homepage": "https://github.com/ethul/purs-loader",
"dependencies": {
- "chalk": "^0.5.1",
- "glob": "4.0.6",
- "loader-utils": "^0.2.3",
- "lodash": "^2.4.1"
+ "glob": "^5.0.3",
+ "loader-utils": "^0.2.6"
}
}
--- /dev/null
+module PursLoader.ChildProcess
+ ( ChildProcess()
+ , spawn
+ ) where
+
+import Control.Monad.Aff (Aff(), makeAff)
+import Control.Monad.Eff (Eff())
+import Control.Monad.Eff.Exception (Error())
+
+import Data.Function
+
+foreign import data ChildProcess :: !
+
+spawn :: forall eff. String -> [String] -> Aff (cp :: ChildProcess | eff) String
+spawn command args = makeAff $ runFn4 spawnFn command args
+
+foreign import spawnFn """
+function spawnFn(command, args, errback, callback) {
+ return function(){
+ var child_process = require('child_process');
+
+ var process = child_process.spawn(command, args);
+
+ var stdout = new Buffer(0);
+
+ process.stdout.on('data', function(data){
+ stdout = Buffer.concat([stdout, new Buffer(data)]);
+ });
+
+ process.on('close', function(code){
+ if (code !== 0) errback(new Error(stdout.toString()))();
+ else callback(stdout.toString())();
+ });
+ };
+}
+""" :: forall eff. Fn4 String
+ [String]
+ (Error -> Eff (cp :: ChildProcess | eff) Unit)
+ (String -> Eff (cp :: ChildProcess | eff) Unit)
+ (Eff (cp :: ChildProcess | eff) Unit)
--- /dev/null
+module PursLoader.FS
+ ( FS()
+ , readFileUtf8
+ , readFileUtf8Sync
+ ) where
+
+import Control.Monad.Aff (Aff(), makeAff)
+import Control.Monad.Eff (Eff())
+import Control.Monad.Eff.Exception (Error())
+
+import Data.Function
+
+foreign import data FS :: !
+
+readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String
+readFileUtf8 filepath = makeAff $ runFn3 readFileUtf8Fn filepath
+
+readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String
+readFileUtf8Sync filepath = readFileUtf8SyncFn filepath
+
+foreign import readFileUtf8Fn """
+function readFileUtf8Fn(filepath, errback, callback) {
+ return function(){
+ var fs = require('fs');
+
+ fs.readFile(filepath, 'utf-8', function(e, data){
+ if (e) errback(e)();
+ else callback(data)();
+ });
+ };
+}
+""" :: forall eff. Fn3 String
+ (Error -> Eff (fs :: FS | eff) Unit)
+ (String -> Eff (fs :: FS | eff) Unit)
+ (Eff (fs :: FS | eff) Unit)
+
+foreign import readFileUtf8SyncFn """
+function readFileUtf8SyncFn(filepath) {
+ return function(){
+ var fs = require('fs');
+
+ return fs.readFileSync(filepath, {encoding: 'utf-8'});
+ };
+}
+""" :: forall eff. String -> (Eff (fs :: FS | eff) String)
--- /dev/null
+module PursLoader.Glob
+ ( Glob()
+ , glob
+ ) where
+
+import Control.Monad.Aff (Aff(), makeAff)
+import Control.Monad.Eff (Eff())
+import Control.Monad.Eff.Exception (Error())
+
+import Data.Function
+
+foreign import data Glob :: !
+
+glob :: forall eff. String -> Aff (glob :: Glob | eff) [String]
+glob pattern = makeAff $ runFn3 globFn pattern
+
+foreign import globFn """
+function globFn(pattern, errback, callback) {
+ return function(){
+ var glob = require('glob');
+
+ glob(pattern, function(e, data){
+ if (e) errback(e)();
+ else callback(data)();
+ });
+ };
+}
+""" :: forall eff. Fn3 String
+ (Error -> Eff (glob :: Glob | eff) Unit)
+ ([String] -> Eff (glob :: Glob | eff) Unit)
+ (Eff (glob :: Glob | eff) Unit)
--- /dev/null
+module PursLoader.Loader
+ ( LoaderEff()
+ , loader
+ , loaderFn
+ ) where
+
+import Control.Monad.Aff (Aff(), runAff)
+import Control.Monad.Eff (Eff())
+import Control.Monad.Eff.Class (liftEff)
+import Control.Monad.Eff.Exception (error)
+
+import Data.Array ((!!), catMaybes, concat, nub, null)
+import Data.Function (Fn2(), mkFn2)
+import Data.Maybe (Maybe(..), fromMaybe, maybe)
+import Data.String (joinWith, split)
+import Data.String.Regex (Regex(), match, noFlags, regex)
+import Data.StrMap (StrMap(), fromList, lookup)
+import Data.Traversable (sequence)
+import Data.Tuple.Nested (tuple2)
+
+import PursLoader.ChildProcess (ChildProcess(), spawn)
+import PursLoader.FS (FS(), readFileUtf8, readFileUtf8Sync)
+import PursLoader.Glob (Glob(), glob)
+import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, clearDependencies, addDependency, query, resourcePath)
+import PursLoader.LoaderUtil (getRemainingRequest, parseQuery)
+import PursLoader.OS (eol)
+import PursLoader.Options (pscMakeOptions, pscMakeDefaultOutput, pscMakeOutputOption)
+import PursLoader.Path (dirname, join, relative, resolve)
+
+foreign import cwd "var cwd = process.cwd();" :: String
+
+moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
+
+importRegex = regex "^\\s*import\\s+(?:qualified\\s+)?([\\w\\.]+)" noFlags { ignoreCase = true }
+
+bowerPattern = join [ "bower_components", "purescript-*", "src" ]
+
+pscMakeCommand = "psc-make"
+
+indexFilename = "index.js"
+
+(!!!) = flip (!!)
+
+pursPattern :: String -> String
+pursPattern root = join [ "{" ++ joinWith "," [ bowerPattern, root ] ++ "}"
+ , "**"
+ , "*.purs"
+ ]
+
+type GraphModule = { file :: String, imports :: [String] }
+
+type Graph = StrMap GraphModule
+
+mkGraph :: forall eff. [String] -> Eff (fs :: FS | eff) Graph
+mkGraph files = (fromList <<< catMaybes) <$> sequence (parse <$> files)
+ where parse file = do source <- readFileUtf8Sync file
+ let key = match moduleRegex source >>= (!!!) 1
+ lines = split eol source
+ imports = catMaybes $ (\a -> match importRegex a >>= (!!!) 1) <$> lines
+ return $ (\a -> tuple2 a { file: file, imports: imports }) <$> key
+
+mkDeps :: forall eff. String -> Graph -> [String]
+mkDeps key graph = nub $ go [] key
+ where go acc key =
+ maybe acc (\a -> if null a.imports
+ then acc
+ else concat $ go (acc <> a.imports) <$> a.imports) (lookup key graph)
+
+addDeps :: forall eff. LoaderRef -> Graph -> [String] -> Eff (loader :: Loader | eff) Unit
+addDeps ref graph deps = const unit <$> (sequence $ add <$> deps)
+ where add dep = let res = lookup dep graph
+ path = (\a -> resolve a.file) <$> res
+ in maybe (pure unit) (addDependency ref) path
+
+type LoaderAff eff a = Aff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a
+
+loader' :: forall eff. LoaderRef -> String -> LoaderAff eff (Maybe String)
+loader' ref source = do
+ liftEff $ cacheable ref
+
+ let request = getRemainingRequest ref
+ root = dirname $ relative cwd request
+ parsed = parseQuery $ query ref
+ opts = pscMakeOptions parsed
+ pattern = pursPattern root
+ key = match moduleRegex source >>= (!!!) 1
+
+ files <- glob pattern
+ graph <- liftEff $ mkGraph files
+
+ let deps = fromMaybe [] $ flip mkDeps graph <$> key
+ outputPath = fromMaybe pscMakeDefaultOutput $ pscMakeOutputOption parsed
+ indexPath = (\a -> join [ outputPath, a, indexFilename ]) <$> key
+
+ liftEff $ clearDependencies ref
+ liftEff $ addDependency ref (resourcePath ref)
+ liftEff $ addDeps ref graph deps
+
+ spawn pscMakeCommand (opts <> files)
+ indexFile <- sequence $ readFileUtf8 <$> indexPath
+ return indexFile
+
+type LoaderEff eff a = Eff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a
+
+loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit
+loader ref source = do
+ callback <- async ref
+ runAff (\e -> callback (Just e) "")
+ (maybe (callback (Just $ error "Loader has failed to run") "")
+ (callback Nothing))
+ (loader' ref source)
+
+loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit)
+loaderFn = mkFn2 loader
--- /dev/null
+module PursLoader.LoaderRef
+ ( LoaderRef()
+ , Loader()
+ , async
+ , cacheable
+ , clearDependencies
+ , resourcePath
+ , addDependency
+ , query
+ ) where
+
+import Control.Monad.Eff (Eff())
+import Control.Monad.Eff.Exception (Error())
+
+import Data.Foreign (Foreign())
+import Data.Function (Fn3(), runFn3)
+import Data.Maybe (Maybe(), fromMaybe, isJust)
+
+data LoaderRef
+
+foreign import data Loader :: !
+
+foreign import asyncFn """
+function asyncFn(isJust, fromMaybe, ref){
+ return function(){
+ var callback = ref.async();
+ return function(error){
+ return function(value){
+ return function(){
+ return isJust(error) ? callback(fromMaybe(new Error())(error))
+ : callback(null, value);
+ };
+ };
+ };
+ };
+}""" :: forall eff a. Fn3 (Maybe Error -> Boolean)
+ (Error -> Maybe Error -> Error)
+ LoaderRef
+ (Eff (loader :: Loader | eff) (Maybe Error -> a -> Eff (loader :: Loader | eff) Unit))
+
+async :: forall eff a. LoaderRef -> Eff (loader :: Loader | eff) (Maybe Error -> a -> Eff (loader :: Loader | eff) Unit)
+async ref = runFn3 asyncFn isJust fromMaybe ref
+
+foreign import cacheable """
+function cacheable(ref){
+ return function(){
+ return ref.cacheable && ref.cacheable();
+ };
+}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
+
+foreign import clearDependencies """
+function clearDependencies(ref){
+ return function(){
+ return ref.clearDependencies();
+ };
+}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
+
+foreign import resourcePath """
+function resourcePath(ref){
+ return ref.resourcePath;
+}""" :: LoaderRef -> String
+
+foreign import addDependency """
+function addDependency(ref){
+ return function(dep){
+ return function(){
+ return ref.addDependency(dep);
+ };
+ };
+}""" :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit
+
+foreign import query """
+function query(ref){
+ return ref.query;
+}""" :: LoaderRef -> String
--- /dev/null
+module PursLoader.LoaderUtil
+ ( getRemainingRequest
+ , parseQuery
+ ) where
+
+import Data.Foreign (Foreign())
+
+import PursLoader.LoaderRef (LoaderRef())
+
+foreign import getRemainingRequest """
+function getRemainingRequest(ref){
+ var loaderUtils = require('loader-utils');
+ return loaderUtils.getRemainingRequest(ref);
+}""" :: LoaderRef -> String
+
+foreign import parseQuery """
+function parseQuery(query){
+ var loaderUtils = require('loader-utils');
+ return loaderUtils.parseQuery(query);
+}""" :: String -> Foreign
--- /dev/null
+module PursLoader.OS (eol) where
+
+foreign import eol "var eol = require('os').EOL;" :: String
--- /dev/null
+module PursLoader.Options
+ ( pscMakeOptions
+ , pscMakeDefaultOutput
+ , pscMakeOutputOption
+ ) where
+
+import Data.Either (either)
+
+import Data.Foreign (Foreign(), F())
+import Data.Foreign.Class (IsForeign, read, readProp)
+import Data.Foreign.NullOrUndefined (NullOrUndefined(), runNullOrUndefined)
+
+import Data.Maybe (Maybe(..), maybe)
+
+noPreludeOpt = "no-prelude"
+
+noOptsOpt = "no-opts"
+
+noMagicDoOpt = "no-magic-do"
+
+noTcoOpt = "no-tco"
+
+verboseErrorsOpt = "verbose-errors"
+
+outputOpt = "output"
+
+pscMakeDefaultOutput = "output"
+
+newtype Options
+ = Options { noPrelude :: NullOrUndefined Boolean
+ , noOpts :: NullOrUndefined Boolean
+ , noMagicDo :: NullOrUndefined Boolean
+ , noTco :: NullOrUndefined Boolean
+ , verboseErrors :: NullOrUndefined Boolean
+ , output :: NullOrUndefined String
+ }
+
+instance isForeignOptions :: IsForeign Options where
+ read obj = (\a b c d e f ->
+ Options { noPrelude: a
+ , noOpts: b
+ , noMagicDo: c
+ , noTco: d
+ , verboseErrors: e
+ , output: f
+ }) <$> readProp noPreludeOpt obj
+ <*> readProp noOptsOpt obj
+ <*> readProp noMagicDoOpt obj
+ <*> readProp noTcoOpt obj
+ <*> readProp verboseErrorsOpt obj
+ <*> readProp outputOpt obj
+
+booleanOpt :: String -> NullOrUndefined Boolean -> [String]
+booleanOpt key opt = maybe [] (\a -> if a then ["--" ++ key] else []) (runNullOrUndefined opt)
+
+stringOpt :: String -> NullOrUndefined String -> [String]
+stringOpt key opt = maybe [] (\a -> ["--" ++ key ++ "=" ++ a]) (runNullOrUndefined opt)
+
+pscMakeOutputOption :: Foreign -> Maybe String
+pscMakeOutputOption query = either (const Nothing)
+ (\(Options a) -> runNullOrUndefined a.output)
+ (read query)
+
+pscMakeOptions :: Foreign -> [String]
+pscMakeOptions query = either (const []) fold parsed
+ where parsed = read query :: F Options
+ fold (Options a) = booleanOpt noPreludeOpt a.noPrelude <>
+ booleanOpt noOptsOpt a.noOpts <>
+ booleanOpt noMagicDoOpt a.noMagicDo <>
+ booleanOpt noTcoOpt a.noTco <>
+ booleanOpt verboseErrorsOpt a.verboseErrors <>
+ stringOpt outputOpt a.output
--- /dev/null
+module PursLoader.Path
+ ( dirname
+ , join
+ , relative
+ , resolve
+ ) where
+
+foreign import dirname """
+function dirname(filepath) {
+ var path = require('path');
+ return path.dirname(filepath);
+}
+""" :: String -> String
+
+foreign import join """
+function join(parts) {
+ var path = require('path');
+ return path.join.apply(path, parts);
+}
+""" :: [String] -> String
+
+foreign import relative """
+function relative(from) {
+ return function(to){
+ var path = require('path');
+ return path.relative(from, to);
+ };
+}
+""" :: String -> String -> String
+
+foreign import resolve """
+function resolve(filepath) {
+ var path = require('path');
+ return path.resolve(filepath);
+}
+""" :: String -> String
--- /dev/null
+'use strict';
+
+var path = require('path');
+
+var webpack = require('webpack');
+
+var noErrorsPlugin = webpack.NoErrorsPlugin;
+
+var dedupePlugin = webpack.optimize.DedupePlugin;
+
+var config
+ = { cache: true
+ , target: 'node'
+ , entry: { index: './entry' }
+ , externals: { 'glob': 'commonjs glob'
+ , 'loader-utils': 'commonjs loader-utils'
+ }
+ , output: { path: __dirname
+ , filename: '[name].js'
+ , libraryTarget: 'commonjs2'
+ }
+ , plugins: [ new noErrorsPlugin()
+ , new dedupePlugin()
+ ]
+ , resolve: { modulesDirectories: [ 'build' ] }
+ }
+ ;
+
+module.exports = config;