@langri-sha/projen-project 0.9.0 → 0.11.0

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/src/index.ts CHANGED
@@ -1,9 +1,10 @@
1
+ import * as path from 'node:path'
2
+
1
3
  import {
2
4
  Project as BaseProject,
3
5
  type ProjectOptions as BaseProjectOptions,
4
6
  IgnoreFile,
5
7
  IgnoreFileOptions,
6
- YamlFile,
7
8
  javascript,
8
9
  } from 'projen'
9
10
 
@@ -30,8 +31,17 @@ import {
30
31
  import { Beachball, BeachballOptions } from '@langri-sha/projen-beachball'
31
32
  import { License } from '@langri-sha/projen-license'
32
33
 
33
- import { ProjenrcFile } from './lib/index.js'
34
+ import { NodePackage, NodePackageOptions, ProjenrcFile } from './lib/index.js'
34
35
  import { JestConfig, JestConfigOptions } from '@langri-sha/projen-jest-config'
36
+ import { Prettier, PrettierOptions } from '@langri-sha/projen-prettier'
37
+ import { ESLint, ESLintOptions } from '@langri-sha/projen-eslint'
38
+ import { LintStaged, LintStagedOptions } from '@langri-sha/projen-lint-staged'
39
+ import { Babel, BabelOptions } from '@langri-sha/projen-babel'
40
+ import {
41
+ PnpmWorkspace,
42
+ PnpmWorkspaceOptions,
43
+ } from '@langri-sha/projen-pnpm-workspace'
44
+ import { SWCConfig, type SWCConfigOptions } from '@langri-sha/projen-swcrc'
35
45
 
36
46
  export * from '@langri-sha/projen-typescript-config'
37
47
 
@@ -40,32 +50,47 @@ export interface ProjectOptions
40
50
  /*
41
51
  * Pass in to set up Beachball.
42
52
  */
43
- beachballOptions?: BeachballOptions
53
+ babel?: BabelOptions
44
54
 
45
55
  /*
46
56
  * Pass in to set up Beachball.
47
57
  */
48
- codeownersOptions?: CodeownersOptions
58
+ beachball?: BeachballOptions
59
+
60
+ /*
61
+ * Pass in to set up Beachball.
62
+ */
63
+ codeowners?: CodeownersOptions
49
64
 
50
65
  /**
51
66
  * EditorConfig options.
52
67
  */
53
- editorConfigOptions?: EditorConfigOptions
68
+ editorConfig?: EditorConfigOptions
69
+
70
+ /**
71
+ * Pass in to configure ESLint.
72
+ */
73
+ eslint?: ESLintOptions
54
74
 
55
75
  /**
56
76
  * Husky options.
57
77
  */
58
- huskyOptions?: HuskyOptions
78
+ husky?: HuskyOptions
59
79
 
60
80
  /**
61
81
  * Configures Jest, when provided.
62
82
  */
63
- jestConfigOptions?: JestConfigOptions
83
+ jestConfig?: JestConfigOptions
84
+
85
+ /**
86
+ * Configures `lint-staged`, when provided.
87
+ */
88
+ lintStaged?: LintStagedOptions
64
89
 
65
90
  /*
66
91
  * Options for the linting synthesized files.
67
92
  */
68
- lintSynthesizedOptions?: LintSynthesizedOptions
93
+ lintSynthesized?: LintSynthesizedOptions
69
94
 
70
95
  /**
71
96
  * Package configuration options.
@@ -77,45 +102,61 @@ export interface ProjectOptions
77
102
  * @default "Current full year"
78
103
  */
79
104
  copyrightYear?: string
80
- } & javascript.NodePackageOptions
105
+ } & NodePackageOptions
106
+
107
+ /*
108
+ * PNPM workspaces to generate, if provided.
109
+ */
110
+ pnpmWorkspace?: PnpmWorkspaceOptions
111
+
112
+ /**
113
+ * Pass in to configure Prettier.
114
+ */
115
+ prettier?: PrettierOptions
81
116
 
