@hubspot/local-dev-lib 4.0.4 → 5.0.0-beta.1
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 +2 -2
- package/api/appsDev.js +13 -22
- package/api/crm.d.ts +2 -2
- package/api/crm.js +9 -16
- package/api/customObjects.d.ts +2 -2
- package/api/customObjects.js +13 -22
- package/api/designManager.d.ts +2 -2
- package/api/designManager.js +5 -10
- package/api/devSecrets.d.ts +2 -2
- package/api/devSecrets.js +9 -16
- package/api/developerTestAccounts.d.ts +2 -4
- package/api/developerTestAccounts.js +23 -52
- package/api/fileManager.d.ts +2 -2
- package/api/fileManager.js +14 -24
- package/api/fileMapper.d.ts +2 -3
- package/api/fileMapper.js +34 -49
- package/api/fileTransport.d.ts +1 -1
- package/api/fileTransport.js +12 -21
- package/api/fireAlarm.d.ts +2 -3
- package/api/fireAlarm.js +5 -9
- package/api/functions.d.ts +2 -2
- package/api/functions.js +11 -19
- package/api/github.d.ts +2 -4
- package/api/github.js +16 -27
- package/api/hubdb.d.ts +2 -2
- package/api/hubdb.js +19 -31
- package/api/lighthouseScore.d.ts +2 -2
- package/api/lighthouseScore.js +7 -13
- package/api/localDevAuth.d.ts +3 -6
- package/api/localDevAuth.js +10 -37
- package/api/marketplaceValidation.d.ts +2 -2
- package/api/marketplaceValidation.js +7 -13
- package/api/projects.d.ts +6 -8
- package/api/projects.js +65 -100
- package/api/sandboxHubs.d.ts +2 -5
- package/api/sandboxHubs.js +15 -42
- package/api/sandboxSync.d.ts +2 -2
- package/api/sandboxSync.js +7 -12
- package/api/secrets.d.ts +2 -2
- package/api/secrets.js +9 -16
- package/api/validateHubl.d.ts +2 -2
- package/api/validateHubl.js +3 -7
- package/config/defaultAccountOverride.d.ts +2 -1
- package/config/defaultAccountOverride.js +16 -26
- package/config/index.d.ts +4 -4
- package/config/index.js +141 -177
- package/config/migrate.d.ts +2 -2
- package/config/migrate.js +26 -37
- package/config/state.d.ts +1 -1
- package/config/state.js +17 -45
- package/config/utils.d.ts +4 -4
- package/config/utils.js +85 -108
- package/constants/api.js +3 -6
- package/constants/auth.js +9 -12
- package/constants/config.js +37 -43
- package/constants/endpoints.d.ts +6 -0
- package/constants/endpoints.js +6 -0
- package/constants/environments.js +1 -4
- package/constants/extensions.js +6 -9
- package/constants/files.js +5 -8
- package/constants/ports.js +3 -6
- package/constants/projects.js +2 -5
- package/enums/build.d.ts +1 -0
- package/enums/build.js +6 -8
- package/enums/deploy.js +2 -5
- package/enums/project.js +1 -4
- package/errors/index.d.ts +4 -5
- package/errors/index.js +17 -39
- package/errors/isSystemError.d.ts +2 -0
- package/errors/isSystemError.js +9 -0
- package/http/addQueryParams.d.ts +1 -1
- package/http/addQueryParams.js +1 -5
- package/http/client.js +14 -42
- package/http/getAxiosConfig.d.ts +1 -1
- package/http/getAxiosConfig.js +21 -31
- package/http/index.d.ts +2 -2
- package/http/index.js +39 -46
- package/http/unauthed.d.ts +1 -1
- package/http/unauthed.js +15 -18
- package/lang/en.json +1 -1
- package/lib/archive.d.ts +1 -3
- package/lib/archive.js +37 -67
- package/lib/cms/functions.d.ts +1 -1
- package/lib/cms/functions.js +45 -55
- package/lib/cms/handleFieldsJS.js +36 -44
- package/lib/cms/modules.d.ts +2 -2
- package/lib/cms/modules.js +49 -59
- package/lib/cms/processFieldsJs.js +17 -32
- package/lib/cms/templates.js +17 -26
- package/lib/cms/themes.js +10 -18
- package/lib/cms/uploadFolder.d.ts +4 -4
- package/lib/cms/uploadFolder.js +55 -64
- package/lib/cms/validate.d.ts +1 -1
- package/lib/cms/validate.js +11 -18
- package/lib/cms/watch.d.ts +2 -2
- package/lib/cms/watch.js +66 -73
- package/lib/crm.d.ts +1 -1
- package/lib/crm.js +15 -23
- package/lib/customObjects.d.ts +1 -1
- package/lib/customObjects.js +15 -25
- package/lib/environment.d.ts +1 -1
- package/lib/environment.js +5 -11
- package/lib/escapeRegExp.js +1 -5
- package/lib/fileManager.js +43 -51
- package/lib/fileMapper.d.ts +1 -1
- package/lib/fileMapper.js +68 -84
- package/lib/fs.d.ts +1 -1
- package/lib/fs.js +18 -27
- package/lib/github.d.ts +1 -3
- package/lib/github.js +39 -51
- package/lib/gitignore.d.ts +1 -1
- package/lib/gitignore.js +16 -24
- package/lib/hubdb.d.ts +1 -1
- package/lib/hubdb.js +29 -40
- package/lib/ignoreRules.js +25 -34
- package/lib/isDeepEqual.js +1 -5
- package/lib/logger.d.ts +8 -20
- package/lib/logger.js +47 -59
- package/lib/notify.js +9 -16
- package/lib/oauth.d.ts +2 -2
- package/lib/oauth.js +12 -17
- package/lib/path.d.ts +0 -1
- package/lib/path.js +30 -48
- package/lib/personalAccessKey.d.ts +2 -4
- package/lib/personalAccessKey.js +43 -60
- package/lib/portManager.d.ts +2 -2
- package/lib/portManager.js +26 -41
- package/lib/text.js +2 -7
- package/lib/trackUsage.d.ts +0 -2
- package/lib/trackUsage.js +23 -29
- package/lib/urls.js +4 -9
- package/models/FileSystemError.d.ts +1 -1
- package/models/FileSystemError.js +12 -16
- package/models/HubSpotConfigError.d.ts +1 -1
- package/models/HubSpotConfigError.js +8 -12
- package/models/HubSpotHttpError.d.ts +1 -1
- package/models/HubSpotHttpError.js +22 -26
- package/models/OAuth2Manager.d.ts +1 -1
- package/models/OAuth2Manager.js +17 -24
- package/package.json +20 -16
- package/types/Accounts.d.ts +6 -5
- package/types/Accounts.js +1 -2
- package/types/Activity.d.ts +3 -3
- package/types/Activity.js +1 -2
- package/types/Api.d.ts +1 -1
- package/types/Api.js +1 -2
- package/types/Apps.js +1 -2
- package/types/Archive.js +1 -2
- package/types/Build.d.ts +4 -5
- package/types/Build.js +1 -2
- package/types/CLIOptions.js +1 -2
- package/types/ComponentStructure.d.ts +2 -2
- package/types/ComponentStructure.js +1 -2
- package/types/Config.d.ts +4 -6
- package/types/Config.js +1 -2
- package/types/Crm.js +1 -2
- package/types/Deploy.d.ts +5 -11
- package/types/Deploy.js +1 -2
- package/types/DesignManager.js +1 -2
- package/types/DevSecrets.js +1 -2
- package/types/Error.js +1 -2
- package/types/FieldsJS.js +1 -2
- package/types/FileManager.js +1 -2
- package/types/Files.d.ts +4 -4
- package/types/Files.js +1 -2
- package/types/FireAlarm.js +1 -2
- package/types/Functions.js +1 -2
- package/types/Github.d.ts +1 -1
- package/types/Github.js +1 -2
- package/types/Http.d.ts +0 -4
- package/types/Http.js +1 -2
- package/types/Hubdb.js +1 -2
- package/types/HublValidation.js +1 -2
- package/types/Lang.d.ts +1 -1
- package/types/Lang.js +1 -2
- package/types/Lighthouse.js +1 -2
- package/types/MarketplaceValidation.js +1 -2
- package/types/Migration.d.ts +2 -2
- package/types/Migration.js +1 -4
- package/types/Modules.js +1 -2
- package/types/PortManager.js +1 -2
- package/types/Project.d.ts +3 -21
- package/types/Project.js +1 -2
- package/types/ProjectComponents.d.ts +24 -0
- package/types/ProjectComponents.js +1 -0
- package/types/ProjectLog.js +1 -2
- package/types/Sandbox.js +2 -5
- package/types/Schemas.js +1 -2
- package/types/Secrets.js +1 -2
- package/types/Utils.js +1 -2
- package/types/developerTestAccounts.js +1 -2
- package/utils/PortManagerServer.d.ts +1 -2
- package/utils/PortManagerServer.js +32 -38
- package/utils/cms/fieldsJS.d.ts +1 -1
- package/utils/cms/fieldsJS.js +1 -5
- package/utils/cms/modules.d.ts +1 -1
- package/utils/cms/modules.js +13 -22
- package/utils/detectPort.js +12 -19
- package/utils/git.js +17 -26
- package/utils/lang.d.ts +1 -1
- package/utils/lang.js +5 -14
- package/utils/personalAccessKey.d.ts +8 -0
- package/utils/personalAccessKey.js +51 -0
- package/errors/errors_DEPRECATED.d.ts +0 -3
- package/errors/errors_DEPRECATED.js +0 -60
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const semver_1 = __importDefault(require("semver"));
|
|
10
|
-
const url_1 = require("url");
|
|
11
|
-
const path_2 = require("../path");
|
|
12
|
-
const lang_1 = require("../../utils/lang");
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { pathToFileURL } from 'url';
|
|
5
|
+
import { i18n } from '../../utils/lang.js';
|
|
13
6
|
const i18nKey = 'lib.cms.processFieldsJs';
|
|
14
7
|
const { dirName, fieldOptions, filePath, writeDir } = process.env;
|
|
15
|
-
const baseName =
|
|
8
|
+
const baseName = path.basename(filePath);
|
|
16
9
|
//TODO - Figure out agnostic logging
|
|
17
|
-
console.info(
|
|
10
|
+
console.info(i18n(`${i18nKey}.converting`, {
|
|
18
11
|
src: dirName + `/${baseName}`,
|
|
19
12
|
dest: dirName + '/fields.json',
|
|
20
13
|
}));
|
|
@@ -30,26 +23,26 @@ const fieldsPromise = dynamicImport(filePath).catch(e => {
|
|
|
30
23
|
fieldsPromise.then(fieldsFunc => {
|
|
31
24
|
const fieldsFuncType = typeof fieldsFunc;
|
|
32
25
|
if (fieldsFuncType !== 'function') {
|
|
33
|
-
throw new Error(
|
|
26
|
+
throw new Error(i18n(`${i18nKey}.errors.notFunction`, {
|
|
34
27
|
path: filePath,
|
|
35
28
|
returned: fieldsFuncType,
|
|
36
29
|
}));
|
|
37
30
|
}
|
|
38
31
|
return Promise.resolve(fieldsFunc(fieldOptions)).then(fields => {
|
|
39
32
|
if (!Array.isArray(fields)) {
|
|
40
|
-
throw new Error(
|
|
33
|
+
throw new Error(i18n(`${i18nKey}.errors.notArray`, {
|
|
41
34
|
path: filePath,
|
|
42
35
|
returned: typeof fields,
|
|
43
36
|
}));
|
|
44
37
|
}
|
|
45
|
-
const finalPath =
|
|
38
|
+
const finalPath = path.join(writeDir, '/fields.json');
|
|
46
39
|
return fieldsArrayToJson(fields).then(json => {
|
|
47
|
-
if (!
|
|
48
|
-
|
|
40
|
+
if (!fs.existsSync(writeDir)) {
|
|
41
|
+
fs.mkdirSync(writeDir, { recursive: true });
|
|
49
42
|
}
|
|
50
|
-
|
|
43
|
+
fs.writeFileSync(finalPath, json);
|
|
51
44
|
//TODO - Figure out agnostic logging
|
|
52
|
-
console.log(
|
|
45
|
+
console.log(i18n(`${i18nKey}.converted`, {
|
|
53
46
|
src: dirName + `/${baseName}`,
|
|
54
47
|
dest: dirName + '/fields.json',
|
|
55
48
|
}));
|
|
@@ -79,19 +72,11 @@ async function fieldsArrayToJson(fields) {
|
|
|
79
72
|
return JSON.stringify(jsonFields, null, 2);
|
|
80
73
|
}
|
|
81
74
|
/**
|
|
82
|
-
* Takes in a path to a javascript file and
|
|
75
|
+
* Takes in a path to a javascript file and dynamically imports it.
|
|
83
76
|
* @param {string} filePath - Path to javascript file
|
|
84
|
-
* @returns {Promise
|
|
77
|
+
* @returns {Promise} - Returns _default_ exported content if ESM, or exported module content if CJS.
|
|
85
78
|
*/
|
|
86
79
|
async function dynamicImport(filePath) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return exported.default;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
if ((0, path_2.getExt)(filePath) == 'mjs') {
|
|
93
|
-
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidMjsFile`));
|
|
94
|
-
}
|
|
95
|
-
return require(filePath);
|
|
96
|
-
}
|
|
80
|
+
const exported = await import(pathToFileURL(filePath).href);
|
|
81
|
+
return exported.default || exported;
|
|
97
82
|
}
|
package/lib/cms/templates.js
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
exports.TEMPLATE_TYPES = exports.createTemplate = exports.isCodedFile = exports.getAnnotationValue = exports.ANNOTATION_KEYS = void 0;
|
|
7
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const github_1 = require("../github");
|
|
10
|
-
const logger_1 = require("../logger");
|
|
11
|
-
const lang_1 = require("../../utils/lang");
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { cloneGithubRepo } from '../github.js';
|
|
4
|
+
import { logger } from '../logger.js';
|
|
5
|
+
import { i18n } from '../../utils/lang.js';
|
|
12
6
|
const i18nKey = 'lib.cms.templates';
|
|
13
7
|
// Matches the .html file extension, excluding module.html
|
|
14
8
|
const TEMPLATE_EXTENSION_REGEX = new RegExp(/(?<!module)\.html$/);
|
|
15
9
|
// Matches an annotation value, ending at space, newline, or end of string
|
|
16
10
|
const ANNOTATION_VALUE_REGEX = ':\\s?([\\S|\\s]*?)(\n|$)';
|
|
17
|
-
|
|
11
|
+
export const ANNOTATION_KEYS = {
|
|
18
12
|
isAvailableForNewContent: 'isAvailableForNewContent',
|
|
19
13
|
templateType: 'templateType',
|
|
20
14
|
label: 'label',
|
|
@@ -22,20 +16,18 @@ exports.ANNOTATION_KEYS = {
|
|
|
22
16
|
// 'description' is specific to Sections
|
|
23
17
|
description: 'description',
|
|
24
18
|
};
|
|
25
|
-
function getAnnotationValue(annotations, key) {
|
|
19
|
+
export function getAnnotationValue(annotations, key) {
|
|
26
20
|
const valueRegex = new RegExp(`${key}${ANNOTATION_VALUE_REGEX}`);
|
|
27
21
|
const match = annotations.match(valueRegex);
|
|
28
22
|
return match ? match[1].trim() : null;
|
|
29
23
|
}
|
|
30
|
-
exports.getAnnotationValue = getAnnotationValue;
|
|
31
24
|
/*
|
|
32
25
|
* Returns true if:
|
|
33
26
|
* .html extension (ignoring module.html)
|
|
34
27
|
*/
|
|
35
|
-
function isCodedFile(filePath) {
|
|
28
|
+
export function isCodedFile(filePath) {
|
|
36
29
|
return TEMPLATE_EXTENSION_REGEX.test(filePath);
|
|
37
30
|
}
|
|
38
|
-
exports.isCodedFile = isCodedFile;
|
|
39
31
|
const ASSET_PATHS = {
|
|
40
32
|
'page-template': 'templates/page-template.html',
|
|
41
33
|
partial: 'templates/partial.html',
|
|
@@ -46,26 +38,25 @@ const ASSET_PATHS = {
|
|
|
46
38
|
'search-template': 'templates/search-template.html',
|
|
47
39
|
section: 'templates/section.html',
|
|
48
40
|
};
|
|
49
|
-
async function createTemplate(name, dest, type = 'page-template', options = { allowExisting: false }) {
|
|
41
|
+
export async function createTemplate(name, dest, type = 'page-template', options = { allowExisting: false }) {
|
|
50
42
|
const assetPath = ASSET_PATHS[type];
|
|
51
43
|
const filename = name.endsWith('.html') ? name : `${name}.html`;
|
|
52
|
-
const filePath =
|
|
53
|
-
if (!options.allowExisting &&
|
|
54
|
-
throw new Error(
|
|
44
|
+
const filePath = path.join(dest, filename);
|
|
45
|
+
if (!options.allowExisting && fs.existsSync(filePath)) {
|
|
46
|
+
throw new Error(i18n(`${i18nKey}.createTemplate.errors.pathExists`, {
|
|
55
47
|
path: filePath,
|
|
56
48
|
}));
|
|
57
49
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
logger.debug(i18n(`${i18nKey}.createTemplate.creatingPath`, { path: dest }));
|
|
51
|
+
fs.mkdirp(dest);
|
|
52
|
+
logger.log(i18n(`${i18nKey}.createTemplate.creatingFile`, {
|
|
61
53
|
path: filePath,
|
|
62
54
|
}));
|
|
63
|
-
await
|
|
55
|
+
await cloneGithubRepo('HubSpot/cms-sample-assets', filePath, {
|
|
64
56
|
sourceDir: assetPath,
|
|
65
57
|
});
|
|
66
58
|
}
|
|
67
|
-
|
|
68
|
-
exports.TEMPLATE_TYPES = {
|
|
59
|
+
export const TEMPLATE_TYPES = {
|
|
69
60
|
unmapped: 0,
|
|
70
61
|
email_base_template: 1,
|
|
71
62
|
email: 2,
|
package/lib/cms/themes.js
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const findup_sync_1 = __importDefault(require("findup-sync"));
|
|
8
|
-
const urls_1 = require("../urls");
|
|
9
|
-
const environments_1 = require("../../constants/environments");
|
|
10
|
-
const config_1 = require("../../config");
|
|
11
|
-
function getThemeJSONPath(path) {
|
|
12
|
-
return (0, findup_sync_1.default)('theme.json', {
|
|
1
|
+
import findup from 'findup-sync';
|
|
2
|
+
import { getHubSpotWebsiteOrigin } from '../urls.js';
|
|
3
|
+
import { ENVIRONMENTS } from '../../constants/environments.js';
|
|
4
|
+
import { getConfigAccountEnvironment } from '../../config/index.js';
|
|
5
|
+
export function getThemeJSONPath(path) {
|
|
6
|
+
return findup('theme.json', {
|
|
13
7
|
cwd: path,
|
|
14
8
|
nocase: true,
|
|
15
9
|
});
|
|
16
10
|
}
|
|
17
|
-
exports.getThemeJSONPath = getThemeJSONPath;
|
|
18
11
|
function getThemeNameFromPath(filePath) {
|
|
19
12
|
const themeJSONPath = getThemeJSONPath(filePath);
|
|
20
13
|
if (!themeJSONPath)
|
|
@@ -24,13 +17,12 @@ function getThemeNameFromPath(filePath) {
|
|
|
24
17
|
return;
|
|
25
18
|
return pathParts[pathParts.length - 2];
|
|
26
19
|
}
|
|
27
|
-
function getThemePreviewUrl(filePath, accountId) {
|
|
20
|
+
export function getThemePreviewUrl(filePath, accountId) {
|
|
28
21
|
const themeName = getThemeNameFromPath(filePath);
|
|
29
22
|
if (!themeName)
|
|
30
23
|
return;
|
|
31
|
-
const baseUrl =
|
|
32
|
-
?
|
|
33
|
-
:
|
|
24
|
+
const baseUrl = getHubSpotWebsiteOrigin(getConfigAccountEnvironment(accountId) === 'qa'
|
|
25
|
+
? ENVIRONMENTS.QA
|
|
26
|
+
: ENVIRONMENTS.PROD);
|
|
34
27
|
return `${baseUrl}/theme-previewer/${accountId}/edit/${encodeURIComponent(themeName)}`;
|
|
35
28
|
}
|
|
36
|
-
exports.getThemePreviewUrl = getThemePreviewUrl;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FieldsJs } from './handleFieldsJS';
|
|
2
|
-
import { FileMapperInputOptions } from '../../types/Files';
|
|
3
|
-
import { UploadFolderResults, CommandOptions, FilePathsByType } from '../../types/Files';
|
|
4
|
-
import { CmsPublishMode } from '../../types/Files';
|
|
1
|
+
import { FieldsJs } from './handleFieldsJS.js';
|
|
2
|
+
import { FileMapperInputOptions } from '../../types/Files.js';
|
|
3
|
+
import { UploadFolderResults, CommandOptions, FilePathsByType } from '../../types/Files.js';
|
|
4
|
+
import { CmsPublishMode } from '../../types/Files.js';
|
|
5
5
|
export declare function getFilesByType(filePaths: Array<string>, projectDir: string, rootWriteDir: string | null, commandOptions: CommandOptions): Promise<[FilePathsByType, Array<FieldsJs>]>;
|
|
6
6
|
export declare function uploadFolder(accountId: number, src: string, dest: string, fileMapperOptions: FileMapperInputOptions, commandOptions?: CommandOptions, filePaths?: Array<string>, cmsPublishMode?: CmsPublishMode | null): Promise<Array<UploadFolderResults>>;
|
|
7
7
|
export declare function hasUploadErrors(results: Array<UploadFolderResults>): boolean;
|
package/lib/cms/uploadFolder.js
CHANGED
|
@@ -1,59 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const path_2 = require("../path");
|
|
15
|
-
const errors_1 = require("../../errors");
|
|
16
|
-
const logger_1 = require("../logger");
|
|
17
|
-
const files_1 = require("../../constants/files");
|
|
18
|
-
const lang_1 = require("../../utils/lang");
|
|
19
|
-
const HubSpotHttpError_1 = require("../../models/HubSpotHttpError");
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import PQueue from 'p-queue';
|
|
3
|
+
import { isConvertableFieldJs, FieldsJs, createTmpDirSync, cleanupTmpDirSync, } from './handleFieldsJS.js';
|
|
4
|
+
import { getFileMapperQueryValues } from '../fileMapper.js';
|
|
5
|
+
import { upload } from '../../api/fileMapper.js';
|
|
6
|
+
import { isModuleFolderChild } from '../../utils/cms/modules.js';
|
|
7
|
+
import { escapeRegExp } from '../escapeRegExp.js';
|
|
8
|
+
import { convertToUnixPath, getExt } from '../path.js';
|
|
9
|
+
import { isAuthError, isHubSpotHttpError } from '../../errors/index.js';
|
|
10
|
+
import { logger } from '../logger.js';
|
|
11
|
+
import { FILE_TYPES, FILE_UPLOAD_RESULT_TYPES } from '../../constants/files.js';
|
|
12
|
+
import { i18n } from '../../utils/lang.js';
|
|
13
|
+
import { HubSpotHttpError } from '../../models/HubSpotHttpError.js';
|
|
20
14
|
const i18nKey = 'lib.cms.uploadFolder';
|
|
21
|
-
const queue = new
|
|
15
|
+
const queue = new PQueue({
|
|
22
16
|
concurrency: 10,
|
|
23
17
|
});
|
|
24
18
|
function getFileType(filePath) {
|
|
25
|
-
const extension =
|
|
26
|
-
const moduleFolder =
|
|
19
|
+
const extension = getExt(filePath);
|
|
20
|
+
const moduleFolder = isModuleFolderChild({ path: filePath, isLocal: true });
|
|
27
21
|
if (moduleFolder)
|
|
28
|
-
return
|
|
22
|
+
return FILE_TYPES.module;
|
|
29
23
|
switch (extension) {
|
|
30
24
|
case 'js':
|
|
31
25
|
case 'css':
|
|
32
|
-
return
|
|
26
|
+
return FILE_TYPES.cssAndJs;
|
|
33
27
|
case 'html':
|
|
34
|
-
return
|
|
28
|
+
return FILE_TYPES.template;
|
|
35
29
|
case 'json':
|
|
36
|
-
return
|
|
30
|
+
return FILE_TYPES.json;
|
|
37
31
|
default:
|
|
38
|
-
return
|
|
32
|
+
return FILE_TYPES.other;
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
35
|
function isMetaJsonFile(filePath) {
|
|
42
|
-
return
|
|
36
|
+
return path.basename(filePath).toLowerCase() === 'meta.json';
|
|
43
37
|
}
|
|
44
38
|
function resolveUploadPath(file, fieldsJsPaths, tmpDirRegex, regex, dest) {
|
|
45
39
|
const fieldsJsFileInfo = fieldsJsPaths.find(f => f.outputPath === file);
|
|
46
40
|
const relativePath = file.replace(fieldsJsFileInfo ? tmpDirRegex : regex, '');
|
|
47
|
-
const destPath =
|
|
41
|
+
const destPath = convertToUnixPath(path.join(dest, relativePath));
|
|
48
42
|
const originalFilePath = fieldsJsFileInfo ? fieldsJsFileInfo.filePath : file;
|
|
49
43
|
return { fieldsJsFileInfo, relativePath, destPath, originalFilePath };
|
|
50
44
|
}
|
|
51
|
-
async function getFilesByType(filePaths, projectDir, rootWriteDir, commandOptions) {
|
|
45
|
+
export async function getFilesByType(filePaths, projectDir, rootWriteDir, commandOptions) {
|
|
52
46
|
const { convertFields, fieldOptions } = commandOptions;
|
|
53
|
-
const projectDirRegex = new RegExp(`^${
|
|
47
|
+
const projectDirRegex = new RegExp(`^${escapeRegExp(projectDir)}`);
|
|
54
48
|
const fieldsJsObjects = [];
|
|
55
49
|
// Create object with key-value pairs of form { FileType.type: [] }
|
|
56
|
-
const filePathsByType = Object.values(
|
|
50
|
+
const filePathsByType = Object.values(FILE_TYPES).reduce((acc, fileType) => {
|
|
57
51
|
return {
|
|
58
52
|
...acc,
|
|
59
53
|
[fileType]: [],
|
|
@@ -66,10 +60,10 @@ async function getFilesByType(filePaths, projectDir, rootWriteDir, commandOption
|
|
|
66
60
|
filePathsByType[fileType].push(filePath);
|
|
67
61
|
continue;
|
|
68
62
|
}
|
|
69
|
-
const convertableFields =
|
|
63
|
+
const convertableFields = isConvertableFieldJs(projectDir, filePath, convertFields);
|
|
70
64
|
if (convertableFields) {
|
|
71
|
-
const rootOrModule =
|
|
72
|
-
const fieldsJs = await new
|
|
65
|
+
const rootOrModule = path.dirname(relPath) === '/' ? FILE_TYPES.json : FILE_TYPES.module;
|
|
66
|
+
const fieldsJs = await new FieldsJs(projectDir, filePath, rootWriteDir, fieldOptions).init();
|
|
73
67
|
/*
|
|
74
68
|
* A fields.js will be rejected if the promise is rejected or if the some other error occurs.
|
|
75
69
|
* We handle this gracefully by not adding the failed fields.js to the object list.
|
|
@@ -85,32 +79,31 @@ async function getFilesByType(filePaths, projectDir, rootWriteDir, commandOption
|
|
|
85
79
|
}
|
|
86
80
|
return [filePathsByType, fieldsJsObjects];
|
|
87
81
|
}
|
|
88
|
-
|
|
89
|
-
const defaultUploadAttemptCallback = (file, destPath) => logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.uploadFolder.attempt`, {
|
|
82
|
+
const defaultUploadAttemptCallback = (file, destPath) => logger.debug(i18n(`${i18nKey}.uploadFolder.attempt`, {
|
|
90
83
|
file: file || '',
|
|
91
84
|
destPath,
|
|
92
85
|
}));
|
|
93
|
-
const defaultUploadSuccessCallback = (file, destPath) =>
|
|
86
|
+
const defaultUploadSuccessCallback = (file, destPath) => logger.log(i18n(`${i18nKey}.uploadFolder.success`, {
|
|
94
87
|
file: file || '',
|
|
95
88
|
destPath,
|
|
96
89
|
}));
|
|
97
90
|
const defaultUploadFirstErrorCallback = (file, destPath, error) => {
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
|
|
91
|
+
logger.debug(i18n(`${i18nKey}.uploadFolder.failed`, { file, destPath }));
|
|
92
|
+
if (isHubSpotHttpError(error)) {
|
|
93
|
+
logger.debug(error.data);
|
|
101
94
|
}
|
|
102
95
|
else if (error instanceof Error) {
|
|
103
|
-
|
|
96
|
+
logger.debug(error.message);
|
|
104
97
|
}
|
|
105
98
|
};
|
|
106
|
-
const defaultUploadRetryCallback = (file, destPath) =>
|
|
99
|
+
const defaultUploadRetryCallback = (file, destPath) => logger.debug(i18n(`${i18nKey}.uploadFolder.retry`, { file, destPath }));
|
|
107
100
|
const defaultUploadFinalErrorCallback = (accountId, file, destPath, error) => {
|
|
108
|
-
const retryFailed =
|
|
101
|
+
const retryFailed = i18n(`${i18nKey}.uploadFolder.retryFailed`, {
|
|
109
102
|
file,
|
|
110
103
|
destPath,
|
|
111
104
|
});
|
|
112
|
-
|
|
113
|
-
throw new
|
|
105
|
+
logger.debug(retryFailed);
|
|
106
|
+
throw new HubSpotHttpError(retryFailed, { cause: error }, {
|
|
114
107
|
accountId,
|
|
115
108
|
request: destPath,
|
|
116
109
|
payload: file,
|
|
@@ -122,7 +115,7 @@ async function uploadMetaJsonFiles(moduleFiles, uploadFile) {
|
|
|
122
115
|
await queue.addAll(moduleMetaJsonFiles.map(uploadFile));
|
|
123
116
|
}
|
|
124
117
|
}
|
|
125
|
-
async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOptions = {}, filePaths = [], cmsPublishMode = null) {
|
|
118
|
+
export async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOptions = {}, filePaths = [], cmsPublishMode = null) {
|
|
126
119
|
const { saveOutput, convertFields, onAttemptCallback, onSuccessCallback, onFirstErrorCallback, onRetryCallback, onFinalErrorCallback, } = commandOptions;
|
|
127
120
|
const _onAttemptCallback = onAttemptCallback || defaultUploadAttemptCallback;
|
|
128
121
|
const _onSuccessCallback = onSuccessCallback || defaultUploadSuccessCallback;
|
|
@@ -130,13 +123,13 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
|
|
|
130
123
|
const _onRetryCallback = onRetryCallback || defaultUploadRetryCallback;
|
|
131
124
|
const _onFinalErrorCallback = onFinalErrorCallback || defaultUploadFinalErrorCallback;
|
|
132
125
|
const tmpDir = convertFields
|
|
133
|
-
?
|
|
126
|
+
? createTmpDirSync('hubspot-temp-fieldsjs-output-')
|
|
134
127
|
: null;
|
|
135
|
-
const regex = new RegExp(`^${
|
|
136
|
-
const apiOptions =
|
|
128
|
+
const regex = new RegExp(`^${escapeRegExp(src)}`);
|
|
129
|
+
const apiOptions = getFileMapperQueryValues(cmsPublishMode, fileMapperOptions);
|
|
137
130
|
const failures = [];
|
|
138
131
|
let fieldsJsPaths = [];
|
|
139
|
-
const tmpDirRegex = new RegExp(`^${
|
|
132
|
+
const tmpDirRegex = new RegExp(`^${escapeRegExp(tmpDir || '')}`);
|
|
140
133
|
const [filesByType, fieldsJsObjects] = await getFilesByType(filePaths, src, tmpDir, commandOptions);
|
|
141
134
|
if (fieldsJsObjects.length) {
|
|
142
135
|
fieldsJsPaths = fieldsJsObjects.map(fieldsJs => {
|
|
@@ -148,11 +141,11 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
|
|
|
148
141
|
return async () => {
|
|
149
142
|
_onAttemptCallback(originalFilePath, destPath);
|
|
150
143
|
try {
|
|
151
|
-
await
|
|
144
|
+
await upload(accountId, file, destPath, apiOptions);
|
|
152
145
|
_onSuccessCallback(originalFilePath, destPath);
|
|
153
146
|
}
|
|
154
147
|
catch (err) {
|
|
155
|
-
if (
|
|
148
|
+
if (isAuthError(err)) {
|
|
156
149
|
throw err;
|
|
157
150
|
}
|
|
158
151
|
_onFirstErrorCallback(file, destPath, err);
|
|
@@ -164,11 +157,11 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
|
|
|
164
157
|
};
|
|
165
158
|
}
|
|
166
159
|
// Upload all meta.json files first
|
|
167
|
-
await uploadMetaJsonFiles(filesByType[
|
|
160
|
+
await uploadMetaJsonFiles(filesByType[FILE_TYPES.module] || [], uploadFile);
|
|
168
161
|
// Collect all remaining files for upload
|
|
169
162
|
const deferredFiles = [];
|
|
170
163
|
Object.entries(filesByType).forEach(([fileType, files]) => {
|
|
171
|
-
if (fileType ===
|
|
164
|
+
if (fileType === FILE_TYPES.module) {
|
|
172
165
|
// Add non-meta.json module files
|
|
173
166
|
deferredFiles.push(...files.filter(f => !isMetaJsonFile(f)));
|
|
174
167
|
}
|
|
@@ -186,21 +179,21 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
|
|
|
186
179
|
return async () => {
|
|
187
180
|
_onRetryCallback(file, destPath);
|
|
188
181
|
try {
|
|
189
|
-
await
|
|
182
|
+
await upload(accountId, file, destPath, apiOptions);
|
|
190
183
|
_onSuccessCallback(file, destPath);
|
|
191
184
|
return {
|
|
192
|
-
resultType:
|
|
185
|
+
resultType: FILE_UPLOAD_RESULT_TYPES.SUCCESS,
|
|
193
186
|
error: null,
|
|
194
187
|
file,
|
|
195
188
|
};
|
|
196
189
|
}
|
|
197
190
|
catch (error) {
|
|
198
|
-
if (
|
|
191
|
+
if (isAuthError(error)) {
|
|
199
192
|
throw error;
|
|
200
193
|
}
|
|
201
194
|
_onFinalErrorCallback(accountId, file, destPath, error);
|
|
202
195
|
return {
|
|
203
|
-
resultType:
|
|
196
|
+
resultType: FILE_UPLOAD_RESULT_TYPES.FAILURE,
|
|
204
197
|
error,
|
|
205
198
|
file,
|
|
206
199
|
};
|
|
@@ -213,12 +206,10 @@ async function uploadFolder(accountId, src, dest, fileMapperOptions, commandOpti
|
|
|
213
206
|
if (saveOutput) {
|
|
214
207
|
fieldsJsObjects.forEach(fieldsJs => fieldsJs.saveOutput());
|
|
215
208
|
}
|
|
216
|
-
|
|
209
|
+
cleanupTmpDirSync(tmpDir || '');
|
|
217
210
|
});
|
|
218
211
|
return results;
|
|
219
212
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return results.some(result => result.resultType === files_1.FILE_UPLOAD_RESULT_TYPES.FAILURE);
|
|
213
|
+
export function hasUploadErrors(results) {
|
|
214
|
+
return results.some(result => result.resultType === FILE_UPLOAD_RESULT_TYPES.FAILURE);
|
|
223
215
|
}
|
|
224
|
-
exports.hasUploadErrors = hasUploadErrors;
|
package/lib/cms/validate.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { LintResult } from '../../types/HublValidation';
|
|
1
|
+
import { LintResult } from '../../types/HublValidation.js';
|
|
2
2
|
export declare function lint(accountId: number, filepath: string, callback?: (lintResult: LintResult) => number): Promise<Array<Partial<LintResult>> | void>;
|
package/lib/cms/validate.js
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const validateHubl_1 = require("../../api/validateHubl");
|
|
10
|
-
const fs_1 = require("../fs");
|
|
11
|
-
const path_1 = require("../path");
|
|
12
|
-
async function lint(accountId, filepath, callback) {
|
|
13
|
-
const stats = await fs_extra_1.default.stat(filepath);
|
|
14
|
-
const files = stats.isDirectory() ? await (0, fs_1.walk)(filepath) : [filepath];
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { HUBL_EXTENSIONS } from '../../constants/extensions.js';
|
|
3
|
+
import { validateHubl } from '../../api/validateHubl.js';
|
|
4
|
+
import { walk } from '../fs.js';
|
|
5
|
+
import { getExt } from '../path.js';
|
|
6
|
+
export async function lint(accountId, filepath, callback) {
|
|
7
|
+
const stats = await fs.stat(filepath);
|
|
8
|
+
const files = stats.isDirectory() ? await walk(filepath) : [filepath];
|
|
15
9
|
if (!(files && files.length)) {
|
|
16
10
|
return [];
|
|
17
11
|
}
|
|
18
12
|
return Promise.all(files
|
|
19
|
-
.filter(file =>
|
|
13
|
+
.filter(file => HUBL_EXTENSIONS.has(getExt(file)))
|
|
20
14
|
.map(async (file) => {
|
|
21
|
-
const source = await
|
|
15
|
+
const source = await fs.readFile(file, { encoding: 'utf8' });
|
|
22
16
|
if (!(source && source.trim())) {
|
|
23
17
|
const result = { file, validation: null };
|
|
24
18
|
if (callback) {
|
|
@@ -26,7 +20,7 @@ async function lint(accountId, filepath, callback) {
|
|
|
26
20
|
}
|
|
27
21
|
return result;
|
|
28
22
|
}
|
|
29
|
-
const { data: validation } = await
|
|
23
|
+
const { data: validation } = await validateHubl(accountId, source);
|
|
30
24
|
const result = {
|
|
31
25
|
file,
|
|
32
26
|
validation,
|
|
@@ -37,4 +31,3 @@ async function lint(accountId, filepath, callback) {
|
|
|
37
31
|
return result;
|
|
38
32
|
}));
|
|
39
33
|
}
|
|
40
|
-
exports.lint = lint;
|
package/lib/cms/watch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import chokidar from 'chokidar';
|
|
2
|
-
import { WatchOptions, WatchErrorHandler } from '../../types/Files';
|
|
3
|
-
import { UploadFolderResults } from '../../types/Files';
|
|
2
|
+
import { WatchOptions, WatchErrorHandler } from '../../types/Files.js';
|
|
3
|
+
import { UploadFolderResults } from '../../types/Files.js';
|
|
4
4
|
export declare function watch(accountId: number, src: string, dest: string, { cmsPublishMode, remove, disableInitial, notify, commandOptions, filePaths, }: WatchOptions, postInitialUploadCallback?: ((result: Array<UploadFolderResults>) => void) | null, onUploadFolderError?: WatchErrorHandler, onQueueAddError?: WatchErrorHandler, onUploadFileError?: (file: string, dest: string, accountId: number) => WatchErrorHandler): chokidar.FSWatcher;
|