Project Directory Structure
Relevant source files
The following files were used as context for generating this wiki page:- package.json
- packages/avatar/build.config.ts
- packages/avatar/package.json
- packages/avatar/src/core/utils/svg.ts
- packages/avatar/src/open-peeps/components/face.ts
- packages/avatar/src/open-peeps/components/facialHair.ts
- packages/avatar/src/open-peeps/index.ts
- packages/avatar/test/unit/index.test.ts
- tsconfig.json
- vitest.config.ts
The avatar project is a monorepo managed by pnpm. Its structure is designed to separate the core avatar generation library from the overall project configuration, tooling, and testing setup. The primary package, @nextorders/avatar, resides within the packages directory and contains all the source code for generating SVG avatars.
This document outlines the high-level directory structure, detailing the purpose of key configuration files at the root level and the internal structure of the main @nextorders/avatar package. The focus is on how files are organized to support development, testing, and the final build process.
Monorepo Root
The root of the repository contains configuration files that govern the entire monorepo, including workspace management, dependencies, scripts, and testing strategies.
This diagram shows the key files and directories at the root level.
Sources: package.json, tsconfig.json, vitest.config.ts
Key Configuration Files
| File | Description |
|---|---|
package.json | Defines the monorepo, its name (@nextorders/avatar-monorepo), private status, and pnpm as the package manager. It contains scripts for building, linting, testing, and releasing all packages in the workspace. |
tsconfig.json | The root TypeScript configuration. It sets the compiler target to es2022, defines module resolution as Bundler, and configures path aliases like @nextorders/avatar to point to the source code in packages/avatar/index.ts. |
vitest.config.ts | Configures the Vitest test runner. It defines two separate test projects: unit for Node.js environment tests and browser for tests that run in a headless Chromium instance via Playwright. |
Sources: package.json:2-4, 15-30, tsconfig.json:2-20, vitest.config.ts:4-39
Root Scripts
The root package.json orchestrates tasks across the entire monorepo using pnpm -r (recursive).
| Script | Action |
|---|---|
build | Executes the build script in each package of the workspace. |
test | Runs all tests (unit and browser) using Vitest. |
lint | Runs ESLint on the entire codebase. |
typecheck | Executes the typecheck script in each package to ensure type safety. |
check:full | A comprehensive check that runs linting, type checking, and all tests. |
Sources: package.json:15-27
The @nextorders/avatar Package
This is the core library package located at packages/avatar. It is responsible for generating the SVG avatars and is published to npm as @nextorders/avatar.
Package Structure
The diagram below illustrates the structure of the avatar package.
Build Configuration
The build process is defined in packages/avatar/build.config.ts and uses unbuild.
// packages/avatar/build.config.ts
import { copyFileSync } from 'node:fs'
import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
declaration: true,
entries: [
'src/index',
],
hooks: {
'build:before': () => {
// Copy README.md from root
copyFileSync('../../README.md', './README.md')
},
},
})
declaration: true: Generates TypeScript declaration files (.d.ts).entries: ['src/index']: Specifies the main entry point for the build.hooks: Abuild:beforehook copies the rootREADME.mdfile into the package directory before the build starts, ensuring it's included in the published package.
The output of this process is placed in the dist/ directory, as specified by the files array in packages/avatar/package.json.
Sources: packages/avatar/build.config.ts:4-15, packages/avatar/package.json:28-30
Source Code (src/)
The src/ directory contains the logic for avatar generation. It is organized into a core module for generic utilities and an open-peeps module for a specific avatar style.
src/core/utils/svg.ts
This file provides helper functions for manipulating the generated SVG string. These functions are used to apply user-defined options like scale, rotation, and background color.
| Function | Description |
|---|---|
addBackground | Adds a solid or gradient background layer to the SVG. |
addScale | Applies a scaling transformation to the SVG body. |
addTranslate | Applies a translation (move) transformation. |
addRotate | Applies a rotation transformation around the center of the viewbox. |
addFlip | Flips the SVG horizontally. |
addViewboxMask | Adds a mask to create rounded corners. |
createAttrString | Constructs the attribute string for the root <svg> element. |
Sources: packages/avatar/src/core/utils/svg.ts:26-108
src/open-peeps/
This directory implements the "Open Peeps" avatar style.
index.ts: This is the entry point for theopen-peepsstyle. Thecreatefunction assembles the final avatar. It gets the components (like face, hair) and colors, then constructs the SVG body by embedding the component SVG strings within<g>tags with appropriate transforms.components/: This sub-directory holds the raw SVG path data for each part of the avatar. Files likeface.tsandfacialHair.tsexport aComponentGroupobject, which is a collection of functions. Each function (e.g.,smile,chin) returns a string of SVG<path>elements.
The following diagram shows the avatar creation flow for the open-peeps style.
Testing (test/)
The test/ directory contains tests for the avatar package. The structure mirrors the testing strategy defined in vitest.config.ts.
test/unit/index.test.ts: Contains unit tests that run in a Node.js environment. These tests verify the corecreateAvatarfunction. They check for correct function definition, error handling when aseedis not provided, and whether the output SVG string contains expected path data for specific options.
// packages/avatar/test/unit/index.test.ts
it('should return error if seed is not provided', () => {
try {
// @ts-expect-error seed is required
createAvatar({})
} catch (error) {
expect(error).toBeInstanceOf(Error)
}
})
it('should return correct result with emotion 5', () => {
const result = createAvatar({ seed: 'random4', emotion: 5 })
expect(result).toContain('m157.9 261 2-.5c7.7-2 15.7-5.4')
})
Sources: packages/avatar/test/unit/index.test.ts:14-26, vitest.config.ts:8-15