From 011f8d36278ad22711a1a94ae31aff435bd1ac60 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 13:36:59 +0100 Subject: [PATCH 01/45] Use ES6 import syntax --- src/index.ts | 15 ++++++++------- src/worker.ts | 9 ++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5b1e79f..5808780 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,13 @@ -'use strict'; +import * as spawn from "cross-spawn"; +import * as _ from "lodash" +import * as fs from "fs"; +import * as path from "path"; +import * as temp from "temp"; +import { findAllDependencies } from "find-elm-dependencies"; -var spawn = require("cross-spawn"); -var _ = require("lodash"); var elmBinaryName = "elm"; -var fs = require("fs"); -var path = require("path"); -var temp = require("temp").track(); -var findAllDependencies = require("find-elm-dependencies").findAllDependencies; + +temp.track(); var defaultOptions = { spawn: spawn, diff --git a/src/worker.ts b/src/worker.ts index 0e1220f..1a5344a 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,5 +1,8 @@ -var temp = require("temp").track(); -var path = require("path"); +import * as temp from "temp"; +import * as path from "path"; + +temp.track(); + var jsEmitterFilename = "emitter.js"; var KNOWN_MODULES = @@ -37,7 +40,7 @@ module.exports = function (compile) { process.chdir(projectRootDir); return createTmpDir() - .then(function (tmpDirPath) { + .then(function (tmpDirPath: string) { var dest = path.join(tmpDirPath, jsEmitterFilename); return compileEmitter(compile, modulePath, { output: dest }) From 085bedbc16c5e448df3d33ef7054a655e320dfe5 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 13:37:06 +0100 Subject: [PATCH 02/45] Add @types --- package-lock.json | 24 ++++++++++++++++++++++++ package.json | 5 ++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index d8e18ce..87acda5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,21 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/cross-spawn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.0.tgz", + "integrity": "sha512-evp2ZGsFw9YKprDbg8ySgC9NA15g3YgiI8ANkGmKKvvi0P2aDGYLPxQIC5qfeKNUOe3TjABVGuah6omPRpIYhg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.119", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.119.tgz", + "integrity": "sha512-Z3TNyBL8Vd/M9D9Ms2S3LmFq2sSMzahodD6rCS9V2N44HUMINb75jNkSuwAx7eo2ufqTdfOdtGQpNbieUjPQmw==", + "dev": true + }, "@types/mocha": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", @@ -16,6 +31,15 @@ "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==", "dev": true }, + "@types/temp": { + "version": "0.8.32", + "resolved": "https://registry.npmjs.org/@types/temp/-/temp-0.8.32.tgz", + "integrity": "sha512-gyIhOlWPqI8vtYTlRb61HKV7x+3wjpJIQi8mTaweVtEMvhIV6Xajo8FVcNJWeJOBuedRCzK2Uy+uhj/rJmR9oQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", diff --git a/package.json b/package.json index 4edd108..aff60f7 100644 --- a/package.json +++ b/package.json @@ -33,12 +33,15 @@ "temp": "^0.8.3" }, "devDependencies": { + "@types/cross-spawn": "^6.0.0", + "@types/lodash": "^4.14.119", "@types/mocha": "^5.2.5", "@types/node": "^10.12.15", + "@types/temp": "^0.8.32", "chai": "3.5.0", "glob": "7.1.1", "mocha": "5.1.1", "ts-node": "^7.0.1", "typescript": "^3.2.2" } -} \ No newline at end of file +} From d5db267fd800d4a54b573f560a2430d2c6e90c63 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 13:41:33 +0100 Subject: [PATCH 03/45] Move exported functions to top of index.ts --- src/index.ts | 170 ++++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 84 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5808780..0b84b5c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,92 @@ var elmBinaryName = "elm"; temp.track(); + +function compile(sources, options) { + var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); + var pathToElm = options.pathToElm || elmBinaryName; + + + try { + return runCompiler(sources, optionsWithDefaults, pathToElm) + .on('error', function (err) { throw (err); }); + } catch (err) { + throw compilerErrorToString(err, pathToElm); + } +} + +function compileSync(sources, options) { + var optionsWithDefaults = prepareOptions(options, options.spawn || spawn.sync); + var pathToElm = options.pathToElm || elmBinaryName; + + try { + return runCompiler(sources, optionsWithDefaults, pathToElm); + } catch (err) { + throw compilerErrorToString(err, pathToElm); + } +} + +// write compiled Elm to a string output +// returns a Promise which will contain a Buffer of the text +// If you want html instead of js, use options object to set +// output to a html file instead +// creates a temp file and deletes it after reading +function compileToString(sources, options) { + const suffix = getSuffix(options.output, '.js'); + + return new Promise(function (resolve, reject) { + temp.open({ suffix }, function (err, info) { + if (err) { + return reject(err); + } + + options.output = info.path; + options.processOpts = { stdio: 'pipe' } + + var compiler; + + try { + compiler = compile(sources, options); + } catch (compileError) { + return reject(compileError); + } + + compiler.stdout.setEncoding("utf8"); + compiler.stderr.setEncoding("utf8"); + + var output = ''; + compiler.stdout.on('data', function (chunk) { + output += chunk; + }); + compiler.stderr.on('data', function (chunk) { + output += chunk; + }); + + compiler.on("close", function (exitCode) { + if (exitCode !== 0) { + return reject(new Error('Compilation failed\n' + output)); + } else if (options.verbose) { + console.log(output); + } + + fs.readFile(info.path, { encoding: "utf8" }, function (err, data) { + return err ? reject(err) : resolve(data); + }); + }); + }); + }); +} + +function compileToStringSync(sources, options) { + const suffix = getSuffix(options.output, '.js'); + + const file = temp.openSync({ suffix }); + options.output = file.path; + compileSync(sources, options); + + return fs.readFileSync(file.path, { encoding: "utf8" }); +} + var defaultOptions = { spawn: spawn, cwd: undefined, @@ -84,29 +170,6 @@ function compilerErrorToString(err, pathToElm) { } } -function compileSync(sources, options) { - var optionsWithDefaults = prepareOptions(options, options.spawn || spawn.sync); - var pathToElm = options.pathToElm || elmBinaryName; - - try { - return runCompiler(sources, optionsWithDefaults, pathToElm); - } catch (err) { - throw compilerErrorToString(err, pathToElm); - } -} - -function compile(sources, options) { - var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); - var pathToElm = options.pathToElm || elmBinaryName; - - - try { - return runCompiler(sources, optionsWithDefaults, pathToElm) - .on('error', function (err) { throw (err); }); - } catch (err) { - throw compilerErrorToString(err, pathToElm); - } -} function getSuffix(outputPath, defaultSuffix) { if (outputPath) { @@ -116,67 +179,6 @@ function getSuffix(outputPath, defaultSuffix) { } } -// write compiled Elm to a string output -// returns a Promise which will contain a Buffer of the text -// If you want html instead of js, use options object to set -// output to a html file instead -// creates a temp file and deletes it after reading -function compileToString(sources, options) { - const suffix = getSuffix(options.output, '.js'); - - return new Promise(function (resolve, reject) { - temp.open({ suffix }, function (err, info) { - if (err) { - return reject(err); - } - - options.output = info.path; - options.processOpts = { stdio: 'pipe' } - - var compiler; - - try { - compiler = compile(sources, options); - } catch (compileError) { - return reject(compileError); - } - - compiler.stdout.setEncoding("utf8"); - compiler.stderr.setEncoding("utf8"); - - var output = ''; - compiler.stdout.on('data', function (chunk) { - output += chunk; - }); - compiler.stderr.on('data', function (chunk) { - output += chunk; - }); - - compiler.on("close", function (exitCode) { - if (exitCode !== 0) { - return reject(new Error('Compilation failed\n' + output)); - } else if (options.verbose) { - console.log(output); - } - - fs.readFile(info.path, { encoding: "utf8" }, function (err, data) { - return err ? reject(err) : resolve(data); - }); - }); - }); - }); -} - -function compileToStringSync(sources, options) { - const suffix = getSuffix(options.output, '.js'); - - const file = temp.openSync({ suffix }); - options.output = file.path; - compileSync(sources, options); - - return fs.readFileSync(file.path, { encoding: "utf8" }); -} - // Converts an object of key/value pairs to an array of arguments suitable // to be passed to child_process.spawn for elm-make. function compilerArgsFromOptions(options) { From c3a65d4c0d21cf63a133122152b2a64e01b30779 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 13:53:19 +0100 Subject: [PATCH 04/45] Add type declaration for find-elm-dependencies --- src/find-elm-dependencies.d.ts | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/find-elm-dependencies.d.ts diff --git a/src/find-elm-dependencies.d.ts b/src/find-elm-dependencies.d.ts new file mode 100644 index 0000000..08c2179 --- /dev/null +++ b/src/find-elm-dependencies.d.ts @@ -0,0 +1,3 @@ +declare module "find-elm-dependencies" { + export function findAllDependencies(src: string): Promise +} \ No newline at end of file From b00acd32cf779c388952b4c426bf95e28b80ca14 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:01:24 +0100 Subject: [PATCH 05/45] Add Options type --- src/index.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 0b84b5c..8bbb0b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -95,8 +95,24 @@ function compileToStringSync(sources, options) { return fs.readFileSync(file.path, { encoding: "utf8" }); } -var defaultOptions = { +type Options = { + spawn: typeof spawn, + runtimeOptions: string[], + cwd: string, + pathToElm: string, + help: boolean, + output: string, + report: string, + debug: boolean, + verbose: boolean, + processOpts: SpawnOptions, + docs: string, + optimize: boolean, +} + +var defaultOptions: Partial = { spawn: spawn, + runtimeOptions: undefined, cwd: undefined, pathToElm: undefined, help: undefined, From 231f9dfe4343275d281b973c69fc1c8964c0b6d1 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:02:26 +0100 Subject: [PATCH 06/45] Type compilerArgsFromOptions --- src/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8bbb0b0..44284c0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -197,17 +197,17 @@ function getSuffix(outputPath, defaultSuffix) { // Converts an object of key/value pairs to an array of arguments suitable // to be passed to child_process.spawn for elm-make. -function compilerArgsFromOptions(options) { - return _.flatten(_.map(options, function (value, opt) { +function compilerArgsFromOptions(options: Options): string[] { + return _.flatten(_.map(options, function (value, opt): string[] { if (value) { switch (opt) { case "help": return ["--help"]; - case "output": return ["--output", value]; - case "report": return ["--report", value]; + case "output": return ["--output", (value as string)]; + case "report": return ["--report", (value as string)]; case "debug": return ["--debug"]; - case "docs": return ["--docs", value]; + case "docs": return ["--docs", (value as string)]; case "optimize": return ["--optimize"]; - case "runtimeOptions": return [].concat(["+RTS"], value, ["-RTS"]); + case "runtimeOptions": return _.concat(["+RTS"], (value as string), ["-RTS"]); default: if (supportedOptions.indexOf(opt) === -1) { if (opt === "yes") { From fb87a9df63c164185b707b5ef2b777513441b737 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:03:01 +0100 Subject: [PATCH 07/45] Type getSuffix --- src/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 44284c0..411b85a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,8 @@ import * as path from "path"; import * as temp from "temp"; import { findAllDependencies } from "find-elm-dependencies"; +import { SpawnOptions } from "child_process"; + var elmBinaryName = "elm"; temp.track(); @@ -186,8 +188,7 @@ function compilerErrorToString(err, pathToElm) { } } - -function getSuffix(outputPath, defaultSuffix) { +function getSuffix(outputPath: string, defaultSuffix: string): string { if (outputPath) { return path.extname(outputPath) || defaultSuffix; } else { From a4de84cd2a584cca506dc6a851d347a4cd2c9f99 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:04:56 +0100 Subject: [PATCH 08/45] Type compilerErrorToString --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 411b85a..08b0671 100644 --- a/src/index.ts +++ b/src/index.ts @@ -169,7 +169,7 @@ function runCompiler(sources, options, pathToElm) { return options.spawn(pathToElm, processArgs, processOpts); } -function compilerErrorToString(err, pathToElm) { +function compilerErrorToString(err: { code?: string, message?: string }, pathToElm: string): string { if ((typeof err === "object") && (typeof err.code === "string")) { switch (err.code) { case "ENOENT": From 5b993151fa64259bfc35e8f19d6ab83bbe288ed6 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:06:22 +0100 Subject: [PATCH 09/45] Reorder index.ts --- src/index.ts | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/index.ts b/src/index.ts index 08b0671..37ea0a7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -129,31 +129,10 @@ var defaultOptions: Partial = { var supportedOptions = _.keys(defaultOptions); -function prepareSources(sources) { - if (!(sources instanceof Array || typeof sources === "string")) { - throw "compile() received neither an Array nor a String for its sources argument."; - } - - return typeof sources === "string" ? [sources] : sources; -} - function prepareOptions(options, spawnFn) { return _.defaults({ spawn: spawnFn }, options, defaultOptions); } -function prepareProcessArgs(sources, options) { - var preparedSources = prepareSources(sources); - var compilerArgs = compilerArgsFromOptions(options); - - return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); -} - -function prepareProcessOpts(options) { - var env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); - return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); - -} - function runCompiler(sources, options, pathToElm) { if (typeof options.spawn !== "function") { throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; @@ -168,6 +147,27 @@ function runCompiler(sources, options, pathToElm) { return options.spawn(pathToElm, processArgs, processOpts); } +function prepareProcessArgs(sources, options) { + var preparedSources = prepareSources(sources); + var compilerArgs = compilerArgsFromOptions(options); + + return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); +} + +function prepareSources(sources) { + if (!(sources instanceof Array || typeof sources === "string")) { + throw "compile() received neither an Array nor a String for its sources argument."; + } + + return typeof sources === "string" ? [sources] : sources; +} + +function prepareProcessOpts(options) { + var env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); + return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); + +} + function compilerErrorToString(err: { code?: string, message?: string }, pathToElm: string): string { if ((typeof err === "object") && (typeof err.code === "string")) { From fc8aca4a6a6038cb5d5e659ccf80dcb5ca45244e Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:08:38 +0100 Subject: [PATCH 10/45] Type prepareProcessOpts --- src/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 37ea0a7..8f0951b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -147,6 +147,7 @@ function runCompiler(sources, options, pathToElm) { return options.spawn(pathToElm, processArgs, processOpts); } + function prepareProcessArgs(sources, options) { var preparedSources = prepareSources(sources); var compilerArgs = compilerArgsFromOptions(options); @@ -162,13 +163,18 @@ function prepareSources(sources) { return typeof sources === "string" ? [sources] : sources; } -function prepareProcessOpts(options) { +type ProcessOptions = { + env: { [key: string]: string }, + stdio: string, + cwd: string, +} + +function prepareProcessOpts(options: Options): ProcessOptions { var env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); } - function compilerErrorToString(err: { code?: string, message?: string }, pathToElm: string): string { if ((typeof err === "object") && (typeof err.code === "string")) { switch (err.code) { From 5c742e4feeaf83d5770cf3ff3c9b259e4b6aaae0 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:09:40 +0100 Subject: [PATCH 11/45] Type prepareSources --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 8f0951b..6d42dfb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -155,7 +155,7 @@ function prepareProcessArgs(sources, options) { return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); } -function prepareSources(sources) { +function prepareSources(sources: any): string[] { if (!(sources instanceof Array || typeof sources === "string")) { throw "compile() received neither an Array nor a String for its sources argument."; } From 0ac20bf9d5ec9b9414cceb57b9e922c9236d024d Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:10:23 +0100 Subject: [PATCH 12/45] Type prepareProcessArgs --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 6d42dfb..4d88432 100644 --- a/src/index.ts +++ b/src/index.ts @@ -148,7 +148,7 @@ function runCompiler(sources, options, pathToElm) { return options.spawn(pathToElm, processArgs, processOpts); } -function prepareProcessArgs(sources, options) { +function prepareProcessArgs(sources: any, options: Options): string[] { var preparedSources = prepareSources(sources); var compilerArgs = compilerArgsFromOptions(options); From 3a1ec5ad289cf42205aacdb7b9c69467b7aa4f41 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:12:02 +0100 Subject: [PATCH 13/45] Type runCompiler --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 4d88432..8ac918c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -133,7 +133,7 @@ function prepareOptions(options, spawnFn) { return _.defaults({ spawn: spawnFn }, options, defaultOptions); } -function runCompiler(sources, options, pathToElm) { +function runCompiler(sources: any, options: Options, pathToElm: string): ChildProcess { if (typeof options.spawn !== "function") { throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; } From 15f0670514f419cf2352c60e412df1256143c239 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:12:44 +0100 Subject: [PATCH 14/45] Fix prepareProcessOpts's return type --- src/index.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8ac918c..f45772d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ import * as path from "path"; import * as temp from "temp"; import { findAllDependencies } from "find-elm-dependencies"; -import { SpawnOptions } from "child_process"; +import { SpawnOptions, ChildProcess } from "child_process"; var elmBinaryName = "elm"; @@ -163,13 +163,7 @@ function prepareSources(sources: any): string[] { return typeof sources === "string" ? [sources] : sources; } -type ProcessOptions = { - env: { [key: string]: string }, - stdio: string, - cwd: string, -} - -function prepareProcessOpts(options: Options): ProcessOptions { +function prepareProcessOpts(options: Options): SpawnOptions { var env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); From 0ea654a675c48ac9692b22e322a3ca3905fc85cb Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:14:46 +0100 Subject: [PATCH 15/45] Type prepareOptions --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index f45772d..c5c365b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -129,7 +129,7 @@ var defaultOptions: Partial = { var supportedOptions = _.keys(defaultOptions); -function prepareOptions(options, spawnFn) { +function prepareOptions(options: Options, spawnFn: typeof spawn): Options { return _.defaults({ spawn: spawnFn }, options, defaultOptions); } From 5219a891accf0fbd9a0265e215b7a567c50869f6 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:15:47 +0100 Subject: [PATCH 16/45] Type compileToStringSync --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index c5c365b..f0f80a8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -87,7 +87,7 @@ function compileToString(sources, options) { }); } -function compileToStringSync(sources, options) { +function compileToStringSync(sources: any, options: Options): string { const suffix = getSuffix(options.output, '.js'); const file = temp.openSync({ suffix }); From 55746348f9b3257bbce68a4183623fe3959208d6 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:16:45 +0100 Subject: [PATCH 17/45] Type compileToString --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index f0f80a8..b42a111 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,7 +41,7 @@ function compileSync(sources, options) { // If you want html instead of js, use options object to set // output to a html file instead // creates a temp file and deletes it after reading -function compileToString(sources, options) { +function compileToString(sources: any, options: Options): Promise { const suffix = getSuffix(options.output, '.js'); return new Promise(function (resolve, reject) { From f76b30fbe03d5cba7b1fe5d26ca1d3c1bf7f8179 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:17:36 +0100 Subject: [PATCH 18/45] Type compileSync --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index b42a111..d374057 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,7 +25,7 @@ function compile(sources, options) { } } -function compileSync(sources, options) { +function compileSync(sources: any, options: Options): ChildProcess { var optionsWithDefaults = prepareOptions(options, options.spawn || spawn.sync); var pathToElm = options.pathToElm || elmBinaryName; From be4ab66953d8b2e03789d7e566c07bbbb0c1a431 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:18:59 +0100 Subject: [PATCH 19/45] Type compile --- src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index d374057..d7c24e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,11 +12,10 @@ var elmBinaryName = "elm"; temp.track(); -function compile(sources, options) { +function compile(sources: any, options: Options): ChildProcess { var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); var pathToElm = options.pathToElm || elmBinaryName; - try { return runCompiler(sources, optionsWithDefaults, pathToElm) .on('error', function (err) { throw (err); }); From 184b3a1473633470c502f8a0cbc8478d591697ef Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:19:40 +0100 Subject: [PATCH 20/45] Fix type of sources parameter --- src/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index d7c24e9..683e8c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ var elmBinaryName = "elm"; temp.track(); -function compile(sources: any, options: Options): ChildProcess { +function compile(sources: string | string[], options: Options): ChildProcess { var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); var pathToElm = options.pathToElm || elmBinaryName; @@ -24,7 +24,7 @@ function compile(sources: any, options: Options): ChildProcess { } } -function compileSync(sources: any, options: Options): ChildProcess { +function compileSync(sources: string | string[], options: Options): ChildProcess { var optionsWithDefaults = prepareOptions(options, options.spawn || spawn.sync); var pathToElm = options.pathToElm || elmBinaryName; @@ -40,7 +40,7 @@ function compileSync(sources: any, options: Options): ChildProcess { // If you want html instead of js, use options object to set // output to a html file instead // creates a temp file and deletes it after reading -function compileToString(sources: any, options: Options): Promise { +function compileToString(sources: string | string[], options: Options): Promise { const suffix = getSuffix(options.output, '.js'); return new Promise(function (resolve, reject) { @@ -86,7 +86,7 @@ function compileToString(sources: any, options: Options): Promise { }); } -function compileToStringSync(sources: any, options: Options): string { +function compileToStringSync(sources: string | string[], options: Options): string { const suffix = getSuffix(options.output, '.js'); const file = temp.openSync({ suffix }); @@ -132,7 +132,7 @@ function prepareOptions(options: Options, spawnFn: typeof spawn): Options { return _.defaults({ spawn: spawnFn }, options, defaultOptions); } -function runCompiler(sources: any, options: Options, pathToElm: string): ChildProcess { +function runCompiler(sources: string | string[], options: Options, pathToElm: string): ChildProcess { if (typeof options.spawn !== "function") { throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; } @@ -147,14 +147,14 @@ function runCompiler(sources: any, options: Options, pathToElm: string): ChildPr return options.spawn(pathToElm, processArgs, processOpts); } -function prepareProcessArgs(sources: any, options: Options): string[] { +function prepareProcessArgs(sources: string | string[], options: Options): string[] { var preparedSources = prepareSources(sources); var compilerArgs = compilerArgsFromOptions(options); return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); } -function prepareSources(sources: any): string[] { +function prepareSources(sources: string | string[]): string[] { if (!(sources instanceof Array || typeof sources === "string")) { throw "compile() received neither an Array nor a String for its sources argument."; } From cdd8b3bc5d858f92a6d8ee6f6dec5b949972bf4f Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:25:50 +0100 Subject: [PATCH 21/45] Type compileEmitter --- src/index.ts | 4 ++-- src/worker.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 683e8c2..7d7e1c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ var elmBinaryName = "elm"; temp.track(); -function compile(sources: string | string[], options: Options): ChildProcess { +export function compile(sources: string | string[], options: Options): ChildProcess { var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); var pathToElm = options.pathToElm || elmBinaryName; @@ -96,7 +96,7 @@ function compileToStringSync(sources: string | string[], options: Options): stri return fs.readFileSync(file.path, { encoding: "utf8" }); } -type Options = { +export type Options = { spawn: typeof spawn, runtimeOptions: string[], cwd: string, diff --git a/src/worker.ts b/src/worker.ts index 1a5344a..e3ce8c8 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,6 +1,8 @@ import * as temp from "temp"; import * as path from "path"; +import { compile as compileFunc, Options } from './index'; + temp.track(); var jsEmitterFilename = "emitter.js"; @@ -32,6 +34,7 @@ var KNOWN_MODULES = "Css" ]; +type Compile = typeof compileFunc; // elmModuleName is optional, and is by default inferred based on the filename. module.exports = function (compile) { @@ -117,7 +120,7 @@ function runWorker(jsFilename, moduleName, workerArgs) { }); } -function compileEmitter(compile, src, options) { +function compileEmitter(compile: Compile, src: string, options: Options): Promise { return new Promise(function (resolve, reject) { compile(src, options) .on("close", function (exitCode) { From 49dc62eff90c30c1d100db93dc7605ddf03a2694 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:27:43 +0100 Subject: [PATCH 22/45] type runWorker --- src/worker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/worker.ts b/src/worker.ts index e3ce8c8..541f739 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -102,7 +102,9 @@ function noPortsMessage(moduleName) { return errorMessage.trim(); } -function runWorker(jsFilename, moduleName, workerArgs) { +type ElmWorker = object; + +function runWorker(jsFilename: string, moduleName: string, workerArgs: string[]): Promise { return new Promise(function (resolve, reject) { var Elm = require(jsFilename).Elm; From 4fb54dde1e20779b8015aa3683bd3a225d1cbebf Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:27:53 +0100 Subject: [PATCH 23/45] Type noPortsMessage --- src/worker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/worker.ts b/src/worker.ts index 541f739..1b0bb68 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -93,7 +93,7 @@ function missingEntryModuleMessage(moduleName, Elm) { return errorMessage; } -function noPortsMessage(moduleName) { +function noPortsMessage(moduleName: string): string { var errorMessage = "The module " + moduleName + " doesn't expose any ports!\n"; errorMessage += "\n\nTry adding something like"; From e40a8cb7c64126483be69b5aa7ceb40421f47dd0 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:28:24 +0100 Subject: [PATCH 24/45] Type missingEntryModuleMessage --- src/worker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/worker.ts b/src/worker.ts index 1b0bb68..e1f79c2 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -78,7 +78,7 @@ function suggestModulesNames(Elm) { }) } -function missingEntryModuleMessage(moduleName, Elm) { +function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { var errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; var suggestions = suggestModulesNames(Elm); From 0c66e791d2a9c9cf6fb86242619e8a3ec3cc2f59 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:29:34 +0100 Subject: [PATCH 25/45] Type suggestModulesNames --- src/worker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/worker.ts b/src/worker.ts index e1f79c2..de182a6 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -72,7 +72,9 @@ function createTmpDir() { }); } -function suggestModulesNames(Elm) { +type ElmWorker = object; + +function suggestModulesNames(Elm: ElmWorker): string[] { return Object.keys(Elm).filter(function (key) { return KNOWN_MODULES.indexOf(key) === -1; }) @@ -102,8 +104,6 @@ function noPortsMessage(moduleName: string): string { return errorMessage.trim(); } -type ElmWorker = object; - function runWorker(jsFilename: string, moduleName: string, workerArgs: string[]): Promise { return new Promise(function (resolve, reject) { var Elm = require(jsFilename).Elm; From f5069bc632a22e7f4f528d6df7daa4b92ff172de Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 4 Jan 2019 14:29:58 +0100 Subject: [PATCH 26/45] Type createTmpDir --- src/worker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/worker.ts b/src/worker.ts index de182a6..061ad59 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -60,7 +60,7 @@ module.exports = function (compile) { }; }; -function createTmpDir() { +function createTmpDir(): Promise { return new Promise(function (resolve, reject) { temp.mkdir("node-elm-compiler", function (err, tmpDirPath) { if (err) { From 882d27812b5805d92eebc05945f4f0151494748b Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Tue, 15 Jan 2019 11:37:46 +0100 Subject: [PATCH 27/45] Fix getSuffix --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 7d7e1c6..44cbc6a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -187,7 +187,7 @@ function compilerErrorToString(err: { code?: string, message?: string }, pathToE } } -function getSuffix(outputPath: string, defaultSuffix: string): string { +function getSuffix(outputPath: string | undefined, defaultSuffix: string): string { if (outputPath) { return path.extname(outputPath) || defaultSuffix; } else { From 7329c3c9c32e378be6b18c73a860de84d4e786d6 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Tue, 15 Jan 2019 11:37:51 +0100 Subject: [PATCH 28/45] Fix Options --- src/index.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index 44cbc6a..49af2e0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,8 +12,8 @@ var elmBinaryName = "elm"; temp.track(); -export function compile(sources: string | string[], options: Options): ChildProcess { - var optionsWithDefaults = prepareOptions(options, options.spawn || spawn); +export function compile(sources: string | string[], options: Partial): ChildProcess { + var optionsWithDefaults = prepareOptions(options, spawn); var pathToElm = options.pathToElm || elmBinaryName; try { @@ -24,8 +24,8 @@ export function compile(sources: string | string[], options: Options): ChildProc } } -function compileSync(sources: string | string[], options: Options): ChildProcess { - var optionsWithDefaults = prepareOptions(options, options.spawn || spawn.sync); +function compileSync(sources: string | string[], options: Partial): ChildProcess { + var optionsWithDefaults = prepareOptions(options, spawn.sync as any); var pathToElm = options.pathToElm || elmBinaryName; try { @@ -40,7 +40,7 @@ function compileSync(sources: string | string[], options: Options): ChildProcess // If you want html instead of js, use options object to set // output to a html file instead // creates a temp file and deletes it after reading -function compileToString(sources: string | string[], options: Options): Promise { +function compileToString(sources: string | string[], options: Partial): Promise { const suffix = getSuffix(options.output, '.js'); return new Promise(function (resolve, reject) { @@ -98,20 +98,20 @@ function compileToStringSync(sources: string | string[], options: Options): stri export type Options = { spawn: typeof spawn, - runtimeOptions: string[], - cwd: string, - pathToElm: string, - help: boolean, - output: string, - report: string, - debug: boolean, - verbose: boolean, - processOpts: SpawnOptions, - docs: string, - optimize: boolean, + runtimeOptions?: string[], + cwd?: string, + pathToElm?: string, + help?: boolean, + output?: string, + report?: string, + debug?: boolean, + verbose?: boolean, + processOpts?: SpawnOptions, + docs?: string, + optimize?: boolean, } -var defaultOptions: Partial = { +var defaultOptions: Options = { spawn: spawn, runtimeOptions: undefined, cwd: undefined, @@ -128,7 +128,7 @@ var defaultOptions: Partial = { var supportedOptions = _.keys(defaultOptions); -function prepareOptions(options: Options, spawnFn: typeof spawn): Options { +function prepareOptions(options: Partial, spawnFn: typeof spawn): Options { return _.defaults({ spawn: spawnFn }, options, defaultOptions); } From 06ba11ff68f78c78664a67356a4a6546e91d1544 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Tue, 15 Jan 2019 11:38:30 +0100 Subject: [PATCH 29/45] Type worker.ts --- src/worker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/worker.ts b/src/worker.ts index 061ad59..0fd5ada 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -37,8 +37,8 @@ var KNOWN_MODULES = type Compile = typeof compileFunc; // elmModuleName is optional, and is by default inferred based on the filename. -module.exports = function (compile) { - return function (projectRootDir, modulePath, moduleName, workerArgs) { +module.exports = function (compile: Compile) { + return function (projectRootDir: string, modulePath: string, moduleName: string, workerArgs: object) { var originalWorkingDir = process.cwd(); process.chdir(projectRootDir); @@ -104,7 +104,7 @@ function noPortsMessage(moduleName: string): string { return errorMessage.trim(); } -function runWorker(jsFilename: string, moduleName: string, workerArgs: string[]): Promise { +function runWorker(jsFilename: string, moduleName: string, workerArgs: object): Promise { return new Promise(function (resolve, reject) { var Elm = require(jsFilename).Elm; @@ -122,7 +122,7 @@ function runWorker(jsFilename: string, moduleName: string, workerArgs: string[]) }); } -function compileEmitter(compile: Compile, src: string, options: Options): Promise { +function compileEmitter(compile: Compile, src: string, options: Partial): Promise { return new Promise(function (resolve, reject) { compile(src, options) .on("close", function (exitCode) { From b53d3771e46558595c8bdc1d061cedafa0099da6 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Tue, 15 Jan 2019 11:38:40 +0100 Subject: [PATCH 30/45] Type tests --- test/compile.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/compile.ts b/test/compile.ts index 5b446a1..9ea21be 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -9,7 +9,7 @@ var expect = chai.expect; var fixturesDir = path.join(__dirname, "fixtures"); -function prependFixturesDir(filename) { +function prependFixturesDir(filename: string) { return path.join(fixturesDir, filename); } @@ -24,7 +24,7 @@ describe("#compile", function () { }; var compileProcess = compiler.compile(prependFixturesDir("Bad.elm"), opts); - compileProcess.on("exit", function (exitCode) { + compileProcess.on("exit", function (exitCode: number) { var desc = "Expected elm make to have exit code 1"; expect(exitCode, desc).to.equal(1); done(); @@ -69,7 +69,7 @@ describe("#compileToString", function () { }; var compilePromise = compiler.compileToString(prependFixturesDir("Bad.elm"), opts); - return compilePromise.catch(function (err) { + return compilePromise.catch(function (err: Error) { expect(err).to.be.an('error'); expect(String(err)) .to.contain("Compilation failed") @@ -84,7 +84,7 @@ describe("#compileToString", function () { }; var compilePromise = compiler.compileToString(prependFixturesDir("TypeError.elm"), opts); - return compilePromise.catch(function (err) { + return compilePromise.catch(function (err: Error) { expect(err).to.be.an('error'); expect(String(err)) .to.contain("Compilation failed") @@ -120,7 +120,7 @@ describe("#compileToString", function () { var runCompile = function () { var compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts) - return compilePromise.then(function (result) { + return compilePromise.then(function (result: string) { var desc = "Expected elm make to return the result of the compilation"; expect(result.toString(), desc).to.be.a('string'); }); @@ -144,7 +144,7 @@ describe("#compileToString", function () { }; return compiler.compileToString(prependFixturesDir("Parent.elm"), opts) - .then(function (result) { + .then(function (result: string) { var desc = "Expected elm make to return the result of the compilation"; expect(result.toString(), desc).to.be.a('string'); }); @@ -166,8 +166,8 @@ describe("#compileWorker", function () { "BasicWorker" ); - return compilePromise.then(function (app) { - app.ports.reportFromWorker.subscribe(function (str) { + return compilePromise.then(function (app: any) { + app.ports.reportFromWorker.subscribe(function (str: string) { expect(str).to.equal("it's alive!"); }); }) From 7799a04e936c0e799e9793acde7a8fb726971701 Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Fri, 22 Mar 2019 21:56:51 +0100 Subject: [PATCH 31/45] Improve types in compilerArgsFromOptions --- src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index 49af2e0..2798f2d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -198,16 +198,16 @@ function getSuffix(outputPath: string | undefined, defaultSuffix: string): strin // Converts an object of key/value pairs to an array of arguments suitable // to be passed to child_process.spawn for elm-make. function compilerArgsFromOptions(options: Options): string[] { - return _.flatten(_.map(options, function (value, opt): string[] { + return _.flatten(_.map(options, function (value: string, opt: string): string[] { if (value) { switch (opt) { case "help": return ["--help"]; - case "output": return ["--output", (value as string)]; - case "report": return ["--report", (value as string)]; + case "output": return ["--output", value]; + case "report": return ["--report", value]; case "debug": return ["--debug"]; - case "docs": return ["--docs", (value as string)]; + case "docs": return ["--docs", value]; case "optimize": return ["--optimize"]; - case "runtimeOptions": return _.concat(["+RTS"], (value as string), ["-RTS"]); + case "runtimeOptions": return _.concat(["+RTS"], value, ["-RTS"]); default: if (supportedOptions.indexOf(opt) === -1) { if (opt === "yes") { From 84b0a3cb37d35605bc584fc2c6efc7f39faea0a4 Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Tue, 8 Sep 2020 17:25:42 +0200 Subject: [PATCH 32/45] Update Elm version in test fixtures to 0.19.1 --- test/fixtures/elm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/elm.json b/test/fixtures/elm.json index ce36fa3..d47ac2e 100644 --- a/test/fixtures/elm.json +++ b/test/fixtures/elm.json @@ -3,7 +3,7 @@ "source-directories": [ "." ], - "elm-version": "0.19.0", + "elm-version": "0.19.1", "dependencies": { "direct": { "elm/browser": "1.0.0", From f17bd3950813bf2953c537aeb035cfb5725c9e8a Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Tue, 8 Sep 2020 17:36:35 +0200 Subject: [PATCH 33/45] Fix parsing error in SimplestMain.elm test fixture --- test/fixtures/SimplestMain.elm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/fixtures/SimplestMain.elm b/test/fixtures/SimplestMain.elm index 771e409..54fc33f 100644 --- a/test/fixtures/SimplestMain.elm +++ b/test/fixtures/SimplestMain.elm @@ -1,4 +1,7 @@ +module SimplestMain exposing (..) + import Html + main = Html.text "Hello, World!" From 437ef7001855906484df5c54119f4c1067dd85af Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Tue, 8 Sep 2020 17:36:57 +0200 Subject: [PATCH 34/45] Fix unanticipated parsing error in Bad.elm test fixture --- test/compile.ts | 2 +- test/fixtures/Bad.elm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/compile.ts b/test/compile.ts index 5b446a1..61672fc 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -73,7 +73,7 @@ describe("#compileToString", function () { expect(err).to.be.an('error'); expect(String(err)) .to.contain("Compilation failed") - .and.contain("PARSE ERROR"); + .and.contain("MISSING EXPRESSION"); }); }); diff --git a/test/fixtures/Bad.elm b/test/fixtures/Bad.elm index 3934ce7..3b54a56 100644 --- a/test/fixtures/Bad.elm +++ b/test/fixtures/Bad.elm @@ -1,4 +1,4 @@ -module Bad +module Bad exposing (..) main = From 07868b732d18452279de370a87c9f684d564ef2b Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Tue, 8 Sep 2020 17:39:28 +0200 Subject: [PATCH 35/45] Update Elm version on CI to 0.19.1-3 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 53da1b1..0b84194 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ os: env: matrix: - - ELM_VERSION=0.19.0-no-deps + - ELM_VERSION=0.19.1-3 before_install: - rm -rf ~/.elm diff --git a/appveyor.yml b/appveyor.yml index 52537ac..767a2f1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ environment: - ELM_VERSION: "0.19.0-bugfix6" + ELM_VERSION: "0.19.1-3" matrix: - nodejs_version: "12.0" - nodejs_version: "10.0" From ae430c467c8a1cefdfda5ad9fcabe83d436f1be5 Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Tue, 8 Sep 2020 18:22:40 +0200 Subject: [PATCH 36/45] Update Elm version in example to 0.19.1 --- examples/elm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/elm.json b/examples/elm.json index a587ae1..dddfda2 100644 --- a/examples/elm.json +++ b/examples/elm.json @@ -3,7 +3,7 @@ "source-directories": [ "." ], - "elm-version": "0.19.0", + "elm-version": "0.19.1", "dependencies": { "direct": { "elm/browser": "1.0.0", From d54b902fd81ef196e9ced0f112f3bd6d1351ea8d Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Sat, 12 Sep 2020 17:39:22 +0200 Subject: [PATCH 37/45] Replace var with const or let --- src/index.ts | 29 +++++++++++------------ src/worker.ts | 18 +++++++-------- test/compile.ts | 46 ++++++++++++++++++------------------- test/compileSync.ts | 24 +++++++++---------- test/compileToStringSync.ts | 8 +++---- 5 files changed, 62 insertions(+), 63 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2798f2d..a8c823a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,14 +7,13 @@ import { findAllDependencies } from "find-elm-dependencies"; import { SpawnOptions, ChildProcess } from "child_process"; -var elmBinaryName = "elm"; +const elmBinaryName = "elm"; temp.track(); - export function compile(sources: string | string[], options: Partial): ChildProcess { - var optionsWithDefaults = prepareOptions(options, spawn); - var pathToElm = options.pathToElm || elmBinaryName; + const optionsWithDefaults = prepareOptions(options, spawn); + const pathToElm = options.pathToElm || elmBinaryName; try { return runCompiler(sources, optionsWithDefaults, pathToElm) @@ -25,8 +24,8 @@ export function compile(sources: string | string[], options: Partial): } function compileSync(sources: string | string[], options: Partial): ChildProcess { - var optionsWithDefaults = prepareOptions(options, spawn.sync as any); - var pathToElm = options.pathToElm || elmBinaryName; + const optionsWithDefaults = prepareOptions(options, spawn.sync as any); + const pathToElm = options.pathToElm || elmBinaryName; try { return runCompiler(sources, optionsWithDefaults, pathToElm); @@ -52,7 +51,7 @@ function compileToString(sources: string | string[], options: Partial): options.output = info.path; options.processOpts = { stdio: 'pipe' } - var compiler; + let compiler; try { compiler = compile(sources, options); @@ -63,7 +62,7 @@ function compileToString(sources: string | string[], options: Partial): compiler.stdout.setEncoding("utf8"); compiler.stderr.setEncoding("utf8"); - var output = ''; + let output = ''; compiler.stdout.on('data', function (chunk) { output += chunk; }); @@ -111,7 +110,7 @@ export type Options = { optimize?: boolean, } -var defaultOptions: Options = { +const defaultOptions: Options = { spawn: spawn, runtimeOptions: undefined, cwd: undefined, @@ -126,7 +125,7 @@ var defaultOptions: Options = { optimize: undefined, }; -var supportedOptions = _.keys(defaultOptions); +const supportedOptions = _.keys(defaultOptions); function prepareOptions(options: Partial, spawnFn: typeof spawn): Options { return _.defaults({ spawn: spawnFn }, options, defaultOptions); @@ -137,8 +136,8 @@ function runCompiler(sources: string | string[], options: Options, pathToElm: st throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; } - var processArgs = prepareProcessArgs(sources, options); - var processOpts = prepareProcessOpts(options); + const processArgs = prepareProcessArgs(sources, options); + const processOpts = prepareProcessOpts(options); if (options.verbose) { console.log(["Running", pathToElm].concat(processArgs).join(" ")); @@ -148,8 +147,8 @@ function runCompiler(sources: string | string[], options: Options, pathToElm: st } function prepareProcessArgs(sources: string | string[], options: Options): string[] { - var preparedSources = prepareSources(sources); - var compilerArgs = compilerArgsFromOptions(options); + const preparedSources = prepareSources(sources); + const compilerArgs = compilerArgsFromOptions(options); return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); } @@ -163,7 +162,7 @@ function prepareSources(sources: string | string[]): string[] { } function prepareProcessOpts(options: Options): SpawnOptions { - var env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); + const env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); } diff --git a/src/worker.ts b/src/worker.ts index 0fd5ada..9290fd1 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -5,9 +5,9 @@ import { compile as compileFunc, Options } from './index'; temp.track(); -var jsEmitterFilename = "emitter.js"; +const jsEmitterFilename = "emitter.js"; -var KNOWN_MODULES = +const KNOWN_MODULES = [ "fullscreen", "embed", @@ -39,12 +39,12 @@ type Compile = typeof compileFunc; // elmModuleName is optional, and is by default inferred based on the filename. module.exports = function (compile: Compile) { return function (projectRootDir: string, modulePath: string, moduleName: string, workerArgs: object) { - var originalWorkingDir = process.cwd(); + const originalWorkingDir = process.cwd(); process.chdir(projectRootDir); return createTmpDir() .then(function (tmpDirPath: string) { - var dest = path.join(tmpDirPath, jsEmitterFilename); + const dest = path.join(tmpDirPath, jsEmitterFilename); return compileEmitter(compile, modulePath, { output: dest }) .then(function () { return runWorker(dest, moduleName, workerArgs) }); @@ -81,8 +81,8 @@ function suggestModulesNames(Elm: ElmWorker): string[] { } function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { - var errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; - var suggestions = suggestModulesNames(Elm); + let errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; + const suggestions = suggestModulesNames(Elm); if (suggestions.length > 1) { errorMessage += "\nMaybe you meant one of these: " + suggestions.join(","); @@ -96,7 +96,7 @@ function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { } function noPortsMessage(moduleName: string): string { - var errorMessage = "The module " + moduleName + " doesn't expose any ports!\n"; + let errorMessage = "The module " + moduleName + " doesn't expose any ports!\n"; errorMessage += "\n\nTry adding something like"; errorMessage += "port foo : Value\nport foo =\n someValue\n\nto " + moduleName + "!"; @@ -106,13 +106,13 @@ function noPortsMessage(moduleName: string): string { function runWorker(jsFilename: string, moduleName: string, workerArgs: object): Promise { return new Promise(function (resolve, reject) { - var Elm = require(jsFilename).Elm; + const Elm = require(jsFilename).Elm; if (!(moduleName in Elm)) { return reject(missingEntryModuleMessage(moduleName, Elm)); } - var worker = Elm[moduleName].init(workerArgs); + const worker = Elm[moduleName].init(workerArgs); if (Object.keys(worker.ports).length === 0) { return reject(noPortsMessage(moduleName)); diff --git a/test/compile.ts b/test/compile.ts index 9ea21be..240affe 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -5,9 +5,9 @@ var childProcess = require("child_process"); var _ = require("lodash"); var temp = require("temp"); -var expect = chai.expect; +const expect = chai.expect; -var fixturesDir = path.join(__dirname, "fixtures"); +const fixturesDir = path.join(__dirname, "fixtures"); function prependFixturesDir(filename: string) { return path.join(fixturesDir, filename); @@ -18,21 +18,21 @@ describe("#compile", function () { this.timeout(300000); it("reports errors on bad source", function (done) { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compileProcess = compiler.compile(prependFixturesDir("Bad.elm"), opts); + const compileProcess = compiler.compile(prependFixturesDir("Bad.elm"), opts); compileProcess.on("exit", function (exitCode: number) { - var desc = "Expected elm make to have exit code 1"; + const desc = "Expected elm make to have exit code 1"; expect(exitCode, desc).to.equal(1); done(); }); }); it("throws when given an unrecognized argument", function () { - var opts = { + const opts = { foo: "bar", output: "/dev/null", verbose: true, @@ -40,7 +40,7 @@ describe("#compile", function () { }; expect(function () { - var compileProcess = compiler.compile(prependFixturesDir("Parent.elm"), opts); + const compileProcess = compiler.compile(prependFixturesDir("Parent.elm"), opts); }).to.throw(); }); @@ -51,7 +51,7 @@ describe("#compileToString", function () { this.timeout(600000); it("adds runtime options as arguments", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir, runtimeOptions: ["-A128M", "-H128M", "-n8m"] @@ -63,11 +63,11 @@ describe("#compileToString", function () { }); it("reports errors on bad syntax", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compilePromise = compiler.compileToString(prependFixturesDir("Bad.elm"), opts); + const compilePromise = compiler.compileToString(prependFixturesDir("Bad.elm"), opts); return compilePromise.catch(function (err: Error) { expect(err).to.be.an('error'); @@ -78,11 +78,11 @@ describe("#compileToString", function () { }); it("reports type errors", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compilePromise = compiler.compileToString(prependFixturesDir("TypeError.elm"), opts); + const compilePromise = compiler.compileToString(prependFixturesDir("TypeError.elm"), opts); return compilePromise.catch(function (err: Error) { expect(err).to.be.an('error'); @@ -93,13 +93,13 @@ describe("#compileToString", function () { }); it("Rejects the Promise when given an unrecognized argument like `yes`", function () { - var opts = { + const opts = { foo: "bar", verbose: true, cwd: fixturesDir }; - var compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts); + const compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts); return new Promise(function (resolve, reject) { return compilePromise.then(function () { @@ -112,16 +112,16 @@ describe("#compileToString", function () { it("works when run multiple times", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var runCompile = function () { - var compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts) + const runCompile = function () { + const compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts) return compilePromise.then(function (result: string) { - var desc = "Expected elm make to return the result of the compilation"; + const desc = "Expected elm make to return the result of the compilation"; expect(result.toString(), desc).to.be.a('string'); }); }; @@ -130,14 +130,14 @@ describe("#compileToString", function () { // the compilations instead. For details, see https://github.com/elm/compiler/issues/1853. // This issue is tracked as https://github.com/rtfeldman/node-elm-compiler/issues/86. let promiseChain = Promise.resolve(); - for (var i = 0; i < 10; i++) { + for (let i = 0; i < 10; i++) { promiseChain = promiseChain.then(() => runCompile()); } return promiseChain; }); it("handles output suffix correctly", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir, output: prependFixturesDir("compiled.html"), @@ -145,7 +145,7 @@ describe("#compileToString", function () { return compiler.compileToString(prependFixturesDir("Parent.elm"), opts) .then(function (result: string) { - var desc = "Expected elm make to return the result of the compilation"; + const desc = "Expected elm make to return the result of the compilation"; expect(result.toString(), desc).to.be.a('string'); }); }); @@ -156,11 +156,11 @@ describe("#compileWorker", function () { this.timeout(300000); it("works with BasicWorker.elm", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compilePromise = compiler.compileWorker( + const compilePromise = compiler.compileWorker( prependFixturesDir(""), prependFixturesDir("BasicWorker.elm"), "BasicWorker" diff --git a/test/compileSync.ts b/test/compileSync.ts index 6be54d8..1a2c910 100644 --- a/test/compileSync.ts +++ b/test/compileSync.ts @@ -2,9 +2,9 @@ var chai = require("chai") var path = require("path"); var compiler = require(path.join(__dirname, "../src")); -var expect = chai.expect; +const expect = chai.expect; -var fixturesDir = path.join(__dirname, "fixtures"); +const fixturesDir = path.join(__dirname, "fixtures"); function prependFixturesDir(filename) { return path.join(fixturesDir, filename); @@ -15,31 +15,31 @@ describe("#compileSync", function () { this.timeout(300000); it("succeeds on SimplestMain", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts); + const compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts); - var exitCode = compileProcess.status; - var desc = "Expected elm make to have exit code 0"; + const exitCode = compileProcess.status; + const desc = "Expected elm make to have exit code 0"; expect(exitCode, desc).to.equal(0); }); it("reports errors on bad source", function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir }; - var compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts); + const compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts); - var exitCode = compileProcess.status; - var desc = "Expected elm make to have exit code 1"; + const exitCode = compileProcess.status; + const desc = "Expected elm make to have exit code 1"; expect(exitCode, desc).to.equal(1); }); it("throws when given an unrecognized argument like `yes`", function () { - var opts = { + const opts = { yes: true, output: "/dev/null", verbose: true, @@ -47,7 +47,7 @@ describe("#compileSync", function () { }; expect(function () { - var compileProcess = compiler.compileSync(prependFixturesDir("Parent.elm"), opts); + const compileProcess = compiler.compileSync(prependFixturesDir("Parent.elm"), opts); }).to.throw(); }); }); diff --git a/test/compileToStringSync.ts b/test/compileToStringSync.ts index e24237d..048a44c 100644 --- a/test/compileToStringSync.ts +++ b/test/compileToStringSync.ts @@ -12,19 +12,19 @@ function prependFixturesDir(filename) { describe("#compileToStringSync", function () { it('returns string JS output of the given elm file', function () { - var opts = { verbose: true, cwd: fixturesDir }; - var result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); + const opts = { verbose: true, cwd: fixturesDir }; + const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); expect(result).to.include("_Platform_export"); }); it('returns html output given "html" output option', function () { - var opts = { + const opts = { verbose: true, cwd: fixturesDir, output: prependFixturesDir('compiled.html'), }; - var result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); + const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); expect(result).to.include(''); expect(result).to.include('Parent'); From 339203802862bc9d0e721cb3fd195af1a3bbd9be Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Sat, 12 Sep 2020 17:56:58 +0200 Subject: [PATCH 38/45] Use ES5-style imports and exports --- package-lock.json | 6 ++++++ package.json | 1 + src/index.ts | 24 ++++++++++-------------- src/worker.ts | 2 +- test/compile.ts | 18 ++++++++++-------- test/compileSync.ts | 11 ++++++----- test/compileToStringSync.ts | 11 ++++++----- 7 files changed, 40 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ce77e8..2654d12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/chai": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz", + "integrity": "sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ==", + "dev": true + }, "@types/cross-spawn": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.0.tgz", diff --git a/package.json b/package.json index 2641d21..1d734e1 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "temp": "^0.9.0" }, "devDependencies": { + "@types/chai": "^4.2.12", "@types/cross-spawn": "^6.0.0", "@types/lodash": "^4.14.119", "@types/mocha": "^5.2.5", diff --git a/src/index.ts b/src/index.ts index a8c823a..0284cfb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,14 @@ import * as spawn from "cross-spawn"; import * as _ from "lodash" +import { SpawnOptions, ChildProcess } from "child_process"; import * as fs from "fs"; import * as path from "path"; import * as temp from "temp"; -import { findAllDependencies } from "find-elm-dependencies"; -import { SpawnOptions, ChildProcess } from "child_process"; +import compileWorkerBuilder from "./worker"; + + +export { findAllDependencies } from "find-elm-dependencies"; const elmBinaryName = "elm"; @@ -23,7 +26,7 @@ export function compile(sources: string | string[], options: Partial): } } -function compileSync(sources: string | string[], options: Partial): ChildProcess { +export function compileSync(sources: string | string[], options: Partial): ChildProcess { const optionsWithDefaults = prepareOptions(options, spawn.sync as any); const pathToElm = options.pathToElm || elmBinaryName; @@ -39,7 +42,7 @@ function compileSync(sources: string | string[], options: Partial): Chi // If you want html instead of js, use options object to set // output to a html file instead // creates a temp file and deletes it after reading -function compileToString(sources: string | string[], options: Partial): Promise { +export function compileToString(sources: string | string[], options: Partial): Promise { const suffix = getSuffix(options.output, '.js'); return new Promise(function (resolve, reject) { @@ -85,7 +88,7 @@ function compileToString(sources: string | string[], options: Partial): }); } -function compileToStringSync(sources: string | string[], options: Options): string { +export function compileToStringSync(sources: string | string[], options: Options): string { const suffix = getSuffix(options.output, '.js'); const file = temp.openSync({ suffix }); @@ -228,12 +231,5 @@ function compilerArgsFromOptions(options: Options): string[] { })); } -module.exports = { - compile: compile, - compileSync: compileSync, - compileWorker: require("./worker")(compile), - compileToString: compileToString, - compileToStringSync: compileToStringSync, - findAllDependencies: findAllDependencies, - _prepareProcessArgs: prepareProcessArgs -}; +export const compileWorker = compileWorkerBuilder(compile); +export const _prepareProcessArgs = prepareProcessArgs; \ No newline at end of file diff --git a/src/worker.ts b/src/worker.ts index 9290fd1..f23c6fd 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -37,7 +37,7 @@ const KNOWN_MODULES = type Compile = typeof compileFunc; // elmModuleName is optional, and is by default inferred based on the filename. -module.exports = function (compile: Compile) { +export default function (compile: Compile) { return function (projectRootDir: string, modulePath: string, moduleName: string, workerArgs: object) { const originalWorkingDir = process.cwd(); process.chdir(projectRootDir); diff --git a/test/compile.ts b/test/compile.ts index 240affe..653c8f4 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -1,9 +1,10 @@ -var chai = require("chai") -var path = require("path"); -var compiler = require(path.join(__dirname, "../src")); -var childProcess = require("child_process"); -var _ = require("lodash"); -var temp = require("temp"); +import * as chai from "chai"; +import * as path from "path"; +import * as childProcess from "child_process"; +import * as _ from "lodash"; +import * as temp from "temp"; + +import * as compiler from "../src" const expect = chai.expect; @@ -55,7 +56,7 @@ describe("#compileToString", function () { verbose: true, cwd: fixturesDir, runtimeOptions: ["-A128M", "-H128M", "-n8m"] - }; + } as any; return expect(compiler ._prepareProcessArgs("a.elm", opts) @@ -163,7 +164,8 @@ describe("#compileWorker", function () { const compilePromise = compiler.compileWorker( prependFixturesDir(""), prependFixturesDir("BasicWorker.elm"), - "BasicWorker" + "BasicWorker", + {} ); return compilePromise.then(function (app: any) { diff --git a/test/compileSync.ts b/test/compileSync.ts index 1a2c910..9cc5631 100644 --- a/test/compileSync.ts +++ b/test/compileSync.ts @@ -1,6 +1,7 @@ -var chai = require("chai") -var path = require("path"); -var compiler = require(path.join(__dirname, "../src")); +import * as chai from "chai"; +import * as path from "path"; + +import * as compiler from "../src"; const expect = chai.expect; @@ -19,7 +20,7 @@ describe("#compileSync", function () { verbose: true, cwd: fixturesDir }; - const compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts); + const compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts) as any; const exitCode = compileProcess.status; const desc = "Expected elm make to have exit code 0"; @@ -31,7 +32,7 @@ describe("#compileSync", function () { verbose: true, cwd: fixturesDir }; - const compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts); + const compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts) as any; const exitCode = compileProcess.status; const desc = "Expected elm make to have exit code 1"; diff --git a/test/compileToStringSync.ts b/test/compileToStringSync.ts index 048a44c..31b1d06 100644 --- a/test/compileToStringSync.ts +++ b/test/compileToStringSync.ts @@ -1,6 +1,7 @@ -var chai = require("chai"); -var path = require("path"); -var compiler = require(path.join(__dirname, "../src")); +import * as chai from "chai"; +import * as path from "path"; + +import * as compiler from "../src"; var expect = chai.expect; @@ -12,7 +13,7 @@ function prependFixturesDir(filename) { describe("#compileToStringSync", function () { it('returns string JS output of the given elm file', function () { - const opts = { verbose: true, cwd: fixturesDir }; + const opts = { verbose: true, cwd: fixturesDir } as any; const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); expect(result).to.include("_Platform_export"); @@ -23,7 +24,7 @@ describe("#compileToStringSync", function () { verbose: true, cwd: fixturesDir, output: prependFixturesDir('compiled.html'), - }; + } as any; const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); expect(result).to.include(''); From b6c0ec1d7faa5c087a99417042482e78619470cb Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Sun, 20 Sep 2020 12:04:21 +0200 Subject: [PATCH 39/45] Move pathToElm and processOpts processing into own module --- src/index.ts | 31 ++++++++++++------------------- src/options.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 src/options.ts diff --git a/src/index.ts b/src/index.ts index 0284cfb..c697fef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,35 +5,35 @@ import * as fs from "fs"; import * as path from "path"; import * as temp from "temp"; +import { processOptions, ProcessedOptions } from "./options" import compileWorkerBuilder from "./worker"; - export { findAllDependencies } from "find-elm-dependencies"; -const elmBinaryName = "elm"; - temp.track(); export function compile(sources: string | string[], options: Partial): ChildProcess { + const processedOptions = processOptions(options); + const optionsWithDefaults = prepareOptions(options, spawn); - const pathToElm = options.pathToElm || elmBinaryName; try { - return runCompiler(sources, optionsWithDefaults, pathToElm) + return runCompiler(sources, optionsWithDefaults, processedOptions) .on('error', function (err) { throw (err); }); } catch (err) { - throw compilerErrorToString(err, pathToElm); + throw new Error(compilerErrorToString(err, processedOptions.pathToElm)); } } export function compileSync(sources: string | string[], options: Partial): ChildProcess { + const processedOptions = processOptions(options); + const optionsWithDefaults = prepareOptions(options, spawn.sync as any); - const pathToElm = options.pathToElm || elmBinaryName; try { - return runCompiler(sources, optionsWithDefaults, pathToElm); + return runCompiler(sources, optionsWithDefaults, processedOptions); } catch (err) { - throw compilerErrorToString(err, pathToElm); + throw new Error(compilerErrorToString(err, processedOptions.pathToElm)); } } @@ -134,19 +134,18 @@ function prepareOptions(options: Partial, spawnFn: typeof spawn): Optio return _.defaults({ spawn: spawnFn }, options, defaultOptions); } -function runCompiler(sources: string | string[], options: Options, pathToElm: string): ChildProcess { +function runCompiler(sources: string | string[], options: Options, processedOptions: ProcessedOptions): ChildProcess { if (typeof options.spawn !== "function") { throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; } const processArgs = prepareProcessArgs(sources, options); - const processOpts = prepareProcessOpts(options); if (options.verbose) { - console.log(["Running", pathToElm].concat(processArgs).join(" ")); + console.log(["Running", processedOptions.pathToElm].concat(processArgs).join(" ")); } - return options.spawn(pathToElm, processArgs, processOpts); + return options.spawn(processedOptions.pathToElm, processArgs, processedOptions.processOpts); } function prepareProcessArgs(sources: string | string[], options: Options): string[] { @@ -164,12 +163,6 @@ function prepareSources(sources: string | string[]): string[] { return typeof sources === "string" ? [sources] : sources; } -function prepareProcessOpts(options: Options): SpawnOptions { - const env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); - return _.merge({ env: env, stdio: "inherit", cwd: options.cwd }, options.processOpts); - -} - function compilerErrorToString(err: { code?: string, message?: string }, pathToElm: string): string { if ((typeof err === "object") && (typeof err.code === "string")) { switch (err.code) { diff --git a/src/options.ts b/src/options.ts new file mode 100644 index 0000000..ac1046b --- /dev/null +++ b/src/options.ts @@ -0,0 +1,31 @@ +import { SpawnOptions } from "child_process"; +import * as _ from "lodash"; + +export function processOptions(options: Options): ProcessedOptions { + return { + pathToElm: getPathToElm(options.pathToElm), + processOpts: getProcessOpts(options.cwd, options.processOpts), + }; +} + +export type Options = { + pathToElm?: string, + cwd?: string, + processOpts?: SpawnOptions +} + +export type ProcessedOptions = { + pathToElm: string, + processOpts: SpawnOptions +}; + +const elmBinaryName = "elm"; + +function getPathToElm(pathToElm?: string): string { + return pathToElm || elmBinaryName; +} + +function getProcessOpts(cwd?: string, processOpts?: SpawnOptions): SpawnOptions { + const env = _.merge({ LANG: 'en_US.UTF-8' }, process.env); + return _.merge({ env: env, stdio: "inherit", cwd: cwd }, processOpts); +} \ No newline at end of file From 7c4f7735854b63fbfacde7e249c2d836366b22df Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Sun, 20 Sep 2020 14:46:59 +0200 Subject: [PATCH 40/45] Extract arg into options.ts, merge tests, activate strict compilation --- src/find-elm-dependencies.d.ts | 3 - src/index.ts | 157 +++++++-------------------------- src/options.ts | 75 ++++++++++++++-- src/worker.ts | 3 +- test/compile.ts | 98 ++++++++++---------- test/compileSync.ts | 54 ------------ test/compileToStringSync.ts | 34 ------- test/options.ts | 20 +++++ tsconfig.json | 7 +- 9 files changed, 174 insertions(+), 277 deletions(-) delete mode 100644 src/find-elm-dependencies.d.ts delete mode 100644 test/compileSync.ts delete mode 100644 test/compileToStringSync.ts create mode 100644 test/options.ts diff --git a/src/find-elm-dependencies.d.ts b/src/find-elm-dependencies.d.ts deleted file mode 100644 index 08c2179..0000000 --- a/src/find-elm-dependencies.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module "find-elm-dependencies" { - export function findAllDependencies(src: string): Promise -} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index c697fef..58d9c10 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,48 +1,52 @@ import * as spawn from "cross-spawn"; import * as _ from "lodash" -import { SpawnOptions, ChildProcess } from "child_process"; +import { ChildProcess, spawnSync, SpawnSyncReturns } from "child_process"; import * as fs from "fs"; import * as path from "path"; import * as temp from "temp"; -import { processOptions, ProcessedOptions } from "./options" +import { processOptions, ProcessedOptions, Options } from "./options" import compileWorkerBuilder from "./worker"; +// Let's ignore that the following dependency does not have types. +//@ts-ignore export { findAllDependencies } from "find-elm-dependencies"; -temp.track(); +export const compileWorker = compileWorkerBuilder(compile); +export { processOptions, ProcessedOptions, Options }; -export function compile(sources: string | string[], options: Partial): ChildProcess { - const processedOptions = processOptions(options); +temp.track(); - const optionsWithDefaults = prepareOptions(options, spawn); +export function compile(sources: string | string[], rawOptions: Options): ChildProcess { + const processed = processOptions(sources, rawOptions); try { - return runCompiler(sources, optionsWithDefaults, processedOptions) + logCommand(processed); + return spawn(processed.command, processed.args, processed.options) .on('error', function (err) { throw (err); }); } catch (err) { - throw new Error(compilerErrorToString(err, processedOptions.pathToElm)); + throw new Error(compilerErrorToString(err, processed.command)); } } -export function compileSync(sources: string | string[], options: Partial): ChildProcess { - const processedOptions = processOptions(options); - - const optionsWithDefaults = prepareOptions(options, spawn.sync as any); +export function compileSync(sources: string | string[], options: Options): SpawnSyncReturns { + const processed = processOptions(sources, options); try { - return runCompiler(sources, optionsWithDefaults, processedOptions); + logCommand(processed); + return spawnSync(processed.command, processed.args, processed.options) } catch (err) { - throw new Error(compilerErrorToString(err, processedOptions.pathToElm)); + throw new Error(compilerErrorToString(err, processed.command)); } } -// write compiled Elm to a string output -// returns a Promise which will contain a Buffer of the text -// If you want html instead of js, use options object to set -// output to a html file instead -// creates a temp file and deletes it after reading -export function compileToString(sources: string | string[], options: Partial): Promise { +function logCommand(processed: ProcessedOptions) { + if (processed.verbose) { + console.log(["Running", processed.command, ...processed.args].join(" ")); + } +} + +export function compileToString(sources: string | string[], options: Options): Promise { const suffix = getSuffix(options.output, '.js'); return new Promise(function (resolve, reject) { @@ -93,74 +97,18 @@ export function compileToStringSync(sources: string | string[], options: Options const file = temp.openSync({ suffix }); options.output = file.path; + compileSync(sources, options); return fs.readFileSync(file.path, { encoding: "utf8" }); } -export type Options = { - spawn: typeof spawn, - runtimeOptions?: string[], - cwd?: string, - pathToElm?: string, - help?: boolean, - output?: string, - report?: string, - debug?: boolean, - verbose?: boolean, - processOpts?: SpawnOptions, - docs?: string, - optimize?: boolean, -} - -const defaultOptions: Options = { - spawn: spawn, - runtimeOptions: undefined, - cwd: undefined, - pathToElm: undefined, - help: undefined, - output: undefined, - report: undefined, - debug: undefined, - verbose: false, - processOpts: undefined, - docs: undefined, - optimize: undefined, -}; - -const supportedOptions = _.keys(defaultOptions); - -function prepareOptions(options: Partial, spawnFn: typeof spawn): Options { - return _.defaults({ spawn: spawnFn }, options, defaultOptions); -} - -function runCompiler(sources: string | string[], options: Options, processedOptions: ProcessedOptions): ChildProcess { - if (typeof options.spawn !== "function") { - throw "options.spawn was a(n) " + (typeof options.spawn) + " instead of a function."; - } - - const processArgs = prepareProcessArgs(sources, options); - - if (options.verbose) { - console.log(["Running", processedOptions.pathToElm].concat(processArgs).join(" ")); - } - - return options.spawn(processedOptions.pathToElm, processArgs, processedOptions.processOpts); -} - -function prepareProcessArgs(sources: string | string[], options: Options): string[] { - const preparedSources = prepareSources(sources); - const compilerArgs = compilerArgsFromOptions(options); - - return ["make"].concat(preparedSources ? preparedSources.concat(compilerArgs) : compilerArgs); -} - -function prepareSources(sources: string | string[]): string[] { - if (!(sources instanceof Array || typeof sources === "string")) { - throw "compile() received neither an Array nor a String for its sources argument."; +function getSuffix(outputPath: string | undefined, defaultSuffix: string): string { + if (outputPath) { + return path.extname(outputPath) || defaultSuffix; + } else { + return defaultSuffix; } - - return typeof sources === "string" ? [sources] : sources; } function compilerErrorToString(err: { code?: string, message?: string }, pathToElm: string): string { @@ -181,48 +129,3 @@ function compilerErrorToString(err: { code?: string, message?: string }, pathToE return "Exception thrown when attempting to run Elm compiler " + JSON.stringify(pathToElm); } } - -function getSuffix(outputPath: string | undefined, defaultSuffix: string): string { - if (outputPath) { - return path.extname(outputPath) || defaultSuffix; - } else { - return defaultSuffix; - } -} - -// Converts an object of key/value pairs to an array of arguments suitable -// to be passed to child_process.spawn for elm-make. -function compilerArgsFromOptions(options: Options): string[] { - return _.flatten(_.map(options, function (value: string, opt: string): string[] { - if (value) { - switch (opt) { - case "help": return ["--help"]; - case "output": return ["--output", value]; - case "report": return ["--report", value]; - case "debug": return ["--debug"]; - case "docs": return ["--docs", value]; - case "optimize": return ["--optimize"]; - case "runtimeOptions": return _.concat(["+RTS"], value, ["-RTS"]); - default: - if (supportedOptions.indexOf(opt) === -1) { - if (opt === "yes") { - throw new Error('node-elm-compiler received the `yes` option, but that was removed in Elm 0.19. Try re-running without passing the `yes` option.'); - } else if (opt === "warn") { - throw new Error('node-elm-compiler received the `warn` option, but that was removed in Elm 0.19. Try re-running without passing the `warn` option.'); - } else if (opt === "pathToMake") { - throw new Error('node-elm-compiler received the `pathToMake` option, but that was renamed to `pathToElm` in Elm 0.19. Try re-running after renaming the parameter to `pathToElm`.'); - } else { - throw new Error('node-elm-compiler was given an unrecognized Elm compiler option: ' + opt); - } - } - - return []; - } - } else { - return []; - } - })); -} - -export const compileWorker = compileWorkerBuilder(compile); -export const _prepareProcessArgs = prepareProcessArgs; \ No newline at end of file diff --git a/src/options.ts b/src/options.ts index ac1046b..e1ed14d 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,28 +1,87 @@ import { SpawnOptions } from "child_process"; import * as _ from "lodash"; -export function processOptions(options: Options): ProcessedOptions { +export function processOptions(sources: string | string[], options: Options): ProcessedOptions { return { - pathToElm: getPathToElm(options.pathToElm), - processOpts: getProcessOpts(options.cwd, options.processOpts), + command: getPathToElm(options.pathToElm), + args: getElmArgs(sources, options), + options: getProcessOpts(options.cwd, options.processOpts), + verbose: options.verbose || false, }; } -export type Options = { +export type Options = CliOptions & ElmArgs + +interface CliOptions { pathToElm?: string, cwd?: string, processOpts?: SpawnOptions + verbose?: boolean, +} + +interface ElmArgs { + output?: string, + optimize?: boolean, + debug?: boolean, + report?: string, + docs?: string, + help?: boolean, + runtimeOptions?: string[], } export type ProcessedOptions = { - pathToElm: string, - processOpts: SpawnOptions + command: string, + args: string[], + options: SpawnOptions, + verbose: boolean }; const elmBinaryName = "elm"; -function getPathToElm(pathToElm?: string): string { - return pathToElm || elmBinaryName; +function getPathToElm(rawPath?: string): string { + return rawPath || elmBinaryName; +} + +function getElmArgs(rawSources: string | string[], rawArgs: ElmArgs): string[] { + const sources = getSources(rawSources); + const args = getArgs(rawArgs); + + return ["make", ...sources, ...args]; +} + +function getSources(rawSources: string | string[]): string[] { + // Removed exception when `sources` has unexpected type. + + return typeof rawSources === "string" ? [rawSources] : rawSources; +} + +function getArgs(rawArgs: ElmArgs): string[] { + // Removed exception when extra, i.e. unsupported, arguments were present. + + let args = []; + if (rawArgs.help) { + args.push("--help"); + } + if (rawArgs.output) { + args = args.concat(["--output", rawArgs.output]); + } + if (rawArgs.report) { + args = args.concat(["--report", rawArgs.report]); + } + if (rawArgs.debug) { + args.push("--debug"); + } + if (rawArgs.docs) { + args = args.concat(["--docs", rawArgs.docs]); + } + if (rawArgs.optimize) { + args.push("--optimize") + } + if (rawArgs.runtimeOptions) { + args = args.concat(["+RTS", ...rawArgs.runtimeOptions, "-RTS"]) + } + + return args; } function getProcessOpts(cwd?: string, processOpts?: SpawnOptions): SpawnOptions { diff --git a/src/worker.ts b/src/worker.ts index f23c6fd..57462d2 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,7 +1,8 @@ import * as temp from "temp"; import * as path from "path"; -import { compile as compileFunc, Options } from './index'; +import { compile as compileFunc } from './index'; +import { Options } from "./options" temp.track(); diff --git a/test/compile.ts b/test/compile.ts index 653c8f4..256d4aa 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -1,8 +1,6 @@ import * as chai from "chai"; import * as path from "path"; -import * as childProcess from "child_process"; import * as _ from "lodash"; -import * as temp from "temp"; import * as compiler from "../src" @@ -31,38 +29,12 @@ describe("#compile", function () { done(); }); }); - - it("throws when given an unrecognized argument", function () { - const opts = { - foo: "bar", - output: "/dev/null", - verbose: true, - cwd: fixturesDir - }; - - expect(function () { - const compileProcess = compiler.compile(prependFixturesDir("Parent.elm"), opts); - - }).to.throw(); - }); }); describe("#compileToString", function () { // Use an epic timeout because Travis on Linux can be SUPER slow. this.timeout(600000); - it("adds runtime options as arguments", function () { - const opts = { - verbose: true, - cwd: fixturesDir, - runtimeOptions: ["-A128M", "-H128M", "-n8m"] - } as any; - - return expect(compiler - ._prepareProcessArgs("a.elm", opts) - .join(" ")).to.equal("make a.elm +RTS -A128M -H128M -n8m -RTS"); - }); - it("reports errors on bad syntax", function () { const opts = { verbose: true, @@ -93,25 +65,6 @@ describe("#compileToString", function () { }); }); - it("Rejects the Promise when given an unrecognized argument like `yes`", function () { - const opts = { - foo: "bar", - verbose: true, - cwd: fixturesDir - }; - - const compilePromise = compiler.compileToString(prependFixturesDir("Parent.elm"), opts); - - return new Promise(function (resolve, reject) { - return compilePromise.then(function () { - reject("Expected the compilation promise to be rejected due to the unrecognized compiler argument."); - }).catch(function () { - resolve(); - }); - }); - }); - - it("works when run multiple times", function () { const opts = { verbose: true, @@ -152,6 +105,57 @@ describe("#compileToString", function () { }); }); +describe("#compileSync", function () { + // Use a timeout of 5 minutes because Travis on Linux can be SUPER slow. + this.timeout(300000); + + it("succeeds on SimplestMain", function () { + const opts = { + verbose: true, + cwd: fixturesDir + }; + const compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts) as any; + + const exitCode = compileProcess.status; + const desc = "Expected elm make to have exit code 0"; + expect(exitCode, desc).to.equal(0); + }); + + it("reports errors on bad source", function () { + const opts = { + verbose: true, + cwd: fixturesDir + }; + const compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts) as any; + + const exitCode = compileProcess.status; + const desc = "Expected elm make to have exit code 1"; + expect(exitCode, desc).to.equal(1); + }); +}); + +describe("#compileToStringSync", function () { + it('returns string JS output of the given elm file', function () { + const opts = { verbose: true, cwd: fixturesDir }; + const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); + + expect(result).to.include("_Platform_export"); + }); + + it('returns html output given "html" output option', function () { + const opts = { + verbose: true, + cwd: fixturesDir, + output: prependFixturesDir('compiled.html'), + }; + const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); + + expect(result).to.include(''); + expect(result).to.include('Parent'); + expect(result).to.include("_Platform_export"); + }); +}); + describe("#compileWorker", function () { // Use a timeout of 5 minutes because Travis on Linux can be SUPER slow. this.timeout(300000); diff --git a/test/compileSync.ts b/test/compileSync.ts deleted file mode 100644 index 9cc5631..0000000 --- a/test/compileSync.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as chai from "chai"; -import * as path from "path"; - -import * as compiler from "../src"; - -const expect = chai.expect; - -const fixturesDir = path.join(__dirname, "fixtures"); - -function prependFixturesDir(filename) { - return path.join(fixturesDir, filename); -} - -describe("#compileSync", function () { - // Use a timeout of 5 minutes because Travis on Linux can be SUPER slow. - this.timeout(300000); - - it("succeeds on SimplestMain", function () { - const opts = { - verbose: true, - cwd: fixturesDir - }; - const compileProcess = compiler.compileSync(prependFixturesDir("SimplestMain.elm"), opts) as any; - - const exitCode = compileProcess.status; - const desc = "Expected elm make to have exit code 0"; - expect(exitCode, desc).to.equal(0); - }); - - it("reports errors on bad source", function () { - const opts = { - verbose: true, - cwd: fixturesDir - }; - const compileProcess = compiler.compileSync(prependFixturesDir("Bad.elm"), opts) as any; - - const exitCode = compileProcess.status; - const desc = "Expected elm make to have exit code 1"; - expect(exitCode, desc).to.equal(1); - }); - - it("throws when given an unrecognized argument like `yes`", function () { - const opts = { - yes: true, - output: "/dev/null", - verbose: true, - cwd: fixturesDir - }; - - expect(function () { - const compileProcess = compiler.compileSync(prependFixturesDir("Parent.elm"), opts); - }).to.throw(); - }); -}); diff --git a/test/compileToStringSync.ts b/test/compileToStringSync.ts deleted file mode 100644 index 31b1d06..0000000 --- a/test/compileToStringSync.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as chai from "chai"; -import * as path from "path"; - -import * as compiler from "../src"; - -var expect = chai.expect; - -var fixturesDir = path.join(__dirname, "fixtures"); - -function prependFixturesDir(filename) { - return path.join(fixturesDir, filename); -} - -describe("#compileToStringSync", function () { - it('returns string JS output of the given elm file', function () { - const opts = { verbose: true, cwd: fixturesDir } as any; - const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); - - expect(result).to.include("_Platform_export"); - }); - - it('returns html output given "html" output option', function () { - const opts = { - verbose: true, - cwd: fixturesDir, - output: prependFixturesDir('compiled.html'), - } as any; - const result = compiler.compileToStringSync(prependFixturesDir("Parent.elm"), opts); - - expect(result).to.include(''); - expect(result).to.include('Parent'); - expect(result).to.include("_Platform_export"); - }); -}); diff --git a/test/options.ts b/test/options.ts new file mode 100644 index 0000000..62ad889 --- /dev/null +++ b/test/options.ts @@ -0,0 +1,20 @@ +import * as chai from "chai"; + +import { processOptions, Options } from "../src"; + +const expect = chai.expect; + +describe("#options", function () { + it("adds runtime options as arguments", function () { + const opts: Options = { + verbose: true, + runtimeOptions: ["-A128M", "-H128M", "-n8m"] + }; + const source = "Nonexistant.elm"; + + const processed = processOptions(source, opts); + const argsResult = processed.args.join(" "); + + return expect(argsResult).to.equal(`make ${source} +RTS -A128M -H128M -n8m -RTS`); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 64c5ff1..54ab6d6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,14 @@ { "compilerOptions": { + "strict": true, "outDir": "./dist", "allowJs": true, "target": "es5", "lib": [ - "es2015" - ] + "es2015", + ], }, "include": [ - "./src/**/*" + "./src/**/*", ] } \ No newline at end of file From 42936e990299f7b76835e3152f7c9eeecaf50fdb Mon Sep 17 00:00:00 2001 From: Y0hy0h Date: Sun, 20 Sep 2020 16:59:07 +0200 Subject: [PATCH 41/45] Use cross-spawn instead of child_process --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 58d9c10..2edab28 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import * as spawn from "cross-spawn"; import * as _ from "lodash" -import { ChildProcess, spawnSync, SpawnSyncReturns } from "child_process"; +import { ChildProcess, SpawnSyncReturns } from "child_process"; import * as fs from "fs"; import * as path from "path"; import * as temp from "temp"; @@ -34,7 +34,7 @@ export function compileSync(sources: string | string[], options: Options): Spawn try { logCommand(processed); - return spawnSync(processed.command, processed.args, processed.options) + return spawn.sync(processed.command, processed.args, processed.options) } catch (err) { throw new Error(compilerErrorToString(err, processed.command)); } From 1ebac4485eb5e57bcc860699fa073e20800011de Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Sun, 27 Sep 2020 16:17:40 +0200 Subject: [PATCH 42/45] Document --- src/index.ts | 2 ++ src/options.ts | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/index.ts b/src/index.ts index 2edab28..c0a0ab2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,6 +15,8 @@ export { findAllDependencies } from "find-elm-dependencies"; export const compileWorker = compileWorkerBuilder(compile); export { processOptions, ProcessedOptions, Options }; +// Track temp files, so that they will be automatically deleted on process exit. +// See https://github.com/bruce/node-temp#want-cleanup-make-sure-you-ask-for-it temp.track(); export function compile(sources: string | string[], rawOptions: Options): ChildProcess { diff --git a/src/options.ts b/src/options.ts index e1ed14d..878cd10 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,6 +1,12 @@ import { SpawnOptions } from "child_process"; import * as _ from "lodash"; +/** + * Transforms our CLI options into a form suitable for spawning a process. + * @param sources Path(s) to the files to compile. + * @param options CLI input options. + * @returns Options suitable for spawning a process. + */ export function processOptions(sources: string | string[], options: Options): ProcessedOptions { return { command: getPathToElm(options.pathToElm), @@ -10,8 +16,16 @@ export function processOptions(sources: string | string[], options: Options): Pr }; } +/** + * All options our CLI accepts. + * + * For backwards compatibility, we merge the CLI options and Elm compiler arguments. + */ export type Options = CliOptions & ElmArgs +/** + * Our CLI-specific options. + */ interface CliOptions { pathToElm?: string, cwd?: string, @@ -19,6 +33,9 @@ interface CliOptions { verbose?: boolean, } +/** + * Arguments for the elm compiler. + */ interface ElmArgs { output?: string, optimize?: boolean, @@ -29,6 +46,9 @@ interface ElmArgs { runtimeOptions?: string[], } +/** + * Arguments for spawning the process. + */ export type ProcessedOptions = { command: string, args: string[], From 80c9f191bf5d7d8ac332ef6c01b7903836b9443c Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Sun, 27 Sep 2020 16:17:49 +0200 Subject: [PATCH 43/45] Rearrange worker.ts --- src/worker.ts | 116 +++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/src/worker.ts b/src/worker.ts index 57462d2..40a7f2a 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -8,33 +8,6 @@ temp.track(); const jsEmitterFilename = "emitter.js"; -const KNOWN_MODULES = - [ - "fullscreen", - "embed", - "worker", - "Basics", - "Maybe", - "List", - "Array", - "Char", - "Color", - "Transform2D", - "Text", - "Graphics", - "Debug", - "Result", - "Task", - "Signal", - "String", - "Dict", - "Json", - "Regex", - "VirtualDom", - "Html", - "Css" - ]; - type Compile = typeof compileFunc; // elmModuleName is optional, and is by default inferred based on the filename. @@ -73,14 +46,72 @@ function createTmpDir(): Promise { }); } +function compileEmitter(compile: Compile, src: string, options: Partial): Promise { + return new Promise(function (resolve, reject) { + compile(src, options) + .on("close", function (exitCode) { + if (exitCode === 0) { + resolve(exitCode); + } else { + reject("Errored with exit code " + exitCode); + } + }) + }); +} + type ElmWorker = object; +function runWorker(jsFilename: string, moduleName: string, workerArgs: object): Promise { + return new Promise(function (resolve, reject) { + const Elm = require(jsFilename).Elm; + + if (!(moduleName in Elm)) { + return reject(missingEntryModuleMessage(moduleName, Elm)); + } + + const worker = Elm[moduleName].init(workerArgs); + + if (Object.keys(worker.ports).length === 0) { + return reject(noPortsMessage(moduleName)); + } + + return resolve(worker); + }); +} + function suggestModulesNames(Elm: ElmWorker): string[] { return Object.keys(Elm).filter(function (key) { return KNOWN_MODULES.indexOf(key) === -1; }) } +const KNOWN_MODULES = + [ + "fullscreen", + "embed", + "worker", + "Basics", + "Maybe", + "List", + "Array", + "Char", + "Color", + "Transform2D", + "Text", + "Graphics", + "Debug", + "Result", + "Task", + "Signal", + "String", + "Dict", + "Json", + "Regex", + "VirtualDom", + "Html", + "Css" + ]; + function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { let errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; const suggestions = suggestModulesNames(Elm); @@ -104,34 +135,3 @@ function noPortsMessage(moduleName: string): string { return errorMessage.trim(); } - -function runWorker(jsFilename: string, moduleName: string, workerArgs: object): Promise { - return new Promise(function (resolve, reject) { - const Elm = require(jsFilename).Elm; - - if (!(moduleName in Elm)) { - return reject(missingEntryModuleMessage(moduleName, Elm)); - } - - const worker = Elm[moduleName].init(workerArgs); - - if (Object.keys(worker.ports).length === 0) { - return reject(noPortsMessage(moduleName)); - } - - return resolve(worker); - }); -} - -function compileEmitter(compile: Compile, src: string, options: Partial): Promise { - return new Promise(function (resolve, reject) { - compile(src, options) - .on("close", function (exitCode) { - if (exitCode === 0) { - resolve(exitCode); - } else { - reject("Errored with exit code " + exitCode); - } - }) - }); -} From 4e54b817a3724de12869526194166135f3c3b959 Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Sat, 10 Oct 2020 13:47:17 +0200 Subject: [PATCH 44/45] Update TypeScript dependency --- package-lock.json | 31 ++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2654d12..eae107c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -252,12 +252,20 @@ "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } } }, "mocha": { @@ -292,6 +300,15 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } } } }, @@ -429,9 +446,9 @@ "dev": true }, "typescript": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", - "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", + "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", "dev": true }, "which": { diff --git a/package.json b/package.json index 1d734e1..7c7e97c 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,6 @@ "glob": "7.1.1", "mocha": "5.1.1", "ts-node": "^7.0.1", - "typescript": "^3.2.2" + "typescript": "^4.0.3" } } From d88db259b5cec7cd3aa17b1717f496e5581f0930 Mon Sep 17 00:00:00 2001 From: Johannes Maas Date: Sat, 10 Oct 2020 13:47:33 +0200 Subject: [PATCH 45/45] Refactor worker, add test for passing flags --- src/index.ts | 3 +- src/worker.ts | 113 ++++++++++++++++++----------------- test/compile.ts | 20 ++++++- test/fixtures/EchoWorker.elm | 15 +++++ 4 files changed, 94 insertions(+), 57 deletions(-) create mode 100644 test/fixtures/EchoWorker.elm diff --git a/src/index.ts b/src/index.ts index c0a0ab2..00f8412 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,13 +6,12 @@ import * as path from "path"; import * as temp from "temp"; import { processOptions, ProcessedOptions, Options } from "./options" -import compileWorkerBuilder from "./worker"; +export { compileWorker } from "./worker"; // Let's ignore that the following dependency does not have types. //@ts-ignore export { findAllDependencies } from "find-elm-dependencies"; -export const compileWorker = compileWorkerBuilder(compile); export { processOptions, ProcessedOptions, Options }; // Track temp files, so that they will be automatically deleted on process exit. diff --git a/src/worker.ts b/src/worker.ts index 40a7f2a..5d08f89 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,38 +1,40 @@ import * as temp from "temp"; import * as path from "path"; -import { compile as compileFunc } from './index'; +import { compile } from './index'; import { Options } from "./options" +// Track temp files, so that they will be automatically deleted on process exit. +// See https://github.com/bruce/node-temp#want-cleanup-make-sure-you-ask-for-it temp.track(); -const jsEmitterFilename = "emitter.js"; - -type Compile = typeof compileFunc; - -// elmModuleName is optional, and is by default inferred based on the filename. -export default function (compile: Compile) { - return function (projectRootDir: string, modulePath: string, moduleName: string, workerArgs: object) { - const originalWorkingDir = process.cwd(); - process.chdir(projectRootDir); +type Path = string; - return createTmpDir() - .then(function (tmpDirPath: string) { - const dest = path.join(tmpDirPath, jsEmitterFilename); +const jsEmitterFilename = "emitter.js"; - return compileEmitter(compile, modulePath, { output: dest }) - .then(function () { return runWorker(dest, moduleName, workerArgs) }); - }) - .then(function (worker) { - process.chdir(originalWorkingDir); - return worker; - }) - .catch(function (err) { - process.chdir(originalWorkingDir); - throw Error(err); - }); - }; -}; +export async function compileWorker( + projectRootDir: Path, + modulePath: Path, + moduleName: string, + workerArgs?: { flags: any }, +): Promise { + const originalWorkingDir = process.cwd(); + process.chdir(projectRootDir); + + try { + const tmpDirPath = await createTmpDir(); + const dest = path.join(tmpDirPath, jsEmitterFilename); + + await compileAsync(modulePath, { output: dest }); + const worker = await runWorker(dest, moduleName, workerArgs?.flags); + + return worker; + } catch (err) { + throw Error(err); + } finally { + process.chdir(originalWorkingDir); + } +} function createTmpDir(): Promise { return new Promise(function (resolve, reject) { @@ -46,7 +48,7 @@ function createTmpDir(): Promise { }); } -function compileEmitter(compile: Compile, src: string, options: Partial): Promise { +function compileAsync(src: string, options: Partial): Promise { return new Promise(function (resolve, reject) { compile(src, options) .on("close", function (exitCode) { @@ -61,22 +63,40 @@ function compileEmitter(compile: Compile, src: string, options: Partial type ElmWorker = object; -function runWorker(jsFilename: string, moduleName: string, workerArgs: object): Promise { - return new Promise(function (resolve, reject) { - const Elm = require(jsFilename).Elm; +async function runWorker( + jsFilename: string, + moduleName: string, + flags?: any, +): Promise { + const elmFile = await import(jsFilename); + const Elm = elmFile.Elm; - if (!(moduleName in Elm)) { - return reject(missingEntryModuleMessage(moduleName, Elm)); - } + if (!(moduleName in Elm)) { + throw missingEntryModuleMessage(moduleName, Elm); + } - const worker = Elm[moduleName].init(workerArgs); + const worker = Elm[moduleName].init({ flags }); - if (Object.keys(worker.ports).length === 0) { - return reject(noPortsMessage(moduleName)); - } + if (Object.keys(worker.ports).length === 0) { + throw noPortsMessage(moduleName); + } - return resolve(worker); - }); + return worker; +} + +function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { + let errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; + const suggestions = suggestModulesNames(Elm); + + if (suggestions.length > 1) { + errorMessage += "\nMaybe you meant one of these: " + suggestions.join(","); + } else if (suggestions.length === 1) { + errorMessage += "\nMaybe you meant: " + suggestions; + } + + errorMessage += "\nYou can pass me a different module to use with --module="; + + return errorMessage; } function suggestModulesNames(Elm: ElmWorker): string[] { @@ -112,21 +132,6 @@ const KNOWN_MODULES = "Css" ]; -function missingEntryModuleMessage(moduleName: string, Elm: ElmWorker): string { - let errorMessage = "I couldn't find the entry module " + moduleName + ".\n"; - const suggestions = suggestModulesNames(Elm); - - if (suggestions.length > 1) { - errorMessage += "\nMaybe you meant one of these: " + suggestions.join(","); - } else if (suggestions.length === 1) { - errorMessage += "\nMaybe you meant: " + suggestions; - } - - errorMessage += "\nYou can pass me a different module to use with --module="; - - return errorMessage; -} - function noPortsMessage(moduleName: string): string { let errorMessage = "The module " + moduleName + " doesn't expose any ports!\n"; diff --git a/test/compile.ts b/test/compile.ts index 2248e64..022d0fb 100644 --- a/test/compile.ts +++ b/test/compile.ts @@ -169,7 +169,6 @@ describe("#compileWorker", function () { prependFixturesDir(""), prependFixturesDir("BasicWorker.elm"), "BasicWorker", - {} ); return compilePromise.then(function (app: any) { @@ -178,4 +177,23 @@ describe("#compileWorker", function () { }); }) }); + + it("accepts arguments", function () { + const opts = { + verbose: true, + cwd: fixturesDir + }; + const compilePromise = compiler.compileWorker( + prependFixturesDir(""), + prependFixturesDir("EchoWorker.elm"), + "EchoWorker", + { flags: "echo" } + ); + + return compilePromise.then(function (app: any) { + app.ports.reportFromWorker.subscribe(function (str: string) { + expect(str).to.equal("You said: echo"); + }); + }) + }); }); diff --git a/test/fixtures/EchoWorker.elm b/test/fixtures/EchoWorker.elm new file mode 100644 index 0000000..d8fbea7 --- /dev/null +++ b/test/fixtures/EchoWorker.elm @@ -0,0 +1,15 @@ +port module EchoWorker exposing (..) + +import Platform + + +main : Program String String msg +main = + Platform.worker + { init = \msg -> ( "", reportFromWorker ("You said: " ++ msg) ) + , update = \_ _ -> ( "", Cmd.none ) + , subscriptions = \_ -> Sub.none + } + + +port reportFromWorker : String -> Cmd a