1 |
|
2 |
|
3 |
|
4 | 'use strict';
|
5 |
|
6 | const chalk = require('chalk');
|
7 | const glob = require('glob');
|
8 | const flatten = require('lodash.flatten');
|
9 | const map = require('lodash.map');
|
10 | const property = require('lodash.property');
|
11 | const uniq = require('lodash.uniq');
|
12 | const emoji = require('node-emoji');
|
13 | const os = require('os');
|
14 | const fss = require('@absolunet/fss');
|
15 | const { terminal } = require('@absolunet/terminal');
|
16 | const paths = require('~/helpers/paths');
|
17 |
|
18 |
|
19 | const NAME = 'nwayo';
|
20 |
|
21 |
|
22 | const WORKFLOW_PACKAGE = fss.readJson(paths.config.workflowPackage);
|
23 | const PACKAGE = fss.readJson(paths.config.projectPackage);
|
24 | const CONFIG = fss.readYaml(paths.config.main);
|
25 |
|
26 | const EXTENSIONS = (() => {
|
27 | const enabled = {};
|
28 | const prefix = `${NAME}-extension-`;
|
29 |
|
30 | Object.keys(CONFIG.extensions || {}).forEach((name) => {
|
31 | if (CONFIG.extensions[name].enabled === true) {
|
32 | let normalizedName = '';
|
33 |
|
34 | const scopedMatch = (/^(?<kebab1>@[a-z0-9-]+\/)(?<kebab2>[a-z0-9-]+)$/u).exec(name);
|
35 | if (scopedMatch !== null) {
|
36 | normalizedName = `${scopedMatch[1]}${prefix}${scopedMatch[2]}`;
|
37 | } else {
|
38 | const namedMatch = (/^[a-z0-9-]+$/u).exec(name);
|
39 | if (namedMatch !== null) {
|
40 | normalizedName = `${prefix}${name}`;
|
41 | } else {
|
42 | normalizedName = name;
|
43 | }
|
44 | }
|
45 |
|
46 | let extension;
|
47 | try {
|
48 | extension = require(normalizedName);
|
49 | } catch (error) {
|
50 | terminal.exit(`Extension '${name}' not found`);
|
51 | }
|
52 |
|
53 | extension.init({ options: CONFIG.extensions[name].options });
|
54 |
|
55 | enabled[extension.id] = extension;
|
56 | }
|
57 | });
|
58 |
|
59 | return enabled;
|
60 | })();
|
61 |
|
62 |
|
63 | const deployTier = {
|
64 | local: Symbol('local'),
|
65 | production: Symbol('production')
|
66 | };
|
67 |
|
68 | const __ = {
|
69 | watching: false,
|
70 | deployTier: deployTier.local
|
71 | };
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | class Env {
|
79 |
|
80 | get packageConfig() { return PACKAGE; }
|
81 | get workflowConfig() { return WORKFLOW_PACKAGE; }
|
82 | get konstan() { return __.konstan; }
|
83 | get bundles() { return __.bundles; }
|
84 | get bundlesComponents() { return __.bundlesComponents; }
|
85 | get isScopeSubbundle() { return __.scope === 'subbundle'; }
|
86 | get watching() { return __.watching; }
|
87 | get deployTier() { return __.deployTier; }
|
88 | get isWindows() { return os.platform() === 'win32'; }
|
89 |
|
90 |
|
91 |
|
92 | get logo() {
|
93 | return emoji.get('chestnut');
|
94 | }
|
95 |
|
96 |
|
97 |
|
98 | get id() {
|
99 | return NAME;
|
100 | }
|
101 |
|
102 |
|
103 |
|
104 | get packageName() {
|
105 | return WORKFLOW_PACKAGE.name;
|
106 | }
|
107 |
|
108 |
|
109 |
|
110 | get production() {
|
111 | return __.deployTier === deployTier.production;
|
112 | }
|
113 |
|
114 |
|
115 | get configRaw() {
|
116 | return CONFIG;
|
117 | }
|
118 |
|
119 |
|
120 | get extensions() {
|
121 | return EXTENSIONS;
|
122 | }
|
123 |
|
124 |
|
125 | setToProduction() {
|
126 | __.deployTier = deployTier.production;
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 | setToWatching() {
|
132 | __.watching = true;
|
133 | }
|
134 |
|
135 |
|
136 |
|
137 | initWorkflow({ bundle = '*' }) {
|
138 |
|
139 |
|
140 | __.konstan = fss.readYaml(paths.config.konstan);
|
141 |
|
142 |
|
143 |
|
144 | const [requiredName, requiredSubname = '*'] = bundle.split(':');
|
145 | if (requiredName === '*') {
|
146 | __.scope = 'all';
|
147 | } else if (requiredSubname === '*') {
|
148 | __.scope = 'bundle';
|
149 | } else {
|
150 | __.scope = 'subbundle';
|
151 | }
|
152 |
|
153 | const bundlesList = glob.sync(`${paths.directory.bundles}/${requiredName}/`);
|
154 |
|
155 |
|
156 | const data = {};
|
157 | if (bundlesList.length !== 0) {
|
158 |
|
159 | for (const folder of bundlesList) {
|
160 | const [, name] = folder.match(/\/(?<alphanum>[0-9a-zA-Z-]+)\/$/u);
|
161 | data[name] = fss.readYaml(`${folder}/${name}.${paths.extension.bundles}`);
|
162 |
|
163 | if (!data[name].assets) {
|
164 | data[name].assets = {};
|
165 | }
|
166 |
|
167 | if (!data[name].assets.components) {
|
168 | data[name].assets.components = [];
|
169 | }
|
170 |
|
171 | if (!data[name].scripts.collections) {
|
172 | data[name].scripts.collections = {};
|
173 | }
|
174 |
|
175 | if (!data[name].styles.collections) {
|
176 | data[name].styles.collections = {};
|
177 | }
|
178 |
|
179 | const subBundlesList = glob.sync(`${paths.directory.bundles}/${name}/_${requiredSubname}.${paths.extension.bundles}`);
|
180 | if (subBundlesList.length !== 0) {
|
181 | for (const subBundleFile of subBundlesList) {
|
182 |
|
183 | const subBundleData = fss.readYaml(subBundleFile);
|
184 | if (subBundleData.assets && subBundleData.assets.components) {
|
185 | data[name].assets.components = [...new Set([...data[name].assets.components, ...subBundleData.assets.components])];
|
186 | }
|
187 |
|
188 | if (subBundleData.scripts && subBundleData.scripts.collections) {
|
189 | Object.assign(data[name].scripts.collections, subBundleData.scripts.collections);
|
190 | }
|
191 |
|
192 | if (subBundleData.styles && subBundleData.styles.collections) {
|
193 | Object.assign(data[name].styles.collections, subBundleData.styles.collections);
|
194 | }
|
195 | }
|
196 |
|
197 | } else if (requiredSubname !== '*') {
|
198 | terminal.exit(`Bundle ${chalk.underline(bundle)} does not exists`);
|
199 | }
|
200 | }
|
201 | } else {
|
202 | terminal.exit(`${requiredName !== '*' ? `Bundle ${chalk.underline(bundle)} does not exists` : `No bundle found`}`);
|
203 | }
|
204 |
|
205 | __.bundles = data;
|
206 | __.bundlesComponents = uniq(flatten(map(__.bundles, property('assets.components'))));
|
207 | }
|
208 |
|
209 | }
|
210 |
|
211 |
|
212 | module.exports = new Env();
|