@codedrifters/configulator 0.0.74 → 0.0.76

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,452 @@ 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
199
+
200
+ ```typescript
201
+ import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
202
+
203
+ const root = new MonorepoProject({
204
+ name: 'my-monorepo'
205
+ });
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();
232
+ ```
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();
355
+ ```
356
+
357
+ Note: Without a parent, the project will use the default PNPM version from Configulator's version constants.
358
+
359
+ ### Dependency Management
360
+
361
+ #### Using Catalog Dependencies
362
+
363
+ The `MonorepoProject` automatically sets up a default catalog with common dependencies:
364
+
365
+ ```typescript
366
+ // Defined in MonorepoProject defaults
367
+ defaultCatalog: {
368
+ 'aws-cdk': VERSION.AWS_CDK_CLI_VERSION,
369
+ 'aws-cdk-lib': VERSION.AWS_CDK_LIB_VERSION,
370
+ 'projen': VERSION.PROJEN_VERSION,
371
+ 'constructs': VERSION.AWS_CONSTRUCTS_VERSION,
372
+ 'turbo': VERSION.TURBO_VERSION,
373
+ }
374
+ ```
375
+
376
+ Sub-projects can reference these using the `catalog:` protocol:
377
+
378
+ ```typescript
379
+ const myPackage = new TypeScriptProject({
380
+ // ... other options
381
+ devDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
382
+ peerDeps: ['aws-cdk-lib@catalog:', 'constructs@catalog:'],
383
+ });
384
+ ```
385
+
386
+ #### Workspace Dependencies
387
+
388
+ Sub-projects can depend on other packages in the same monorepo:
389
+
390
+ ```typescript
391
+ const packageB = new TypeScriptProject({
392
+ // ... other options
393
+ deps: ['@myorg/package-a@workspace:*'],
394
+ });
395
+ ```
95
396
 
96
- ## Understanding the Monorepo Configuration
397
+ #### Custom Catalog
97
398
 
98
- Our monorepo projects are configured in `.projenrc/` folder with multiple files:
399
+ You can also define custom catalogs in the `MonorepoProject`:
99
400
 
401
+ ```typescript
402
+ const root = new MonorepoProject({
403
+ name: 'my-monorepo',
404
+ pnpmOptions: {
405
+ pnpmWorkspaceOptions: {
406
+ defaultCatalog: {
407
+ 'react': '^18.0.0',
408
+ 'typescript': '^5.0.0',
409
+ },
410
+ namedCatalogs: {
411
+ frontend: {
412
+ 'react': '^18.0.0',
413
+ 'react-dom': '^18.0.0',
414
+ },
415
+ backend: {
416
+ 'express': '^4.18.0',
417
+ },
418
+ },
419
+ },
420
+ },
421
+ });
100
422
  ```
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
423
+
424
+ Then reference them in sub-projects:
425
+
426
+ ```typescript
427
+ // Default catalog
428
+ deps: ['react@catalog:react']
429
+
430
+ // Named catalog
431
+ deps: ['react@catalog:frontend/react']
106
432
  ```
107
433
 
108
- ### Key Configuration Options
434
+ ### Turborepo Integration
435
+
436
+ 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.
109
437
 
110
- The root configuration extends Projen's TypeScript app with our defaults:
438
+ The integration includes:
439
+ - Automatic task definitions (compile, test, package)
440
+ - Output directory configuration (`dist/**`, `lib/**`)
441
+ - Remote cache support (when configured)
442
+ - Build workflow integration
111
443
 
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
444
+ See the [Turbo Repo](#turbo-repo) section for more details.
445
+
446
+ ## Configuration Options
447
+
448
+ ### MonorepoProjectOptions
449
+
450
+ Extends `TypeScriptProjectOptions` with:
451
+
452
+ ```typescript
453
+ interface MonorepoProjectOptions {
454
+ name: string; // Required
455
+ turbo?: boolean; // Default: true
456
+ turboOptions?: TurboRepoOptions;
457
+ pnpmOptions?: {
458
+ version?: string;
459
+ pnpmWorkspaceOptions?: PnpmWorkspaceOptions;
460
+ };
461
+ // ... all TypeScriptProjectOptions
462
+ }
463
+ ```
464
+
465
+ ### TypeScriptProjectOptions
466
+
467
+ Extends Projen's `TypeScriptProjectOptions` with CodeDrifters defaults. See the [TypeScriptProject](#typescriptproject) section for details.
468
+
469
+ ### TurboRepoOptions
470
+
471
+ ```typescript
472
+ interface TurboRepoOptions {
473
+ turboVersion?: string;
474
+ remoteCacheOptions?: RemoteCacheOptions;
475
+ extends?: Array<string>;
476
+ globalDependencies?: Array<string>;
477
+ globalEnv?: Array<string>;
478
+ globalPassThroughEnv?: Array<string>;
479
+ ui?: 'tui' | 'stream';
480
+ envMode?: string;
481
+ // ... and more
482
+ }
483
+
484
+ interface RemoteCacheOptions {
485
+ profileName: string;
486
+ oidcRole: string;
487
+ endpointParamName: string;
488
+ tokenParamName: string;
489
+ teamName: string;
490
+ }
491
+ ```
492
+
493
+ ### PnpmWorkspaceOptions
494
+
495
+ ```typescript
496
+ interface PnpmWorkspaceOptions {
497
+ fileName?: string; // Default: 'pnpm-workspace.yaml'
498
+ minimumReleaseAge?: number; // Minutes, default: ONE_DAY (1440)
499
+ minimumReleaseAgeExclude?: Array<string>; // Default: ['@codedrifters/*']
500
+ onlyBuiltDependencies?: Array<string>;
501
+ ignoredBuiltDependencies?: Array<string>;
502
+ subprojects?: Array<string>;
503
+ defaultCatalog?: { [key: string]: string };
504
+ namedCatalogs?: { [catalogName: string]: { [dependencyName: string]: string } };
505
+ }
506
+ ```
120
507
 
121
508
  ## Turbo Repo
122
509
 
@@ -139,6 +526,25 @@ Turbo Repo is a build system for monorepos that:
139
526
 
140
527
  **Remote Cache:** Build outputs stored in S3 (not Vercel) for team sharing
141
528
 
529
+ ### Configuration
530
+
531
+ Turborepo is automatically enabled in `MonorepoProject` (can be disabled with `turbo: false`). Configure it using the `turboOptions`:
532
+
533
+ ```typescript
534
+ const project = new MonorepoProject({
535
+ name: 'my-monorepo',
536
+ turboOptions: {
537
+ remoteCacheOptions: {
538
+ profileName: 'my-profile',
539
+ oidcRole: 'arn:aws:iam::123456789012:role/TurborepoRole',
540
+ endpointParamName: '/TURBOREPO/ENDPOINT',
541
+ tokenParamName: '/TURBOREPO/TOKEN',
542
+ teamName: 'my-team',
543
+ },
544
+ },
545
+ });
546
+ ```
547
+
142
548
  ### Running Locally
143
549
 
144
550
  Before using Turbo Repo locally, you need AWS credentials:
@@ -156,150 +562,170 @@ Before using Turbo Repo locally, you need AWS credentials:
156
562
  - **Selective Rebuilds:** Only changed code rebuilds, not the entire monorepo
157
563
  - **Local + CI Sharing:** Cache between your machine and GitHub Actions
158
564
 
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
565
+ ## PNPM Workspace
167
566
 
168
- **Review Process:** If tests pass, the updates are likely safe to merge. Good test coverage makes this workflow reliable.
567
+ The `MonorepoProject` automatically generates and manages `pnpm-workspace.yaml`. This file:
169
568
 
170
- ## VS Code Configuration
569
+ - Lists all sub-projects in the `packages` array
570
+ - Configures PNPM settings like `minimumReleaseAge` and `onlyBuiltDependencies`
571
+ - Defines dependency catalogs for version management
171
572
 
172
- Projects automatically include VS Code settings:
573
+ ### Workspace Structure
173
574
 
174
- - Tab size: 2 spaces
175
- - Format on save with Prettier
176
- - Recommended extensions (can be customized)
575
+ The workspace file is auto-generated and lists all sub-projects:
177
576
 
178
- Settings are in `.vscode/settings.json` (auto-generated).
577
+ ```yaml
578
+ packages:
579
+ - 'packages/package-a'
580
+ - 'packages/package-b'
581
+ - 'apps/frontend'
582
+ ```
179
583
 
180
- ## Custom Components
584
+ Sub-projects are automatically discovered from `project.subprojects` and any additional paths specified in `pnpmWorkspaceOptions.subprojects`.
181
585
 
182
- You can create custom components for repeated configurations. Examples:
586
+ ### Configuration
183
587
 
184
- ### Storybook Component
588
+ Configure the workspace through `pnpmOptions.pnpmWorkspaceOptions`:
185
589
 
186
590
  ```typescript
187
- // Adds Storybook with all necessary config
188
- import { StorybookComponent } from './.projenrc/storybook';
189
-
190
- // In your project config
191
- new StorybookComponent(project);
591
+ const project = new MonorepoProject({
592
+ name: 'my-monorepo',
593
+ pnpmOptions: {
594
+ pnpmWorkspaceOptions: {
595
+ minimumReleaseAge: MIMIMUM_RELEASE_AGE.ONE_DAY,
596
+ minimumReleaseAgeExclude: ['@codedrifters/*'],
597
+ onlyBuiltDependencies: ['@swc/core', 'esbuild'],
598
+ defaultCatalog: {
599
+ 'react': '^18.0.0',
600
+ },
601
+ },
602
+ },
603
+ });
192
604
  ```
193
605
 
194
- ### Playwright Component
195
-
196
- ```typescript
197
- // Adds Playwright testing framework
198
- import { PlaywrightComponent } from './.projenrc/playwright';
606
+ ## File Management Rules
199
607
 
200
- new PlaywrightComponent(project);
201
- ```
608
+ ### DO NOT Edit These Files Directly
202
609
 
203
- Components encapsulate:
610
+ Projen manages many files automatically. Never edit these files by hand:
204
611
 
205
- - Dependencies (dev and production)
206
- - Configuration files
612
+ - Configuration files (`.prettierrc`, `tsconfig.json`, etc.)
613
+ - GitHub workflows (`.github/workflows/*`)
207
614
  - 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.
615
+ - Most files listed in `.projen/files.json`
225
616
 
226
- ## Working with Monorepos
617
+ ### Exception: package.json
227
618
 
228
- ### Workspace Structure
619
+ `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
620
 
230
- Our monorepos use PNPM workspaces. The workspace file (`.pnpm-workspace.yaml`) is auto-generated and lists all sub-projects:
621
+ ### Adding Dependencies
231
622
 
232
- ```yaml
233
- packages:
234
- - 'packages/package-a'
235
- - 'packages/package-b'
236
- - 'apps/frontend'
623
+ **WRONG:**
624
+ ```bash
625
+ npm install some-package
237
626
  ```
238
627
 
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/`)
628
+ **CORRECT:** Add dependencies in your `.projenrc.ts` configuration and run `npx projen`.
245
629
 
246
- For individual projects, consider creating VS Code workspace files (advanced topic).
630
+ ```typescript
631
+ const project = new TypeScriptProject({
632
+ // ... other options
633
+ deps: ['some-package'],
634
+ });
635
+ ```
247
636
 
248
637
  ## Workflow Tips
249
638
 
250
639
  ### Before Committing
251
640
 
252
- Run Turbo build locally to cache everything:
641
+ Run Turbo build locally (from monorepo root) to cache everything:
253
642
 
254
643
  ```bash
255
644
  # This caches outputs that GitHub Actions can reuse
256
- turbo run build
645
+ pnpm build:all
257
646
  ```
258
647
 
259
648
  Then commit and push. Your GitHub build will be much faster.
260
649
 
261
650
  ### Adding New Packages
262
651
 
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
652
+ 1. Create a new configuration file in `projenrc/` (e.g., `projenrc/new-package.ts`)
653
+ 2. Export a function that creates a `TypeScriptProject` with the parent as a parameter
654
+ 3. Import and call it in your main projenrc file
655
+ 4. Run `npx projen` to regenerate configs
656
+ 5. Commit the changes
657
+
658
+ Example:
659
+
660
+ ```typescript
661
+ // projenrc/new-package.ts
662
+ import { MonorepoProject, TypeScriptProject } from '@codedrifters/configulator';
663
+
664
+ export const configureNewPackage = (parent: MonorepoProject) => {
665
+ return new TypeScriptProject({
666
+ name: 'new-package',
667
+ packageName: '@myorg/new-package',
668
+ outdir: 'packages/new-package',
669
+ parent,
670
+ deps: ['dependency'],
671
+ });
672
+ };
673
+ ```
267
674
 
268
675
  ### Updating Configulator
269
676
 
270
677
  To receive updates from Configulator in your project:
271
678
 
272
- 1. Update the version in `versions.ts`
679
+ 1. Update the version in your projenrc definition file
273
680
  2. Run `npx projen`
274
681
  3. Review and test changes
275
682
  4. Commit
276
683
 
277
- ## Common Patterns
684
+ ## API Reference
278
685
 
279
- ### Version Management
686
+ ### MonorepoProject
687
+
688
+ **Constructor:**
689
+ ```typescript
690
+ new MonorepoProject(options: MonorepoProjectOptions)
691
+ ```
280
692
 
281
- Versions for specific packages can be pinned in a `versions.ts` file:
693
+ **Key Properties:**
694
+ - `pnpmVersion: string` - The PNPM version used by the monorepo
282
695
 
696
+ **Key Methods:**
697
+ - Inherits all methods from `TypeScriptAppProject`
698
+
699
+ ### TypeScriptProject
700
+
701
+ **Constructor:**
283
702
  ```typescript
284
- export const versions = {
285
- turbo: '1.10.0',
286
- pnpm: '8.6.0',
287
- node: '18.x'
288
- };
703
+ new TypeScriptProject(options: TypeScriptProjectOptions)
289
704
  ```
290
705
 
291
- This gives you explicit control over important dependencies while letting others auto-update.
706
+ **Key Methods:**
707
+ - `addDeps(...deps: string[])` - Add runtime dependencies
708
+ - `addDevDeps(...deps: string[])` - Add dev dependencies
709
+ - `addPeerDeps(...deps: string[])` - Add peer dependencies
710
+ - Inherits all methods from Projen's `TypeScriptProject`
292
711
 
293
- ### AWS Profiles Setup
712
+ ### PnpmWorkspace
294
713
 
295
- For Turbo Repo caching and CDK deployment, set up AWS profiles:
714
+ **Static Method:**
715
+ ```typescript
716
+ PnpmWorkspace.of(project: Project): PnpmWorkspace | undefined
717
+ ```
296
718
 
297
- ```bash
298
- # Run the appropriate setup script
299
- ./scripts/aws-profile-turbo-repo.sh
719
+ Returns the PnpmWorkspace component from a project if it exists.
720
+
721
+ ### TurboRepo
722
+
723
+ **Static Method:**
724
+ ```typescript
725
+ TurboRepo.of(project: Project): TurboRepo | undefined
300
726
  ```
301
727
 
302
- These create temporary credentials (~8 hours) using SSO - much safer than long-lived access keys.
728
+ Returns the TurboRepo component from a project if it exists.
303
729
 
304
730
  ## Troubleshooting
305
731
 
@@ -320,36 +746,19 @@ Check that you haven't manually edited generated files. If you have, run `npx pr
320
746
 
321
747
  Don't mix `npm install` with Projen. Always add dependencies through configuration.
322
748
 
323
- ## Next Steps
749
+ **Sub-project not appearing in workspace**
324
750
 
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
751
+ - Ensure the sub-project has `parent` set to the MonorepoProject
752
+ - Ensure `outdir` is set correctly
753
+ - Run `npx projen` to regenerate the workspace file
329
754
 
330
755
  ## Additional Resources
331
756
 
332
757
  - **Projen Documentation:** https://projen.io
333
758
  - **Turbo Repo Docs:** https://turbo.build/repo/docs
334
- - **Code Drifters Configulator:** https://www.npmjs.com/package/@codedrifters/configulator
759
+ - **PNPM Workspaces:** https://pnpm.io/workspaces
760
+ - **Code Drifters Configulator:** https://www.npmjs.com/package/@codedrifters/packages
335
761
 
336
762
  ---
337
763
 
338
764
  **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.