@hubspot/project-parsing-lib 0.0.1 → 0.0.3-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/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@hubspot/project-parsing-lib",
3
- "version": "0.0.1",
3
+ "version": "0.0.3-experimental.0",
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",
7
7
  "devDependencies": {
8
+ "@hubspot/local-dev-lib": "^3.1.0",
8
9
  "@inquirer/prompts": "^7.1.0",
9
10
  "@types/jest": "^29.5.14",
10
11
  "@types/semver": "^7.5.8",
@@ -22,17 +23,21 @@
22
23
  "typescript": "^5.6.2"
23
24
  },
24
25
  "dependencies": {
25
- "@hubspot/local-dev-lib": "^3.1.0",
26
26
  "ajv": "^8.17.1",
27
27
  "ajv-draft-04": "^1.0.0"
28
28
  },
29
+ "peerDependencies": {
30
+ "@hubspot/local-dev-lib": "^3.1.0"
31
+ },
29
32
  "scripts": {
30
33
  "build": "ts-node ./scripts/build.ts",
31
34
  "lint": "eslint --max-warnings=0 . && prettier ./src/** --check",
32
35
  "local-dev": "yarn build && yarn link --cwd=./dist && tsc --watch --rootDir . --outdir dist",
33
36
  "prettier:write": "prettier ./src/** --write",
34
37
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ./node_modules/.bin/jest",
35
- "release": "yarn ts-node ./scripts/release.ts release"
38
+ "release": "yarn ts-node ./scripts/release.ts release",
39
+ "acceptance-test": "yarn --cwd=./acceptance-tests test",
40
+ "update-north-star": "git submodule update --remote --merge"
36
41
  },
37
42
  "engines": {
38
43
  "node": ">=18"
@@ -15,6 +15,7 @@ interface ComponentMetadata {
15
15
  parentComponent?: string;
16
16
  }
17
17
  export declare const Components: Record<string, ComponentMetadata>;
18
+ export declare const externalTypeToInternalType: Record<string, string>;
18
19
  export declare const metafileExtension = "-hsmeta.json";
19
20
  export declare const allowedAppSubComponentsDirs: string[];
20
21
  export declare const allowedThemeSubComponentsDirs: string[];
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.allowedSubComponentDirectories = exports.allowedComponentDirectories = exports.ProjectStructure = exports.allowedThemeSubComponentsDirs = exports.allowedAppSubComponentsDirs = exports.metafileExtension = 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;
26
+ 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
27
  // Top Level Component types
28
28
  const path = __importStar(require("path"));
29
29
  // Component types
@@ -85,6 +85,9 @@ exports.Components = {
85
85
  parentComponent: exports.AppKey,
86
86
  },
87
87
  };
88
+ exports.externalTypeToInternalType = {
89
+ [exports.AppKey]: 'application',
90
+ };
88
91
  exports.metafileExtension = '-hsmeta.json';
