@hubspot/local-dev-lib 0.4.1-experimental.0 → 0.4.2-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/api/appsDev.d.ts CHANGED
@@ -5,3 +5,4 @@ export declare function fetchPublicAppDeveloperTestAccountInstallData(appId: num
5
5
  export declare function fetchPublicAppProductionInstallCounts(appId: number, accountId: number): HubSpotPromise<PublicAppInstallCounts>;
6
6
  export declare function fetchPublicAppMetadata(appId: number, accountId: number): HubSpotPromise<PublicApp>;
7
7
  export declare function installStaticAuthAppOnTestAccount(appId: number, accountId: number, scopeGroupIds: number[]): HubSpotPromise<void>;
8
+ export declare function fetchAppMetadataByUid(appUid: string, accountId: number): HubSpotPromise<PublicApp>;
package/api/appsDev.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installStaticAuthAppOnTestAccount = exports.fetchPublicAppMetadata = exports.fetchPublicAppProductionInstallCounts = exports.fetchPublicAppDeveloperTestAccountInstallData = exports.fetchPublicAppsForPortal = void 0;
3
+ exports.fetchAppMetadataByUid = exports.installStaticAuthAppOnTestAccount = exports.fetchPublicAppMetadata = exports.fetchPublicAppProductionInstallCounts = exports.fetchPublicAppDeveloperTestAccountInstallData = exports.fetchPublicAppsForPortal = void 0;
4
4
  const http_1 = require("../http");
5
5
  const APPS_DEV_API_PATH = 'apps-dev/external/public/v3';
6
6
  const APPS_HUBLETS_API_PATH = 'apps-hublets/external/static-token/v3';
@@ -39,3 +39,12 @@ function installStaticAuthAppOnTestAccount(appId, accountId, scopeGroupIds) {
39
39
  });
40
40
  }
41
41
  exports.installStaticAuthAppOnTestAccount = installStaticAuthAppOnTestAccount;
42
+ function fetchAppMetadataByUid(appUid, accountId) {
43
+ return http_1.http.get(accountId, {
44
+ url: `${APPS_DEV_API_PATH}/full/portal/sourceId`,
45
+ params: {
46
+ sourceId: appUid,
47
+ },
48
+ });
49
+ }
50
+ exports.fetchAppMetadataByUid = fetchAppMetadataByUid;
package/api/crm.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { HubSpotPromise } from '../types/Http';
2
+ import { ImportRequest, ImportResponse } from '../types/Crm';
3
+ export declare function createImport(accountId: number, importRequest: ImportRequest, dataFileNames: string[]): HubSpotPromise<ImportResponse>;
package/api/crm.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createImport = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const form_data_1 = __importDefault(require("form-data"));
10
+ const http_1 = require("../http");
11
+ const path_2 = require("../lib/path");
12
+ const HUBSPOT_CRM_IMPORT_PATH = '/crm/v3/imports';
13
+ function createImport(accountId, importRequest, dataFileNames) {
14
+ const jsonImportRequest = JSON.stringify(importRequest);
15
+ const formData = new form_data_1.default();
16
+ formData.append('importRequest', jsonImportRequest);
17
+ dataFileNames.forEach(file => {
18
+ const stream = fs_extra_1.default.createReadStream(path_1.default.resolve((0, path_2.getCwd)(), file));
19
+ formData.append('files', stream, file);
20
+ });
21
+ return http_1.http.post(accountId, {
22
+ url: `${HUBSPOT_CRM_IMPORT_PATH}`,
23
+ data: formData,
24
+ headers: {
25
+ ...formData.getHeaders(),
26
+ },
27
+ });
28
+ }
29
+ exports.createImport = createImport;
package/api/github.js CHANGED
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.fetchRepoContents = exports.fetchRepoFileByDownloadUrl = exports.fetchRepoFile = exports.fetchRepoAsZip = exports.fetchRepoReleaseData = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const getAxiosConfig_1 = require("../http/getAxiosConfig");
9
+ const errors_1 = require("../errors");
9
10
  const GITHUB_REPOS_API = 'https://api.github.com/repos';
10
11
  const GITHUB_RAW_CONTENT_API_PATH = 'https://raw.githubusercontent.com';
11
12
  function getAdditionalHeaders() {
@@ -18,16 +19,33 @@ function getAdditionalHeaders() {
18
19
  }
19
20
  return headers;
20
21
  }
