1 | const path = require('path');
|
2 | const fs = require('fs-extra');
|
3 | const { getCwd, getExt, splitHubSpotPath, splitLocalPath } = require('./path');
|
4 | const { walk } = require('./lib/walk');
|
5 | const { MODULE_EXTENSION } = require('./lib/constants');
|
6 |
|
7 | const isBool = x => !!x === x;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | const isPathInput = pathInput => {
|
21 | return !!(
|
22 | pathInput &&
|
23 | typeof pathInput.path === 'string' &&
|
24 | (isBool(pathInput.isLocal) || isBool(pathInput.isHubSpot))
|
25 | );
|
26 | };
|
27 |
|
28 | const throwInvalidPathInput = pathInput => {
|
29 | if (isPathInput(pathInput)) return;
|
30 | throw new TypeError('Expected PathInput');
|
31 | };
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | const isModuleFolder = pathInput => {
|
38 | throwInvalidPathInput(pathInput);
|
39 | const _path = pathInput.isHubSpot
|
40 | ? path.posix.normalize(pathInput.path)
|
41 | : path.normalize(pathInput.path);
|
42 | return getExt(_path) === MODULE_EXTENSION;
|
43 | };
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | const isModuleFolderChild = pathInput => {
|
51 | throwInvalidPathInput(pathInput);
|
52 | let pathParts = [];
|
53 | if (pathInput.isLocal) {
|
54 | pathParts = splitLocalPath(pathInput.path);
|
55 | } else if (pathInput.isHubSpot) {
|
56 | pathParts = splitHubSpotPath(pathInput.path);
|
57 | }
|
58 | const { length } = pathParts;
|
59 |
|
60 | if (length <= 1) return false;
|
61 |
|
62 | return pathParts
|
63 | .slice(0, length - 1)
|
64 | .some(part => isModuleFolder({ ...pathInput, path: part }));
|
65 | };
|
66 |
|
67 |
|
68 | const ValidationIds = {
|
69 | SRC_REQUIRED: 'SRC_REQUIRED',
|
70 | DEST_REQUIRED: 'DEST_REQUIRED',
|
71 | MODULE_FOLDER_REQUIRED: 'MODULE_FOLDER_REQUIRED',
|
72 | MODULE_TO_MODULE_NESTING: 'MODULE_TO_MODULE_NESTING',
|
73 | MODULE_NESTING: 'MODULE_NESTING',
|
74 | };
|
75 |
|
76 | const getValidationResult = (id, message) => ({ id, message });
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | async function validateSrcAndDestPaths(src, dest) {
|
84 | const results = [];
|
85 | if (!isPathInput(src)) {
|
86 | results.push(
|
87 | getValidationResult(ValidationIds.SRC_REQUIRED, '`src` is required.')
|
88 | );
|
89 | }
|
90 | if (!isPathInput(dest)) {
|
91 | results.push(
|
92 | getValidationResult(ValidationIds.DEST_REQUIRED, '`dest` is required.')
|
93 | );
|
94 | }
|
95 | if (results.length) {
|
96 | return results;
|
97 | }
|
98 | const [_src, _dest] = [src, dest].map(inputPath => {
|
99 | const result = { ...inputPath };
|
100 | if (result.isLocal) {
|
101 | result.path = path.resolve(getCwd(), result.path);
|
102 | } else if (result.isHubSpot) {
|
103 | result.path = path.posix.normalize(result.path);
|
104 | }
|
105 | return result;
|
106 | });
|
107 |
|
108 |
|
109 | if (isModuleFolder(_src) && isModuleFolderChild(_dest)) {
|
110 | return results.concat(
|
111 | getValidationResult(
|
112 | ValidationIds.MODULE_TO_MODULE_NESTING,
|
113 | '`src` is a module path and `dest` is within a module.'
|
114 | )
|
115 | );
|
116 | }
|
117 |
|
118 |
|
119 | if (isModuleFolder(_src) && !isModuleFolder(_dest)) {
|
120 | return results.concat(
|
121 | getValidationResult(
|
122 | ValidationIds.MODULE_FOLDER_REQUIRED,
|
123 | '`src` is a module path but `dest` is not.'
|
124 | )
|
125 | );
|
126 | }
|
127 |
|
128 | if (_src.isLocal && isModuleFolderChild(_dest)) {
|
129 | const stat = await fs.stat(_src.path);
|
130 | if (stat.isDirectory()) {
|
131 | const files = await walk(_src.path);
|
132 | const srcHasModulesChildren = files.some(file =>
|
133 | isModuleFolderChild({ ..._src, path: file })
|
134 | );
|
135 | if (srcHasModulesChildren) {
|
136 | return results.concat(
|
137 | getValidationResult(
|
138 | ValidationIds.MODULE_NESTING,
|
139 | '`src` contains modules and `dest` is within a module.'
|
140 | )
|
141 | );
|
142 | }
|
143 | }
|
144 | }
|
145 |
|
146 | return results;
|
147 | }
|
148 |
|
149 | module.exports = {
|
150 | isModuleFolder,
|
151 | isModuleFolderChild,
|
152 | validateSrcAndDestPaths,
|
153 | ValidationIds,
|
154 | };
|