89
92
  function getSubComponentDirsForParentType(parentComponent) {
90
93
  return Object.values(exports.Components).reduce((acc, item) => {
package/src/lib/files.js CHANGED
@@ -15,21 +15,17 @@ async function loadHsMetaFiles(translationContext) {
15
15
  async function locateHsMetaFiles(translationContext) {
16
16
  const { projectSourceDir } = translationContext;
17
17
  return (await (0, fs_1.walk)(projectSourceDir, ['node_modules'])).reduce((metaFiles, file) => {
18
- // Ignore the node_modules directory
19
- if (file.includes('node_modules')) {
18
+ if (!file.endsWith(constants_1.metafileExtension)) {
20
19
  return metaFiles;
21
20
  }
22
21
  const pathRelativeToProjectSrcDir = path_1.default.relative(projectSourceDir, file);
23
- if (!pathRelativeToProjectSrcDir.endsWith(constants_1.metafileExtension)) {
24
- return metaFiles;
25
- }
26
22
  const { dir: metaFileDir } = path_1.default.parse(pathRelativeToProjectSrcDir);
27
- const parent = metaFileDir.split(path_1.default.sep)[0];
23
+ const parentDirectory = metaFileDir.split(path_1.default.sep)[0];
28
24
  if (constants_1.allowedComponentDirectories.includes(metaFileDir)) {
29
25
  metaFiles.push({ file });
30
26
  }
31
27
  else if (constants_1.allowedSubComponentDirectories.includes(metaFileDir)) {
32
- metaFiles.push({ file, parent });
28
+ metaFiles.push({ file, parentDirectory });
33
29
  }
34
30
  else {
35
31
  console.warn(`Skipping ${pathRelativeToProjectSrcDir} as it is not in a valid directory`);
@@ -46,7 +42,7 @@ async function parseHsMetaFiles(metaFileLocations, translationContext) {
46
42
  function loadFile(metaFileLocation, translationContext) {
47
43
  const { projectSourceDir } = translationContext;
48
44
  return new Promise(async (resolve) => {
49
- const { file, parent } = metaFileLocation;
45
+ const { file, parentDirectory } = metaFileLocation;
50
46
  fs_2.default.readFile(file, 'utf-8', (err, content) => {
51
47
  if (err) {
52
48
  return resolve({
@@ -57,7 +53,7 @@ function loadFile(metaFileLocation, translationContext) {
57
53
  resolve({
58
54
  file: path_1.default.relative(projectSourceDir, file),
59
55
  content,
60
- parent,
56
+ parentDirectory,
61
57
  errors: [],
62
58
  });
63
59
  });
@@ -2,9 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getIntermediateRepresentationSchema = getIntermediateRepresentationSchema;
4
4
  const http_1 = require("@hubspot/local-dev-lib/http");
5
+ const index_1 = require("@hubspot/local-dev-lib/errors/index");
5
6
  async function getIntermediateRepresentationSchema(translationContext) {
6
- // This is just a placeholder that resolves the hardcoded object until we
7
- // implement the actual logic to load the schemas from the backend
8
7
  try {
9
8
  const { accountId } = translationContext;
10
9
  const { data } = await http_1.http.get(accountId, {
@@ -14,6 +13,9 @@ async function getIntermediateRepresentationSchema(translationContext) {
14
13
  return data;
15
14
  }
16
15
  catch (e) {
16
+ if ((0, index_1.isHubSpotHttpError)(e)) {
17
+ throw e;
18
+ }
17
19
  throw new Error('Failed to fetch schemas', { cause: e });
18
20
  }
19
21
  }
@@ -7,11 +7,16 @@ function calculateComponentDeps(fileValidationResult, parentComponents) {
7
7
  return {
8
8
  ...fileValidationResult.content?.dependencies,
9
9
  // If the file has a parent, add it as a dependency
10
- ...(fileValidationResult.parent
11
- ? { upstreamBuildArtifact: parentComponents[fileValidationResult.parent] }
10
+ ...(fileValidationResult.parentDirectory
11
+ ? {
12
+ app: parentComponents[fileValidationResult.parentDirectory],
13
+ }
12
14
  : {}),
13
15
  };
14
16
  }
17
+ function mapToInternalType(type) {
18
+ return (constants_1.externalTypeToInternalType[type] || type || '').toUpperCase();
19
+ }
15
20
  function transform(fileParseResults) {
16
21
  const parentTypes = Object.keys(constants_1.ProjectStructure);
17
22
  // Compute the parent components, so we can add them as dependencies to the child components
@@ -26,12 +31,12 @@ function transform(fileParseResults) {
26
31
  currentFile.errors?.push(`File content is missing for ${currentFile.file}`);
27
32
  return { intermediateRepresentation: null, fileParseResult: currentFile };
28
33
  }
29
- const { config, uid } = currentFile.content;
34
+ const { config, uid, type } = currentFile.content;
30
35
  return {
31
36
  intermediateRepresentation: {
32
37
  uid,
33
38
  config,
34
- componentType: currentFile.content?.type.toUpperCase() || '',
39
+ componentType: mapToInternalType(type),
35
40
  componentDeps: calculateComponentDeps(currentFile, parentComponents),
36
41
  files: {},
37
42
  },
@@ -41,10 +46,16 @@ function transform(fileParseResults) {
41
46
  }
42
47
  function getIntermediateRepresentation(transformations) {
43
48
  const nodes = transformations.reduce((acc, current) => {
49
+ const { uid } = current.intermediateRepresentation;
50
+ if (acc[uid]) {
51
+ const duplicates = transformations
52
+ .filter(t => t.intermediateRepresentation?.uid === uid)
53
+ .map(t => t.fileParseResult.file);
54
+ throw new Error(`Duplicate uid '${uid}' found in ${duplicates.join(', ')}`);
55
+ }
44
56
  return {
45
57
  ...acc,
46
- [current.intermediateRepresentation
47
- .uid]: current.intermediateRepresentation,
58
+ [uid]: current.intermediateRepresentation,
48
59
  };
49
60
  }, {});
50
61
  return {
@@ -6,7 +6,7 @@ export interface Components {
6
6
  }
7
7
  export interface FileActionResult {
8
8
  file: string;
9
- parent?: string;
9
+ parentDirectory?: string;
10
10
  errors: string[];
11
11
  }
12
12
  export interface FileLoadResult extends FileActionResult {