From e1833149aa2bf921b278322807732fca0653fb50 Mon Sep 17 00:00:00 2001 From: Alexandre Anicio Date: Thu, 13 Feb 2025 12:29:45 -0300 Subject: [PATCH] BA-2259: improve dev mode --- .scripts/command-utils.mjs | 111 ++++++ README.md | 55 ++- package.json | 3 + .../components/.scripts/build-command.mjs | 3 + packages/components/.scripts/build.mjs | 61 ++++ packages/components/.scripts/dev-command.mjs | 100 ++++++ packages/components/README.md | 4 +- packages/components/package.json | 11 +- packages/components/tsup.config.ts | 2 +- .../design-system/.scripts/build-command.mjs | 3 + packages/design-system/.scripts/build.mjs | 57 +++ .../design-system/.scripts/dev-command.mjs | 107 ++++++ packages/design-system/README.md | 6 +- packages/design-system/package.json | 7 +- packages/design-system/tsup.config.ts | 2 +- pnpm-lock.yaml | 325 +++++++++++++----- pnpm-workspace.yaml | 31 +- turbo.json | 1 + 18 files changed, 758 insertions(+), 131 deletions(-) create mode 100644 .scripts/command-utils.mjs create mode 100644 packages/components/.scripts/build-command.mjs create mode 100644 packages/components/.scripts/build.mjs create mode 100644 packages/components/.scripts/dev-command.mjs create mode 100644 packages/design-system/.scripts/build-command.mjs create mode 100644 packages/design-system/.scripts/build.mjs create mode 100644 packages/design-system/.scripts/dev-command.mjs diff --git a/.scripts/command-utils.mjs b/.scripts/command-utils.mjs new file mode 100644 index 00000000..d9556c87 --- /dev/null +++ b/.scripts/command-utils.mjs @@ -0,0 +1,111 @@ +import chalk from "chalk" +import chokidar from "chokidar" +import fs from "fs/promises" +import path from "path" +import { execa } from "execa" + +export const cancelCurrentBuild = async ({ + currentBuildProcesses, + commandTag, +}) => { + console.log(chalk.red(`${commandTag} Canceling current build processes...`)) + for (const proc of currentBuildProcesses) { + try { + proc.kill() + } catch (err) { + console.error( + chalk.red( + `${commandTag} Error killing process ${proc.pid}: ${err.message}` + ) + ) + } + } + await execa("pnpm", ["clean:tmp"], { preferLocal: true }) + currentBuildProcesses = [] +} + +export const getConsumerAppBasePath = () => { + const consumerPath = process.env.BASEAPP_FRONTEND_TEMPLATE_PATH + if (!consumerPath) { + console.error( + chalk.red( + " Error: Please set the environment variable BASEAPP_FRONTEND_TEMPLATE_PATH in your shell startup (e.g., in ~/.bashrc or ~/.zshrc) before running this command.\n", + "Example: export BASEAPP_FRONTEND_TEMPLATE_PATH=/path/to/the/baseapp-frontend-template\n", + `Note: Don't forget to restart your terminal after setting the new environment variable.` + ) + ) + + process.exit(1) + } + return consumerPath +} + +export const updateConsumerRsync = async ({ + consumerAppPath, + sourceDist, + packageName, + commandTag, +}) => { + const targetDist = + path.join( + consumerAppPath, + "node_modules", + "@baseapp-frontend", + packageName, + "dist" + ) + "/" + + console.log( + chalk.cyan(`${commandTag} Syncing dist folder to consumer app...`) + ) + try { + await execa( + "rsync", + ["-av", "--delete", "--delay-updates", sourceDist, targetDist], + { + shell: true, + } + ) + console.log(chalk.cyan(`${commandTag} Sync completed successfully.`)) + } catch (error) { + console.error(chalk.red(`${commandTag} Sync failed:`)) + console.error(chalk.red(error.stderr || error.message)) + } +} + +export const waitForReadyFile = async ({ readyFileParentPath, commandTag }) => { + console.log( + chalk.yellow(`${commandTag} Waiting for other packages to start...`) + ) + + return new Promise((resolve, reject) => { + const watcher = chokidar.watch(readyFileParentPath, { + ignoreInitial: false, + usePolling: true, + interval: 100, + awaitWriteFinish: { + stabilityThreshold: 500, + pollInterval: 100, + }, + }) + watcher.on('add', (filePath) => { + if (path.basename(filePath) === 'build.ready') { + console.log(chalk.green(`${commandTag} Ready file detected.`)) + watcher.close() + resolve() + } + }) + watcher.on("error", (err) => { + watcher.close() + reject(err) + }) + }) +} + +export const cleanupReadyFile = async ({readyFilePath}) => { + try { + await fs.unlink(readyFilePath) + } catch (err) { + // pass + } +} \ No newline at end of file diff --git a/README.md b/README.md index 7776be73..f72b4763 100644 --- a/README.md +++ b/README.md @@ -83,17 +83,56 @@ To build all apps and packages, run the following command: pnpm build # build only the authentication package -pnpm build --filter=authentication +pnpm build --filter=@baseapp-frontend/authentication ``` ## Develop -To develop all apps and packages, run the following command: +Our development mode is designed to provide immediate feedback as you work on our monorepo apps and packages. In dev mode, each package automatically watches for changes in its source files, rebuilds itself using a custom build process, and synchronizes its output (bundled code, type declarations, etc.) to the consumer app. + +This ensures that any changes you make are quickly reflected in the running application without the need to manually rebuild or restart servers. + +### What Happens in Dev Mode + +Some of our packages—like `@baseapp-frontend/components` and `@baseapp-frontend/design-system`—have a multi-step build process. When you run: ```bash pnpm dev ``` +Each package in our monorepo enters a persistent watch mode. + +For example, when running dev mode for `@baseapp-frontend/components`, you might see output similar to the following: +```bash +[@baseapp-frontend/components] Waiting for other packages to start... # wait for other dependencies to be build +[@baseapp-frontend/components] Starting build process... # start the build process +[@baseapp-frontend/components] Running Relay Compiler... # since this package uses relay, run the relay compiler +[@baseapp-frontend/components] Relay compilation completed. +[@baseapp-frontend/components] Running Babel transpiling... # run babel step to transpile the code +[@baseapp-frontend/components] Babel transpilation completed. +[@baseapp-frontend/components] Running tsup bundling... # run tsup step to bunle the code +[@baseapp-frontend/components] Running type declaration generation... # run tsc step to create type declarations +[@baseapp-frontend/components] tsup Bundling completed. +[@baseapp-frontend/components] Type declarations generated. +[@baseapp-frontend/components] Copying DTS files... # merge the declaration files with the bundled files +[@baseapp-frontend/components] DTS files copied. +[@baseapp-frontend/components] Cleaning temporary files... # remove temporary folders +[@baseapp-frontend/components] Temporary files cleaned. +[@baseapp-frontend/components] Build completed successfully. # build completed +[@baseapp-frontend/components] Syncing dist folder to consumer app... # sync the build output with the consumer app (baseapp-frontend-template) +[@baseapp-frontend/components] Sync completed successfully. +``` +**Disclaimer** + +The dev mode is a powerful tool that makes live testing of changes very convenient by automatically rebuilding packages as you edit files. + +However, note that for packages like `@baseapp-frontend/design-system` and `@baseapp-frontend/components`, the watch process can trigger multiple build tasks upon every file change. + +This continuous rebuild may lead to increased memory consumption and CPU usage if you’re making a lot of simultaneous changes. + +It is recommended to use this live mode only at appropriate times rather than throughout your entire development phase. + + ## **PNPM Catalog Overview** This monorepo manages some dependencies using pnpm catalogs. As a rule of thumb, we often add dependencies to the catalogs that are reused across multiple packages, rather than arbitrarily adding dependencies to these lists. This approach ensures that shared dependencies are centrally managed and consistently applied across the codebase. @@ -104,13 +143,10 @@ Make sure to keep [`@baseapp-frontend's catalog`](https://github.com/silverlogic ### **Remove Catalog Entries**: - Before using a package from GitHub, remove its catalog entry. This is necessary because pnpm doesn't handle catalogs well when using non-published versions. To remove the catalogs for the desired package, run the following command: + Before using a package from GitHub, remove its catalog entry. This is necessary because pnpm doesn't handle catalogs well when using non-published versions. To remove the catalogs for all packages, run the following command: ```bash - # will replace catalogs for utils and authentication packages - pnpm replace-catalogs utils authentication - - # will replace catalogs for all packages + pnpm i # make sure the dependencies are installed pnpm replace-catalogs ``` @@ -119,10 +155,7 @@ Make sure to keep [`@baseapp-frontend's catalog`](https://github.com/silverlogic To restore the catalog entries to their original state, run the following command: ```bash - # will restore catalogs for utils and authentication packages - pnpm restore-catalogs utils authentication - - # will restore catalogs for all packages + pnpm i # make sure the dependencies are installed pnpm restore-catalogs ``` diff --git a/package.json b/package.json index 309febe5..f5acfa3e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,10 @@ "@parcel/packager-ts": "latest", "@parcel/transformer-typescript-types": "latest", "@types/node": "catalog:", + "chalk": "^5.4.1", + "chokidar": "^4.0.3", "eslint": "catalog:lint", + "execa": "^9.5.2", "husky": "catalog:lint", "lint-staged": "catalog:lint", "prettier": "catalog:lint", diff --git a/packages/components/.scripts/build-command.mjs b/packages/components/.scripts/build-command.mjs new file mode 100644 index 00000000..8fa16390 --- /dev/null +++ b/packages/components/.scripts/build-command.mjs @@ -0,0 +1,3 @@ +import { runBuild } from './build.mjs' + +runBuild() diff --git a/packages/components/.scripts/build.mjs b/packages/components/.scripts/build.mjs new file mode 100644 index 00000000..daaddaa1 --- /dev/null +++ b/packages/components/.scripts/build.mjs @@ -0,0 +1,61 @@ +import chalk from 'chalk' +import { execa } from 'execa' + +const commandTag = '[@baseapp-frontend/components]' + +export const runBuild = async (currentBuildProcesses = []) => { + console.log(`${chalk.magenta(`${commandTag} Starting build process...`)}`) + + try { + console.log(chalk.cyanBright(`${commandTag} Running Relay Compiler...`)) + const relayProc = execa('pnpm', ['relay'], { preferLocal: true }) + currentBuildProcesses?.push(relayProc) + await relayProc + console.log(chalk.cyanBright(`${commandTag} Relay compilation completed.`)) + + console.log(chalk.yellowBright(`${commandTag} Running Babel transpiling...`)) + const babelProc = execa('pnpm', ['babel:transpile'], { preferLocal: true }) + currentBuildProcesses?.push(babelProc) + await babelProc + console.log(chalk.yellowBright(`${commandTag} Babel transpilation completed.`)) + + await Promise.all([ + (async () => { + console.log(chalk.yellow(`${commandTag} Running tsup bundling...`)) + const tsupProc = execa('pnpm', ['tsup:bundle', '--silent'], { preferLocal: true }) + currentBuildProcesses?.push(tsupProc) + await tsupProc + console.log(chalk.yellow(`${commandTag} tsup Bundling completed.`)) + })(), + (async () => { + console.log(chalk.blue(`${commandTag} Running type declaration generation...`)) + const tscProc = execa('pnpm', ['tsc:declaration'], { preferLocal: true }) + currentBuildProcesses?.push(tscProc) + await tscProc + console.log(chalk.blue(`${commandTag} Type declarations generated.`)) + + console.log(chalk.cyan(`${commandTag} Copying DTS files...`)) + const copyProc = execa('pnpm', ['copy:dts'], { preferLocal: true }) + currentBuildProcesses?.push(copyProc) + await copyProc + console.log(chalk.cyan(`${commandTag} DTS files copied.`)) + })(), + ]) + + console.log(chalk.hex('#c86c2c')(`${commandTag} Cleaning temporary files...`)) + const cleanProc = execa('pnpm', ['clean:tmp'], { preferLocal: true }) + currentBuildProcesses?.push(cleanProc) + await cleanProc + console.log(chalk.hex('#c86c2c')(`${commandTag} Temporary files cleaned.`)) + + console.log(chalk.green(`${commandTag} Build completed successfully.`)) + } catch (error) { + if (error.signal !== 'SIGTERM') { + console.error(chalk.red(`${commandTag} Build failed:`)) + console.error(chalk.red(error.stderr || error.message)) + } + throw error + } finally { + currentBuildProcesses = [] + } +} diff --git a/packages/components/.scripts/dev-command.mjs b/packages/components/.scripts/dev-command.mjs new file mode 100644 index 00000000..c60cbbff --- /dev/null +++ b/packages/components/.scripts/dev-command.mjs @@ -0,0 +1,100 @@ +import chalk from 'chalk' +import chokidar from 'chokidar' +import path from 'path' +import { fileURLToPath } from 'url' + +import { + cancelCurrentBuild, + getConsumerAppBasePath, + updateConsumerRsync, + waitForReadyFile, +} from '../../../.scripts/command-utils.mjs' +import { runBuild } from './build.mjs' + +const currentDir = path.dirname(fileURLToPath(import.meta.url)) +const rootDir = path.join(currentDir, '..') + +const commandTag = '[@baseapp-frontend/components]' + +let isBuilding = false +let needsRebuild = false +let buildTimeout = null +let currentBuildProcesses = [] + +const runWatchBuild = async () => { + if (isBuilding) { + needsRebuild = true + await cancelCurrentBuild({ currentBuildProcesses, commandTag }) + return + } + + isBuilding = true + + try { + const consumerAppPath = getConsumerAppBasePath() + + const designSystemPath = path.join(rootDir, '..', 'design-system') + const readyFileParentPath = path.join(designSystemPath, 'dist') + await waitForReadyFile({ readyFileParentPath, commandTag }) + + await runBuild(currentBuildProcesses) + + await updateConsumerRsync({ + consumerAppPath, + sourceDist: path.join(rootDir, 'dist/'), + packageName: 'components', + commandTag, + }) + + console.log(`${chalk.magenta(`${commandTag} Watching for file changes...`)}`) + } catch (error) { + if (error.signal !== 'SIGTERM') { + console.error(chalk.red(`${commandTag} Build failed:`)) + console.error(chalk.red(error.stderr || error.message)) + } + } finally { + isBuilding = false + currentBuildProcesses = [] + if (needsRebuild) { + needsRebuild = false + runWatchBuild() + } + } +} + +const watchRegex = /^modules\/(?:.*\/)?(common|web|native)\/.*$/ + +const watcher = chokidar.watch(rootDir, { + ignoreInitial: true, + usePolling: true, + interval: 100, + awaitWriteFinish: { + stabilityThreshold: 500, + pollInterval: 100, + }, + ignored: (filePath, stats) => { + if ( + filePath.includes('node_modules') || + filePath.includes('dist') || + filePath.includes('tmp') + ) { + return true + } + if (stats && stats.isFile()) { + const relative = path.relative(rootDir, filePath).replace(/\\/g, '/') + if (!watchRegex.test(relative)) { + return true + } + } + return false + }, +}) + +watcher.on('all', (event, changedPath) => { + const relativePath = path.relative(rootDir, changedPath).replace(/\\/g, '/') + console.log(`${commandTag} Detected event "${event}" on: ${relativePath}`) + if (buildTimeout) clearTimeout(buildTimeout) + buildTimeout = setTimeout(runWatchBuild, 2000) +}) + +runWatchBuild() diff --git a/packages/components/README.md b/packages/components/README.md index 96f55484..7b0f1d01 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -18,12 +18,12 @@ pnpm install @baseapp-frontend/components ## **What is in here?** -This package contains essential BaseApp modules such as `comments`, `notifications`, `messages` and `navigations`. It also includes Storybook, a tool for component documentation and visualization. To run the Storybook locally, navigate to the package folder and run the following command: +This package contains essential BaseApp modules such as `comments`, `notifications`, `messages` and `navigations`. It also includes Storybook, a tool for component documentation and visualization. To run the Storybook locally, run the following command: ```bash # at root level -pnpm storybook --filter components +pnpm storybook --filter @baseapp-frontend/components ``` ## **Build Process** diff --git a/packages/components/package.json b/packages/components/package.json index 560ec71c..db54b1d9 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -4,13 +4,13 @@ "version": "1.0.7", "sideEffects": false, "scripts": { - "babel:bundle": "babel modules -d tmp-babel --extensions .ts,.tsx --ignore '**/__tests__/**','**/__storybook__/**'", + "babel:transpile": "babel modules -d tmp-babel --extensions .ts,.tsx --ignore '**/__tests__/**','**/__storybook__/**'", "tsup:bundle": "tsup tmp-babel --tsconfig tsconfig.build.json", "tsc:declaration": "tsc -p tsconfig.build.json --emitDeclarationOnly", "copy:dts": "node ../../.scripts/copy-dts.js", "clean:tmp": "rm -rf tmp-babel tmp-dts", - "build": "rm -rf dist && pnpm relay && pnpm babel:bundle && pnpm tsup:bundle && pnpm tsc:declaration && pnpm copy:dts && pnpm clean:tmp", - "dev": "pnpm relay && tsup --watch", + "build": "node .scripts/build-command.mjs", + "dev": "rm -rf dist && node .scripts/dev-command.mjs", "relay": "relay-compiler", "relay-download-schema": "dotenv -- bash -c 'get-graphql-schema \"$NEXT_PUBLIC_RELAY_ENDPOINT\" > schema.graphql'", "relay-update-schema": "pnpm relay-download-schema && pnpm relay", @@ -112,7 +112,7 @@ "@babel/preset-env": "catalog:storybook", "@babel/preset-react": "catalog:storybook", "@babel/preset-typescript": "catalog:storybook", - "@baseapp-frontend/config": "workspace:*", + "@baseapp-frontend/config": "workspace:^", "@baseapp-frontend/test": "workspace:*", "@baseapp-frontend/tsconfig": "workspace:*", "@chromatic-com/storybook": "catalog:storybook", @@ -144,6 +144,8 @@ "babel-jest": "catalog:test", "babel-loader": "catalog:storybook", "babel-plugin-relay": "catalog:graphql", + "chalk": "catalog:dev-tools", + "chokidar": "catalog:dev-tools", "css-loader": "catalog:storybook", "cypress": "catalog:test", "cypress-plugin-steps": "catalog:test", @@ -151,6 +153,7 @@ "dotenv": "^16.4.5", "dotenv-cli": "^7.4.2", "eslint-plugin-storybook": "catalog:lint", + "execa": "catalog:dev-tools", "get-graphql-schema": "catalog:graphql", "html-webpack-plugin": "catalog:storybook", "jest": "catalog:test", diff --git a/packages/components/tsup.config.ts b/packages/components/tsup.config.ts index 5393cb3a..5f6d40c2 100644 --- a/packages/components/tsup.config.ts +++ b/packages/components/tsup.config.ts @@ -4,7 +4,7 @@ import { defineConfig } from 'tsup' export default defineConfig((options) => ({ - clean: false, + clean: true, dts: false, entry: ['./modules/**/(common|web|native)/index.ts'], esbuildOptions(esbuildOptions) { diff --git a/packages/design-system/.scripts/build-command.mjs b/packages/design-system/.scripts/build-command.mjs new file mode 100644 index 00000000..8fa16390 --- /dev/null +++ b/packages/design-system/.scripts/build-command.mjs @@ -0,0 +1,3 @@ +import { runBuild } from './build.mjs' + +runBuild() diff --git a/packages/design-system/.scripts/build.mjs b/packages/design-system/.scripts/build.mjs new file mode 100644 index 00000000..21638dc9 --- /dev/null +++ b/packages/design-system/.scripts/build.mjs @@ -0,0 +1,57 @@ +import chalk from 'chalk' +import { execa } from 'execa' +import fs from 'fs/promises' +import path from 'path' +import { fileURLToPath } from 'url' + +const commandTag = '[@baseapp-frontend/design-system]' + +export const runBuild = async (currentBuildProcesses = []) => { + const currentDir = path.dirname(fileURLToPath(import.meta.url)) + const rootDir = path.join(currentDir, '..') + const readyFilePath = path.join(rootDir, 'dist', 'build.ready') + + console.log(`${chalk.magenta(`${commandTag} Starting build process...`)}`) + + try { + await Promise.all([ + (async () => { + console.log(chalk.yellow(`${commandTag} Running tsup bundling...`)) + const tsupProc = execa('pnpm', ['tsup:bundle', '--silent'], { preferLocal: true }) + currentBuildProcesses?.push(tsupProc) + await tsupProc + console.log(chalk.yellow(`${commandTag} Bundling completed.`)) + })(), + (async () => { + console.log(chalk.blue(`${commandTag} Running type declaration generation...`)) + const tscProc = execa('pnpm', ['tsc:declaration'], { preferLocal: true }) + currentBuildProcesses?.push(tscProc) + await tscProc + console.log(chalk.blue(`${commandTag} Type declarations generated.`)) + + console.log(chalk.cyan(`${commandTag} Copying DTS files...`)) + const copyProc = execa('pnpm', ['copy:dts'], { preferLocal: true }) + currentBuildProcesses?.push(copyProc) + await copyProc + console.log(chalk.cyan(`${commandTag} DTS files copied.`)) + })(), + ]) + + console.log(chalk.hex('#c86c2c')(`${commandTag} Cleaning temporary files...`)) + const cleanProc = execa('pnpm', ['clean:tmp'], { preferLocal: true }) + currentBuildProcesses?.push(cleanProc) + await cleanProc + console.log(chalk.hex('#c86c2c')(`${commandTag} Temporary files cleaned.`)) + + await fs.writeFile(readyFilePath, 'ready', 'utf8') + console.log(chalk.green(`${commandTag} Build completed successfully.`)) + } catch (error) { + if (error.signal !== 'SIGTERM') { + console.error(chalk.red(`${commandTag} Build failed:`)) + console.error(chalk.red(error.stderr || error.message)) + } + throw error + } finally { + currentBuildProcesses = [] + } +} diff --git a/packages/design-system/.scripts/dev-command.mjs b/packages/design-system/.scripts/dev-command.mjs new file mode 100644 index 00000000..0acf0c2c --- /dev/null +++ b/packages/design-system/.scripts/dev-command.mjs @@ -0,0 +1,107 @@ +import chalk from 'chalk' +import chokidar from 'chokidar' +import path from 'path' +import { fileURLToPath } from 'url' + +import { + cancelCurrentBuild, + cleanupReadyFile, + getConsumerAppBasePath, + updateConsumerRsync, +} from '../../../.scripts/command-utils.mjs' +import { runBuild } from './build.mjs' + +const currentDir = path.dirname(fileURLToPath(import.meta.url)) +const rootDir = path.join(currentDir, '..') + +const readyFilePath = path.join(rootDir, 'dist', 'build.ready') + +const commandTag = '[@baseapp-frontend/design-system]' + +let isBuilding = false +let needsRebuild = false +let buildTimeout = null +let currentBuildProcesses = [] + +process.on('SIGINT', async () => { + const readyFilePath = path.join(rootDir, 'dist', 'build.ready') + await cleanupReadyFile({ readyFilePath }) + if (buildTimeout) clearTimeout(buildTimeout) + process.exit() +}) + +const runWatchBuild = async () => { + await cleanupReadyFile({ readyFilePath }) + + if (isBuilding) { + needsRebuild = true + await cancelCurrentBuild({ commandTag, currentBuildProcesses }) + return + } + + isBuilding = true + + try { + const consumerAppPath = getConsumerAppBasePath() + + await runBuild(currentBuildProcesses) + + await updateConsumerRsync({ + commandTag, + consumerAppPath, + packageName: 'design-system', + sourceDist: path.join(rootDir, 'dist/'), + }) + + console.log(`${chalk.magenta(`${commandTag} Watching for file changes...`)}`) + } catch (error) { + if (error.signal !== 'SIGTERM') { + console.error(chalk.red(`${commandTag} Build failed:`)) + console.error(chalk.red(error.stderr || error.message)) + } + } finally { + isBuilding = false + currentBuildProcesses = [] + if (needsRebuild) { + needsRebuild = false + runWatchBuild() + } + } +} + +const watchRegex = /^(components|hooks|layouts|providers|styles|utils)\/(common|web|native)(\/.*)?$/ + +const watcher = chokidar.watch(rootDir, { + ignoreInitial: true, + usePolling: true, + interval: 100, + awaitWriteFinish: { + stabilityThreshold: 500, + pollInterval: 100, + }, + ignored: (filePath, stats) => { + if ( + filePath.includes('node_modules') || + filePath.includes('dist') || + filePath.includes('tmp') + ) { + return true + } + if (stats && stats.isFile()) { + const relative = path.relative(rootDir, filePath).replace(/\\/g, '/') + if (!watchRegex.test(relative)) { + return true + } + } + return false + }, +}) + +watcher.on('all', (event, changedPath) => { + const relativePath = path.relative(rootDir, changedPath).replace(/\\/g, '/') + console.log(`${commandTag} Detected event "${event}" on: ${relativePath}`) + if (buildTimeout) clearTimeout(buildTimeout) + buildTimeout = setTimeout(runWatchBuild, 2000) +}) + +runWatchBuild() diff --git a/packages/design-system/README.md b/packages/design-system/README.md index 52a36195..9ada520e 100644 --- a/packages/design-system/README.md +++ b/packages/design-system/README.md @@ -6,19 +6,19 @@ This package defines our design system configuration (e.g. color pallete, typogr ## **What is in here?** -This package contains essential BaseApp modules such as `comments`, `notifications`, `messages` and `navigations`. It also includes Storybook, a tool for component documentation and visualization. To run the Storybook locally, navigate to the package folder and run the following command: +This package contains essential BaseApp modules such as `comments`, `notifications`, `messages` and `navigations`. It also includes Storybook, a tool for component documentation and visualization. To run the Storybook locally, run the following command: ```bash # at root level -pnpm storybook --filter design-system +pnpm storybook --filter @baseapp-frontend/design-system ``` ## **Build Process** We use a hybrid build pipeline combining `tsup`, and `TypeScript Compiler` to balance type accuracy and modern bundling: -1. **Source Code:** Original TypeScript/React files with Relay GraphQL queries. +1. **Source Code:** Original TypeScript/React files. 2. **tsup Bundling:** diff --git a/packages/design-system/package.json b/packages/design-system/package.json index def0a90a..6e8c4aed 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -8,8 +8,8 @@ "tsc:declaration": "tsc -p tsconfig.build.json --emitDeclarationOnly", "copy:dts": "node ../../.scripts/copy-dts.js", "clean:tmp": "rm -rf tmp-dts", - "build": "rm -rf dist && pnpm tsup:bundle && pnpm tsc:declaration && pnpm copy:dts && pnpm clean:tmp", - "dev": "tsup --watch", + "build": "node .scripts/build-command.mjs", + "dev": "rm -rf dist && node .scripts/dev-command.mjs", "lint": "eslint . --ext .tsx --ext .ts && tsc --noEmit", "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", "storybook": "storybook dev -p 6006", @@ -113,9 +113,12 @@ "@types/react": "catalog:react18", "@types/react-dom": "catalog:react18", "autoprefixer": "catalog:tailwind", + "chalk": "catalog:dev-tools", + "chokidar": "catalog:dev-tools", "chokidar-cli": "^3.0.0", "css-loader": "catalog:storybook", "eslint-plugin-storybook": "catalog:lint", + "execa": "catalog:dev-tools", "postcss": "catalog:tailwind", "postcss-loader": "catalog:storybook", "storybook": "catalog:storybook", diff --git a/packages/design-system/tsup.config.ts b/packages/design-system/tsup.config.ts index ebc0b986..5a8cb165 100644 --- a/packages/design-system/tsup.config.ts +++ b/packages/design-system/tsup.config.ts @@ -4,7 +4,7 @@ import { defineConfig } from 'tsup' export default defineConfig((options) => ({ - clean: false, + clean: true, dts: false, entry: ['./(components|hooks|layouts|providers|styles|utils)/(common|web|native)/**/index.ts'], esbuildOptions(esbuildOptions) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1aa818a0..ac75699c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,6 +60,16 @@ catalogs: zustand: specifier: 4.5.2 version: 4.5.2 + dev-tools: + chalk: + specifier: ^5.4.1 + version: 5.4.1 + chokidar: + specifier: ^4.0.3 + version: 4.0.3 + execa: + specifier: ^9.5.2 + version: 9.5.2 graphql: '@types/react-relay': specifier: 16.0.6 @@ -395,9 +405,18 @@ importers: '@types/node': specifier: 'catalog:' version: 22.7.2 + chalk: + specifier: ^5.4.1 + version: 5.4.1 + chokidar: + specifier: ^4.0.3 + version: 4.0.3 eslint: specifier: catalog:lint version: 8.57.1 + execa: + specifier: ^9.5.2 + version: 9.5.2 husky: specifier: catalog:lint version: 9.1.7 @@ -632,7 +651,7 @@ importers: specifier: catalog:storybook version: 7.26.0(@babel/core@7.26.8) '@baseapp-frontend/config': - specifier: workspace:* + specifier: workspace:^ version: link:../config '@baseapp-frontend/test': specifier: workspace:* @@ -727,6 +746,12 @@ importers: babel-plugin-relay: specifier: catalog:graphql version: 17.0.0 + chalk: + specifier: catalog:dev-tools + version: 5.4.1 + chokidar: + specifier: catalog:dev-tools + version: 4.0.3 css-loader: specifier: catalog:storybook version: 7.1.2(webpack@5.93.0) @@ -748,6 +773,9 @@ importers: eslint-plugin-storybook: specifier: catalog:lint version: 0.8.0(eslint@8.57.1)(typescript@5.4.5) + execa: + specifier: catalog:dev-tools + version: 9.5.2 get-graphql-schema: specifier: catalog:graphql version: 2.1.2 @@ -1031,6 +1059,12 @@ importers: autoprefixer: specifier: catalog:tailwind version: 10.4.19(postcss@8.4.38) + chalk: + specifier: catalog:dev-tools + version: 5.4.1 + chokidar: + specifier: catalog:dev-tools + version: 4.0.3 chokidar-cli: specifier: ^3.0.0 version: 3.0.0 @@ -1040,6 +1074,9 @@ importers: eslint-plugin-storybook: specifier: catalog:lint version: 0.8.0(eslint@8.57.1)(typescript@5.4.5) + execa: + specifier: catalog:dev-tools + version: 9.5.2 postcss: specifier: catalog:tailwind version: 8.4.38 @@ -2284,12 +2321,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-react@7.26.3': - resolution: {integrity: sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.26.0': resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} engines: {node: '>=6.9.0'} @@ -4086,12 +4117,19 @@ packages: '@rushstack/eslint-patch@1.10.5': resolution: {integrity: sha512-kkKUDVlII2DQiKy7UstOR1ErJP8kUKAQ4oa+SQtM0K+lPdmmjj0YnnxBgtTVYH7mUKtbsxeFC9y0AmK7Yb78/A==} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@segment/loosely-validate-event@2.0.0': resolution: {integrity: sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==} '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -5473,6 +5511,10 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -6520,6 +6562,10 @@ packages: resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + execa@9.5.2: + resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} + engines: {node: ^18.19.0 || >=20.5.0} + executable@4.1.1: resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} engines: {node: '>=4'} @@ -6713,6 +6759,10 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6953,6 +7003,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -7234,6 +7288,10 @@ packages: resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} engines: {node: '>=14.18.0'} + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + humps@2.0.1: resolution: {integrity: sha512-E0eIbrFWUhwfXJmsbdjRQFQPrl5pTEoKlz163j1mTqqUnU9PgR4AgB8AIITzuB3vLBdxZXyZ9TDIrwB2OASz4g==} @@ -7478,6 +7536,10 @@ packages: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-plain-object@2.0.4: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} @@ -7509,6 +7571,10 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -7532,6 +7598,10 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -8587,6 +8657,10 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -8798,6 +8872,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parse-png@2.1.0: resolution: {integrity: sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==} engines: {node: '>=10'} @@ -9148,6 +9226,10 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -10050,6 +10132,10 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -10531,6 +10617,10 @@ packages: resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unique-filename@3.0.0: resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -11015,6 +11105,10 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + zod@3.24.1: resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} @@ -11097,7 +11191,7 @@ snapshots: '@babel/generator@7.17.7': dependencies: - '@babel/types': 7.17.0 + '@babel/types': 7.26.8 jsesc: 2.5.2 source-map: 0.5.7 @@ -11933,18 +12027,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-react@7.26.3(@babel/core@7.26.8)': - dependencies: - '@babel/core': 7.26.8 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.8) - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.8) - '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.8) - '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.8) - transitivePeerDependencies: - - supports-color - '@babel/preset-typescript@7.26.0(@babel/core@7.26.8)': dependencies: '@babel/core': 7.26.8 @@ -12309,7 +12391,7 @@ snapshots: dependencies: '@babel/runtime': 7.26.7 '@emotion/babel-plugin': 11.13.5 - '@emotion/cache': 11.11.0 + '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) '@emotion/utils': 1.4.2 @@ -12940,7 +13022,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -12953,14 +13035,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -12988,14 +13070,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -13024,7 +13106,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -13042,7 +13124,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.7.2 + '@types/node': 22.13.1 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -13064,7 +13146,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -13134,7 +13216,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.7.2 + '@types/node': 22.13.1 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -14646,6 +14728,8 @@ snapshots: '@rushstack/eslint-patch@1.10.5': {} + '@sec-ant/readable-stream@0.4.1': {} + '@segment/loosely-validate-event@2.0.0': dependencies: component-type: 1.2.2 @@ -14653,6 +14737,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -15443,7 +15529,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.13.1 '@types/hammerjs@2.0.46': {} @@ -15478,7 +15564,7 @@ snapshots: '@types/jsdom@20.0.1': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.13.1 '@types/tough-cookie': 4.0.5 parse5: 7.2.1 @@ -16263,7 +16349,7 @@ snapshots: '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.8) '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.8) '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.8) - '@babel/preset-react': 7.26.3(@babel/core@7.26.8) + '@babel/preset-react': 7.25.9(@babel/core@7.26.8) '@babel/preset-typescript': 7.26.0(@babel/core@7.26.8) '@react-native/babel-preset': 0.76.7(@babel/core@7.26.8)(@babel/preset-env@7.26.0(@babel/core@7.26.8)) babel-plugin-react-native-web: 0.19.13 @@ -16507,6 +16593,8 @@ snapshots: chalk@5.3.0: {} + chalk@5.4.1: {} + char-regex@1.0.2: {} chardet@0.7.0: {} @@ -16864,12 +16952,12 @@ snapshots: css-loader@6.11.0(webpack@5.93.0(@swc/core@1.10.15(@swc/helpers@0.5.15))): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: @@ -16877,12 +16965,12 @@ snapshots: css-loader@6.11.0(webpack@5.93.0): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: @@ -16890,12 +16978,12 @@ snapshots: css-loader@7.1.2(webpack@5.93.0(@swc/core@1.10.15(@swc/helpers@0.5.15))): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: @@ -16903,12 +16991,12 @@ snapshots: css-loader@7.1.2(webpack@5.93.0): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.7.1 optionalDependencies: @@ -17777,6 +17865,21 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 3.0.0 + execa@9.5.2: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + executable@4.1.1: dependencies: pify: 2.3.0 @@ -18173,6 +18276,10 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -18453,6 +18560,11 @@ snapshots: get-stream@6.0.1: {} + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.3 @@ -18771,6 +18883,8 @@ snapshots: human-signals@4.3.1: {} + human-signals@8.0.0: {} + humps@2.0.1: {} husky@9.1.7: {} @@ -18785,9 +18899,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.4.38): + icss-utils@5.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 ieee754@1.2.1: {} @@ -18972,6 +19086,8 @@ snapshots: is-plain-obj@3.0.0: {} + is-plain-obj@4.1.0: {} + is-plain-object@2.0.4: dependencies: isobject: 3.0.1 @@ -18997,6 +19113,8 @@ snapshots: is-stream@3.0.0: {} + is-stream@4.0.1: {} + is-string@1.1.1: dependencies: call-bound: 1.0.3 @@ -19020,6 +19138,8 @@ snapshots: is-unicode-supported@0.1.0: {} + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -19127,7 +19247,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3(babel-plugin-macros@3.1.0) @@ -19216,7 +19336,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)): dependencies: '@babel/core': 7.26.8 '@jest/test-sequencer': 29.7.0 @@ -19241,8 +19361,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.7.2 - ts-node: 10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5) + '@types/node': 22.13.1 + ts-node: 10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -19303,7 +19423,7 @@ snapshots: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 22.7.2 + '@types/node': 22.13.1 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -19327,7 +19447,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.7.2 + '@types/node': 22.13.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -19366,7 +19486,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -19401,7 +19521,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -19429,7 +19549,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.2 @@ -19475,7 +19595,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -19494,7 +19614,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.13.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -19509,7 +19629,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 22.7.2 + '@types/node': 22.13.1 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -20448,6 +20568,11 @@ snapshots: dependencies: path-key: 4.0.0 + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -20706,6 +20831,8 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-ms@4.0.0: {} + parse-png@2.1.0: dependencies: pngjs: 3.4.0 @@ -20803,24 +20930,24 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-import@15.1.0(postcss@8.4.38): + postcss-import@15.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.4.38): + postcss-js@4.0.1(postcss@8.4.49): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.38 + postcss: 8.4.49 - postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)): dependencies: lilconfig: 3.1.3 yaml: 2.7.0 optionalDependencies: - postcss: 8.4.38 + postcss: 8.4.49 ts-node: 10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5) postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.4.38)(yaml@2.7.0): @@ -20853,30 +20980,30 @@ snapshots: transitivePeerDependencies: - typescript - postcss-modules-extract-imports@3.1.0(postcss@8.4.38): + postcss-modules-extract-imports@3.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 - postcss-modules-local-by-default@4.2.0(postcss@8.4.38): + postcss-modules-local-by-default@4.2.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.4.38): + postcss-modules-scope@3.2.1(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-selector-parser: 7.1.0 - postcss-modules-values@4.0.0(postcss@8.4.38): + postcss-modules-values@4.0.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 - postcss-nested@6.2.0(postcss@8.4.38): + postcss-nested@6.2.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.0.10: @@ -20967,6 +21094,10 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + proc-log@4.2.0: {} process-nextick-args@2.0.1: {} @@ -22105,6 +22236,8 @@ snapshots: strip-final-newline@3.0.0: {} + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -22196,11 +22329,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.4.38 - postcss-import: 15.1.0(postcss@8.4.38) - postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)) - postcss-nested: 6.2.0(postcss@8.4.38) + postcss: 8.4.49 + postcss-import: 15.1.0(postcss@8.4.49) + postcss-js: 4.0.1(postcss@8.4.49) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.10.15(@swc/helpers@0.5.15))(@types/node@22.13.1)(typescript@5.4.5)) + postcss-nested: 6.2.0(postcss@8.4.49) postcss-selector-parser: 6.1.2 resolve: 1.22.10 sucrase: 3.35.0 @@ -22635,6 +22768,8 @@ snapshots: unicode-property-aliases-ecmascript@2.1.0: {} + unicorn-magic@0.3.0: {} + unique-filename@3.0.0: dependencies: unique-slug: 4.0.0 @@ -23256,6 +23391,8 @@ snapshots: yoctocolors-cjs@2.1.2: {} + yoctocolors@2.1.1: {} + zod@3.24.1: {} zustand@4.5.2(@types/react@18.3.3)(react@18.3.1): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index abf09a2a..6e8b2ab6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -30,6 +30,20 @@ catalogs: react-dom: 18.3.1 react: 18.3.1 + react-native-core: + "@gorhom/bottom-sheet": ^5.0.6 + "@react-navigation/drawer": ^7.0.19 + "@react-navigation/native": ^7.0.6 + expo-constants: ~17.0.3 + expo-file-system: ~18.0.6 + expo-image-picker: ~16.0.4 + expo-router: ~4.0.5 + expo-secure-store: ~14.0.0 + react-native-paper: ^5.12.5 + react-native-reanimated: ~3.16.3 + react-native: 0.76.3 + react-native-gesture-handler: ~2.20.2 + graphql: "@types/react-relay": 16.0.6 "@types/relay-runtime": 17.0.3 @@ -129,16 +143,7 @@ catalogs: prettier-plugin-tailwindcss: ^0.6.3 prettier: ^3.3.3 - react-native-core: - "@gorhom/bottom-sheet": ^5.0.6 - "@react-navigation/drawer": ^7.0.19 - "@react-navigation/native": ^7.0.6 - expo-constants: ~17.0.3 - expo-file-system: ~18.0.6 - expo-image-picker: ~16.0.4 - expo-router: ~4.0.5 - expo-secure-store: ~14.0.0 - react-native-paper: ^5.12.5 - react-native-reanimated: ~3.16.3 - react-native: 0.76.3 - react-native-gesture-handler: ~2.20.2 + dev-tools: + chalk: ^5.4.1 + chokidar: ^4.0.3 + execa: ^9.5.2 diff --git a/turbo.json b/turbo.json index 387bbcef..a54ee2fb 100644 --- a/turbo.json +++ b/turbo.json @@ -3,6 +3,7 @@ "ui": "tui", "tasks": { "dev": { + "env": ["BASEAPP_FRONTEND_TEMPLATE_PATH"], "cache": false, "persistent": true },