@hubspot/local-dev-lib 0.2.2 → 0.2.3-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.
Files changed (187) hide show
  1. package/LICENSE +12 -0
  2. package/README.md +17 -0
  3. package/api/appsDev.d.ts +6 -0
  4. package/api/appsDev.js +29 -0
  5. package/api/customObjects.d.ts +8 -7
  6. package/api/customObjects.js +13 -16
  7. package/api/designManager.d.ts +4 -13
  8. package/api/designManager.js +6 -9
  9. package/api/developerTestAccounts.d.ts +7 -0
  10. package/api/developerTestAccounts.js +48 -0
  11. package/api/fileManager.d.ts +5 -4
  12. package/api/fileManager.js +11 -11
  13. package/api/fileMapper.d.ts +8 -7
  14. package/api/fileMapper.js +17 -17
  15. package/api/fileTransport.d.ts +4 -0
  16. package/api/fileTransport.js +39 -0
  17. package/api/functions.d.ts +7 -4
  18. package/api/functions.js +22 -11
  19. package/api/github.d.ts +7 -9
  20. package/api/github.js +31 -13
  21. package/api/hubdb.d.ts +11 -10
  22. package/api/hubdb.js +28 -22
  23. package/api/lighthouseScore.d.ts +4 -4
  24. package/api/lighthouseScore.js +9 -12
  25. package/api/localDevAuth.d.ts +8 -16
  26. package/api/localDevAuth.js +34 -13
  27. package/api/marketplaceValidation.d.ts +4 -4
  28. package/api/marketplaceValidation.js +8 -11
  29. package/api/projects.d.ts +31 -24
  30. package/api/projects.js +164 -44
  31. package/api/sandboxHubs.d.ts +6 -4
  32. package/api/sandboxHubs.js +10 -11
  33. package/api/sandboxSync.d.ts +4 -4
  34. package/api/sandboxSync.js +4 -13
  35. package/api/secrets.d.ts +6 -8
  36. package/api/secrets.js +9 -12
  37. package/api/validateHubl.d.ts +2 -1
  38. package/api/validateHubl.js +3 -6
  39. package/config/CLIConfiguration.d.ts +15 -11
  40. package/config/CLIConfiguration.js +175 -90
  41. package/config/configFile.js +12 -18
  42. package/config/configUtils.d.ts +2 -21
  43. package/config/configUtils.js +5 -4
  44. package/config/config_DEPRECATED.d.ts +6 -8
  45. package/config/config_DEPRECATED.js +79 -25
  46. package/config/environment.js +5 -4
  47. package/config/getAccountIdentifier.d.ts +2 -0
  48. package/config/getAccountIdentifier.js +15 -0
  49. package/config/index.d.ts +14 -8
  50. package/config/index.js +108 -57
  51. package/constants/config.d.ts +18 -1
  52. package/constants/config.js +20 -3
  53. package/constants/environments.d.ts +1 -0
  54. package/constants/environments.js +1 -0
  55. package/constants/extensions.d.ts +2 -0
  56. package/constants/extensions.js +3 -1
  57. package/constants/files.d.ts +2 -2
  58. package/constants/files.js +3 -3
  59. package/errors/errors_DEPRECATED.d.ts +1 -5
  60. package/errors/errors_DEPRECATED.js +2 -2
  61. package/errors/index.d.ts +18 -0
  62. package/errors/index.js +63 -0
  63. package/http/addQueryParams.d.ts +2 -0
  64. package/http/addQueryParams.js +14 -0
  65. package/http/getAxiosConfig.d.ts +6 -3
  66. package/http/getAxiosConfig.js +51 -7
  67. package/http/index.d.ts +11 -12
  68. package/http/index.js +35 -41
  69. package/http/unauthed.d.ts +14 -0
  70. package/http/unauthed.js +38 -0
  71. package/lang/en.json +378 -386
  72. package/lib/archive.d.ts +2 -8
  73. package/lib/archive.js +34 -30
  74. package/lib/cms/functions.d.ts +7 -12
  75. package/lib/cms/functions.js +49 -51
  76. package/lib/cms/handleFieldsJS.js +16 -14
  77. package/lib/cms/modules.d.ts +4 -15
  78. package/lib/cms/modules.js +81 -78
  79. package/lib/cms/processFieldsJs.js +10 -33
  80. package/lib/cms/templates.d.ts +43 -3
  81. package/lib/cms/templates.js +53 -11
  82. package/lib/cms/uploadFolder.d.ts +3 -14
  83. package/lib/cms/uploadFolder.js +58 -42
  84. package/lib/cms/validate.js +1 -1
  85. package/lib/cms/watch.d.ts +2 -18
  86. package/lib/cms/watch.js +63 -68
  87. package/lib/customObjects.js +4 -15
  88. package/lib/fileManager.d.ts +2 -6
  89. package/lib/fileManager.js +54 -65
  90. package/lib/fileMapper.d.ts +4 -15
  91. package/lib/fileMapper.js +67 -88
  92. package/lib/fs.d.ts +1 -1
  93. package/lib/fs.js +10 -6
  94. package/lib/github.d.ts +12 -14
  95. package/lib/github.js +70 -35
  96. package/lib/gitignore.d.ts +2 -0
  97. package/lib/gitignore.js +21 -4
  98. package/lib/hubdb.d.ts +3 -2
  99. package/lib/hubdb.js +11 -9
  100. package/{utils → lib}/notify.js +2 -2
  101. package/lib/oauth.d.ts +2 -5
  102. package/lib/oauth.js +14 -25
  103. package/lib/path.d.ts +3 -0
  104. package/lib/path.js +46 -1
  105. package/lib/personalAccessKey.d.ts +8 -11
  106. package/lib/personalAccessKey.js +75 -38
  107. package/lib/portManager.d.ts +3 -5
  108. package/lib/portManager.js +18 -6
  109. package/lib/trackUsage.js +18 -11
  110. package/lib/urls.js +5 -1
  111. package/models/FileSystemError.d.ts +6 -0
  112. package/models/FileSystemError.js +47 -0
  113. package/models/HubSpotHttpError.d.ts +24 -0
  114. package/models/HubSpotHttpError.js +197 -0
  115. package/models/OAuth2Manager.d.ts +5 -27
  116. package/models/OAuth2Manager.js +41 -64
  117. package/package.json +34 -35
  118. package/types/Accounts.d.ts +103 -3
  119. package/types/Apps.d.ts +77 -0
  120. package/types/Archive.d.ts +9 -0
  121. package/types/Archive.js +2 -0
  122. package/types/Build.d.ts +4 -2
  123. package/types/ComponentStructure.d.ts +30 -10
  124. package/types/Config.d.ts +19 -2
  125. package/types/Deploy.d.ts +3 -2
  126. package/types/DesignManager.d.ts +10 -0
  127. package/types/DesignManager.js +2 -0
  128. package/types/Error.d.ts +9 -5
  129. package/types/FieldsJS.d.ts +1 -0
  130. package/types/FieldsJS.js +2 -0
  131. package/types/FileManager.d.ts +1 -1
  132. package/types/Files.d.ts +43 -4
  133. package/types/Functions.d.ts +52 -0
  134. package/types/Github.d.ts +13 -0
  135. package/types/Http.d.ts +12 -11
  136. package/types/Hubdb.d.ts +9 -0
  137. package/types/MarketplaceValidation.d.ts +7 -3
  138. package/types/Migration.d.ts +28 -0
  139. package/types/Migration.js +10 -0
  140. package/types/Modules.d.ts +11 -0
  141. package/types/PortManager.d.ts +7 -0
  142. package/types/Project.d.ts +30 -0
  143. package/types/ProjectLog.d.ts +9 -0
  144. package/types/ProjectLog.js +2 -0
  145. package/types/Sandbox.d.ts +37 -47
  146. package/types/Schemas.d.ts +56 -0
  147. package/types/Secrets.d.ts +3 -0
  148. package/types/Secrets.js +2 -0
  149. package/types/developerTestAccounts.d.ts +13 -0
  150. package/types/developerTestAccounts.js +2 -0
  151. package/utils/PortManagerServer.d.ts +6 -7
  152. package/utils/PortManagerServer.js +22 -16
  153. package/utils/{getAccountIdentifier.d.ts → accounts.d.ts} +0 -6
  154. package/utils/{getAccountIdentifier.js → accounts.js} +1 -13
  155. package/utils/cms/fieldsJS.d.ts +1 -2
  156. package/utils/cms/modules.js +2 -2
  157. package/utils/detectPort.js +3 -3
  158. package/utils/git.d.ts +1 -7
  159. package/utils/git.js +2 -18
  160. package/errors/apiErrors.d.ts +0 -19
  161. package/errors/apiErrors.js +0 -179
  162. package/errors/fileSystemErrors.d.ts +0 -5
  163. package/errors/fileSystemErrors.js +0 -31
  164. package/errors/standardErrors.d.ts +0 -27
  165. package/errors/standardErrors.js +0 -59
  166. package/lang/lang/en.json +0 -401
  167. package/lib/logging/git.d.ts +0 -2
  168. package/lib/logging/git.js +0 -54
  169. package/lib/logging/logs.d.ts +0 -22
  170. package/lib/logging/logs.js +0 -86
  171. package/lib/logging/table.d.ts +0 -3
  172. package/lib/logging/table.js +0 -47
  173. package/lib/sandboxes.d.ts +0 -14
  174. package/lib/sandboxes.js +0 -71
  175. package/models/HubSpotAuthError.d.ts +0 -12
  176. package/models/HubSpotAuthError.js +0 -20
  177. package/types/LogCallbacks.d.ts +0 -7
  178. package/utils/logger.d.ts +0 -5
  179. package/utils/logger.js +0 -23
  180. package/utils/objectUtils.d.ts +0 -8
  181. package/utils/objectUtils.js +0 -33
  182. /package/{utils → lib}/escapeRegExp.d.ts +0 -0
  183. /package/{utils → lib}/escapeRegExp.js +0 -0
  184. /package/lib/{logging/logger.d.ts → logger.d.ts} +0 -0
  185. /package/lib/{logging/logger.js → logger.js} +0 -0
  186. /package/{utils → lib}/notify.d.ts +0 -0
  187. /package/types/{LogCallbacks.js → Apps.js} +0 -0
