@hubspot/local-dev-lib 0.0.1-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/LICENSE +12 -0
- package/README.md +17 -0
- package/api/appsDev.d.ts +6 -0
- package/api/appsDev.js +29 -0
- package/api/customObjects.d.ts +8 -0
- package/api/customObjects.js +45 -0
- package/api/designManager.d.ts +5 -0
- package/api/designManager.js +18 -0
- package/api/developerTestAccounts.d.ts +7 -0
- package/api/developerTestAccounts.js +48 -0
- package/api/fileManager.d.ts +6 -0
- package/api/fileManager.js +63 -0
- package/api/fileMapper.d.ts +12 -0
- package/api/fileMapper.js +106 -0
- package/api/fileTransport.d.ts +4 -0
- package/api/fileTransport.js +39 -0
- package/api/functions.d.ts +8 -0
- package/api/functions.js +43 -0
- package/api/github.d.ts +11 -0
- package/api/github.js +71 -0
- package/api/hubdb.d.ts +12 -0
- package/api/hubdb.js +67 -0
- package/api/lighthouseScore.d.ts +6 -0
- package/api/lighthouseScore.js +26 -0
- package/api/localDevAuth.d.ts +8 -0
- package/api/localDevAuth.js +53 -0
- package/api/marketplaceValidation.d.ts +6 -0
- package/api/marketplaceValidation.js +26 -0
- package/api/projects.d.ts +40 -0
- package/api/projects.js +216 -0
- package/api/sandboxHubs.d.ts +7 -0
- package/api/sandboxHubs.js +49 -0
- package/api/sandboxSync.d.ts +4 -0
- package/api/sandboxSync.js +26 -0
- package/api/secrets.d.ts +6 -0
- package/api/secrets.js +37 -0
- package/api/validateHubl.d.ts +3 -0
- package/api/validateHubl.js +15 -0
- package/config/CLIConfiguration.d.ts +62 -0
- package/config/CLIConfiguration.js +467 -0
- package/config/configFile.d.ts +21 -0
- package/config/configFile.js +102 -0
- package/config/configUtils.d.ts +5 -0
- package/config/configUtils.js +87 -0
- package/config/config_DEPRECATED.d.ts +75 -0
- package/config/config_DEPRECATED.js +678 -0
- package/config/environment.d.ts +2 -0
- package/config/environment.js +60 -0
- package/config/getAccountIdentifier.d.ts +2 -0
- package/config/getAccountIdentifier.js +15 -0
- package/config/index.d.ts +41 -0
- package/config/index.js +260 -0
- package/constants/api.d.ts +15 -0
- package/constants/api.js +18 -0
- package/constants/auth.d.ts +37 -0
- package/constants/auth.js +38 -0
- package/constants/config.d.ts +18 -0
- package/constants/config.js +22 -0
- package/constants/environments.d.ts +15 -0
- package/constants/environments.js +18 -0
- package/constants/extensions.d.ts +6 -0
- package/constants/extensions.js +28 -0
- package/constants/files.d.ts +21 -0
- package/constants/files.js +24 -0
- package/constants/ports.d.ts +3 -0
- package/constants/ports.js +6 -0
- package/enums/build.d.ts +36 -0
- package/enums/build.js +39 -0
- package/enums/deploy.d.ts +11 -0
- package/enums/deploy.js +14 -0
- package/enums/project.d.ts +6 -0
- package/enums/project.js +9 -0
- package/errors/errors_DEPRECATED.d.ts +3 -0
- package/errors/errors_DEPRECATED.js +60 -0
- package/errors/index.d.ts +18 -0
- package/errors/index.js +63 -0
- package/http/addQueryParams.d.ts +2 -0
- package/http/addQueryParams.js +14 -0
- package/http/getAxiosConfig.d.ts +9 -0
- package/http/getAxiosConfig.js +66 -0
- package/http/index.d.ts +17 -0
- package/http/index.js +173 -0
- package/http/unauthed.d.ts +15 -0
- package/http/unauthed.js +38 -0
- package/lang/en.json +389 -0
- package/lib/archive.d.ts +3 -0
- package/lib/archive.js +117 -0
- package/lib/cms/functions.d.ts +8 -0
- package/lib/cms/functions.js +181 -0
- package/lib/cms/handleFieldsJS.d.ts +33 -0
- package/lib/cms/handleFieldsJS.js +148 -0
- package/lib/cms/modules.d.ts +14 -0
- package/lib/cms/modules.js +186 -0
- package/lib/cms/processFieldsJs.d.ts +1 -0
- package/lib/cms/processFieldsJs.js +97 -0
- package/lib/cms/templates.d.ts +65 -0
- package/lib/cms/templates.js +107 -0
- package/lib/cms/themes.d.ts +2 -0
- package/lib/cms/themes.js +34 -0
- package/lib/cms/uploadFolder.d.ts +7 -0
- package/lib/cms/uploadFolder.js +202 -0
- package/lib/cms/validate.d.ts +2 -0
- package/lib/cms/validate.js +40 -0
- package/lib/cms/watch.d.ts +4 -0
- package/lib/cms/watch.js +201 -0
- package/lib/customObjects.d.ts +5 -0
- package/lib/customObjects.js +42 -0
- package/lib/environment.d.ts +2 -0
- package/lib/environment.js +16 -0
- package/lib/escapeRegExp.d.ts +1 -0
- package/lib/escapeRegExp.js +7 -0
- package/lib/fileManager.d.ts +2 -0
- package/lib/fileManager.js +184 -0
- package/lib/fileMapper.d.ts +18 -0
- package/lib/fileMapper.js +317 -0
- package/lib/fs.d.ts +4 -0
- package/lib/fs.js +71 -0
- package/lib/github.d.ts +8 -0
- package/lib/github.js +167 -0
- package/lib/gitignore.d.ts +3 -0
- package/lib/gitignore.js +49 -0
- package/lib/hubdb.d.ts +17 -0
- package/lib/hubdb.js +133 -0
- package/lib/ignoreRules.d.ts +3 -0
- package/lib/ignoreRules.js +69 -0
- package/lib/logger.d.ts +56 -0
- package/lib/logger.js +146 -0
- package/lib/notify.d.ts +1 -0
- package/lib/notify.js +43 -0
- package/lib/oauth.d.ts +4 -0
- package/lib/oauth.js +34 -0
- package/lib/path.d.ts +14 -0
- package/lib/path.js +134 -0
- package/lib/personalAccessKey.d.ts +10 -0
- package/lib/personalAccessKey.js +163 -0
- package/lib/portManager.d.ts +10 -0
- package/lib/portManager.js +46 -0
- package/lib/text.d.ts +2 -0
- package/lib/text.js +24 -0
- package/lib/trackUsage.d.ts +1 -0
- package/lib/trackUsage.js +63 -0
- package/lib/urls.d.ts +2 -0
- package/lib/urls.js +24 -0
- package/models/FileSystemError.d.ts +6 -0
- package/models/FileSystemError.js +47 -0
- package/models/HubSpotHttpError.d.ts +24 -0
- package/models/HubSpotHttpError.js +197 -0
- package/models/OAuth2Manager.d.ts +12 -0
- package/models/OAuth2Manager.js +105 -0
- package/package.json +81 -0
- package/types/Accounts.d.ts +178 -0
- package/types/Accounts.js +2 -0
- package/types/Activity.d.ts +20 -0
- package/types/Activity.js +2 -0
- package/types/Api.d.ts +2 -0
- package/types/Api.js +2 -0
- package/types/Apps.d.ts +77 -0
- package/types/Apps.js +2 -0
- package/types/Archive.d.ts +9 -0
- package/types/Archive.js +2 -0
- package/types/Build.d.ts +41 -0
- package/types/Build.js +2 -0
- package/types/CLIOptions.d.ts +8 -0
- package/types/CLIOptions.js +2 -0
- package/types/ComponentStructure.d.ts +40 -0
- package/types/ComponentStructure.js +2 -0
- package/types/Config.d.ts +37 -0
- package/types/Config.js +2 -0
- package/types/Deploy.d.ts +42 -0
- package/types/Deploy.js +2 -0
- package/types/DesignManager.d.ts +10 -0
- package/types/DesignManager.js +2 -0
- package/types/Error.d.ts +37 -0
- package/types/Error.js +2 -0
- package/types/FieldsJS.d.ts +1 -0
- package/types/FieldsJS.js +2 -0
- package/types/FileManager.d.ts +71 -0
- package/types/FileManager.js +2 -0
- package/types/Files.d.ts +79 -0
- package/types/Files.js +2 -0
- package/types/Functions.d.ts +66 -0
- package/types/Functions.js +2 -0
- package/types/Github.d.ts +76 -0
- package/types/Github.js +2 -0
- package/types/Http.d.ts +29 -0
- package/types/Http.js +2 -0
- package/types/Hubdb.d.ts +109 -0
- package/types/Hubdb.js +2 -0
- package/types/HublValidation.d.ts +59 -0
- package/types/HublValidation.js +2 -0
- package/types/Lang.d.ts +10 -0
- package/types/Lang.js +2 -0
- package/types/Lighthouse.d.ts +25 -0
- package/types/Lighthouse.js +2 -0
- package/types/MarketplaceValidation.d.ts +28 -0
- package/types/MarketplaceValidation.js +2 -0
- package/types/Migration.d.ts +28 -0
- package/types/Migration.js +10 -0
- package/types/Modules.d.ts +16 -0
- package/types/Modules.js +2 -0
- package/types/PortManager.d.ts +11 -0
- package/types/PortManager.js +2 -0
- package/types/Project.d.ts +42 -0
- package/types/Project.js +2 -0
- package/types/ProjectLog.d.ts +9 -0
- package/types/ProjectLog.js +2 -0
- package/types/Sandbox.d.ts +155 -0
- package/types/Sandbox.js +2 -0
- package/types/Schemas.d.ts +39 -0
- package/types/Schemas.js +2 -0
- package/types/Secrets.d.ts +3 -0
- package/types/Secrets.js +2 -0
- package/types/Utils.d.ts +6 -0
- package/types/Utils.js +2 -0
- package/types/developerTestAccounts.d.ts +12 -0
- package/types/developerTestAccounts.js +2 -0
- package/utils/PortManagerServer.d.ts +26 -0
- package/utils/PortManagerServer.js +158 -0
- package/utils/accounts.d.ts +4 -0
- package/utils/accounts.js +28 -0
- package/utils/cms/fieldsJS.d.ts +2 -0
- package/utils/cms/fieldsJS.js +18 -0
- package/utils/cms/modules.d.ts +4 -0
- package/utils/cms/modules.js +54 -0
- package/utils/detectPort.d.ts +1 -0
- package/utils/detectPort.js +102 -0
- package/utils/git.d.ts +3 -0
- package/utils/git.js +71 -0
- package/utils/lang.d.ts +6 -0
- package/utils/lang.js +88 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Schema } from '../types/Schemas';
|
|
2
|
+
export declare function getResolvedPath(dest?: string, name?: string): string;
|
|
3
|
+
export declare function writeSchemaToDisk(schema: Schema, dest?: string): Promise<void>;
|
|
4
|
+
export declare function downloadSchemas(accountId: number, dest?: string): Promise<Array<Schema>>;
|
|
5
|
+
export declare function downloadSchema(accountId: number, schemaObjectType: string, dest?: string): Promise<Schema>;
|
|
@@ -0,0 +1,42 @@
|
|
|
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.downloadSchema = exports.downloadSchemas = exports.writeSchemaToDisk = exports.getResolvedPath = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prettier_1 = __importDefault(require("prettier"));
|
|
10
|
+
const path_2 = require("../lib/path");
|
|
11
|
+
const customObjects_1 = require("../api/customObjects");
|
|
12
|
+
function getResolvedPath(dest, name) {
|
|
13
|
+
if (name)
|
|
14
|
+
return path_1.default.resolve((0, path_2.getCwd)(), dest || '', `${name}.json`);
|
|
15
|
+
return path_1.default.resolve((0, path_2.getCwd)(), dest || '');
|
|
16
|
+
}
|
|
17
|
+
exports.getResolvedPath = getResolvedPath;
|
|
18
|
+
async function writeSchemaToDisk(schema, dest) {
|
|
19
|
+
const formattedSchema = await prettier_1.default.format(JSON.stringify(schema), {
|
|
20
|
+
parser: 'json',
|
|
21
|
+
});
|
|
22
|
+
fs_extra_1.default.outputFileSync(getResolvedPath(dest, schema.name), formattedSchema);
|
|
23
|
+
}
|
|
24
|
+
exports.writeSchemaToDisk = writeSchemaToDisk;
|
|
25
|
+
async function downloadSchemas(accountId, dest) {
|
|
26
|
+
const axiosResponse = await (0, customObjects_1.fetchObjectSchemas)(accountId);
|
|
27
|
+
const response = axiosResponse.data;
|
|
28
|
+
if (response.results.length) {
|
|
29
|
+
for (const schema of response.results) {
|
|
30
|
+
await writeSchemaToDisk(schema, dest);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return response.results;
|
|
34
|
+
}
|
|
35
|
+
exports.downloadSchemas = downloadSchemas;
|
|
36
|
+
async function downloadSchema(accountId, schemaObjectType, dest) {
|
|
37
|
+
const axiosResponse = await (0, customObjects_1.fetchObjectSchema)(accountId, schemaObjectType);
|
|
38
|
+
const response = axiosResponse.data;
|
|
39
|
+
await writeSchemaToDisk(response, dest);
|
|
40
|
+
return response;
|
|
41
|
+
}
|
|
42
|
+
exports.downloadSchema = downloadSchema;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getValidEnv = void 0;
|
|
4
|
+
const environments_1 = require("../constants/environments");
|
|
5
|
+
function getValidEnv(env, maskedProductionValue) {
|
|
6
|
+
const prodValue = typeof maskedProductionValue === 'string'
|
|
7
|
+
? maskedProductionValue
|
|
8
|
+
: environments_1.ENVIRONMENTS.PROD;
|
|
9
|
+
const returnVal = typeof env &&
|
|
10
|
+
typeof env === 'string' &&
|
|
11
|
+
env.toLowerCase() === environments_1.ENVIRONMENTS.QA
|
|
12
|
+
? environments_1.ENVIRONMENTS.QA
|
|
13
|
+
: prodValue;
|
|
14
|
+
return returnVal;
|
|
15
|
+
}
|
|
16
|
+
exports.getValidEnv = getValidEnv;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function escapeRegExp(string: string): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeRegExp = void 0;
|
|
4
|
+
function escapeRegExp(string) {
|
|
5
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
6
|
+
}
|
|
7
|
+
exports.escapeRegExp = escapeRegExp;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// FILE MANAGER - not to be confused with fileMapper.ts
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.downloadFileOrFolder = exports.uploadFolder = void 0;
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const fileManager_1 = require("../api/fileManager");
|
|
11
|
+
const fs_1 = require("./fs");
|
|
12
|
+
const logger_1 = require("./logger");
|
|
13
|
+
const ignoreRules_1 = require("./ignoreRules");
|
|
14
|
+
const http_1 = require("../http");
|
|
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");
|
|
20
|
+
const i18nKey = 'lib.fileManager';
|
|
21
|
+
async function uploadFolder(accountId, src, dest) {
|
|
22
|
+
const regex = new RegExp(`^${(0, escapeRegExp_1.escapeRegExp)(src)}`);
|
|
23
|
+
const files = await (0, fs_1.walk)(src);
|
|
24
|
+
const filesToUpload = files.filter((0, ignoreRules_1.createIgnoreFilter)(false));
|
|
25
|
+
const len = filesToUpload.length;
|
|
26
|
+
for (let index = 0; index < len; index++) {
|
|
27
|
+
const file = filesToUpload[index];
|
|
28
|
+
const relativePath = file.replace(regex, '');
|
|
29
|
+
const destPath = (0, path_2.convertToUnixPath)(path_1.default.join(dest, relativePath));
|
|
30
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.uploadStarted`, {
|
|
31
|
+
file,
|
|
32
|
+
destPath,
|
|
33
|
+
accountId,
|
|
34
|
+
}));
|
|
35
|
+
try {
|
|
36
|
+
await (0, fileManager_1.uploadFile)(accountId, file, destPath);
|
|
37
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.uploadSuccess`, { file, destPath }));
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if ((0, errors_1.isHubSpotHttpError)(err)) {
|
|
41
|
+
err.updateContext({
|
|
42
|
+
filepath: file,
|
|
43
|
+
dest: destPath,
|
|
44
|
+
});
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.uploadFailed`, {
|
|
48
|
+
file,
|
|
49
|
+
destPath,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.uploadFolder = uploadFolder;
|
|
55
|
+
async function skipExisting(overwrite, filepath) {
|
|
56
|
+
if (overwrite) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (await fs_extra_1.default.pathExists(filepath)) {
|
|
60
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, { filepath }));
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
async function downloadFile(accountId, file, dest, overwrite) {
|
|
66
|
+
const fileName = `${file.name}.${file.extension}`;
|
|
67
|
+
const destPath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.join(dest, fileName));
|
|
68
|
+
if (await skipExisting(overwrite || false, destPath)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
await http_1.http.getOctetStream(accountId, {
|
|
72
|
+
baseURL: file.url,
|
|
73
|
+
url: '',
|
|
74
|
+
}, destPath);
|
|
75
|
+
}
|
|
76
|
+
async function fetchAllPagedFiles(accountId, folderId, includeArchived) {
|
|
77
|
+
let totalFiles = null;
|
|
78
|
+
let files = [];
|
|
79
|
+
let count = 0;
|
|
80
|
+
let offset = 0;
|
|
81
|
+
while (totalFiles === null || count < totalFiles) {
|
|
82
|
+
const { data: response } = await (0, fileManager_1.fetchFiles)(accountId, folderId, offset, includeArchived);
|
|
83
|
+
if (totalFiles === null) {
|
|
84
|
+
totalFiles = response.total_count;
|
|
85
|
+
}
|
|
86
|
+
count += response.objects.length;
|
|
87
|
+
offset += response.objects.length;
|
|
88
|
+
files = files.concat(response.objects);
|
|
89
|
+
}
|
|
90
|
+
return files;
|
|
91
|
+
}
|
|
92
|
+
async function fetchFolderContents(accountId, folder, dest, overwrite, includeArchived) {
|
|
93
|
+
try {
|
|
94
|
+
await fs_extra_1.default.ensureDir(dest);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
throw new FileSystemError_1.FileSystemError({ cause: err }, {
|
|
98
|
+
dest,
|
|
99
|
+
accountId,
|
|
100
|
+
operation: 'write',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const files = await fetchAllPagedFiles(accountId, folder.id, includeArchived);
|
|
104
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.fetchingFiles`, {
|
|
105
|
+
fileCount: files.length,
|
|
106
|
+
folderName: folder.name || '',
|
|
107
|
+
}));
|
|
108
|
+
for (const file of files) {
|
|
109
|
+
await downloadFile(accountId, file, dest, overwrite);
|
|
110
|
+
}
|
|
111
|
+
const { data: { objects: folders }, } = await (0, fileManager_1.fetchFolders)(accountId, folder.id);
|
|
112
|
+
for (const folder of folders) {
|
|
113
|
+
const nestedFolder = path_1.default.join(dest, folder.name);
|
|
114
|
+
await fetchFolderContents(accountId, folder, nestedFolder, overwrite, includeArchived);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Download a folder and write to local file system.
|
|
118
|
+
async function downloadFolder(accountId, src, dest, folder, overwrite, includeArchived) {
|
|
119
|
+
let absolutePath;
|
|
120
|
+
if (folder.name) {
|
|
121
|
+
absolutePath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve((0, path_2.getCwd)(), dest, folder.name));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
absolutePath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve((0, path_2.getCwd)(), dest));
|
|
125
|
+
}
|
|
126
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.fetchFolderStarted`, {
|
|
127
|
+
src,
|
|
128
|
+
path: absolutePath,
|
|
129
|
+
accountId,
|
|
130
|
+
}));
|
|
131
|
+
await fetchFolderContents(accountId, folder, absolutePath, overwrite, includeArchived);
|
|
132
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.fetchFolderSuccess`, {
|
|
133
|
+
src,
|
|
134
|
+
dest,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
// Download a single file and write to local file system.
|
|
138
|
+
async function downloadSingleFile(accountId, src, dest, file, overwrite, includeArchived) {
|
|
139
|
+
if (!includeArchived && file.archived) {
|
|
140
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.archivedFile`, { src }));
|
|
141
|
+
}
|
|
142
|
+
if (file.hidden) {
|
|
143
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.hiddenFile`, { src }));
|
|
144
|
+
}
|
|
145
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.fetchFileStarted`, {
|
|
146
|
+
src,
|
|
147
|
+
dest,
|
|
148
|
+
accountId,
|
|
149
|
+
}));
|
|
150
|
+
await downloadFile(accountId, file, dest, overwrite);
|
|
151
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.fetchFileSuccess`, {
|
|
152
|
+
src,
|
|
153
|
+
dest,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
// Lookup path in file manager and initiate download
|
|
157
|
+
async function downloadFileOrFolder(accountId, src, dest, overwrite, includeArchived) {
|
|
158
|
+
try {
|
|
159
|
+
if (src == '/') {
|
|
160
|
+
// Filemanager API treats 'None' as the root
|
|
161
|
+
const rootFolder = { id: 'None', name: '' };
|
|
162
|
+
await downloadFolder(accountId, src, dest, rootFolder, overwrite, includeArchived);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const { data: { file, folder }, } = await (0, fileManager_1.fetchStat)(accountId, src);
|
|
166
|
+
if (file) {
|
|
167
|
+
await downloadSingleFile(accountId, src, dest, file, overwrite, includeArchived);
|
|
168
|
+
}
|
|
169
|
+
else if (folder) {
|
|
170
|
+
await downloadFolder(accountId, src, dest, folder, overwrite, includeArchived);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
if ((0, errors_1.isAuthError)(err)) {
|
|
176
|
+
err.updateContext({
|
|
177
|
+
request: src,
|
|
178
|
+
accountId,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.downloadFileOrFolder = downloadFileOrFolder;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FileMapperNode, Mode, FileMapperOptions, FileMapperInputOptions, PathTypeData, RecursiveFileMapperCallback } from '../types/Files';
|
|
2
|
+
export declare function isPathToFile(filepath: string): boolean;
|
|
3
|
+
export declare function isPathToModule(filepath: string): boolean;
|
|
4
|
+
export declare function isPathToRoot(filepath: string): boolean;
|
|
5
|
+
export declare function isPathToHubspot(filepath: string): boolean;
|
|
6
|
+
export declare function getFileMapperQueryValues(mode?: Mode | null, { staging, assetVersion }?: FileMapperInputOptions): FileMapperOptions;
|
|
7
|
+
export declare function getTypeDataFromPath(src: string): PathTypeData;
|
|
8
|
+
export declare function recurseFolder(node: FileMapperNode, callback: RecursiveFileMapperCallback, filepath?: string, depth?: number): boolean;
|
|
9
|
+
export declare function writeUtimes(accountId: number, filepath: string, node: FileMapperNode): Promise<void>;
|
|
10
|
+
export declare function fetchFolderFromApi(accountId: number, src: string, mode?: Mode, options?: FileMapperInputOptions): Promise<FileMapperNode>;
|
|
11
|
+
/**
|
|
12
|
+
* Fetch a file/folder and write to local file system.
|
|
13
|
+
*
|
|
14
|
+
* @async
|
|
15
|
+
* @param {FileMapperInputArguments} input
|
|
16
|
+
* @returns {Promise}
|
|
17
|
+
*/
|
|
18
|
+
export declare function downloadFileOrFolder(accountId: number, src: string, dest: string, mode?: Mode, options?: FileMapperInputOptions): Promise<void>;
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// FILE MAPPER - not to be confused with fileManager.ts
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.downloadFileOrFolder = exports.fetchFolderFromApi = exports.writeUtimes = exports.recurseFolder = exports.getTypeDataFromPath = exports.getFileMapperQueryValues = exports.isPathToHubspot = exports.isPathToRoot = exports.isPathToModule = exports.isPathToFile = void 0;
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const p_queue_1 = __importDefault(require("p-queue"));
|
|
11
|
+
const path_2 = require("./path");
|
|
12
|
+
const logger_1 = require("./logger");
|
|
13
|
+
const fileMapper_1 = require("../api/fileMapper");
|
|
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");
|
|
19
|
+
const i18nKey = 'lib.fileMapper';
|
|
20
|
+
const queue = new p_queue_1.default({
|
|
21
|
+
concurrency: 10,
|
|
22
|
+
});
|
|
23
|
+
function isPathToFile(filepath) {
|
|
24
|
+
const ext = (0, path_2.getExt)(filepath);
|
|
25
|
+
return !!ext && ext !== extensions_1.MODULE_EXTENSION && ext !== extensions_1.FUNCTIONS_EXTENSION;
|
|
26
|
+
}
|
|
27
|
+
exports.isPathToFile = isPathToFile;
|
|
28
|
+
function isPathToModule(filepath) {
|
|
29
|
+
const ext = (0, path_2.getExt)(filepath);
|
|
30
|
+
return ext === extensions_1.MODULE_EXTENSION;
|
|
31
|
+
}
|
|
32
|
+
exports.isPathToModule = isPathToModule;
|
|
33
|
+
function isPathToRoot(filepath) {
|
|
34
|
+
if (typeof filepath !== 'string')
|
|
35
|
+
return false;
|
|
36
|
+
// Root pattern matches empty strings and: / \
|
|
37
|
+
return /^(\/|\\)?$/.test(filepath.trim());
|
|
38
|
+
}
|
|
39
|
+
exports.isPathToRoot = isPathToRoot;
|
|
40
|
+
function isPathToHubspot(filepath) {
|
|
41
|
+
if (typeof filepath !== 'string')
|
|
42
|
+
return false;
|
|
43
|
+
return /^(\/|\\)?@hubspot/i.test(filepath.trim());
|
|
44
|
+
}
|
|
45
|
+
exports.isPathToHubspot = isPathToHubspot;
|
|
46
|
+
function useApiBuffer(mode) {
|
|
47
|
+
return mode === files_1.MODE.draft;
|
|
48
|
+
}
|
|
49
|
+
// Determines API param based on mode an options
|
|
50
|
+
function getFileMapperQueryValues(mode, { staging, assetVersion } = {}) {
|
|
51
|
+
return {
|
|
52
|
+
params: {
|
|
53
|
+
buffer: useApiBuffer(mode),
|
|
54
|
+
environmentId: staging ? 2 : 1,
|
|
55
|
+
version: assetVersion,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.getFileMapperQueryValues = getFileMapperQueryValues;
|
|
60
|
+
// Determines version number to log based on input.options
|
|
61
|
+
function getAssetVersionIdentifier(assetVersion, src) {
|
|
62
|
+
if (typeof assetVersion !== 'undefined' &&
|
|
63
|
+
typeof src !== 'undefined' &&
|
|
64
|
+
src.startsWith('@hubspot/')) {
|
|
65
|
+
return ` v${assetVersion}`;
|
|
66
|
+
}
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
function validateFileMapperNode(node) {
|
|
70
|
+
if (node === Object(node))
|
|
71
|
+
return;
|
|
72
|
+
let json;
|
|
73
|
+
try {
|
|
74
|
+
json = JSON.stringify(node, null, 2);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
json = node;
|
|
78
|
+
}
|
|
79
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidNode`, {
|
|
80
|
+
json: JSON.stringify(json),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
function getTypeDataFromPath(src) {
|
|
84
|
+
const isModule = isPathToModule(src);
|
|
85
|
+
const isHubspot = isPathToHubspot(src);
|
|
86
|
+
const isFile = !isModule && isPathToFile(src);
|
|
87
|
+
const isRoot = !isModule && !isFile && isPathToRoot(src);
|
|
88
|
+
const isFolder = !isFile;
|
|
89
|
+
return {
|
|
90
|
+
isModule,
|
|
91
|
+
isHubspot,
|
|
92
|
+
isFile,
|
|
93
|
+
isRoot,
|
|
94
|
+
isFolder,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
exports.getTypeDataFromPath = getTypeDataFromPath;
|
|
98
|
+
function recurseFolder(node, callback, filepath = '', depth = 0) {
|
|
99
|
+
validateFileMapperNode(node);
|
|
100
|
+
const isRootFolder = node.folder && depth === 0;
|
|
101
|
+
if (isRootFolder) {
|
|
102
|
+
if (!filepath) {
|
|
103
|
+
filepath = node.name;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
filepath = path_1.default.join(filepath, node.name);
|
|
108
|
+
}
|
|
109
|
+
let __break = callback(node, filepath, depth);
|
|
110
|
+
if (__break === false)
|
|
111
|
+
return __break;
|
|
112
|
+
__break = node.children.every(childNode => {
|
|
113
|
+
__break = recurseFolder(childNode, callback, filepath, depth + 1);
|
|
114
|
+
return __break !== false;
|
|
115
|
+
});
|
|
116
|
+
return depth === 0 ? false : __break;
|
|
117
|
+
}
|
|
118
|
+
exports.recurseFolder = recurseFolder;
|
|
119
|
+
async function writeUtimes(accountId, filepath, node) {
|
|
120
|
+
try {
|
|
121
|
+
const now = new Date();
|
|
122
|
+
const atime = node.createdAt ? new Date(node.createdAt) : now;
|
|
123
|
+
const mtime = node.updatedAt ? new Date(node.updatedAt) : now;
|
|
124
|
+
await fs_extra_1.default.utimes(filepath, atime, mtime);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
throw new FileSystemError_1.FileSystemError({ cause: err }, {
|
|
128
|
+
filepath,
|
|
129
|
+
accountId,
|
|
130
|
+
operation: 'write',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.writeUtimes = writeUtimes;
|
|
135
|
+
async function skipExisting(filepath, overwrite = false) {
|
|
136
|
+
if (overwrite) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
if (await fs_extra_1.default.pathExists(filepath)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
async function fetchAndWriteFileStream(accountId, srcPath, filepath, mode, options = {}) {
|
|
145
|
+
if (typeof srcPath !== 'string' || !srcPath.trim()) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (await skipExisting(filepath, options.overwrite)) {
|
|
149
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, { filepath }));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!(0, path_2.isAllowedExtension)(srcPath, Array.from(extensions_1.JSR_ALLOWED_EXTENSIONS))) {
|
|
153
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidFileType`, { srcPath }));
|
|
154
|
+
}
|
|
155
|
+
const node = await (0, fileMapper_1.fetchFileStream)(accountId, srcPath, filepath, getFileMapperQueryValues(mode, options));
|
|
156
|
+
await writeUtimes(accountId, filepath, node);
|
|
157
|
+
}
|
|
158
|
+
// Writes an individual file or folder (not recursive). If file source is missing, the
|
|
159
|
+
//file is fetched.
|
|
160
|
+
async function writeFileMapperNode(accountId, filepath, node, mode, options = {}) {
|
|
161
|
+
const localFilepath = (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve(filepath));
|
|
162
|
+
if (await skipExisting(localFilepath, options.overwrite)) {
|
|
163
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.skippedExisting`, {
|
|
164
|
+
filepath: localFilepath,
|
|
165
|
+
}));
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
if (!node.folder) {
|
|
169
|
+
try {
|
|
170
|
+
await fetchAndWriteFileStream(accountId, node.path, localFilepath, mode, options);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
await fs_extra_1.default.ensureDir(localFilepath);
|
|
179
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.wroteFolder`, {
|
|
180
|
+
filepath: localFilepath,
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
throw new FileSystemError_1.FileSystemError({ cause: err }, {
|
|
185
|
+
filepath: localFilepath,
|
|
186
|
+
accountId,
|
|
187
|
+
operation: 'write',
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
async function downloadFile(accountId, src, destPath, mode, options = {}) {
|
|
193
|
+
const { isFile, isHubspot } = getTypeDataFromPath(src);
|
|
194
|
+
if (!isFile) {
|
|
195
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidRequest`, { src }));
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const dest = path_1.default.resolve(destPath);
|
|
199
|
+
const cwd = (0, path_2.getCwd)();
|
|
200
|
+
let filepath;
|
|
201
|
+
if (dest === cwd) {
|
|
202
|
+
// Dest: CWD
|
|
203
|
+
filepath = path_1.default.resolve(cwd, path_1.default.basename(src));
|
|
204
|
+
}
|
|
205
|
+
else if (isPathToFile(dest)) {
|
|
206
|
+
// Dest: file path
|
|
207
|
+
filepath = path_1.default.isAbsolute(dest) ? dest : path_1.default.resolve(cwd, dest);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
// Dest: folder path
|
|
211
|
+
const name = path_1.default.basename(src);
|
|
212
|
+
filepath = path_1.default.isAbsolute(dest)
|
|
213
|
+
? path_1.default.resolve(dest, name)
|
|
214
|
+
: path_1.default.resolve(cwd, dest, name);
|
|
215
|
+
}
|
|
216
|
+
const localFsPath = (0, path_2.convertToLocalFileSystemPath)(filepath);
|
|
217
|
+
await fetchAndWriteFileStream(accountId, src, localFsPath, mode, options);
|
|
218
|
+
await queue.onIdle();
|
|
219
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.completedFetch`, {
|
|
220
|
+
src,
|
|
221
|
+
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
222
|
+
dest,
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
const error = err;
|
|
227
|
+
if (isHubspot && (0, errors_1.isTimeoutError)(error)) {
|
|
228
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFile`, { src, dest: destPath }), { cause: error });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function fetchFolderFromApi(accountId, src, mode, options = {}) {
|
|
236
|
+
const { isRoot, isFolder, isHubspot } = getTypeDataFromPath(src);
|
|
237
|
+
if (!isFolder) {
|
|
238
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.invalidFetchFolderRequest`, {
|
|
239
|
+
src,
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
const srcPath = isRoot ? '@root' : src;
|
|
243
|
+
const queryValues = getFileMapperQueryValues(mode, options);
|
|
244
|
+
const { data: node } = isHubspot
|
|
245
|
+
? await (0, fileMapper_1.downloadDefault)(accountId, srcPath, queryValues)
|
|
246
|
+
: await (0, fileMapper_1.download)(accountId, srcPath, queryValues);
|
|
247
|
+
logger_1.logger.log((0, lang_1.i18n)(`${i18nKey}.folderFetch`, { src, accountId }));
|
|
248
|
+
return node;
|
|
249
|
+
}
|
|
250
|
+
exports.fetchFolderFromApi = fetchFolderFromApi;
|
|
251
|
+
async function downloadFolder(accountId, src, destPath, mode, options = {}) {
|
|
252
|
+
try {
|
|
253
|
+
const node = await fetchFolderFromApi(accountId, src, mode, options);
|
|
254
|
+
if (!node) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const dest = path_1.default.resolve(destPath);
|
|
258
|
+
const rootPath = dest === (0, path_2.getCwd)()
|
|
259
|
+
? (0, path_2.convertToLocalFileSystemPath)(path_1.default.resolve(dest, node.name))
|
|
260
|
+
: dest;
|
|
261
|
+
let success = true;
|
|
262
|
+
recurseFolder(node, (childNode, filepath) => {
|
|
263
|
+
queue.add(async () => {
|
|
264
|
+
const succeeded = await writeFileMapperNode(accountId, filepath || '', childNode, mode, options);
|
|
265
|
+
if (succeeded === false) {
|
|
266
|
+
success = false;
|
|
267
|
+
logger_1.logger.debug((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFile`, {
|
|
268
|
+
src: childNode.path,
|
|
269
|
+
dest: filepath || '',
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return success;
|
|
274
|
+
}, rootPath);
|
|
275
|
+
await queue.onIdle();
|
|
276
|
+
if (success) {
|
|
277
|
+
logger_1.logger.success((0, lang_1.i18n)(`${i18nKey}.completedFolderFetch`, {
|
|
278
|
+
src,
|
|
279
|
+
version: getAssetVersionIdentifier(options.assetVersion, src),
|
|
280
|
+
dest,
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
// TODO: Fix this exception. It is triggering the catch block so this error is being rewritten
|
|
285
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.incompleteFetch`, { src }));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
const error = err;
|
|
290
|
+
if ((0, errors_1.isTimeoutError)(error)) {
|
|
291
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.assetTimeout`), { cause: error });
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
throw new Error((0, lang_1.i18n)(`${i18nKey}.errors.failedToFetchFolder`, { src, dest: destPath }), { cause: err });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Fetch a file/folder and write to local file system.
|
|
300
|
+
*
|
|
301
|
+
* @async
|
|
302
|
+
* @param {FileMapperInputArguments} input
|
|
303
|
+
* @returns {Promise}
|
|
304
|
+
*/
|
|
305
|
+
async function downloadFileOrFolder(accountId, src, dest, mode, options = {}) {
|
|
306
|
+
if (!src) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const { isFile } = getTypeDataFromPath(src);
|
|
310
|
+
if (isFile) {
|
|
311
|
+
await downloadFile(accountId, src, dest, mode, options);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
await downloadFolder(accountId, src, dest, mode, options);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
exports.downloadFileOrFolder = downloadFileOrFolder;
|
package/lib/fs.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FileData } from '../types/Files';
|
|
2
|
+
export declare function getFileInfoAsync(dir: string, file: string): Promise<FileData>;
|
|
3
|
+
export declare function flattenAndRemoveSymlinks(filesData: Array<FileData>): Array<string>;
|
|
4
|
+
export declare function walk(dir: string): Promise<Array<string>>;
|
package/lib/fs.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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.walk = exports.flattenAndRemoveSymlinks = exports.getFileInfoAsync = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const files_1 = require("../constants/files");
|
|
10
|
+
const FileSystemError_1 = require("../models/FileSystemError");
|
|
11
|
+
function getFileInfoAsync(dir, file) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const filepath = path_1.default.join(dir, file);
|
|
14
|
+
fs_1.default.lstat(filepath, (error, stats) => {
|
|
15
|
+
if (error) {
|
|
16
|
+
reject(error);
|
|
17
|
+
}
|
|
18
|
+
let type = files_1.STAT_TYPES.FILE;
|
|
19
|
+
if (stats.isSymbolicLink()) {
|
|
20
|
+
type = files_1.STAT_TYPES.SYMBOLIC_LINK;
|
|
21
|
+
}
|
|
22
|
+
else if (stats.isDirectory()) {
|
|
23
|
+
type = files_1.STAT_TYPES.DIRECTORY;
|
|
24
|
+
}
|
|
25
|
+
resolve({ filepath, type });
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.getFileInfoAsync = getFileInfoAsync;
|
|
30
|
+
function flattenAndRemoveSymlinks(filesData) {
|
|
31
|
+
return filesData.reduce((acc, fileData) => {
|
|
32
|
+
switch (fileData.type) {
|
|
33
|
+
case files_1.STAT_TYPES.FILE:
|
|
34
|
+
return acc.concat(fileData.filepath);
|
|
35
|
+
case files_1.STAT_TYPES.DIRECTORY:
|
|
36
|
+
return acc.concat(fileData.files || []);
|
|
37
|
+
case files_1.STAT_TYPES.SYMBOLIC_LINK:
|
|
38
|
+
return acc;
|
|
39
|
+
default:
|
|
40
|
+
return acc;
|
|
41
|
+
}
|
|
42
|
+
}, []);
|
|
43
|
+
}
|
|
44
|
+
exports.flattenAndRemoveSymlinks = flattenAndRemoveSymlinks;
|
|
45
|
+
const generateRecursiveFilePromise = async (dir, file) => {
|
|
46
|
+
return getFileInfoAsync(dir, file).then(fileData => {
|
|
47
|
+
return new Promise(resolve => {
|
|
48
|
+
if (fileData.type === files_1.STAT_TYPES.DIRECTORY) {
|
|
49
|
+
walk(fileData.filepath).then(files => {
|
|
50
|
+
resolve({ ...fileData, files });
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
resolve(fileData);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
async function walk(dir) {
|
|
60
|
+
function processFiles(files) {
|
|
61
|
+
return Promise.all(files.map(file => generateRecursiveFilePromise(dir, file)));
|
|
62
|
+
}
|
|
63
|
+
return fs_1.default.promises
|
|
64
|
+
.readdir(dir)
|
|
65
|
+
.then(processFiles)
|
|
66
|
+
.then(flattenAndRemoveSymlinks)
|
|
67
|
+
.catch(err => {
|
|
68
|
+
throw new FileSystemError_1.FileSystemError({ cause: err });
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.walk = walk;
|