1 | const fs = require('fs')
|
2 | const cloneDeep = require('lodash.clonedeep')
|
3 | const { getRcPath } = require('./util/rcPath')
|
4 | const { exit } = require('@vue/cli-shared-utils/lib/exit')
|
5 | const { error } = require('@vue/cli-shared-utils/lib/logger')
|
6 | const { createSchema, validate } = require('@vue/cli-shared-utils/lib/validate')
|
7 |
|
8 | const rcPath = exports.rcPath = getRcPath('.controllarc')
|
9 |
|
10 | const presetSchema = createSchema(joi => joi.object().keys({
|
11 | bare: joi.boolean(),
|
12 | useConfigFiles: joi.boolean(),
|
13 | router: joi.boolean(),
|
14 | routerHistoryMode: joi.boolean(),
|
15 | vuex: joi.boolean(),
|
16 |
|
17 | cssPreprocessor: joi.string().only(['sass', 'dart-sass', 'node-sass', 'less', 'stylus']),
|
18 | plugins: joi.object().required(),
|
19 | configs: joi.object()
|
20 | }))
|
21 |
|
22 | const schema = createSchema(joi => joi.object().keys({
|
23 | latestVersion: joi.string().regex(/^\d+\.\d+\.\d+$/),
|
24 | lastChecked: joi.date().timestamp(),
|
25 | packageManager: joi.string().only(['yarn', 'npm']),
|
26 | description: joi.string(),
|
27 | repository: joi.string(),
|
28 | useTaobaoRegistry: joi.boolean(),
|
29 | presets: joi.object().pattern(/^/, presetSchema)
|
30 | }))
|
31 |
|
32 | exports.validatePreset = preset => validate(preset, presetSchema, msg => {
|
33 | error(`invalid preset options: ${msg}`)
|
34 | })
|
35 |
|
36 | exports.defaultPreset = {
|
37 | router: false,
|
38 | vuex: false,
|
39 | useConfigFiles: false,
|
40 | cssPreprocessor: undefined,
|
41 | plugins: {
|
42 | '@vue/cli-plugin-babel': {},
|
43 | '@vue/cli-plugin-eslint': {
|
44 | config: 'base',
|
45 | lintOn: ['save']
|
46 | }
|
47 | }
|
48 | }
|
49 |
|
50 | exports.defaults = {
|
51 | lastChecked: undefined,
|
52 | latestVersion: undefined,
|
53 |
|
54 | packageManager: undefined,
|
55 | description: undefined,
|
56 | repository: undefined,
|
57 | useTaobaoRegistry: undefined,
|
58 | presets: {
|
59 | 'default': exports.defaultPreset
|
60 | }
|
61 | }
|
62 |
|
63 | let cachedOptions
|
64 |
|
65 | exports.loadOptions = () => {
|
66 | if (cachedOptions) {
|
67 | return cachedOptions
|
68 | }
|
69 | if (fs.existsSync(rcPath)) {
|
70 | try {
|
71 | cachedOptions = JSON.parse(fs.readFileSync(rcPath, 'utf-8'))
|
72 | } catch (e) {
|
73 | error(
|
74 | `Error loading saved preferences: ` +
|
75 | `~/.controllarc may be corrupted or have syntax errors. ` +
|
76 | `Please fix/delete it and re-run controlla-cli in manual mode.\n` +
|
77 | `(${e.message})`
|
78 | )
|
79 | exit(1)
|
80 | }
|
81 | validate(cachedOptions, schema, () => {
|
82 | error(
|
83 | `~/.controllarc may be outdated. ` +
|
84 | `Please delete it and re-run controlla-cli in manual mode.`
|
85 | )
|
86 | })
|
87 | return cachedOptions
|
88 | } else {
|
89 | return {}
|
90 | }
|
91 | }
|
92 |
|
93 | exports.saveOptions = toSave => {
|
94 | const options = Object.assign(cloneDeep(exports.loadOptions()), toSave)
|
95 | for (const key in options) {
|
96 | if (!(key in exports.defaults)) {
|
97 | delete options[key]
|
98 | }
|
99 | }
|
100 | cachedOptions = options
|
101 | try {
|
102 | fs.writeFileSync(rcPath, JSON.stringify(options, null, 2))
|
103 | } catch (e) {
|
104 | error(
|
105 | `Error saving preferences: ` +
|
106 | `make sure you have write access to ${rcPath}.\n` +
|
107 | `(${e.message})`
|
108 | )
|
109 | }
|
110 | }
|
111 |
|
112 | exports.savePreset = (name, preset) => {
|
113 | const presets = cloneDeep(exports.loadOptions().presets || {})
|
114 | presets[name] = preset
|
115 | exports.saveOptions({ presets })
|
116 | }
|