package/lib/fileMapper.js CHANGED
@@ -9,20 +9,14 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const p_queue_1 = __importDefault(require("p-queue"));
11
11
  const path_2 = require("./path");
12
+ const logger_1 = require("./logger");
12
13
  const fileMapper_1 = require("../api/fileMapper");
13
- const standardErrors_1 = require("../errors/standardErrors");
14
14
  const extensions_1 = require("../constants/extensions");
15
15
  const files_1 = require("../constants/files");
16
- const fileSystemErrors_1 = require("../errors/fileSystemErrors");
17
- const logger_1 = require("../utils/logger");
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
- const filemapperCallbackKeys = [
20
- 'skippedExisting',
21
- 'wroteFolder',
22
- 'completedFetch',
23
- 'folderFetch',
24
- 'completedFolderFetch',
25
- ];
26
20
  const queue = new p_queue_1.default({
27
21
  concurrency: 10,
28
22
  });
@@ -49,14 +43,14 @@ function isPathToHubspot(filepath) {
49
43
  return /^(\/|\\)?@hubspot/i.test(filepath.trim());
50
44
  }
51
45
  exports.isPathToHubspot = isPathToHubspot;
52
- function useApiBuffer(mode) {
53
- return mode === files_1.MODE.draft;
46
+ function useApiBuffer(cmsPublishMode) {
47
+ return cmsPublishMode === files_1.CMS_PUBLISH_MODE.draft;
54
48
  }
55
- // Determines API param based on mode an options
56
- function getFileMapperQueryValues(mode, { staging, assetVersion } = {}) {
49
+ // Determines API param based on publish mode and options
50
+ function getFileMapperQueryValues(cmsPublishMode, { staging, assetVersion } = {}) {
57
51
  return {
58
52
  params: {
59
- buffer: useApiBuffer(mode),
53
+ buffer: useApiBuffer(cmsPublishMode),
60
54
  environmentId: staging ? 2 : 1,
61
55
  version: assetVersion,
62
56
  },
@@ -82,9 +76,9 @@ function validateFileMapperNode(node) {
82
76
  catch (err) {
83
77
  json = node;
84
78
  }
85
- (0, standardErrors_1.throwTypeErrorWithMessage)(`${i18nKey}.errors.invalidNode`, {
79
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidNode`, {
86
80
  json: JSON.stringify(json),
87
- });
81
+ }));
88
82
  }
89
83
  function getTypeDataFromPath(src) {
90
84
  const isModule = isPathToModule(src);
@@ -130,10 +124,10 @@ async function writeUtimes(accountId, filepath, node) {
130
124
  await fs_extra_1.default.utimes(filepath, atime, mtime);
131
125
  }
132
126
  catch (err) {
133
- (0, fileSystemErrors_1.throwFileSystemError)(err, {
127
+ throw new FileSystemError_1.FileSystemError({ cause: err }, {
134
128
  filepath,
135
129
  accountId,
136
- write: true,
130
+ operation: 'write',
137
131
  });
138
132
  }
139
133
  }
@@ -147,41 +141,33 @@ async function skipExisting(filepath, overwrite = false) {
147
141
  }
148
142
  return false;
149
143
  }
150
- async function fetchAndWriteFileStream(accountId, srcPath, filepath, mode, options = {}, logCallbacks) {
151
- const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
144
+ async function fetchAndWriteFileStream(accountId, srcPath, filepath, cmsPublishMode, options = {}) {
152
145
  if (typeof srcPath !== 'string' || !srcPath.trim()) {
153
146
  return;
154
147
  }
155
148
  if (await skipExisting(filepath, options.overwrite)) {
156
- logger('skippedExisting', `${i18nKey}.skippedExisting`, { filepath });
149
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, { filepath }));
157
150
  return;
158
151
  }
159
- if (!(0, path_2.isAllowedExtension)(srcPath)) {
160
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.invalidFileType`, { srcPath });
161
- }
162
- let node;
163
- try {
164
- node = await (0, fileMapper_1.fetchFileStream)(accountId, srcPath, filepath, getFileMapperQueryValues(mode, options));
165
- }
166
- catch (err) {
167
- (0, standardErrors_1.throwError)(err);
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 }));
168
154
  }
155
+ const node = await (0, fileMapper_1.fetchFileStream)(accountId, srcPath, filepath, getFileMapperQueryValues(cmsPublishMode, options));
169
156
  await writeUtimes(accountId, filepath, node);
170
157
  }
171
158
  // Writes an individual file or folder (not recursive). If file source is missing, the
172
159
  //file is fetched.
173
- async function writeFileMapperNode(accountId, filepath, node, mode, options = {}, logCallbacks) {
174
- const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
160
+ async function writeFileMapperNode(accountId, filepath, node, cmsPublishMode, options = {}) {
175
161
  const localFilepath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve(filepath));
176
162
  if (await skipExisting(localFilepath, options.overwrite)) {
177
- logger('skippedExisting', `${i18nKey}.skippedExisting`, {
163
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, {
178
164
  filepath: localFilepath,
179
- });
165
+ }));
180
166
  return true;
181
167
  }
