diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 7967907d..ffe44664 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -26,8 +26,6 @@ jobs: run: npm run lint test: - if: | - !startsWith(github.event.head_commit.message, 'chore: release v') name: Test needs: lint runs-on: ubuntu-latest @@ -43,8 +41,6 @@ jobs: run: npm run test:ci build: - if: | - !startsWith(github.event.head_commit.message, 'chore: release v') name: Build needs: [lint, test] runs-on: ubuntu-latest @@ -60,8 +56,7 @@ jobs: run: npm run build release: - if: | - !startsWith(github.event.head_commit.message, 'chore: release v') && github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' name: Release needs: build runs-on: ubuntu-latest diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3910627a..c50d484b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -19,9 +19,9 @@ on: jobs: build: - name: Build if: | github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && (${{ inputs.publish }} || ${{ inputs.deploy }})) + name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -40,9 +40,9 @@ jobs: path: dist publish: - name: Publish if: | github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && ${{ inputs.publish }}) + name: Publish needs: build permissions: write-all runs-on: ubuntu-latest @@ -69,11 +69,35 @@ jobs: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} NODE_AUTH_TOKEN: ${{secrets.WCP_NPM_TOKEN}} - deploy: - name: Deploy + docs: if: | github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && ${{ inputs.deploy }}) + name: Docs needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + cache: "npm" + node-version: 18.14.2 + - uses: actions/download-artifact@v3 + with: + name: latest + path: dist + - name: Install dependencies + run: npm ci + - name: Generate docs with examples + run: npm run docs + - uses: actions/upload-artifact@v3 + if: success() + with: + name: latest + path: dist + + deploy: + name: Deploy + needs: docs permissions: contents: read pages: write diff --git a/package-lock.json b/package-lock.json index 7afd0c81..89fbfdfd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,8 @@ "@types/pretty": "2.0.1", "@typescript-eslint/eslint-plugin": "5.53.0", "@typescript-eslint/parser": "5.53.0", - "@webcomponents-preview/cem-plugin-examples": "0.0.4", - "@webcomponents-preview/cem-plugin-inline-readme": "0.0.4", + "@webcomponents-preview/cem-plugin-examples": "0.0.23", + "@webcomponents-preview/cem-plugin-inline-readme": "0.0.23", "autoprefixer": "10.4.13", "barrelsby": "2.5.1", "cross-env": "7.0.3", @@ -3099,9 +3099,9 @@ "dev": true }, "node_modules/@webcomponents-preview/cem-plugin-examples": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@webcomponents-preview/cem-plugin-examples/-/cem-plugin-examples-0.0.4.tgz", - "integrity": "sha512-JK+W9aW8QDl4TsC0eH10qU3F8KARXFXOknFM0DcPAwrKJkTIQJJoKuY1ddR/xOufxQ2H4paaRwUIl8NfKLZD3Q==", + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/@webcomponents-preview/cem-plugin-examples/-/cem-plugin-examples-0.0.23.tgz", + "integrity": "sha512-EH344l5wJRXRu/cnufrQRNaT95/ZwaViJ5OBtxz4xSwVOOMEbuYxWHhJLeKCxe57cVYHWMTfD395cBgceDZ7uA==", "dev": true, "engines": { "node": "^18" @@ -3111,9 +3111,9 @@ } }, "node_modules/@webcomponents-preview/cem-plugin-inline-readme": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@webcomponents-preview/cem-plugin-inline-readme/-/cem-plugin-inline-readme-0.0.4.tgz", - "integrity": "sha512-RLyFmA1s7WZTDSf49TkhpM6Xqh/5yui2wGqXtDAAKUECMSYvEsvrFqbCrD5MZ3SrEL78DS3/AxbQEhj7nZ1JMA==", + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/@webcomponents-preview/cem-plugin-inline-readme/-/cem-plugin-inline-readme-0.0.23.tgz", + "integrity": "sha512-hSVVGEnUHbLXoyJQ0PlwreXQkw1Ei6BqQmeUHmhZ2vTlw6c5gOKlpNVF0ucqFuzFg5RdqnQ+Kz1T/2jboCHEQg==", "dev": true, "engines": { "node": "^18" diff --git a/package.json b/package.json index e3399f79..d113bcf4 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "generate:barrels": "barrelsby --config .barrelsby.json", "docs:schema": "cross-env NODE_OPTIONS='--loader ts-node/esm' cem analyze --config custom-elements-manifest.config.ts", "docs:readme": "wca analyze src --format markdown --outFiles '{dir}/README.md'", + "docs:examples": "ts-node ./scripts/prepare-examples.ts --target dist/examples", "docs": "run-p --print-name docs:*", "test": "jest", "test:ci": "jest --ci --passWithNoTests --reporters=default --reporters=jest-junit", @@ -30,7 +31,7 @@ "prebuild": "npm run clean", "build:components": "ts-node esbuild.config.ts", "build:types": "tsc --project tsconfig.types.json", - "build": "run-p --print-name generate:* build:* docs", + "build": "run-p --print-name generate:* build:*", "predev": "run-p --print-name generate:*", "dev:docs": "npm run docs:schema -- --watch", "dev:build": "npm run build:components -- --watch --port 8087", @@ -54,8 +55,8 @@ "@types/pretty": "2.0.1", "@typescript-eslint/eslint-plugin": "5.53.0", "@typescript-eslint/parser": "5.53.0", - "@webcomponents-preview/cem-plugin-examples": "0.0.4", - "@webcomponents-preview/cem-plugin-inline-readme": "0.0.4", + "@webcomponents-preview/cem-plugin-examples": "0.0.23", + "@webcomponents-preview/cem-plugin-inline-readme": "0.0.23", "autoprefixer": "10.4.13", "barrelsby": "2.5.1", "cross-env": "7.0.3", diff --git a/scripts/prepare-examples.config.ts b/scripts/prepare-examples.config.ts new file mode 100644 index 00000000..65cb521e --- /dev/null +++ b/scripts/prepare-examples.config.ts @@ -0,0 +1,7 @@ +#!/usr/bin/env ts-node + +import { customElementExamplesPlugin } from '@webcomponents-preview/cem-plugin-examples'; + +export default { + plugins: [customElementExamplesPlugin()], +}; diff --git a/scripts/prepare-examples.index.html b/scripts/prepare-examples.index.html new file mode 100644 index 00000000..39f93f31 --- /dev/null +++ b/scripts/prepare-examples.index.html @@ -0,0 +1,14 @@ + + + + + + {{sources}} + + + + + + + + diff --git a/scripts/prepare-examples.json b/scripts/prepare-examples.json new file mode 100644 index 00000000..c3853ed1 --- /dev/null +++ b/scripts/prepare-examples.json @@ -0,0 +1,253 @@ +{ + "Lion": { + "git": "https://github.com/ing-bank/lion.git", + "branch": "master", + "path": "packages/ui/components", + "modules": [ + "https://unpkg.com/@lion/ui/exports/define/lion-accordion.js", + "https://unpkg.com/@lion/ui/exports/define/lion-button-reset.js", + "https://unpkg.com/@lion/ui/exports/define/lion-button-submit.js", + "https://unpkg.com/@lion/ui/exports/define/lion-button.js", + "https://unpkg.com/@lion/ui/exports/define/lion-calendar.js", + "https://unpkg.com/@lion/ui/exports/define/lion-checkbox-group.js", + "https://unpkg.com/@lion/ui/exports/define/lion-checkbox-indeterminate.js", + "https://unpkg.com/@lion/ui/exports/define/lion-checkbox.js", + "https://unpkg.com/@lion/ui/exports/define/lion-collapsible.js", + "https://unpkg.com/@lion/ui/exports/define/lion-combobox.js", + "https://unpkg.com/@lion/ui/exports/define/lion-dialog.js", + "https://unpkg.com/@lion/ui/exports/define/lion-drawer.js", + "https://unpkg.com/@lion/ui/exports/define/lion-field.js", + "https://unpkg.com/@lion/ui/exports/define/lion-fieldset.js", + "https://unpkg.com/@lion/ui/exports/define/lion-form.js", + "https://unpkg.com/@lion/ui/exports/define/lion-icon.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-amount.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-date.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-datepicker.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-email.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-iban.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-range.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-stepper.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-tel-dropdown.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input-tel.js", + "https://unpkg.com/@lion/ui/exports/define/lion-input.js", + "https://unpkg.com/@lion/ui/exports/define/lion-listbox.js", + "https://unpkg.com/@lion/ui/exports/define/lion-option.js", + "https://unpkg.com/@lion/ui/exports/define/lion-options.js", + "https://unpkg.com/@lion/ui/exports/define/lion-pagination.js", + "https://unpkg.com/@lion/ui/exports/define/lion-progress-indicator.js", + "https://unpkg.com/@lion/ui/exports/define/lion-radio-group.js", + "https://unpkg.com/@lion/ui/exports/define/lion-radio.js", + "https://unpkg.com/@lion/ui/exports/define/lion-select-invoker.js", + "https://unpkg.com/@lion/ui/exports/define/lion-select-rich.js", + "https://unpkg.com/@lion/ui/exports/define/lion-select.js", + "https://unpkg.com/@lion/ui/exports/define/lion-step.js", + "https://unpkg.com/@lion/ui/exports/define/lion-steps.js", + "https://unpkg.com/@lion/ui/exports/define/lion-switch-button.js", + "https://unpkg.com/@lion/ui/exports/define/lion-switch.js", + "https://unpkg.com/@lion/ui/exports/define/lion-tabs.js", + "https://unpkg.com/@lion/ui/exports/define/lion-textarea.js", + "https://unpkg.com/@lion/ui/exports/define/lion-tooltip.js", + "https://unpkg.com/@lion/ui/exports/define/lion-validation-feedback.js" + ] + }, + "Material": { + "git": "https://github.com/material-components/material-web.git", + "branch": "mwc", + "path": "components", + "modules": [ + "https://material-components.github.io/material-web/demos/button/index.js", + "https://material-components.github.io/material-web/demos/checkbox/index.js", + "https://material-components.github.io/material-web/demos/circular-progress/index.js", + "https://material-components.github.io/material-web/demos/circular-progress-four-color/index.js", + "https://material-components.github.io/material-web/demos/dialog/index.js", + "https://material-components.github.io/material-web/demos/drawer/index.js", + "https://material-components.github.io/material-web/demos/fab/index.js", + "https://material-components.github.io/material-web/demos/formfield/index.js", + "https://material-components.github.io/material-web/demos/icon-button-toggle/index.js", + "https://material-components.github.io/material-web/demos/icon-button/index.js", + "https://material-components.github.io/material-web/demos/icon/index.js", + "https://material-components.github.io/material-web/demos/linear-progress/index.js", + "https://material-components.github.io/material-web/demos/list/index.js", + "https://material-components.github.io/material-web/demos/menu/index.js", + "https://material-components.github.io/material-web/demos/radio/index.js", + "https://material-components.github.io/material-web/demos/select/index.js", + "https://material-components.github.io/material-web/demos/slider/index.js", + "https://material-components.github.io/material-web/demos/snackbar/index.js", + "https://material-components.github.io/material-web/demos/switch/index.js", + "https://material-components.github.io/material-web/demos/tab-bar/index.js", + "https://material-components.github.io/material-web/demos/tab/index.js", + "https://material-components.github.io/material-web/demos/textarea/index.js", + "https://material-components.github.io/material-web/demos/textfield/index.js", + "https://material-components.github.io/material-web/demos/top-app-bar-fixed/index.js", + "https://material-components.github.io/material-web/demos/top-app-bar/index.js" + ] + }, + "UI5": { + "git": "https://github.com/SAP/ui5-webcomponents.git", + "branch": "main", + "path": "packages/main/src", + "modules": [ + "https://unpkg.com/@ui5/webcomponents/dist/Assets-static.js", + "https://unpkg.com/@ui5/webcomponents/dist/Assets.js", + "https://unpkg.com/@ui5/webcomponents/dist/Avatar.js", + "https://unpkg.com/@ui5/webcomponents/dist/AvatarGroup.js", + "https://unpkg.com/@ui5/webcomponents/dist/Badge.js", + "https://unpkg.com/@ui5/webcomponents/dist/Breadcrumbs.js", + "https://unpkg.com/@ui5/webcomponents/dist/BreadcrumbsItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/BusyIndicator.js", + "https://unpkg.com/@ui5/webcomponents/dist/Button.js", + "https://unpkg.com/@ui5/webcomponents/dist/Calendar.js", + "https://unpkg.com/@ui5/webcomponents/dist/CalendarDate.js", + "https://unpkg.com/@ui5/webcomponents/dist/CalendarHeader.js", + "https://unpkg.com/@ui5/webcomponents/dist/CalendarPart.js", + "https://unpkg.com/@ui5/webcomponents/dist/Card.js", + "https://unpkg.com/@ui5/webcomponents/dist/CardHeader.js", + "https://unpkg.com/@ui5/webcomponents/dist/Carousel.js", + "https://unpkg.com/@ui5/webcomponents/dist/CheckBox.js", + "https://unpkg.com/@ui5/webcomponents/dist/ColorPalette.js", + "https://unpkg.com/@ui5/webcomponents/dist/ColorPaletteItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/ColorPalettePopover.js", + "https://unpkg.com/@ui5/webcomponents/dist/ColorPicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/ComboBox.js", + "https://unpkg.com/@ui5/webcomponents/dist/ComboBoxGroupItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/ComboBoxItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/CustomListItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/DateComponentBase.js", + "https://unpkg.com/@ui5/webcomponents/dist/DatePicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/DateRangePicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/DateTimePicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/DayPicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/Dialog.js", + "https://unpkg.com/@ui5/webcomponents/dist/DurationPicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/FileUploader.js", + "https://unpkg.com/@ui5/webcomponents/dist/Filters.js", + "https://unpkg.com/@ui5/webcomponents/dist/GroupHeaderListItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/Icon.js", + "https://unpkg.com/@ui5/webcomponents/dist/Input.js", + "https://unpkg.com/@ui5/webcomponents/dist/Interfaces.js", + "https://unpkg.com/@ui5/webcomponents/dist/Label.js", + "https://unpkg.com/@ui5/webcomponents/dist/Link.js", + "https://unpkg.com/@ui5/webcomponents/dist/List.js", + "https://unpkg.com/@ui5/webcomponents/dist/ListItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/ListItemBase.js", + "https://unpkg.com/@ui5/webcomponents/dist/Menu.js", + "https://unpkg.com/@ui5/webcomponents/dist/MenuItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/MessageStrip.js", + "https://unpkg.com/@ui5/webcomponents/dist/MonthPicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/MultiComboBox.js", + "https://unpkg.com/@ui5/webcomponents/dist/MultiComboBoxGroupItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/MultiComboBoxItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/MultiInput.js", + "https://unpkg.com/@ui5/webcomponents/dist/Option.js", + "https://unpkg.com/@ui5/webcomponents/dist/Panel.js", + "https://unpkg.com/@ui5/webcomponents/dist/Popover.js", + "https://unpkg.com/@ui5/webcomponents/dist/Popup.js", + "https://unpkg.com/@ui5/webcomponents/dist/ProgressIndicator.js", + "https://unpkg.com/@ui5/webcomponents/dist/RadioButton.js", + "https://unpkg.com/@ui5/webcomponents/dist/RadioButtonGroup.js", + "https://unpkg.com/@ui5/webcomponents/dist/RangeSlider.js", + "https://unpkg.com/@ui5/webcomponents/dist/RatingIndicator.js", + "https://unpkg.com/@ui5/webcomponents/dist/ResponsivePopover.js", + "https://unpkg.com/@ui5/webcomponents/dist/SegmentedButton.js", + "https://unpkg.com/@ui5/webcomponents/dist/SegmentedButtonItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/Select.js", + "https://unpkg.com/@ui5/webcomponents/dist/Slider.js", + "https://unpkg.com/@ui5/webcomponents/dist/SliderBase.js", + "https://unpkg.com/@ui5/webcomponents/dist/SplitButton.js", + "https://unpkg.com/@ui5/webcomponents/dist/StandardListItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/StepInput.js", + "https://unpkg.com/@ui5/webcomponents/dist/SuggestionGroupItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/SuggestionItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/SuggestionListItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/Switch.js", + "https://unpkg.com/@ui5/webcomponents/dist/Tab.js", + "https://unpkg.com/@ui5/webcomponents/dist/TabContainer.js", + "https://unpkg.com/@ui5/webcomponents/dist/TabSeparator.js", + "https://unpkg.com/@ui5/webcomponents/dist/Table.js", + "https://unpkg.com/@ui5/webcomponents/dist/TableCell.js", + "https://unpkg.com/@ui5/webcomponents/dist/TableColumn.js", + "https://unpkg.com/@ui5/webcomponents/dist/TableGroupRow.js", + "https://unpkg.com/@ui5/webcomponents/dist/TableRow.js", + "https://unpkg.com/@ui5/webcomponents/dist/TextArea.js", + "https://unpkg.com/@ui5/webcomponents/dist/TimePicker.js", + "https://unpkg.com/@ui5/webcomponents/dist/TimePickerBase.js", + "https://unpkg.com/@ui5/webcomponents/dist/TimeSelection.js", + "https://unpkg.com/@ui5/webcomponents/dist/Title.js", + "https://unpkg.com/@ui5/webcomponents/dist/Toast.js", + "https://unpkg.com/@ui5/webcomponents/dist/ToggleButton.js", + "https://unpkg.com/@ui5/webcomponents/dist/Token.js", + "https://unpkg.com/@ui5/webcomponents/dist/Tokenizer.js", + "https://unpkg.com/@ui5/webcomponents/dist/Tree.js", + "https://unpkg.com/@ui5/webcomponents/dist/TreeItem.js", + "https://unpkg.com/@ui5/webcomponents/dist/TreeItemBase.js", + "https://unpkg.com/@ui5/webcomponents/dist/TreeItemCustom.js", + "https://unpkg.com/@ui5/webcomponents/dist/TreeList.js", + "https://unpkg.com/@ui5/webcomponents/dist/WheelSlider.js", + "https://unpkg.com/@ui5/webcomponents/dist/YearPicker.js" + ] + }, + "Spectrum": { + "git": "https://github.com/adobe/spectrum-web-components.git", + "branch": "main", + "path": "packages", + "modules": ["https://jspm.dev/@spectrum-web-components/bundle/elements.js"] + }, + "Vaadin": { + "git": "https://github.com/vaadin/web-components.git", + "branch": "main", + "path": "packages", + "modules": [ + "https://unpkg.com/@vaadin/accordion", + "https://unpkg.com/@vaadin/app-layout", + "https://unpkg.com/@vaadin/avatar", + "https://unpkg.com/@vaadin/avatar-group", + "https://unpkg.com/@vaadin/button", + "https://unpkg.com/@vaadin/checkbox", + "https://unpkg.com/@vaadin/checkbox-group", + "https://unpkg.com/@vaadin/combo-box", + "https://unpkg.com/@vaadin/confirm-dialog", + "https://unpkg.com/@vaadin/context-menu", + "https://unpkg.com/@vaadin/custom-field", + "https://unpkg.com/@vaadin/date-picker", + "https://unpkg.com/@vaadin/date-time-picker", + "https://unpkg.com/@vaadin/details", + "https://unpkg.com/@vaadin/dialog", + "https://unpkg.com/@vaadin/email-field", + "https://unpkg.com/@vaadin/form-layout", + "https://unpkg.com/@vaadin/grid", + "https://unpkg.com/@vaadin/horizontal-layout", + "https://unpkg.com/@vaadin/icon", + "https://unpkg.com/@vaadin/icons", + "https://unpkg.com/@vaadin/integer-field", + "https://unpkg.com/@vaadin/item", + "https://unpkg.com/@vaadin/list-box", + "https://unpkg.com/@vaadin/login", + "https://unpkg.com/@vaadin/menu-bar", + "https://unpkg.com/@vaadin/message-input", + "https://unpkg.com/@vaadin/message-list", + "https://unpkg.com/@vaadin/multi-select-combo-box", + "https://unpkg.com/@vaadin/notification", + "https://unpkg.com/@vaadin/number-field", + "https://unpkg.com/@vaadin/password-field", + "https://unpkg.com/@vaadin/progress-bar", + "https://unpkg.com/@vaadin/radio-group", + "https://unpkg.com/@vaadin/scroller", + "https://unpkg.com/@vaadin/select", + "https://unpkg.com/@vaadin/split-layout", + "https://unpkg.com/@vaadin/tabs", + "https://unpkg.com/@vaadin/tabsheet", + "https://unpkg.com/@vaadin/text-area", + "https://unpkg.com/@vaadin/text-field", + "https://unpkg.com/@vaadin/time-picker", + "https://unpkg.com/@vaadin/tooltip", + "https://unpkg.com/@vaadin/upload", + "https://unpkg.com/@vaadin/virtual-list" + ] + }, + "Wired": { + "git": "https://github.com/rough-stuff/wired-elements.git", + "branch": "master", + "path": "src", + "modules": ["https://unpkg.com/wired-elements?module"] + } +} diff --git a/scripts/prepare-examples.ts b/scripts/prepare-examples.ts new file mode 100644 index 00000000..99ad7051 --- /dev/null +++ b/scripts/prepare-examples.ts @@ -0,0 +1,143 @@ +#!/usr/bin/env ts-node + +/** + * Provide examples by: + * - Go through a list of public web component UI libraries + * - Check them out from GitHub + * - Generate manifest.json files for each example + * - Make them accessible via WCP + */ + +import { exec } from 'node:child_process'; +import { readdir, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; +import { existsSync } from 'node:fs'; +import { basename, dirname, join, relative, resolve, sep } from 'node:path'; +import { argv } from 'node:process'; +import { parseArgs, promisify } from 'node:util'; + +// load the example config +import libraries from './prepare-examples.json' assert { type: 'json' }; + +const execAsync = promisify(exec); +const [, __filename] = argv; +const __dirname = dirname(__filename); + +const defaultTarget = './dist/examples'; +const { values } = parseArgs({ + options: { + quiet: { type: 'boolean', default: false }, + target: { type: 'string', default: defaultTarget }, + verbose: { type: 'boolean', default: false }, + }, +}); +const { quiet = false, verbose = false } = values; +const target = resolve(values.target ?? defaultTarget); + +const { log, error, info, warn } = global.console; +const console = { + ...global.console, + log: (...args) => (!quiet ? log(...args) : undefined), + error: (...args) => (!quiet ? error(...args) : undefined), + info: (...args) => (!quiet && verbose ? info(...args) : undefined), + warn: (...args) => (!quiet ? warn(...args) : undefined), +} satisfies Console; + +export type Library = { + git: string; + branch: string; + path: string; + modules: string[]; +}; + +export async function cleanDist(target: string): Promise { + if (existsSync(target)) { + await rm(target, { recursive: true }); + console.info(`> Cleaned ${target}.`); + } +} + +export async function cloneExampleSource(name: string, target: string, library: Library): Promise { + const { branch, git, path } = library; + // prepare example folder + const repository = basename(git, '.git'); + const cwd = resolve(target, repository); + await mkdir(cwd, { recursive: true }); + + // checkout example + await execAsync(`git clone --depth 1 --filter=blob:none --sparse --branch ${branch} ${git} ${cwd}`); + await execAsync(`git sparse-checkout set ${path}`, { cwd }); + + // remove all unnecessary files from root folder + const [entry] = path.split(sep); + const entries = await readdir(cwd); + entries.filter((e) => e !== entry).forEach((e) => rm(resolve(cwd, e), { recursive: true })); + + // done + console.info(`> Cloned ${name} source.`); +} + +export async function createExampleEntryPoint(name: string, target: string, library: Library): Promise { + // get the paths to the example + const { git, modules } = library; + const repository = basename(git, '.git'); + const cwd = resolve(target, repository); + const entry = resolve(cwd, 'index.html'); + const template = resolve(__dirname, 'prepare-examples.index.html'); + + // prepare the example entry point + const content = await readFile(template, 'utf-8'); + const context: Record = { + title: name, + sources: modules.map((module) => ``).join('\n\t'), + }; + const html = content.replace(/{{([^}}]*)}}/g, (_, key) => context[key]); + await writeFile(entry, html); + + // done + console.info(`> Created entry point for ${name}.`); +} + +export async function createManifests(name: string, target: string, library: Library): Promise { + // prepare paths + const repository = basename(library.git, '.git'); + const cwd = resolve(target, repository); + const bin = relative(cwd, join(dirname(__dirname), 'node_modules', '.bin', 'custom-elements-manifest')); + const config = relative(cwd, join(__dirname, 'prepare-examples.config.ts')); + + // create manifest + await execAsync(`${bin} analyze --quiet --config ${config}`, { cwd }); + + // done + console.info(`> Created manifest for ${name}.`); +} + +export async function removeExampleSource(name: string, target: string, library: Library): Promise { + const { git, path } = library; + // get the paths and remove the example + const repository = basename(git, '.git'); + const [entry] = path.split(sep); + const cwd = resolve(target, repository, entry); + await rm(cwd, { recursive: true }); + + // done + console.info(`> Removed ${name} source.`); +} + +// remove existing examples +await cleanDist(target); + +// create new examples +await Promise.allSettled( + Object.entries(libraries).map(async ([name, library]) => { + // checkout example + await cloneExampleSource(name, target, library); + // create manifests + await createManifests(name, target, library); + // prepare the example entry point + await createExampleEntryPoint(name, target, library); + // remove example + await removeExampleSource(name, target, library); + // done + console.log(`> Prepared example for ${name}.`); + }) +); diff --git a/src/components/root/README.md b/src/components/root/README.md index 81450cd0..9fc74a01 100644 --- a/src/components/root/README.md +++ b/src/components/root/README.md @@ -9,7 +9,7 @@ | `elements` | | `CustomElementDeclaration[]` | [] | | | `handleHashChange` | | | "(() => {\n const [, activeElement] = window.location.hash.split('#/');\n this.activeElement = activeElement;\n this.emitActiveElementChanged();\n }).bind(this)" | | | `manifestUrl` | `manifest-url` | `string \| undefined` | | Defines the location of the custom element manifest file. | -| `title` | | `string` | "Webcomponents Preview" | | +| `title` | `title` | `string` | | | ## Methods @@ -19,7 +19,6 @@ | `emitManifestLoaded` | `(): void` | | `getActiveElementDeclaration` | `(): CustomElementDeclaration \| undefined` | | `loadCustomElementsManifest` | `(): Promise` | -| `loadTitleFromConfig` | `(): Promise` | ## Events diff --git a/tsconfig.json b/tsconfig.json index e3bce52a..1246b8cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "paths": { "@/*": ["./src/*"] }, + "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "target": "esnext", @@ -21,6 +22,7 @@ "exclude": ["node_modules", "dist"], "ts-node": { "esm": true, + "experimentalResolver": true, "experimentalSpecifierResolution": "node", "files": true, "logError": true,