@tactical-ddd/nx 0.0.2-alpha.3 → 0.0.2
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/generators/domain/domain.d.ts.map +1 -1
- package/generators/domain/domain.js +16 -1
- package/generators/domain/domain.js.map +1 -1
- package/generators/init/init.d.ts.map +1 -1
- package/generators/init/init.js +2 -22
- package/generators/init/init.js.map +1 -1
- package/package.json +4 -1
- package/utils/react-runtime.d.ts +26 -0
- package/utils/react-runtime.d.ts.map +1 -0
- package/utils/react-runtime.js +40 -0
- package/utils/react-runtime.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/domain/domain.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/domain/domain.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,iBAAiB,EACtB,KAAK,IAAI,EAEV,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AActD,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CA8K5B;AA0ED,eAAe,eAAe,CAAC"}
|
|
@@ -25,6 +25,7 @@ const _eslintmoduleboundaries = require("../../utils/eslint-module-boundaries");
|
|
|
25
25
|
const _logger = require("../../utils/logger");
|
|
26
26
|
const _types = require("../../types");
|
|
27
27
|
const _resolvemoduleformat = require("../../utils/resolve-module-format");
|
|
28
|
+
const _reactruntime = require("../../utils/react-runtime");
|
|
28
29
|
/** Conventional location of the shared kernel's contracts library. */ const SHARED_CONTRACTS_ROOT = 'libs/shared/contracts';
|
|
29
30
|
async function domainGenerator(tree, options) {
|
|
30
31
|
// Implicit existence check (CLAUDE.md 7.3.1): domain libraries depend on the
|
|
@@ -124,6 +125,13 @@ async function domainGenerator(tree, options) {
|
|
|
124
125
|
tags: `${_types.LibraryScope.Domain},${domainTag},${_types.LibraryType.Features}`
|
|
125
126
|
}));
|
|
126
127
|
}
|
|
128
|
+
// A React layer (ui/features) needs the React runtime present. Add it
|
|
129
|
+
// centrally — both halves at one specifier, and only when the workspace
|
|
130
|
+
// manages neither yet — mirroring the `init` generator; `@nx/react` was told
|
|
131
|
+
// to skip it above so it can't introduce a skewed `react`/`react-dom`.
|
|
132
|
+
if (options.preset === 'react' && (options.layers.includes('ui') || options.layers.includes('features'))) {
|
|
133
|
+
tasks.push((0, _devkit.addDependenciesToPackageJson)(tree, (0, _reactruntime.reactRuntimeDependencies)(tree), {}));
|
|
134
|
+
}
|
|
127
135
|
// Silo this domain: per-domain constraints are what actually prevent
|
|
128
136
|
// cross-domain imports (a static `domain:*` rule cannot — Nx glob-matches the
|
|
129
137
|
// target tags, so it would let `domain:auth` import `domain:payments`).
|
|
@@ -164,6 +172,12 @@ async function domainGenerator(tree, options) {
|
|
|
164
172
|
*/ async function generateLayerLibrary(tree, options, layer) {
|
|
165
173
|
if (options.preset === 'react') {
|
|
166
174
|
const { libraryGenerator: reactLibraryGenerator } = (0, _devkit.ensurePackage)('@nx/react', _devkit.NX_VERSION);
|
|
175
|
+
// `skipPackageJson` stops `@nx/react` from adding `react`/`react-dom` to the
|
|
176
|
+
// workspace itself: it would add `react-dom` at a floating range that can
|
|
177
|
+
// resolve to a patch the workspace's already-pinned `react` no longer
|
|
178
|
+
// satisfies (an `ERESOLVE` on install). The React runtime is instead added
|
|
179
|
+
// centrally and skew-free via `reactRuntimeDependencies` in the main
|
|
180
|
+
// generator, only when the workspace manages none yet.
|
|
167
181
|
return await reactLibraryGenerator(tree, {
|
|
168
182
|
name: layer.name,
|
|
169
183
|
directory: layer.root,
|
|
@@ -172,7 +186,8 @@ async function domainGenerator(tree, options) {
|
|
|
172
186
|
bundler: options.bundler,
|
|
173
187
|
linter: options.linter,
|
|
174
188
|
style: 'none',
|
|
175
|
-
tags: layer.tags
|
|
189
|
+
tags: layer.tags,
|
|
190
|
+
skipPackageJson: true
|
|
176
191
|
});
|
|
177
192
|
}
|
|
178
193
|
const task = await (0, _js.libraryGenerator)(tree, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx/src/generators/domain/domain.ts"],"sourcesContent":["import {\n ensurePackage,\n formatFiles,\n generateFiles,\n names,\n NX_VERSION,\n OverwriteStrategy,\n readJson,\n runTasksInSerial,\n type GeneratorCallback,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { libraryGenerator as jsLibraryGenerator } from '@nx/js';\nimport { resolve } from 'path';\n\nimport type { DomainGeneratorSchema } from './schema';\nimport { libraryExists } from '../../utils/library-exist';\nimport {\n applyCleanArchitectureBoundaries,\n applyDepConstraints,\n} from '../../utils/eslint-module-boundaries';\nimport { warning } from '../../utils/logger';\nimport { LibraryScope, LibraryType, ModuleFormat } from '../../types';\nimport { resolveLibraryModuleFormat } from '../../utils/resolve-module-format';\n\n/** Conventional location of the shared kernel's contracts library. */\nconst SHARED_CONTRACTS_ROOT = 'libs/shared/contracts';\n\nexport async function domainGenerator(\n tree: Tree,\n options: DomainGeneratorSchema,\n): Promise<GeneratorCallback> {\n // Implicit existence check (CLAUDE.md 7.3.1): domain libraries depend on the\n // shared kernel, so warn if it has not been generated yet rather than\n // producing libraries whose boundary constraints reference tags nothing\n // carries.\n if (!libraryExists(tree, SHARED_CONTRACTS_ROOT)) {\n warning(\n `Shared kernel not found at ${SHARED_CONTRACTS_ROOT}. Run \\`nx g @tactical-ddd/nx:init\\` (or the \\`shared-kernel\\` generator) first so domain libraries can depend on the shared contracts.`,\n );\n }\n\n const contractsRoot = `${options.directory}/contracts`;\n const coreRoot = `${options.directory}/core`;\n const uiRoot = `${options.directory}/ui`;\n const featuresRoot = `${options.directory}/features`;\n const domainTag = `domain:${options.name}`;\n const facadeDomainInterfaceVariants = names(`${options.name}Facade`);\n\n // Install callbacks from the delegated library generators — returned to Nx so\n // the packages backing the inferred plugins (`@nx/eslint`, `@nx/jest`) the\n // libraries register via `addPlugin` get installed.\n const tasks: GeneratorCallback[] = [];\n\n if (\n !libraryExists(tree, contractsRoot) &&\n options.layers.includes('contracts')\n ) {\n tasks.push(\n await jsLibraryGenerator(tree, {\n name: layerName(options, 'contracts'),\n directory: contractsRoot,\n addPlugin: true,\n unitTestRunner: 'none',\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Contracts}`,\n }),\n );\n\n const type = resolveLibraryModuleFormat(tree, contractsRoot);\n\n tree.delete(`${contractsRoot}/src/lib/${options.name}-contracts.ts`);\n tree.write(`${contractsRoot}/src/index.ts`, '');\n generateFiles(\n tree,\n resolve(__dirname, 'files/contracts'),\n contractsRoot,\n {\n name: options.name,\n interfaceName: facadeDomainInterfaceVariants.className,\n esm: type === ModuleFormat.EsModule,\n },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n }\n\n if (!libraryExists(tree, coreRoot) && options.layers.includes('core')) {\n tasks.push(\n await jsLibraryGenerator(tree, {\n name: layerName(options, 'core'),\n directory: coreRoot,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Core}`,\n }),\n );\n\n const type = resolveLibraryModuleFormat(tree, coreRoot);\n const contractsPackage = layerName(options, 'contracts');\n\n tree.delete(`${coreRoot}/src/lib/${options.name}-core.ts`);\n tree.delete(`${coreRoot}/src/lib/${options.name}-core.spec.ts`);\n tree.write(`${coreRoot}/src/index.ts`, '');\n\n // Scaffold the default Clean Architecture layer folders (domain,\n // application, infrastructure — each kept in git via a `.gitkeep`) and lock\n // down imports between them: domain ⊀ application/infrastructure, and\n // application ⊀ infrastructure (the implementation is wired via DI at the\n // composition root, not imported across layers).\n generateFiles(\n tree,\n resolve(__dirname, 'files/core'),\n coreRoot,\n {\n name: options.name,\n interfaceName: facadeDomainInterfaceVariants.className,\n // Full package name of this domain's contracts library, so the facade's\n // import resolves with or without an organization prefix.\n contractsPackage,\n esm: type === ModuleFormat.EsModule,\n },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n\n // The generated facade imports the domain's contracts package, so declare it\n // as a dependency — otherwise `@nx/dependency-checks` flags the core library\n // for using a package missing from its `package.json`.\n if (tree.exists(`${contractsRoot}/package.json`)) {\n const contractsVersion =\n readJson(tree, `${contractsRoot}/package.json`).version ?? '*';\n updateJson(tree, `${coreRoot}/package.json`, (pkg) => {\n pkg.dependencies = {\n ...pkg.dependencies,\n [contractsPackage]: contractsVersion,\n };\n return pkg;\n });\n }\n\n applyCleanArchitectureBoundaries(tree, coreRoot, options.prefix);\n }\n\n if (!libraryExists(tree, uiRoot) && options.layers.includes('ui')) {\n tasks.push(\n await generateLayerLibrary(tree, options, {\n root: uiRoot,\n name: layerName(options, 'ui'),\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Ui}`,\n }),\n );\n }\n\n if (\n !libraryExists(tree, featuresRoot) &&\n options.layers.includes('features')\n ) {\n tasks.push(\n await generateLayerLibrary(tree, options, {\n root: featuresRoot,\n name: layerName(options, 'features'),\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Features}`,\n }),\n );\n }\n\n // Silo this domain: per-domain constraints are what actually prevent\n // cross-domain imports (a static `domain:*` rule cannot — Nx glob-matches the\n // target tags, so it would let `domain:auth` import `domain:payments`).\n //\n // A `domain:<name>` library may depend on its own domain, the shared kernel,\n // and the *public contracts* of any other domain (`type:contracts`) — the\n // published-language pattern: a domain depends on another domain's\n // abstraction, never its implementation (`core`/`ui`/`features`/\n // `infrastructure`), which stays hidden behind DI wired up in the composition\n // root. No-op (with a warning) when there is no ESLint config.\n applyDepConstraints(tree, [\n {\n sourceTag: domainTag,\n onlyDependOnLibsWithTags: [\n domainTag,\n LibraryScope.Shared,\n LibraryType.Contracts,\n ],\n },\n ]);\n\n await formatFiles(tree);\n\n return runTasksInSerial(...tasks);\n}\n\n/** Composes a layer library name, applying the optional organization prefix. */\nfunction layerName(options: DomainGeneratorSchema, layer: string): string {\n const base = `${options.name}-${layer}`;\n return options.prefix ? `${options.prefix}/${base}` : base;\n}\n\n/**\n * Generates a presentational/feature layer library and returns its install\n * callback. Under the `react` preset it uses `@nx/react`'s generator (loaded\n * lazily via `ensurePackage` so the domain generator never hard-depends on\n * `@nx/react` in non-React workspaces); under `none` it uses `@nx/js` and adds\n * the DOM lib to the library `tsconfig` so browser globals type-check.\n *\n * Both pass `addPlugin: true` so the library gets inferred tasks (Project\n * Crystal) rather than the deprecated executor targets the generators' public\n * wrappers default to.\n */\nasync function generateLayerLibrary(\n tree: Tree,\n options: DomainGeneratorSchema,\n layer: { root: string; name: string; tags: string },\n): Promise<GeneratorCallback> {\n if (options.preset === 'react') {\n const { libraryGenerator: reactLibraryGenerator } = ensurePackage<\n typeof import('@nx/react')\n >('@nx/react', NX_VERSION);\n\n return await reactLibraryGenerator(tree, {\n name: layer.name,\n directory: layer.root,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n style: 'none',\n tags: layer.tags,\n });\n }\n\n const task = await jsLibraryGenerator(tree, {\n name: layer.name,\n directory: layer.root,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: layer.tags,\n });\n addDomLibToTsConfig(tree, layer.root);\n return task;\n}\n\n/** Adds the `DOM` lib to a library's `tsconfig.lib.json` (idempotent). */\nfunction addDomLibToTsConfig(tree: Tree, root: string) {\n updateJson(tree, `${root}/tsconfig.lib.json`, (json) => {\n json.compilerOptions ??= {};\n if (!json.compilerOptions.lib) {\n json.compilerOptions.lib = ['ESNext', 'DOM'];\n } else if (!json.compilerOptions.lib.includes('DOM')) {\n json.compilerOptions.lib.push('DOM');\n }\n return json;\n });\n}\n\nexport default domainGenerator;\n"],"names":["domainGenerator","SHARED_CONTRACTS_ROOT","tree","options","libraryExists","warning","contractsRoot","directory","coreRoot","uiRoot","featuresRoot","domainTag","name","facadeDomainInterfaceVariants","names","tasks","layers","includes","push","jsLibraryGenerator","layerName","addPlugin","unitTestRunner","bundler","linter","tags","LibraryScope","Domain","LibraryType","Contracts","type","resolveLibraryModuleFormat","delete","write","generateFiles","resolve","__dirname","interfaceName","className","esm","ModuleFormat","EsModule","overwriteStrategy","OverwriteStrategy","Overwrite","Core","contractsPackage","exists","readJson","contractsVersion","version","updateJson","pkg","dependencies","applyCleanArchitectureBoundaries","prefix","generateLayerLibrary","root","Ui","Features","applyDepConstraints","sourceTag","onlyDependOnLibsWithTags","Shared","formatFiles","runTasksInSerial","layer","base","preset","libraryGenerator","reactLibraryGenerator","ensurePackage","NX_VERSION","style","task","addDomLibToTsConfig","json","compilerOptions","lib"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx/src/generators/domain/domain.ts"],"sourcesContent":["import {\n addDependenciesToPackageJson,\n ensurePackage,\n formatFiles,\n generateFiles,\n names,\n NX_VERSION,\n OverwriteStrategy,\n readJson,\n runTasksInSerial,\n type GeneratorCallback,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { libraryGenerator as jsLibraryGenerator } from '@nx/js';\nimport { resolve } from 'path';\n\nimport type { DomainGeneratorSchema } from './schema';\nimport { libraryExists } from '../../utils/library-exist';\nimport {\n applyCleanArchitectureBoundaries,\n applyDepConstraints,\n} from '../../utils/eslint-module-boundaries';\nimport { warning } from '../../utils/logger';\nimport { LibraryScope, LibraryType, ModuleFormat } from '../../types';\nimport { resolveLibraryModuleFormat } from '../../utils/resolve-module-format';\nimport { reactRuntimeDependencies } from '../../utils/react-runtime';\n\n/** Conventional location of the shared kernel's contracts library. */\nconst SHARED_CONTRACTS_ROOT = 'libs/shared/contracts';\n\nexport async function domainGenerator(\n tree: Tree,\n options: DomainGeneratorSchema,\n): Promise<GeneratorCallback> {\n // Implicit existence check (CLAUDE.md 7.3.1): domain libraries depend on the\n // shared kernel, so warn if it has not been generated yet rather than\n // producing libraries whose boundary constraints reference tags nothing\n // carries.\n if (!libraryExists(tree, SHARED_CONTRACTS_ROOT)) {\n warning(\n `Shared kernel not found at ${SHARED_CONTRACTS_ROOT}. Run \\`nx g @tactical-ddd/nx:init\\` (or the \\`shared-kernel\\` generator) first so domain libraries can depend on the shared contracts.`,\n );\n }\n\n const contractsRoot = `${options.directory}/contracts`;\n const coreRoot = `${options.directory}/core`;\n const uiRoot = `${options.directory}/ui`;\n const featuresRoot = `${options.directory}/features`;\n const domainTag = `domain:${options.name}`;\n const facadeDomainInterfaceVariants = names(`${options.name}Facade`);\n\n // Install callbacks from the delegated library generators — returned to Nx so\n // the packages backing the inferred plugins (`@nx/eslint`, `@nx/jest`) the\n // libraries register via `addPlugin` get installed.\n const tasks: GeneratorCallback[] = [];\n\n if (\n !libraryExists(tree, contractsRoot) &&\n options.layers.includes('contracts')\n ) {\n tasks.push(\n await jsLibraryGenerator(tree, {\n name: layerName(options, 'contracts'),\n directory: contractsRoot,\n addPlugin: true,\n unitTestRunner: 'none',\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Contracts}`,\n }),\n );\n\n const type = resolveLibraryModuleFormat(tree, contractsRoot);\n\n tree.delete(`${contractsRoot}/src/lib/${options.name}-contracts.ts`);\n tree.write(`${contractsRoot}/src/index.ts`, '');\n generateFiles(\n tree,\n resolve(__dirname, 'files/contracts'),\n contractsRoot,\n {\n name: options.name,\n interfaceName: facadeDomainInterfaceVariants.className,\n esm: type === ModuleFormat.EsModule,\n },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n }\n\n if (!libraryExists(tree, coreRoot) && options.layers.includes('core')) {\n tasks.push(\n await jsLibraryGenerator(tree, {\n name: layerName(options, 'core'),\n directory: coreRoot,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Core}`,\n }),\n );\n\n const type = resolveLibraryModuleFormat(tree, coreRoot);\n const contractsPackage = layerName(options, 'contracts');\n\n tree.delete(`${coreRoot}/src/lib/${options.name}-core.ts`);\n tree.delete(`${coreRoot}/src/lib/${options.name}-core.spec.ts`);\n tree.write(`${coreRoot}/src/index.ts`, '');\n\n // Scaffold the default Clean Architecture layer folders (domain,\n // application, infrastructure — each kept in git via a `.gitkeep`) and lock\n // down imports between them: domain ⊀ application/infrastructure, and\n // application ⊀ infrastructure (the implementation is wired via DI at the\n // composition root, not imported across layers).\n generateFiles(\n tree,\n resolve(__dirname, 'files/core'),\n coreRoot,\n {\n name: options.name,\n interfaceName: facadeDomainInterfaceVariants.className,\n // Full package name of this domain's contracts library, so the facade's\n // import resolves with or without an organization prefix.\n contractsPackage,\n esm: type === ModuleFormat.EsModule,\n },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n\n // The generated facade imports the domain's contracts package, so declare it\n // as a dependency — otherwise `@nx/dependency-checks` flags the core library\n // for using a package missing from its `package.json`.\n if (tree.exists(`${contractsRoot}/package.json`)) {\n const contractsVersion =\n readJson(tree, `${contractsRoot}/package.json`).version ?? '*';\n updateJson(tree, `${coreRoot}/package.json`, (pkg) => {\n pkg.dependencies = {\n ...pkg.dependencies,\n [contractsPackage]: contractsVersion,\n };\n return pkg;\n });\n }\n\n applyCleanArchitectureBoundaries(tree, coreRoot, options.prefix);\n }\n\n if (!libraryExists(tree, uiRoot) && options.layers.includes('ui')) {\n tasks.push(\n await generateLayerLibrary(tree, options, {\n root: uiRoot,\n name: layerName(options, 'ui'),\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Ui}`,\n }),\n );\n }\n\n if (\n !libraryExists(tree, featuresRoot) &&\n options.layers.includes('features')\n ) {\n tasks.push(\n await generateLayerLibrary(tree, options, {\n root: featuresRoot,\n name: layerName(options, 'features'),\n tags: `${LibraryScope.Domain},${domainTag},${LibraryType.Features}`,\n }),\n );\n }\n\n // A React layer (ui/features) needs the React runtime present. Add it\n // centrally — both halves at one specifier, and only when the workspace\n // manages neither yet — mirroring the `init` generator; `@nx/react` was told\n // to skip it above so it can't introduce a skewed `react`/`react-dom`.\n if (\n options.preset === 'react' &&\n (options.layers.includes('ui') || options.layers.includes('features'))\n ) {\n tasks.push(\n addDependenciesToPackageJson(tree, reactRuntimeDependencies(tree), {}),\n );\n }\n\n // Silo this domain: per-domain constraints are what actually prevent\n // cross-domain imports (a static `domain:*` rule cannot — Nx glob-matches the\n // target tags, so it would let `domain:auth` import `domain:payments`).\n //\n // A `domain:<name>` library may depend on its own domain, the shared kernel,\n // and the *public contracts* of any other domain (`type:contracts`) — the\n // published-language pattern: a domain depends on another domain's\n // abstraction, never its implementation (`core`/`ui`/`features`/\n // `infrastructure`), which stays hidden behind DI wired up in the composition\n // root. No-op (with a warning) when there is no ESLint config.\n applyDepConstraints(tree, [\n {\n sourceTag: domainTag,\n onlyDependOnLibsWithTags: [\n domainTag,\n LibraryScope.Shared,\n LibraryType.Contracts,\n ],\n },\n ]);\n\n await formatFiles(tree);\n\n return runTasksInSerial(...tasks);\n}\n\n/** Composes a layer library name, applying the optional organization prefix. */\nfunction layerName(options: DomainGeneratorSchema, layer: string): string {\n const base = `${options.name}-${layer}`;\n return options.prefix ? `${options.prefix}/${base}` : base;\n}\n\n/**\n * Generates a presentational/feature layer library and returns its install\n * callback. Under the `react` preset it uses `@nx/react`'s generator (loaded\n * lazily via `ensurePackage` so the domain generator never hard-depends on\n * `@nx/react` in non-React workspaces); under `none` it uses `@nx/js` and adds\n * the DOM lib to the library `tsconfig` so browser globals type-check.\n *\n * Both pass `addPlugin: true` so the library gets inferred tasks (Project\n * Crystal) rather than the deprecated executor targets the generators' public\n * wrappers default to.\n */\nasync function generateLayerLibrary(\n tree: Tree,\n options: DomainGeneratorSchema,\n layer: { root: string; name: string; tags: string },\n): Promise<GeneratorCallback> {\n if (options.preset === 'react') {\n const { libraryGenerator: reactLibraryGenerator } = ensurePackage<\n typeof import('@nx/react')\n >('@nx/react', NX_VERSION);\n\n // `skipPackageJson` stops `@nx/react` from adding `react`/`react-dom` to the\n // workspace itself: it would add `react-dom` at a floating range that can\n // resolve to a patch the workspace's already-pinned `react` no longer\n // satisfies (an `ERESOLVE` on install). The React runtime is instead added\n // centrally and skew-free via `reactRuntimeDependencies` in the main\n // generator, only when the workspace manages none yet.\n return await reactLibraryGenerator(tree, {\n name: layer.name,\n directory: layer.root,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n style: 'none',\n tags: layer.tags,\n skipPackageJson: true,\n });\n }\n\n const task = await jsLibraryGenerator(tree, {\n name: layer.name,\n directory: layer.root,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: layer.tags,\n });\n addDomLibToTsConfig(tree, layer.root);\n return task;\n}\n\n/** Adds the `DOM` lib to a library's `tsconfig.lib.json` (idempotent). */\nfunction addDomLibToTsConfig(tree: Tree, root: string) {\n updateJson(tree, `${root}/tsconfig.lib.json`, (json) => {\n json.compilerOptions ??= {};\n if (!json.compilerOptions.lib) {\n json.compilerOptions.lib = ['ESNext', 'DOM'];\n } else if (!json.compilerOptions.lib.includes('DOM')) {\n json.compilerOptions.lib.push('DOM');\n }\n return json;\n });\n}\n\nexport default domainGenerator;\n"],"names":["domainGenerator","SHARED_CONTRACTS_ROOT","tree","options","libraryExists","warning","contractsRoot","directory","coreRoot","uiRoot","featuresRoot","domainTag","name","facadeDomainInterfaceVariants","names","tasks","layers","includes","push","jsLibraryGenerator","layerName","addPlugin","unitTestRunner","bundler","linter","tags","LibraryScope","Domain","LibraryType","Contracts","type","resolveLibraryModuleFormat","delete","write","generateFiles","resolve","__dirname","interfaceName","className","esm","ModuleFormat","EsModule","overwriteStrategy","OverwriteStrategy","Overwrite","Core","contractsPackage","exists","readJson","contractsVersion","version","updateJson","pkg","dependencies","applyCleanArchitectureBoundaries","prefix","generateLayerLibrary","root","Ui","Features","preset","addDependenciesToPackageJson","reactRuntimeDependencies","applyDepConstraints","sourceTag","onlyDependOnLibsWithTags","Shared","formatFiles","runTasksInSerial","layer","base","libraryGenerator","reactLibraryGenerator","ensurePackage","NX_VERSION","style","skipPackageJson","task","addDomLibToTsConfig","json","compilerOptions","lib"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/init/init.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/init/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,iBAAiB,EAEtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAgDpD,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA8B5B;AAwID,eAAe,aAAa,CAAC"}
|
package/generators/init/init.js
CHANGED
|
@@ -21,6 +21,7 @@ const _interop_require_default = require("@swc/helpers/_/_interop_require_defaul
|
|
|
21
21
|
const _devkit = require("@nx/devkit");
|
|
22
22
|
const _moduleboundaries = require("./module-boundaries");
|
|
23
23
|
const _eslintmoduleboundaries = require("../../utils/eslint-module-boundaries");
|
|
24
|
+
const _reactruntime = require("../../utils/react-runtime");
|
|
24
25
|
const _sharedkernel = /*#__PURE__*/ _interop_require_default._(require("../shared-kernel/shared-kernel"));
|
|
25
26
|
/**
|
|
26
27
|
* Collection name this plugin publishes its generators under. Used as the key
|
|
@@ -46,14 +47,6 @@ const REACT_LIBRARY_GENERATORS = [
|
|
|
46
47
|
'@nx/react:library'
|
|
47
48
|
];
|
|
48
49
|
/** The Tactical DDD React runtime bindings package. */ const TACTICAL_DDD_REACT = '@tactical-ddd/react';
|
|
49
|
-
/**
|
|
50
|
-
* React runtime version added to the *user's* workspace under the `react`
|
|
51
|
-
* preset. `react` and `react-dom` are pinned to the *same* specifier and only
|
|
52
|
-
* ever added together (see {@link ensureGeneratorDependencies}) so we never
|
|
53
|
-
* introduce a `react` vs `react-dom` version skew of our own. Kept in step with
|
|
54
|
-
* the React version `@nx/react`'s own generators install so the two never
|
|
55
|
-
* disagree.
|
|
56
|
-
*/ const REACT_VERSION = '^19.0.0';
|
|
57
50
|
/**
|
|
58
51
|
* Version specifier to install `@tactical-ddd/react` at. The React bindings are
|
|
59
52
|
* released in lockstep with this plugin, so we mirror the running plugin's own
|
|
@@ -145,23 +138,10 @@ async function initGenerator(tree, options) {
|
|
|
145
138
|
// Only provide the React runtime when the workspace manages neither half of
|
|
146
139
|
// it yet; if it already has `react` (or `react-dom`), defer to whatever
|
|
147
140
|
// versions it pinned rather than re-resolving and risking a peer conflict.
|
|
148
|
-
|
|
149
|
-
dependencies['react'] = REACT_VERSION;
|
|
150
|
-
dependencies['react-dom'] = REACT_VERSION;
|
|
151
|
-
}
|
|
141
|
+
Object.assign(dependencies, (0, _reactruntime.reactRuntimeDependencies)(tree));
|
|
152
142
|
}
|
|
153
143
|
return (0, _devkit.addDependenciesToPackageJson)(tree, dependencies, devDependencies);
|
|
154
144
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Whether the workspace `package.json` already declares `react` or `react-dom`
|
|
157
|
-
* (in either `dependencies` or `devDependencies`). When it does, `init` leaves
|
|
158
|
-
* the React runtime untouched so it can't introduce a version skew or trigger a
|
|
159
|
-
* conflicting re-resolve.
|
|
160
|
-
*/ function workspaceHasReactRuntime(tree) {
|
|
161
|
-
const packageJson = (0, _devkit.readJson)(tree, 'package.json');
|
|
162
|
-
const declared = _extends._({}, packageJson.devDependencies, packageJson.dependencies);
|
|
163
|
-
return 'react' in declared || 'react-dom' in declared;
|
|
164
|
-
}
|
|
165
145
|
/**
|
|
166
146
|
* Persists workspace-wide generator defaults into `nx.json` so choices like the
|
|
167
147
|
* organization `prefix`, linter and test runner are configured once during
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx/src/generators/init/init.ts"],"sourcesContent":["import {\n addDependenciesToPackageJson,\n formatFiles,\n NX_VERSION,\n readJson,\n readNxJson,\n runTasksInSerial,\n updateNxJson,\n type GeneratorCallback,\n type NxJsonConfiguration,\n type Tree,\n} from '@nx/devkit';\n\nimport type { InitGeneratorSchema } from './schema';\nimport { DEP_CONSTRAINTS } from './module-boundaries';\nimport { applyDepConstraints } from '../../utils/eslint-module-boundaries';\nimport sharedKernelGenerator from '../shared-kernel/shared-kernel';\n\n/**\n * Collection name this plugin publishes its generators under. Used as the key\n * in `nx.json`'s `generators` map so defaults apply to every generator we ship.\n */\nconst COLLECTION = '@tactical-ddd/nx';\n\n/**\n * Generators that accept (and should inherit) the workspace-wide `prefix`.\n * Extend this list as new generators are added — for now only `shared-kernel`\n * consumes the prefix.\n */\nconst PREFIXED_GENERATORS = ['shared-kernel', 'domain'] as const;\n\n/**\n * Built-in Nx library generators that should inherit the workspace-wide\n * build/lint/test defaults so hand-rolled libraries match the conventions.\n * `@nx/js:library` always applies; `@nx/react:library` is layered on only for\n * the `react` preset (see {@link setGeneratorDefaults}).\n */\nconst BASE_LIBRARY_GENERATORS = ['@nx/js:library'] as const;\nconst REACT_LIBRARY_GENERATORS = ['@nx/react:library'] as const;\n\n/** The Tactical DDD React runtime bindings package. */\nconst TACTICAL_DDD_REACT = '@tactical-ddd/react';\n\n/**\n * React runtime version added to the *user's* workspace under the `react`\n * preset. `react` and `react-dom` are pinned to the *same* specifier and only\n * ever added together (see {@link ensureGeneratorDependencies}) so we never\n * introduce a `react` vs `react-dom` version skew of our own. Kept in step with\n * the React version `@nx/react`'s own generators install so the two never\n * disagree.\n */\nconst REACT_VERSION = '^19.0.0';\n\n/**\n * Version specifier to install `@tactical-ddd/react` at. The React bindings are\n * released in lockstep with this plugin, so we mirror the running plugin's own\n * version. This also makes the e2e suite resolve the locally-published build:\n * both packages are published to the local registry under the same e2e version.\n */\nfunction tacticalDddReactVersion(): string {\n try {\n // Resolves from the workspace the generator runs in, where the plugin is\n // installed (real usage and e2e).\n return require('@tactical-ddd/nx/package.json').version as string;\n } catch {\n // Source / unit-test fallback: this package's own manifest.\n return require('../../../package.json').version as string;\n }\n}\n\nexport async function initGenerator(\n tree: Tree,\n options: InitGeneratorSchema,\n): Promise<GeneratorCallback> {\n setGeneratorDefaults(tree, options);\n\n // Make sure every Nx plugin the configured/invoked generators rely on is\n // present; the returned task installs whatever was missing once the generator\n // finishes writing to the tree.\n const installDependencies = ensureGeneratorDependencies(tree, options);\n\n // Generate the shared kernel first: in a fresh workspace the root ESLint\n // config does not exist until the first library is generated, so this is what\n // establishes the config that `applyDepConstraints` then tunes.\n const installKernel = await sharedKernelGenerator(tree, {\n directory: options.sharedDirectory,\n prefix: options.prefix,\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n });\n\n // Populate the root ESLint config with the Tactical DDD dependency graph so\n // the architecture is enforced at lint time. Skipped (with a warning) when\n // the workspace has no ESLint config — e.g. `linter: none`.\n applyDepConstraints(tree, DEP_CONSTRAINTS);\n\n await formatFiles(tree);\n\n // Run both the plugin-dependency install and the shared kernel's own install\n // callbacks (the latter installs the packages backing the inferred ESLint/Jest\n // plugins the generated libraries registered).\n return runTasksInSerial(installDependencies, installKernel);\n}\n\n/**\n * Ensures the Nx plugin packages the configured/invoked generators depend on are\n * declared in the workspace `package.json`, installing any that are missing.\n *\n * `addDependenciesToPackageJson` is itself the presence check: it only adds (or\n * bumps) entries that are absent or older, leaving existing versions untouched,\n * and returns a task that runs the package manager install for whatever changed.\n * All versions are pinned to `NX_VERSION` — the Nx version this plugin runs\n * against — so the added plugins stay in lockstep with the workspace's Nx core.\n *\n * Dependencies are scoped to the chosen options: the ESLint tooling is only\n * required when `linter: 'eslint'`, and the test-runner plugin follows\n * `unitTestRunner`. The `react` preset additionally pulls in the `@nx/react`\n * generator plugin (dev-time) plus the `@tactical-ddd/react` bindings as a\n * production dependency.\n *\n * The `react`/`react-dom` runtime is treated carefully: a React workspace\n * already ships its own React, and declaring our own range on top adds nothing\n * but forces the package manager to re-resolve — which can surface a latent\n * peer-dependency conflict already present in the workspace (e.g. an exactly\n * pinned `react` that a newer `react-dom` patch no longer satisfies) and abort\n * the install. So we only add `react` and `react-dom` when *neither* is already\n * present, and add them together at the same {@link REACT_VERSION} specifier —\n * never introducing a skew of our own.\n */\nfunction ensureGeneratorDependencies(\n tree: Tree,\n options: InitGeneratorSchema,\n): GeneratorCallback {\n const dependencies: Record<string, string> = {};\n const devDependencies: Record<string, string> = {\n // Powers the shared-kernel generator (`@nx/js:library`) and the\n // `@nx/js:library` defaults written above.\n '@nx/js': NX_VERSION,\n };\n\n if (options.linter === 'eslint') {\n // `@nx/eslint` provides the flat-config AST utilities and lint target;\n // `@nx/eslint-plugin` provides the `@nx/enforce-module-boundaries` rule.\n devDependencies['@nx/eslint'] = NX_VERSION;\n devDependencies['@nx/eslint-plugin'] = NX_VERSION;\n }\n\n if (options.unitTestRunner === 'jest') {\n devDependencies['@nx/jest'] = NX_VERSION;\n } else if (options.unitTestRunner === 'vitest') {\n devDependencies['@nx/vite'] = NX_VERSION;\n }\n\n if (options.preset === 'react') {\n // Dev-time: powers the `@nx/react:library` defaults and React generators.\n devDependencies['@nx/react'] = NX_VERSION;\n // Run-time: our React bindings always ship in the app.\n dependencies[TACTICAL_DDD_REACT] = tacticalDddReactVersion();\n\n // Only provide the React runtime when the workspace manages neither half of\n // it yet; if it already has `react` (or `react-dom`), defer to whatever\n // versions it pinned rather than re-resolving and risking a peer conflict.\n if (!workspaceHasReactRuntime(tree)) {\n dependencies['react'] = REACT_VERSION;\n dependencies['react-dom'] = REACT_VERSION;\n }\n }\n\n return addDependenciesToPackageJson(tree, dependencies, devDependencies);\n}\n\n/**\n * Whether the workspace `package.json` already declares `react` or `react-dom`\n * (in either `dependencies` or `devDependencies`). When it does, `init` leaves\n * the React runtime untouched so it can't introduce a version skew or trigger a\n * conflicting re-resolve.\n */\nfunction workspaceHasReactRuntime(tree: Tree): boolean {\n const packageJson = readJson<{\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n }>(tree, 'package.json');\n\n const declared = {\n ...packageJson.devDependencies,\n ...packageJson.dependencies,\n };\n\n return 'react' in declared || 'react-dom' in declared;\n}\n\n/**\n * Persists workspace-wide generator defaults into `nx.json` so choices like the\n * organization `prefix`, linter and test runner are configured once during\n * `init` and then transparently injected by Nx into every subsequent generator\n * invocation (e.g. `nx g @tactical-ddd/nx:shared-kernel`, or even the built-in\n * `nx g @nx/js:library`) without the user re-typing them.\n *\n * Two groups of defaults are written:\n *\n * \"generators\": {\n * // 1. Our own collection — inherit the prefix and linting/testing choices.\n * \"@tactical-ddd/nx\": {\n * \"shared-kernel\": { \"prefix\": \"@my-org\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" }\n * },\n * // 2. The built-in library generators — so hand-rolled libs match conventions.\n * \"@nx/js:library\": { \"bundler\": \"none\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" },\n * // `@nx/react:library` is added only under the `react` preset.\n * \"@nx/react:library\": { \"bundler\": \"none\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" }\n * }\n */\nfunction setGeneratorDefaults(tree: Tree, options: InitGeneratorSchema) {\n const nxJson = readNxJson(tree) ?? ({} as NxJsonConfiguration);\n\n const generators = (nxJson.generators ??= {}) as Record<\n string,\n Record<string, unknown>\n >;\n\n // 1. Our own collection's generators inherit the prefix + linting/testing.\n const collectionDefaults = (generators[COLLECTION] ??= {}) as Record<\n string,\n Record<string, unknown>\n >;\n\n for (const generator of PREFIXED_GENERATORS) {\n collectionDefaults[generator] = {\n ...collectionDefaults[generator],\n prefix: options.prefix,\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n preset: options.preset,\n };\n }\n\n // 2. The built-in library generators get the same workspace-wide build/lint/\n // test defaults, so a plain `nx g @nx/js:library` (or `@nx/react:library`)\n // produces a library that already matches the Tactical DDD conventions.\n // `@nx/react:library` defaults are written only under the `react` preset, so\n // we don't advertise React tooling a non-React workspace never installed.\n const libraryDefaults: Record<string, unknown> = {\n bundler: options.bundler ?? 'none',\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n };\n\n const libraryGenerators =\n options.preset === 'react'\n ? [...BASE_LIBRARY_GENERATORS, ...REACT_LIBRARY_GENERATORS]\n : BASE_LIBRARY_GENERATORS;\n\n for (const generator of libraryGenerators) {\n generators[generator] = {\n ...generators[generator],\n ...libraryDefaults,\n };\n }\n\n updateNxJson(tree, nxJson);\n}\n\nexport default initGenerator;\n"],"names":["initGenerator","COLLECTION","PREFIXED_GENERATORS","BASE_LIBRARY_GENERATORS","REACT_LIBRARY_GENERATORS","TACTICAL_DDD_REACT","REACT_VERSION","tacticalDddReactVersion","require","version","tree","options","setGeneratorDefaults","installDependencies","ensureGeneratorDependencies","installKernel","sharedKernelGenerator","directory","sharedDirectory","prefix","linter","unitTestRunner","bundler","applyDepConstraints","DEP_CONSTRAINTS","formatFiles","runTasksInSerial","dependencies","devDependencies","NX_VERSION","preset","workspaceHasReactRuntime","addDependenciesToPackageJson","packageJson","readJson","declared","readNxJson","nxJson","generators","collectionDefaults","generator","libraryDefaults","libraryGenerators","updateNxJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx/src/generators/init/init.ts"],"sourcesContent":["import {\n addDependenciesToPackageJson,\n formatFiles,\n NX_VERSION,\n readNxJson,\n runTasksInSerial,\n updateNxJson,\n type GeneratorCallback,\n type NxJsonConfiguration,\n type Tree,\n} from '@nx/devkit';\n\nimport type { InitGeneratorSchema } from './schema';\nimport { DEP_CONSTRAINTS } from './module-boundaries';\nimport { applyDepConstraints } from '../../utils/eslint-module-boundaries';\nimport { reactRuntimeDependencies } from '../../utils/react-runtime';\nimport sharedKernelGenerator from '../shared-kernel/shared-kernel';\n\n/**\n * Collection name this plugin publishes its generators under. Used as the key\n * in `nx.json`'s `generators` map so defaults apply to every generator we ship.\n */\nconst COLLECTION = '@tactical-ddd/nx';\n\n/**\n * Generators that accept (and should inherit) the workspace-wide `prefix`.\n * Extend this list as new generators are added — for now only `shared-kernel`\n * consumes the prefix.\n */\nconst PREFIXED_GENERATORS = ['shared-kernel', 'domain'] as const;\n\n/**\n * Built-in Nx library generators that should inherit the workspace-wide\n * build/lint/test defaults so hand-rolled libraries match the conventions.\n * `@nx/js:library` always applies; `@nx/react:library` is layered on only for\n * the `react` preset (see {@link setGeneratorDefaults}).\n */\nconst BASE_LIBRARY_GENERATORS = ['@nx/js:library'] as const;\nconst REACT_LIBRARY_GENERATORS = ['@nx/react:library'] as const;\n\n/** The Tactical DDD React runtime bindings package. */\nconst TACTICAL_DDD_REACT = '@tactical-ddd/react';\n\n/**\n * Version specifier to install `@tactical-ddd/react` at. The React bindings are\n * released in lockstep with this plugin, so we mirror the running plugin's own\n * version. This also makes the e2e suite resolve the locally-published build:\n * both packages are published to the local registry under the same e2e version.\n */\nfunction tacticalDddReactVersion(): string {\n try {\n // Resolves from the workspace the generator runs in, where the plugin is\n // installed (real usage and e2e).\n return require('@tactical-ddd/nx/package.json').version as string;\n } catch {\n // Source / unit-test fallback: this package's own manifest.\n return require('../../../package.json').version as string;\n }\n}\n\nexport async function initGenerator(\n tree: Tree,\n options: InitGeneratorSchema,\n): Promise<GeneratorCallback> {\n setGeneratorDefaults(tree, options);\n\n // Make sure every Nx plugin the configured/invoked generators rely on is\n // present; the returned task installs whatever was missing once the generator\n // finishes writing to the tree.\n const installDependencies = ensureGeneratorDependencies(tree, options);\n\n // Generate the shared kernel first: in a fresh workspace the root ESLint\n // config does not exist until the first library is generated, so this is what\n // establishes the config that `applyDepConstraints` then tunes.\n const installKernel = await sharedKernelGenerator(tree, {\n directory: options.sharedDirectory,\n prefix: options.prefix,\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n });\n\n // Populate the root ESLint config with the Tactical DDD dependency graph so\n // the architecture is enforced at lint time. Skipped (with a warning) when\n // the workspace has no ESLint config — e.g. `linter: none`.\n applyDepConstraints(tree, DEP_CONSTRAINTS);\n\n await formatFiles(tree);\n\n // Run both the plugin-dependency install and the shared kernel's own install\n // callbacks (the latter installs the packages backing the inferred ESLint/Jest\n // plugins the generated libraries registered).\n return runTasksInSerial(installDependencies, installKernel);\n}\n\n/**\n * Ensures the Nx plugin packages the configured/invoked generators depend on are\n * declared in the workspace `package.json`, installing any that are missing.\n *\n * `addDependenciesToPackageJson` is itself the presence check: it only adds (or\n * bumps) entries that are absent or older, leaving existing versions untouched,\n * and returns a task that runs the package manager install for whatever changed.\n * All versions are pinned to `NX_VERSION` — the Nx version this plugin runs\n * against — so the added plugins stay in lockstep with the workspace's Nx core.\n *\n * Dependencies are scoped to the chosen options: the ESLint tooling is only\n * required when `linter: 'eslint'`, and the test-runner plugin follows\n * `unitTestRunner`. The `react` preset additionally pulls in the `@nx/react`\n * generator plugin (dev-time) plus the `@tactical-ddd/react` bindings as a\n * production dependency.\n *\n * The `react`/`react-dom` runtime is treated carefully: a React workspace\n * already ships its own React, and declaring our own range on top adds nothing\n * but forces the package manager to re-resolve — which can surface a latent\n * peer-dependency conflict already present in the workspace (e.g. an exactly\n * pinned `react` that a newer `react-dom` patch no longer satisfies) and abort\n * the install. So we only add `react` and `react-dom` when *neither* is already\n * present, and add them together at the same {@link REACT_VERSION} specifier —\n * never introducing a skew of our own.\n */\nfunction ensureGeneratorDependencies(\n tree: Tree,\n options: InitGeneratorSchema,\n): GeneratorCallback {\n const dependencies: Record<string, string> = {};\n const devDependencies: Record<string, string> = {\n // Powers the shared-kernel generator (`@nx/js:library`) and the\n // `@nx/js:library` defaults written above.\n '@nx/js': NX_VERSION,\n };\n\n if (options.linter === 'eslint') {\n // `@nx/eslint` provides the flat-config AST utilities and lint target;\n // `@nx/eslint-plugin` provides the `@nx/enforce-module-boundaries` rule.\n devDependencies['@nx/eslint'] = NX_VERSION;\n devDependencies['@nx/eslint-plugin'] = NX_VERSION;\n }\n\n if (options.unitTestRunner === 'jest') {\n devDependencies['@nx/jest'] = NX_VERSION;\n } else if (options.unitTestRunner === 'vitest') {\n devDependencies['@nx/vite'] = NX_VERSION;\n }\n\n if (options.preset === 'react') {\n // Dev-time: powers the `@nx/react:library` defaults and React generators.\n devDependencies['@nx/react'] = NX_VERSION;\n // Run-time: our React bindings always ship in the app.\n dependencies[TACTICAL_DDD_REACT] = tacticalDddReactVersion();\n\n // Only provide the React runtime when the workspace manages neither half of\n // it yet; if it already has `react` (or `react-dom`), defer to whatever\n // versions it pinned rather than re-resolving and risking a peer conflict.\n Object.assign(dependencies, reactRuntimeDependencies(tree));\n }\n\n return addDependenciesToPackageJson(tree, dependencies, devDependencies);\n}\n\n/**\n * Persists workspace-wide generator defaults into `nx.json` so choices like the\n * organization `prefix`, linter and test runner are configured once during\n * `init` and then transparently injected by Nx into every subsequent generator\n * invocation (e.g. `nx g @tactical-ddd/nx:shared-kernel`, or even the built-in\n * `nx g @nx/js:library`) without the user re-typing them.\n *\n * Two groups of defaults are written:\n *\n * \"generators\": {\n * // 1. Our own collection — inherit the prefix and linting/testing choices.\n * \"@tactical-ddd/nx\": {\n * \"shared-kernel\": { \"prefix\": \"@my-org\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" }\n * },\n * // 2. The built-in library generators — so hand-rolled libs match conventions.\n * \"@nx/js:library\": { \"bundler\": \"none\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" },\n * // `@nx/react:library` is added only under the `react` preset.\n * \"@nx/react:library\": { \"bundler\": \"none\", \"linter\": \"eslint\", \"unitTestRunner\": \"jest\" }\n * }\n */\nfunction setGeneratorDefaults(tree: Tree, options: InitGeneratorSchema) {\n const nxJson = readNxJson(tree) ?? ({} as NxJsonConfiguration);\n\n const generators = (nxJson.generators ??= {}) as Record<\n string,\n Record<string, unknown>\n >;\n\n // 1. Our own collection's generators inherit the prefix + linting/testing.\n const collectionDefaults = (generators[COLLECTION] ??= {}) as Record<\n string,\n Record<string, unknown>\n >;\n\n for (const generator of PREFIXED_GENERATORS) {\n collectionDefaults[generator] = {\n ...collectionDefaults[generator],\n prefix: options.prefix,\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n preset: options.preset,\n };\n }\n\n // 2. The built-in library generators get the same workspace-wide build/lint/\n // test defaults, so a plain `nx g @nx/js:library` (or `@nx/react:library`)\n // produces a library that already matches the Tactical DDD conventions.\n // `@nx/react:library` defaults are written only under the `react` preset, so\n // we don't advertise React tooling a non-React workspace never installed.\n const libraryDefaults: Record<string, unknown> = {\n bundler: options.bundler ?? 'none',\n linter: options.linter,\n unitTestRunner: options.unitTestRunner,\n };\n\n const libraryGenerators =\n options.preset === 'react'\n ? [...BASE_LIBRARY_GENERATORS, ...REACT_LIBRARY_GENERATORS]\n : BASE_LIBRARY_GENERATORS;\n\n for (const generator of libraryGenerators) {\n generators[generator] = {\n ...generators[generator],\n ...libraryDefaults,\n };\n }\n\n updateNxJson(tree, nxJson);\n}\n\nexport default initGenerator;\n"],"names":["initGenerator","COLLECTION","PREFIXED_GENERATORS","BASE_LIBRARY_GENERATORS","REACT_LIBRARY_GENERATORS","TACTICAL_DDD_REACT","tacticalDddReactVersion","require","version","tree","options","setGeneratorDefaults","installDependencies","ensureGeneratorDependencies","installKernel","sharedKernelGenerator","directory","sharedDirectory","prefix","linter","unitTestRunner","bundler","applyDepConstraints","DEP_CONSTRAINTS","formatFiles","runTasksInSerial","dependencies","devDependencies","NX_VERSION","preset","Object","assign","reactRuntimeDependencies","addDependenciesToPackageJson","readNxJson","nxJson","generators","collectionDefaults","generator","libraryDefaults","libraryGenerators","updateNxJson"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tactical-ddd/nx",
|
|
3
|
-
"version": "0.0.2
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"nx",
|
|
6
6
|
"nx-plugin",
|
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
"email": "kayun.artem@gmail.com",
|
|
25
25
|
"url": "https://github.com/kayun"
|
|
26
26
|
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"url": "https://github.com/kayun/tactical-ddd/tree/main/packages/nx"
|
|
29
|
+
},
|
|
27
30
|
"type": "commonjs",
|
|
28
31
|
"main": "./index.js",
|
|
29
32
|
"module": "./index.js",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* React runtime version added to the *user's* workspace under the `react`
|
|
4
|
+
* preset. `react` and `react-dom` are pinned to the *same* specifier and only
|
|
5
|
+
* ever added together (see {@link reactRuntimeDependencies}) so we never
|
|
6
|
+
* introduce a `react` vs `react-dom` version skew of our own. Kept in step with
|
|
7
|
+
* the React version `@nx/react`'s own generators install so the two never
|
|
8
|
+
* disagree.
|
|
9
|
+
*/
|
|
10
|
+
export declare const REACT_VERSION = "^19.0.0";
|
|
11
|
+
/**
|
|
12
|
+
* Whether the workspace `package.json` already declares `react` or `react-dom`
|
|
13
|
+
* (in either `dependencies` or `devDependencies`). When it does, the generators
|
|
14
|
+
* leave the React runtime untouched so they can't introduce a version skew or
|
|
15
|
+
* trigger a conflicting re-resolve.
|
|
16
|
+
*/
|
|
17
|
+
export declare function workspaceHasReactRuntime(tree: Tree): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The React runtime dependencies a generator should add: both halves at the
|
|
20
|
+
* same {@link REACT_VERSION} specifier, but only when the workspace manages
|
|
21
|
+
* neither yet. Returns `{}` when `react`/`react-dom` is already present, so we
|
|
22
|
+
* never bump a pinned version or add a second half whose floating range
|
|
23
|
+
* resolves to a patch the existing one no longer satisfies (an `ERESOLVE`).
|
|
24
|
+
*/
|
|
25
|
+
export declare function reactRuntimeDependencies(tree: Tree): Record<string, string>;
|
|
26
|
+
//# sourceMappingURL=react-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-runtime.d.ts","sourceRoot":"","sources":["../../../../packages/nx/src/utils/react-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAY5D;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS3E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get REACT_VERSION () {
|
|
13
|
+
return REACT_VERSION;
|
|
14
|
+
},
|
|
15
|
+
get reactRuntimeDependencies () {
|
|
16
|
+
return reactRuntimeDependencies;
|
|
17
|
+
},
|
|
18
|
+
get workspaceHasReactRuntime () {
|
|
19
|
+
return workspaceHasReactRuntime;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _extends = require("@swc/helpers/_/_extends");
|
|
23
|
+
const _devkit = require("@nx/devkit");
|
|
24
|
+
const REACT_VERSION = '^19.0.0';
|
|
25
|
+
function workspaceHasReactRuntime(tree) {
|
|
26
|
+
const packageJson = (0, _devkit.readJson)(tree, 'package.json');
|
|
27
|
+
const declared = _extends._({}, packageJson.devDependencies, packageJson.dependencies);
|
|
28
|
+
return 'react' in declared || 'react-dom' in declared;
|
|
29
|
+
}
|
|
30
|
+
function reactRuntimeDependencies(tree) {
|
|
31
|
+
if (workspaceHasReactRuntime(tree)) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
react: REACT_VERSION,
|
|
36
|
+
'react-dom': REACT_VERSION
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=react-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../packages/nx/src/utils/react-runtime.ts"],"sourcesContent":["import { readJson, type Tree } from '@nx/devkit';\n\n/**\n * React runtime version added to the *user's* workspace under the `react`\n * preset. `react` and `react-dom` are pinned to the *same* specifier and only\n * ever added together (see {@link reactRuntimeDependencies}) so we never\n * introduce a `react` vs `react-dom` version skew of our own. Kept in step with\n * the React version `@nx/react`'s own generators install so the two never\n * disagree.\n */\nexport const REACT_VERSION = '^19.0.0';\n\n/**\n * Whether the workspace `package.json` already declares `react` or `react-dom`\n * (in either `dependencies` or `devDependencies`). When it does, the generators\n * leave the React runtime untouched so they can't introduce a version skew or\n * trigger a conflicting re-resolve.\n */\nexport function workspaceHasReactRuntime(tree: Tree): boolean {\n const packageJson = readJson<{\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n }>(tree, 'package.json');\n\n const declared = {\n ...packageJson.devDependencies,\n ...packageJson.dependencies,\n };\n\n return 'react' in declared || 'react-dom' in declared;\n}\n\n/**\n * The React runtime dependencies a generator should add: both halves at the\n * same {@link REACT_VERSION} specifier, but only when the workspace manages\n * neither yet. Returns `{}` when `react`/`react-dom` is already present, so we\n * never bump a pinned version or add a second half whose floating range\n * resolves to a patch the existing one no longer satisfies (an `ERESOLVE`).\n */\nexport function reactRuntimeDependencies(tree: Tree): Record<string, string> {\n if (workspaceHasReactRuntime(tree)) {\n return {};\n }\n\n return {\n react: REACT_VERSION,\n 'react-dom': REACT_VERSION,\n };\n}\n"],"names":["REACT_VERSION","reactRuntimeDependencies","workspaceHasReactRuntime","tree","packageJson","readJson","declared","devDependencies","dependencies","react"],"mappings":";;;;;;;;;;;QAUaA;eAAAA;;QA6BGC;eAAAA;;QArBAC;eAAAA;;;;wBAlBoB;AAU7B,MAAMF,gBAAgB;AAQtB,SAASE,yBAAyBC,IAAU;IACjD,MAAMC,cAAcC,IAAAA,gBAAQ,EAGzBF,MAAM;IAET,MAAMG,WAAW,eACZF,YAAYG,eAAe,EAC3BH,YAAYI,YAAY;IAG7B,OAAO,WAAWF,YAAY,eAAeA;AAC/C;AASO,SAASL,yBAAyBE,IAAU;IACjD,IAAID,yBAAyBC,OAAO;QAClC,OAAO,CAAC;IACV;IAEA,OAAO;QACLM,OAAOT;QACP,aAAaA;IACf;AACF"}
|