182
168
  if (!node.folder) {
183
169
  try {
184
- await fetchAndWriteFileStream(accountId, node.path, localFilepath, mode, options, logCallbacks);
170
+ await fetchAndWriteFileStream(accountId, node.path, localFilepath, cmsPublishMode, options);
185
171
  return true;
186
172
  }
187
173
  catch (err) {
@@ -190,30 +176,25 @@ async function writeFileMapperNode(accountId, filepath, node, mode, options = {}
190
176
  }
191
177
  try {
192
178
  await fs_extra_1.default.ensureDir(localFilepath);
193
- logger('wroteFolder', `${i18nKey}.wroteFolder`, {
179
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.wroteFolder`, {
194
180
  filepath: localFilepath,
195
- });
181
+ }));
196
182
  }
197
183
  catch (err) {
198
- (0, fileSystemErrors_1.throwFileSystemError)(err, {
184
+ throw new FileSystemError_1.FileSystemError({ cause: err }, {
199
185
  filepath: localFilepath,
200
186
  accountId,
201
- write: true,
187
+ operation: 'write',
202
188
  });
203
- return false;
204
189
  }
205
190
  return true;
206
191
  }
207
- function isTimeout(err) {
208
- return !!err && (err.status === 408 || err.code === 'ESOCKETTIMEDOUT');
209
- }
210
- async function downloadFile(accountId, src, destPath, mode, options = {}, logCallbacks) {
211
- const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
192
+ async function downloadFile(accountId, src, destPath, cmsPublishMode, options = {}) {
212
193
  const { isFile, isHubspot } = getTypeDataFromPath(src);
194
+ if (!isFile) {
195
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidRequest`, { src }));
196
+ }
213
197
  try {
214
- if (!isFile) {
215
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.invalidRequest`, { src });
216
- }
217
198
  const dest = path_1.default.resolve(destPath);
218
199
  const cwd = (0, path_2.getCwd)();
219
200
  let filepath;
@@ -233,56 +214,43 @@ async function downloadFile(accountId, src, destPath, mode, options = {}, logCal
233
214
  : path_1.default.resolve(cwd, dest, name);
234
215
  }
235
216
  const localFsPath = (0, path_2.convertToLocalFileSystemPath)(filepath);
236
- await fetchAndWriteFileStream(accountId, src, localFsPath, mode, options, logCallbacks);
217
+ await fetchAndWriteFileStream(accountId, src, localFsPath, cmsPublishMode, options);
237
218
  await queue.onIdle();
238
- logger('completedFetch', `${i18nKey}.completedFetch`, {
219
+ logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.completedFetch`, {
239
220
  src,
240
221
  version: getAssetVersionIdentifier(options.assetVersion, src),
241
222
  dest,
242
- });
223
+ }));
243
224
  }
