@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 +1 -0
- package/api/appsDev.js +10 -1
- package/api/crm.d.ts +3 -0
- package/api/crm.js +29 -0
- package/api/github.js +28 -22
- package/api/localDevAuth.d.ts +1 -1
- package/config/config_DEPRECATED.js +2 -4
- package/lang/en.json +16 -7
- package/lib/cms/uploadFolder.js +35 -13
- package/lib/crm.d.ts +6 -0
- package/lib/crm.js +55 -0
- package/lib/hubdb.d.ts +1 -1
- package/lib/isDeepEqual.d.ts +1 -0
- package/lib/isDeepEqual.js +35 -0
- package/package.json +4 -2
- package/types/Crm.d.ts +26 -0
- package/types/Crm.js +2 -0
- package/types/Deploy.d.ts +1 -2
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
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
|
|
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
|
-
|
|
45
|
-
|
|
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
|
|
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
|
|
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;
|
package/api/localDevAuth.d.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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": "
|
|
247
|
-
"noConfigAccounts": "
|
|
248
|
-
"emptyAccountConfig": "
|
|
249
|
-
"noAccountId": "
|
|
250
|
-
"duplicateAccountIds": "
|
|
251
|
-
"duplicateAccountNames": "
|
|
252
|
-
"nameContainsSpaces": "
|
|
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.",
|
package/lib/cms/uploadFolder.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
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.
|
|
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.
|
|
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
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 {};
|