diff --git a/package-lock.json b/package-lock.json index 6ce338a111..fa0a9e0900 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55652,6 +55652,19 @@ "dev": true, "license": "MIT" }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stencil-inline-svg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stencil-inline-svg/-/stencil-inline-svg-1.1.0.tgz", @@ -61008,6 +61021,7 @@ "@whitespace/storybook-addon-html": "6.1.1", "autoprefixer": "10.4.20", "axe-core": "4.10.2", + "chalk": "4.1.2", "cypress": "13.7.3", "cypress-axe": "1.5.0", "cypress-repeat": "2.3.8", @@ -61022,6 +61036,7 @@ "lit-html": "3.2.1", "local-web-server": "5.4.0", "natural-orderby": "5.0.0", + "ora": "8.2.0", "playwright": "1.50.0", "postcss": "8.5.1", "postcss-focus-visible": "10.0.1", @@ -62038,6 +62053,227 @@ "pretty-format": "^29.0.0" } }, + "packages/atomic/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "packages/atomic/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/atomic/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "packages/atomic/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "packages/atomic/node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/log-symbols/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "packages/atomic/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/ora/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "packages/atomic/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/atomic/node_modules/rollup": { "version": "4.31.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz", @@ -62077,6 +62313,53 @@ "fsevents": "~2.3.2" } }, + "packages/atomic/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/atomic/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "packages/atomic/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "packages/atomic/storybookUtils": { "extraneous": true }, diff --git a/packages/atomic/.storybook/main.mts b/packages/atomic/.storybook/main.mts index 34c623ac6e..7f0c30de95 100644 --- a/packages/atomic/.storybook/main.mts +++ b/packages/atomic/.storybook/main.mts @@ -63,15 +63,15 @@ const config: StorybookConfig = { mergeConfig(config, { plugins: [ nxViteTsPaths(), - resolveStorybookUtils(), + resolveStorybookUtilsImports(), configType === 'PRODUCTION' && isCDN && externalizeDependencies(), ], }), }; -const resolveStorybookUtils: PluginImpl = () => { +const resolveStorybookUtilsImports: PluginImpl = () => { return { - name: 'resolve-storybook-utils', + name: 'resolve-storybook-utils-imports', async resolveId(source: string, importer, options) { if (source.startsWith('@/storybook-utils')) { return this.resolve( diff --git a/packages/atomic/package.json b/packages/atomic/package.json index 04e6c67c0e..1e3e32ed38 100644 --- a/packages/atomic/package.json +++ b/packages/atomic/package.json @@ -119,6 +119,7 @@ "@whitespace/storybook-addon-html": "6.1.1", "autoprefixer": "10.4.20", "axe-core": "4.10.2", + "chalk": "4.1.2", "cypress": "13.7.3", "cypress-axe": "1.5.0", "cypress-repeat": "2.3.8", @@ -133,6 +134,7 @@ "lit-html": "3.2.1", "local-web-server": "5.4.0", "natural-orderby": "5.0.0", + "ora": "8.2.0", "playwright": "1.50.0", "postcss": "8.5.1", "postcss-focus-visible": "10.0.1", diff --git a/packages/atomic/project.json b/packages/atomic/project.json index 26fa6c2593..28db8fb7e6 100644 --- a/packages/atomic/project.json +++ b/packages/atomic/project.json @@ -92,10 +92,6 @@ "cwd": "{projectRoot}" } }, - "dev": { - "dependsOn": ["storybook", "build:watch", "cem:dev", "web:dev"], - "executor": "nx:noop" - }, "build:watch": { "executor": "nx:run-commands", "options": { @@ -107,7 +103,7 @@ "web:dev": { "executor": "nx:run-commands", "options": { - "command": "node ./scripts/start-dev.mjs", + "command": "node ./scripts/start-vite.mjs", "cwd": "{projectRoot}" } }, @@ -119,13 +115,6 @@ "cwd": "{projectRoot}" } }, - "cem:dev": { - "executor": "nx:run-commands", - "options": { - "command": "cem analyze --watch", - "cwd": "{projectRoot}" - } - }, "cem:build": { "executor": "nx:run-commands", "options": { @@ -147,13 +136,6 @@ "command": "wait-on http://localhost:3333/ping" } }, - "storybook": { - "executor": "nx:run-commands", - "options": { - "cwd": "{projectRoot}", - "command": "npx storybook dev -p 4400" - } - }, "build-storybook": { "dependsOn": ["cached:build:stencil", "cem:build", "list-assets"], "executor": "nx:run-commands", @@ -180,7 +162,7 @@ "generate-component": { "executor": "nx:run-commands", "options": { - "command": "node ./scripts/generate-component.js {args.name} {args.output}", + "command": "node ./scripts/generate-component.mjs {args.name} {args.output}", "cwd": "{projectRoot}" }, "inputs": [], @@ -197,6 +179,21 @@ }, "required": ["name", "output"] } + }, + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "node ./scripts/dev.mjs", + "cwd": "{projectRoot}" + }, + "schema": { + "properties": { + "stencil": { + "type": "boolean", + "description": "If you want to rebuild stencil in dev mode" + } + } + } } } } diff --git a/packages/atomic/scripts/build.mjs b/packages/atomic/scripts/build.mjs index 3ea239f5a7..95966cc280 100644 --- a/packages/atomic/scripts/build.mjs +++ b/packages/atomic/scripts/build.mjs @@ -9,6 +9,7 @@ import { createProgram, flattenDiagnosticMessageText, } from 'typescript'; +import pathTransformer from './path-transform.mjs'; import svgTransformer from './svg-transform.mjs'; const args = argv.slice(2); @@ -38,7 +39,7 @@ function emit(program) { const writeFile = undefined; const emitOnlyDtsFiles = false; const customTransformers = { - before: [svgTransformer], + before: [svgTransformer, pathTransformer], }; return program.emit( diff --git a/packages/atomic/scripts/dev.mjs b/packages/atomic/scripts/dev.mjs new file mode 100644 index 0000000000..de164f968e --- /dev/null +++ b/packages/atomic/scripts/dev.mjs @@ -0,0 +1,205 @@ +import chalk from 'chalk'; +import {exec} from 'node:child_process'; +import {watch} from 'node:fs'; +import net from 'node:net'; +import ora from 'ora'; +import waitOn from 'wait-on'; + +/** + * An array to keep track of running processes. + * @type {Array} + */ +let runningProcesses = []; +/** + * A flag to stop the build process if a file changes during the build. + * @type {boolean} + */ +let isStopped = false; +/** + * @type {import('node:child_process').ChildProcess} + */ +let storybookServer; + +/** + * Executes a command as a child process with a spinner animation. + * + * @param {string} text - The text to display alongside the spinner. + * @param {string} command - The command to execute in the child process. + * @returns {Promise} A promise that resolves when the command completes successfully, or rejects if an error occurs. + */ +async function nextTask(text, command) { + const frames = ['⚽ 🐕 ', ' ⚽ 🐕 ', ' ⚽🐕 ', ' ⚽🐕 ', '⚽ 🐕 ']; + const spinner = ora({ + text: text, + spinner: {frames, interval: 200}, + }).start(); + + return new Promise((resolve, reject) => { + const childProcess = exec(command, {stdio: 'inherit'}); + + // Add the process to the list of running processes to be able to stop them + runningProcesses.push(childProcess); + + childProcess.on('exit', (code) => { + runningProcesses = runningProcesses.filter((p) => p !== childProcess); + + if (code === 0) { + spinner.succeed(chalk.magenta.bold(`${text}`)); + resolve(); + } else { + spinner.fail(chalk.red.bold(`${text}`)); + } + }); + + childProcess.on('error', (error) => { + spinner.fail(chalk.red.bold(`${text}`)); + reject(error); + }); + }); +} + +async function stopAllProcesses() { + isStopped = true; + + runningProcesses.forEach((process) => { + if (process && process.kill) { + process.kill('SIGTERM'); + } + }); + + runningProcesses = []; + + // Wait briefly to ensure processes terminate before restarting the build + await new Promise((resolve) => setTimeout(resolve, 300)); +} + +/** + * Waits for a specific port to be available on the given host using wait-on. + * + * @param {number} port - The port number to check. + * @param {string} [host='localhost'] - The host to check the port on. + * @param {number} [timeout=30000] - The maximum time to wait for the port to be available, in milliseconds. + * @returns {Promise} A promise that resolves when the port is available, or rejects if the timeout is reached. + */ +async function waitForPort(port, host = 'localhost', timeout = 30000) { + const resource = `tcp:${host}:${port}`; + try { + await waitOn({ + resources: [resource], + timeout, + tcpTimeout: 1000, + interval: 500, + }); + } catch (error) { + throw new Error(`Timeout waiting for port ${port} on ${host}`); + } +} + +async function startServers() { + console.log(chalk.green.bold('🚀 Starting development servers...')); + + storybookServer = exec('npx storybook dev -p 4400 --no-open', { + stdio: 'ignore', + }); + + // Script that starts the Vite server and copies files for CDN mode + exec('node ./scripts/start-vite.mjs', {stdio: 'ignore'}); + + console.log( + chalk.yellow('⌛ Waiting for Storybook (4400) and Vite (3333)...') + ); + await Promise.all([waitForPort(4400), waitForPort(3333)]); + + console.log(chalk.blue.bold('✅ Servers started! Watching for changes...')); +} + +// Get the stencil flag +const isStencil = process.argv.includes('--stencil'); + +// Start the servers (vite & storybook) first +startServers(); + +// Watch the src folder for changes +watch('src', {recursive: true}, async (_, filename) => { + // Stop all processes if a file changes to prevent multiple builds at once + await stopAllProcesses(); + console.log(chalk.cyanBright(`📂 File changed: ${filename}`)); + + // Flag to stop the build process if a file changes during the build + isStopped = false; + + if (isStencil) { + await nextTask( + 'Rebuilding Stencil...', + 'node --max_old_space_size=6144 ../../node_modules/@stencil/core/bin/stencil build --tsConfig tsconfig.stencil.json' + ); + + if (isStopped) { + return; + } + + await nextTask( + 'Placing the Stencil Proxy...', + 'node ./scripts/stencil-proxy.mjs' + ); + + if (isStopped) { + return; + } + } + + await nextTask( + 'Rebuilding Lit...', + 'node ./scripts/build.mjs --config=tsconfig.lit.json' + ); + + if (isStopped) { + return; + } + + await nextTask( + 'Processing CSS...', + 'node ./scripts/process-css.mjs --config=tsconfig.lit.json' + ); + + if (isStopped) { + return; + } + + await nextTask( + 'Running esbuild for autoloader ESM...', + 'esbuild src/autoloader/index.ts --format=esm --outfile=dist/atomic/autoloader/index.esm.js' + ); + + if (isStopped) { + return; + } + + await nextTask( + 'Running esbuild for autoloader CJS...', + 'esbuild src/autoloader/index.ts --format=cjs --outfile=dist/atomic/autoloader/index.cjs.js' + ); + + if (isStopped) { + return; + } + + await nextTask( + 'Building storybook...', + 'npx storybook build -o dist-storybook' + ); + + // Restart storybook server + // Somehow even after a build, the dev server doesn't pick up the changes. + // It needs a dev restart to pick them up. + storybookServer.kill('SIGTERM'); + storybookServer = exec('npx storybook dev -p 4400 --no-open', { + stdio: 'ignore', + }); + + if (isStopped) { + return; + } + + console.log(chalk.magenta.bold(' 🎇 Build process completed! 🎇 ')); +}); diff --git a/packages/atomic/scripts/generate-component-templates/component.ts.hbs b/packages/atomic/scripts/generate-component-templates/component.ts.hbs index b3420bfc00..4de0d6db4d 100644 --- a/packages/atomic/scripts/generate-component-templates/component.ts.hbs +++ b/packages/atomic/scripts/generate-component-templates/component.ts.hbs @@ -1,4 +1,4 @@ -import {TailwindLitElement} from '@/src/utils/tailwind.element'; +import {TailwindLitElement} from '@/src/utils/tailwind.element.js'; import {CSSResultGroup, html, unsafeCSS} from 'lit'; import {customElement, property} from 'lit/decorators.js'; import styles from './{{name}}.css'; diff --git a/packages/atomic/scripts/generate-component.js b/packages/atomic/scripts/generate-component.mjs similarity index 97% rename from packages/atomic/scripts/generate-component.js rename to packages/atomic/scripts/generate-component.mjs index 044d55dc74..d0e7110f22 100644 --- a/packages/atomic/scripts/generate-component.js +++ b/packages/atomic/scripts/generate-component.mjs @@ -90,7 +90,7 @@ if (outputDir) { if (!componentName) { console.error( - 'Usage: node generate-component.js []' + 'Usage: npx nx run atomic:generate-component --name= --output=' ); process.exit(1); } diff --git a/packages/atomic/scripts/path-transform.mjs b/packages/atomic/scripts/path-transform.mjs new file mode 100644 index 0000000000..52d54cac3d --- /dev/null +++ b/packages/atomic/scripts/path-transform.mjs @@ -0,0 +1,61 @@ +import {dirname, resolve, relative} from 'path'; +import { + isImportDeclaration, + visitEachChild, + visitNode, + isStringLiteral, +} from 'typescript'; + +// The import prefix as defined in the tsconfig under paths +const IMPORT_PREFIX = '@/'; + +/** + * Transforms import paths in TypeScript source files. + * + * @param {import('typescript').TransformationContext} context - The transformation context provided by TypeScript. + * @returns {import('typescript').Transformer} A transformer function that processes a source file. + */ +export default function pathTransformer(context) { + const {factory} = context; + + function visit(node, sourceFile) { + if (isImportDeclaration(node) && isStringLiteral(node.moduleSpecifier)) { + const importPath = node.moduleSpecifier.text; + + if (importPath.startsWith(IMPORT_PREFIX)) { + const relativePath = getRelativeImportPath( + sourceFile.fileName, + importPath + ); + + return factory.updateImportDeclaration( + node, + node.modifiers, + node.importClause, + factory.createStringLiteral(relativePath) + ); + } + } + return visitEachChild(node, (child) => visit(child, sourceFile), context); + } + + return (sourceFile) => + visitNode(sourceFile, (node) => visit(node, sourceFile)); +} + +/** + * Generates a relative import path from a source file path and an import path. + * + * @param {string} sourceFilePath - The file path of the source file. + * @param {string} importPath - The import path to be transformed. + * @returns {string} The relative import path. + */ +function getRelativeImportPath(sourceFilePath, importPath) { + const basePath = resolve(process.cwd()); + const absoluteImportPath = resolve( + basePath, + importPath.replace(IMPORT_PREFIX, '') + ); + const relativePath = relative(dirname(sourceFilePath), absoluteImportPath); + return relativePath.startsWith('.') ? relativePath : `./${relativePath}`; +} diff --git a/packages/atomic/scripts/start-dev.mjs b/packages/atomic/scripts/start-vite.mjs similarity index 100% rename from packages/atomic/scripts/start-dev.mjs rename to packages/atomic/scripts/start-vite.mjs diff --git a/packages/atomic/scripts/watch.mjs b/packages/atomic/scripts/watch.mjs deleted file mode 100644 index 5542253045..0000000000 --- a/packages/atomic/scripts/watch.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import {execSync} from 'node:child_process'; -import {watch, cpSync} from 'node:fs'; -import {createServer} from 'node:http'; - -function checkPort(port) { - return new Promise((resolve, reject) => { - const server = createServer(); - server.once('error', (err) => { - if (err.code === 'EADDRINUSE') { - resolve(true); - } else { - reject(err); - } - }); - server.once('listening', () => { - server.close(); - resolve(false); - }); - server.listen(port); - }); -} - -async function rebuild(event, fileName) { - if (fileName.contains('/e2e/') || fileName.contains('/.e2e.')) { - return; - } - const commands = [ - 'node --max_old_space_size=6144 ../../node_modules/@stencil/core/bin/stencil build --tsConfig tsconfig.stencil.json', - 'node ./scripts/stencil-proxy.mjs', - 'node ./scripts/build.mjs --config=tsconfig.lit.json', - 'node ./scripts/process-css.mjs --config=tsconfig.lit.json ', - 'if [ "$DEPLOYMENT_ENVIRONMENT" == "CDN" ]; then rollup -c rollup.config.js; fi', - 'esbuild src/autoloader/index.ts --format=esm --outfile=dist/atomic/autoloader/index.esm.js', - 'esbuild src/autoloader/index.ts --format=cjs --outfile=dist/atomic/autoloader/index.cjs.js', - ]; - for (const command of commands) { - execSync(command, { - stdio: 'inherit', - env: {...process.env, IS_DEV: 'true'}, - }); - } - if (await checkPort(4400)) { - cpSync('./dist/atomic', './dist-storybook/assets', {recursive: true}); - cpSync('./dist/atomic/lang', './dist-storybook/lang', {recursive: true}); - } -} - -watch('src', {recursive: true}, rebuild); -rebuild(); diff --git a/packages/atomic/tsconfig.storybook.json b/packages/atomic/tsconfig.storybook.json index 094372902a..30d5ba207d 100644 --- a/packages/atomic/tsconfig.storybook.json +++ b/packages/atomic/tsconfig.storybook.json @@ -4,10 +4,7 @@ "emitDecoratorMetadata": true, "composite": true, "jsxFactory": "h", - "declaration": true, - "paths": { - "@/*": ["./*"] - } + "declaration": true }, "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"], "include": [