244
225
  catch (err) {
245
226
  const error = err;
246
- if (isHubspot && isTimeout(error)) {
247
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.assetTimeout`, {}, error);
227
+ if (isHubspot && (0, errors_1.isTimeoutError)(error)) {
228
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.assetTimeout`), { cause: error });
248
229
  }
249
230
  else {
250
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.failedToFetchFile`, { src, dest: destPath }, error);
231
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFile`, { src, dest: destPath }), { cause: error });
251
232
  }
252
233
  }
253
234
  }
254
- async function fetchFolderFromApi(accountId, src, mode, options = {}, logCallbacks) {
255
- const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
235
+ async function fetchFolderFromApi(accountId, src, cmsPublishMode, options = {}) {
256
236
  const { isRoot, isFolder, isHubspot } = getTypeDataFromPath(src);
257
237
  if (!isFolder) {
258
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.invalidFetchFolderRequest`, {
238
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidFetchFolderRequest`, {
259
239
  src,
260
- });
261
- }
262
- try {
263
- const srcPath = isRoot ? '@root' : src;
264
- const queryValues = getFileMapperQueryValues(mode, options);
265
- const node = isHubspot
266
- ? await (0, fileMapper_1.downloadDefault)(accountId, srcPath, queryValues)
267
- : await (0, fileMapper_1.download)(accountId, srcPath, queryValues);
268
- logger('folderFetch', `${i18nKey}.folderFetch`, { src, accountId });
269
- return node;
270
- }
271
- catch (err) {
272
- const error = err;
273
- if (isHubspot && isTimeout(error)) {
274
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.assetTimeout`, {}, error);
275
- }
276
- else {
277
- (0, standardErrors_1.throwError)(error);
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, mode, options = {}, logCallbacks) {
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, mode, options, logCallbacks);
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, mode, options, logCallbacks);
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('completedFolderFetch', `${i18nKey}.completedFolderFetch`, {
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
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.incompleteFetch`, { src });
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
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.failedToFetchFolder`, { src, dest: destPath }, err);
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, mode, options = {}, logCallbacks) {
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, mode, options, logCallbacks);
311
+ await downloadFile(accountId, src, dest, cmsPublishMode, options);
333
312
  }
334
313
  else {
335
- await downloadFolder(accountId, src, dest, mode, options, logCallbacks);
314
+ await downloadFolder(accountId, src, dest, cmsPublishMode, options);
336
315
  }
337
316
  }
338
317
  exports.downloadFileOrFolder = downloadFileOrFolder;
package/lib/fs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { FileData } from '../types/Files';
2
2
  export declare function getFileInfoAsync(dir: string, file: string): Promise<FileData>;
3
3
  export declare function flattenAndRemoveSymlinks(filesData: Array<FileData>): Array<string>;
4
- export declare function walk(dir: string): Promise<Array<string>>;
4
+ export declare function walk(dir: string, ignoreDirs?: string[]): Promise<Array<string>>;
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 standardErrors_1 = require("../errors/standardErrors");
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);
@@ -42,11 +42,11 @@ function flattenAndRemoveSymlinks(filesData) {
42
42
  }, []);
43
43
  }
44
44
  exports.flattenAndRemoveSymlinks = flattenAndRemoveSymlinks;
45
- const generateRecursiveFilePromise = async (dir, file) => {
45
+ const generateRecursiveFilePromise = async (dir, file, ignoreDirs) => {
46
46
  return getFileInfoAsync(dir, file).then(fileData => {
47
47
  return new Promise(resolve => {
48
48
  if (fileData.type === files_1.STAT_TYPES.DIRECTORY) {
49
- walk(fileData.filepath).then(files => {
49
+ walk(fileData.filepath, ignoreDirs).then(files => {
50
50
  resolve({ ...fileData, files });
51
51
  });
52
52
  }
@@ -56,16 +56,20 @@ const generateRecursiveFilePromise = async (dir, file) => {
56
56
  });
57
57
  });
58
58
  };
59
- async function walk(dir) {
59
+ async function walk(dir, ignoreDirs) {
60
60
  function processFiles(files) {
61
- return Promise.all(files.map(file => generateRecursiveFilePromise(dir, file)));
61
+ // If the directory is in the ignore list, return an empty array to skip the directory contents
62
+ if (ignoreDirs?.some(ignored => dir.includes(ignored))) {
63
+ return [];
64
+ }
65
+ return Promise.all(files.map(file => generateRecursiveFilePromise(dir, file, ignoreDirs)));
62
66
  }
63
67
  return fs_1.default.promises
64
68
  .readdir(dir)
65
69
  .then(processFiles)
66
70
  .then(flattenAndRemoveSymlinks)
67
71
  .catch(err => {
68
- (0, standardErrors_1.throwError)(err);
72
+ throw new FileSystemError_1.FileSystemError({ cause: err });
69
73
  });
70
74
  }
71
75
  exports.walk = walk;
package/lib/github.d.ts CHANGED
@@ -1,17 +1,15 @@
1
1
  /// <reference types="node" />
2
- import { GithubReleaseData } from '../types/Github';
3
- import { LogCallbacksArg } from '../types/LogCallbacks';
4
- declare const cloneGithubRepoCallbackKeys: readonly ["success"];
5
- type RepoPath = `${string}/${string}`;
6
- export declare function fetchFileFromRepository(repoPath: RepoPath, filePath: string, ref: string): Promise<Buffer>;
2
+ import { GithubReleaseData, GithubRepoFile, RepoPath, CloneGithubRepoOptions } from '../types/Github';
3
+ /**
4
+ * @deprecated Use `fetchRepoFile` instead - this util is a thin wrapper around it
5
+ */
6
+ export declare function fetchFileFromRepository<T = Buffer>(repoPath: RepoPath, filePath: string, ref: string): Promise<T>;
7
7
  export declare function fetchReleaseData(repoPath: RepoPath, tag?: string): Promise<GithubReleaseData>;
8
- type CloneGithubRepoOptions = {
9
- isRelease?: boolean;
10
- type?: string;
11
- branch?: string;
12
- tag?: string;
13
- sourceDir?: string;
14
- };
15
- export declare function cloneGithubRepo(repoPath: RepoPath, dest: string, options?: CloneGithubRepoOptions, logCallbacks?: LogCallbacksArg<typeof cloneGithubRepoCallbackKeys>): Promise<boolean>;
8
+ export declare function cloneGithubRepo(repoPath: RepoPath, dest: string, options?: CloneGithubRepoOptions): Promise<boolean>;
9
+ export declare function fetchGitHubRepoContentFromDownloadUrl(dest: string, downloadUrl: string): Promise<void>;
10
+ /**
11
+ * Writes files from a public repository to the destination folder
12
+ @deprecated - This method fetches all the files individually, which can hit rate limits for unauthorized requests. Use `cloneGithubRepo` instead.
13
+ */
16
14
  export declare function downloadGithubRepoContents(repoPath: RepoPath, contentPath: string, dest: string, ref?: string, filter?: (contentPiecePath: string, downloadPath: string) => boolean): Promise<void>;
17
- export {};
15
+ export declare function listGithubRepoContents(repoPath: RepoPath, contentPath: string, fileFilter?: 'file' | 'dir'): Promise<GithubRepoFile[]>;
package/lib/github.js CHANGED
@@ -3,25 +3,30 @@ 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.fetchFileFromRepository = void 0;
6
+ exports.listGithubRepoContents = exports.downloadGithubRepoContents = exports.fetchGitHubRepoContentFromDownloadUrl = exports.cloneGithubRepo = exports.fetchReleaseData = exports.fetchFileFromRepository = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
- const logger_1 = require("../utils/logger");
10
- const standardErrors_1 = require("../errors/standardErrors");
11
9
  const archive_1 = require("./archive");
10
+ const logger_1 = require("./logger");
12
11
  const github_1 = require("../api/github");
12
+ const lang_1 = require("../utils/lang");
13
+ const errors_1 = require("../errors");
13
14
  const i18nKey = 'lib.github';
14
- const cloneGithubRepoCallbackKeys = ['success'];
15
+ /**
16
+ * @deprecated Use `fetchRepoFile` instead - this util is a thin wrapper around it
17
+ */
15
18
  async function fetchFileFromRepository(repoPath, filePath, ref) {
16
19
  try {
17
- (0, logger_1.debug)(`${i18nKey}.fetchFileFromRepository.fetching`, {
20
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.fetchFileFromRepository.fetching`, {
18
21
  path: `${repoPath}/${ref}/${filePath}`,
19
- });
22
+ }));
20
23
  const { data } = await (0, github_1.fetchRepoFile)(repoPath, filePath, ref);
