@hubspot/local-dev-lib 4.0.4-beta.0 → 5.0.0-beta.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 +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 +3 -3
- package/api/developerTestAccounts.js +29 -40
- package/api/fileManager.d.ts +2 -2
- package/api/fileManager.js +14 -24
- package/api/fileMapper.d.ts +2 -2
- 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 -2
- 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 +5 -5
- package/api/localDevAuth.js +17 -25
- 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 +3 -3
- package/api/sandboxHubs.js +21 -30
- 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.js +18 -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/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.js +5 -8
- package/enums/deploy.js +2 -5
- package/enums/project.js +1 -4
- package/errors/errors_DEPRECATED.d.ts +1 -1
- package/errors/errors_DEPRECATED.js +2 -7
- package/errors/index.d.ts +4 -4
- package/errors/index.js +17 -31
- package/http/addQueryParams.d.ts +1 -1
- package/http/addQueryParams.js +1 -5
- package/http/client.js +16 -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/lib/archive.d.ts +1 -3
- package/lib/archive.js +38 -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 +16 -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 +70 -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 +3 -3
- package/lib/personalAccessKey.js +47 -59
- package/lib/portManager.d.ts +2 -2
- package/lib/portManager.js +26 -41
- package/lib/text.js +2 -7
- package/lib/trackUsage.d.ts +2 -2
- package/lib/trackUsage.js +26 -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 +17 -16
- package/types/Accounts.d.ts +5 -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 +5 -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 +5 -5
- package/types/Config.js +1 -2
- package/types/Crm.js +1 -2
- package/types/Deploy.d.ts +5 -5
- 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 -3
- package/types/Project.js +1 -2
- 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/lib/fileManager.js
CHANGED
|
@@ -1,74 +1,67 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// FILE MANAGER - not to be confused with fileMapper.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const escapeRegExp_1 = require("./escapeRegExp");
|
|
16
|
-
const path_2 = require("./path");
|
|
17
|
-
const lang_1 = require("../utils/lang");
|
|
18
|
-
const errors_1 = require("../errors");
|
|
19
|
-
const FileSystemError_1 = require("../models/FileSystemError");
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { uploadFile, fetchStat, fetchFiles, fetchFolders, } from '../api/fileManager.js';
|
|
5
|
+
import { walk } from './fs.js';
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
import { createIgnoreFilter } from './ignoreRules.js';
|
|
8
|
+
import { http } from '../http/index.js';
|
|
9
|
+
import { escapeRegExp } from './escapeRegExp.js';
|
|
10
|
+
import { getCwd, convertToUnixPath, convertToLocalFileSystemPath, } from './path.js';
|
|
11
|
+
import { i18n } from '../utils/lang.js';
|
|
12
|
+
import { isAuthError, isHubSpotHttpError } from '../errors/index.js';
|
|
13
|
+
import { FileSystemError } from '../models/FileSystemError.js';
|
|
20
14
|
const i18nKey = 'lib.fileManager';
|
|
21
|
-
async function uploadFolder(accountId, src, dest) {
|
|
22
|
-
const regex = new RegExp(`^${
|
|
23
|
-
const files = await
|
|
24
|
-
const filesToUpload = files.filter(
|
|
15
|
+
export async function uploadFolder(accountId, src, dest) {
|
|
16
|
+
const regex = new RegExp(`^${escapeRegExp(src)}`);
|
|
17
|
+
const files = await walk(src);
|
|
18
|
+
const filesToUpload = files.filter(createIgnoreFilter(false));
|
|
25
19
|
const len = filesToUpload.length;
|
|
26
20
|
for (let index = 0; index < len; index++) {
|
|
27
21
|
const file = filesToUpload[index];
|
|
28
22
|
const relativePath = file.replace(regex, '');
|
|
29
|
-
const destPath =
|
|
30
|
-
|
|
23
|
+
const destPath = convertToUnixPath(path.join(dest, relativePath));
|
|
24
|
+
logger.debug(i18n(`${i18nKey}.uploadStarted`, {
|
|
31
25
|
file,
|
|
32
26
|
destPath,
|
|
33
27
|
accountId,
|
|
34
28
|
}));
|
|
35
29
|
try {
|
|
36
|
-
await
|
|
37
|
-
|
|
30
|
+
await uploadFile(accountId, file, destPath);
|
|
31
|
+
logger.log(i18n(`${i18nKey}.uploadSuccess`, { file, destPath }));
|
|
38
32
|
}
|
|
39
33
|
catch (err) {
|
|
40
|
-
if (
|
|
34
|
+
if (isHubSpotHttpError(err)) {
|
|
41
35
|
err.updateContext({
|
|
42
36
|
filepath: file,
|
|
43
37
|
dest: destPath,
|
|
44
38
|
});
|
|
45
39
|
throw err;
|
|
46
40
|
}
|
|
47
|
-
throw new Error(
|
|
41
|
+
throw new Error(i18n(`${i18nKey}.errors.uploadFailed`, {
|
|
48
42
|
file,
|
|
49
43
|
destPath,
|
|
50
44
|
}));
|
|
51
45
|
}
|
|
52
46
|
}
|
|
53
47
|
}
|
|
54
|
-
exports.uploadFolder = uploadFolder;
|
|
55
48
|
async function skipExisting(overwrite, filepath) {
|
|
56
49
|
if (overwrite) {
|
|
57
50
|
return false;
|
|
58
51
|
}
|
|
59
|
-
if (await
|
|
60
|
-
|
|
52
|
+
if (await fs.pathExists(filepath)) {
|
|
53
|
+
logger.log(i18n(`${i18nKey}.skippedExisting`, { filepath }));
|
|
61
54
|
return true;
|
|
62
55
|
}
|
|
63
56
|
return false;
|
|
64
57
|
}
|
|
65
58
|
async function downloadFile(accountId, file, dest, overwrite) {
|
|
66
59
|
const fileName = `${file.name}.${file.extension}`;
|
|
67
|
-
const destPath =
|
|
60
|
+
const destPath = convertToLocalFileSystemPath(path.join(dest, fileName));
|
|
68
61
|
if (await skipExisting(overwrite || false, destPath)) {
|
|
69
62
|
return;
|
|
70
63
|
}
|
|
71
|
-
await
|
|
64
|
+
await http.getOctetStream(accountId, {
|
|
72
65
|
baseURL: file.url,
|
|
73
66
|
url: '',
|
|
74
67
|
}, destPath);
|
|
@@ -79,7 +72,7 @@ async function fetchAllPagedFiles(accountId, folderId, includeArchived) {
|
|
|
79
72
|
let count = 0;
|
|
80
73
|
let offset = 0;
|
|
81
74
|
while (totalFiles === null || count < totalFiles) {
|
|
82
|
-
const { data: response } = await
|
|
75
|
+
const { data: response } = await fetchFiles(accountId, folderId, offset, includeArchived);
|
|
83
76
|
if (totalFiles === null) {
|
|
84
77
|
totalFiles = response.total_count;
|
|
85
78
|
}
|
|
@@ -91,26 +84,26 @@ async function fetchAllPagedFiles(accountId, folderId, includeArchived) {
|
|
|
91
84
|
}
|
|
92
85
|
async function fetchFolderContents(accountId, folder, dest, overwrite, includeArchived) {
|
|
93
86
|
try {
|
|
94
|
-
await
|
|
87
|
+
await fs.ensureDir(dest);
|
|
95
88
|
}
|
|
96
89
|
catch (err) {
|
|
97
|
-
throw new
|
|
90
|
+
throw new FileSystemError({ cause: err }, {
|
|
98
91
|
dest,
|
|
99
92
|
accountId,
|
|
100
93
|
operation: 'write',
|
|
101
94
|
});
|
|
102
95
|
}
|
|
103
96
|
const files = await fetchAllPagedFiles(accountId, folder.id, includeArchived);
|
|
104
|
-
|
|
97
|
+
logger.debug(i18n(`${i18nKey}.fetchingFiles`, {
|
|
105
98
|
fileCount: files.length,
|
|
106
99
|
folderName: folder.name || '',
|
|
107
100
|
}));
|
|
108
101
|
for (const file of files) {
|
|
109
102
|
await downloadFile(accountId, file, dest, overwrite);
|
|
110
103
|
}
|
|
111
|
-
const { data: { objects: folders }, } = await
|
|
104
|
+
const { data: { objects: folders }, } = await fetchFolders(accountId, folder.id);
|
|
112
105
|
for (const folder of folders) {
|
|
113
|
-
const nestedFolder =
|
|
106
|
+
const nestedFolder = path.join(dest, folder.name);
|
|
114
107
|
await fetchFolderContents(accountId, folder, nestedFolder, overwrite, includeArchived);
|
|
115
108
|
}
|
|
116
109
|
}
|
|
@@ -118,18 +111,18 @@ async function fetchFolderContents(accountId, folder, dest, overwrite, includeAr
|
|
|
118
111
|
async function downloadFolder(accountId, src, dest, folder, overwrite, includeArchived) {
|
|
119
112
|
let absolutePath;
|
|
120
113
|
if (folder.name) {
|
|
121
|
-
absolutePath =
|
|
114
|
+
absolutePath = convertToLocalFileSystemPath(path.resolve(getCwd(), dest, folder.name));
|
|
122
115
|
}
|
|
123
116
|
else {
|
|
124
|
-
absolutePath =
|
|
117
|
+
absolutePath = convertToLocalFileSystemPath(path.resolve(getCwd(), dest));
|
|
125
118
|
}
|
|
126
|
-
|
|
119
|
+
logger.log(i18n(`${i18nKey}.fetchFolderStarted`, {
|
|
127
120
|
src,
|
|
128
121
|
path: absolutePath,
|
|
129
122
|
accountId,
|
|
130
123
|
}));
|
|
131
124
|
await fetchFolderContents(accountId, folder, absolutePath, overwrite, includeArchived);
|
|
132
|
-
|
|
125
|
+
logger.success(i18n(`${i18nKey}.fetchFolderSuccess`, {
|
|
133
126
|
src,
|
|
134
127
|
dest,
|
|
135
128
|
}));
|
|
@@ -137,24 +130,24 @@ async function downloadFolder(accountId, src, dest, folder, overwrite, includeAr
|
|
|
137
130
|
// Download a single file and write to local file system.
|
|
138
131
|
async function downloadSingleFile(accountId, src, dest, file, overwrite, includeArchived) {
|
|
139
132
|
if (!includeArchived && file.archived) {
|
|
140
|
-
throw new Error(
|
|
133
|
+
throw new Error(i18n(`${i18nKey}.errors.archivedFile`, { src }));
|
|
141
134
|
}
|
|
142
135
|
if (file.hidden) {
|
|
143
|
-
throw new Error(
|
|
136
|
+
throw new Error(i18n(`${i18nKey}.errors.hiddenFile`, { src }));
|
|
144
137
|
}
|
|
145
|
-
|
|
138
|
+
logger.log(i18n(`${i18nKey}.fetchFileStarted`, {
|
|
146
139
|
src,
|
|
147
140
|
dest,
|
|
148
141
|
accountId,
|
|
149
142
|
}));
|
|
150
143
|
await downloadFile(accountId, file, dest, overwrite);
|
|
151
|
-
|
|
144
|
+
logger.success(i18n(`${i18nKey}.fetchFileSuccess`, {
|
|
152
145
|
src,
|
|
153
146
|
dest,
|
|
154
147
|
}));
|
|
155
148
|
}
|
|
156
149
|
// Lookup path in file manager and initiate download
|
|
157
|
-
async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArchived) {
|
|
150
|
+
export async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArchived) {
|
|
158
151
|
try {
|
|
159
152
|
if (src == '/') {
|
|
160
153
|
// Filemanager API treats 'None' as the root
|
|
@@ -162,7 +155,7 @@ async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArch
|
|
|
162
155
|
await downloadFolder(accountId, src, dest, rootFolder, overwrite, includeArchived);
|
|
163
156
|
}
|
|
164
157
|
else {
|
|
165
|
-
const { data: { file, folder }, } = await
|
|
158
|
+
const { data: { file, folder }, } = await fetchStat(accountId, src);
|
|
166
159
|
if (file) {
|
|
167
160
|
await downloadSingleFile(accountId, src, dest, file, overwrite, includeArchived);
|
|
168
161
|
}
|
|
@@ -172,7 +165,7 @@ async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArch
|
|
|
172
165
|
}
|
|
173
166
|
}
|
|
174
167
|
catch (err) {
|
|
175
|
-
if (
|
|
168
|
+
if (isAuthError(err)) {
|
|
176
169
|
err.updateContext({
|
|
177
170
|
request: src,
|
|
178
171
|
accountId,
|
|
@@ -181,4 +174,3 @@ async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArch
|
|
|
181
174
|
throw err;
|
|
182
175
|
}
|
|
183
176
|
}
|
|
184
|
-
exports.downloadFileOrFolder = downloadFileOrFolder;
|
package/lib/fileMapper.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileMapperNode, CmsPublishMode, FileMapperOptions, FileMapperInputOptions, PathTypeData, RecursiveFileMapperCallback } from '../types/Files';
|
|
1
|
+
import { FileMapperNode, CmsPublishMode, FileMapperOptions, FileMapperInputOptions, PathTypeData, RecursiveFileMapperCallback } from '../types/Files.js';
|
|
2
2
|
export declare function isPathToFile(filepath: string): boolean;
|
|
3
3
|
export declare function isPathToModule(filepath: string): boolean;
|
|
4
4
|
export declare function isPathToRoot(filepath: string): boolean;
|
package/lib/fileMapper.js
CHANGED
|
@@ -1,53 +1,43 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// FILE MAPPER - not to be confused with fileManager.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const extensions_1 = require("../constants/extensions");
|
|
15
|
-
const files_1 = require("../constants/files");
|
|
16
|
-
const errors_1 = require("../errors");
|
|
17
|
-
const lang_1 = require("../utils/lang");
|
|
18
|
-
const FileSystemError_1 = require("../models/FileSystemError");
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import PQueue from 'p-queue';
|
|
5
|
+
import { getCwd, getExt, convertToLocalFileSystemPath, isAllowedExtension, } from './path.js';
|
|
6
|
+
import { logger } from './logger.js';
|
|
7
|
+
import { fetchFileStream, download, downloadDefault, } from '../api/fileMapper.js';
|
|
8
|
+
import { MODULE_EXTENSION, FUNCTIONS_EXTENSION, JSR_ALLOWED_EXTENSIONS, } from '../constants/extensions.js';
|
|
9
|
+
import { CMS_PUBLISH_MODE } from '../constants/files.js';
|
|
10
|
+
import { isTimeoutError } from '../errors/index.js';
|
|
11
|
+
import { i18n } from '../utils/lang.js';
|
|
12
|
+
import { FileSystemError } from '../models/FileSystemError.js';
|
|
19
13
|
const i18nKey = 'lib.fileMapper';
|
|
20
|
-
const queue = new
|
|
14
|
+
const queue = new PQueue({
|
|
21
15
|
concurrency: 10,
|
|
22
16
|
});
|
|
23
|
-
function isPathToFile(filepath) {
|
|
24
|
-
const ext =
|
|
25
|
-
return !!ext && ext !==
|
|
17
|
+
export function isPathToFile(filepath) {
|
|
18
|
+
const ext = getExt(filepath);
|
|
19
|
+
return !!ext && ext !== MODULE_EXTENSION && ext !== FUNCTIONS_EXTENSION;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return ext === extensions_1.MODULE_EXTENSION;
|
|
21
|
+
export function isPathToModule(filepath) {
|
|
22
|
+
const ext = getExt(filepath);
|
|
23
|
+
return ext === MODULE_EXTENSION;
|
|
31
24
|
}
|
|
32
|
-
|
|
33
|
-
function isPathToRoot(filepath) {
|
|
25
|
+
export function isPathToRoot(filepath) {
|
|
34
26
|
if (typeof filepath !== 'string')
|
|
35
27
|
return false;
|
|
36
28
|
// Root pattern matches empty strings and: / \
|
|
37
29
|
return /^(\/|\\)?$/.test(filepath.trim());
|
|
38
30
|
}
|
|
39
|
-
|
|
40
|
-
function isPathToHubspot(filepath) {
|
|
31
|
+
export function isPathToHubspot(filepath) {
|
|
41
32
|
if (typeof filepath !== 'string')
|
|
42
33
|
return false;
|
|
43
34
|
return /^(\/|\\)?@hubspot/i.test(filepath.trim());
|
|
44
35
|
}
|
|
45
|
-
exports.isPathToHubspot = isPathToHubspot;
|
|
46
36
|
function useApiBuffer(cmsPublishMode) {
|
|
47
|
-
return cmsPublishMode ===
|
|
37
|
+
return cmsPublishMode === CMS_PUBLISH_MODE.draft;
|
|
48
38
|
}
|
|
49
39
|
// Determines API param based on publish mode and options
|
|
50
|
-
function getFileMapperQueryValues(cmsPublishMode, { staging, assetVersion } = {}) {
|
|
40
|
+
export function getFileMapperQueryValues(cmsPublishMode, { staging, assetVersion } = {}) {
|
|
51
41
|
return {
|
|
52
42
|
params: {
|
|
53
43
|
buffer: useApiBuffer(cmsPublishMode),
|
|
@@ -56,7 +46,6 @@ function getFileMapperQueryValues(cmsPublishMode, { staging, assetVersion } = {}
|
|
|
56
46
|
},
|
|
57
47
|
};
|
|
58
48
|
}
|
|
59
|
-
exports.getFileMapperQueryValues = getFileMapperQueryValues;
|
|
60
49
|
// Determines version number to log based on input.options
|
|
61
50
|
function getAssetVersionIdentifier(assetVersion, src) {
|
|
62
51
|
if (typeof assetVersion !== 'undefined' &&
|
|
@@ -72,15 +61,16 @@ function validateFileMapperNode(node) {
|
|
|
72
61
|
let json;
|
|
73
62
|
try {
|
|
74
63
|
json = JSON.stringify(node, null, 2);
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
75
65
|
}
|
|
76
66
|
catch (err) {
|
|
77
67
|
json = node;
|
|
78
68
|
}
|
|
79
|
-
throw new Error(
|
|
69
|
+
throw new Error(i18n(`${i18nKey}.errors.invalidNode`, {
|
|
80
70
|
json: JSON.stringify(json),
|
|
81
71
|
}));
|
|
82
72
|
}
|
|
83
|
-
function getTypeDataFromPath(src) {
|
|
73
|
+
export function getTypeDataFromPath(src) {
|
|
84
74
|
const isModule = isPathToModule(src);
|
|
85
75
|
const isHubspot = isPathToHubspot(src);
|
|
86
76
|
const isFile = !isModule && isPathToFile(src);
|
|
@@ -94,8 +84,7 @@ function getTypeDataFromPath(src) {
|
|
|
94
84
|
isFolder,
|
|
95
85
|
};
|
|
96
86
|
}
|
|
97
|
-
|
|
98
|
-
function recurseFolder(node, callback, filepath = '', depth = 0) {
|
|
87
|
+
export function recurseFolder(node, callback, filepath = '', depth = 0) {
|
|
99
88
|
validateFileMapperNode(node);
|
|
100
89
|
const isRootFolder = node.folder && depth === 0;
|
|
101
90
|
if (isRootFolder) {
|
|
@@ -104,7 +93,7 @@ function recurseFolder(node, callback, filepath = '', depth = 0) {
|
|
|
104
93
|
}
|
|
105
94
|
}
|
|
106
95
|
else {
|
|
107
|
-
filepath =
|
|
96
|
+
filepath = path.join(filepath, node.name);
|
|
108
97
|
}
|
|
109
98
|
let __break = callback(node, filepath, depth);
|
|
110
99
|
if (__break === false)
|
|
@@ -115,28 +104,26 @@ function recurseFolder(node, callback, filepath = '', depth = 0) {
|
|
|
115
104
|
});
|
|
116
105
|
return depth === 0 ? false : __break;
|
|
117
106
|
}
|
|
118
|
-
|
|
119
|
-
async function writeUtimes(accountId, filepath, node) {
|
|
107
|
+
export async function writeUtimes(accountId, filepath, node) {
|
|
120
108
|
try {
|
|
121
109
|
const now = new Date();
|
|
122
110
|
const atime = node.createdAt ? new Date(node.createdAt) : now;
|
|
123
111
|
const mtime = node.updatedAt ? new Date(node.updatedAt) : now;
|
|
124
|
-
await
|
|
112
|
+
await fs.utimes(filepath, atime, mtime);
|
|
125
113
|
}
|
|
126
114
|
catch (err) {
|
|
127
|
-
throw new
|
|
115
|
+
throw new FileSystemError({ cause: err }, {
|
|
128
116
|
filepath,
|
|
129
117
|
accountId,
|
|
130
118
|
operation: 'write',
|
|
131
119
|
});
|
|
132
120
|
}
|
|
133
121
|
}
|
|
134
|
-
exports.writeUtimes = writeUtimes;
|
|
135
122
|
async function skipExisting(filepath, overwrite = false) {
|
|
136
123
|
if (overwrite) {
|
|
137
124
|
return false;
|
|
138
125
|
}
|
|
139
|
-
if (await
|
|
126
|
+
if (await fs.pathExists(filepath)) {
|
|
140
127
|
return true;
|
|
141
128
|
}
|
|
142
129
|
return false;
|
|
@@ -146,21 +133,21 @@ async function fetchAndWriteFileStream(accountId, srcPath, filepath, cmsPublishM
|
|
|
146
133
|
return;
|
|
147
134
|
}
|
|
148
135
|
if (await skipExisting(filepath, options.overwrite)) {
|
|
149
|
-
|
|
136
|
+
logger.log(i18n(`${i18nKey}.skippedExisting`, { filepath }));
|
|
150
137
|
return;
|
|
151
138
|
}
|
|
152
|
-
if (!
|
|
153
|
-
throw new Error(
|
|
139
|
+
if (!isAllowedExtension(srcPath, Array.from(JSR_ALLOWED_EXTENSIONS))) {
|
|
140
|
+
throw new Error(i18n(`${i18nKey}.errors.invalidFileType`, { srcPath }));
|
|
154
141
|
}
|
|
155
|
-
const node = await
|
|
142
|
+
const node = await fetchFileStream(accountId, srcPath, filepath, getFileMapperQueryValues(cmsPublishMode, options));
|
|
156
143
|
await writeUtimes(accountId, filepath, node);
|
|
157
144
|
}
|
|
158
145
|
// Writes an individual file or folder (not recursive). If file source is missing, the
|
|
159
146
|
//file is fetched.
|
|
160
147
|
async function writeFileMapperNode(accountId, filepath, node, cmsPublishMode, options = {}) {
|
|
161
|
-
const localFilepath =
|
|
148
|
+
const localFilepath = convertToLocalFileSystemPath(path.resolve(filepath));
|
|
162
149
|
if (await skipExisting(localFilepath, options.overwrite)) {
|
|
163
|
-
|
|
150
|
+
logger.log(i18n(`${i18nKey}.skippedExisting`, {
|
|
164
151
|
filepath: localFilepath,
|
|
165
152
|
}));
|
|
166
153
|
return true;
|
|
@@ -169,19 +156,20 @@ async function writeFileMapperNode(accountId, filepath, node, cmsPublishMode, op
|
|
|
169
156
|
try {
|
|
170
157
|
await fetchAndWriteFileStream(accountId, node.path, localFilepath, cmsPublishMode, options);
|
|
171
158
|
return true;
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
172
160
|
}
|
|
173
161
|
catch (err) {
|
|
174
162
|
return false;
|
|
175
163
|
}
|
|
176
164
|
}
|
|
177
165
|
try {
|
|
178
|
-
await
|
|
179
|
-
|
|
166
|
+
await fs.ensureDir(localFilepath);
|
|
167
|
+
logger.log(i18n(`${i18nKey}.wroteFolder`, {
|
|
180
168
|
filepath: localFilepath,
|
|
181
169
|
}));
|
|
182
170
|
}
|
|
183
171
|
catch (err) {
|
|
184
|
-
throw new
|
|
172
|
+
throw new FileSystemError({ cause: err }, {
|
|
185
173
|
filepath: localFilepath,
|
|
186
174
|
accountId,
|
|
187
175
|
operation: 'write',
|
|
@@ -192,31 +180,31 @@ async function writeFileMapperNode(accountId, filepath, node, cmsPublishMode, op
|
|
|
192
180
|
async function downloadFile(accountId, src, destPath, cmsPublishMode, options = {}) {
|
|
193
181
|
const { isFile, isHubspot } = getTypeDataFromPath(src);
|
|
194
182
|
if (!isFile) {
|
|
195
|
-
throw new Error(
|
|
183
|
+
throw new Error(i18n(`${i18nKey}.errors.invalidRequest`, { src }));
|
|
196
184
|
}
|
|
197
185
|
try {
|
|
198
|
-
const dest =
|
|
199
|
-
const cwd =
|
|
186
|
+
const dest = path.resolve(destPath);
|
|
187
|
+
const cwd = getCwd();
|
|
200
188
|
let filepath;
|
|
201
189
|
if (dest === cwd) {
|
|
202
190
|
// Dest: CWD
|
|
203
|
-
filepath =
|
|
191
|
+
filepath = path.resolve(cwd, path.basename(src));
|
|
204
192
|
}
|
|
205
193
|
else if (isPathToFile(dest)) {
|
|
206
194
|
// Dest: file path
|
|
207
|
-
filepath =
|
|
195
|
+
filepath = path.isAbsolute(dest) ? dest : path.resolve(cwd, dest);
|
|
208
196
|
}
|
|
209
197
|
else {
|
|
210
198
|
// Dest: folder path
|
|
211
|
-
const name =
|
|
212
|
-
filepath =
|
|
213
|
-
?
|
|
214
|
-
:
|
|
199
|
+
const name = path.basename(src);
|
|
200
|
+
filepath = path.isAbsolute(dest)
|
|
201
|
+
? path.resolve(dest, name)
|
|
202
|
+
: path.resolve(cwd, dest, name);
|
|
215
203
|
}
|
|
216
|
-
const localFsPath =
|
|
204
|
+
const localFsPath = convertToLocalFileSystemPath(filepath);
|
|
217
205
|
await fetchAndWriteFileStream(accountId, src, localFsPath, cmsPublishMode, options);
|
|
218
206
|
await queue.onIdle();
|
|
219
|
-
|
|
207
|
+
logger.success(i18n(`${i18nKey}.completedFetch`, {
|
|
220
208
|
src,
|
|
221
209
|
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
222
210
|
dest,
|
|
@@ -224,39 +212,38 @@ async function downloadFile(accountId, src, destPath, cmsPublishMode, options =
|
|
|
224
212
|
}
|
|
225
213
|
catch (err) {
|
|
226
214
|
const error = err;
|
|
227
|
-
if (isHubspot &&
|
|
228
|
-
throw new Error(
|
|
215
|
+
if (isHubspot && isTimeoutError(error)) {
|
|
216
|
+
throw new Error(i18n(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
229
217
|
}
|
|
230
218
|
else {
|
|
231
|
-
throw new Error(
|
|
219
|
+
throw new Error(i18n(`${i18nKey}.errors.failedToFetchFile`, { src, dest: destPath }), { cause: error });
|
|
232
220
|
}
|
|
233
221
|
}
|
|
234
222
|
}
|
|
235
|
-
async function fetchFolderFromApi(accountId, src, cmsPublishMode, options = {}) {
|
|
223
|
+
export async function fetchFolderFromApi(accountId, src, cmsPublishMode, options = {}) {
|
|
236
224
|
const { isRoot, isFolder, isHubspot } = getTypeDataFromPath(src);
|
|
237
225
|
if (!isFolder) {
|
|
238
|
-
throw new Error(
|
|
226
|
+
throw new Error(i18n(`${i18nKey}.errors.invalidFetchFolderRequest`, {
|
|
239
227
|
src,
|
|
240
228
|
}));
|
|
241
229
|
}
|
|
242
230
|
const srcPath = isRoot ? '@root' : src;
|
|
243
231
|
const queryValues = getFileMapperQueryValues(cmsPublishMode, options);
|
|
244
232
|
const { data: node } = isHubspot
|
|
245
|
-
? await
|
|
246
|
-
: await
|
|
247
|
-
|
|
233
|
+
? await downloadDefault(accountId, srcPath, queryValues)
|
|
234
|
+
: await download(accountId, srcPath, queryValues);
|
|
235
|
+
logger.log(i18n(`${i18nKey}.folderFetch`, { src, accountId }));
|
|
248
236
|
return node;
|
|
249
237
|
}
|
|
250
|
-
exports.fetchFolderFromApi = fetchFolderFromApi;
|
|
251
238
|
async function downloadFolder(accountId, src, destPath, cmsPublishMode, options = {}) {
|
|
252
239
|
try {
|
|
253
240
|
const node = await fetchFolderFromApi(accountId, src, cmsPublishMode, options);
|
|
254
241
|
if (!node) {
|
|
255
242
|
return;
|
|
256
243
|
}
|
|
257
|
-
const dest =
|
|
258
|
-
const rootPath = dest ===
|
|
259
|
-
?
|
|
244
|
+
const dest = path.resolve(destPath);
|
|
245
|
+
const rootPath = dest === getCwd()
|
|
246
|
+
? convertToLocalFileSystemPath(path.resolve(dest, node.name))
|
|
260
247
|
: dest;
|
|
261
248
|
let success = true;
|
|
262
249
|
recurseFolder(node, (childNode, filepath) => {
|
|
@@ -264,7 +251,7 @@ async function downloadFolder(accountId, src, destPath, cmsPublishMode, options
|
|
|
264
251
|
const succeeded = await writeFileMapperNode(accountId, filepath || '', childNode, cmsPublishMode, options);
|
|
265
252
|
if (succeeded === false) {
|
|
266
253
|
success = false;
|
|
267
|
-
|
|
254
|
+
logger.debug(i18n(`${i18nKey}.errors.failedToFetchFile`, {
|
|
268
255
|
src: childNode.path,
|
|
269
256
|
dest: filepath || '',
|
|
270
257
|
}));
|
|
@@ -274,7 +261,7 @@ async function downloadFolder(accountId, src, destPath, cmsPublishMode, options
|
|
|
274
261
|
}, rootPath);
|
|
275
262
|
await queue.onIdle();
|
|
276
263
|
if (success) {
|
|
277
|
-
|
|
264
|
+
logger.success(i18n(`${i18nKey}.completedFolderFetch`, {
|
|
278
265
|
src,
|
|
279
266
|
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
280
267
|
dest,
|
|
@@ -282,16 +269,16 @@ async function downloadFolder(accountId, src, destPath, cmsPublishMode, options
|
|
|
282
269
|
}
|
|
283
270
|
else {
|
|
284
271
|
// TODO: Fix this exception. It is triggering the catch block so this error is being rewritten
|
|
285
|
-
throw new Error(
|
|
272
|
+
throw new Error(i18n(`${i18nKey}.errors.incompleteFetch`, { src }));
|
|
286
273
|
}
|
|
287
274
|
}
|
|
288
275
|
catch (err) {
|
|
289
276
|
const error = err;
|
|
290
|
-
if (
|
|
291
|
-
throw new Error(
|
|
277
|
+
if (isTimeoutError(error)) {
|
|
278
|
+
throw new Error(i18n(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
292
279
|
}
|
|
293
280
|
else {
|
|
294
|
-
throw new Error(
|
|
281
|
+
throw new Error(i18n(`${i18nKey}.errors.failedToFetchFolder`, { src, dest: destPath }), { cause: err });
|
|
295
282
|
}
|
|
296
283
|
}
|
|
297
284
|
}
|
|
@@ -302,7 +289,7 @@ async function downloadFolder(accountId, src, destPath, cmsPublishMode, options
|
|
|
302
289
|
* @param {FileMapperInputArguments} input
|
|
303
290
|
* @returns {Promise}
|
|
304
291
|
*/
|
|
305
|
-
async function downloadFileOrFolder(accountId, src, dest, cmsPublishMode, options = {}) {
|
|
292
|
+
export async function downloadFileOrFolder(accountId, src, dest, cmsPublishMode, options = {}) {
|
|
306
293
|
if (!src) {
|
|
307
294
|
return;
|
|
308
295
|
}
|
|
@@ -314,4 +301,3 @@ async function downloadFileOrFolder(accountId, src, dest, cmsPublishMode, option
|
|
|
314
301
|
await downloadFolder(accountId, src, dest, cmsPublishMode, options);
|
|
315
302
|
}
|
|
316
303
|
}
|
|
317
|
-
exports.downloadFileOrFolder = downloadFileOrFolder;
|
package/lib/fs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileData } from '../types/Files';
|
|
1
|
+
import { FileData } from '../types/Files.js';
|
|
2
2
|
export declare function getFileInfoAsync(dir: string, file: string): Promise<FileData>;
|
|
3
3
|
export declare function flattenAndRemoveSymlinks(filesData: Array<FileData>): Array<string>;
|
|
4
4
|
export declare function walk(dir: string, ignoreDirs?: string[]): Promise<Array<string>>;
|