22
+ function githubRequestWithFallback(url, responseType) {
23
+ const headersWithAuth = {
24
+ ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(),
25
+ ...getAdditionalHeaders(),
26
+ };
27
+ if (headersWithAuth.authorization) {
28
+ return axios_1.default
29
+ .get(url, { headers: headersWithAuth, responseType })
30
+ .catch(error => {
31
+ // 404 with an auth token might mean an SSO issue so retry without the authorization header
32
+ if ((0, errors_1.isSpecifiedError)(error, { statusCode: 404 })) {
33
+ return axios_1.default.get(url, {
34
+ headers: { ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)() },
35
+ responseType,
36
+ });
37
+ }
38
+ throw error;
39
+ });
40
+ }
41
+ // No auth token, proceed normally
42
+ return axios_1.default.get(url, { headers: headersWithAuth, responseType });
43
+ }
21
44
  // Returns information about the repo's releases. Defaults to "latest" if no tag is provided
22
45
  // https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#get-a-release-by-tag-name
23
46
  function fetchRepoReleaseData(repoPath, tag = '') {
24
47
  const URL = `${GITHUB_REPOS_API}/${repoPath}/releases`;
25
- return axios_1.default.get(`${URL}/${tag ? `tags/${tag}` : 'latest'}`, {
26
- headers: {
27
- ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(),
28
- ...getAdditionalHeaders(),
29
- },
30
- });
48
+ return githubRequestWithFallback(`${URL}/${tag ? `tags/${tag}` : 'latest'}`);
31
49
  }
32
50
  exports.fetchRepoReleaseData = fetchRepoReleaseData;
33
51
  // Returns the entire repo content as a zip, using the zipball_url from fetchRepoReleaseData()