21
24
  return data;
22
25
  }
23
26
  catch (err) {
24
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.fetchFileFromRepository.errors.fetchFail`, {}, err);
27
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.fetchFileFromRepository.errors.fetchFail`), {
28
+ cause: err,
29
+ });
25
30
  }
26
31
  }
27
32
  exports.fetchFileFromRepository = fetchFileFromRepository;
@@ -38,8 +43,9 @@ async function fetchReleaseData(repoPath, tag) {
38
43
  return data;
39
44
  }
40
45
  catch (err) {
41
- const error = err;
42
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.fetchReleaseData.errors.fetchFail`, { tag: tag || 'latest' }, error);
46
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.fetchReleaseData.errors.fetchFail`, {
47
+ tag: tag || 'latest',
48
+ }), { cause: err });
43
49
  }
44
50
  }
45
51
  exports.fetchReleaseData = fetchReleaseData;
@@ -53,48 +59,61 @@ async function downloadGithubRepoZip(repoPath, isRelease = false, options = {})
53
59
  const releaseData = await fetchReleaseData(repoPath, tag);
54
60
  zipUrl = releaseData.zipball_url;
55
61
  const { name } = releaseData;
56
- (0, logger_1.debug)(`${i18nKey}.downloadGithubRepoZip.fetchingName`, { name });
62
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.fetchingName`, { name }));
57
63
  }
58
64
  else {
59
65
  // If downloading a repository, manually construct the zip url. This url supports both branches and tags as refs
60
- (0, logger_1.debug)(`${i18nKey}.downloadGithubRepoZip.fetching`, { repoPath });
66
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.fetching`, { repoPath }));
61
67
  const ref = branch || tag;