82
117
  /**
83
118
  * Pass in to configure NPM ignore options.
84
119
  */
85
- npmIgnoreOptions?: IgnoreFileOptions
120
+ npmIgnore?: IgnoreFileOptions
86
121
 
87
122
  /*
88
123
  * Pass in to configure Renovate.
89
124
  */
90
- renovateOptions?: RenovateOptions
125
+ renovate?: RenovateOptions
126
+
127
+ /*
128
+ * Pass in to configure SWC.
129
+ */
130
+ swcrc?: SWCConfigOptions
91
131
 
92
132
  /**
93
133
  * TypeScript configuration options.
94
134
  */
95
- typeScriptConfigOptions?: TypeScriptConfigOptions
135
+ typeScriptConfig?: TypeScriptConfigOptions
96
136
 
97
137
  /*
98
138
  * Whether to use Terrafom.
99
139
  */
100
140
  withTerraform?: boolean
101
-
102
- /*
103
- * PNPM workspaces to generate.
104
- */
105
- workspaces?: string[]
106
141
  }
107
142
 
108
143
  export class Project extends BaseProject {
144
+ babel?: Babel
109
145
  beachball?: Beachball
110
146
  codeowners?: Codeowners
111
147
  editorConfig?: EditorConfig
148
+ eslint?: ESLint
112
149
  husky?: Husky
113
150
  jestConfig?: JestConfig
114
151
  license?: License
152
+ lintStaged?: LintStaged
115
153
  npmIgnore?: IgnoreFile
116
- package?: javascript.NodePackage
154
+ package?: NodePackage
155
+ pnpmWorkspace?: PnpmWorkspace
156
+ prettier?: Prettier
117
157
  projenrc?: ProjenrcFile
118
158
  renovate?: Renovate
159
+ swcrc?: SWCConfig
119
160
  typeScriptConfig?: TypeScriptConfig
120
161
 
121
162
  constructor(options: ProjectOptions) {
@@ -133,9 +174,10 @@ export class Project extends BaseProject {
133
174
  this.tasks.removeTask('pre-compile')
134
175
  this.tasks.removeTask('watch')
135
176
 
136
- this.#configureProjenrc()
137
177
  this.#configurePackage(options)
138
178
  this.#configureTypeScript(options)
179
+ this.#configureSWC(options)
180
+ this.#configureProjenrc()
139
181
 
140
182
  if (this.parent) {
141
183
  this.tasks.tryFind('default')?.reset()
@@ -143,61 +185,90 @@ export class Project extends BaseProject {
143
185
  this.tasks.tryFind('install:ci')?.reset()
144
186
  }
145
187
 
188
+ this.#configureESLint(options)
189
+ this.#configurePrettier(options)
190
+
191
+ this.#configureBabel(options)
146
192
  this.#configureBeachball(options)
147
193
  this.#configureCodeowners(options)
148
194
  this.#configureEditorConfig(options)
149
195
  this.#configureHusky(options)
150
196
  this.#configureJestConfig(options)
151
197
  this.#configureLicense(options)
198
+ this.#configureLintStaged(options)
152
199
  this.#configureLintSynthesized(options)
153
200
  this.#configureNpmIgnore(options)
201
+ this.#configurePnpmWorkspace(options)
154
202
  this.#configureRenovate(options)
155
- this.#createPnpmWorkspaces(options)
203
+ }
204
+
205
+ override preSynthesize(): void {
206
+ super.preSynthesize()
207
+
208
+ this.#populateTypeScriptProjectReferencesFromDependencies()
209
+ }
210
+
211
+ get allSubprojects(): BaseProject[] {
212
+ return this.root.node
213
+ .findAll(0)
214
+ .filter((node) => node !== this.root)
215
+ .filter((node): node is BaseProject => node instanceof BaseProject)
216
+ }
217
+
218
+ get allSubprojectsKind(): Project[] {
219
+ return this.allSubprojects.filter(
220
+ (project): project is Project => project instanceof Project,
221
+ )
156
222
  }
157
223
 
158
224
  /**
159
225
  * Add a subproject.
160
226
  */
161
- addSubproject(projectOptions: ProjectOptions) {
162
- return new Project({
227
+ addSubproject(
228
+ projectOptions: ProjectOptions,
229
+ ...compose: Array<(project: Project) => void>
230
+ ): Project {
231
+ const project = new Project({
163
232
  parent: this,
164
233
  ...projectOptions,
165
234
  })
235
+
236
+ for (const callback of compose) {
237
+ callback(project)
238
+ }
239
+
240
+ return project
166
241
  }
167
242
 
168
243
  /**
169
244
  * Find a project by it's name, e.g. `@acme/some`.
170
245
  */
171
- findSubproject(name: string): Project {
172
- const subprojects: Array<BaseProject> = []
173
-
174
- const addSubproject = (project: BaseProject) => {
175
- for (const subproject of project.subprojects) {
176
- subprojects.push(subproject)
246
+ findSubproject(name: string): Project | undefined {
247
+ return this.allSubprojectsKind.find((project) => project.name === name)
248
+ }
177
249
 
178
- if (subproject.subprojects.length) {
179
- addSubproject(subproject)
180
- }
181
- }
250
+ #configureBabel({ babel }: ProjectOptions) {
251
+ if (!babel) {
252
+ return
182
253
  }
183
254
 
184
- addSubproject(this.root)
185
-
186
- const result = subprojects.find((subproject) => subproject.name === name)
187
-
188
- if (result instanceof Project) {
189
- return result
255
+ const defaults: BabelOptions = {
256
+ options: {
257
+ presets: ['@langri-sha/babel-preset'],
258
+ },
190
259
  }
191
260
 
192
- throw new Error(`Cannot find subproject ${name}`)
261
+ this.babel = new Babel(this, deepMerge(defaults, babel))
262
+
263
+ this.typeScriptConfig?.addFile(this.babel.path)
193
264
  }
194
265
 
195
- #configureBeachball({ beachballOptions }: ProjectOptions) {
196
- if (!beachballOptions || this.parent) {
266
+ #configureBeachball({ beachball }: ProjectOptions) {
267
+ if (!beachball || this.parent) {
197
268
  return
198
269
  }
199
270
 
200
- const options = deepMerge(beachballOptions, {
271
+ const options = deepMerge(beachball, {
201
272
  branch: 'origin/main',
202
273
  gitTags: false,
203
274
  ignorePatterns: [
@@ -211,11 +282,12 @@ export class Project extends BaseProject {
211
282
 
212
283
  this.beachball = new Beachball(this, options)
213
284
 
285
+ this.prettier?.ignore.addPatterns('CHANGELOG.md')
214
286
  this.package?.addDevDeps('beachball@2.43.1')
215
287
  this.typeScriptConfig?.addFile('beachball.config.js')
216
288
  }
217
289
 
218
- #configureCodeowners({ codeownersOptions }: ProjectOptions) {
290
+ #configureCodeowners({ codeowners: codeownersOptions }: ProjectOptions) {
219
291
  if (!codeownersOptions) {
220
292
  return
221
293
  }
@@ -223,7 +295,9 @@ export class Project extends BaseProject {
223
295
  this.codeowners = new Codeowners(this, codeownersOptions)
224
296
  }
225
297
 
226
- #configureEditorConfig({ editorConfigOptions }: ProjectOptions) {
298
+ #configureEditorConfig({
299
+ editorConfig: editorConfigOptions,
300
+ }: ProjectOptions) {
227
301
  if (!editorConfigOptions || this.parent) {
228
302
  return
229
303
  }
@@ -246,9 +320,31 @@ export class Project extends BaseProject {
246
320
  this,
247
321
  deepMerge(editorConfigOptions ?? {}, defaults),
248
322
  )
323
+
324
+ this.prettier?.ignore.addPatterns('!.editorconfig')
249
325
  }
250
326
 
251
- #configureHusky({ huskyOptions }: ProjectOptions) {
327
+ #configureESLint({ eslint: eslintOptions }: ProjectOptions) {
328
+ if (!eslintOptions) {
329
+ return
330
+ }
331
+
332
+ const defaults: ESLintOptions = {
333
+ filename: 'eslint.config.mjs',
334
+ ignorePatterns: ['.*', 'dist/'],
335
+ extends: '@langri-sha/eslint-config',
336
+ }
337
+
338
+ this.eslint = new ESLint(this, deepMerge(defaults, eslintOptions))
339
+
340
+ if (this.projenrc?.filePath) {
341
+ this.eslint.ignorePatterns.push(`!${this.projenrc.filePath}`)
342
+ }
343
+
344
+ this.typeScriptConfig?.addFile(this.eslint.path)
345
+ }
346
+
347
+ #configureHusky({ husky: huskyOptions }: ProjectOptions) {
252
348
  if (!huskyOptions || this.parent) {
253
349
  return
254
350
  }
@@ -260,12 +356,14 @@ export class Project extends BaseProject {
260
356
  this.tryFindObjectFile('package.json')?.addDeletionOverride('pnpm')
261
357
  }
262
358
 
263
- #configureJestConfig({ jestConfigOptions }: ProjectOptions) {
359
+ #configureJestConfig({ jestConfig: jestConfigOptions }: ProjectOptions) {
264
360
  if (!jestConfigOptions || this.parent) {
265
361
  return
266
362
  }
267
363
 
268
364
  this.jestConfig = new JestConfig(this, jestConfigOptions)
365
+
366
+ this.typeScriptConfig?.addFile(this.jestConfig.path)
269
367
  }
270
368
 
271
369
  #configureLicense({ package: pkg }: ProjectOptions) {
@@ -292,33 +390,59 @@ export class Project extends BaseProject {
292
390
  })
293
391
  }
294
392
 
295
- #configureLintSynthesized({ lintSynthesizedOptions }: ProjectOptions) {
296
- new LintSynthesized(
393
+ #configureLintStaged({ lintStaged: lintStagedOptions }: ProjectOptions) {
394
+ if (!lintStagedOptions) {
395
+ return
396
+ }
397
+
398
+ const defaults: LintStagedOptions = {
399
+ filename: 'lint-staged.config.mjs',
400
+ extends: '@langri-sha/lint-staged',
401
+ }
402
+
403
+ this.lintStaged = new LintStaged(
297
404
  this,
298
- lintSynthesizedOptions ?? {
299
- 'package.json': 'pnpx sort-package-json',
300
- '*.{js,jsx,ts,tsx}': 'pnpm eslint --fix',
301
- '*': 'pnpm prettier --write --ignore-unknown',
302
- },
405
+ deepMerge(defaults, lintStagedOptions),
303
406
  )
407
+
408
+ this.typeScriptConfig?.addFile(this.lintStaged!.path)
304
409
  }
305
410
 
306
- #configureNpmIgnore({ jestConfigOptions, npmIgnoreOptions }: ProjectOptions) {
307
- if (!npmIgnoreOptions) {
411
+ #configureLintSynthesized({ lintSynthesized }: ProjectOptions) {
412
+ if (!lintSynthesized) {
413
+ return
414
+ }
415
+
416
+ const defaults: LintSynthesizedOptions = {
417
+ 'package.json': 'pnpx sort-package-json',
418
+ '*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}': 'pnpm eslint --fix',
419
+ '*': 'pnpm prettier --write --ignore-unknown',
420
+ }
421
+
422
+ new LintSynthesized(this, deepMerge(defaults, lintSynthesized))
423
+ }
424
+
425
+ #configureNpmIgnore({
426
+ typeScriptConfig,
427
+ jestConfig,
428
+ npmIgnore,
429
+ }: ProjectOptions) {
430
+ if (!npmIgnore) {
308
431
  return
309
432
  }
310
433
 
311
434
  const defaults: IgnoreFileOptions = {
312
435
  ignorePatterns: [
313
- ...(jestConfigOptions ? ['*.test.*', '.*', '__snapshots__/'] : []),
314
- 'tsconfig*.json',
436
+ '.*',
437
+ ...(jestConfig ? ['*.test.*', '__snapshots__/'] : []),
438
+ ...(typeScriptConfig ? ['tsconfig*.json'] : []),
315
439
  ],
316
440
  }
317
441
 
318
442
  this.npmIgnore = new IgnoreFile(
319
443
  this,
320
444
  '.npmignore',
321
- deepMerge(defaults, npmIgnoreOptions),
445
+ deepMerge(defaults, npmIgnore),
322
446
  )
323
447
  }
324
448
 
@@ -327,17 +451,16 @@ export class Project extends BaseProject {
327
451
  return
328
452
  }
329
453
 
330
- const defaults: javascript.NodePackageOptions = {
454
+ const defaults: NodePackageOptions = {
331
455
  entrypoint: 'src/index.ts',
332
456
  packageManager: javascript.NodePackageManager.PNPM,
333
- minNodeVersion: '20.12.0',
334
457
  }
335
458
 
336
- this.package = new javascript.NodePackage(this, deepMerge(defaults, pkg))
459
+ this.package = new NodePackage(this, deepMerge(defaults, pkg))
337
460
 
338
461
  if (!this.parent) {
339
462
  this.package.addDevDeps('@langri-sha/projen-project@*')
340
- this.package.addDevDeps('projen@0.81.15')
463
+ this.package.addDevDeps('projen@0.82.4')
341
464
  }
342
465
 
343
466
  this.package.removeScript('start')
@@ -348,11 +471,47 @@ export class Project extends BaseProject {
348
471
  }
349
472
  }
350
473
 
474
+ #configurePnpmWorkspace({ pnpmWorkspace }: ProjectOptions) {
475
+ if (!pnpmWorkspace) {
476
+ return
477
+ }
478
+
479
+ this.pnpmWorkspace = new PnpmWorkspace(this, pnpmWorkspace)
480
+ }
481
+
482
+ #configurePrettier({ prettier: prettierOptions }: ProjectOptions) {
483
+ if (!prettierOptions || this.parent) {
484
+ return
485
+ }
486
+
487
+ const defaults: PrettierOptions = {
488
+ filename: 'prettier.config.mjs',
489
+ extends: '@langri-sha/prettier',
490
+ ignorePatterns: ['.*', 'dist/'],
491
+ }
492
+
493
+ this.prettier = new Prettier(this, deepMerge(defaults, prettierOptions))
494
+
495
+ if (this.projenrc?.filePath) {
496
+ this.prettier.ignore.include(this.projenrc.filePath)
497
+ }
498
+
499
+ if (this.package?.packageManager === javascript.NodePackageManager.PNPM) {
500
+ this.prettier.ignore.addPatterns('pnpm-lock.yaml')
501
+ }
502
+
503
+ this.typeScriptConfig?.addFile(this.prettier!.path)
504
+ }
505
+
351
506
  #configureProjenrc() {
352
507
  this.projenrc = new ProjenrcFile(this, {})
508
+
509
+ if (!this.parent) {
510
+ this.typeScriptConfig?.addFile(this.projenrc.filePath)
511
+ }
353
512
  }
354
513
 
355
- #configureRenovate({ renovateOptions }: ProjectOptions) {
514
+ #configureRenovate({ renovate: renovateOptions }: ProjectOptions) {
356
515
  if (!renovateOptions || this.parent) {
357
516
  return
358
517
  }
@@ -362,7 +521,19 @@ export class Project extends BaseProject {
362
521
  extends: ['config:recommended'],
363
522
  labels: ['dependencies'],
364
523
  reviewersFromCodeOwners: true,
524
+ lockFileMaintenance: {
525
+ enabled: true,
526
+ },
365
527
  customManagers: [
528
+ {
529
+ customType: 'regex',
530
+ datasourceTemplate: 'node',
531
+ depNameTemplate: 'node',
532
+ versioningTemplate: 'node',
533
+ currentValueTemplate: '>= {{currentValue}}',
534
+ fileMatch: ['\\.?projen.*.(js|cjs|mjs|ts|mts|cts)$'],
535
+ matchStrings: ["minNodeVersion:\\s*'(?<currentValue>[^']+)'"],
536
+ },
366
537
  {
367
538
  customType: 'regex',
368
539
  datasourceTemplate: 'npm',
@@ -370,7 +541,7 @@ export class Project extends BaseProject {
370
541
  matchStringsStrategy: 'recursive',
371
542
  matchStrings: [
372
543
  '\\.(?<depType>addDeps|addDevDeps|addPeerDeps)\\([^)]*\\)',
373
- "'(?<depName>[a-zA-Z0-9-]+)@(?<currentValue>[^']+)'",
544
+ "'(?<depName>@?[\\w-\\/]+)@(?<currentValue>[^']+)'",
374
545
  ],
375
546
  depTypeTemplate:
376
547
  "{{#if (equals depType 'addDeps')}}dependencies{{else if (equals depType 'addDevDeps')}}devDependencies{{else}}peerDependencies{{/if}}",
@@ -382,7 +553,7 @@ export class Project extends BaseProject {
382
553
  matchStringsStrategy: 'recursive',
383
554
  matchStrings: [
384
555
  '(?<depType>deps|devDeps|peerDeps):\\s*\\[[^\\]]*\\]',
385
- "'(?<depName>[a-zA-Z0-9-]+)@(?<currentValue>[^']+)'",
556
+ "'(?<depName>@?[\\w-\\/]+)@(?<currentValue>[^']+)'",
386
557
  ],
387
558
  depTypeTemplate:
388
559
  "{{#if (equals depType 'deps')}}dependencies{{else if (equals depType 'devDeps')}}devDependencies{{else}}peerDependencies{{/if}}",
@@ -398,22 +569,54 @@ export class Project extends BaseProject {
398
569
  ],
399
570
  }
400
571
 
572
+ this.addTask('renovate', {
573
+ description: 'Run Renovate locally for debugging',
574
+ exec: 'pnpx renovate --platform=local --repository-cache=reset --dry-run=full',
575
+ })
576
+
401
577
  this.renovate = new Renovate(this, deepMerge(defaults, renovateOptions))
402
578
  }
403
579
 
404
- #configureTypeScript({ parent, typeScriptConfigOptions }: ProjectOptions) {
405
- if (!typeScriptConfigOptions) {
580
+ #configureSWC({ swcrc, typeScriptConfig }: ProjectOptions) {
581
+ if (!swcrc) {
582
+ return
583
+ }
584
+
585
+ if (!this.parent) {
586
+ this.package?.addDevDeps('@swc/core@1.6.13')
587
+ this.package?.addDevDeps('@swc-node/register@1.10.2')
588
+ }
589
+
590
+ const defaults: SWCConfigOptions = {
591
+ $schema: 'https://json.schemastore.org/swcrc',
592
+ ...(typeScriptConfig
593
+ ? {
594
+ jsc: {
595
+ parser: {
596
+ syntax: 'typescript',
597
+ },
598
+ },
599
+ }
600
+ : {}),
601
+ env: {
602
+ targets: {
603
+ node: 'current',
604
+ },
605
+ },
606
+ }
607
+
608
+ this.swcrc = new SWCConfig(this, deepMerge(defaults, swcrc))
609
+ }
610
+
611
+ #configureTypeScript({ parent, typeScriptConfig, swcrc }: ProjectOptions) {
612
+ if (!typeScriptConfig) {
406
613
  return
407
614
  }
408
615
 
409
616
  const defaults: TypeScriptConfigOptions = parent
410
617
  ? {
411
618
  config: {
412
- extends: '@langri-sha/tsconfig/project.json',
413
- compilerOptions: {
414
- baseUrl: '.',
415
- outDir: '.tsbuild',
416
- },
619
+ extends: '@langri-sha/tsconfig/project',
417
620
  },
418
621
  }
419
622
  : {
@@ -424,39 +627,61 @@ export class Project extends BaseProject {
424
627
 
425
628
  this.typeScriptConfig = new TypeScriptConfig(
426
629
  this,
427
- deepMerge(defaults, typeScriptConfigOptions),
630
+ deepMerge(defaults, typeScriptConfig),
428
631
  )
429
632
 
430
633
  if (!this.parent) {
431
- this.package?.addDevDeps('typescript@5.4.5')
432
- this.package?.addDevDeps('ts-node@10.9.2')
634
+ this.package?.addDevDeps('typescript@5.5.3')
635
+
636
+ if (!swcrc) {
637
+ this.package?.addDevDeps('ts-node@10.9.2')
638
+ }
433
639
  }
434
640
 
435
- this.package?.addDevDeps('@langri-sha/tsconfig@*')
641
+ if (this.name !== '@langri-sha/tsconfig') {
642
+ this.package?.addDevDeps('@langri-sha/tsconfig@*')
643
+ }
436
644
  }
437
645
 
438
- #createPnpmWorkspaces({ workspaces }: ProjectOptions) {
439
- if (!workspaces) {
646
+ #populateTypeScriptProjectReferencesFromDependencies() {
647
+ if (this.parent || !this.package || !this.typeScriptConfig) {
440
648
  return
441
649
  }
442
650
 
443
- new YamlFile(this, 'pnpm-workspace.yaml', {
444
- readonly: true,
445
- marker: true,
446
- obj: {
447
- packages: workspaces,
448
- },
449
- })
651
+ const subprojects = this.allSubprojectsKind.filter(
652
+ (project) => project.package && project.typeScriptConfig,
653
+ )
654
+
655
+ const root = path.dirname(this.package!.file.absolutePath)
656
+
657
+ for (const project of subprojects) {
658
+ const from = path.dirname(project.package!.file.absolutePath)
659
+
660
+ if (project.name !== '@langri-sha/tsconfig') {
661
+ this.typeScriptConfig!.addReference(path.relative(root, from))
662
+ }
663
+
664
+ for (const dep of project.deps.all) {
665
+ const reference = subprojects.find(({ name }) => name === dep.name)
666
+
667
+ if (!reference) {
668
+ continue
669
+ }
670
+
671
+ const to = path.dirname(reference.package!.file.absolutePath)
672
+
673
+ project.typeScriptConfig!.addReference(path.relative(from, to))
674
+ }
675
+ }
450
676
  }
451
677
  }
452
678
 
453
679
  const getGitIgnoreOptions = ({
454
680
  gitIgnoreOptions,
455
- huskyOptions,
681
+ husky: huskyOptions,
456
682
  parent,
457
- typeScriptConfigOptions,
683
+ typeScriptConfig: typeScriptConfigOptions,
458
684
  withTerraform,
459
- ...options
460
685
  }: ProjectOptions): ProjectOptions['gitIgnoreOptions'] =>
461
686
  parent
462
687
  ? gitIgnoreOptions
@@ -481,7 +706,7 @@ const getGitIgnoreOptions = ({
481
706
  !.github/
482
707
  ${huskyOptions ? '!.husky/' : ''}
483
708
  !.projen/
484
- ${options.workspaces?.map((workspace) => `${workspace}/lib/`).join('\n') ?? ''}
709
+ dist/
485
710
  node_modules/
486
711
  `
487
712
  .split('\n')
@@ -491,4 +716,11 @@ const getGitIgnoreOptions = ({
491
716
  ],
492
717
  }
493
718
 
494
- const deepMerge = R.mergeDeepWith(R.concat)
719
+ const deepMerge = R.mergeDeepWith(
720
+ R.cond([
721
+ // When both arguments are strings, use the right string.
722
+ [R.allPass([R.is(String), R.is(String)]), R.nthArg(1)],
723
+ // Otherwise, concatenate.
724
+ [R.T, R.concat],
725
+ ]),
726
+ )
package/src/lib/index.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from './node-package.js'
1
2
  export * from './projenrc.js'