@hubspot/project-parsing-lib 0.19.2 → 0.20.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/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # @hubspot/project-parsing-lib
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@hubspot/project-parsing-lib)](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@hubspot/project-parsing-lib)](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
5
+ [![npm license](https://img.shields.io/npm/l/@hubspot/project-parsing-lib)](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
6
+ [![node version](https://img.shields.io/node/v/@hubspot/project-parsing-lib)](https://www.npmjs.com/package/@hubspot/project-parsing-lib)
7
+
3
8
  A parsing library for converting HubSpot project directory structures to their intermediate representation (IR).
4
9
 
5
10
  ## Description
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/project-parsing-lib",
3
- "version": "0.19.2",
3
+ "version": "0.20.0-beta.0",
4
4
  "description": "Parsing library for converting projects directory structures to their intermediate representation",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -107,7 +107,7 @@
107
107
  }
108
108
  },
109
109
  "devDependencies": {
110
- "@hubspot/npm-scripts": "0.3.0",
110
+ "@hubspot/npm-scripts": "0.3.1",
111
111
  "@inquirer/prompts": "^7.1.0",
112
112
  "@types/node": "^24.9.0",
113
113
  "@types/npm-packlist": "7.0.3",
@@ -1,4 +1,4 @@
1
1
  export { getProjectMetadata } from '../lib/project.js';
2
2
  export { projectContainsHsMetaFiles } from '../lib/files.js';
3
3
  export type { ProjectMetadata } from '../lib/project.js';
4
- export { LATEST_SUPPORTED_PLATFORM_VERSION, isSupportedPlatformVersion, isLegacyProject, supportsComponentPermissions, } from '../lib/platformVersion.js';
4
+ export { LATEST_SUPPORTED_PLATFORM_VERSION, isKnownPlatformVersion, isLegacyProject, meetsMinimumPlatformVersion, } from '../lib/platformVersion.js';
@@ -1,3 +1,3 @@
1
1
  export { getProjectMetadata } from '../lib/project.js';
2
2
  export { projectContainsHsMetaFiles } from '../lib/files.js';
3
- export { LATEST_SUPPORTED_PLATFORM_VERSION, isSupportedPlatformVersion, isLegacyProject, supportsComponentPermissions, } from '../lib/platformVersion.js';
3
+ export { LATEST_SUPPORTED_PLATFORM_VERSION, isKnownPlatformVersion, isLegacyProject, meetsMinimumPlatformVersion, } from '../lib/platformVersion.js';
@@ -1,11 +1,13 @@
1
+ export declare const DEPRECATED_PLATFORM_VERSIONS: {
2
+ readonly v2025_1: "2025.1";
3
+ };
1
4
  export declare const PLATFORM_VERSIONS: {
2
- v2023_2: string;
3
- v2025_1: string;
4
- v2025_2: string;
5
- v2026_03_BETA: string;
6
- v2026_03: string;
7
- v2026_09_BETA: string;
8
- UNSTABLE: string;
5
+ readonly v2023_2: "2023.2";
6
+ readonly v2025_2: "2025.2";
7
+ readonly v2026_03_BETA: "2026.03-beta";
8
+ readonly v2026_03: "2026.03";
9
+ readonly v2026_09_BETA: "2026.09-beta";
10
+ readonly UNSTABLE: "unstable";
9
11
  };
10
12
  import { ComponentMeta as ComponentsTopLevel } from './types.js';
11
13
  export declare const APP_KEY = "app";
@@ -1,7 +1,10 @@
1
- // Project Platform Versions
1
+ // Previously supported Project Platform Versions
2
+ export const DEPRECATED_PLATFORM_VERSIONS = {
3
+ v2025_1: '2025.1',
4
+ };
5
+ // Supported Project Platform Versions
2
6
  export const PLATFORM_VERSIONS = {
3
7
  v2023_2: '2023.2',
4
- v2025_1: '2025.1',
5
8
  v2025_2: '2025.2',
6
9
  v2026_03_BETA: '2026.03-beta',
7
10
  v2026_03: '2026.03',
@@ -1,4 +1,8 @@
1
- export declare const LATEST_SUPPORTED_PLATFORM_VERSION: string;
2
- export declare function isSupportedPlatformVersion(platformVersion?: string | null): boolean;
1
+ export declare const LATEST_SUPPORTED_PLATFORM_VERSION: "2026.03";
2
+ export declare function isKnownPlatformVersion(platformVersion?: string | null): boolean;
3
+ /**
4
+ * Returns true if platformVersion meets or exceeds minimumVersion.
5
+ * Versions that do not match the expected format are treated as newer than all known versions.
6
+ */
7
+ export declare function meetsMinimumPlatformVersion(platformVersion: string, minimumVersion: string): boolean;
3
8
  export declare function isLegacyProject(platformVersion?: string | null): boolean;
4
- export declare function supportsComponentPermissions(platformVersion: string): boolean;
@@ -1,30 +1,74 @@
1
- import { PLATFORM_VERSIONS } from './constants.js';
1
+ import { PLATFORM_VERSIONS, DEPRECATED_PLATFORM_VERSIONS, } from './constants.js';
2
2
  // Used for logging suggestions to users whenever we encouter an unknown version
3
3
  export const LATEST_SUPPORTED_PLATFORM_VERSION = PLATFORM_VERSIONS.v2026_03;
4
- // We are unable to reliably interact versions of projects that are not officially supported by this library
5
- export function isSupportedPlatformVersion(platformVersion) {
6
- if (!platformVersion || typeof platformVersion !== 'string') {
4
+ export function isKnownPlatformVersion(platformVersion) {
5
+ if (!platformVersion) {
7
6
  return false;
8
7
  }
9
8
  if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
10
9
  return true;
11
- const supportedPlatformVersions = Object.values(PLATFORM_VERSIONS);
12
- return supportedPlatformVersions.includes(platformVersion);
10
+ const knownVersions = [
11
+ ...Object.values(PLATFORM_VERSIONS),
12
+ ...Object.values(DEPRECATED_PLATFORM_VERSIONS),
13
+ ];
14
+ return knownVersions.includes(platformVersion);
15
+ }
16
+ function parseVersion(version) {
17
+ if (version === PLATFORM_VERSIONS.UNSTABLE)
18
+ return { type: PLATFORM_VERSIONS.UNSTABLE };
19
+ const match = version.match(/^(\d{4})\.(\d{1,2})(-beta)?$/);
20
+ if (!match)
21
+ return { type: 'unknown' };
22
+ return {
23
+ type: 'dated',
24
+ year: parseInt(match[1], 10),
25
+ month: parseInt(match[2], 10),
26
+ beta: !!match[3],
27
+ };
28
+ }
29
+ function compareVersions(a, b) {
30
+ if (b.type === 'unknown') {
31
+ throw new Error(`platformVersion: thresholdVersion could not be parsed as a known version format`);
32
+ }
33
+ // "Unstable" is always the most recent version
34
+ if (a.type === PLATFORM_VERSIONS.UNSTABLE &&
35
+ b.type === PLATFORM_VERSIONS.UNSTABLE) {
36
+ return 0;
37
+ }
38
+ if (a.type === PLATFORM_VERSIONS.UNSTABLE)
39
+ return 1;
40
+ if (b.type === PLATFORM_VERSIONS.UNSTABLE)
41
+ return -1;
42
+ if (a.type !== 'dated') {
43
+ throw new Error(`platformVersion: thresholdVersion could not be parsed as a known version format`);
44
+ }
45
+ if (a.year !== b.year)
46
+ return a.year - b.year;
47
+ if (a.month !== b.month)
48
+ return a.month - b.month;
49
+ // Look for beta tags if all else is equal
50
+ if (a.beta === b.beta)
51
+ return 0;
52
+ return a.beta ? -1 : 1;
53
+ }
54
+ /**
55
+ * Returns true if platformVersion meets or exceeds minimumVersion.
56
+ * Versions that do not match the expected format are treated as newer than all known versions.
57
+ */
58
+ export function meetsMinimumPlatformVersion(platformVersion, minimumVersion) {
59
+ const parsedMinimum = parseVersion(minimumVersion);
60
+ if (parsedMinimum.type === 'unknown') {
61
+ throw new Error(`platformVersion: minimumVersion could not be parsed as a known version format`);
62
+ }
63
+ const parsed = parseVersion(platformVersion);
64
+ if (parsed.type === 'unknown')
65
+ return true;
66
+ return compareVersions(parsed, parsedMinimum) >= 0;
13
67
  }
14
68
  export function isLegacyProject(platformVersion) {
15
- if (!platformVersion)
69
+ if (!platformVersion || typeof platformVersion !== 'string')
16
70
  return false;
17
71
  if (process.env.HUBSPOT_PROJECT_INTERNAL_TEST === 'true')
18
72
  return false;
19
- return [PLATFORM_VERSIONS.v2023_2, PLATFORM_VERSIONS.v2025_1].includes(platformVersion);
20
- }
21
- const PRE_PERMISSIONS_VERSIONS = new Set([
22
- PLATFORM_VERSIONS.v2023_2,
23
- PLATFORM_VERSIONS.v2025_1,
24
- PLATFORM_VERSIONS.v2025_2,
25
- PLATFORM_VERSIONS.v2026_03_BETA,
26
- PLATFORM_VERSIONS.v2026_03,
27
- ]);
28
- export function supportsComponentPermissions(platformVersion) {
29
- return !PRE_PERMISSIONS_VERSIONS.has(platformVersion);
73
+ return !meetsMinimumPlatformVersion(platformVersion, PLATFORM_VERSIONS.v2025_2);
30
74
  }
@@ -3,14 +3,14 @@ import { validateIntermediateRepresentation } from './validation.js';
3
3
  import { getIntermediateRepresentation, getParsingErrors, transform, } from './transform.js';
4
4
  import { errorMessages } from '../lang/copy.js';
5
5
  import { getLocalDevProfileData, getLocalDevProjectNodes, getRemovedNodesAndNodesWithErrors, } from './localDev.js';
6
- import { isSupportedPlatformVersion } from './platformVersion.js';
6
+ import { isKnownPlatformVersion } from './platformVersion.js';
7
7
  const defaultOptions = {
8
8
  skipValidation: false,
9
9
  };
10
10
  export async function translate(translationContext, translationOptions = defaultOptions) {
11
11
  const { skipValidation, profile } = translationOptions;
12
12
  if (!skipValidation &&
13
- !isSupportedPlatformVersion(translationContext.platformVersion)) {
13
+ !isKnownPlatformVersion(translationContext.platformVersion)) {
14
14
  throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
15
15
  }
16
16
  const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
@@ -32,7 +32,7 @@ export async function translate(translationContext, translationOptions = default
32
32
  export async function translateForLocalDev(translationContext, translationOptions) {
33
33
  const { skipValidation, profile, projectNodesAtLastUpload } = translationOptions || {};
34
34
  if (!skipValidation &&
35
- !isSupportedPlatformVersion(translationContext.platformVersion)) {
35
+ !isKnownPlatformVersion(translationContext.platformVersion)) {
36
36
  throw new Error(errorMessages.project.unsupportedPlatformVersion(translationContext.platformVersion));
37
37
  }
38
38
  const { results: metafileContents, skippedFiles } = await loadHsMetaFiles(translationContext);
@@ -2,10 +2,10 @@ import { getIntermediateRepresentationSchema } from './schemas.js';
2
2
  import { Ajv2020, } from 'ajv/dist/2020.js';
3
3
  import { compileError, TranslationError } from './errors.js';
4
4
  import { errorMessages } from '../lang/copy.js';
5
- import { AUTO_GENERATED_COMPONENT_TYPES, Components } from './constants.js';
5
+ import { AUTO_GENERATED_COMPONENT_TYPES, Components, PLATFORM_VERSIONS, } from './constants.js';
6
6
  import path from 'path';
7
7
  import { findTransformationByUid, mapToUserFacingType } from './transform.js';
8
- import { supportsComponentPermissions } from './platformVersion.js';
8
+ import { meetsMinimumPlatformVersion } from './platformVersion.js';
9
9
  import { validateUid } from './uid.js';
10
10
  // ajv-formats does not play nicely with ESM and TS
11
11
  import addFormatsModule from 'ajv-formats';
@@ -49,7 +49,7 @@ function validateIntermediateRepresentationNode(schema, transformation, irNode,
49
49
  shouldSkipValidation = true;
50
50
  }
51
51
  if (irNode.permissions &&
52
- !supportsComponentPermissions(translationContext.platformVersion)) {
52
+ !meetsMinimumPlatformVersion(translationContext.platformVersion, PLATFORM_VERSIONS.v2026_09_BETA)) {
53
53
  transformation.fileParseResult.errors.push(errorMessages.validation.permissionsNotSupported(translationContext.platformVersion));
54
54
  }
55
55
  if (!schema[irNode.componentType]) {