oc-template-elm-compiler 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,58 @@
1
- # oc-template-elm-compiler - Compiler module
1
+ # WORK IN PROGRESS [NOT READY FOR PRODUCTION]
2
2
 
3
- OC template to compile components of type `oc-template-elm`
3
+ # oc-template-elm
4
+
5
+ [Elm](https://elm-lang.org) template for the [OpenComponents](https://github.com/opentable/oc) template system
6
+
7
+ ---
8
+
9
+ ## Ports
10
+
11
+ Your Elm component will have access to two ports by default, if you want to use them.
12
+
13
+ ```elm
14
+ -- To do a oc.getData request passing your properties
15
+ port getData : E.Value -> Cmd msg
16
+
17
+ -- A listener after the oc.getData request finishes. It will be up to you to decode errors you may get.
18
+ port dataReceiver : (E.Value -> msg) -> Sub msg
19
+ ```
20
+
21
+ ## Custom ports
22
+
23
+ So what can you do if you want to have extra custom ports? (Maybe to listen to OC events). In that case you can point your entry as a javascript file.
24
+
25
+ ```json
26
+ {
27
+ "oc": {
28
+ "files": {
29
+ "data": "src/server.ts",
30
+ "template": {
31
+ "src": "src/index.js",
32
+ "type": "oc-template-elm"
33
+ }
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ Then, on that file, just `export default` an object that will take two parameters: `program` with your Elm main program and `js` with a function that takes the elm app as a parameter where you can set whatever you want
40
+
41
+ ```js
42
+ /// src/index.js
43
+ import { Elm } from "./Main.elm";
44
+
45
+ export default {
46
+ js: (app) => {
47
+ window.oc.events.on("myEvent", (event) => {
48
+ // Elm will get event data on that port!
49
+ app.ports.myPortReceiver.send(event.data);
50
+ });
51
+ },
52
+ program: Elm.Main,
53
+ };
54
+ ```
55
+
56
+ ## Missing features
57
+
58
+ - Server side rendering
@@ -10,27 +10,14 @@ const oc_template_elm_1 = require("oc-template-elm");
10
10
  const oc_vite_compiler_1 = require("oc-vite-compiler");
11
11
  const vite_plugin_elm_1 = __importDefault(require("vite-plugin-elm"));
12
12
  const elmOCProviderTemplate_1 = __importDefault(require("./elmOCProviderTemplate"));
13
- const htmlTemplate_1 = __importDefault(require("./htmlTemplate"));
14
13
  exports.compile = (0, oc_generic_template_compiler_1.createCompile)({
15
14
  compileView: (options, cb) => (0, oc_vite_compiler_1.viteView)({
16
15
  ...options,
17
16
  plugins: [(0, vite_plugin_elm_1.default)()],
18
- viewWrapper: ({ viewPath }) => (0, elmOCProviderTemplate_1.default)({ viewPath, jsPath: undefined }),
19
- htmlTemplate: htmlTemplate_1.default,
17
+ viewWrapper: elmOCProviderTemplate_1.default,
20
18
  externals: (0, oc_template_elm_1.getInfo)().externals
21
19
  }, cb),
22
20
  compileServer: oc_vite_compiler_1.viteServer,
23
21
  compileStatics: oc_statics_compiler_1.default,
24
22
  getInfo: oc_template_elm_1.getInfo
25
23
  });
26
- // OPTIONS
27
- // =======
28
- // componentPath
29
- // componentPackage,
30
- // logger,
31
- // minify
32
- // ocPackage
33
- // publishPath
34
- // verbose,
35
- // watch,
36
- // production
@@ -1,4 +1,3 @@
1
- export default function elmOCProviderTemplate({ jsPath, viewPath }: {
2
- jsPath?: string;
1
+ export default function elmOCProviderTemplate({ viewPath }: {
3
2
  viewPath: string;
4
3
  }): string;
@@ -2,10 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const extractName = (path) => path.match(/(\w+)\.elm$/)[1];
4
4
  const removeJsExtension = (path) => path.replace(/\.(t|j)s?$/, '');
5
- function elmOCProviderTemplate({ jsPath, viewPath }) {
5
+ function elmEntry({ viewPath }) {
6
6
  return `
7
7
  import { Elm } from '${viewPath}';
8
- ${jsPath ? `import jsApp from '${removeJsExtension(jsPath)}'` : ''}
9
8
 
10
9
  function getData(providerProps, parameters, cb) {
11
10
  return window.oc.getData({
@@ -42,7 +41,56 @@ function elmOCProviderTemplate({ jsPath, viewPath }) {
42
41
  });
43
42
  }
44
43
 
45
- ${jsPath ? 'jsApp(app);' : ''}
44
+ return app;
45
+ }
46
+
47
+ export default renderer;
48
+ `;
49
+ }
50
+ function jsEntry({ viewPath }) {
51
+ return `
52
+ import config from '${removeJsExtension(viewPath)}';
53
+ const { js, program } = config;
54
+
55
+ if (!program) throw new Error('Missing program in config');
56
+ if (!program.init) throw new Error('Program does not look like an elm instance (missing init)');
57
+
58
+ function getData(providerProps, parameters, cb) {
59
+ return window.oc.getData({
60
+ name: providerProps._componentName,
61
+ version: providerProps._componentVersion,
62
+ baseUrl: providerProps._baseUrl,
63
+ parameters
64
+ }, (err, data) => {
65
+ if (err) {
66
+ return cb(err);
67
+ }
68
+ const { _staticPath, _baseUrl, _componentName, _componentVersion, ...rest } = data.component.props;
69
+ cb(null, rest);
70
+ });
71
+ }
72
+
73
+ function renderer(model, node) {
74
+ const { _baseUrl, _componentName, _componentVersion, _staticPath, ...props } = model;
75
+ const app = program.init({
76
+ node,
77
+ flags: props
78
+ })
79
+
80
+ if (app.ports && app.ports.getData) {
81
+ app.ports.getData.subscribe(parameters => {
82
+ getData({ _baseUrl, _componentName, _componentVersion }, parameters, (err, data) => {
83
+ if (err && process.env.NODE_ENV !== 'production') {
84
+ console.error('Error requesting OC Data', err);
85
+ }
86
+ if (app.ports.dataReceiver) {
87
+ app.ports.dataReceiver.send(err || data);
88
+ }
89
+ });
90
+ });
91
+ }
92
+
93
+ js && js(app);
46
94
 
47
95
  return app;
48
96
  }
@@ -50,4 +98,10 @@ function elmOCProviderTemplate({ jsPath, viewPath }) {
50
98
  export default renderer;
51
99
  `;
52
100
  }
101
+ function elmOCProviderTemplate({ viewPath }) {
102
+ if (viewPath.endsWith('.elm')) {
103
+ return elmEntry({ viewPath });
104
+ }
105
+ return jsEntry({ viewPath });
106
+ }
53
107
  exports.default = elmOCProviderTemplate;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oc-template-elm-compiler",
3
- "version": "0.1.0",
4
- "description": "",
3
+ "version": "0.2.0",
4
+ "description": "Compiler for the Elm OC template",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
@@ -30,13 +30,12 @@
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
32
  "chalk": "^3.0.0",
33
- "cssesc": "^3.0.0",
34
33
  "elm": "^0.19.1-6",
35
34
  "oc-generic-template-compiler": "2.0.4",
36
35
  "oc-statics-compiler": "2.0.10",
37
- "oc-template-elm": "0.1.0",
36
+ "oc-template-elm": "^0.1.0",
38
37
  "oc-view-wrapper": "1.0.3",
39
- "oc-vite-compiler": "^3.0.0",
38
+ "oc-vite-compiler": "^3.1.1",
40
39
  "resolve": "1.18.1",
41
40
  "vite-plugin-elm": "^2.8.0"
42
41
  },
@@ -1,7 +0,0 @@
1
- declare const async: any;
2
- declare const fs: any;
3
- declare const hashBuilder: any;
4
- declare const MemoryFS: any;
5
- declare const path: any;
6
- declare const compiler: any, webpackConfigurator: any;
7
- declare const higherOrderServerTemplate: any;
@@ -1,73 +0,0 @@
1
- 'use strict';
2
- const async = require('async');
3
- const fs = require('fs-extra');
4
- const hashBuilder = require('oc-hash-builder');
5
- const MemoryFS = require('memory-fs');
6
- const path = require('path');
7
- const { compiler, configurator: { server: webpackConfigurator } } = require('./to-abstract-base-template-utils/oc-webpack');
8
- const higherOrderServerTemplate = require('./higherOrderServerTemplate');
9
- module.exports = (options, callback) => {
10
- const componentPath = options.componentPath;
11
- const serverFileName = options.componentPackage.oc.files.data;
12
- let serverPath = path.join(options.componentPath, serverFileName);
13
- if (process.platform === 'win32') {
14
- serverPath = serverPath.split('\\').join('\\\\');
15
- }
16
- const publishFileName = options.publishFileName || 'server.js';
17
- const publishPath = options.publishPath;
18
- const stats = options.verbose ? 'verbose' : 'errors-only';
19
- const dependencies = options.componentPackage.dependencies || {};
20
- const componentName = options.componentPackage.name;
21
- const componentVersion = options.componentPackage.version;
22
- const production = options.production;
23
- const higherOrderServerContent = higherOrderServerTemplate({
24
- serverPath,
25
- componentName,
26
- componentVersion,
27
- bundleHashKey: options.compiledViewInfo.bundle.hashKey
28
- });
29
- const tempFolder = path.join(serverPath, '../_package/temp');
30
- const higherOrderServerPath = path.join(tempFolder, '__oc_higherOrderServer.ts');
31
- const config = webpackConfigurator({
32
- componentPath,
33
- serverPath: higherOrderServerPath,
34
- publishFileName,
35
- dependencies,
36
- stats,
37
- production
38
- });
39
- async.waterfall([
40
- (next) => fs.outputFile(higherOrderServerPath, higherOrderServerContent, next),
41
- (next) => {
42
- return compiler(config, next);
43
- },
44
- (data, next) => {
45
- const basePath = path.join(tempFolder, 'build');
46
- const memory = new MemoryFS(data);
47
- const getCompiled = (fileName) => memory.readFileSync(`${basePath}/${fileName}`, 'UTF8');
48
- return fs.ensureDir(publishPath, (err) => {
49
- if (err)
50
- return next(err);
51
- const result = { 'server.js': getCompiled(config.output.filename) };
52
- if (!production) {
53
- try {
54
- result['server.js.map'] = getCompiled(`${config.output.filename}.map`);
55
- }
56
- catch (e) {
57
- // skip sourcemap if it doesn't exist
58
- }
59
- }
60
- next(null, result);
61
- });
62
- },
63
- (compiledFiles, next) => {
64
- return async.eachOf(compiledFiles, (fileContent, fileName, next) => fs.writeFile(path.join(publishPath, fileName), fileContent, next), (err) => next(err, err
65
- ? null
66
- : {
67
- type: 'node.js',
68
- hashKey: hashBuilder.fromString(compiledFiles[publishFileName]),
69
- src: publishFileName
70
- }));
71
- }
72
- ], (err, data) => fs.remove(tempFolder, (_err2) => callback(err, data)));
73
- };
@@ -1,12 +0,0 @@
1
- declare const async: any;
2
- declare const fs: any;
3
- declare const hashBuilder: any;
4
- declare const MemoryFS: any;
5
- declare const ocViewWrapper: any;
6
- declare const path: any;
7
- declare const strings: any;
8
- declare const elmComponentWrapper: (hash: any, content: any, nameSpace: any) => string;
9
- declare const compiler: any, webpackConfigurator: any;
10
- declare const fontFamilyUnicodeParser: any;
11
- declare const elmOCProviderTemplate: any;
12
- declare const viewTemplate: any;
@@ -1,102 +0,0 @@
1
- 'use strict';
2
- const async = require('async');
3
- const fs = require('fs-extra');
4
- const hashBuilder = require('oc-hash-builder');
5
- const MemoryFS = require('memory-fs');
6
- const ocViewWrapper = require('oc-view-wrapper');
7
- const path = require('path');
8
- const strings = require('oc-templates-messages');
9
- const elmComponentWrapper = (hash, content, nameSpace) => {
10
- nameSpace = nameSpace || 'oc';
11
- return `var ${nameSpace}=${nameSpace}||{};${nameSpace}.elmComponents=${nameSpace}.elmComponents||{};${nameSpace}.elmComponents['${hash}']=${nameSpace}.elmComponents['${hash}']||(function(){var ${content}
12
- ; return module.default}())`;
13
- };
14
- const { compiler, configurator: { client: webpackConfigurator } } = require('./to-abstract-base-template-utils/oc-webpack');
15
- const fontFamilyUnicodeParser = require('./to-abstract-base-template-utils/font-family-unicode-parser');
16
- const elmOCProviderTemplate = require('./elmOCProviderTemplate');
17
- const viewTemplate = require('./viewTemplate');
18
- module.exports = (options, callback) => {
19
- const viewFileName = options.componentPackage.oc.files.template.src;
20
- const jsFileName = options.componentPackage.oc.files.template.js;
21
- const componentPath = options.componentPath;
22
- let viewPath = path.join(options.componentPath, viewFileName);
23
- let jsPath = jsFileName && path.join(options.componentPath, viewFileName);
24
- if (process.platform === 'win32') {
25
- viewPath = viewPath.split('\\').join('\\\\');
26
- jsPath = jsPath && jsPath.split('\\').join('\\\\');
27
- }
28
- const publishPath = options.publishPath;
29
- const tempPath = path.join(publishPath, 'temp');
30
- const publishFileName = options.publishFileName || 'template.js';
31
- const componentPackage = options.componentPackage;
32
- const production = options.production;
33
- const elmOCProviderContent = elmOCProviderTemplate({ viewPath, jsPath });
34
- const elmOCProviderName = 'elmOCProvider.js';
35
- const elmOCProviderPath = path.join(tempPath, elmOCProviderName);
36
- const compile = (options, cb) => {
37
- const config = webpackConfigurator({
38
- componentPath,
39
- viewPath: options.viewPath,
40
- publishFileName,
41
- production,
42
- buildIncludes: componentPackage.oc.files.template.buildIncludes || []
43
- });
44
- compiler(config, (err, data) => {
45
- if (err) {
46
- return cb(err);
47
- }
48
- const memoryFs = new MemoryFS(data);
49
- const bundle = memoryFs.readFileSync(`/build/${config.output.filename}`, 'UTF8');
50
- const bundleHash = hashBuilder.fromString(bundle);
51
- const bundleName = 'elm-component';
52
- const bundlePath = path.join(publishPath, `${bundleName}.js`);
53
- const wrappedBundle = elmComponentWrapper(bundleHash, bundle);
54
- fs.outputFileSync(bundlePath, wrappedBundle);
55
- let css = null;
56
- if (data.build['main.css']) {
57
- // This is an awesome hack by KimTaro that will blow your mind.
58
- // Remove it once this get merged: https://github.com/webpack-contrib/css-loader/pull/523
59
- css = fontFamilyUnicodeParser(memoryFs.readFileSync(`/build/main.css`, 'UTF8'));
60
- const cssPath = path.join(publishPath, `styles.css`);
61
- // We convert single quotes to double quotes in order to
62
- // support the viewTemplate's string interpolation
63
- fs.outputFileSync(cssPath, css.replace(/'/g, '"'));
64
- }
65
- const elmRoot = `oc-elmRoot-${componentPackage.name}`;
66
- const templateString = viewTemplate({
67
- elmRoot,
68
- css,
69
- bundleHash,
70
- bundleName
71
- });
72
- const templateStringCompressed = production
73
- ? templateString.replace(/\s+/g, ' ')
74
- : templateString;
75
- const hash = hashBuilder.fromString(templateStringCompressed);
76
- const view = ocViewWrapper(hash, templateStringCompressed);
77
- return cb(null, {
78
- template: { view, hash },
79
- bundle: { hash: bundleHash }
80
- });
81
- });
82
- };
83
- async.waterfall([
84
- (next) => fs.outputFile(elmOCProviderPath, elmOCProviderContent, next),
85
- (next) => compile({ viewPath: elmOCProviderPath }, next),
86
- (compiled, next) => fs.remove(elmOCProviderPath, (err) => next(err, compiled)),
87
- (compiled, next) => fs.ensureDir(publishPath, (err) => next(err, compiled)),
88
- (compiled, next) => fs.writeFile(path.join(publishPath, publishFileName), compiled.template.view, (err) => next(err, compiled))
89
- ], (err, compiled) => {
90
- if (err) {
91
- return callback(strings.errors.compilationFailed(viewFileName, err));
92
- }
93
- callback(null, {
94
- template: {
95
- type: options.componentPackage.oc.files.template.type,
96
- hashKey: compiled.template.hash,
97
- src: publishFileName
98
- },
99
- bundle: { hashKey: compiled.bundle.hash }
100
- });
101
- });
102
- };
@@ -1,7 +0,0 @@
1
- declare const removeTsExtension: (path: any) => any;
2
- declare const higherOrderServerTemplate: ({ serverPath, bundleHashKey, componentName, componentVersion }: {
3
- serverPath: any;
4
- bundleHashKey: any;
5
- componentName: any;
6
- componentVersion: any;
7
- }) => string;
@@ -1,29 +0,0 @@
1
- "use strict";
2
- const removeTsExtension = (path) => path.replace(/\.tsx?$/, '');
3
- const higherOrderServerTemplate = ({ serverPath, bundleHashKey, componentName, componentVersion }) => `
4
- import { data as dataProvider } from '${removeTsExtension(serverPath)}';
5
-
6
- export const data = (context : any, callback : (error: any, data?: any) => void) => {
7
- dataProvider(context, (error: any, model: any) => {
8
- if (error) {
9
- return callback(error);
10
- }
11
- const flags = Object.assign({}, model, {
12
- _staticPath: context.staticPath,
13
- _baseUrl: context.baseUrl,
14
- _componentName: "${componentName}",
15
- _componentVersion: "${componentVersion}"
16
- });
17
- const srcPathHasProtocol = context.staticPath.indexOf("http") === 0;
18
- const srcPath = srcPathHasProtocol ? context.staticPath : ("https:" + context.staticPath);
19
- return callback(null, Object.assign({}, {
20
- elmComponent: {
21
- key: "${bundleHashKey}",
22
- src: srcPath + "elm-component.js",
23
- flags
24
- }
25
- }));
26
- });
27
- }
28
- `;
29
- module.exports = higherOrderServerTemplate;
@@ -1,6 +0,0 @@
1
- export default function viewTemplate({ templateId, css, hash, bundle }: {
2
- templateId: string;
3
- css: string;
4
- hash: string;
5
- bundle: string;
6
- }): string;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const cssesc_1 = __importDefault(require("cssesc"));
7
- function viewTemplate({ templateId, css, hash, bundle }) {
8
- return `function(model){
9
- oc.elmComponents = oc.elmComponents || {};
10
- oc.elmComponents['${hash}'] = oc.elmComponents['${hash}'] || (${bundle});
11
- if (!model) return;
12
- var modelHTML = model.__html ? model.__html : '';
13
- var staticPath = model.component.props._staticPath;
14
- var props = JSON.stringify(model.component.props);
15
- window.oc = window.oc || {};
16
- window.oc.__elmTemplate = window.oc.__elmTemplate || { count: 0 };
17
- var count = window.oc.__elmTemplate.count;
18
- var templateId = "${templateId}-" + count;
19
- window.oc.__elmTemplate.count++;
20
- return '<div id="' + templateId + '" class="${templateId}">' + modelHTML + '</div>' +
21
- '${css ? '<style>' + (0, cssesc_1.default)(css) + '</style>' : ''}' +
22
- '<script>' +
23
- 'window.oc = window.oc || {};' +
24
- 'oc.cmd = oc.cmd || [];' +
25
-
26
- 'oc.cmd.push(function(oc){' +
27
- '${css ? "oc.events.fire(\\'oc:cssDidMount\\', \\'" + css + "\\');" : ''}' +
28
- 'var targetNode = document.getElementById("' + templateId + '");' +
29
- 'targetNode.setAttribute("id","");' +
30
- 'oc.elmComponents["${hash}"](' + props + ', targetNode);' +
31
- '});' +
32
- '</script>'
33
- }`;
34
- }
35
- exports.default = viewTemplate;
@@ -1,5 +0,0 @@
1
- declare const RE_FONT_FAMILY: RegExp;
2
- declare const RE_FONT_NAMES: RegExp;
3
- declare const RE_DOUBLE_COUTE: RegExp;
4
- declare const RE_SPACE: RegExp;
5
- declare const RE_UNICODE: RegExp;
@@ -1,23 +0,0 @@
1
- "use strict";
2
- const RE_FONT_FAMILY = /font-family\s*:\s*([^;\n]+)[;\n]/g;
3
- const RE_FONT_NAMES = /(?:(?:'|(?:\\"))?([(?:\\\\)\w\d _-]+)(?:'|(?:\\"))?(,\s*)?)/g;
4
- const RE_DOUBLE_COUTE = /"/g;
5
- const RE_SPACE = /[ ]+/g;
6
- const RE_UNICODE = /\\([\d\w]{4})/g;
7
- module.exports = function (source) {
8
- source = source.replace(RE_FONT_FAMILY, (str, fontNames) => {
9
- const strFontNames = fontNames
10
- .replace(RE_DOUBLE_COUTE, "'")
11
- .replace(RE_FONT_NAMES, (match, fontName, sep) => {
12
- if (match.includes("'")) {
13
- const replacement = fontName
14
- .replace(RE_SPACE, ' ')
15
- .replace(RE_UNICODE, (m, unicode) => String.fromCharCode(parseInt(unicode, 16)));
16
- return `'${replacement}'${sep || ''}`;
17
- }
18
- return match;
19
- });
20
- return `font-family: ${strFontNames};`;
21
- });
22
- return source;
23
- };
@@ -1,8 +0,0 @@
1
- declare const chalk: any;
2
- declare const fs: any;
3
- declare const resolve: any;
4
- declare const path: any;
5
- declare const os: any;
6
- declare const immer: any;
7
- declare function writeJson(fileName: any, object: any): void;
8
- declare function verifyTypeScriptSetup(componentPath: any): void;
@@ -1,146 +0,0 @@
1
- "use strict";
2
- const chalk = require('chalk');
3
- const fs = require('fs');
4
- const resolve = require('resolve');
5
- const path = require('path');
6
- const os = require('os');
7
- const immer = require('immer').produce;
8
- function writeJson(fileName, object) {
9
- fs.writeFileSync(fileName, JSON.stringify(object, null, 2).replace(/\n/g, os.EOL) + os.EOL);
10
- }
11
- function verifyTypeScriptSetup(componentPath) {
12
- const paths = {
13
- appTsConfig: path.resolve(componentPath, 'tsconfig.json'),
14
- yarnLockFile: path.resolve(componentPath, 'yarn.lock'),
15
- appNodeModules: path.resolve(componentPath, 'node_modules')
16
- };
17
- let firstTimeSetup = false;
18
- if (!fs.existsSync(paths.appTsConfig)) {
19
- writeJson(paths.appTsConfig, {});
20
- firstTimeSetup = true;
21
- }
22
- const isYarn = fs.existsSync(paths.yarnLockFile);
23
- // Ensure typescript is installed
24
- let ts;
25
- try {
26
- ts = require(resolve.sync('typescript', {
27
- basedir: paths.appNodeModules
28
- }));
29
- }
30
- catch (_) {
31
- console.error(chalk.bold.red(`It looks like you're trying to use TypeScript but do not have ${chalk.bold('typescript')} installed.`));
32
- console.error(chalk.bold('Please install', chalk.cyan.bold('typescript'), 'by running', chalk.cyan.bold(isYarn ? 'yarn add typescript' : 'npm install typescript') + '.'));
33
- console.error();
34
- process.exit(1);
35
- }
36
- const compilerOptions = {
37
- // These are suggested values and will be set when not present in the
38
- // tsconfig.json
39
- // 'parsedValue' matches the output value from ts.parseJsonConfigFileContent()
40
- target: {
41
- parsedValue: ts.ScriptTarget.ES5,
42
- suggested: 'es5'
43
- },
44
- lib: { suggested: ['dom', 'dom.iterable', 'esnext'] },
45
- allowJs: { suggested: true },
46
- skipLibCheck: { suggested: true },
47
- esModuleInterop: { suggested: true },
48
- allowSyntheticDefaultImports: { suggested: true },
49
- strict: { suggested: true },
50
- forceConsistentCasingInFileNames: { suggested: true },
51
- // TODO: Enable for v4.0 (#6936)
52
- // noFallthroughCasesInSwitch: { suggested: true },
53
- // These values are required and cannot be changed by the user
54
- // Keep this in sync with the webpack config
55
- module: {
56
- parsedValue: ts.ModuleKind.ESNext,
57
- value: 'esnext',
58
- reason: 'for import() and import/export'
59
- },
60
- moduleResolution: {
61
- parsedValue: ts.ModuleResolutionKind.NodeJs,
62
- value: 'node',
63
- reason: 'to match webpack resolution'
64
- },
65
- resolveJsonModule: { value: true, reason: 'to match webpack loader' },
66
- isolatedModules: { value: true, reason: 'implementation limitation' },
67
- paths: { value: undefined, reason: 'aliased imports are not supported' }
68
- };
69
- const formatDiagnosticHost = {
70
- getCanonicalFileName: (fileName) => fileName,
71
- getCurrentDirectory: ts.sys.getCurrentDirectory,
72
- getNewLine: () => os.EOL
73
- };
74
- const messages = [];
75
- let appTsConfig;
76
- let parsedTsConfig;
77
- let parsedCompilerOptions;
78
- try {
79
- const { config: readTsConfig, error } = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile);
80
- if (error) {
81
- throw new Error(ts.formatDiagnostic(error, formatDiagnosticHost));
82
- }
83
- appTsConfig = readTsConfig;
84
- // Get TS to parse and resolve any "extends"
85
- // Calling this function also mutates the tsconfig above,
86
- // adding in "include" and "exclude", but the compilerOptions remain untouched
87
- let result;
88
- parsedTsConfig = immer(readTsConfig, (config) => {
89
- result = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(paths.appTsConfig));
90
- });
91
- if (result.errors && result.errors.length) {
92
- throw new Error(ts.formatDiagnostic(result.errors[0], formatDiagnosticHost));
93
- }
94
- parsedCompilerOptions = result.options;
95
- }
96
- catch (e) {
97
- if (e && e.name === 'SyntaxError') {
98
- console.error(chalk.red.bold('Could not parse', chalk.cyan('tsconfig.json') + '.', 'Please make sure it contains syntactically correct JSON.'));
99
- }
100
- console.log(e && e.message ? `${e.message}` : '');
101
- process.exit(1);
102
- }
103
- if (appTsConfig.compilerOptions == null) {
104
- appTsConfig.compilerOptions = {};
105
- firstTimeSetup = true;
106
- }
107
- for (const option of Object.keys(compilerOptions)) {
108
- const { parsedValue, value, suggested, reason } = compilerOptions[option];
109
- const valueToCheck = parsedValue === undefined ? value : parsedValue;
110
- const coloredOption = chalk.cyan('compilerOptions.' + option);
111
- if (suggested != null) {
112
- if (parsedCompilerOptions[option] === undefined) {
113
- appTsConfig.compilerOptions[option] = suggested;
114
- messages.push(`${coloredOption} to be ${chalk.bold('suggested')} value: ${chalk.cyan.bold(suggested)} (this can be changed)`);
115
- }
116
- }
117
- else if (parsedCompilerOptions[option] !== valueToCheck) {
118
- appTsConfig.compilerOptions[option] = value;
119
- messages.push(`${coloredOption} ${chalk.bold(valueToCheck == null ? 'must not' : 'must')} be ${valueToCheck == null ? 'set' : chalk.cyan.bold(value)}` + (reason != null ? ` (${reason})` : ''));
120
- }
121
- }
122
- // tsconfig will have the merged "include" and "exclude" by this point
123
- if (parsedTsConfig.include == null) {
124
- appTsConfig.include = ['src'];
125
- messages.push(`${chalk.cyan('include')} should be ${chalk.cyan.bold('src')}`);
126
- }
127
- if (parsedTsConfig.exclude == null) {
128
- appTsConfig.exclude = ['src/_package'];
129
- messages.push(`${chalk.cyan('exclude')} should have ${chalk.cyan.bold('src/_package')}`);
130
- }
131
- if (messages.length > 0) {
132
- if (firstTimeSetup) {
133
- console.log(chalk.bold('Your', chalk.cyan('tsconfig.json'), 'has been populated with default values.'));
134
- console.log();
135
- }
136
- else {
137
- console.warn(chalk.bold('The following changes are being made to your', chalk.cyan('tsconfig.json'), 'file:'));
138
- messages.forEach((message) => {
139
- console.warn(' - ' + message);
140
- });
141
- console.warn();
142
- }
143
- writeJson(paths.appTsConfig, appTsConfig);
144
- }
145
- }
146
- module.exports = verifyTypeScriptSetup;
@@ -1,6 +0,0 @@
1
- declare const viewTemplate: ({ elmRoot, css, bundleHash, bundleName }: {
2
- elmRoot: any;
3
- css: any;
4
- bundleHash: any;
5
- bundleName: any;
6
- }) => string;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- const viewTemplate = ({ elmRoot, css, bundleHash, bundleName }) => `function elmViewTemplate(model) {
3
- var modelHTML = model.__html ? model.__html : '';
4
- var staticPath = model.elmComponent.flags._staticPath;
5
- var flags = JSON.stringify(model.elmComponent.flags);
6
- window.oc = window.oc || {};
7
- window.oc.__elmTemplate = window.oc.__elmTemplate || { count: 0 };
8
- var count = window.oc.__elmTemplate.count;
9
- var templateId = "${elmRoot}-" + count;
10
- window.oc.__elmTemplate.count++;
11
- return '<div id="' + templateId + '" class="${elmRoot}">' + modelHTML + '</div>' +
12
- '${css ? '<style>' + css + '</style>' : ''}' +
13
- '<script>' +
14
- 'window.oc = window.oc || {};' +
15
- 'oc.cmd = oc.cmd || [];' +
16
- 'oc.cmd.push(function(oc){' +
17
- '${css ? "oc.events.fire(\\'oc:cssDidMount\\', \\'" + css + "\\');" : ''}' +
18
- 'oc.require(' +
19
- '["oc", "elmComponents", "${bundleHash}"],' +
20
- '"' + staticPath + '${bundleName}.js",' +
21
- 'function(ElmComponent) {' +
22
- 'var targetNode = document.getElementById("' + templateId + '");' +
23
- 'targetNode.setAttribute("id","");' +
24
- 'ElmComponent({ node: targetNode, flags:' + flags + '});' +
25
- '}' +
26
- ');' +
27
- '});' +
28
- '</script>'
29
- }`;
30
- module.exports = viewTemplate;