@@ -41,31 +59,19 @@ function fetchRepoAsZip(zipUrl) {
41
59
  exports.fetchRepoAsZip = fetchRepoAsZip;
42
60
  // Returns the raw file contents via the raw.githubusercontent endpoint
43
61
  function fetchRepoFile(repoPath, filePath, ref) {
44
- return axios_1.default.get(`${GITHUB_RAW_CONTENT_API_PATH}/${repoPath}/${ref}/${filePath}`, {
45
- headers: {
46
- ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(),
47
- ...getAdditionalHeaders(),
48
- },
49
- });
62
+ const url = `${GITHUB_RAW_CONTENT_API_PATH}/${repoPath}/${ref}/${filePath}`;
63
+ return githubRequestWithFallback(url);
50
64
  }
51
65
  exports.fetchRepoFile = fetchRepoFile;
52
66
  // Returns the raw file contents via the raw.githubusercontent endpoint
53
67
  function fetchRepoFileByDownloadUrl(downloadUrl) {
54
- return axios_1.default.get(downloadUrl, {
55
- headers: { ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(), ...getAdditionalHeaders() },
56
- responseType: 'arraybuffer',
57
- });
68
+ return githubRequestWithFallback(downloadUrl, 'arraybuffer');
58
69
  }
59
70
  exports.fetchRepoFileByDownloadUrl = fetchRepoFileByDownloadUrl;
60
71
  // Returns the contents of a file or directory in a repository by path
61
72
  // https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content
62
73
  function fetchRepoContents(repoPath, path, ref) {
63
74
  const refQuery = ref ? `?ref=${ref}` : '';
64
- return axios_1.default.get(`${GITHUB_REPOS_API}/${repoPath}/contents/${path}${refQuery}`, {
65
- headers: {
66
- ...(0, getAxiosConfig_1.getDefaultUserAgentHeader)(),
67
- ...getAdditionalHeaders(),
68
- },
69
- });
75
+ return githubRequestWithFallback(`${GITHUB_REPOS_API}/${repoPath}/contents/${path}${refQuery}`);
70
76
  }
71
77
  exports.fetchRepoContents = fetchRepoContents;
@@ -7,4 +7,4 @@ export declare function fetchAccessToken(personalAccessKey: string, env?: Enviro
7
7
  export declare function fetchScopeData(accountId: number, scopeGroup: string): HubSpotPromise<ScopeData>;
8
8
  export declare function fetchScopeAuthorizationData(accountId: number): HubSpotPromise<ScopeAuthorizationResponse>;
9
9
  export declare function fetchAppInstallationData(portalId: number, projectId: number, appUid: string, requiredScopeGroups: Array<string>, optionalScopeGroups?: Array<string>): HubSpotPromise<PublicAppInstallationData>;
10
- export declare function fetchEnabledFeatures(accountId: number): Promise<import("axios").AxiosResponse<EnabledFeaturesResponse, any>>;
10
+ export declare function fetchEnabledFeatures(accountId: number): Promise<import("axios").AxiosResponse<EnabledFeaturesResponse, any, {}>>;
@@ -14,7 +14,6 @@ const auth_1 = require("../constants/auth");
14
14
  const files_1 = require("../constants/files");
15
15
  const environment_1 = require("../lib/environment");
16
16
  const logger_1 = require("../lib/logger");
17
- const git_1 = require("../utils/git");
18
17
  const errors_DEPRECATED_1 = require("../errors/errors_DEPRECATED");
19
18
  const ALL_CMS_PUBLISH_MODES = Object.values(files_1.CMS_PUBLISH_MODE);
20
19
  let _config;
@@ -191,12 +190,11 @@ function readConfigFile() {
191
190
  return { source, error };
192
191
  }
193
192
  try {
194
- (0, git_1.isConfigPathInGitRepo)(_configPath);
195
193
  source = fs_extra_1.default.readFileSync(_configPath);
196
194
  }
197
195
  catch (err) {
198
196
  error = err;
199
- logger_1.logger.error('Config file could not be read "%s"', _configPath);
197
+ logger_1.logger.error(`Config file could not be read: ${_configPath}`);
200
198
  (0, errors_DEPRECATED_1.logFileSystemErrorInstance)(error, {
201
199
  filepath: _configPath,
202
200
  operation: 'read',
@@ -215,7 +213,7 @@ function parseConfig(configSource) {
215
213
  }
216
214
  catch (err) {
217
215
  error = err;
218
- logger_1.logger.error('Config file could not be parsed "%s"', _configPath);
216
+ logger_1.logger.error(`Config file could not be parsed: ${_configPath}`);
219
217
  (0, errors_DEPRECATED_1.logErrorInstance)(err);
220
218
  }
221
219
  return { parsed, error };
package/lang/en.json CHANGED
@@ -78,6 +78,15 @@
78
78
  "invalidPersonalAccessKey": "Error while retrieving new access token: {{ errorMessage }}"
79
79
  }
80
80
  },
81
+ "crm": {
82
+ "importData": {
83
+ "errors": {
84
+ "fileNotFound": "The file {{ fileName }} does not exist",
85
+ "notJson": "You must provide a JSON file for the import data request schema.",
86
+ "noFiles": "You must provide at least one data file for the import data request schema."
87
+ }
88
+ }
89
+ },
81
90
  "cms": {
82
91
  "modules": {
83
92
  "createModule": {
@@ -243,13 +252,13 @@
243
252
  "empty": "The config file was empty. Initializing an empty config."
244
253
  },
245
254
  "validate": {
246
- "noConfig": "Valiation failed: No config was found.",
247
- "noConfigAccounts": "Valiation failed: config.accounts[] is not defined.",
248
- "emptyAccountConfig": "Valiation failed: config.accounts[] has an empty entry.",
249
- "noAccountId": "Valiation failed: config.accounts[] has an entry missing accountId.",
250
- "duplicateAccountIds": "Valiation failed: config.accounts[] has multiple entries with {{ accountId }}.",
251
- "duplicateAccountNames": "Valiation failed: config.accounts[] has multiple entries with {{ accountName }}.",
252
- "nameContainsSpaces": "Valiation failed: config.name {{ accountName }} cannot contain spaces."
255
+ "noConfig": "Validation failed: No config was found.",
256
+ "noConfigAccounts": "Validation failed: config.accounts[] is not defined.",
257
+ "emptyAccountConfig": "Validation failed: config.accounts[] has an empty entry.",
258
+ "noAccountId": "Validation failed: config.accounts[] has an entry missing accountId.",
259
+ "duplicateAccountIds": "Validation failed: config.accounts[] has multiple entries with {{ accountId }}.",
260
+ "duplicateAccountNames": "Validation failed: config.accounts[] has multiple entries with {{ accountName }}.",
261
+ "nameContainsSpaces": "Validation failed: config.name {{ accountName }} cannot contain spaces."
253
262
  },
254
263
  "updateAccount": {
255
264
  "noConfigToUpdate": "No config to update.",
@@ -38,6 +38,16 @@ function getFileType(filePath) {
38
38
  return files_1.FILE_TYPES.other;
39
39
  }
40
40
  }
41
+ function isMetaJsonFile(filePath) {
42
+ return path_1.default.basename(filePath).toLowerCase() === 'meta.json';
43
+ }
44
+ function resolveUploadPath(file, fieldsJsPaths, tmpDirRegex, regex, dest) {
45
+ const fieldsJsFileInfo = fieldsJsPaths.find(f => f.outputPath === file);
46
+ const relativePath = file.replace(fieldsJsFileInfo ? tmpDirRegex : regex, '');
47
+ const destPath = (0, path_2.convertToUnixPath)(path_1.default.join(dest, relativePath));
48
+ const originalFilePath = fieldsJsFileInfo ? fieldsJsFileInfo.filePath : file;
49
+ return { fieldsJsFileInfo, relativePath, destPath, originalFilePath };
50
+ }
41
51
  async function getFilesByType(filePaths, projectDir, rootWriteDir, commandOptions) {
42
52
  const { convertFields, fieldOptions } = commandOptions;
43
53
  const projectDirRegex = new RegExp(`^${(0, escapeRegExp_1.escapeRegExp)(projectDir)}`);
@@ -106,6 +116,12 @@ const defaultUploadFinalErrorCallback = (accountId, file, destPath, error) => {
106
116
  payload: file,
107
117
  });
108
118
  };
119
+ async function uploadMetaJsonFiles(moduleFiles, uploadFile) {
120
+ const moduleMetaJsonFiles = moduleFiles.filter(isMetaJsonFile);
121
+ if (moduleMetaJsonFiles.length > 0) {
122
+ await queue.addAll(moduleMetaJsonFiles.map(uploadFile));
123
+ }
124
+ }
109
125
  async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOptions = {}, filePaths = [], cmsPublishMode = null) {
110
126
  const { saveOutput, convertFields, onAttemptCallback, onSuccessCallback, onFirstErrorCallback, onRetryCallback, onFinalErrorCallback, } = commandOptions;
111
127
  const _onAttemptCallback = onAttemptCallback || defaultUploadAttemptCallback;
@@ -120,23 +136,15 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
120
136
  const apiOptions = (0, fileMapper_1.getFileMapperQueryValues)(cmsPublishMode, fileMapperOptions);
121
137
  const failures = [];
122
138
  let fieldsJsPaths = [];
123
- let tmpDirRegex;
139
+ const tmpDirRegex = new RegExp(`^${(0, escapeRegExp_1.escapeRegExp)(tmpDir || '')}`);
124
140
  const [filesByType, fieldsJsObjects] = await getFilesByType(filePaths, src, tmpDir, commandOptions);
125
- const fileList = Object.values(filesByType);
126
141
  if (fieldsJsObjects.length) {
127
142
  fieldsJsPaths = fieldsJsObjects.map(fieldsJs => {
128
143
  return { outputPath: fieldsJs.outputPath, filePath: fieldsJs.filePath };
129
144
  });
130
- tmpDirRegex = new RegExp(`^${(0, escapeRegExp_1.escapeRegExp)(tmpDir || '')}`);
131
145
  }
132
146
  function uploadFile(file) {
133
- const fieldsJsFileInfo = fieldsJsPaths.find(f => f.outputPath === file);
134
- const originalFilePath = fieldsJsFileInfo
135
- ? fieldsJsFileInfo.filePath
136
- : file;
137
- // files in fieldsJsPaths always belong to the tmp directory.
138
- const relativePath = file.replace(fieldsJsFileInfo ? tmpDirRegex : regex, '');
139
- const destPath = (0, path_2.convertToUnixPath)(path_1.default.join(dest, relativePath));
147
+ const { originalFilePath, destPath } = resolveUploadPath(file, fieldsJsPaths, tmpDirRegex, regex, dest);
140
148
  return async () => {
141
149
  _onAttemptCallback(originalFilePath, destPath);
142
150
  try {
@@ -155,9 +163,23 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
155
163
  }
156
164
  };
157
165
  }
158
- for (let i = 0; i < fileList.length; i++) {
159
- const filesToUpload = fileList[i];
160
- await queue.addAll(filesToUpload.map(uploadFile));
166
+ // Upload all meta.json files first
167
+ await uploadMetaJsonFiles(filesByType[files_1.FILE_TYPES.module] || [], uploadFile);
168
+ // Collect all remaining files for upload
169
+ const deferredFiles = [];
170
+ Object.entries(filesByType).forEach(([fileType, files]) => {
171
+ if (fileType === files_1.FILE_TYPES.module) {
172
+ // Add non-meta.json module files
173
+ deferredFiles.push(...files.filter(f => !isMetaJsonFile(f)));
174
+ }
175
+ else {
176
+ // Add all non-module files
177
+ deferredFiles.push(...files);
178
+ }
179
+ });
180
+ // Upload all remaining files concurrently
181
+ if (deferredFiles.length > 0) {
182
+ await queue.addAll(deferredFiles.map(uploadFile));
161
183
  }
162
184
  const results = await queue
163
185
  .addAll(failures.map(({ file, destPath }) => {
package/lib/crm.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { ImportRequest } from '../types/Crm';
2
+ export declare function getImportDataRequest(fileName: string): {
3
+ importRequest: ImportRequest;
4
+ dataFileNames: string[];
5
+ };
6
+ export declare function validateImportRequestFile(fileName: string): void;
package/lib/crm.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateImportRequestFile = exports.getImportDataRequest = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const path_2 = require("./path");
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const lang_1 = require("../utils/lang");
11
+ function getImportDataRequest(fileName) {
12
+ validateImportRequestFile(fileName);
13
+ const importRequest = fs_extra_1.default.readJsonSync(path_1.default.resolve((0, path_2.getCwd)(), fileName));
14
+ const dataFileNames = importRequest.files.map(file => file.fileName);
15
+ // allow relative paths in the provided import request
16
+ importRequest.files = importRequest.files.map(file => ({
17
+ ...file,
18
+ fileName: path_1.default.basename(file.fileName),
19
+ }));
20
+ if (dataFileNames.length === 0) {
21
+ throw new Error((0, lang_1.i18n)('lib.crm.importData.errors.noFiles'));
22
+ }
23
+ dataFileNames.forEach(fileName => {
24
+ if (!fileExists(fileName)) {
25
+ throw new Error((0, lang_1.i18n)('lib.crm.importData.errors.fileNotFound', { fileName }));
26
+ }
27
+ });
28
+ return { importRequest, dataFileNames };
29
+ }
30
+ exports.getImportDataRequest = getImportDataRequest;
31
+ function validateImportRequestFile(fileName) {
32
+ if (!fileExists(fileName)) {
33
+ throw new Error((0, lang_1.i18n)('lib.crm.importData.errors.fileNotFound', { fileName }));
34
+ }
35
+ if (path_1.default.extname(fileName) !== '.json') {
36
+ throw new Error((0, lang_1.i18n)('lib.crm.importData.errors.notJson'));
37
+ }
38
+ }
39
+ exports.validateImportRequestFile = validateImportRequestFile;
40
+ function fileExists(_path) {
41
+ try {
42
+ const absoluteSrcPath = path_1.default.resolve((0, path_2.getCwd)(), _path);
43
+ if (!absoluteSrcPath)
44
+ return false;
45
+ const stats = fs_extra_1.default.statSync(absoluteSrcPath);
46
+ const isFile = stats.isFile();
47
+ if (!isFile) {
48
+ return false;
49
+ }
50
+ }
51
+ catch (e) {
52
+ return false;
53
+ }
54
+ return true;
55
+ }
package/lib/hubdb.d.ts CHANGED
@@ -8,7 +8,7 @@ export declare function createHubDbTable(accountId: number, src: string): Promis
8
8
  tableId: string;
9
9
  rowCount: number;
10
10
  }>;
11
- export declare function updateHubDbTable(accountId: number, tableId: string, src: string): Promise<AxiosResponse<Table, any>>;
11
+ export declare function updateHubDbTable(accountId: number, tableId: string, src: string): Promise<AxiosResponse<Table, any, {}>>;
12
12
  export declare function downloadHubDbTable(accountId: number, tableId: string, dest: string): Promise<{
13
13
  filePath: string;
14
14
  }>;
@@ -0,0 +1 @@
1
+ export declare function isDeepEqual(object1: unknown, object2: unknown, ignoreKeys?: string[]): boolean;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDeepEqual = void 0;
4
+ function isDeepEqual(object1, object2, ignoreKeys) {
5
+ if (object1 === object2) {
6
+ return true;
7
+ }
8
+ if (object1 === null ||
9
+ object2 === null ||
10
+ typeof object1 !== 'object' ||
11
+ typeof object2 !== 'object') {
12
+ return object1 === object2;
13
+ }
14
+ if (typeof object1 !== typeof object2) {
15
+ return false;
16
+ }
17
+ const isArray1 = Array.isArray(object1);
18
+ const isArray2 = Array.isArray(object2);
19
+ if (isArray1 !== isArray2) {
20
+ return false;
21
+ }
22
+ const objKeys1 = Object.keys(object1).filter(key => !ignoreKeys?.includes(key));
23
+ const objKeys2 = Object.keys(object2).filter(key => !ignoreKeys?.includes(key));
24
+ if (objKeys1.length !== objKeys2.length)
25
+ return false;
26
+ for (const key of objKeys1) {
27
+ const value1 = object1[key];
28
+ const value2 = object2[key];
29
+ if (!isDeepEqual(value1, value2, ignoreKeys)) {
30
+ return false;
31
+ }
32
+ }
33
+ return true;
34
+ }
35
+ exports.isDeepEqual = isDeepEqual;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/local-dev-lib",
3
- "version": "0.4.1-experimental.0",
3
+ "version": "0.4.2-experimental.0",
4
4
  "description": "Provides library functionality for HubSpot local development tooling, including the HubSpot CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "license": "Apache-2.0",
22
22
  "devDependencies": {
23
+ "@hubspot/npm-scripts": "0.0.4-beta.0",
23
24
  "@inquirer/prompts": "^7.0.1",
24
25
  "@types/content-disposition": "^0.5.5",
25
26
  "@types/cors": "^2.8.15",
@@ -61,7 +62,7 @@
61
62
  },
62
63
  "dependencies": {
63
64
  "address": "2.0.2",
64
- "axios": "1.8.4",
65
+ "axios": "1.12.0",
65
66
  "chalk": "2.4.2",
66
67
  "chokidar": "3.6.0",
67
68
  "content-disposition": "0.5.4",
@@ -70,6 +71,7 @@
70
71
  "express": "4.21.2",
71
72
  "extract-zip": "2.0.1",
72
73
  "findup-sync": "5.0.0",
74
+ "form-data": "^4.0.4",
73
75
  "fs-extra": "11.2.0",
74
76
  "ignore": "5.3.1",
75
77
  "js-yaml": "4.1.0",
package/types/Crm.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ export interface ImportRequest {
2
+ name: string;
3
+ importOperations: {
4
+ [objectTypeId: string]: 'CREATE' | 'UPDATE' | 'UPSERT';
5
+ };
6
+ dateFormat?: string;
7
+ marketableContactImport?: boolean;
8
+ createContactListFromImport?: boolean;
9
+ files: Array<{
10
+ fileName: string;
11
+ fileFormat: 'CSV' | 'XLSX' | 'XLS';
12
+ fileImportPage: {
13
+ hasHeader: boolean;
14
+ columnMappings: Array<{
15
+ columnObjectTypeId: string;
16
+ columnName: string;
17
+ propertyName: string;
18
+ columnType?: string;
19
+ }>;
20
+ };
21
+ }>;
22
+ }
23
+ export interface ImportResponse {
24
+ id: string;
25
+ state: 'STARTED' | 'PROCESSING' | 'DONE' | 'FAILED' | 'CANCELED' | 'DEFERRED';
26
+ }
package/types/Crm.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/types/Deploy.d.ts CHANGED
@@ -42,7 +42,7 @@ export type ProjectDeployResponseQueued = {
42
42
  status: string;
43
43
  };
44
44
  };
45
- type SubdeployValidationIssue = {
45
+ export type SubdeployValidationIssue = {
46
46
  uid: string;
47
47
  componentTypeName: string;
48
48
  errorMessages: string[];
@@ -56,4 +56,3 @@ export type ProjectDeployResponseBlocked = {
56
56
  issues: SubdeployValidationIssue[];
57
57
  };
58
58
  export type ProjectDeployResponse = ProjectDeployResponseQueued | ProjectDeployResponseBlocked;
59
- export {};