1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const core_1 = require("@angular-devkit/core");
|
4 | const fs_1 = require("fs");
|
5 | const command_1 = require("../models/command");
|
6 | const config_1 = require("../utilities/config");
|
7 | const SilentError = require('silent-error');
|
8 | const validCliPaths = new Map([
|
9 | ['cli.warnings.versionMismatch', 'boolean'],
|
10 | ['cli.warnings.typescriptMismatch', 'boolean'],
|
11 | ['cli.defaultCollection', 'string'],
|
12 | ['cli.packageManager', 'string'],
|
13 | ]);
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | function parseJsonPath(path) {
|
23 | const fragments = (path || '').split(/\./g);
|
24 | const result = [];
|
25 | while (fragments.length > 0) {
|
26 | const fragment = fragments.shift();
|
27 | const match = fragment.match(/([^\[]+)((\[.*\])*)/);
|
28 | if (!match) {
|
29 | throw new Error('Invalid JSON path.');
|
30 | }
|
31 | result.push(match[1]);
|
32 | if (match[2]) {
|
33 | const indices = match[2].slice(1, -1).split('][');
|
34 | result.push(...indices);
|
35 | }
|
36 | }
|
37 | return result.filter(fragment => !!fragment);
|
38 | }
|
39 | function getValueFromPath(root, path) {
|
40 | const fragments = parseJsonPath(path);
|
41 | try {
|
42 | return fragments.reduce((value, current) => {
|
43 | if (value == undefined || typeof value != 'object') {
|
44 | return undefined;
|
45 | }
|
46 | else if (typeof current == 'string' && !Array.isArray(value)) {
|
47 | return value[current];
|
48 | }
|
49 | else if (typeof current == 'number' && Array.isArray(value)) {
|
50 | return value[current];
|
51 | }
|
52 | else {
|
53 | return undefined;
|
54 | }
|
55 | }, root);
|
56 | }
|
57 | catch (_a) {
|
58 | return undefined;
|
59 | }
|
60 | }
|
61 | function setValueFromPath(root, path, newValue) {
|
62 | const fragments = parseJsonPath(path);
|
63 | try {
|
64 | return fragments.reduce((value, current, index) => {
|
65 | if (value == undefined || typeof value != 'object') {
|
66 | return undefined;
|
67 | }
|
68 | else if (typeof current == 'string' && !Array.isArray(value)) {
|
69 | if (index === fragments.length - 1) {
|
70 | value[current] = newValue;
|
71 | }
|
72 | else if (value[current] == undefined) {
|
73 | if (typeof fragments[index + 1] == 'number') {
|
74 | value[current] = [];
|
75 | }
|
76 | else if (typeof fragments[index + 1] == 'string') {
|
77 | value[current] = {};
|
78 | }
|
79 | }
|
80 | return value[current];
|
81 | }
|
82 | else if (typeof current == 'number' && Array.isArray(value)) {
|
83 | if (index === fragments.length - 1) {
|
84 | value[current] = newValue;
|
85 | }
|
86 | else if (value[current] == undefined) {
|
87 | if (typeof fragments[index + 1] == 'number') {
|
88 | value[current] = [];
|
89 | }
|
90 | else if (typeof fragments[index + 1] == 'string') {
|
91 | value[current] = {};
|
92 | }
|
93 | }
|
94 | return value[current];
|
95 | }
|
96 | else {
|
97 | return undefined;
|
98 | }
|
99 | }, root);
|
100 | }
|
101 | catch (_a) {
|
102 | return undefined;
|
103 | }
|
104 | }
|
105 | function normalizeValue(value, path) {
|
106 | const cliOptionType = validCliPaths.get(path);
|
107 | if (cliOptionType) {
|
108 | switch (cliOptionType) {
|
109 | case 'boolean':
|
110 | if (value.trim() === 'true') {
|
111 | return true;
|
112 | }
|
113 | else if (value.trim() === 'false') {
|
114 | return false;
|
115 | }
|
116 | break;
|
117 | case 'number':
|
118 | const numberValue = Number(value);
|
119 | if (!Number.isNaN(numberValue)) {
|
120 | return numberValue;
|
121 | }
|
122 | break;
|
123 | case 'string':
|
124 | return value;
|
125 | }
|
126 | throw new Error(`Invalid value type; expected a ${cliOptionType}.`);
|
127 | }
|
128 | if (typeof value === 'string') {
|
129 | try {
|
130 | return core_1.parseJson(value, core_1.JsonParseMode.Loose);
|
131 | }
|
132 | catch (e) {
|
133 | if (e instanceof core_1.InvalidJsonCharacterException && !value.startsWith('{')) {
|
134 | return value;
|
135 | }
|
136 | else {
|
137 | throw e;
|
138 | }
|
139 | }
|
140 | }
|
141 | return value;
|
142 | }
|
143 | class ConfigCommand extends command_1.Command {
|
144 | constructor() {
|
145 | super(...arguments);
|
146 | this.name = 'config';
|
147 | this.description = 'Get/set configuration values.';
|
148 | this.arguments = ['jsonPath', 'value'];
|
149 | this.options = [
|
150 | {
|
151 | name: 'global',
|
152 | type: Boolean,
|
153 | 'default': false,
|
154 | aliases: ['g'],
|
155 | description: 'Get/set the value in the global configuration (in your home directory).'
|
156 | }
|
157 | ];
|
158 | }
|
159 | run(options) {
|
160 | const level = options.global ? 'global' : 'local';
|
161 | let config = config_1.getWorkspace(level);
|
162 | if (options.global && !config) {
|
163 | try {
|
164 | if (config_1.migrateLegacyGlobalConfig()) {
|
165 | config =
|
166 | config_1.getWorkspace(level);
|
167 | this.logger.info(core_1.tags.oneLine `
|
168 | We found a global configuration that was used in Angular CLI 1.
|
169 | It has been automatically migrated.`);
|
170 | }
|
171 | }
|
172 | catch (_a) { }
|
173 | }
|
174 | if (options.value == undefined) {
|
175 | if (!config) {
|
176 | throw new SilentError('No config found.');
|
177 | }
|
178 | this.get(config._workspace, options);
|
179 | }
|
180 | else {
|
181 | this.set(options);
|
182 | }
|
183 | }
|
184 | get(config, options) {
|
185 | const value = options.jsonPath ? getValueFromPath(config, options.jsonPath) : config;
|
186 | if (value === undefined) {
|
187 | throw new SilentError('Value cannot be found.');
|
188 | }
|
189 | else if (typeof value == 'object') {
|
190 | this.logger.info(JSON.stringify(value, null, 2));
|
191 | }
|
192 | else {
|
193 | this.logger.info(value.toString());
|
194 | }
|
195 | }
|
196 | set(options) {
|
197 | if (!options.jsonPath || !options.jsonPath.trim()) {
|
198 | throw new Error('Invalid Path.');
|
199 | }
|
200 | if (options.global
|
201 | && !options.jsonPath.startsWith('schematics.')
|
202 | && !validCliPaths.has(options.jsonPath)) {
|
203 | throw new Error('Invalid Path.');
|
204 | }
|
205 | const [config, configPath] = config_1.getWorkspaceRaw(options.global ? 'global' : 'local');
|
206 |
|
207 | const configValue = config.value;
|
208 | const value = normalizeValue(options.value, options.jsonPath);
|
209 | const result = setValueFromPath(configValue, options.jsonPath, value);
|
210 | if (result === undefined) {
|
211 | throw new SilentError('Value cannot be found.');
|
212 | }
|
213 | try {
|
214 | config_1.validateWorkspace(configValue);
|
215 | }
|
216 | catch (error) {
|
217 | this.logger.error(error.message);
|
218 | throw new SilentError();
|
219 | }
|
220 | const output = JSON.stringify(configValue, null, 2);
|
221 | fs_1.writeFileSync(configPath, output);
|
222 | }
|
223 | }
|
224 | exports.default = ConfigCommand;
|
225 |
|
\ | No newline at end of file |