@hubspot/local-dev-lib 1.4.0 → 1.6.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/api/appsDev.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- import { PublicApp } from '../types/Apps';
1
+ import { PublicApp, PublicAppDeveloperTestAccountInstallData } from '../types/Apps';
2
2
  export declare function fetchPublicAppsForPortal(accountId: number): Promise<Array<PublicApp>>;
3
+ export declare function fetchPublicAppDeveloperTestAccountInstallData(appId: number, accountId: number): Promise<PublicAppDeveloperTestAccountInstallData>;
package/api/appsDev.js CHANGED
@@ -3,7 +3,7 @@ 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.fetchPublicAppsForPortal = void 0;
6
+ exports.fetchPublicAppDeveloperTestAccountInstallData = exports.fetchPublicAppsForPortal = void 0;
7
7
  const http_1 = __importDefault(require("../http"));
8
8
  const APPS_DEV_API_PATH = 'apps-dev/external/public/v3';
9
9
  async function fetchPublicAppsForPortal(accountId) {
@@ -13,3 +13,9 @@ async function fetchPublicAppsForPortal(accountId) {
13
13
  return resp ? resp.results : [];
14
14
  }
15
15
  exports.fetchPublicAppsForPortal = fetchPublicAppsForPortal;
16
+ function fetchPublicAppDeveloperTestAccountInstallData(appId, accountId) {
17
+ return http_1.default.get(accountId, {
18
+ url: `${APPS_DEV_API_PATH}/${appId}/test-portal-installs`,
19
+ });
20
+ }
21
+ exports.fetchPublicAppDeveloperTestAccountInstallData = fetchPublicAppDeveloperTestAccountInstallData;
package/api/github.js CHANGED
@@ -40,6 +40,7 @@ exports.fetchRepoFile = fetchRepoFile;
40
40
  async function fetchRepoFileByDownloadUrl(downloadUrl) {
41
41
  return axios_1.default.get(downloadUrl, {
42
42
  headers: { ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(), ...GITHUB_AUTH_HEADERS },
43
+ responseType: 'arraybuffer',
43
44
  });
44
45
  }
45
46
  exports.fetchRepoFileByDownloadUrl = fetchRepoFileByDownloadUrl;
@@ -1,9 +1,28 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.getAxiosConfig = exports.getDefaultUserAgentHeader = exports.USER_AGENTS = void 0;
4
7
  const package_json_1 = require("../package.json");
5
8
  const config_1 = require("../config");
6
9
  const urls_1 = require("../lib/urls");
10
+ const https_1 = __importDefault(require("https"));
11
+ const http_1 = __importDefault(require("http"));
12
+ // Total number of sockets across all hosts
13
+ const MAX_TOTAL_SOCKETS = 25;
14
+ // Total number of sockets per each host
15
+ const MAX_SOCKETS_PER_HOST = 5;
16
+ const httpAgent = new http_1.default.Agent({
17
+ keepAlive: true,
18
+ maxTotalSockets: MAX_TOTAL_SOCKETS,
19
+ maxSockets: MAX_SOCKETS_PER_HOST,
20
+ });
21
+ const httpsAgent = new https_1.default.Agent({
22
+ keepAlive: true,
23
+ maxTotalSockets: MAX_TOTAL_SOCKETS,
24
+ maxSockets: MAX_SOCKETS_PER_HOST,
25
+ });
7
26
  exports.USER_AGENTS = {
8
27
  'HubSpot Local Dev Lib': package_json_1.version,
9
28
  };
@@ -31,6 +50,8 @@ function getAxiosConfig(options) {
31
50
  },
32
51
  timeout: httpTimeout || 15000,
33
52
  transitional: DEFAULT_TRANSITIONAL,
53
+ httpAgent,
54
+ httpsAgent,
34
55
  ...rest,
35
56
  };
36
57
  }
package/lang/en.json CHANGED
@@ -10,15 +10,15 @@
10
10
  "init": "Extracting project source...",
11
11
  "success": "Completed project source extraction.",
12
12
  "errors": {
13
- "write": "An error occured writing temp project source.",
14
- "extract": "An error occured extracting project source."
13
+ "write": "An error occurred writing temp project source.",
14
+ "extract": "An error occurred extracting project source."
15
15
  }
16
16
  },
17
17
  "copySourceToDest": {
18
18
  "init": "Copying project source...",
19
19
  "sourceEmpty": "Project source is empty",
20
20
  "success": "Completed copying project source.",
21
- "error": "An error occured copying project source to {{ dest }}."
21
+ "error": "An error occurred copying project source to {{ dest }}."
22
22
  },