62
68
  zipUrl = `https://api.github.com/repos/${repoPath}/zipball${ref ? `/${ref}` : ''}`;
63
69
  }
64
70
  const { data } = await (0, github_1.fetchRepoAsZip)(zipUrl);
65
- (0, logger_1.debug)(`${i18nKey}.downloadGithubRepoZip.completed`);
71
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.completed`));
66
72
  return data;
67
73
  }
68
74
  catch (err) {
69
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.downloadGithubRepoZip.errors.fetchFail`, {}, err);
75
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoZip.errors.fetchFail`), {
76
+ cause: err,
77
+ });
70
78
  }
71
79
  }
72
- async function cloneGithubRepo(repoPath, dest, options = {}, logCallbacks) {
73
- const logger = (0, logger_1.makeTypedLogger)(logCallbacks);
74
- const { tag, isRelease, branch, sourceDir, type } = options;
80
+ async function cloneGithubRepo(repoPath, dest, options = {}) {
81
+ const { tag, isRelease, branch, sourceDir, type, hideLogs } = options;
75
82
  const zip = await downloadGithubRepoZip(repoPath, isRelease, {
76
83
  tag,
77
84
  branch,
78
85
  });
79
86
  const repoName = repoPath.split('/')[1];
80
- const success = await (0, archive_1.extractZipArchive)(zip, repoName, dest, { sourceDir });
81
- if (success) {
82
- logger('success', `${i18nKey}.cloneGithubRepo.success`, {
87
+ const success = await (0, archive_1.extractZipArchive)(zip, repoName, dest, {
88
+ sourceDir,
89
+ hideLogs,
90
+ });
91
+ if (success && !hideLogs) {
92
+ logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.cloneGithubRepo.success`, {
83
93
  type: type || '',
84
94
  dest,
85
- });
95
+ }));
86
96
  }
