@hubspot/project-parsing-lib 0.0.4 → 0.0.5
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/package.json +1 -1
- package/src/index.js +3 -2
- package/src/lang/copy.d.ts +24 -0
- package/src/lang/copy.js +27 -0
- package/src/lib/constants.js +17 -7
- package/src/lib/errors.js +2 -1
- package/src/lib/files.js +4 -2
- package/src/lib/schemas.js +4 -4
- package/src/lib/transform.js +3 -1
- package/src/lib/types.d.ts +1 -0
- package/src/lib/validation.js +8 -4
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -6,16 +6,17 @@ const files_1 = require("./lib/files");
|
|
|
6
6
|
const validation_1 = require("./lib/validation");
|
|
7
7
|
const transform_1 = require("./lib/transform");
|
|
8
8
|
const errors_1 = require("./lib/errors");
|
|
9
|
+
const copy_1 = require("./lang/copy");
|
|
9
10
|
async function translate(translationContext) {
|
|
10
11
|
const metafileContents = await (0, files_1.loadHsMetaFiles)(translationContext);
|
|
11
12
|
if (metafileContents.length === 0) {
|
|
12
|
-
throw new Error(
|
|
13
|
+
throw new Error(copy_1.errorMessages.project.noHsMetaFiles);
|
|
13
14
|
}
|
|
14
15
|
const transformation = (0, transform_1.transform)(metafileContents);
|
|
15
16
|
const intermediateRepresentation = (0, transform_1.getIntermediateRepresentation)(transformation);
|
|
16
17
|
const { valid, errors } = await (0, validation_1.validateIntermediateRepresentation)(intermediateRepresentation, transformation, translationContext);
|
|
17
18
|
if (!valid) {
|
|
18
|
-
throw new errors_1.TranslationError(
|
|
19
|
+
throw new errors_1.TranslationError(copy_1.errorMessages.project.failedToTranslateProject, errors);
|
|
19
20
|
}
|
|
20
21
|
return intermediateRepresentation;
|
|
21
22
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const errorMessages: {
|
|
2
|
+
api: {
|
|
3
|
+
failedToFetchSchemas: string;
|
|
4
|
+
};
|
|
5
|
+
project: {
|
|
6
|
+
noHsMetaFiles: string;
|
|
7
|
+
failedToTranslateProject: string;
|
|
8
|
+
duplicateUid: (uid: string, files: string[]) => string;
|
|
9
|
+
};
|
|
10
|
+
file: {
|
|
11
|
+
errorWithFileHeader: (file: string) => string;
|
|
12
|
+
missingRequiredField: (field: string) => string;
|
|
13
|
+
missingUid: string;
|
|
14
|
+
missingType: string;
|
|
15
|
+
unsupportedType: (type: string) => string;
|
|
16
|
+
errorWithField: (field: string, error: string | undefined) => string;
|
|
17
|
+
invalidJson: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export declare const logMessages: {
|
|
21
|
+
files: {
|
|
22
|
+
skippingPath: (path: string) => string;
|
|
23
|
+
};
|
|
24
|
+
};
|
package/src/lang/copy.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logMessages = exports.errorMessages = void 0;
|
|
4
|
+
exports.errorMessages = {
|
|
5
|
+
api: {
|
|
6
|
+
failedToFetchSchemas: 'Failed to fetch schemas',
|
|
7
|
+
},
|
|
8
|
+
project: {
|
|
9
|
+
noHsMetaFiles: 'No *-hsmeta.json files found, make sure you are inside a project',
|
|
10
|
+
failedToTranslateProject: 'Failed to translate project',
|
|
11
|
+
duplicateUid: (uid, files) => `Duplicate uid '${uid}' found in ${files.join(', ')}`,
|
|
12
|
+
},
|
|
13
|
+
file: {
|
|
14
|
+
errorWithFileHeader: (file) => `Encountered the following errors for ${file}:`,
|
|
15
|
+
missingRequiredField: (field) => `Missing required field: '${field}'`,
|
|
16
|
+
missingUid: `Missing required field: 'uid'`,
|
|
17
|
+
missingType: `Missing required field: 'type'`,
|
|
18
|
+
unsupportedType: (type) => `Unsupported type: ${type.toLowerCase()}`,
|
|
19
|
+
errorWithField: (field, error) => `Error with ${field}: ${error || 'Unknown error'}`,
|
|
20
|
+
invalidJson: 'Invalid JSON',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
exports.logMessages = {
|
|
24
|
+
files: {
|
|
25
|
+
skippingPath: (path) => `Skipping ${path} as it is not in a valid directory`,
|
|
26
|
+
},
|
|
27
|
+
};
|
package/src/lib/constants.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.allowedSubComponentDirectories = exports.allowedComponentDirectories = exports.ProjectStructure = exports.allowedThemeSubComponentsDirs = exports.allowedAppSubComponentsDirs = exports.metafileExtension = exports.externalTypeToInternalType = exports.Components = exports.WorkflowActionsKey = exports.WebhooksKey = exports.VideoConferencingKey = exports.TimelineEventsKey = exports.MediaBridgeKey = exports.MarketingEventsKey = exports.FunctionsKey = exports.CardsKey = exports.CallingKey = exports.ThemeKey = exports.AppKey = void 0;
|
|
27
37
|
// Top Level Component types
|
package/src/lib/errors.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TranslationError = void 0;
|
|
4
4
|
exports.isTranslationError = isTranslationError;
|
|
5
5
|
exports.compileError = compileError;
|
|
6
|
+
const copy_1 = require("../lang/copy");
|
|
6
7
|
class TranslationError extends Error {
|
|
7
8
|
errors;
|
|
8
9
|
constructor(message, errors) {
|
|
@@ -22,7 +23,7 @@ function compileError(validatedTransformation) {
|
|
|
22
23
|
const { fileParseResult } = validatedTransformation;
|
|
23
24
|
const { errors, file: filePath } = fileParseResult;
|
|
24
25
|
return {
|
|
25
|
-
message:
|
|
26
|
+
message: copy_1.errorMessages.file.errorWithFileHeader(filePath),
|
|
26
27
|
errors,
|
|
27
28
|
};
|
|
28
29
|
}
|
package/src/lib/files.js
CHANGED
|
@@ -8,6 +8,8 @@ const fs_1 = require("@hubspot/local-dev-lib/fs");
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const constants_1 = require("./constants");
|
|
10
10
|
const fs_2 = __importDefault(require("fs"));
|
|
11
|
+
const copy_1 = require("../lang/copy");
|
|
12
|
+
const logger_1 = require("@hubspot/local-dev-lib/logger");
|
|
11
13
|
async function loadHsMetaFiles(translationContext) {
|
|
12
14
|
const metaFiles = await locateHsMetaFiles(translationContext);
|
|
13
15
|
return parseHsMetaFiles(metaFiles, translationContext);
|
|
@@ -28,7 +30,7 @@ async function locateHsMetaFiles(translationContext) {
|
|
|
28
30
|
metaFiles.push({ file, parentDirectory });
|
|
29
31
|
}
|
|
30
32
|
else {
|
|
31
|
-
|
|
33
|
+
logger_1.logger.warn(copy_1.logMessages.files.skippingPath(pathRelativeToProjectSrcDir));
|
|
32
34
|
}
|
|
33
35
|
return metaFiles;
|
|
34
36
|
}, []);
|
|
@@ -69,7 +71,7 @@ function parseFile(fileLoadResult) {
|
|
|
69
71
|
parsedFileContents = JSON.parse(fileLoadResult.content);
|
|
70
72
|
}
|
|
71
73
|
catch (_e) {
|
|
72
|
-
fileLoadResult.errors?.push(
|
|
74
|
+
fileLoadResult.errors?.push(copy_1.errorMessages.file.invalidJson);
|
|
73
75
|
}
|
|
74
76
|
return { ...fileLoadResult, content: parsedFileContents };
|
|
75
77
|
}
|
package/src/lib/schemas.js
CHANGED
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getIntermediateRepresentationSchema = getIntermediateRepresentationSchema;
|
|
4
4
|
const http_1 = require("@hubspot/local-dev-lib/http");
|
|
5
5
|
const index_1 = require("@hubspot/local-dev-lib/errors/index");
|
|
6
|
+
const copy_1 = require("../lang/copy");
|
|
6
7
|
async function getIntermediateRepresentationSchema(translationContext) {
|
|
7
8
|
try {
|
|
8
|
-
const { accountId } = translationContext;
|
|
9
|
+
const { accountId, platformVersion } = translationContext;
|
|
9
10
|
const { data } = await http_1.http.get(accountId, {
|
|
10
|
-
|
|
11
|
-
url: `project-components-external/project-schemas/v3?platformVersion=testing`,
|
|
11
|
+
url: `project-components-external/project-schemas/v3/${platformVersion}`,
|
|
12
12
|
});
|
|
13
13
|
return data;
|
|
14
14
|
}
|
|
@@ -16,6 +16,6 @@ async function getIntermediateRepresentationSchema(translationContext) {
|
|
|
16
16
|
if ((0, index_1.isHubSpotHttpError)(e)) {
|
|
17
17
|
throw e;
|
|
18
18
|
}
|
|
19
|
-
throw new Error(
|
|
19
|
+
throw new Error(copy_1.errorMessages.api.failedToFetchSchemas, { cause: e });
|
|
20
20
|
}
|
|
21
21
|
}
|
package/src/lib/transform.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.transform = transform;
|
|
4
4
|
exports.getIntermediateRepresentation = getIntermediateRepresentation;
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
+
const copy_1 = require("../lang/copy");
|
|
6
7
|
function calculateComponentDeps(fileValidationResult, parentComponents) {
|
|
7
8
|
return {
|
|
8
9
|
...fileValidationResult.content?.dependencies,
|
|
@@ -38,6 +39,7 @@ function transform(fileParseResults) {
|
|
|
38
39
|
config,
|
|
39
40
|
componentType: mapToInternalType(type),
|
|
40
41
|
componentDeps: calculateComponentDeps(currentFile, parentComponents),
|
|
42
|
+
metaFilePath: currentFile.file,
|
|
41
43
|
files: {},
|
|
42
44
|
},
|
|
43
45
|
fileParseResult: currentFile,
|
|
@@ -51,7 +53,7 @@ function getIntermediateRepresentation(transformations) {
|
|
|
51
53
|
const duplicates = transformations
|
|
52
54
|
.filter(t => t.intermediateRepresentation?.uid === uid)
|
|
53
55
|
.map(t => t.fileParseResult.file);
|
|
54
|
-
throw new Error(
|
|
56
|
+
throw new Error(copy_1.errorMessages.project.duplicateUid(uid, duplicates));
|
|
55
57
|
}
|
|
56
58
|
return {
|
|
57
59
|
...acc,
|
package/src/lib/types.d.ts
CHANGED
package/src/lib/validation.js
CHANGED
|
@@ -7,15 +7,19 @@ exports.validateIntermediateRepresentation = validateIntermediateRepresentation;
|
|
|
7
7
|
const schemas_1 = require("./schemas");
|
|
8
8
|
const ajv_draft_04_1 = __importDefault(require("ajv-draft-04"));
|
|
9
9
|
const errors_1 = require("./errors");
|
|
10
|
+
const copy_1 = require("../lang/copy");
|
|
10
11
|
async function validateIntermediateRepresentation(intermediateRepresentation, transformation, translationContext) {
|
|
11
12
|
const schema = await (0, schemas_1.getIntermediateRepresentationSchema)(translationContext);
|
|
12
13
|
const results = Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).map((irNode, index) => {
|
|
13
14
|
const ajv = new ajv_draft_04_1.default({ allErrors: true });
|
|
14
15
|
if (!irNode.uid) {
|
|
15
|
-
transformation[index].fileParseResult.errors.push(
|
|
16
|
+
transformation[index].fileParseResult.errors.push(copy_1.errorMessages.file.missingUid);
|
|
16
17
|
}
|
|
17
18
|
if (!schema[irNode.componentType]) {
|
|
18
|
-
|
|
19
|
+
if (!irNode.componentType) {
|
|
20
|
+
transformation[index].fileParseResult.errors.push(copy_1.errorMessages.file.missingType);
|
|
21
|
+
}
|
|
22
|
+
transformation[index].fileParseResult.errors.push(copy_1.errorMessages.file.unsupportedType(irNode.componentType));
|
|
19
23
|
return {
|
|
20
24
|
valid: false,
|
|
21
25
|
errors: (0, errors_1.compileError)(transformation[index]),
|
|
@@ -73,7 +77,7 @@ const missingRequiredFieldRegex = /must have required property '(.+)'/;
|
|
|
73
77
|
function generateErrorMessage(path, error) {
|
|
74
78
|
let errorMessage = '';
|
|
75
79
|
const dotNotationPath = path.length === 0 || path[0] === '' ? 'Root Level' : path.join('.');
|
|
76
|
-
errorMessage =
|
|
80
|
+
errorMessage = copy_1.errorMessages.file.errorWithField(dotNotationPath, error.message);
|
|
77
81
|
const params = Object.entries(error.params);
|
|
78
82
|
if (params.length > 0) {
|
|
79
83
|
const additionalContext = params
|
|
@@ -83,7 +87,7 @@ function generateErrorMessage(path, error) {
|
|
|
83
87
|
missingRequiredFieldRegex.test(error.message) &&
|
|
84
88
|
error.params) {
|
|
85
89
|
// TODO: This error message doesn't work well for nested objects, it makes it seem like the field is missing from the root object
|
|
86
|
-
return
|
|
90
|
+
return copy_1.errorMessages.file.missingRequiredField(error.params.missingProperty);
|
|
87
91
|
}
|
|
88
92
|
errorMessage += `${additionalContext.length > 0
|
|
89
93
|
? `\n\t\t- ${additionalContext.join('\n\t\t- ')}`
|