diff --git a/packages/cli-lib/lib/constants.js b/packages/cli-lib/lib/constants.js index fdda071cd..254287956 100644 --- a/packages/cli-lib/lib/constants.js +++ b/packages/cli-lib/lib/constants.js @@ -118,6 +118,49 @@ const PROJECT_TEMPLATE_TYPES = { }, }; +const TEMPLATE_TYPES = { + unmapped: 0, + email_base_template: 1, + email: 2, + landing_page_base_template: 3, + landing_page: 4, + blog_base: 5, + blog: 6, + blog_listing: 42, + site_page: 8, + blog_listing_context: 9, + blog_post_context: 10, + error_page: 11, + subscription_preferences: 12, + unsubscribe_confirmation: 13, + unsubscribe_simple: 14, + optin_email: 15, + optin_followup_email: 16, + optin_confirmation_page: 17, + global_group: 18, + password_prompt_page: 19, + resubscribe_email: 20, + unsubscribe_confirmation_email: 21, + resubscribe_confirmation_email: 22, + custom_module: 23, + css: 24, + js: 25, + search_results: 27, + membership_login: 29, + membership_register: 30, + membership_reset: 31, + membership_reset_request: 32, + drag_drop_email: 34, + knowledge_article: 35, + membership_email: 36, + section: 37, + global_content_partial: 38, + simple_landing_page_template: 39, + proposal: 40, + blog_post: 41, + quote: 43, +}; + const PROJECT_BUILD_STATUS = { BUILDING: 'BUILDING', ENQUEUED: 'ENQUEUED', @@ -162,4 +205,5 @@ module.exports = { PROJECT_BUILD_STATUS_TEXT, PROJECT_TEMPLATE_TYPES, SCOPE_GROUPS, + TEMPLATE_TYPES, }; diff --git a/packages/cli-lib/modules.js b/packages/cli-lib/modules.js index a9ca97be7..a88a21ffd 100644 --- a/packages/cli-lib/modules.js +++ b/packages/cli-lib/modules.js @@ -4,6 +4,11 @@ const { getCwd, getExt, splitHubSpotPath, splitLocalPath } = require('./path'); const { walk } = require('./lib/walk'); const { MODULE_EXTENSION } = require('./lib/constants'); +// Matches files named module.html +const MODULE_HTML_EXTENSION_REGEX = new RegExp(/\.module\/module\.html$/); +// Matches files named module.css +const MODULE_CSS_EXTENSION_REGEX = new RegExp(/\.module\/module\.css$/); + const isBool = x => !!x === x; /** @@ -150,9 +155,25 @@ async function validateSrcAndDestPaths(src, dest) { return results; } +/** + * Checks if the given path points to an .html file within a .module folder + * @param {string} filePath + * @returns {boolean} + */ +const isModuleHTMLFile = filePath => MODULE_HTML_EXTENSION_REGEX.test(filePath); + +/** + * Checks if the given path points to an .css file within a .module folder + * @param {string} filePath + * @returns {boolean} + */ +const isModuleCSSFile = filePath => MODULE_CSS_EXTENSION_REGEX.test(filePath); + module.exports = { isModuleFolder, isModuleFolderChild, validateSrcAndDestPaths, ValidationIds, + isModuleHTMLFile, + isModuleCSSFile, }; diff --git a/packages/cli-lib/templates.js b/packages/cli-lib/templates.js index 1dbd7beb1..27a92f0f7 100644 --- a/packages/cli-lib/templates.js +++ b/packages/cli-lib/templates.js @@ -1,8 +1,6 @@ -const fs = require('fs'); -const { logger } = require('./logger'); - // Matches the .html file extension, excluding module.html const TEMPLATE_EXTENSION_REGEX = new RegExp(/(?/; // Matches an annotation value, ending at space, newline, or end of string @@ -17,24 +15,18 @@ const ANNOTATION_KEYS = { description: 'description', }; -const getFileAnnotations = filePath => { - try { - const data = fs.readFileSync(filePath, 'utf8'); - const match = data.match(ANNOTATIONS_REGEX); - const annotation = match && match[1] ? match[1] : ''; - return annotation; - } catch (err) { - logger.debug(err); - return ''; - } -}; - const getAnnotationValue = (annotations, key) => { const valueRegex = new RegExp(`${key}${ANNOTATION_VALUE_REGEX}`); const match = annotations.match(valueRegex); return match ? match[1].trim() : null; }; +const buildAnnotationValueGetter = source => { + const match = source.match(ANNOTATIONS_REGEX); + const annotation = match && match[1] ? match[1] : ''; + return annotationKey => getAnnotationValue(annotation, annotationKey); +}; + /* * Returns true if: * .html extension (ignoring module.html) @@ -44,6 +36,6 @@ const isCodedFile = filePath => TEMPLATE_EXTENSION_REGEX.test(filePath); module.exports = { ANNOTATION_KEYS, getAnnotationValue, - getFileAnnotations, + buildAnnotationValueGetter, isCodedFile, }; diff --git a/packages/cli/lib/validators/__tests__/TemplateValidator.js b/packages/cli/lib/validators/__tests__/TemplateValidator.js index 3da6e9dec..d5ad90b08 100644 --- a/packages/cli/lib/validators/__tests__/TemplateValidator.js +++ b/packages/cli/lib/validators/__tests__/TemplateValidator.js @@ -15,11 +15,13 @@ jest.mock('@hubspot/cli-lib/templates'); const TEMPLATE_LIMIT = 50; const mockGetAnnotationValue = (templateType, rest) => { - templates.getAnnotationValue.mockImplementation((x, key) => { - if (key === 'templateType') { - return templateType; - } - return rest; + templates.buildAnnotationValueGetter.mockImplementation(() => { + return key => { + if (key === 'templateType') { + return templateType; + } + return rest; + }; }); }; diff --git a/packages/cli/lib/validators/marketplaceValidators/theme/TemplateValidator.js b/packages/cli/lib/validators/marketplaceValidators/theme/TemplateValidator.js index 1bd0443ef..8c908e8ae 100644 --- a/packages/cli/lib/validators/marketplaceValidators/theme/TemplateValidator.js +++ b/packages/cli/lib/validators/marketplaceValidators/theme/TemplateValidator.js @@ -1,11 +1,12 @@ +const fs = require('fs'); const { ANNOTATION_KEYS, - getAnnotationValue, - getFileAnnotations, + buildAnnotationValueGetter, isCodedFile, } = require('@hubspot/cli-lib/templates'); const BaseValidator = require('../BaseValidator'); const { VALIDATOR_KEYS } = require('../../constants'); +const { logger } = require('@hubspot/cli-lib/logger'); const TEMPLATE_LIMIT = 50; const TEMPLATE_IGNORE_LIST = ['section']; @@ -100,29 +101,28 @@ class TemplateValidator extends BaseValidator { files.forEach(file => { if (isCodedFile(file)) { - const annotations = getFileAnnotations(file); + let data; + try { + data = fs.readFileSync(file, 'utf8'); + } catch (e) { + logger.error(`Error reading file ${file}`); + } + const getAnnotationValue = buildAnnotationValueGetter(data); + const isAvailableForNewContent = getAnnotationValue( - annotations, ANNOTATION_KEYS.isAvailableForNewContent ); if (isAvailableForNewContent !== 'false') { - const templateType = getAnnotationValue( - annotations, - ANNOTATION_KEYS.templateType - ); + const templateType = getAnnotationValue(ANNOTATION_KEYS.templateType); if (TEMPLATE_IGNORE_LIST.includes(templateType)) { return; } if (templateType) { - const label = getAnnotationValue( - annotations, - ANNOTATION_KEYS.label - ); + const label = getAnnotationValue(ANNOTATION_KEYS.label); const screenshotPath = getAnnotationValue( - annotations, ANNOTATION_KEYS.screenshotPath );