87
97
  return success;
88
98
  }
89
99
  exports.cloneGithubRepo = cloneGithubRepo;
90
100
  async function fetchGitHubRepoContentFromDownloadUrl(dest, downloadUrl) {
91
101
  const resp = await (0, github_1.fetchRepoFileByDownloadUrl)(downloadUrl);
92
- const fileContents = typeof resp.data === 'string'
93
- ? resp.data
94
- : JSON.stringify(resp.data, null, 2);
95
- fs_extra_1.default.outputFileSync(dest, fileContents, 'utf8');
102
+ const contentType = resp.headers['content-type'];
103
+ let fileContents;
104
+ if (contentType.startsWith('text')) {
105
+ fileContents = Buffer.from(resp.data).toString('utf8');
106
+ }
107
+ else {
108
+ fileContents = resp.data;
109
+ }
110
+ fs_extra_1.default.outputFileSync(dest, fileContents);
96
111
  }
97
- // Writes files from a public repository to the destination folder
112
+ exports.fetchGitHubRepoContentFromDownloadUrl = fetchGitHubRepoContentFromDownloadUrl;
113
+ /**
114
+ * Writes files from a public repository to the destination folder
115
+ @deprecated - This method fetches all the files individually, which can hit rate limits for unauthorized requests. Use `cloneGithubRepo` instead.
116
+ */
98
117
  async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filter) {
99
118
  fs_extra_1.default.ensureDirSync(path_1.default.dirname(dest));
100
119
  try {
@@ -105,11 +124,11 @@ async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filt
105
124
  if (filter && !filter(contentPiecePath, downloadPath)) {
106
125
  return Promise.resolve();
107
126
  }
108
- (0, logger_1.debug)(`${i18nKey}.downloadGithubRepoContents.downloading`, {
127
+ logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.downloading`, {
109
128
  contentPiecePath,
110
129
  downloadUrl: download_url,
111
130
  downloadPath,
112
- });
131
+ }));
113
132
  if (contentPieceType === 'dir') {
114
133
  const { data: innerDirContent } = await (0, github_1.fetchRepoContents)(repoPath, contentPiecePath, ref);
115
134
  await Promise.all(innerDirContent.map(downloadContent));
@@ -127,15 +146,31 @@ async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filt
127
146
  await Promise.all(contentPromises);
128
147
  }
129
148
  catch (e) {
130
- const error = e;
131
- if (error?.error?.message) {
132
- (0, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.downloadGithubRepoContents.errors.fetchFail`, {
133
- errorMessage: error.error.message,
134
- }, error);
135
- }
136
- else {
137
- (0, standardErrors_1.throwError)(error);
149
+ if ((0, errors_1.isSystemError)(e) && e?.error?.message) {
150
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.errors.fetchFail`, {
151
+ errorMessage: e.error.message,
152
+ }), { cause: e });
138
153
  }
154
+ throw e;
139
155
  }
140
156
  }
141
157
  exports.downloadGithubRepoContents = downloadGithubRepoContents;
158
+ // Lists content from a public repository at the specified path
159
+ async function listGithubRepoContents(repoPath, contentPath, fileFilter) {
160
+ try {
161
+ const { data: contentsResp } = await (0, github_1.fetchRepoContents)(repoPath, contentPath);
162
+ const filteredFiles = fileFilter && fileFilter != undefined
163
+ ? contentsResp.filter(item => item.type === fileFilter)
164
+ : contentsResp;
165
+ return filteredFiles;
166
+ }
167
+ catch (e) {
168
+ if ((0, errors_1.isHubSpotHttpError)(e) && e.data.message) {
169
+ throw new Error((0, lang_1.i18n)(`${i18nKey}.downloadGithubRepoContents.errors.fetchFail`, {
170
+ errorMessage: e.data.message,
171
+ }));
172
+ }
173
+ throw e;
174
+ }
175
+ }
176
+ exports.listGithubRepoContents = listGithubRepoContents;
@@ -1 +1,3 @@
1
+ import { GitInclusionResult } from '../types/Config';
1
2
  export declare function checkAndAddConfigToGitignore(configPath: string): void;
3
+ export declare function checkGitInclusion(configPath: string): GitInclusionResult;
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 standardErrors_1 = require("../errors/standardErrors");
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 } = (0, git_1.checkGitInclusion)(configPath);
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, standardErrors_1.throwErrorWithMessage)(`${i18nKey}.errors.configIgnore`, {}, e);
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;
package/lib/hubdb.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Row } from '../types/Hubdb';
1
+ import { AxiosResponse } from 'axios';
2
+ import { Row, Table } from '../types/Hubdb';
2
3
  export declare function addRowsToHubDbTable(accountId: number, tableId: string, rows?: Array<Row>): Promise<{
3
4
  tableId: string;
4
5
  rowCount: number;
@@ -7,7 +8,7 @@ export declare function createHubDbTable(accountId: number, src: string): Promis
7
8
  tableId: string;
8
9
  rowCount: number;
9
10
  }>;
10
- export declare function updateHubDbTable(accountId: number, tableId: string, src: string): Promise<unknown>;
11
+ export declare function updateHubDbTable(accountId: number, tableId: string, src: string): Promise<AxiosResponse<Table, any>>;
11
12
  export declare function downloadHubDbTable(accountId: number, tableId: string, dest: string): Promise<{
12
13
  filePath: string;
13
14
  }>;