@tactical-ddd/nx 0.0.2-alpha.2 → 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 -5
- package/generators/domain/domain.js.map +1 -1
- package/generators/init/init.d.ts.map +1 -1
- package/generators/init/init.js +17 -11
- package/generators/init/init.js.map +1 -1
- package/generators/shared-kernel/files/contracts/README.md +24 -0
- package/generators/shared-kernel/files/infrastructure/README.md +26 -0
- package/generators/shared-kernel/files/utils/README.md +26 -0
- package/generators/shared-kernel/shared-kernel.d.ts.map +1 -1
- package/generators/shared-kernel/shared-kernel.js +18 -10
- package/generators/shared-kernel/shared-kernel.js.map +1 -1
- package/package.json +4 -1
- package/utils/library-exist.d.ts +10 -3
- package/utils/library-exist.d.ts.map +1 -1
- package/utils/library-exist.js +1 -1
- package/utils/library-exist.js.map +1 -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
|
|
@@ -48,7 +49,6 @@ async function domainGenerator(tree, options) {
|
|
|
48
49
|
tasks.push(await (0, _js.libraryGenerator)(tree, {
|
|
49
50
|
name: layerName(options, 'contracts'),
|
|
50
51
|
directory: contractsRoot,
|
|
51
|
-
useProjectJson: false,
|
|
52
52
|
addPlugin: true,
|
|
53
53
|
unitTestRunner: 'none',
|
|
54
54
|
bundler: options.bundler,
|
|
@@ -70,7 +70,6 @@ async function domainGenerator(tree, options) {
|
|
|
70
70
|
tasks.push(await (0, _js.libraryGenerator)(tree, {
|
|
71
71
|
name: layerName(options, 'core'),
|
|
72
72
|
directory: coreRoot,
|
|
73
|
-
useProjectJson: false,
|
|
74
73
|
addPlugin: true,
|
|
75
74
|
unitTestRunner: options.unitTestRunner,
|
|
76
75
|
bundler: options.bundler,
|
|
@@ -126,6 +125,13 @@ async function domainGenerator(tree, options) {
|
|
|
126
125
|
tags: `${_types.LibraryScope.Domain},${domainTag},${_types.LibraryType.Features}`
|
|
127
126
|
}));
|
|
128
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
|
+
}
|
|
129
135
|
// Silo this domain: per-domain constraints are what actually prevent
|
|
130
136
|
// cross-domain imports (a static `domain:*` rule cannot — Nx glob-matches the
|
|
131
137
|
// target tags, so it would let `domain:auth` import `domain:payments`).
|
|
@@ -166,22 +172,27 @@ async function domainGenerator(tree, options) {
|
|
|
166
172
|
*/ async function generateLayerLibrary(tree, options, layer) {
|
|
167
173
|
if (options.preset === 'react') {
|
|
168
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.
|
|
169
181
|
return await reactLibraryGenerator(tree, {
|
|
170
182
|
name: layer.name,
|
|
171
183
|
directory: layer.root,
|
|
172
|
-
useProjectJson: false,
|
|
173
184
|
addPlugin: true,
|
|
174
185
|
unitTestRunner: options.unitTestRunner,
|
|
175
186
|
bundler: options.bundler,
|
|
176
187
|
linter: options.linter,
|
|
177
188
|
style: 'none',
|
|
178
|
-
tags: layer.tags
|
|
189
|
+
tags: layer.tags,
|
|
190
|
+
skipPackageJson: true
|
|
179
191
|
});
|
|
180
192
|
}
|
|
181
193
|
const task = await (0, _js.libraryGenerator)(tree, {
|
|
182
194
|
name: layer.name,
|
|
183
195
|
directory: layer.root,
|
|
184
|
-
useProjectJson: false,
|
|
185
196
|
addPlugin: true,
|
|
186
197
|
unitTestRunner: options.unitTestRunner,
|
|
187
198
|
bundler: options.bundler,
|
|
@@ -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 useProjectJson: false,\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 useProjectJson: false,\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 useProjectJson: false,\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 useProjectJson: false,\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","useProjectJson","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,EAOL,KAAK,iBAAiB,EAEtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;
|
|
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,12 +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 versions added to the *user's* workspace under the `react`
|
|
51
|
-
* preset. Kept in step with the React version `@nx/react`'s own generators
|
|
52
|
-
* install so the two never disagree.
|
|
53
|
-
*/ const REACT_VERSION = '^19.0.0';
|
|
54
|
-
const REACT_DOM_VERSION = '^19.0.0';
|
|
55
50
|
/**
|
|
56
51
|
* Version specifier to install `@tactical-ddd/react` at. The React bindings are
|
|
57
52
|
* released in lockstep with this plugin, so we mirror the running plugin's own
|
|
@@ -106,8 +101,17 @@ async function initGenerator(tree, options) {
|
|
|
106
101
|
* Dependencies are scoped to the chosen options: the ESLint tooling is only
|
|
107
102
|
* required when `linter: 'eslint'`, and the test-runner plugin follows
|
|
108
103
|
* `unitTestRunner`. The `react` preset additionally pulls in the `@nx/react`
|
|
109
|
-
* generator plugin (dev-time) plus the
|
|
110
|
-
*
|
|
104
|
+
* generator plugin (dev-time) plus the `@tactical-ddd/react` bindings as a
|
|
105
|
+
* production dependency.
|
|
106
|
+
*
|
|
107
|
+
* The `react`/`react-dom` runtime is treated carefully: a React workspace
|
|
108
|
+
* already ships its own React, and declaring our own range on top adds nothing
|
|
109
|
+
* but forces the package manager to re-resolve — which can surface a latent
|
|
110
|
+
* peer-dependency conflict already present in the workspace (e.g. an exactly
|
|
111
|
+
* pinned `react` that a newer `react-dom` patch no longer satisfies) and abort
|
|
112
|
+
* the install. So we only add `react` and `react-dom` when *neither* is already
|
|
113
|
+
* present, and add them together at the same {@link REACT_VERSION} specifier —
|
|
114
|
+
* never introducing a skew of our own.
|
|
111
115
|
*/ function ensureGeneratorDependencies(tree, options) {
|
|
112
116
|
const dependencies = {};
|
|
113
117
|
const devDependencies = {
|
|
@@ -129,10 +133,12 @@ async function initGenerator(tree, options) {
|
|
|
129
133
|
if (options.preset === 'react') {
|
|
130
134
|
// Dev-time: powers the `@nx/react:library` defaults and React generators.
|
|
131
135
|
devDependencies['@nx/react'] = _devkit.NX_VERSION;
|
|
132
|
-
// Run-time:
|
|
133
|
-
dependencies['react'] = REACT_VERSION;
|
|
134
|
-
dependencies['react-dom'] = REACT_DOM_VERSION;
|
|
136
|
+
// Run-time: our React bindings always ship in the app.
|
|
135
137
|
dependencies[TACTICAL_DDD_REACT] = tacticalDddReactVersion();
|
|
138
|
+
// Only provide the React runtime when the workspace manages neither half of
|
|
139
|
+
// it yet; if it already has `react` (or `react-dom`), defer to whatever
|
|
140
|
+
// versions it pinned rather than re-resolving and risking a peer conflict.
|
|
141
|
+
Object.assign(dependencies, (0, _reactruntime.reactRuntimeDependencies)(tree));
|
|
136
142
|
}
|
|
137
143
|
return (0, _devkit.addDependenciesToPackageJson)(tree, dependencies, devDependencies);
|
|
138
144
|
}
|
|
@@ -1 +1 @@
|
|
|
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 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 versions added to the *user's* workspace under the `react`\n * preset. Kept in step with the React version `@nx/react`'s own generators\n * install so the two never disagree.\n */\nconst REACT_VERSION = '^19.0.0';\nconst REACT_DOM_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 React runtime — `react`, `react-dom`\n * and the `@tactical-ddd/react` bindings — as production dependencies.\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: the React framework and our React bindings ship in the app.\n dependencies['react'] = REACT_VERSION;\n dependencies['react-dom'] = REACT_DOM_VERSION;\n dependencies[TACTICAL_DDD_REACT] = tacticalDddReactVersion();\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","REACT_VERSION","REACT_DOM_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","addDependenciesToPackageJson","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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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# <%= prefix ? prefix + '/' : '' %>shared-contracts
|
|
2
|
+
|
|
3
|
+
Global, framework-agnostic **contracts** for the whole workspace — the published
|
|
4
|
+
language every layer is allowed to depend on.
|
|
5
|
+
|
|
6
|
+
- **Tags:** `scope:shared`, `type:contracts`
|
|
7
|
+
- **May import:** nothing. This is the root of the dependency graph.
|
|
8
|
+
- **Contains:** type-level declarations only — no runtime logic, no framework code.
|
|
9
|
+
|
|
10
|
+
## What goes here
|
|
11
|
+
|
|
12
|
+
- Cross-cutting interfaces and their DI tokens (e.g. `HttpClient`, `Store`).
|
|
13
|
+
- Shared DTOs and API request/response shapes.
|
|
14
|
+
- Global type aliases, enums and union types reused across domains.
|
|
15
|
+
|
|
16
|
+
Anything here can be imported by `shared/*` and by every domain's `contracts`
|
|
17
|
+
and `core`, so keep it stable and intentionally small.
|
|
18
|
+
|
|
19
|
+
## What does NOT go here
|
|
20
|
+
|
|
21
|
+
- Implementations of these interfaces — those live in `shared/infrastructure`
|
|
22
|
+
(or a domain's `core`), wired up via DI.
|
|
23
|
+
- Domain-specific contracts — those belong in `libs/<domain>/contracts`.
|
|
24
|
+
- Anything that imports another library.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# <%= prefix ? prefix + '/' : '' %>shared-infrastructure
|
|
2
|
+
|
|
3
|
+
Global, workspace-wide **infrastructure** — the concrete adapters that implement
|
|
4
|
+
the abstractions declared in `shared-contracts`.
|
|
5
|
+
|
|
6
|
+
- **Tags:** `scope:shared`, `type:infrastructure`
|
|
7
|
+
- **May import:** `shared-contracts` only.
|
|
8
|
+
- **Contains:** runtime implementations of cross-cutting technical concerns.
|
|
9
|
+
|
|
10
|
+
## What goes here
|
|
11
|
+
|
|
12
|
+
- HTTP/WS clients and `fetch`/`axios` wrappers implementing `HttpClient`.
|
|
13
|
+
- Storage adapters implementing `Store` (localStorage, cookies, in-memory…).
|
|
14
|
+
- Core data-layer setup shared across domains (e.g. `@tanstack/query-core`
|
|
15
|
+
query client configuration).
|
|
16
|
+
|
|
17
|
+
These implementations are wired into consumers via DI tokens from
|
|
18
|
+
`shared-contracts`, so application and domain code depends on the interface,
|
|
19
|
+
never on this library directly.
|
|
20
|
+
|
|
21
|
+
## What does NOT go here
|
|
22
|
+
|
|
23
|
+
- Type/interface declarations — those belong in `shared-contracts`.
|
|
24
|
+
- Pure, dependency-free helpers — those belong in `shared-utils`.
|
|
25
|
+
- Domain or business logic — that belongs in `libs/<domain>/core`.
|
|
26
|
+
- Imports from any domain library or `shared-utils`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# <%= prefix ? prefix + '/' : '' %>shared-utils
|
|
2
|
+
|
|
3
|
+
Global, framework-agnostic **utilities** — pure helper functions reused across
|
|
4
|
+
the whole workspace.
|
|
5
|
+
|
|
6
|
+
- **Tags:** `scope:shared`, `type:utils`
|
|
7
|
+
- **May import:** `shared-contracts` only.
|
|
8
|
+
- **Contains:** small, side-effect-free functions with no framework or I/O
|
|
9
|
+
dependencies.
|
|
10
|
+
|
|
11
|
+
## What goes here
|
|
12
|
+
|
|
13
|
+
- Date/time formatters and parsers.
|
|
14
|
+
- String, number and math helpers.
|
|
15
|
+
- Array/object transformation utilities, type guards and predicates.
|
|
16
|
+
|
|
17
|
+
Functions here should be deterministic and dependency-light, so they are safe to
|
|
18
|
+
import from anywhere (`shared/*` and every domain's `contracts`/`core`).
|
|
19
|
+
|
|
20
|
+
## What does NOT go here
|
|
21
|
+
|
|
22
|
+
- Interfaces/types — those belong in `shared-contracts`.
|
|
23
|
+
- Anything doing I/O, network or storage — that belongs in
|
|
24
|
+
`shared-infrastructure`.
|
|
25
|
+
- Domain or business logic — that belongs in `libs/<domain>/core`.
|
|
26
|
+
- Imports from any domain library or `shared-infrastructure`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-kernel.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/shared-kernel/shared-kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAM5D,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"shared-kernel.d.ts","sourceRoot":"","sources":["../../../../../packages/nx/src/generators/shared-kernel/shared-kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAM5D,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CA+G5B;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -37,22 +37,22 @@ async function sharedKernelGenerator(tree, options) {
|
|
|
37
37
|
// deprecated executor targets instead of inferred tasks (Project Crystal).
|
|
38
38
|
const tasks = [];
|
|
39
39
|
if (!(0, _libraryexist.libraryExists)(tree, contractsRoot)) {
|
|
40
|
+
var _options_prefix;
|
|
40
41
|
(0, _logger.info)(`Creating contracts library at ${contractsRoot}...`);
|
|
41
42
|
tasks.push(await (0, _js.libraryGenerator)(tree, {
|
|
42
43
|
name: options.prefix ? `${options.prefix}/shared-contracts` : 'shared-contracts',
|
|
43
44
|
directory: contractsRoot,
|
|
44
|
-
useProjectJson: false,
|
|
45
45
|
addPlugin: true,
|
|
46
46
|
unitTestRunner: 'none',
|
|
47
47
|
bundler: options.bundler,
|
|
48
48
|
linter: options.linter,
|
|
49
|
-
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Contracts}
|
|
50
|
-
minimal: true
|
|
49
|
+
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Contracts}`
|
|
51
50
|
}));
|
|
52
51
|
const type = (0, _resolvemoduleformat.resolveLibraryModuleFormat)(tree, contractsRoot);
|
|
53
52
|
tree.delete(`${contractsRoot}/src/lib/shared-contracts.ts`);
|
|
54
53
|
(0, _devkit.generateFiles)(tree, (0, _path.resolve)(__dirname, 'files/contracts'), contractsRoot, {
|
|
55
|
-
esm: type === _types.ModuleFormat.EsModule
|
|
54
|
+
esm: type === _types.ModuleFormat.EsModule,
|
|
55
|
+
prefix: (_options_prefix = options.prefix) != null ? _options_prefix : ''
|
|
56
56
|
}, {
|
|
57
57
|
overwriteStrategy: _devkit.OverwriteStrategy.Overwrite
|
|
58
58
|
});
|
|
@@ -60,40 +60,48 @@ async function sharedKernelGenerator(tree, options) {
|
|
|
60
60
|
(0, _logger.info)(`Contracts library already exists at ${contractsRoot}`);
|
|
61
61
|
}
|
|
62
62
|
if (!(0, _libraryexist.libraryExists)(tree, utilsRoot)) {
|
|
63
|
+
var _options_prefix1;
|
|
63
64
|
(0, _logger.info)(`Creating utils library at ${utilsRoot}...`);
|
|
64
65
|
tasks.push(await (0, _js.libraryGenerator)(tree, {
|
|
65
66
|
name: options.prefix ? `${options.prefix}/shared-utils` : 'shared-utils',
|
|
66
67
|
directory: utilsRoot,
|
|
67
|
-
useProjectJson: false,
|
|
68
68
|
addPlugin: true,
|
|
69
69
|
unitTestRunner: options.unitTestRunner,
|
|
70
70
|
bundler: options.bundler,
|
|
71
71
|
linter: options.linter,
|
|
72
|
-
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Utils}
|
|
73
|
-
minimal: true
|
|
72
|
+
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Utils}`
|
|
74
73
|
}));
|
|
75
74
|
tree.delete(`${utilsRoot}/src/lib/shared-utils.ts`);
|
|
76
75
|
tree.delete(`${utilsRoot}/src/lib/shared-utils.spec.ts`);
|
|
77
76
|
tree.write(`${utilsRoot}/src/index.ts`, '');
|
|
77
|
+
(0, _devkit.generateFiles)(tree, (0, _path.resolve)(__dirname, 'files/utils'), utilsRoot, {
|
|
78
|
+
prefix: (_options_prefix1 = options.prefix) != null ? _options_prefix1 : ''
|
|
79
|
+
}, {
|
|
80
|
+
overwriteStrategy: _devkit.OverwriteStrategy.Overwrite
|
|
81
|
+
});
|
|
78
82
|
} else {
|
|
79
83
|
(0, _logger.info)(`Utils library already exists at ${utilsRoot}`);
|
|
80
84
|
}
|
|
81
85
|
if (!(0, _libraryexist.libraryExists)(tree, infrastructureRoot)) {
|
|
86
|
+
var _options_prefix2;
|
|
82
87
|
(0, _logger.info)(`Creating infrastructure library at ${infrastructureRoot}...`);
|
|
83
88
|
tasks.push(await (0, _js.libraryGenerator)(tree, {
|
|
84
89
|
name: options.prefix ? `${options.prefix}/shared-infrastructure` : 'shared-infrastructure',
|
|
85
90
|
directory: infrastructureRoot,
|
|
86
|
-
useProjectJson: false,
|
|
87
91
|
addPlugin: true,
|
|
88
92
|
unitTestRunner: options.unitTestRunner,
|
|
89
93
|
bundler: options.bundler,
|
|
90
94
|
linter: options.linter,
|
|
91
|
-
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Infrastructure}
|
|
92
|
-
minimal: true
|
|
95
|
+
tags: `${_types.LibraryScope.Shared},${_types.LibraryType.Infrastructure}`
|
|
93
96
|
}));
|
|
94
97
|
tree.delete(`${infrastructureRoot}/src/lib/shared-infrastructure.ts`);
|
|
95
98
|
tree.delete(`${infrastructureRoot}/src/lib/shared-infrastructure.spec.ts`);
|
|
96
99
|
tree.write(`${infrastructureRoot}/src/index.ts`, '');
|
|
100
|
+
(0, _devkit.generateFiles)(tree, (0, _path.resolve)(__dirname, 'files/infrastructure'), infrastructureRoot, {
|
|
101
|
+
prefix: (_options_prefix2 = options.prefix) != null ? _options_prefix2 : ''
|
|
102
|
+
}, {
|
|
103
|
+
overwriteStrategy: _devkit.OverwriteStrategy.Overwrite
|
|
104
|
+
});
|
|
97
105
|
} else {
|
|
98
106
|
(0, _logger.info)(`Infrastructure library already exists at ${infrastructureRoot}`);
|
|
99
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx/src/generators/shared-kernel/shared-kernel.ts"],"sourcesContent":["import {\n formatFiles,\n generateFiles,\n OverwriteStrategy,\n runTasksInSerial,\n type GeneratorCallback,\n type Tree,\n} from '@nx/devkit';\nimport { libraryGenerator } from '@nx/js';\nimport { resolve } from 'path';\n\nimport type { SharedKernelGeneratorSchema } from './schema';\nimport { LibraryScope, LibraryType, ModuleFormat } from '../../types';\nimport { resolveLibraryModuleFormat } from '../../utils/resolve-module-format';\nimport { libraryExists } from '../../utils/library-exist';\nimport { info } from '../../utils/logger';\n\nexport async function sharedKernelGenerator(\n tree: Tree,\n options: SharedKernelGeneratorSchema,\n): Promise<GeneratorCallback> {\n const sharedDirectory = options.directory;\n const contractsRoot = `${sharedDirectory}/contracts`;\n const utilsRoot = `${sharedDirectory}/utils`;\n const infrastructureRoot = `${sharedDirectory}/infrastructure`;\n\n // Install callbacks returned by the delegated `@nx/js:library` generator.\n // They must be returned to Nx so the packages backing the inferred plugins\n // registered via `addPlugin` — `@nx/eslint`, `@nx/jest` — actually get\n // installed; otherwise nx.json references plugins Nx cannot load on the next\n // command. Every library also passes `addPlugin: true`: the `@nx/js` public\n // wrapper defaults it to `false`, which makes the delegated generators emit\n // deprecated executor targets instead of inferred tasks (Project Crystal).\n const tasks: GeneratorCallback[] = [];\n\n if (!libraryExists(tree, contractsRoot)) {\n info(`Creating contracts library at ${contractsRoot}...`);\n\n tasks.push(\n await libraryGenerator(tree, {\n name: options.prefix\n ? `${options.prefix}/shared-contracts`\n : 'shared-contracts',\n directory: contractsRoot,\n
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx/src/generators/shared-kernel/shared-kernel.ts"],"sourcesContent":["import {\n formatFiles,\n generateFiles,\n OverwriteStrategy,\n runTasksInSerial,\n type GeneratorCallback,\n type Tree,\n} from '@nx/devkit';\nimport { libraryGenerator } from '@nx/js';\nimport { resolve } from 'path';\n\nimport type { SharedKernelGeneratorSchema } from './schema';\nimport { LibraryScope, LibraryType, ModuleFormat } from '../../types';\nimport { resolveLibraryModuleFormat } from '../../utils/resolve-module-format';\nimport { libraryExists } from '../../utils/library-exist';\nimport { info } from '../../utils/logger';\n\nexport async function sharedKernelGenerator(\n tree: Tree,\n options: SharedKernelGeneratorSchema,\n): Promise<GeneratorCallback> {\n const sharedDirectory = options.directory;\n const contractsRoot = `${sharedDirectory}/contracts`;\n const utilsRoot = `${sharedDirectory}/utils`;\n const infrastructureRoot = `${sharedDirectory}/infrastructure`;\n\n // Install callbacks returned by the delegated `@nx/js:library` generator.\n // They must be returned to Nx so the packages backing the inferred plugins\n // registered via `addPlugin` — `@nx/eslint`, `@nx/jest` — actually get\n // installed; otherwise nx.json references plugins Nx cannot load on the next\n // command. Every library also passes `addPlugin: true`: the `@nx/js` public\n // wrapper defaults it to `false`, which makes the delegated generators emit\n // deprecated executor targets instead of inferred tasks (Project Crystal).\n const tasks: GeneratorCallback[] = [];\n\n if (!libraryExists(tree, contractsRoot)) {\n info(`Creating contracts library at ${contractsRoot}...`);\n\n tasks.push(\n await libraryGenerator(tree, {\n name: options.prefix\n ? `${options.prefix}/shared-contracts`\n : 'shared-contracts',\n directory: contractsRoot,\n addPlugin: true,\n unitTestRunner: 'none',\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Shared},${LibraryType.Contracts}`,\n }),\n );\n\n const type = resolveLibraryModuleFormat(tree, contractsRoot);\n\n tree.delete(`${contractsRoot}/src/lib/shared-contracts.ts`);\n generateFiles(\n tree,\n resolve(__dirname, 'files/contracts'),\n contractsRoot,\n { esm: type === ModuleFormat.EsModule, prefix: options.prefix ?? '' },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n } else {\n info(`Contracts library already exists at ${contractsRoot}`);\n }\n\n if (!libraryExists(tree, utilsRoot)) {\n info(`Creating utils library at ${utilsRoot}...`);\n\n tasks.push(\n await libraryGenerator(tree, {\n name: options.prefix\n ? `${options.prefix}/shared-utils`\n : 'shared-utils',\n directory: utilsRoot,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Shared},${LibraryType.Utils}`,\n }),\n );\n\n tree.delete(`${utilsRoot}/src/lib/shared-utils.ts`);\n tree.delete(`${utilsRoot}/src/lib/shared-utils.spec.ts`);\n tree.write(`${utilsRoot}/src/index.ts`, '');\n generateFiles(\n tree,\n resolve(__dirname, 'files/utils'),\n utilsRoot,\n { prefix: options.prefix ?? '' },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n } else {\n info(`Utils library already exists at ${utilsRoot}`);\n }\n\n if (!libraryExists(tree, infrastructureRoot)) {\n info(`Creating infrastructure library at ${infrastructureRoot}...`);\n\n tasks.push(\n await libraryGenerator(tree, {\n name: options.prefix\n ? `${options.prefix}/shared-infrastructure`\n : 'shared-infrastructure',\n directory: infrastructureRoot,\n addPlugin: true,\n unitTestRunner: options.unitTestRunner,\n bundler: options.bundler,\n linter: options.linter,\n tags: `${LibraryScope.Shared},${LibraryType.Infrastructure}`,\n }),\n );\n\n tree.delete(`${infrastructureRoot}/src/lib/shared-infrastructure.ts`);\n tree.delete(`${infrastructureRoot}/src/lib/shared-infrastructure.spec.ts`);\n tree.write(`${infrastructureRoot}/src/index.ts`, '');\n generateFiles(\n tree,\n resolve(__dirname, 'files/infrastructure'),\n infrastructureRoot,\n { prefix: options.prefix ?? '' },\n { overwriteStrategy: OverwriteStrategy.Overwrite },\n );\n } else {\n info(`Infrastructure library already exists at ${infrastructureRoot}`);\n }\n\n await formatFiles(tree);\n\n return runTasksInSerial(...tasks);\n}\n\nexport default sharedKernelGenerator;\n"],"names":["sharedKernelGenerator","tree","options","sharedDirectory","directory","contractsRoot","utilsRoot","infrastructureRoot","tasks","libraryExists","info","push","libraryGenerator","name","prefix","addPlugin","unitTestRunner","bundler","linter","tags","LibraryScope","Shared","LibraryType","Contracts","type","resolveLibraryModuleFormat","delete","generateFiles","resolve","__dirname","esm","ModuleFormat","EsModule","overwriteStrategy","OverwriteStrategy","Overwrite","Utils","write","Infrastructure","formatFiles","runTasksInSerial"],"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",
|
package/utils/library-exist.d.ts
CHANGED
|
@@ -2,11 +2,18 @@ import { Tree } from '@nx/devkit';
|
|
|
2
2
|
/**
|
|
3
3
|
* Whether a kernel library has actually been generated at `root`.
|
|
4
4
|
*
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
* We key off the library's project manifest rather than the directory:
|
|
6
8
|
* `tree.exists(root)` is `true` for *any* existing directory — including an
|
|
7
9
|
* empty leftover from an aborted run — which would make the generator wrongly
|
|
8
|
-
* skip a layer that has no files in it.
|
|
9
|
-
*
|
|
10
|
+
* skip a layer that has no files in it.
|
|
11
|
+
*
|
|
12
|
+
* `@nx/js:library` writes its configuration to whichever manifest suits the
|
|
13
|
+
* workspace: `project.json` in an integrated (tsconfig-paths) workspace, or the
|
|
14
|
+
* `package.json` `nx` block in a package-manager-workspaces (TS solution) one —
|
|
15
|
+
* and in the latter the bundler-less case may leave only `project.json`. Either
|
|
16
|
+
* manifest existing is a reliable marker that the library was scaffolded.
|
|
10
17
|
*/
|
|
11
18
|
export declare function libraryExists(tree: Tree, root: string): boolean;
|
|
12
19
|
//# sourceMappingURL=library-exist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library-exist.d.ts","sourceRoot":"","sources":["../../../../packages/nx/src/utils/library-exist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"library-exist.d.ts","sourceRoot":"","sources":["../../../../packages/nx/src/utils/library-exist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAI/D"}
|
package/utils/library-exist.js
CHANGED
|
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "libraryExists", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
function libraryExists(tree, root) {
|
|
12
|
-
return tree.exists(`${root}/package.json`);
|
|
12
|
+
return tree.exists(`${root}/package.json`) || tree.exists(`${root}/project.json`);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
//# sourceMappingURL=library-exist.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../packages/nx/src/utils/library-exist.ts"],"sourcesContent":["import { Tree } from '@nx/devkit';\n\n/**\n * Whether a kernel library has actually been generated at `root`.\n *\n * We key off the library manifest
|
|
1
|
+
{"version":3,"sources":["../../../../packages/nx/src/utils/library-exist.ts"],"sourcesContent":["import { Tree } from '@nx/devkit';\n\n/**\n * Whether a kernel library has actually been generated at `root`.\n *\n\n\n * We key off the library's project manifest rather than the directory:\n * `tree.exists(root)` is `true` for *any* existing directory — including an\n * empty leftover from an aborted run — which would make the generator wrongly\n * skip a layer that has no files in it.\n *\n * `@nx/js:library` writes its configuration to whichever manifest suits the\n * workspace: `project.json` in an integrated (tsconfig-paths) workspace, or the\n * `package.json` `nx` block in a package-manager-workspaces (TS solution) one —\n * and in the latter the bundler-less case may leave only `project.json`. Either\n * manifest existing is a reliable marker that the library was scaffolded.\n */\nexport function libraryExists(tree: Tree, root: string): boolean {\n return (\n tree.exists(`${root}/package.json`) || tree.exists(`${root}/project.json`)\n );\n}\n"],"names":["libraryExists","tree","root","exists"],"mappings":";;;;+BAkBgBA;;;eAAAA;;;AAAT,SAASA,cAAcC,IAAU,EAAEC,IAAY;IACpD,OACED,KAAKE,MAAM,CAAC,GAAGD,KAAK,aAAa,CAAC,KAAKD,KAAKE,MAAM,CAAC,GAAGD,KAAK,aAAa,CAAC;AAE7E"}
|
|
@@ -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"}
|