diff --git a/.hlxignore b/.hlxignore index c505916696..58ce85d166 100644 --- a/.hlxignore +++ b/.hlxignore @@ -5,3 +5,4 @@ LICENSE package.json package-lock.json test/* +_* diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000000..0b01328761 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +node .husky/pre-commit.mjs diff --git a/.husky/pre-commit.mjs b/.husky/pre-commit.mjs new file mode 100644 index 0000000000..cb30e931f7 --- /dev/null +++ b/.husky/pre-commit.mjs @@ -0,0 +1,21 @@ +import { exec } from "node:child_process"; + +const run = (cmd) => new Promise((resolve, reject) => exec( + cmd, + (error, stdout, stderr) => { + if (error) reject(); + if (stderr) reject(stderr); + resolve(stdout); + } +)); + +const changeset = await run('git diff --cached --name-only --diff-filter=ACMR'); +const modifiedFiles = changeset.split('\n').filter(Boolean); + +// check if there are any model files staged +const modifledPartials = modifiedFiles.filter((file) => file.match(/(^|\/)_.*.json/)); +if (modifledPartials.length > 0) { + const output = await run('npm run build:json --silent'); + console.log(output); + await run('git add .'); +} diff --git a/README.md b/README.md index 896a0ea2de..de4defe301 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,19 @@ npm run lint 1. Install the [AEM CLI](https://github.com/adobe/helix-cli): `npm install -g @adobe/aem-cli` 1. Start AEM Proxy: `aem up` (opens your browser at `http://localhost:3000`) 1. Open the `{repo}` directory in your favorite IDE and start coding :) + +## Prerequisites + +- nodejs 18.3.x or newer +- AEM Cloud Service release 2024.8 or newer (>= `17465`) + +## Resources + +### Documentation +- [Getting Started Guide](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/edge-delivery/wysiwyg-authoring/edge-dev-getting-started) +- [Creating Blocks](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/edge-delivery/wysiwyg-authoring/create-block) +- [Content Modelling](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/edge-delivery/wysiwyg-authoring/content-modeling) +- [Working with Tabular Data / Spreadsheets](https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/edge-delivery/wysiwyg-authoring/tabular-data) + +### Presentations and Recordings +- [Getting started with AEM Authoring and Edge Delivery Services](https://experienceleague.adobe.com/en/docs/events/experience-manager-gems-recordings/gems2024/aem-authoring-and-edge-delivery) diff --git a/blocks/cards/_cards.json b/blocks/cards/_cards.json new file mode 100644 index 0000000000..1b2ca0e217 --- /dev/null +++ b/blocks/cards/_cards.json @@ -0,0 +1,63 @@ +{ + "definitions": [ + { + "title": "Cards", + "id": "cards", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/block/v1/block", + "template": { + "name": "Cards", + "filter": "cards" + } + } + } + } + }, + { + "title": "Card", + "id": "card", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/block/v1/block/item", + "template": { + "name": "Card", + "model": "card" + } + } + } + } + } + ], + "models": [ + { + "id": "card", + "fields": [ + { + "component": "reference", + "valueType": "string", + "name": "image", + "label": "Image", + "multi": false + }, + { + "component": "richtext", + "name": "text", + "value": "", + "label": "Text", + "valueType": "string" + } + ] + } + ], + "filters": [ + { + "id": "cards", + "components": [ + "card" + ] + } + ] +} diff --git a/blocks/columns/_columns.json b/blocks/columns/_columns.json new file mode 100644 index 0000000000..6f08e8ad43 --- /dev/null +++ b/blocks/columns/_columns.json @@ -0,0 +1,57 @@ +{ + "definitions": [ + { + "title": "Columns", + "id": "columns", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/columns/v1/columns", + "template": { + "columns": "2", + "rows": "1" + } + } + } + } + } + ], + "models": [ + { + "id": "columns", + "fields": [ + { + "component": "text", + "valueType": "number", + "name": "columns", + "value": "", + "label": "Columns" + }, + { + "component": "text", + "valueType": "number", + "name": "rows", + "value": "", + "label": "Rows" + } + ] + } + ], + "filters": [ + { + "id": "columns", + "components": [ + "column" + ] + }, + { + "id": "column", + "components": [ + "text", + "image", + "button", + "title" + ] + } + ] +} \ No newline at end of file diff --git a/blocks/fragment/_fragment.json b/blocks/fragment/_fragment.json new file mode 100644 index 0000000000..e7163c4f17 --- /dev/null +++ b/blocks/fragment/_fragment.json @@ -0,0 +1,32 @@ +{ + "definitions": [ + { + "title": "Fragment", + "id": "fragment", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/block/v1/block", + "template": { + "name": "Fragment", + "model": "fragment" + } + } + } + } + } + ], + "models": [ + { + "id": "fragment", + "fields": [ + { + "component": "aem-content", + "name": "reference", + "label": "Reference" + } + ] + } + ], + "filters": [] +} \ No newline at end of file diff --git a/blocks/hero/_hero.json b/blocks/hero/_hero.json new file mode 100644 index 0000000000..0e64ea4376 --- /dev/null +++ b/blocks/hero/_hero.json @@ -0,0 +1,48 @@ +{ + "definitions": [ + { + "title": "Hero", + "id": "hero", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/block/v1/block", + "template": { + "name": "Hero", + "model": "hero" + } + } + } + } + } + ], + "models": [ + { + "id": "hero", + "fields": [ + { + "component": "reference", + "valueType": "string", + "name": "image", + "label": "Image", + "multi": false + }, + { + "component": "text", + "valueType": "string", + "name": "imageAlt", + "label": "Alt", + "value": "" + }, + { + "component": "richtext", + "name": "text", + "value": "", + "label": "Text", + "valueType": "string" + } + ] + } + ], + "filters": [] +} diff --git a/component-definition.json b/component-definition.json index d1706da214..c2e9c800af 100644 --- a/component-definition.json +++ b/component-definition.json @@ -23,7 +23,9 @@ "xwalk": { "page": { "resourceType": "core/franklin/components/title/v1/title", - "template": {} + "template": { + "model": "title" + } } } } @@ -47,7 +49,9 @@ "xwalk": { "page": { "resourceType": "core/franklin/components/button/v1/button", - "template": {} + "template": { + "model": "button" + } } } } @@ -65,7 +69,9 @@ "xwalk": { "page": { "resourceType": "core/franklin/components/section/v1/section", - "template": {} + "template": { + "model": "section" + } } } } @@ -77,75 +83,75 @@ "id": "blocks", "components": [ { - "title": "Columns", - "id": "columns", + "title": "Cards", + "id": "cards", "plugins": { "xwalk": { "page": { - "resourceType": "core/franklin/components/columns/v1/columns", + "resourceType": "core/franklin/components/block/v1/block", "template": { - "columns": "2", - "rows": "1" + "name": "Cards", + "filter": "cards" } } } } }, { - "title": "Hero", - "id": "hero", + "title": "Card", + "id": "card", "plugins": { "xwalk": { "page": { - "resourceType": "core/franklin/components/block/v1/block", + "resourceType": "core/franklin/components/block/v1/block/item", "template": { - "name": "Hero", - "model": "hero" + "name": "Card", + "model": "card" } } } } }, { - "title": "Cards", - "id": "cards", + "title": "Columns", + "id": "columns", "plugins": { "xwalk": { "page": { - "resourceType": "core/franklin/components/block/v1/block", + "resourceType": "core/franklin/components/columns/v1/columns", "template": { - "name": "Cards", - "filter": "cards" + "columns": "2", + "rows": "1" } } } } }, { - "title": "Card", - "id": "card", + "title": "Fragment", + "id": "fragment", "plugins": { "xwalk": { "page": { - "resourceType": "core/franklin/components/block/v1/block/item", + "resourceType": "core/franklin/components/block/v1/block", "template": { - "name": "Card", - "model": "card" + "name": "Fragment", + "model": "fragment" } } } } }, { - "title": "Fragment", - "id": "fragment", + "title": "Hero", + "id": "hero", "plugins": { "xwalk": { "page": { "resourceType": "core/franklin/components/block/v1/block", "template": { - "name": "Fragment", - "model": "fragment" + "name": "Hero", + "model": "hero" } } } @@ -154,4 +160,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/component-filters.json b/component-filters.json index a4158e1b35..1edc202cbe 100644 --- a/component-filters.json +++ b/component-filters.json @@ -5,19 +5,6 @@ "section" ] }, - { - "id": "columns", - "components": [] - }, - { - "id": "column", - "components": [ - "text", - "image", - "button", - "title" - ] - }, { "id": "section", "components": [ @@ -36,5 +23,20 @@ "components": [ "card" ] + }, + { + "id": "columns", + "components": [ + "column" + ] + }, + { + "id": "column", + "components": [ + "text", + "image", + "button", + "title" + ] } -] +] \ No newline at end of file diff --git a/component-models.json b/component-models.json index 082d6d4eb4..146dbaf809 100644 --- a/component-models.json +++ b/component-models.json @@ -1,20 +1,32 @@ [ + { + "id": "image", + "fields": [ + { + "component": "reference", + "name": "image", + "label": "Image", + "multi": false + }, + { + "component": "text", + "name": "imageAlt", + "label": "Alt Text" + } + ] + }, { "id": "title", "fields": [ { "component": "text", - "valueType": "string", - "name": "jcr:title", - "value": "", - "label": "Text" + "name": "title", + "label": "Title" }, { "component": "select", - "name": "type", - "value": "h1", - "label": "Type", - "valueType": "string", + "name": "titleType", + "label": "Title Type", "options": [ { "name": "h1", @@ -44,55 +56,28 @@ } ] }, - { - "id": "image", - "fields": [ - { - "component": "reference", - "valueType": "string", - "name": "fileReference", - "label": "Image", - "multi": false - }, - { - "component": "text", - "valueType": "string", - "name": "alt", - "value": "Default alt", - "label": "Alt Text" - } - ] - }, { "id": "button", "fields": [ { - "component": "text", - "valueType": "string", - "name": "href", - "value": "", + "component": "aem-content", + "name": "link", "label": "Link" }, { "component": "text", - "valueType": "string", - "name": "text", - "value": "", + "name": "linkText", "label": "Text" }, { "component": "text", - "valueType": "string", - "name": "title", - "value": "", + "name": "linkTitle", "label": "Title" }, { "component": "select", - "name": "type", - "value": "", + "name": "linkType", "label": "Type", - "valueType": "string", "options": [ { "name": "default", @@ -111,21 +96,18 @@ ] }, { - "id": "columns", + "id": "section", "fields": [ { - "component": "text", - "valueType": "number", - "name": "columns", - "value": "", - "label": "Columns" - }, - { - "component": "text", - "valueType": "number", - "name": "rows", - "value": "", - "label": "Rows" + "component": "multiselect", + "name": "style", + "label": "Style", + "options": [ + { + "name": "Highlight", + "value": "highlight" + } + ] } ] }, @@ -149,14 +131,31 @@ ] }, { - "id": "section", + "id": "columns", "fields": [ { "component": "text", - "name": "style", + "valueType": "number", + "name": "columns", "value": "", - "label": "Style", - "valueType": "string" + "label": "Columns" + }, + { + "component": "text", + "valueType": "number", + "name": "rows", + "value": "", + "label": "Rows" + } + ] + }, + { + "id": "fragment", + "fields": [ + { + "component": "aem-content", + "name": "reference", + "label": "Reference" } ] }, @@ -185,15 +184,5 @@ "valueType": "string" } ] - }, - { - "id": "fragment", - "fields": [ - { - "component": "aem-content", - "name": "reference", - "label": "Reference" - } - ] } -] +] \ No newline at end of file diff --git a/models/_button.json b/models/_button.json new file mode 100644 index 0000000000..a11c5e2036 --- /dev/null +++ b/models/_button.json @@ -0,0 +1,59 @@ +{ + "definitions": [ + { + "title": "Button", + "id": "button", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/button/v1/button", + "template": { + "model": "button" + } + } + } + } + } + ], + "models": [ + { + "id": "button", + "fields": [ + { + "component": "aem-content", + "name": "link", + "label": "Link" + }, + { + "component": "text", + "name": "linkText", + "label": "Text" + }, + { + "component": "text", + "name": "linkTitle", + "label": "Title" + }, + { + "component": "select", + "name": "linkType", + "label": "Type", + "options": [ + { + "name": "default", + "value": "" + }, + { + "name": "primary", + "value": "primary" + }, + { + "name": "secondary", + "value": "secondary" + } + ] + } + ] + } + ] +} diff --git a/models/_component-definition.json b/models/_component-definition.json new file mode 100644 index 0000000000..800e247df3 --- /dev/null +++ b/models/_component-definition.json @@ -0,0 +1,40 @@ +{ + "groups": [ + { + "title": "Default Content", + "id": "default", + "components": [ + { + "...": "./_text.json#/definitions" + }, + { + "...": "./_title.json#/definitions" + }, + { + "...": "./_image.json#/definitions" + }, + { + "...": "./_button.json#/definitions" + } + ] + }, + { + "title": "Sections", + "id": "sections", + "components": [ + { + "...": "./_section.json#/definitions" + } + ] + }, + { + "title": "Blocks", + "id": "blocks", + "components": [ + { + "...": "../blocks/*/_*.json#/definitions" + } + ] + } + ] +} diff --git a/models/_component-filters.json b/models/_component-filters.json new file mode 100644 index 0000000000..c22120420d --- /dev/null +++ b/models/_component-filters.json @@ -0,0 +1,14 @@ +[ + { + "id": "main", + "components": [ + "section" + ] + }, + { + "...": "./_section.json#/filters" + }, + { + "...": "../blocks/*/_*.json#/filters" + } +] diff --git a/models/_component-models.json b/models/_component-models.json new file mode 100644 index 0000000000..ab958de263 --- /dev/null +++ b/models/_component-models.json @@ -0,0 +1,20 @@ +[ + { + "...": "./_image.json#/models" + }, + { + "...": "./_title.json#/models" + }, + { + "...": "./_text.json#/models" + }, + { + "...": "./_button.json#/models" + }, + { + "...": "./_section.json#/models" + }, + { + "...": "../blocks/*/_*.json#/models" + } +] diff --git a/models/_image.json b/models/_image.json new file mode 100644 index 0000000000..add08e0786 --- /dev/null +++ b/models/_image.json @@ -0,0 +1,34 @@ +{ + "definitions": [ + { + "title": "Image", + "id": "image", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/image/v1/image", + "template": {} + } + } + } + } + ], + "models": [ + { + "id": "image", + "fields": [ + { + "component": "reference", + "name": "image", + "label": "Image", + "multi": false + }, + { + "component": "text", + "name": "imageAlt", + "label": "Alt Text" + } + ] + } + ] +} diff --git a/models/_section.json b/models/_section.json new file mode 100644 index 0000000000..e00b3f3b4a --- /dev/null +++ b/models/_section.json @@ -0,0 +1,51 @@ +{ + "definitions": [ + { + "title": "Section", + "id": "section", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/section/v1/section", + "template": { + "model": "section" + } + } + } + } + } + ], + "models": [ + { + "id": "section", + "fields": [ + { + "component": "multiselect", + "name": "style", + "label": "Style", + "options": [ + { + "name": "Highlight", + "value": "highlight" + } + ] + } + ] + } + ], + "filters": [ + { + "id": "section", + "components": [ + "text", + "image", + "button", + "title", + "hero", + "cards", + "columns", + "fragment" + ] + } + ] +} diff --git a/models/_text.json b/models/_text.json new file mode 100644 index 0000000000..133c8a7046 --- /dev/null +++ b/models/_text.json @@ -0,0 +1,17 @@ +{ + "definitions": [ + { + "title": "Text", + "id": "text", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/text/v1/text", + "template": {} + } + } + } + } + ], + "models": [] +} diff --git a/models/_title.json b/models/_title.json new file mode 100644 index 0000000000..922a799f00 --- /dev/null +++ b/models/_title.json @@ -0,0 +1,61 @@ +{ + "definitions": [ + { + "title": "Title", + "id": "title", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/title/v1/title", + "template": { + "model": "title" + } + } + } + } + } + ], + "models": [ + { + "id": "title", + "fields": [ + { + "component": "text", + "name": "title", + "label": "Title" + }, + { + "component": "select", + "name": "titleType", + "label": "Title Type", + "options": [ + { + "name": "h1", + "value": "h1" + }, + { + "name": "h2", + "value": "h2" + }, + { + "name": "h3", + "value": "h3" + }, + { + "name": "h4", + "value": "h4" + }, + { + "name": "h5", + "value": "h5" + }, + { + "name": "h6", + "value": "h6" + } + ] + } + ] + } + ] +} diff --git a/package-lock.json b/package-lock.json index 3ab5318389..722d3fd8d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,9 @@ "eslint-plugin-import": "2.29.1", "eslint-plugin-json": "3.1.0", "eslint-plugin-xwalk": "github:adobe-rnd/eslint-plugin-xwalk#v0.1.0", + "husky": "9.1.1", + "merge-json-cli": "^1.0.3", + "npm-run-all": "4.1.5", "stylelint": "16.6.1", "stylelint-config-standard": "36.0.0" } @@ -2258,6 +2261,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2345,6 +2354,12 @@ "node": ">= 0.4" } }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, "node_modules/html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", @@ -2357,6 +2372,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/husky": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.1.tgz", + "integrity": "sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2753,6 +2783,12 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2833,6 +2869,34 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2892,6 +2956,15 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", @@ -2904,6 +2977,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge-json-cli": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-json-cli/-/merge-json-cli-1.0.3.tgz", + "integrity": "sha512-FYxuhEFQRAaLhysnXdLICWzpnqzOTxm0bJwc52ps/RuiUMg/5it4Kql+UtUIDb1B92En1xfq4F9iGWwu1Dd2dg==", + "dev": true, + "dependencies": { + "fast-glob": "^3.3.2" + }, + "bin": { + "merge-json-cli": "src/cli.js" + }, + "engines": { + "node": ">=18.3.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2977,6 +3065,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -2984,6 +3078,27 @@ "dev": true, "peer": true }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2993,6 +3108,98 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -3238,6 +3445,27 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -3364,6 +3592,32 @@ } ] }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -3563,6 +3817,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -3661,6 +3924,38 @@ "node": ">=0.10.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -3675,6 +3970,24 @@ "node": ">=8" } }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -4226,6 +4539,16 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vscode-json-languageservice": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", diff --git a/package.json b/package.json index e9d984e649..42a2fce5e2 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,14 @@ "version": "1.3.0", "description": "Starter project for Adobe Helix", "scripts": { - "lint:js": "eslint . --ext .json,.js", + "lint:js": "eslint . --ext .json,.js,.mjs", "lint:css": "stylelint blocks/**/*.css styles/*.css", - "lint": "npm run lint:js && npm run lint:css" + "lint": "npm run lint:js && npm run lint:css", + "build:json": "npm-run-all -p build:json:models build:json:definitions build:json:filters", + "build:json:models": "merge-json-cli -i 'models/_component-models.json' -o 'component-models.json'", + "build:json:definitions": "merge-json-cli -i 'models/_component-definition.json' -o 'component-definition.json'", + "build:json:filters": "merge-json-cli -i 'models/_component-filters.json' -o 'component-filters.json'", + "prepare": "husky" }, "repository": { "type": "git", @@ -25,6 +30,9 @@ "eslint-plugin-import": "2.29.1", "eslint-plugin-json": "3.1.0", "eslint-plugin-xwalk": "github:adobe-rnd/eslint-plugin-xwalk#v0.1.0", + "husky": "9.1.1", + "merge-json-cli": "1.0.3", + "npm-run-all": "4.1.5", "stylelint": "16.6.1", "stylelint-config-standard": "36.0.0" }