23
23
  "cleanupTempDir": {
24
24
  "error": "Failed to clean up temp dir: {{ tmpDir }}"
@@ -33,7 +33,7 @@
33
33
  "fetchFileFromRepository": {
34
34
  "fetching": "Fetching {{ path }}...",
35
35
  "errors": {
36
- "fetchFail": "An error occured fetching JSON file."
36
+ "fetchFail": "An error occurred fetching JSON file."
37
37
  }
38
38
  },
39
39
  "fetchReleaseData": {
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "createTmpDirSync": {
132
132
  "errors": {
133
- "writeFailed": "An error occured writing temporary project source."
133
+ "writeFailed": "An error occurred writing temporary project source."
134
134
  }
135
135
  },
136
136
  "cleanupTmpDirSync": {
package/lang/lang/en.json CHANGED
@@ -10,15 +10,15 @@
10
10
  "init": "Extracting project source...",
11
11
  "success": "Completed project source extraction.",
12
12
  "errors": {
13
- "write": "An error occured writing temp project source.",
14
- "extract": "An error occured extracting project source."
13
+ "write": "An error occurred writing temp project source.",
14
+ "extract": "An error occurred extracting project source."
15
15
  }
16
16
  },
17
17
  "copySourceToDest": {
18
18
  "init": "Copying project source...",
19
19
  "sourceEmpty": "Project source is empty",
20
20
  "success": "Completed copying project source.",
21
- "error": "An error occured copying project source to {{ dest }}."
21
+ "error": "An error occurred copying project source to {{ dest }}."
22
22
  },
23
23
  "cleanupTempDir": {
24
24
  "error": "Failed to clean up temp dir: {{ tmpDir }}"
@@ -33,7 +33,7 @@
33
33
  "fetchFileFromRepository": {
34
34
  "fetching": "Fetching {{ path }}...",
35
35
  "errors": {
36
- "fetchFail": "An error occured fetching JSON file."
36
+ "fetchFail": "An error occurred fetching JSON file."
37
37
  }
38
38
  },
39
39
  "fetchReleaseData": {
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "createTmpDirSync": {
132
132
  "errors": {
133
- "writeFailed": "An error occured writing temporary project source."
133
+ "writeFailed": "An error occurred writing temporary project source."
134
134
  }
135
135
  },
136
136
  "cleanupTmpDirSync": {
package/lib/archive.js CHANGED
@@ -65,7 +65,7 @@ async function copySourceToDest(src, dest, { sourceDir, includesRootDir = true,
65
65
  if (!rootDir) {
66
66
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.copySourceToDest.sourceEmpty`));
67
67
  // Create the dest path if it doesn't already exist
68
- fs_extra_1.default.ensureDir(dest);
68
+ await fs_extra_1.default.ensureDir(dest);
69
69
  // No root found so nothing to copy
70
70
  return true;
71
71
  }
@@ -88,11 +88,11 @@ async function copySourceToDest(src, dest, { sourceDir, includesRootDir = true,
88
88
  }
89
89
  return false;
90
90
  }
91
- function cleanupTempDir(tmpDir) {
91
+ async function cleanupTempDir(tmpDir) {
92
92
  if (!tmpDir)
93
93
  return;
94
94
  try {
95
- fs_extra_1.default.remove(tmpDir);
95
+ await fs_extra_1.default.remove(tmpDir);
96
96
  }
97
97
  catch (e) {
98
98
  logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.cleanupTempDir.error`, { tmpDir }));
@@ -109,7 +109,7 @@ async function extractZipArchive(zip, name, dest, { sourceDir, includesRootDir,
109
109
  hideLogs,
110
110
  });
111
111
  }
112
- cleanupTempDir(tmpDir);
112
+ await cleanupTempDir(tmpDir);
113
113
  }
114
114
  return success;
115
115
  }
@@ -103,7 +103,7 @@ const defaultUploadFinalErrorCallback = (accountId, file, destPath, error) => {
103
103
  });
104
104
  };
105
105
  async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOptions = {}, filePaths = [], mode = null) {
106
- const { saveOutput, convertFields, onAttemptCallback, onSuccessCallback, onFirstErrorCallback, onRetryCallback, onFinalErrorCallback } = commandOptions;
106
+ const { saveOutput, convertFields, onAttemptCallback, onSuccessCallback, onFirstErrorCallback, onRetryCallback, onFinalErrorCallback, } = commandOptions;
107
107
  const _onAttemptCallback = onAttemptCallback || defaultUploadAttemptCallback;
108
108
  const _onSuccessCallback = onSuccessCallback || defaultUploadSuccessCallback;
109
109
  const _onFirstErrorCallback = onFirstErrorCallback || defaultUploadFirstErrorCallback;
package/lib/github.d.ts CHANGED
@@ -11,6 +11,7 @@ type CloneGithubRepoOptions = {
11
11
  sourceDir?: string;
12
12
  };
13
13
  export declare function cloneGithubRepo(repoPath: RepoPath, dest: string, options?: CloneGithubRepoOptions): Promise<boolean>;
14
+ export declare function fetchGitHubRepoContentFromDownloadUrl(dest: string, downloadUrl: string): Promise<void>;
14
15
  export declare function downloadGithubRepoContents(repoPath: RepoPath, contentPath: string, dest: string, ref?: string, filter?: (contentPiecePath: string, downloadPath: string) => boolean): Promise<void>;
15
16
  export declare function listGithubRepoContents(repoPath: RepoPath, contentPath: string, fileFilter?: 'file' | 'dir'): Promise<GithubRepoFile[]>;
16
17
  export {};
package/lib/github.js CHANGED
@@ -3,7 +3,7 @@ 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.listGithubRepoContents = 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
9
  const standardErrors_1 = require("../errors/standardErrors");
@@ -88,11 +88,17 @@ async function cloneGithubRepo(repoPath, dest, options = {}) {
88
88
  exports.cloneGithubRepo = cloneGithubRepo;
89
89
  async function fetchGitHubRepoContentFromDownloadUrl(dest, downloadUrl) {
90
90
  const resp = await (0, github_1.fetchRepoFileByDownloadUrl)(downloadUrl);
91
- const fileContents = typeof resp.data === 'string'
92
- ? resp.data
93
- : JSON.stringify(resp.data, null, 2);
94
- fs_extra_1.default.outputFileSync(dest, fileContents, 'utf8');
91
+ const contentType = resp.headers['content-type'];
92
+ let fileContents;
93
+ if (contentType.startsWith('text')) {
94
+ fileContents = Buffer.from(resp.data).toString('utf8');
95
+ }
96
+ else {
97
+ fileContents = resp.data;
98
+ }
99
+ await fs_extra_1.default.outputFileSync(dest, fileContents);
95
100
  }
101
+ exports.fetchGitHubRepoContentFromDownloadUrl = fetchGitHubRepoContentFromDownloadUrl;
96
102
  // Writes files from a public repository to the destination folder
97
103
  async function downloadGithubRepoContents(repoPath, contentPath, dest, ref, filter) {
98
104
  fs_extra_1.default.ensureDirSync(path_1.default.dirname(dest));
package/lib/path.d.ts CHANGED
@@ -9,3 +9,5 @@ export declare function getExt(filepath: string): string;
9
9
  export declare function getAllowedExtensions(allowList?: Array<string>): Set<string>;
10
10
  export declare function isAllowedExtension(filepath: string, allowList?: Array<string>): boolean;
11
11
  export declare function getAbsoluteFilePath(_path: string): string;
12
+ export declare function sanitizeFileName(fileName: string): string;
13
+ export declare function isValidPath(_path: string): boolean;
package/lib/path.js CHANGED
@@ -3,7 +3,7 @@ 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.getAbsoluteFilePath = exports.isAllowedExtension = exports.getAllowedExtensions = exports.getExt = exports.getCwd = exports.splitHubSpotPath = exports.splitLocalPath = exports.convertToLocalFileSystemPath = exports.convertToUnixPath = void 0;
6
+ exports.isValidPath = exports.sanitizeFileName = exports.getAbsoluteFilePath = exports.isAllowedExtension = exports.getAllowedExtensions = exports.getExt = exports.getCwd = exports.splitHubSpotPath = exports.splitLocalPath = exports.convertToLocalFileSystemPath = exports.convertToUnixPath = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const unixify_1 = __importDefault(require("unixify"));
9
9
  const extensions_1 = require("../constants/extensions");
@@ -87,3 +87,36 @@ function getAbsoluteFilePath(_path) {
87
87
  return path_1.default.resolve(getCwd(), _path);
88
88
  }
89
89
  exports.getAbsoluteFilePath = getAbsoluteFilePath;
90
+ // Reserved names (Windows specific)
91
+ const reservedNames = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i;
92
+ // Based on the node-sanitize-filename package: https://github.com/parshap/node-sanitize-filename/blob/master/index.js
93
+ function sanitizeFileName(fileName) {
94
+ // Windows invalid/control characters
95
+ // eslint-disable-next-line no-control-regex
96
+ const invalidChars = /[<>:"/|?*\x00-\x1F]/g;
97
+ //Replace invalid characters with dash
98
+ let sanitizedFileName = fileName.replace(invalidChars, '-');
99
+ // Removes trailing periods and spaces for Windows
100
+ sanitizedFileName = sanitizedFileName.replace(/[. ]+$/, '');
101
+ //Reserved names check for Windows
102
+ if (reservedNames.test(sanitizedFileName)) {
103
+ sanitizedFileName = `-${sanitizedFileName}`;
104
+ }
105
+ return sanitizedFileName;
106
+ }
107
+ exports.sanitizeFileName = sanitizeFileName;
108
+ // Based on the node-sanitize-filename package: https://github.com/parshap/node-sanitize-filename/blob/master/index.js
109
+ function isValidPath(_path) {
110
+ // Invalid characters excluding forward slash
111
+ // eslint-disable-next-line no-control-regex
112
+ const invalidChars = /[<>:"|?*\x00-\x1F]/;
113
+ const baseName = path_1.default.basename(_path);
114
+ if (invalidChars.test(baseName)) {
115
+ return false;
116
+ }
117
+ if (reservedNames.test(baseName)) {
118
+ return false;
119
+ }
120
+ return true;
121
+ }
122
+ exports.isValidPath = isValidPath;
package/lib/sandboxes.js CHANGED
@@ -51,8 +51,7 @@ async function initiateSync(fromHubId, toHubId, tasks, sandboxHubId) {
51
51
  exports.initiateSync = initiateSync;
52
52
  async function fetchTaskStatus(accountId, taskId) {
53
53
  try {
54
- const result = await (0, sandboxSync_1.fetchTaskStatus)(accountId, taskId);
55
- return result;
54
+ return await (0, sandboxSync_1.fetchTaskStatus)(accountId, taskId);
56
55
  }
57
56
  catch (err) {
58
57
  (0, apiErrors_1.throwApiError)(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/local-dev-lib",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
5
5
  "main": "lib/index.js",
6
6
  "repository": {
@@ -16,15 +16,15 @@
16
16
  "check-main": "branch=$(git rev-parse --abbrev-ref HEAD) && [ $branch = main ] || (echo 'Error: New release can only be published on main branch' && exit 1)",
17
17
  "clear-postinstall": "cd dist && npm pkg delete scripts.postinstall",
18
18
  "copy-files": "cp -r lang dist/lang",
19
- "lint": "eslint --max-warnings=0 . && prettier --check ./**/*.ts",
19
+ "lint": "eslint --max-warnings=0 . && prettier . --check",
20
20
  "local-dev": "yarn build && cd dist && yarn link && cd .. && tsc --watch --rootDir . --outdir dist",
21
- "prettier:write": "prettier --write ./**/*.{ts,js,json}",
21
+ "prettier:write": "prettier . --write",
22
22
  "pub": "cd dist && npm publish --tag latest && cd ..",
23
23
  "push": "git push --atomic origin main v$npm_package_version",
24
24
  "release:major": "yarn check-main && yarn version --major && yarn build && yarn pub && yarn push",
25
25
  "release:minor": "yarn check-main && yarn version --minor && yarn build && yarn pub && yarn push",
26
26
  "release:patch": "yarn check-main && yarn version --patch && yarn build && yarn pub && yarn push",
27
- "test": "node --experimental-vm-modules ./node_modules/.bin/jest"
27
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ./node_modules/.bin/jest"
28
28
  },
29
29
  "license": "Apache-2.0",
30
30
  "devDependencies": {
@@ -37,7 +37,6 @@
37
37
  "@types/jest": "^29.5.0",
38
38
  "@types/js-yaml": "^4.0.5",
39
39
  "@types/node": "^18.14.2",
40
- "@types/prettier": "^3.0.0",
41
40
  "@types/unixify": "^1.0.0",
42
41
  "@typescript-eslint/eslint-plugin": "^5.54.0",
43
42
  "@typescript-eslint/parser": "^5.59.7",
@@ -72,7 +71,7 @@
72
71
  "js-yaml": "^4.1.0",
73
72
  "moment": "^2.29.4",
74
73
  "p-queue": "^6.0.2",
75
- "prettier": "^3.0.3",
74
+ "prettier": "^3.3.0",
76
75
  "semver": "^6.3.0",
77
76
  "unixify": "^1.0.0"
78
77
  },
package/types/Apps.d.ts CHANGED
@@ -6,6 +6,13 @@ export type PublicAppInstallationData = {
6
6
  name: string;
7
7
  }>;
8
8
  };
9
+ export type PublicAppDeveloperTestAccountInstallData = {
10
+ testPortalInstalls: Array<{
11
+ portalId: number;
12
+ accountName: string;
13
+ }>;
14
+ testPortalInstallCount: string;
15
+ };
9
16
  export type PublicApp = {
10
17
  id: number;
11
18
  name: string;
@@ -13,7 +13,6 @@ export type File = {
13
13
  friendly_url: string;
14
14
  meta: {
15
15
  allows_anonymous_access: boolean;
16
- charset_guess: string;
17
16
  line_count: number;
18
17
  indexable: boolean;
19
18
  };