@codedrifters/configulator 0.0.75 → 0.0.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,24 @@
1
- # Project Setup Guide: Projen & Configulator
1
+ # Configulator
2
+
3
+ A library of [Projen](https://projen.io/) components used by CodeDrifters to manage repository configuration across various projects. Configulator extends standard Projen configurations with our preferred defaults and provides company-specific components and workflows.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [What is Projen?](#what-is-projen)
9
+ - [What is Configulator?](#what-is-configulator)
10
+ - [Project Types](#project-types)
11
+ - [MonorepoProject](#monorepoproject)
12
+ - [TypeScriptProject](#typescriptproject)
13
+ - [Usage Patterns](#usage-patterns)
14
+ - [Configuration Options](#configuration-options)
15
+ - [Turbo Repo](#turbo-repo)
16
+ - [PNPM Workspace](#pnpm-workspace)
17
+ - [File Management Rules](#file-management-rules)
18
+ - [Workflow Tips](#workflow-tips)
19
+ - [API Reference](#api-reference)
20
+ - [Troubleshooting](#troubleshooting)
21
+ - [Additional Resources](#additional-resources)
2
22
 
3
23
  ## Overview
4
24
 
@@ -23,11 +43,10 @@ Projen is a project generator and configuration management tool that:
23
43
 
24
44
  ## What is Configulator?
25
45
 
26
- configulator is Code Drifters' custom extension of Projen. It:
46
+ Configulator is CodeDrifters' custom extension of Projen. It:
27
47
 
28
48
  - Extends standard Projen configurations with our preferred defaults
29
49
  - Provides company-specific components and workflows
30
- - Currently at version 0.48 (alpha/internal use)
31
50
  - Available as an npm package: `@codedrifters/configulator`
32
51
 
33
52
  ### Why We Built It
@@ -39,84 +58,454 @@ Instead of setting up each new project from scratch (90% identical setup repeate
39
58
  - Maintain standardized tooling across all projects
40
59
  - Receive updates to common configurations automatically
41
60
 
42
- ## Creating a New Project
61
+ ## Project Types
43
62
 
44
- ### Basic Setup
63
+ Configulator provides two main project types designed for monorepo workflows:
45
64
 
46
- ```bash
47
- npx projen new --from @codedrifters/Configulator@0.48 monorepo
48
- ```
65
+ ### MonorepoProject
66
+
67
+ **MonorepoProject** extends Projen's `TypeScriptAppProject` and is designed specifically for monorepo root projects. It provides all the infrastructure needed to manage a monorepo with multiple sub-projects.
68
+
69
+ #### When to Use It
49
70
 
50
- This creates a project with:
71
+ Use `MonorepoProject` for:
72
+ - Root-level monorepo configuration
73
+ - Managing workspace-wide settings (PNPM, Turborepo, VS Code)
74
+ - Defining shared dependency catalogs
75
+ - Configuring build workflows for the entire monorepo
51
76
 
52
- - TypeScript configuration
53
- - Prettier for code formatting
54
- - VS Code settings
55
- - GitHub workflows (build, PR checks)
56
- - Weekly dependency upgrade workflow
77
+ #### Key Features
57
78
 
58
- ### Minimal Configuration Example
79
+ - **PNPM Workspace Management**: Automatically generates and manages `pnpm-workspace.yaml`
80
+ - **Turborepo Integration**: Built-in support for Turborepo with remote caching capabilities
81
+ - **VS Code Configuration**: Automatic VS Code settings for consistent development experience
82
+ - **Default Catalog**: Pre-configured catalog of common dependency versions (AWS CDK, Projen, Constructs, Turbo)
83
+ - **Build Workflow Configuration**: GitHub Actions workflows with Turborepo support
84
+ - **TypeScript Configuration**: Pre-configured TypeScript with sensible defaults
59
85
 
60
- The simplest `.projenrc.ts` file:
86
+ #### Basic Example
61
87
 
62
88
  ```typescript
63
- import { MonorepoProject } from '@codedrifters/Configulator';
89
+ import { MonorepoProject } from '@codedrifters/configulator';
64
90
 
65
91
  const project = new MonorepoProject({
66
- name: 'my-project-name'
92
+ name: 'my-monorepo'
67
93
  });
68
94
 
69
95
  project.synth();
70
96
  ```
71
97
 
72
- ## Important: File Management Rules
98
+ #### Advanced Example with Remote Cache
73
99
 
74
- ### DO NOT Edit These Files Directly
100
+ ```typescript
101
+ import { MonorepoProject } from '@codedrifters/configulator';
75
102
 
76
- Projen manages many files automatically. Never edit these files by hand:
103
+ const project = new MonorepoProject({
104
+ name: 'my-monorepo',
105
+
106
+ turboOptions: {
107
+ remoteCacheOptions: {
108
+ profileName: 'profile-prod-000000000000-us-east-1',
109
+ oidcRole: 'arn:aws:iam::000000000000:role/TurborepoRemoteCachingRole',
110
+ endpointParamName: '/TURBOREPO/ENDPOINT/PARAMETER',
111
+ tokenParamName: '/TURBOREPO/TOKEN/PARAMETER',
112
+ teamName: 'prod',
113
+ },
114
+ },
115
+
116
+ pnpmOptions: {
117
+ pnpmWorkspaceOptions: {
118
+ onlyBuiltDependencies: ['@swc/core', 'esbuild', 'unrs-resolver'],
119
+ },
120
+ },
121
+ });
77
122
 
78
- - Configuration files (`.prettierrc`, `tsconfig.json`, etc.)
79
- - GitHub workflows (`.github/workflows/*`)
80
- - Build scripts
81
- - Most files listed in `.projen/files.json`
123
+ project.synth();
124
+ ```
82
125
 
83
- ### Exception: package.json
126
+ #### Configuration Options
84
127
 
85
- `package.json` is special - Projen reads, modifies, and writes it back, preserving some manual changes. However, you should still manage dependencies through Projen config, not by editing `package.json` directly.
128
+ The `MonorepoProject` accepts all options from `TypeScriptProjectOptions` plus:
86
129
 
87
- ### Adding Dependencies
130
+ | Option | Type | Default | Description |
131
+ |--------|------|---------|-------------|
132
+ | `name` | `string` | **Required** | Project name |
133
+ | `turbo` | `boolean` | `true` | Enable Turborepo support |
134
+ | `turboOptions` | `TurboRepoOptions` | `undefined` | Turborepo configuration including remote cache options |
135
+ | `pnpmOptions.version` | `string` | `VERSION.PNPM_VERSION` | PNPM version to use |
136
+ | `pnpmOptions.pnpmWorkspaceOptions` | `PnpmWorkspaceOptions` | See below | PNPM workspace configuration |
88
137
 
89
- **WRONG:**
90
- ```bash
91
- npm install some-package
138
+ **Default Behavior:**
139
+ - `projenrcTs: true` - Uses TypeScript for projen configuration
140
+ - `prettier: true` - Enables Prettier formatting
141
+ - `licensed: false` - No license by default
142
+ - `sampleCode: false` - No sample code generated
143
+ - `jest: false` - Jest disabled at root level
144
+ - `release: false` - Root project is not released
145
+ - `depsUpgrade: false` - No automatic dependency upgrades at root
146
+ - `disableTsconfigDev: true` - No tsconfig.dev.json at root
147
+ - `packageManager: NodePackageManager.PNPM` - PNPM is mandatory
148
+ - `defaultReleaseBranch: "main"` - Standard branch name
149
+
150
+ The root project automatically includes `@codedrifters/configulator` and `constructs` as dev dependencies.
151
+
152
+ ### TypeScriptProject
153
+
154
+ **TypeScriptProject** extends Projen's `TypeScriptProject` with CodeDrifters defaults. It's designed for sub-projects within a monorepo or standalone TypeScript projects.
155
+
156
+ #### When to Use It
157
+
158
+ Use `TypeScriptProject` for:
159
+ - Sub-projects within a monorepo (most common use case)
160
+ - Standalone TypeScript libraries or applications
161
+ - Packages that will be published to NPM
162
+ - Projects that need consistent testing, linting, and build configuration
163
+
164
+ #### Key Features
165
+
166
+ - **Automatic PNPM Version Inheritance**: Inherits PNPM version from parent `MonorepoProject` when used as a sub-project
167
+ - **SWC for Testing**: Uses `@swc/jest` instead of `ts-jest` for faster test execution
168
+ - **Prettier Integration**: Automatic Prettier configuration
169
+ - **Jest Configuration**: External Jest config file (not in package.json) with sensible defaults
170
+ - **Automatic Turborepo Integration**: Automatically configures Turborepo tasks when parent has TurboRepo enabled
171
+ - **Catalog Dependency Support**: Can use catalog dependencies defined in parent workspace
172
+ - **Release Support**: Built-in support for NPM releases with continuous deployment triggers
173
+
174
+ #### Basic Example
175
+
176
+ ```typescript
177
+ import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
178
+
179
+ // Root project
180
+ const root = new MonorepoProject({
181
+ name: 'my-monorepo'
182
+ });
183
+
184
+ // Sub-project
185
+ const myPackage = new TypeScriptProject({
186
+ name: 'my-package',
187
+ packageName: '@myorg/my-package',
188
+ outdir: 'packages/my-package',
189
+ parent: root,
190
+ description: 'My awesome package',
191
+ deps: ['some-dependency'],
192
+ devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
193
+ });
194
+
195
+ root.synth();
92
196
  ```
93
197
 
94
- **CORRECT:** Add dependencies in your `.projenrc.ts` configuration and run `npx projen`.
198
+ #### Example with Release Configuration
95
199
 
96
- ## Understanding the Monorepo Configuration
200
+ ```typescript
201
+ import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
97
202
 
98
- Our monorepo projects are configured in `.projenrc/` folder with multiple files:
203
+ const root = new MonorepoProject({
204
+ name: 'my-monorepo'
205
+ });
99
206
 
207
+ const constructs = new TypeScriptProject({
208
+ name: '@codedrifters/constructs',
209
+ packageName: '@codedrifters/constructs',
210
+ outdir: 'packages/@codedrifters/constructs',
211
+ description: 'Constructs frequently used in CodeDrifter projects.',
212
+ repository: 'https://github.com/codedrifters/packages',
213
+ authorName: 'CodeDrifters',
214
+ authorOrganization: true,
215
+ licensed: false,
216
+ parent: root,
217
+
218
+ deps: [
219
+ '@aws-sdk/client-dynamodb',
220
+ '@types/aws-lambda',
221
+ 'change-case@^4.0',
222
+ 'type-fest@^4',
223
+ ],
224
+ devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
225
+ peerDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
226
+
227
+ release: true,
228
+ releaseToNpm: true,
229
+ });
230
+
231
+ root.synth();
100
232
  ```
101
- .projenrc/
102
- ├── index.ts # Main configuration
103
- ├── root.ts # Root project config
104
- ├── sample-app.ts # Example sub-project
105
- └── ehr-project.ts # Actual sub-project
233
+
234
+ #### Parent-Child Relationship
235
+
236
+ When `TypeScriptProject` is created with a `parent` that is a `MonorepoProject`:
237
+
238
+ 1. **PNPM Version**: Automatically inherits the PNPM version from the parent
239
+ 2. **Workspace Integration**: Automatically added to the parent's PNPM workspace
240
+ 3. **Turborepo Integration**: If parent has Turborepo enabled, the sub-project automatically gets Turborepo task configuration
241
+ 4. **Catalog Dependencies**: Can reference catalog dependencies defined in the parent's workspace
242
+ 5. **Dependency Upgrade Exclusions**: Automatically excludes catalog-managed dependencies from upgrade workflows
243
+
244
+ #### Configuration Options
245
+
246
+ The `TypeScriptProject` accepts all options from Projen's `TypeScriptProjectOptions` with these defaults:
247
+
248
+ | Option | Type | Default | Description |
249
+ |--------|------|---------|-------------|
250
+ | `name` | `string` | **Required** | Project name |
251
+ | `packageName` | `string` | Same as `name` | NPM package name |
252
+ | `outdir` | `string` | `"."` | Output directory (required for sub-projects) |
253
+ | `parent` | `MonorepoProject` | `undefined` | Parent monorepo project (recommended) |
254
+ | `defaultReleaseBranch` | `string` | `"main"` | Default release branch |
255
+ | `packageManager` | `NodePackageManager` | `PNPM` | Package manager (always PNPM) |
256
+ | `prettier` | `boolean` | `true` | Enable Prettier |
257
+ | `sampleCode` | `boolean` | `false` | Generate sample code |
258
+ | `release` | `boolean` | `false` | Enable NPM releases |
259
+ | `licensed` | `boolean` | `false` | Include license (unless `license` option provided) |
260
+
261
+ **Jest Configuration:**
262
+ - Uses external `jest.config.json` file
263
+ - Configured to use `@swc/jest` for faster compilation
264
+ - Test files in `src/` directory
265
+ - ESLint rule `import/no-extraneous-dependencies` disabled for test files
266
+
267
+ **NPM Ignore:**
268
+ - Automatically ignores `*.spec.*`, `*.test.*`, and `__fixtures__` patterns
269
+
270
+ **Release Configuration:**
271
+ - Uses continuous release trigger
272
+ - Only releases when package directory content changes
273
+ - Release path based on `outdir`
274
+
275
+ ## Usage Patterns
276
+
277
+ ### Monorepo Setup Pattern
278
+
279
+ The most common pattern is to create a monorepo with a root project and multiple sub-projects:
280
+
281
+ 1. **Create the root project** using `MonorepoProject`:
282
+
283
+ ```typescript
284
+ // projenrc/root-project.ts
285
+ import { MonorepoProject } from '@codedrifters/configulator';
286
+
287
+ export const configureRootProject = () => {
288
+ const project = new MonorepoProject({
289
+ name: 'my-monorepo',
290
+ turboOptions: {
291
+ remoteCacheOptions: {
292
+ profileName: 'my-profile',
293
+ oidcRole: 'arn:aws:iam::123456789012:role/TurborepoRole',
294
+ endpointParamName: '/TURBOREPO/ENDPOINT',
295
+ tokenParamName: '/TURBOREPO/TOKEN',
296
+ teamName: 'my-team',
297
+ },
298
+ },
299
+ });
300
+
301
+ return project;
302
+ };
303
+ ```
304
+
305
+ 2. **Add sub-projects** using `TypeScriptProject`:
306
+
307
+ ```typescript
308
+ // projenrc/my-package.ts
309
+ import { MonorepoProject } from '@codedrifters/configulator';
310
+ import { TypeScriptProject } from '@codedrifters/configulator';
311
+
312
+ export const configureMyPackage = (parent: MonorepoProject) => {
313
+ const myPackage = new TypeScriptProject({
314
+ name: 'my-package',
315
+ packageName: '@myorg/my-package',
316
+ outdir: 'packages/my-package',
317
+ description: 'My package description',
318
+ parent,
319
+ deps: ['dependency-1', 'dependency-2'],
320
+ devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
321
+ });
322
+
323
+ return { myPackage };
324
+ };
325
+ ```
326
+
327
+ 3. **Wire everything together** in your main projenrc file:
328
+
329
+ ```typescript
330
+ // .projenrc.ts or projenrc/index.ts
331
+ import { configureRootProject } from './projenrc/root-project';
332
+ import { configureMyPackage } from './projenrc/my-package';
333
+
334
+ const root = configureRootProject();
335
+ const { myPackage } = configureMyPackage(root);
336
+
337
+ root.synth();
338
+ ```
339
+
340
+ ### Standalone Project Pattern
341
+
342
+ You can also use `TypeScriptProject` without a parent for standalone projects:
343
+
344
+ ```typescript
345
+ import { TypeScriptProject } from '@codedrifters/configulator';
346
+
347
+ const project = new TypeScriptProject({
348
+ name: 'standalone-project',
349
+ packageName: '@myorg/standalone-project',
350
+ description: 'A standalone TypeScript project',
351
+ deps: ['some-dependency'],
352
+ });
353
+
354
+ project.synth();
106
355
  ```
107
356
 
108
- ### Key Configuration Options
357
+ Note: Without a parent, the project will use the default PNPM version from Configulator's version constants.
358
+
359
+ ### Dependency Management
360
+
361
+ > **⚠️ Important:** All dependencies must be configured through Projen configuration files (`.projenrc.ts` or `projenrc/*.ts`), never by manually running package manager commands like `npm install`, `pnpm add`, or `yarn add`. Manual installation will create conflicts with Projen-managed files and may be overwritten when you run `npx projen`.
362
+
363
+ #### Using Catalog Dependencies
364
+
365
+ The `MonorepoProject` automatically sets up a default catalog with common dependencies:
366
+
367
+ ```typescript
368
+ // Defined in MonorepoProject defaults
369
+ defaultCatalog: {
370
+ 'aws-cdk': VERSION.AWS_CDK_CLI_VERSION,
371
+ 'aws-cdk-lib': VERSION.AWS_CDK_LIB_VERSION,
372
+ 'projen': VERSION.PROJEN_VERSION,
373
+ 'constructs': VERSION.AWS_CONSTRUCTS_VERSION,
374
+ 'turbo': VERSION.TURBO_VERSION,
375
+ }
376
+ ```
377
+
378
+ Sub-projects can reference these using the `catalog:` protocol:
379
+
380
+ ```typescript
381
+ const myPackage = new TypeScriptProject({
382
+ // ... other options
383
+ devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
384
+ peerDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
385
+ });
386
+ ```
109
387
 
110
- The root configuration extends Projen's TypeScript app with our defaults:
388
+ #### Workspace Dependencies
111
389
 
112
- - **TypeScript:** Enabled by default
113
- - **Prettier:** Enabled for consistent formatting
114
- - **License:** Unlicensed (for client work)
115
- - **Package Manager:** PNPM (mandatory)
116
- - **Default Branch:** main
117
- - **Sample Code:** Disabled (no hello-world examples)
118
- - **Dependency Upgrades:** Configured but can be adjusted
119
- - **Turbo Repo:** Enabled for monorepo builds
390
+ Sub-projects can depend on other packages in the same monorepo:
391
+
392
+ ```typescript
393
+ const packageB = new TypeScriptProject({
394
+ // ... other options
395
+ deps: ['@myorg/package-a@workspace:*'],
396
+ });
397
+ ```
398
+
399
+ #### Custom Catalog
400
+
401
+ You can also define custom catalogs in the `MonorepoProject`:
402
+
403
+ ```typescript
404
+ const root = new MonorepoProject({
405
+ name: 'my-monorepo',
406
+ pnpmOptions: {
407
+ pnpmWorkspaceOptions: {
408
+ defaultCatalog: {
409
+ 'react': '^18.0.0',
410
+ 'typescript': '^5.0.0',
411
+ },
412
+ namedCatalogs: {
413
+ frontend: {
414
+ 'react': '^18.0.0',
415
+ 'react-dom': '^18.0.0',
416
+ },
417
+ backend: {
418
+ 'express': '^4.18.0',
419
+ },
420
+ },
421
+ },
422
+ },
423
+ });
424
+ ```
425
+
426
+ Then reference them in sub-projects:
427
+
428
+ ```typescript
429
+ // Default catalog
430
+ deps: ['react@catalog:react']
431
+
432
+ // Named catalog
433
+ deps: ['react@catalog:frontend/react']
434
+ ```
435
+
436
+ ### Turborepo Integration
437
+
438
+ When you create a `MonorepoProject` with `turbo: true` (the default), Turborepo is automatically configured. Sub-projects created with `TypeScriptProject` automatically get Turborepo task configuration if their parent has Turborepo enabled.
439
+
440
+ The integration includes:
441
+ - Automatic task definitions (compile, test, package)
442
+ - Output directory configuration (`dist/**`, `lib/**`)
443
+ - Remote cache support (when configured)
444
+ - Build workflow integration
445
+
446
+ See the [Turbo Repo](#turbo-repo) section for more details.
447
+
448
+ ## Configuration Options
449
+
450
+ ### MonorepoProjectOptions
451
+
452
+ Extends `TypeScriptProjectOptions` with:
453
+
454
+ ```typescript
455
+ interface MonorepoProjectOptions {
456
+ name: string; // Required
457
+ turbo?: boolean; // Default: true
458
+ turboOptions?: TurboRepoOptions;
459
+ pnpmOptions?: {
460
+ version?: string;
461
+ pnpmWorkspaceOptions?: PnpmWorkspaceOptions;
462
+ };
463
+ // ... all TypeScriptProjectOptions
464
+ }
465
+ ```
466
+
467
+ ### TypeScriptProjectOptions
468
+
469
+ Extends Projen's `TypeScriptProjectOptions` with CodeDrifters defaults. See the [TypeScriptProject](#typescriptproject) section for details.
470
+
471
+ ### TurboRepoOptions
472
+
473
+ ```typescript
474
+ interface TurboRepoOptions {
475
+ turboVersion?: string;
476
+ remoteCacheOptions?: RemoteCacheOptions;
477
+ extends?: Array<string>;
478
+ globalDependencies?: Array<string>;
479
+ globalEnv?: Array<string>;
480
+ globalPassThroughEnv?: Array<string>;
481
+ ui?: 'tui' | 'stream';
482
+ envMode?: string;
483
+ // ... and more
484
+ }
485
+
486
+ interface RemoteCacheOptions {
487
+ profileName: string;
488
+ oidcRole: string;
489
+ endpointParamName: string;
490
+ tokenParamName: string;
491
+ teamName: string;
492
+ }
493
+ ```
494
+
495
+ ### PnpmWorkspaceOptions
496
+
497
+ ```typescript
498
+ interface PnpmWorkspaceOptions {
499
+ fileName?: string; // Default: 'pnpm-workspace.yaml'
500
+ minimumReleaseAge?: number; // Minutes, default: ONE_DAY (1440)
501
+ minimumReleaseAgeExclude?: Array<string>; // Default: ['@codedrifters/*']
502
+ onlyBuiltDependencies?: Array<string>;
503
+ ignoredBuiltDependencies?: Array<string>;
504
+ subprojects?: Array<string>;
505
+ defaultCatalog?: { [key: string]: string };
506
+ namedCatalogs?: { [catalogName: string]: { [dependencyName: string]: string } };
507
+ }
508
+ ```
120
509
 
121
510
  ## Turbo Repo
122
511
 
@@ -139,6 +528,25 @@ Turbo Repo is a build system for monorepos that:
139
528
 
140
529
  **Remote Cache:** Build outputs stored in S3 (not Vercel) for team sharing
141
530
 
531
+ ### Configuration
532
+
533
+ Turborepo is automatically enabled in `MonorepoProject` (can be disabled with `turbo: false`). Configure it using the `turboOptions`:
534
+
535
+ ```typescript
536
+ const project = new MonorepoProject({
537
+ name: 'my-monorepo',
538
+ turboOptions: {
539
+ remoteCacheOptions: {
540
+ profileName: 'my-profile',
541
+ oidcRole: 'arn:aws:iam::123456789012:role/TurborepoRole',
542
+ endpointParamName: '/TURBOREPO/ENDPOINT',
543
+ tokenParamName: '/TURBOREPO/TOKEN',
544
+ teamName: 'my-team',
545
+ },
546
+ },
547
+ });
548
+ ```
549
+
142
550
  ### Running Locally
143
551
 
144
552
  Before using Turbo Repo locally, you need AWS credentials:
@@ -156,150 +564,170 @@ Before using Turbo Repo locally, you need AWS credentials:
156
564
  - **Selective Rebuilds:** Only changed code rebuilds, not the entire monorepo
157
565
  - **Local + CI Sharing:** Cache between your machine and GitHub Actions
158
566
 
159
- ## Automatic Dependency Updates
160
-
161
- Our projects include a GitHub Action that:
162
-
163
- - Runs weekly (configurable)
164
- - Checks for updated packages
165
- - Opens a PR with updates
166
- - Runs all tests automatically
567
+ ## PNPM Workspace
167
568
 
168
- **Review Process:** If tests pass, the updates are likely safe to merge. Good test coverage makes this workflow reliable.
569
+ The `MonorepoProject` automatically generates and manages `pnpm-workspace.yaml`. This file:
169
570
 
170
- ## VS Code Configuration
571
+ - Lists all sub-projects in the `packages` array
572
+ - Configures PNPM settings like `minimumReleaseAge` and `onlyBuiltDependencies`
573
+ - Defines dependency catalogs for version management
171
574
 
172
- Projects automatically include VS Code settings:
575
+ ### Workspace Structure
173
576
 
174
- - Tab size: 2 spaces
175
- - Format on save with Prettier
176
- - Recommended extensions (can be customized)
577
+ The workspace file is auto-generated and lists all sub-projects:
177
578
 
178
- Settings are in `.vscode/settings.json` (auto-generated).
579
+ ```yaml
580
+ packages:
581
+ - 'packages/package-a'
582
+ - 'packages/package-b'
583
+ - 'apps/frontend'
584
+ ```
179
585
 
180
- ## Custom Components
586
+ Sub-projects are automatically discovered from `project.subprojects` and any additional paths specified in `pnpmWorkspaceOptions.subprojects`.
181
587
 
182
- You can create custom components for repeated configurations. Examples:
588
+ ### Configuration
183
589
 
184
- ### Storybook Component
590
+ Configure the workspace through `pnpmOptions.pnpmWorkspaceOptions`:
185
591
 
186
592
  ```typescript
187
- // Adds Storybook with all necessary config
188
- import { StorybookComponent } from './.projenrc/storybook';
189
-
190
- // In your project config
191
- new StorybookComponent(project);
593
+ const project = new MonorepoProject({
594
+ name: 'my-monorepo',
595
+ pnpmOptions: {
596
+ pnpmWorkspaceOptions: {
597
+ minimumReleaseAge: MIMIMUM_RELEASE_AGE.ONE_DAY,
598
+ minimumReleaseAgeExclude: ['@codedrifters/*'],
599
+ onlyBuiltDependencies: ['@swc/core', 'esbuild'],
600
+ defaultCatalog: {
601
+ 'react': '^18.0.0',
602
+ },
603
+ },
604
+ },
605
+ });
192
606
  ```
193
607
 
194
- ### Playwright Component
195
-
196
- ```typescript
197
- // Adds Playwright testing framework
198
- import { PlaywrightComponent } from './.projenrc/playwright';
608
+ ## File Management Rules
199
609
 
200
- new PlaywrightComponent(project);
201
- ```
610
+ ### DO NOT Edit These Files Directly
202
611
 
203
- Components encapsulate:
612
+ Projen manages many files automatically. Never edit these files by hand:
204
613
 
205
- - Dependencies (dev and production)
206
- - Configuration files
614
+ - Configuration files (`.prettierrc`, `tsconfig.json`, etc.)
615
+ - GitHub workflows (`.github/workflows/*`)
207
616
  - Build scripts
208
- - Sample files (one-time generation)
209
-
210
- ### Sample Files vs Config Files
211
-
212
- **Config Files:** Deleted and regenerated on every `npx projen` run
213
-
214
- - YAML, JSON, INI files
215
- - TypeScript configs
216
- - Build configurations
217
-
218
- **Sample Files:** Generated once, never overwritten
219
-
220
- - Starter code templates
221
- - Example tests
222
- - Framework setup files (e.g., Storybook's `main.ts`)
223
-
224
- Sample files give you a starting point but won't receive updates. Modify them freely for your needs.
617
+ - Most files listed in `.projen/files.json`
225
618
 
226
- ## Working with Monorepos
619
+ ### Exception: package.json
227
620
 
228
- ### Workspace Structure
621
+ `package.json` is special - Projen reads, modifies, and writes it back, preserving some manual changes. However, you should still manage dependencies through Projen config, not by editing `package.json` directly.
229
622
 
230
- Our monorepos use PNPM workspaces. The workspace file (`.pnpm-workspace.yaml`) is auto-generated and lists all sub-projects:
623
+ ### Adding Dependencies
231
624
 
232
- ```yaml
233
- packages:
234
- - 'packages/package-a'
235
- - 'packages/package-b'
236
- - 'apps/frontend'
625
+ **WRONG:**
626
+ ```bash
627
+ npm install some-package
237
628
  ```
238
629
 
239
- ### Opening Sub-Projects in VS Code
240
-
241
- You can:
242
-
243
- - Open the entire monorepo (uses root `.vscode/`)
244
- - Open individual sub-projects (can have their own `.vscode/`)
630
+ **CORRECT:** Add dependencies in your `.projenrc.ts` configuration and run `npx projen`.
245
631
 
246
- For individual projects, consider creating VS Code workspace files (advanced topic).
632
+ ```typescript
633
+ const project = new TypeScriptProject({
634
+ // ... other options
635
+ deps: ['some-package'],
636
+ });
637
+ ```
247
638
 
248
639
  ## Workflow Tips
249
640
 
250
641
  ### Before Committing
251
642
 
252
- Run Turbo build locally to cache everything:
643
+ Run Turbo build locally (from monorepo root) to cache everything:
253
644
 
254
645
  ```bash
255
646
  # This caches outputs that GitHub Actions can reuse
256
- turbo run build
647
+ pnpm build:all
257
648
  ```
258
649
 
259
650
  Then commit and push. Your GitHub build will be much faster.
260
651
 
261
652
  ### Adding New Packages
262
653
 
263
- 1. Edit your `.projenrc.ts` configuration
264
- 2. Add dependencies using the project API
265
- 3. Run `npx projen` to regenerate configs
266
- 4. Commit the changes
654
+ 1. Create a new configuration file in `projenrc/` (e.g., `projenrc/new-package.ts`)
655
+ 2. Export a function that creates a `TypeScriptProject` with the parent as a parameter
656
+ 3. Import and call it in your main projenrc file
657
+ 4. Run `npx projen` to regenerate configs
658
+ 5. Commit the changes
659
+
660
+ Example:
661
+
662
+ ```typescript
663
+ // projenrc/new-package.ts
664
+ import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
665
+
666
+ export const configureNewPackage = (parent: MonorepoProject) => {
667
+ return new TypeScriptProject({
668
+ name: 'new-package',
669
+ packageName: '@myorg/new-package',
670
+ outdir: 'packages/new-package',
671
+ parent,
672
+ deps: ['dependency'],
673
+ });
674
+ };
675
+ ```
267
676
 
268
677
  ### Updating Configulator
269
678
 
270
679
  To receive updates from Configulator in your project:
271
680
 
272
- 1. Update the version in `versions.ts`
681
+ 1. Update the version in your projenrc definition file
273
682
  2. Run `npx projen`
274
683
  3. Review and test changes
275
684
  4. Commit
276
685
 
277
- ## Common Patterns
686
+ ## API Reference
278
687
 
279
- ### Version Management
688
+ ### MonorepoProject
689
+
690
+ **Constructor:**
691
+ ```typescript
692
+ new MonorepoProject(options: MonorepoProjectOptions)
693
+ ```
280
694
 
281
- Versions for specific packages can be pinned in a `versions.ts` file:
695
+ **Key Properties:**
696
+ - `pnpmVersion: string` - The PNPM version used by the monorepo
282
697
 
698
+ **Key Methods:**
699
+ - Inherits all methods from `TypeScriptAppProject`
700
+
701
+ ### TypeScriptProject
702
+
703
+ **Constructor:**
283
704
  ```typescript
284
- export const versions = {
285
- turbo: '1.10.0',
286
- pnpm: '8.6.0',
287
- node: '18.x'
288
- };
705
+ new TypeScriptProject(options: TypeScriptProjectOptions)
289
706
  ```
290
707
 
291
- This gives you explicit control over important dependencies while letting others auto-update.
708
+ **Key Methods:**
709
+ - `addDeps(...deps: string[])` - Add runtime dependencies
710
+ - `addDevDeps(...deps: string[])` - Add dev dependencies
711
+ - `addPeerDeps(...deps: string[])` - Add peer dependencies
712
+ - Inherits all methods from Projen's `TypeScriptProject`
292
713
 
293
- ### AWS Profiles Setup
714
+ ### PnpmWorkspace
294
715
 
295
- For Turbo Repo caching and CDK deployment, set up AWS profiles:
716
+ **Static Method:**
717
+ ```typescript
718
+ PnpmWorkspace.of(project: Project): PnpmWorkspace | undefined
719
+ ```
296
720
 
297
- ```bash
298
- # Run the appropriate setup script
299
- ./scripts/aws-profile-turbo-repo.sh
721
+ Returns the PnpmWorkspace component from a project if it exists.
722
+
723
+ ### TurboRepo
724
+
725
+ **Static Method:**
726
+ ```typescript
727
+ TurboRepo.of(project: Project): TurboRepo | undefined
300
728
  ```
301
729
 
302
- These create temporary credentials (~8 hours) using SSO - much safer than long-lived access keys.
730
+ Returns the TurboRepo component from a project if it exists.
303
731
 
304
732
  ## Troubleshooting
305
733
 
@@ -320,36 +748,19 @@ Check that you haven't manually edited generated files. If you have, run `npx pr
320
748
 
321
749
  Don't mix `npm install` with Projen. Always add dependencies through configuration.
322
750
 
323
- ## Next Steps
751
+ **Sub-project not appearing in workspace**
324
752
 
325
- - Learn about CDK setup for AWS deployments
326
- - Explore creating custom components for your team's needs
327
- - Review project-specific configurations in existing repos (on-site, openhigh)
328
- - Set up AWS profiles for Turbo Repo remote caching
753
+ - Ensure the sub-project has `parent` set to the MonorepoProject
754
+ - Ensure `outdir` is set correctly
755
+ - Run `npx projen` to regenerate the workspace file
329
756
 
330
757
  ## Additional Resources
331
758
 
332
759
  - **Projen Documentation:** https://projen.io
333
760
  - **Turbo Repo Docs:** https://turbo.build/repo/docs
334
- - **Code Drifters Configulator:** https://www.npmjs.com/package/@codedrifters/configulator
761
+ - **PNPM Workspaces:** https://pnpm.io/workspaces
762
+ - **Code Drifters Configulator:** https://www.npmjs.com/package/@codedrifters/packages
335
763
 
336
764
  ---
337
765
 
338
766
  **Remember:** The goal is consistency and automation. Let the tools manage the boilerplate so you can focus on building features.
339
-
340
- # **ARCHIVE FROM INITIAL SETUP**
341
- ## Configulator
342
-
343
- A library of [Projen](https://projen.io/) components used by CodeDrifters to manage repository configuration across various projects.
344
-
345
- ## Usage
346
-
347
- To init a monorepo you can use:
348
-
349
- `npx projen new --from @codedrifters/configulator monorepo`
350
-
351
- For a specific version, use:
352
-
353
- `npx projen new --from @codedrifters/configulator@0.0.15 monorepo`
354
-
355
- These docs are a work in progress and very light currently.