@hubspot/local-dev-lib 0.0.11 → 0.1.0-experimental.0
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.
- package/LICENSE +12 -0
- package/README.md +17 -0
- package/api/appsDev.d.ts +6 -0
- package/api/appsDev.js +29 -0
- package/api/customObjects.d.ts +8 -7
- package/api/customObjects.js +13 -16
- package/api/designManager.d.ts +5 -13
- package/api/designManager.js +6 -9
- package/api/developerTestAccounts.d.ts +7 -0
- package/api/developerTestAccounts.js +48 -0
- package/api/fileManager.d.ts +6 -5
- package/api/fileManager.js +13 -12
- package/api/fileMapper.d.ts +8 -8
- package/api/fileMapper.js +19 -18
- package/api/fileTransport.d.ts +4 -0
- package/api/fileTransport.js +39 -0
- package/api/functions.d.ts +7 -3
- package/api/functions.js +22 -11
- package/api/github.d.ts +11 -0
- package/api/github.js +71 -0
- package/api/hubdb.d.ts +11 -9
- package/api/hubdb.js +28 -22
- package/api/lighthouseScore.d.ts +4 -3
- package/api/lighthouseScore.js +9 -12
- package/api/localDevAuth.d.ts +7 -15
- package/api/localDevAuth.js +28 -13
- package/api/marketplaceValidation.d.ts +4 -3
- package/api/marketplaceValidation.js +8 -11
- package/api/projects.d.ts +34 -21
- package/api/projects.js +135 -45
- package/api/sandboxHubs.d.ts +5 -4
- package/api/sandboxHubs.js +10 -11
- package/api/sandboxSync.d.ts +4 -4
- package/api/sandboxSync.js +5 -14
- package/api/secrets.d.ts +6 -8
- package/api/secrets.js +9 -12
- package/api/validateHubl.d.ts +2 -1
- package/api/validateHubl.js +3 -6
- package/config/CLIConfiguration.d.ts +13 -10
- package/config/CLIConfiguration.js +129 -77
- package/config/configFile.js +12 -18
- package/config/configUtils.d.ts +2 -21
- package/config/configUtils.js +5 -4
- package/config/config_DEPRECATED.d.ts +6 -8
- package/config/config_DEPRECATED.js +73 -24
- package/config/environment.js +5 -4
- package/config/getAccountIdentifier.d.ts +2 -0
- package/config/getAccountIdentifier.js +15 -0
- package/config/index.d.ts +10 -7
- package/config/index.js +83 -55
- package/constants/api.d.ts +10 -12
- package/constants/api.js +10 -12
- package/constants/config.d.ts +15 -1
- package/constants/config.js +17 -3
- package/constants/environments.d.ts +1 -0
- package/constants/environments.js +1 -0
- package/constants/extensions.d.ts +2 -0
- package/constants/extensions.js +3 -1
- package/constants/files.d.ts +2 -2
- package/constants/files.js +3 -3
- package/errors/errors_DEPRECATED.d.ts +1 -5
- package/errors/errors_DEPRECATED.js +3 -16
- package/errors/index.d.ts +18 -0
- package/errors/index.js +63 -0
- package/http/addQueryParams.d.ts +2 -0
- package/http/addQueryParams.js +14 -0
- package/http/getAxiosConfig.d.ts +6 -3
- package/http/getAxiosConfig.js +51 -7
- package/http/index.d.ts +10 -11
- package/http/index.js +35 -41
- package/http/unauthed.d.ts +15 -0
- package/http/unauthed.js +38 -0
- package/lang/en.json +374 -368
- package/lib/archive.d.ts +2 -8
- package/lib/archive.js +34 -30
- package/lib/cms/functions.d.ts +7 -12
- package/lib/cms/functions.js +47 -50
- package/lib/cms/handleFieldsJS.js +16 -14
- package/lib/cms/modules.d.ts +5 -15
- package/lib/cms/modules.js +100 -39
- package/lib/cms/processFieldsJs.js +10 -33
- package/lib/cms/templates.d.ts +43 -3
- package/lib/cms/templates.js +51 -11
- package/lib/cms/uploadFolder.d.ts +3 -14
- package/lib/cms/uploadFolder.js +58 -42
- package/lib/{validate.d.ts → cms/validate.d.ts} +1 -1
- package/lib/{validate.js → cms/validate.js} +5 -5
- package/lib/cms/watch.d.ts +2 -18
- package/lib/cms/watch.js +63 -68
- package/lib/customObjects.js +4 -15
- package/lib/fileManager.d.ts +2 -0
- package/lib/fileManager.js +184 -0
- package/lib/fileMapper.d.ts +4 -15
- package/lib/fileMapper.js +68 -89
- package/lib/fs.js +2 -2
- package/lib/github.d.ts +6 -18
- package/lib/github.js +97 -76
- package/lib/gitignore.d.ts +2 -0
- package/lib/gitignore.js +21 -4
- package/lib/hubdb.d.ts +3 -2
- package/lib/hubdb.js +11 -9
- package/lib/{logging/logger.d.ts → logger.d.ts} +20 -8
- package/{utils → lib}/notify.js +2 -2
- package/lib/oauth.d.ts +2 -5
- package/lib/oauth.js +14 -25
- package/lib/path.d.ts +3 -0
- package/lib/path.js +46 -1
- package/lib/personalAccessKey.d.ts +7 -10
- package/lib/personalAccessKey.js +75 -48
- package/lib/portManager.d.ts +3 -5
- package/lib/portManager.js +18 -6
- package/lib/text.d.ts +1 -0
- package/lib/text.js +9 -1
- package/lib/trackUsage.js +18 -11
- package/lib/urls.js +5 -1
- package/models/FileSystemError.d.ts +6 -0
- package/models/FileSystemError.js +47 -0
- package/models/HubSpotHttpError.d.ts +24 -0
- package/models/HubSpotHttpError.js +197 -0
- package/models/OAuth2Manager.d.ts +5 -27
- package/models/OAuth2Manager.js +41 -64
- package/package.json +19 -18
- package/types/Accounts.d.ts +86 -3
- package/types/Apps.d.ts +77 -0
- package/types/Archive.d.ts +9 -0
- package/types/Archive.js +2 -0
- package/types/ComponentStructure.d.ts +30 -10
- package/types/Config.d.ts +19 -2
- package/types/DesignManager.d.ts +10 -0
- package/types/DesignManager.js +2 -0
- package/types/Error.d.ts +12 -34
- package/types/FieldsJS.d.ts +1 -0
- package/types/FieldsJS.js +2 -0
- package/types/FileManager.d.ts +12 -7
- package/types/Files.d.ts +43 -4
- package/types/Functions.d.ts +26 -0
- package/types/Github.d.ts +12 -0
- package/types/Http.d.ts +11 -12
- package/types/Hubdb.d.ts +9 -0
- package/types/Lang.d.ts +3 -0
- package/types/Migration.d.ts +28 -0
- package/types/Migration.js +10 -0
- package/types/Modules.d.ts +11 -0
- package/types/PortManager.d.ts +7 -0
- package/types/Project.d.ts +4 -0
- package/types/ProjectLog.d.ts +9 -0
- package/types/ProjectLog.js +2 -0
- package/types/Sandbox.d.ts +37 -47
- package/types/Schemas.d.ts +12 -0
- package/types/Secrets.d.ts +3 -0
- package/types/Secrets.js +2 -0
- package/types/developerTestAccounts.d.ts +12 -0
- package/types/developerTestAccounts.js +2 -0
- package/utils/PortManagerServer.d.ts +6 -7
- package/utils/PortManagerServer.js +24 -18
- package/utils/{getAccountIdentifier.d.ts → accounts.d.ts} +0 -6
- package/utils/{getAccountIdentifier.js → accounts.js} +1 -13
- package/utils/cms/fieldsJS.d.ts +1 -2
- package/utils/cms/modules.js +2 -2
- package/utils/detectPort.js +3 -3
- package/utils/git.d.ts +1 -7
- package/utils/git.js +2 -18
- package/utils/lang.d.ts +1 -5
- package/constants/github.d.ts +0 -4
- package/constants/github.js +0 -7
- package/errors/apiErrors.d.ts +0 -23
- package/errors/apiErrors.js +0 -197
- package/errors/fileSystemErrors.d.ts +0 -5
- package/errors/fileSystemErrors.js +0 -31
- package/errors/standardErrors.d.ts +0 -26
- package/errors/standardErrors.js +0 -64
- package/lang/lang/en.json +0 -383
- package/lib/logging/git.d.ts +0 -2
- package/lib/logging/git.js +0 -54
- package/lib/logging/logs.d.ts +0 -22
- package/lib/logging/logs.js +0 -86
- package/lib/logging/table.d.ts +0 -3
- package/lib/logging/table.js +0 -47
- package/lib/sandboxes.d.ts +0 -14
- package/lib/sandboxes.js +0 -71
- package/models/HubSpotAuthError.d.ts +0 -9
- package/models/HubSpotAuthError.js +0 -20
- package/types/LogCallbacks.d.ts +0 -6
- package/utils/logger.d.ts +0 -11
- package/utils/logger.js +0 -23
- package/utils/objectUtils.d.ts +0 -8
- package/utils/objectUtils.js +0 -33
- /package/{utils → lib}/escapeRegExp.d.ts +0 -0
- /package/{utils → lib}/escapeRegExp.js +0 -0
- /package/lib/{logging/logger.js → logger.js} +0 -0
- /package/{utils → lib}/notify.d.ts +0 -0
- /package/types/{LogCallbacks.js → Apps.js} +0 -0
package/lib/fileMapper.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// FILE MAPPER - not to be confused with fileManager.ts
|
|
2
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
5
|
};
|
|
@@ -8,13 +9,13 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
9
10
|
const p_queue_1 = __importDefault(require("p-queue"));
|
|
10
11
|
const path_2 = require("./path");
|
|
12
|
+
const logger_1 = require("./logger");
|
|
11
13
|
const fileMapper_1 = require("../api/fileMapper");
|
|
12
|
-
const standardErrors_1 = require("../errors/standardErrors");
|
|
13
14
|
const extensions_1 = require("../constants/extensions");
|
|
14
15
|
const files_1 = require("../constants/files");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const errors_1 = require("../errors");
|
|
17
|
+
const lang_1 = require("../utils/lang");
|
|
18
|
+
const FileSystemError_1 = require("../models/FileSystemError");
|
|
18
19
|
const i18nKey = 'lib.fileMapper';
|
|
19
20
|
const queue = new p_queue_1.default({
|
|
20
21
|
concurrency: 10,
|
|
@@ -42,14 +43,14 @@ function isPathToHubspot(filepath) {
|
|
|
42
43
|
return /^(\/|\\)?@hubspot/i.test(filepath.trim());
|
|
43
44
|
}
|
|
44
45
|
exports.isPathToHubspot = isPathToHubspot;
|
|
45
|
-
function useApiBuffer(
|
|
46
|
-
return
|
|
46
|
+
function useApiBuffer(cmsPublishMode) {
|
|
47
|
+
return cmsPublishMode === files_1.CMS_PUBLISH_MODE.draft;
|
|
47
48
|
}
|
|
48
|
-
// Determines API param based on mode
|
|
49
|
-
function getFileMapperQueryValues(
|
|
49
|
+
// Determines API param based on publish mode and options
|
|
50
|
+
function getFileMapperQueryValues(cmsPublishMode, { staging, assetVersion } = {}) {
|
|
50
51
|
return {
|
|
51
52
|
params: {
|
|
52
|
-
buffer: useApiBuffer(
|
|
53
|
+
buffer: useApiBuffer(cmsPublishMode),
|
|
53
54
|
environmentId: staging ? 2 : 1,
|
|
54
55
|
version: assetVersion,
|
|
55
56
|
},
|
|
@@ -75,9 +76,9 @@ function validateFileMapperNode(node) {
|
|
|
75
76
|
catch (err) {
|
|
76
77
|
json = node;
|
|
77
78
|
}
|
|
78
|
-
(0,
|
|
79
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidNode`, {
|
|
79
80
|
json: JSON.stringify(json),
|
|
80
|
-
});
|
|
81
|
+
}));
|
|
81
82
|
}
|
|
82
83
|
function getTypeDataFromPath(src) {
|
|
83
84
|
const isModule = isPathToModule(src);
|
|
@@ -123,10 +124,10 @@ async function writeUtimes(accountId, filepath, node) {
|
|
|
123
124
|
await fs_extra_1.default.utimes(filepath, atime, mtime);
|
|
124
125
|
}
|
|
125
126
|
catch (err) {
|
|
126
|
-
|
|
127
|
+
throw new FileSystemError_1.FileSystemError({ cause: err }, {
|
|
127
128
|
filepath,
|
|
128
129
|
accountId,
|
|
129
|
-
|
|
130
|
+
operation: 'write',
|
|
130
131
|
});
|
|
131
132
|
}
|
|
132
133
|
}
|
|
@@ -140,45 +141,33 @@ async function skipExisting(filepath, overwrite = false) {
|
|
|
140
141
|
}
|
|
141
142
|
return false;
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
-
async function fetchAndWriteFileStream(accountId, srcPath, filepath, mode, options = {}, logCallbacks) {
|
|
145
|
-
const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
|
|
144
|
+
async function fetchAndWriteFileStream(accountId, srcPath, filepath, cmsPublishMode, options = {}) {
|
|
146
145
|
if (typeof srcPath !== 'string' || !srcPath.trim()) {
|
|
147
146
|
return;
|
|
148
147
|
}
|
|
149
148
|
if (await skipExisting(filepath, options.overwrite)) {
|
|
150
|
-
logger(
|
|
149
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, { filepath }));
|
|
151
150
|
return;
|
|
152
151
|
}
|
|
153
|
-
if (!(0, path_2.isAllowedExtension)(srcPath)) {
|
|
154
|
-
(0,
|
|
155
|
-
}
|
|
156
|
-
let node;
|
|
157
|
-
try {
|
|
158
|
-
node = await (0, fileMapper_1.fetchFileStream)(accountId, srcPath, filepath, getFileMapperQueryValues(mode, options));
|
|
159
|
-
}
|
|
160
|
-
catch (err) {
|
|
161
|
-
(0, apiErrors_1.throwStatusCodeError)(err, {
|
|
162
|
-
accountId,
|
|
163
|
-
request: srcPath,
|
|
164
|
-
});
|
|
152
|
+
if (!(0, path_2.isAllowedExtension)(srcPath, Array.from(extensions_1.JSR_ALLOWED_EXTENSIONS))) {
|
|
153
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidFileType`, { srcPath }));
|
|
165
154
|
}
|
|
155
|
+
const node = await (0, fileMapper_1.fetchFileStream)(accountId, srcPath, filepath, getFileMapperQueryValues(cmsPublishMode, options));
|
|
166
156
|
await writeUtimes(accountId, filepath, node);
|
|
167
157
|
}
|
|
168
158
|
// Writes an individual file or folder (not recursive). If file source is missing, the
|
|
169
159
|
//file is fetched.
|
|
170
|
-
async function writeFileMapperNode(accountId, filepath, node,
|
|
171
|
-
const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
|
|
160
|
+
async function writeFileMapperNode(accountId, filepath, node, cmsPublishMode, options = {}) {
|
|
172
161
|
const localFilepath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve(filepath));
|
|
173
162
|
if (await skipExisting(localFilepath, options.overwrite)) {
|
|
174
|
-
logger(
|
|
163
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, {
|
|
175
164
|
filepath: localFilepath,
|
|
176
|
-
});
|
|
165
|
+
}));
|
|
177
166
|
return true;
|
|
178
167
|
}
|
|
179
168
|
if (!node.folder) {
|
|
180
169
|
try {
|
|
181
|
-
await fetchAndWriteFileStream(accountId, node.path, localFilepath,
|
|
170
|
+
await fetchAndWriteFileStream(accountId, node.path, localFilepath, cmsPublishMode, options);
|
|
182
171
|
return true;
|
|
183
172
|
}
|
|
184
173
|
catch (err) {
|
|
@@ -187,30 +176,25 @@ async function writeFileMapperNode(accountId, filepath, node, mode, options = {}
|
|
|
187
176
|
}
|
|
188
177
|
try {
|
|
189
178
|
await fs_extra_1.default.ensureDir(localFilepath);
|
|
190
|
-
logger(
|
|
179
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.wroteFolder`, {
|
|
191
180
|
filepath: localFilepath,
|
|
192
|
-
});
|
|
181
|
+
}));
|
|
193
182
|
}
|
|
194
183
|
catch (err) {
|
|
195
|
-
|
|
184
|
+
throw new FileSystemError_1.FileSystemError({ cause: err }, {
|
|
196
185
|
filepath: localFilepath,
|
|
197
186
|
accountId,
|
|
198
|
-
|
|
187
|
+
operation: 'write',
|
|
199
188
|
});
|
|
200
|
-
return false;
|
|
201
189
|
}
|
|
202
190
|
return true;
|
|
203
191
|
}
|
|
204
|
-
function
|
|
205
|
-
return !!err && (err.status === 408 || err.code === 'ESOCKETTIMEDOUT');
|
|
206
|
-
}
|
|
207
|
-
async function downloadFile(accountId, src, destPath, mode, options = {}, logCallbacks) {
|
|
208
|
-
const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
|
|
192
|
+
async function downloadFile(accountId, src, destPath, cmsPublishMode, options = {}) {
|
|
209
193
|
const { isFile, isHubspot } = getTypeDataFromPath(src);
|
|
194
|
+
if (!isFile) {
|
|
195
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidRequest`, { src }));
|
|
196
|
+
}
|
|
210
197
|
try {
|
|
211
|
-
if (!isFile) {
|
|
212
|
-
(0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.invalidRequest`, { src });
|
|
213
|
-
}
|
|
214
198
|
const dest = path_1.default.resolve(destPath);
|
|
215
199
|
const cwd = (0, path_2.getCwd)();
|
|
216
200
|
let filepath;
|
|
@@ -230,59 +214,43 @@ async function downloadFile(accountId, src, destPath, mode, options = {}, logCal
|
|
|
230
214
|
: path_1.default.resolve(cwd, dest, name);
|
|
231
215
|
}
|
|
232
216
|
const localFsPath = (0, path_2.convertToLocalFileSystemPath)(filepath);
|
|
233
|
-
await fetchAndWriteFileStream(accountId, src, localFsPath,
|
|
217
|
+
await fetchAndWriteFileStream(accountId, src, localFsPath, cmsPublishMode, options);
|
|
234
218
|
await queue.onIdle();
|
|
235
|
-
logger(
|
|
219
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.completedFetch`, {
|
|
236
220
|
src,
|
|
237
221
|
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
238
222
|
dest,
|
|
239
|
-
});
|
|
223
|
+
}));
|
|
240
224
|
}
|
|
241
225
|
catch (err) {
|
|
242
226
|
const error = err;
|
|
243
|
-
if (isHubspot &&
|
|
244
|
-
(0,
|
|
227
|
+
if (isHubspot && (0, errors_1.isTimeoutError)(error)) {
|
|
228
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
245
229
|
}
|
|
246
230
|
else {
|
|
247
|
-
(0,
|
|
231
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFile`, { src, dest: destPath }), { cause: error });
|
|
248
232
|
}
|
|
249
233
|
}
|
|
250
234
|
}
|
|
251
|
-
async function fetchFolderFromApi(accountId, src,
|
|
252
|
-
const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
|
|
235
|
+
async function fetchFolderFromApi(accountId, src, cmsPublishMode, options = {}) {
|
|
253
236
|
const { isRoot, isFolder, isHubspot } = getTypeDataFromPath(src);
|
|
254
237
|
if (!isFolder) {
|
|
255
|
-
(0,
|
|
238
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidFetchFolderRequest`, {
|
|
256
239
|
src,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
try {
|
|
260
|
-
const srcPath = isRoot ? '@root' : src;
|
|
261
|
-
const queryValues = getFileMapperQueryValues(mode, options);
|
|
262
|
-
const node = isHubspot
|
|
263
|
-
? await (0, fileMapper_1.downloadDefault)(accountId, srcPath, queryValues)
|
|
264
|
-
: await (0, fileMapper_1.download)(accountId, srcPath, queryValues);
|
|
265
|
-
logger('folderFetch', `${i18nKey}.folderFetch`, { src, accountId });
|
|
266
|
-
return node;
|
|
267
|
-
}
|
|
268
|
-
catch (err) {
|
|
269
|
-
const error = err;
|
|
270
|
-
if (isHubspot && isTimeout(error)) {
|
|
271
|
-
(0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.assetTimeout`, {}, error);
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
(0, apiErrors_1.throwStatusCodeError)(error, {
|
|
275
|
-
accountId,
|
|
276
|
-
request: src,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
240
|
+
}));
|
|
279
241
|
}
|
|
242
|
+
const srcPath = isRoot ? '@root' : src;
|
|
243
|
+
const queryValues = getFileMapperQueryValues(cmsPublishMode, options);
|
|
244
|
+
const { data: node } = isHubspot
|
|
245
|
+
? await (0, fileMapper_1.downloadDefault)(accountId, srcPath, queryValues)
|
|
246
|
+
: await (0, fileMapper_1.download)(accountId, srcPath, queryValues);
|
|
247
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.folderFetch`, { src, accountId }));
|
|
248
|
+
return node;
|
|
280
249
|
}
|
|
281
250
|
exports.fetchFolderFromApi = fetchFolderFromApi;
|
|
282
|
-
async function downloadFolder(accountId, src, destPath,
|
|
283
|
-
const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
|
|
251
|
+
async function downloadFolder(accountId, src, destPath, cmsPublishMode, options = {}) {
|
|
284
252
|
try {
|
|
285
|
-
const node = await fetchFolderFromApi(accountId, src,
|
|
253
|
+
const node = await fetchFolderFromApi(accountId, src, cmsPublishMode, options);
|
|
286
254
|
if (!node) {
|
|
287
255
|
return;
|
|
288
256
|
}
|
|
@@ -293,27 +261,38 @@ async function downloadFolder(accountId, src, destPath, mode, options = {}, logC
|
|
|
293
261
|
let success = true;
|
|
294
262
|
recurseFolder(node, (childNode, filepath) => {
|
|
295
263
|
queue.add(async () => {
|
|
296
|
-
const succeeded = await writeFileMapperNode(accountId, filepath || '', childNode,
|
|
264
|
+
const succeeded = await writeFileMapperNode(accountId, filepath || '', childNode, cmsPublishMode, options);
|
|
297
265
|
if (succeeded === false) {
|
|
298
266
|
success = false;
|
|
267
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFile`, {
|
|
268
|
+
src: childNode.path,
|
|
269
|
+
dest: filepath || '',
|
|
270
|
+
}));
|
|
299
271
|
}
|
|
300
272
|
});
|
|
301
273
|
return success;
|
|
302
274
|
}, rootPath);
|
|
303
275
|
await queue.onIdle();
|
|
304
276
|
if (success) {
|
|
305
|
-
logger(
|
|
277
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.completedFolderFetch`, {
|
|
306
278
|
src,
|
|
307
279
|
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
308
280
|
dest,
|
|
309
|
-
});
|
|
281
|
+
}));
|
|
310
282
|
}
|
|
311
283
|
else {
|
|
312
|
-
|
|
284
|
+
// TODO: Fix this exception. It is triggering the catch block so this error is being rewritten
|
|
285
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.incompleteFetch`, { src }));
|
|
313
286
|
}
|
|
314
287
|
}
|
|
315
288
|
catch (err) {
|
|
316
|
-
|
|
289
|
+
const error = err;
|
|
290
|
+
if ((0, errors_1.isTimeoutError)(error)) {
|
|
291
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFolder`, { src, dest: destPath }), { cause: err });
|
|
295
|
+
}
|
|
317
296
|
}
|
|
318
297
|
}
|
|
319
298
|
/**
|
|
@@ -323,16 +302,16 @@ async function downloadFolder(accountId, src, destPath, mode, options = {}, logC
|
|
|
323
302
|
* @param {FileMapperInputArguments} input
|
|
324
303
|
* @returns {Promise}
|
|
325
304
|
*/
|
|
326
|
-
async function downloadFileOrFolder(accountId, src, dest,
|
|
305
|
+
async function downloadFileOrFolder(accountId, src, dest, cmsPublishMode, options = {}) {
|
|
327
306
|
if (!src) {
|
|
328
307
|
return;
|
|
329
308
|
}
|
|
330
309
|
const { isFile } = getTypeDataFromPath(src);
|
|
331
310
|
if (isFile) {
|
|
332
|
-
await downloadFile(accountId, src, dest,
|
|
311
|
+
await downloadFile(accountId, src, dest, cmsPublishMode, options);
|
|
333
312
|
}
|
|
334
313
|
else {
|
|
335
|
-
await downloadFolder(accountId, src, dest,
|
|
314
|
+
await downloadFolder(accountId, src, dest, cmsPublishMode, options);
|
|
336
315
|
}
|
|
337
316
|
}
|
|
338
317
|
exports.downloadFileOrFolder = downloadFileOrFolder;
|
package/lib/fs.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.walk = exports.flattenAndRemoveSymlinks = exports.getFileInfoAsync = voi
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const files_1 = require("../constants/files");
|
|
10
|
-
const
|
|
10
|
+
const FileSystemError_1 = require("../models/FileSystemError");
|
|
11
11
|
function getFileInfoAsync(dir, file) {
|
|
12
12
|
return new Promise((resolve, reject) => {
|
|
13
13
|
const filepath = path_1.default.join(dir, file);
|
|
@@ -65,7 +65,7 @@ async function walk(dir) {
|
|
|
65
65
|
.then(processFiles)
|
|
66
66
|
.then(flattenAndRemoveSymlinks)
|
|
67
67
|
.catch(err => {
|
|
68
|
-
|
|
68
|
+
throw new FileSystemError_1.FileSystemError({ cause: err });
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
exports.walk = walk;
|
package/lib/github.d.ts
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import { GithubReleaseData } from '../types/Github';
|
|
3
|
-
|
|
4
|
-
import { LogCallbacksArg } from '../types/LogCallbacks';
|
|
5
|
-
declare global {
|
|
6
|
-
var githubToken: string;
|
|
7
|
-
}
|
|
8
|
-
type RepoPath = `${string}/${string}`;
|
|
9
|
-
export declare function fetchJsonFromRepository(repoPath: RepoPath, filePath: string, ref: string): Promise<JSON>;
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { GithubReleaseData, GithubRepoFile, RepoPath, CloneGithubRepoOptions } from '../types/Github';
|
|
3
|
+
export declare function fetchFileFromRepository(repoPath: RepoPath, filePath: string, ref: string): Promise<Buffer>;
|
|
10
4
|
export declare function fetchReleaseData(repoPath: RepoPath, tag?: string): Promise<GithubReleaseData>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
projectVersion?: string;
|
|
14
|
-
releaseType?: ValueOf<typeof GITHUB_RELEASE_TYPES>;
|
|
15
|
-
ref?: string;
|
|
16
|
-
};
|
|
17
|
-
declare const cloneGithubRepoCallbackKeys: string[];
|
|
18
|
-
export declare function cloneGithubRepo(dest: string, type: string, repoPath: RepoPath, sourceDir: string, options?: CloneGithubRepoOptions, logCallbacks?: LogCallbacksArg<typeof cloneGithubRepoCallbackKeys>): Promise<boolean>;
|
|
5
|
+
export declare function cloneGithubRepo(repoPath: RepoPath, dest: string, options?: CloneGithubRepoOptions): Promise<boolean>;
|
|
6
|
+
export declare function fetchGitHubRepoContentFromDownloadUrl(dest: string, downloadUrl: string): Promise<void>;
|
|
19
7
|
export declare function downloadGithubRepoContents(repoPath: RepoPath, contentPath: string, dest: string, ref?: string, filter?: (contentPiecePath: string, downloadPath: string) => boolean): Promise<void>;
|
|
20
|
-
export
|
|
8
|
+
export declare function listGithubRepoContents(repoPath: RepoPath, contentPath: string, fileFilter?: 'file' | 'dir'): Promise<GithubRepoFile[]>;
|
package/lib/github.js
CHANGED
|
@@ -3,123 +3,128 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.downloadGithubRepoContents = exports.cloneGithubRepo = exports.fetchReleaseData = exports.
|
|
7
|
-
const axios_1 = __importDefault(require("axios"));
|
|
6
|
+
exports.listGithubRepoContents = exports.downloadGithubRepoContents = exports.fetchGitHubRepoContentFromDownloadUrl = exports.cloneGithubRepo = exports.fetchReleaseData = exports.fetchFileFromRepository = void 0;
|
|
8
7
|
const path_1 = __importDefault(require("path"));
|
|
9
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
-
const logger_1 = require("../utils/logger");
|
|
11
|
-
const standardErrors_1 = require("../errors/standardErrors");
|
|
12
9
|
const archive_1 = require("./archive");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
10
|
+
const logger_1 = require("./logger");
|
|
11
|
+
const github_1 = require("../api/github");
|
|
12
|
+
const lang_1 = require("../utils/lang");
|
|
13
|
+
const errors_1 = require("../errors");
|
|
15
14
|
const i18nKey = 'lib.github';
|
|
16
|
-
|
|
17
|
-
authorization: global && global.githubToken ? `Bearer ${global.githubToken}` : null,
|
|
18
|
-
};
|
|
19
|
-
async function fetchJsonFromRepository(repoPath, filePath, ref) {
|
|
15
|
+
async function fetchFileFromRepository(repoPath, filePath, ref) {
|
|
20
16
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
17
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.fetchFileFromRepository.fetching`, {
|
|
18
|
+
path: `${repoPath}/${ref}/${filePath}`,
|
|
19
|
+
}));
|
|
20
|
+
const { data } = await (0, github_1.fetchRepoFile)(repoPath, filePath, ref);
|
|
26
21
|
return data;
|
|
27
22
|
}
|
|
28
23
|
catch (err) {
|
|
29
|
-
(0,
|
|
24
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.fetchFileFromRepository.errors.fetchFail`), {
|
|
25
|
+
cause: err,
|
|
26
|
+
});
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
|
-
exports.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (tag
|
|
36
|
-
tag =
|
|
29
|
+
exports.fetchFileFromRepository = fetchFileFromRepository;
|
|
30
|
+
// Fetches information about a specific release (Defaults to latest)
|
|
31
|
+
async function fetchReleaseData(repoPath, tag) {
|
|
32
|
+
if (tag) {
|
|
33
|
+
tag = tag.trim().toLowerCase();
|
|
34
|
+
if (tag.length && tag[0] !== 'v') {
|
|
35
|
+
tag = `v${tag}`;
|
|
36
|
+
}
|
|
37
37
|
}
|
|
38
|
-
const URI = tag
|
|
39
|
-
? `https://api.github.com/repos/${repoPath}/releases/tags/${tag}`
|
|
40
|
-
: `https://api.github.com/repos/${repoPath}/releases/latest`;
|
|
41
38
|
try {
|
|
42
|
-
const { data } = await
|
|
43
|
-
headers: { ...getAxiosConfig_1.DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS },
|
|
44
|
-
});
|
|
39
|
+
const { data } = await (0, github_1.fetchRepoReleaseData)(repoPath, tag);
|
|
45
40
|
return data;
|
|
46
41
|
}
|
|
47
42
|
catch (err) {
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.fetchReleaseData.errors.fetchFail`, {
|
|
44
|
+
tag: tag || 'latest',
|
|
45
|
+
}), { cause: err });
|
|
50
46
|
}
|
|
51
47
|
}
|
|
52
48
|
exports.fetchReleaseData = fetchReleaseData;
|
|
53
|
-
async function downloadGithubRepoZip(repoPath,
|
|
49
|
+
async function downloadGithubRepoZip(repoPath, isRelease = false, options = {}) {
|
|
50
|
+
const { branch, tag } = options;
|
|
54
51
|
try {
|
|
55
52
|
let zipUrl;
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
repoPath,
|
|
60
|
-
});
|
|
61
|
-
zipUrl = `https://api.github.com/repos/${repoPath}/zipball${ref ? `/${ref}` : ''}`;
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
53
|
+
if (isRelease) {
|
|
54
|
+
// If downloading a release, first get the release info using fetchReleaseData().
|
|
55
|
+
// Supports a custom tag, but will default to the latest release
|
|
64
56
|
const releaseData = await fetchReleaseData(repoPath, tag);
|
|
65
57
|
zipUrl = releaseData.zipball_url;
|
|
66
58
|
const { name } = releaseData;
|
|
67
|
-
(0,
|
|
59
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.fetchingName`, { name }));
|
|
68
60
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
else {
|
|
62
|
+
// If downloading a repository, manually construct the zip url. This url supports both branches and tags as refs
|
|
63
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.fetching`, { repoPath }));
|
|
64
|
+
const ref = branch || tag;
|
|
65
|
+
zipUrl = `https://api.github.com/repos/${repoPath}/zipball${ref ? `/${ref}` : ''}`;
|
|
66
|
+
}
|
|
67
|
+
const { data } = await (0, github_1.fetchRepoAsZip)(zipUrl);
|
|
68
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.completed`));
|
|
73
69
|
return data;
|
|
74
70
|
}
|
|
75
71
|
catch (err) {
|
|
76
|
-
(0,
|
|
72
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.errors.fetchFail`), {
|
|
73
|
+
cause: err,
|
|
74
|
+
});
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
async function cloneGithubRepo(repoPath, dest, options = {}) {
|
|
78
|
+
const { tag, isRelease, branch, sourceDir, type } = options;
|
|
79
|
+
const zip = await downloadGithubRepoZip(repoPath, isRelease, {
|
|
80
|
+
tag,
|
|
81
|
+
branch,
|
|
82
|
+
});
|
|
85
83
|
const repoName = repoPath.split('/')[1];
|
|
86
84
|
const success = await (0, archive_1.extractZipArchive)(zip, repoName, dest, { sourceDir });
|
|
87
85
|
if (success) {
|
|
88
|
-
logger(
|
|
86
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.cloneGithubRepo.success`, {
|
|
87
|
+
type: type || '',
|
|
88
|
+
dest,
|
|
89
|
+
}));
|
|
89
90
|
}
|
|
90
91
|
return success;
|
|
91
92
|
}
|
|
92
93
|
exports.cloneGithubRepo = cloneGithubRepo;
|
|
93
|
-
async function getGitHubRepoContentsAtPath(repoPath, path, ref) {
|
|
94
|
-
const refQuery = ref ? `?ref=${ref}` : '';
|
|
95
|
-
const contentsRequestUrl = `https://api.github.com/repos/${repoPath}/contents/${path}${refQuery}`;
|
|
96
|
-
const response = await axios_1.default.get(contentsRequestUrl, {
|
|
97
|
-
headers: { ...getAxiosConfig_1.DEFAULT_USER_AGENT_HEADERS, ...GITHUB_AUTH_HEADERS },
|
|
98
|
-
});
|
|
99
|
-
return response.data;
|
|
100
|
-
}
|
|
101
94
|
async function fetchGitHubRepoContentFromDownloadUrl(dest, downloadUrl) {
|
|
102
|
-
const resp = await
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
const resp = await (0, github_1.fetchRepoFileByDownloadUrl)(downloadUrl);
|
|
96
|
+
const contentType = resp.headers['content-type'];
|
|
97
|
+
let fileContents;
|
|
98
|
+
if (contentType.startsWith('text')) {
|
|
99
|
+
fileContents = Buffer.from(resp.data).toString('utf8');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
fileContents = resp.data;
|
|
103
|
+
}
|
|
104
|
+
fs_extra_1.default.outputFileSync(dest, fileContents);
|
|
106
105
|
}
|
|
106
|
+
exports.fetchGitHubRepoContentFromDownloadUrl = fetchGitHubRepoContentFromDownloadUrl;
|
|
107
107
|
// Writes files from a public repository to the destination folder
|
|
108
108
|
async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filter) {
|
|
109
109
|
fs_extra_1.default.ensureDirSync(path_1.default.dirname(dest));
|
|
110
110
|
try {
|
|
111
|
-
const contentsResp = await
|
|
111
|
+
const { data: contentsResp } = await (0, github_1.fetchRepoContents)(repoPath, contentPath, ref);
|
|
112
112
|
const downloadContent = async (contentPiece) => {
|
|
113
|
-
const { path: contentPiecePath, download_url } = contentPiece;
|
|
113
|
+
const { path: contentPiecePath, download_url, type: contentPieceType, } = contentPiece;
|
|
114
114
|
const downloadPath = path_1.default.join(dest, contentPiecePath.replace(contentPath, ''));
|
|
115
115
|
if (filter && !filter(contentPiecePath, downloadPath)) {
|
|
116
116
|
return Promise.resolve();
|
|
117
117
|
}
|
|
118
|
-
(0,
|
|
118
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.downloading`, {
|
|
119
119
|
contentPiecePath,
|
|
120
120
|
downloadUrl: download_url,
|
|
121
121
|
downloadPath,
|
|
122
|
-
});
|
|
122
|
+
}));
|
|
123
|
+
if (contentPieceType === 'dir') {
|
|
124
|
+
const { data: innerDirContent } = await (0, github_1.fetchRepoContents)(repoPath, contentPiecePath, ref);
|
|
125
|
+
await Promise.all(innerDirContent.map(downloadContent));
|
|
126
|
+
return Promise.resolve();
|
|
127
|
+
}
|
|
123
128
|
return fetchGitHubRepoContentFromDownloadUrl(downloadPath, download_url);
|
|
124
129
|
};
|
|
125
130
|
let contentPromises;
|
|
@@ -129,18 +134,34 @@ async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filt
|
|
|
129
134
|
else {
|
|
130
135
|
contentPromises = [downloadContent(contentsResp)];
|
|
131
136
|
}
|
|
132
|
-
Promise.all(contentPromises);
|
|
137
|
+
await Promise.all(contentPromises);
|
|
133
138
|
}
|
|
134
139
|
catch (e) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}, error);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
(0, standardErrors_1.throwError)(error);
|
|
140
|
+
if ((0, errors_1.isSystemError)(e) && e?.error?.message) {
|
|
141
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.errors.fetchFail`, {
|
|
142
|
+
errorMessage: e.error.message,
|
|
143
|
+
}), { cause: e });
|
|
143
144
|
}
|
|
145
|
+
throw e;
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
148
|
exports.downloadGithubRepoContents = downloadGithubRepoContents;
|
|
149
|
+
// Lists content from a public repository at the specified path
|
|
150
|
+
async function listGithubRepoContents(repoPath, contentPath, fileFilter) {
|
|
151
|
+
try {
|
|
152
|
+
const { data: contentsResp } = await (0, github_1.fetchRepoContents)(repoPath, contentPath);
|
|
153
|
+
const filteredFiles = fileFilter && fileFilter != undefined
|
|
154
|
+
? contentsResp.filter(item => item.type === fileFilter)
|
|
155
|
+
: contentsResp;
|
|
156
|
+
return filteredFiles;
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
if ((0, errors_1.isHubSpotHttpError)(e) && e.data.message) {
|
|
160
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.errors.fetchFail`, {
|
|
161
|
+
errorMessage: e.data.message,
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
throw e;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.listGithubRepoContents = listGithubRepoContents;
|
package/lib/gitignore.d.ts
CHANGED
package/lib/gitignore.js
CHANGED
|
@@ -3,17 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.checkAndAddConfigToGitignore = void 0;
|
|
6
|
+
exports.checkGitInclusion = exports.checkAndAddConfigToGitignore = void 0;
|
|
7
7
|
const fs_extra_1 = require("fs-extra");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const git_1 = require("../utils/git");
|
|
10
10
|
const config_1 = require("../constants/config");
|
|
11
|
-
const
|
|
11
|
+
const lang_1 = require("../utils/lang");
|
|
12
12
|
const i18nKey = 'lib.gitignore';
|
|
13
13
|
const GITIGNORE_FILE = '.gitignore';
|
|
14
14
|
function checkAndAddConfigToGitignore(configPath) {
|
|
15
15
|
try {
|
|
16
|
-
const { configIgnored, gitignoreFiles } =
|
|
16
|
+
const { configIgnored, gitignoreFiles } = checkGitInclusion(configPath);
|
|
17
17
|
if (configIgnored)
|
|
18
18
|
return;
|
|
19
19
|
let gitignoreFilePath = gitignoreFiles && gitignoreFiles.length ? gitignoreFiles[0] : null;
|
|
@@ -26,7 +26,24 @@ function checkAndAddConfigToGitignore(configPath) {
|
|
|
26
26
|
(0, fs_extra_1.writeFileSync)(gitignoreFilePath, updatedContents);
|
|
27
27
|
}
|
|
28
28
|
catch (e) {
|
|
29
|
-
(0,
|
|
29
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.configIgnore`), { cause: e });
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
exports.checkAndAddConfigToGitignore = checkAndAddConfigToGitignore;
|
|
33
|
+
function checkGitInclusion(configPath) {
|
|
34
|
+
const result = {
|
|
35
|
+
inGit: false,
|
|
36
|
+
configIgnored: false,
|
|
37
|
+
gitignoreFiles: [],
|
|
38
|
+
};
|
|
39
|
+
if ((0, git_1.isConfigPathInGitRepo)(configPath)) {
|
|
40
|
+
result.inGit = true;
|
|
41
|
+
result.gitignoreFiles = (0, git_1.getGitignoreFiles)(configPath);
|
|
42
|
+
if ((0, git_1.configFilenameIsIgnoredByGitignore)(result.gitignoreFiles, configPath)) {
|
|
43
|
+
// Found ignore statement in .gitignore that matches config filename
|
|
44
|
+
result.configIgnored = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
exports.checkGitInclusion = checkGitInclusion;
|