@unvt/charites 0.1.1

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.
Files changed (43) hide show
  1. package/.editorconfig +9 -0
  2. package/.github/workflows/build.yml +50 -0
  3. package/LICENSE +21 -0
  4. package/README.md +137 -0
  5. package/dist/cli.js +76 -0
  6. package/dist/commands/build.js +62 -0
  7. package/dist/commands/convert.js +89 -0
  8. package/dist/commands/init.js +33 -0
  9. package/dist/commands/serve.js +100 -0
  10. package/dist/lib/defaultValues.js +31 -0
  11. package/dist/lib/validate-style.js +24 -0
  12. package/dist/lib/yaml-parser.js +46 -0
  13. package/package.json +42 -0
  14. package/provider/default/app.css +7 -0
  15. package/provider/default/app.js +11 -0
  16. package/provider/default/index.html +13 -0
  17. package/provider/geolonia/app.css +7 -0
  18. package/provider/geolonia/app.js +11 -0
  19. package/provider/geolonia/index.html +12 -0
  20. package/provider/mapbox/app.css +7 -0
  21. package/provider/mapbox/app.js +13 -0
  22. package/provider/mapbox/index.html +13 -0
  23. package/src/cli.ts +83 -0
  24. package/src/commands/build.ts +64 -0
  25. package/src/commands/convert.ts +95 -0
  26. package/src/commands/init.ts +29 -0
  27. package/src/commands/serve.ts +105 -0
  28. package/src/lib/defaultValues.ts +36 -0
  29. package/src/lib/validate-style.ts +22 -0
  30. package/src/lib/yaml-parser.ts +51 -0
  31. package/test/build.spec.ts +36 -0
  32. package/test/convert.spec.ts +43 -0
  33. package/test/data/convert.json +23 -0
  34. package/test/data/error.yml +1 -0
  35. package/test/data/example.yml +20 -0
  36. package/test/data/layers/background.yml +4 -0
  37. package/test/data/layers/water.yml +8 -0
  38. package/test/data/names.yml +3 -0
  39. package/test/data/style.json +33 -0
  40. package/test/data/style.yml +12 -0
  41. package/test/validate-style.spec.ts +18 -0
  42. package/test/yaml-parser.spec.ts +25 -0
  43. package/tsconfig.json +19 -0
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@unvt/charites",
3
+ "version": "0.1.1",
4
+ "description": "",
5
+ "bin": {
6
+ "charites": "dist/cli.js"
7
+ },
8
+ "scripts": {
9
+ "build": "tsc -p .",
10
+ "watch": "tsc -w",
11
+ "lint": "eslint .",
12
+ "fix": "eslint --fix .",
13
+ "test": "mocha -r ts-node/register test/*.ts",
14
+ "test:watch": "npm test -- --watch --watch-files src/**/*.ts --watch-files test/**/*.ts",
15
+ "command": "./node_modules/.bin/ts-node ./src/cli.ts"
16
+ },
17
+ "author": "",
18
+ "license": "MIT",
19
+ "dependencies": {
20
+ "@mapbox/mapbox-gl-style-spec": "^13.22.0",
21
+ "@maplibre/maplibre-gl-style-spec": "^14.0.2",
22
+ "@types/jsonminify": "^0.4.1",
23
+ "commander": "^8.2.0",
24
+ "js-yaml": "^4.0.0",
25
+ "jsonminify": "^0.4.1",
26
+ "node-watch": "^0.7.2",
27
+ "open": "^8.2.1",
28
+ "ws": "^8.2.2",
29
+ "yaml-include": "^1.2.1"
30
+ },
31
+ "devDependencies": {
32
+ "@types/chai": "^4.2.11",
33
+ "@types/js-yaml": "^4.0.3",
34
+ "@types/mocha": "^7.0.2",
35
+ "@types/node": "^14.0.14",
36
+ "@types/ws": "^8.2.0",
37
+ "chai": "^4.2.0",
38
+ "mocha": "^8.0.1",
39
+ "ts-node": "^8.10.2",
40
+ "typescript": "^3.9.5"
41
+ }
42
+ }
@@ -0,0 +1,7 @@
1
+ html, body, #map
2
+ {
3
+ width: 100vw;
4
+ height: 100vh;
5
+ padding: 0;
6
+ margin: 0;
7
+ }
@@ -0,0 +1,11 @@
1
+ const map = new maplibregl.Map({
2
+ container: 'map',
3
+ hash: true,
4
+ style: `http://${window.location.host}/style.json`
5
+ });
6
+
7
+ const socket = new WebSocket('ws://localhost:___PORT___');
8
+
9
+ socket.addEventListener('message',(message)=>{
10
+ map.setStyle(JSON.parse(message.data))
11
+ });
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="/app.css" />
5
+ <link href='https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.css' rel='stylesheet' />
6
+ <title>Charites Live Preview</title>
7
+ <script src='https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.js'></script>
8
+ </head>
9
+ <body>
10
+ <div id="map"></div>
11
+ <script type="text/javascript" src="/app.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,7 @@
1
+ html, body, #map
2
+ {
3
+ width: 100vw;
4
+ height: 100vh;
5
+ padding: 0;
6
+ margin: 0;
7
+ }
@@ -0,0 +1,11 @@
1
+ const map = new geolonia.Map({
2
+ container: "#map",
3
+ hash: true,
4
+ style: `http://${window.location.host}/style.json`
5
+ })
6
+
7
+ const socket = new WebSocket('ws://localhost:___PORT___');
8
+
9
+ socket.addEventListener('message',(message)=>{
10
+ map.setStyle(JSON.parse(message.data))
11
+ });
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="/app.css" />
5
+ <title>Charites Live Preview</title>
6
+ </head>
7
+ <body>
8
+ <div id="map"></div>
9
+ <script type="text/javascript" src="https://cdn.geolonia.com/v1/embed?geolonia-api-key=YOUR-API-KEY"></script>
10
+ <script type="text/javascript" src="/app.js"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,7 @@
1
+ html, body, #map
2
+ {
3
+ width: 100vw;
4
+ height: 100vh;
5
+ padding: 0;
6
+ margin: 0;
7
+ }
@@ -0,0 +1,13 @@
1
+ mapboxgl.accessToken = '___MAPBOX_ACCESS_TOKEN___'
2
+
3
+ const map = new mapboxgl.Map({
4
+ container: 'map',
5
+ hash: true,
6
+ style: `http://${window.location.host}/style.json`
7
+ });
8
+
9
+ const socket = new WebSocket('ws://localhost:___PORT___');
10
+
11
+ socket.addEventListener('message',(message)=>{
12
+ map.setStyle(JSON.parse(message.data))
13
+ });
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="/app.css" />
5
+ <link href='https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.css' rel='stylesheet' />
6
+ <title>Charites Live Preview</title>
7
+ <script src='https://api.mapbox.com/mapbox-gl-js/v2.5.0/mapbox-gl.js'></script>
8
+ </head>
9
+ <body>
10
+ <div id="map"></div>
11
+ <script type="text/javascript" src="/app.js"></script>
12
+ </body>
13
+ </html>
package/src/cli.ts ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import fs from 'fs'
5
+
6
+ import { init } from './commands/init'
7
+ import { convert } from './commands/convert'
8
+ import { build } from './commands/build'
9
+ import { serve } from './commands/serve'
10
+
11
+ import { defaultSettings } from './lib/defaultValues'
12
+
13
+ interface buildOptions {
14
+ compactOutput?: boolean
15
+ }
16
+
17
+ const program = new Command();
18
+
19
+ const error = (message: any) => {
20
+ console.error(message.toString())
21
+ process.exit(1)
22
+ }
23
+
24
+ program
25
+ .option('--provider [provider]', 'your map service. e.g. `mapbox`, `geolonia`')
26
+ .option('--mapbox-access-token [mapboxAccessToken]', 'Access Token for the Mapbox')
27
+
28
+ program
29
+ .command('init <file>')
30
+ .description('initialize a style JSON')
31
+ .action((file: string) => {
32
+ try {
33
+ init(file)
34
+ } catch(e) {
35
+ error(e)
36
+ }
37
+ })
38
+
39
+ program
40
+ .command('convert <source> [destination]')
41
+ .description('convert the style JSON to YAML')
42
+ .action((source: string, destination: string) => {
43
+ try {
44
+ convert(source, destination)
45
+ } catch(e) {
46
+ error(e)
47
+ }
48
+ })
49
+
50
+ program
51
+ .command('build <source> [destination]')
52
+ .description('build a style JSON from the YAML')
53
+ .option('-c, --compact-output', 'build a minified style JSON')
54
+ .action((source: string, destination: string, buildOptions: buildOptions) => {
55
+ const options = program.opts()
56
+ options.compactOutput = buildOptions.compactOutput
57
+
58
+ if (! fs.existsSync(defaultSettings.configFile)) {
59
+ fs.writeFileSync(defaultSettings.configFile, `provider: ${options.provider || 'default'}`)
60
+ }
61
+ try {
62
+ build(source, destination, options)
63
+ } catch(e) {
64
+ error(e)
65
+ }
66
+ })
67
+
68
+ program
69
+ .command('serve <source>')
70
+ .description('serve your map locally')
71
+ .action((source: string) => {
72
+ const options = program.opts()
73
+ if (! fs.existsSync(defaultSettings.configFile)) {
74
+ fs.writeFileSync(defaultSettings.configFile, `provider: ${options.provider || 'default'}`)
75
+ }
76
+ try {
77
+ serve(source, program.opts())
78
+ } catch(e) {
79
+ error(e)
80
+ }
81
+ })
82
+
83
+ program.parse(process.argv)
@@ -0,0 +1,64 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import { parser } from '../lib/yaml-parser'
4
+ import { validateStyle } from '../lib/validate-style'
5
+ import { defaultValues } from '../lib/defaultValues'
6
+ import jsonminify from 'jsonminify'
7
+
8
+ interface options {
9
+ provider?: string,
10
+ compactOutput?: boolean
11
+ }
12
+
13
+ export function build(source: string, destination: string, options: options) {
14
+ let sourcePath = path.resolve(process.cwd(), source)
15
+
16
+ // The `source` is absolute path.
17
+ if (source.match(/^\//)) {
18
+ sourcePath = source
19
+ }
20
+
21
+ if (! fs.existsSync(sourcePath)) {
22
+ throw `${sourcePath}: No such file or directory`
23
+ }
24
+
25
+ let destinationPath = ""
26
+
27
+ if (destination) {
28
+ if (destination.match(/^\//)) {
29
+ destinationPath = destination
30
+ } else {
31
+ destinationPath = path.resolve(process.cwd(), destination)
32
+ }
33
+ } else {
34
+ destinationPath = path.join(path.dirname(sourcePath), `${path.basename(source, '.yml')}.json`)
35
+ }
36
+
37
+ let provider = defaultValues.provider
38
+ if (options.provider) {
39
+ provider = options.provider
40
+ }
41
+
42
+ let style = ''
43
+
44
+ try {
45
+ const _style = parser(sourcePath)
46
+ validateStyle(_style, provider)
47
+ style = JSON.stringify(_style, null, ' ')
48
+ if (options.compactOutput) {
49
+ style = jsonminify(style)
50
+ }
51
+ } catch(err) {
52
+ if (err) {
53
+ throw err
54
+ } else {
55
+ throw `${sourcePath}: Invalid YAML syntax`
56
+ }
57
+ }
58
+
59
+ try {
60
+ fs.writeFileSync(destinationPath, style)
61
+ } catch(err) {
62
+ throw `${destinationPath}: Permission denied`
63
+ }
64
+ }
@@ -0,0 +1,95 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import YAML from 'js-yaml'
4
+ import readline from 'readline'
5
+
6
+ // TODO: Type of style should be loaded from maplibre or mapbox style spec.
7
+ const writeYaml = (destinationPath: string, style: any) => {
8
+ const layers = []
9
+
10
+ for (let i = 0; i < style.layers.length; i++) {
11
+ const layer = style.layers[i]
12
+ const layerYml = YAML.dump(layer)
13
+ const fileName = `${style.layers[i].id}.yml`
14
+ const dirName = path.join(path.dirname(destinationPath), 'layers')
15
+ fs.mkdirSync(dirName, { recursive: true })
16
+ fs.writeFileSync(path.join(dirName, fileName), layerYml)
17
+
18
+ layers.push(`!!inc/file ${path.join('layers', fileName)}`)
19
+ }
20
+
21
+ style.layers = layers
22
+
23
+ fs.writeFileSync(destinationPath, YAML.dump(style).replace(/'\!\!inc\/file layers\/.+\.yml'/g, function (match) {
24
+ return match.replace(/'/g, '')
25
+ }))
26
+ }
27
+
28
+ const getDestinationPath = (destination: string, sourcePath: string = '') => {
29
+ let destinationPath
30
+
31
+ if (destination) {
32
+ if (destination.match(/^\//)) {
33
+ destinationPath = destination
34
+ } else {
35
+ destinationPath = path.resolve(process.cwd(), destination)
36
+ }
37
+ } else {
38
+ if (sourcePath) {
39
+ destinationPath = path.join(path.dirname(sourcePath), `${path.basename(sourcePath, '.json')}.yml`)
40
+ } else {
41
+ destinationPath = path.join(process.cwd(), 'style.yml')
42
+ }
43
+ }
44
+
45
+ return destinationPath
46
+ }
47
+
48
+ export function convert(source: string, destination: string) {
49
+ let style, sourcePath
50
+
51
+ if ('-' === source) {
52
+ const rl = readline.createInterface({
53
+ input: process.stdin,
54
+ terminal: false
55
+ });
56
+
57
+ const lines: string[] = []
58
+
59
+ rl.on("line", (line) => {
60
+ lines.push(line)
61
+ });
62
+
63
+ rl.on("close", () => {
64
+ const style = JSON.parse(lines.join(''))
65
+ const destinationPath = getDestinationPath(destination)
66
+
67
+ try {
68
+ writeYaml(destinationPath, style)
69
+ } catch(err) {
70
+ throw `${destinationPath}: Permission denied`
71
+ }
72
+ })
73
+ } else {
74
+ sourcePath = path.resolve(process.cwd(), source)
75
+
76
+ // The `source` is absolute path.
77
+ if (source.match(/^\//)) {
78
+ sourcePath = source
79
+ }
80
+
81
+ if (! fs.existsSync(sourcePath)) {
82
+ throw `${sourcePath}: No such file or directory`
83
+ }
84
+
85
+ style = JSON.parse(fs.readFileSync(sourcePath, 'utf-8'))
86
+
87
+ const destinationPath = getDestinationPath(destination, sourcePath)
88
+
89
+ try {
90
+ writeYaml(destinationPath, style)
91
+ } catch(err) {
92
+ throw `${destinationPath}: Permission denied`
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,29 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import YAML from 'js-yaml'
4
+
5
+ // TODO: We need type definition for style.
6
+ const styleRoot = {
7
+ version: 8,
8
+ name: "My Style",
9
+ sprite: "",
10
+ glyphs: "",
11
+ sources: {},
12
+ layers: []
13
+ }
14
+
15
+ export function init(file: string) {
16
+ const styleYAML = YAML.dump(styleRoot)
17
+ let stylePath = path.resolve(process.cwd(), file)
18
+
19
+ // The `source` is absolute path.
20
+ if (file.match(/^\//)) {
21
+ stylePath = file
22
+ }
23
+
24
+ try {
25
+ fs.writeFileSync(stylePath, styleYAML)
26
+ } catch(err) {
27
+ throw `${stylePath}: Permission denied`
28
+ }
29
+ }
@@ -0,0 +1,105 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import http from 'http'
4
+ import open from 'open'
5
+ import { WebSocketServer } from 'ws'
6
+ import watch from 'node-watch'
7
+
8
+ import { parser } from '../lib/yaml-parser'
9
+ import { validateStyle } from '../lib/validate-style'
10
+ import { defaultValues } from '../lib/defaultValues'
11
+
12
+ interface options {
13
+ provider?: string
14
+ mapboxAccessToken?: string
15
+ }
16
+
17
+ export function serve(source: string, options: options) {
18
+ const port = process.env.PORT || 8080
19
+ let sourcePath = path.resolve(process.cwd(), source)
20
+
21
+ let provider = defaultValues.provider
22
+ if (options.provider) {
23
+ provider = options.provider
24
+ }
25
+
26
+ // The `source` is absolute path.
27
+ if (source.match(/^\//)) {
28
+ sourcePath = source
29
+ }
30
+
31
+ if (! fs.existsSync(sourcePath)) {
32
+ throw `${sourcePath}: No such file or directory`
33
+ }
34
+
35
+ const server = http.createServer((req, res) => {
36
+ const url = (req.url || '').replace(/\?.*/, '')
37
+ const dir = path.join(defaultValues.providerDir, provider)
38
+
39
+ switch (url) {
40
+ case '/':
41
+ res.statusCode = 200
42
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8')
43
+ const content = fs.readFileSync(path.join(dir, 'index.html'), 'utf-8')
44
+ res.end(content)
45
+ break;
46
+ case '/style.json':
47
+ const style = parser(sourcePath)
48
+ try {
49
+ validateStyle(style, provider)
50
+ } catch(error) {
51
+ console.log(error)
52
+ }
53
+ res.statusCode = 200
54
+ res.setHeader('Content-Type', 'application/json; charset=UTF-8')
55
+ res.end(JSON.stringify(style))
56
+ break;
57
+ case '/app.css':
58
+ res.statusCode = 200
59
+ res.setHeader('Content-Type', 'text/css; charset=UTF-8')
60
+ const css = fs.readFileSync(path.join(dir, 'app.css'), 'utf-8')
61
+ res.end(css)
62
+ break;
63
+ case `/app.js`:
64
+ res.statusCode = 200
65
+ res.setHeader('Content-Type', 'application/javascript; charset=UTF-8')
66
+ try {
67
+ const app = fs.readFileSync(path.join(dir, 'app.js'), 'utf-8')
68
+ const js = app.replace('___PORT___', `${port}`)
69
+ .replace('___MAPBOX_ACCESS_TOKEN___', `${options.mapboxAccessToken || defaultValues.mapboxAccessToken}`)
70
+ res.end(js)
71
+ } catch(e) {
72
+ throw `Invalid provider: ${provider}`
73
+ }
74
+ break;
75
+ }
76
+ })
77
+
78
+ server.listen(port, () => {
79
+ console.log(`Provider: ${provider}`)
80
+ console.log(`Loading your style: ${sourcePath}`)
81
+ console.log(`Your map is running on http://localhost:${port}/\n`)
82
+ open(`http://localhost:${port}`)
83
+ })
84
+
85
+ const wss = new WebSocketServer({ server });
86
+
87
+ wss.on('connection', (ws) => {
88
+ watch(path.dirname(sourcePath), { recursive: true, filter: /\.yml$/ }, (event, file) => {
89
+ console.log(`${(event || '').toUpperCase()}: ${file}`)
90
+ try {
91
+ const style = parser(sourcePath)
92
+ try {
93
+ validateStyle(style, provider)
94
+ } catch(error) {
95
+ console.log(error)
96
+ }
97
+ ws.send(JSON.stringify(style))
98
+ } catch(e) {
99
+ // Nothing to do
100
+ }
101
+ })
102
+ });
103
+
104
+ return server
105
+ }
@@ -0,0 +1,36 @@
1
+ import path from 'path'
2
+ import os from 'os'
3
+ import fs from 'fs'
4
+ import YAML from 'js-yaml'
5
+
6
+ interface Config {
7
+ provider: string
8
+ providerDir: string
9
+ mapboxAccessToken?: string
10
+ }
11
+
12
+ const homedir = os.homedir()
13
+ const defaultProvider = "default"
14
+
15
+ const configDir = path.join(homedir, '.charites')
16
+ fs.mkdirSync(configDir, { recursive: true });
17
+
18
+ const configFile = path.join(configDir, 'config.yml')
19
+ let config: Config = {provider: '', providerDir: '', mapboxAccessToken: ''}
20
+
21
+ try {
22
+ const yaml = fs.readFileSync(configFile, 'utf-8')
23
+ config = YAML.load(yaml) as Config
24
+ } catch(e) {
25
+ // nothing to do
26
+ }
27
+
28
+ export const defaultValues: Config = {
29
+ provider: config.provider || defaultProvider,
30
+ providerDir: path.join(path.dirname(path.dirname(__dirname)), 'provider'),
31
+ mapboxAccessToken: config.mapboxAccessToken || ''
32
+ }
33
+
34
+ export const defaultSettings = {
35
+ configFile: configFile
36
+ }
@@ -0,0 +1,22 @@
1
+ const maplibreStyleSpec = require('@maplibre/maplibre-gl-style-spec')
2
+ const mapboxStyleSpec = require('@mapbox/mapbox-gl-style-spec')
3
+
4
+ export function validateStyle(style: object, provider: string = "default"): void {
5
+ let result = []
6
+ if ('mapbox' === provider) {
7
+ result = mapboxStyleSpec.validate(style)
8
+ } else {
9
+ result = maplibreStyleSpec.validate(style)
10
+ }
11
+
12
+ const errors = []
13
+ for (let i = 0; i < result.length; i++) {
14
+ if (result[i].message) {
15
+ errors.push(result[i].message)
16
+ }
17
+ }
18
+
19
+ if (errors.length) {
20
+ throw `\u001b[31mError:\u001b[0m ${errors.join("\n\u001b[31mError:\u001b[0m ")}`
21
+ }
22
+ }
@@ -0,0 +1,51 @@
1
+ import fs from 'fs'
2
+ import YAML from 'js-yaml'
3
+
4
+ const yamlinc = require('yaml-include')
5
+
6
+ interface StyleObject {
7
+ [key: string]: any;
8
+ }
9
+
10
+ export function parser(file: string): object {
11
+ yamlinc.setBaseFile(file)
12
+ const yaml = fs.readFileSync(file, 'utf8')
13
+
14
+ const obj: StyleObject = YAML.load(yaml, {
15
+ schema: yamlinc.YAML_INCLUDE_SCHEMA,
16
+ filename: file,
17
+ json: true
18
+ }) as StyleObject
19
+
20
+ const styleObj: StyleObject = {}
21
+ let variables: StyleObject = {}
22
+
23
+ for (const key in obj as any) {
24
+ if (key.match(/^\$/)) {
25
+ variables[key] = obj[key]
26
+ } else {
27
+ styleObj[key] = obj[key]
28
+ }
29
+ }
30
+
31
+ // Handle all nested variables.
32
+ while(JSON.stringify(Object.values(variables)).match(/\$/)) {
33
+ for (const key in variables as any) {
34
+ for (const variable in variables) {
35
+ let _value = JSON.stringify(variables[key])
36
+ const regex = new RegExp(`\"\\${variable}\"`, 'g')
37
+ _value = _value.replace(regex, JSON.stringify(variables[variable]))
38
+ variables[key] = JSON.parse(_value)
39
+ }
40
+ }
41
+ }
42
+
43
+ let style = JSON.stringify(styleObj)
44
+
45
+ for (const key in variables) {
46
+ const regex = new RegExp(`\"\\${key}\"`, 'g')
47
+ style = style.replace(regex, JSON.stringify(variables[key]))
48
+ }
49
+
50
+ return JSON.parse(style)
51
+ }
@@ -0,0 +1,36 @@
1
+ import { assert } from 'chai'
2
+ import path from 'path'
3
+ import fs from 'fs'
4
+ import os from 'os'
5
+
6
+ import { build } from '../src/commands/build'
7
+ import { defaultValues } from '../src/lib/defaultValues'
8
+
9
+ describe('Test for the `build.ts`.', () => {
10
+
11
+ const stylePath = path.join(__dirname, 'data/style.yml')
12
+
13
+ it('Should convert `data/style.yml` to JSON.', () => {
14
+ const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'charites-'))
15
+ const styleJson = path.join(tmpdir, 'style.json')
16
+
17
+ build(stylePath, styleJson, {provider: defaultValues.provider})
18
+
19
+ // The file should exists.
20
+ assert.deepEqual(true, !! fs.statSync(styleJson))
21
+ assert.deepEqual(8, JSON.parse(fs.readFileSync(styleJson, 'utf-8')).version)
22
+ });
23
+
24
+ it('Should minify `data/style.yml` to JSON.', () => {
25
+
26
+ const tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'charites-'))
27
+ const styleJson = path.join(tmpdir, 'style.json')
28
+
29
+ build(stylePath, styleJson, {provider: defaultValues.provider, compactOutput: true})
30
+
31
+ const contents = fs.readFileSync(styleJson, 'utf-8')
32
+ const lines = contents.split('\n').length
33
+
34
+ assert.deepEqual(lines, 1)
35
+ });
36
+ });