@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/project-parsing-lib",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Parsing library for converting projects directory structures to their intermediate representation",
5
5
  "license": "Apache-2.0",
6
6
  "main": "src/index.js",
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('No *-hsmeta.json files found, make sure you are inside a project');
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('Failed to translate project', errors);
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
+ };
@@ -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
+ };
@@ -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 (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
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: `Encountered the following errors for ${filePath}:`,
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
- console.warn(`Skipping ${pathRelativeToProjectSrcDir} as it is not in a valid directory`);
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('Invalid JSON');
74
+ fileLoadResult.errors?.push(copy_1.errorMessages.file.invalidJson);
73
75
  }
74
76
  return { ...fileLoadResult, content: parsedFileContents };
75
77
  }
@@ -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
- // TODO: update this to use the real platform version
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('Failed to fetch schemas', { cause: e });
19
+ throw new Error(copy_1.errorMessages.api.failedToFetchSchemas, { cause: e });
20
20
  }
21
21
  }
@@ -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(`Duplicate uid '${uid}' found in ${duplicates.join(', ')}`);
56
+ throw new Error(copy_1.errorMessages.project.duplicateUid(uid, duplicates));
55
57
  }
56
58
  return {
57
59
  ...acc,
@@ -18,6 +18,7 @@ export interface FileParseResult extends FileActionResult {
18
18
  export interface IntermediateRepresentationNode {
19
19
  componentType: string;
20
20
  componentDeps: Record<string, string>;
21
+ metaFilePath: string;
21
22
  uid: string;
22
23
  config: unknown;
23
24
  files: unknown;
@@ -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(`Missing required field: 'uid'`);
16
+ transformation[index].fileParseResult.errors.push(copy_1.errorMessages.file.missingUid);
16
17
  }
17
18
  if (!schema[irNode.componentType]) {
18
- transformation[index].fileParseResult.errors.push(`Unsupported 'type': '${irNode.componentType.toLowerCase()}'`);
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 = `Error with ${dotNotationPath}: ${error.message}`;
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 `Missing required field: '${error.params.missingProperty}'`;
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- ')}`