[workspace-plugin] library generator emits "^undefined" peer versions — reads rootPkg.dependencies but framework deps live in devDependencies since E0
#742
Found while scaffolding platform-activity-tracking-api (#740). The E2a library generator (tools/workspace-plugin/src/generators/library/generator.ts:37-39) reads:
But since the E0 housekeeping (SSR strip, epic #722), @angular/core and rxjs live in root devDependencies — only tslib is still in dependencies. Generated package.json comes out as:
Two bugs: (1) look in dependencies then fall back to devDependencies; (2) tslibDep: ^${tslibVersion}`` double-prefixes because the manifest value already carries ^ — strip/normalize before prefixing.
Low stakes (these per-lib manifests are informational under ng-packagr-lite), but every future nx g @spikersoft/workspace-plugin:library output is malformed until fixed. The two libs generated in #740 were corrected by hand.
Found while scaffolding `platform-activity-tracking-api` (#740). The E2a library generator (`tools/workspace-plugin/src/generators/library/generator.ts:37-39`) reads:
```ts
const angularVersion: string = rootPkg.dependencies["@angular/core"];
const rxjsVersion: string = rootPkg.dependencies["rxjs"];
const tslibVersion: string = rootPkg.dependencies["tslib"];
```
But since the E0 housekeeping (SSR strip, epic #722), `@angular/core` and `rxjs` live in root **devDependencies** — only `tslib` is still in `dependencies`. Generated package.json comes out as:
```json
"peerDependencies": { "@angular/common": "^undefined", "@angular/core": "^undefined", "rxjs": "^undefined" },
"dependencies": { "tslib": "^^2.8.1" }
```
Two bugs: (1) look in `dependencies` then fall back to `devDependencies`; (2) `tslibDep: `^${tslibVersion}`` double-prefixes because the manifest value already carries `^` — strip/normalize before prefixing.
Low stakes (these per-lib manifests are informational under ng-packagr-lite), but every future `nx g @spikersoft/workspace-plugin:library` output is malformed until fixed. The two libs generated in #740 were corrected by hand.
Board-sweep verification (2026-07-22): bug CONFIRMED still live, root-caused exactly. tools/workspace-plugin/src/generators/library/generator.ts reads rootPkg.dependencies['@angular/core'] and ['rxjs'], but in the root package.json BOTH live under devDependencies (verified) → undefined → '^undefined' peers; tslib happens to sit in dependencies, which is why only some ranges rot. One-line fix: coalesce both maps, e.g. const dep = (k) => rootPkg.dependencies?.[k] ?? rootPkg.devDependencies?.[k]; and fail loudly if still undefined. No fix commit exists for the plugin since its E2a introduction (3c12680e).
Board-sweep verification (2026-07-22): bug CONFIRMED still live, root-caused exactly. tools/workspace-plugin/src/generators/library/generator.ts reads rootPkg.dependencies['@angular/core'] and ['rxjs'], but in the root package.json BOTH live under devDependencies (verified) → undefined → '^undefined' peers; tslib happens to sit in dependencies, which is why only some ranges rot. One-line fix: coalesce both maps, e.g. const dep = (k) => rootPkg.dependencies?.[k] ?? rootPkg.devDependencies?.[k]; and fail loudly if still undefined. No fix commit exists for the plugin since its E2a introduction (3c12680e).
No devDependencies fallback, and no loud failure when the lookup returns undefined.
The root manifest confirms the mismatch is live: package.json:78 opens "devDependencies" containing @angular/core (:92) and rxjs (:147), while "dependencies" doesn't open until :163, with tslib at :245. So two of the three resolve to undefined and emit ^undefined.
Second bug, not in the ticket body:tslib — the one that does resolve — is declared as "^2.8.1", already carrying its caret. The template then emits tslibDep: `^${tslibVersion}` → ^^2.8.1. So all three peer entries are malformed, just in two different ways. Worth fixing together, since anyone touching the ^undefined lines will be looking straight at it.
git log for that file shows exactly one commit ever — 438c4ac9, the E2a introduction. No fix has been attempted.
Remaining: read from dependencies ?? devDependencies (or merge both), strip any leading caret before re-adding one, and fail loudly rather than emitting a literal ^undefined into a generated package.json. Given the memory that a lib's package.json name must exactly match its import alias or consumer builds crash, a generator that silently emits malformed peer ranges is worth making noisy.
Re-verified against `origin/master` — **NOT DONE, and there's a second bug in the same three lines.**
`tools/workspace-plugin/src/generators/library/generator.ts` still reads all three versions from `dependencies` only:
```ts
const angularVersion: string = rootPkg.dependencies["@angular/core"];
const rxjsVersion: string = rootPkg.dependencies["rxjs"];
const tslibVersion: string = rootPkg.dependencies["tslib"];
```
No `devDependencies` fallback, and no loud failure when the lookup returns `undefined`.
The root manifest confirms the mismatch is live: `package.json:78` opens `"devDependencies"` containing `@angular/core` (`:92`) and `rxjs` (`:147`), while `"dependencies"` doesn't open until `:163`, with `tslib` at `:245`. So two of the three resolve to `undefined` and emit `^undefined`.
**Second bug, not in the ticket body:** `tslib` — the one that *does* resolve — is declared as `"^2.8.1"`, already carrying its caret. The template then emits `` tslibDep: `^${tslibVersion}` `` → **`^^2.8.1`**. So all three peer entries are malformed, just in two different ways. Worth fixing together, since anyone touching the `^undefined` lines will be looking straight at it.
`git log` for that file shows exactly **one** commit ever — `438c4ac9`, the E2a introduction. No fix has been attempted.
**Remaining:** read from `dependencies ?? devDependencies` (or merge both), strip any leading caret before re-adding one, and fail loudly rather than emitting a literal `^undefined` into a generated `package.json`. Given the memory that a lib's `package.json` name must exactly match its import alias or consumer builds crash, a generator that silently emits malformed peer ranges is worth making noisy.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found while scaffolding
platform-activity-tracking-api(#740). The E2a library generator (tools/workspace-plugin/src/generators/library/generator.ts:37-39) reads:But since the E0 housekeeping (SSR strip, epic #722),
@angular/coreandrxjslive in root devDependencies — onlytslibis still independencies. Generated package.json comes out as:Two bugs: (1) look in
dependenciesthen fall back todevDependencies; (2)tslibDep:^${tslibVersion}`` double-prefixes because the manifest value already carries^— strip/normalize before prefixing.Low stakes (these per-lib manifests are informational under ng-packagr-lite), but every future
nx g @spikersoft/workspace-plugin:libraryoutput is malformed until fixed. The two libs generated in #740 were corrected by hand.Board-sweep verification (2026-07-22): bug CONFIRMED still live, root-caused exactly. tools/workspace-plugin/src/generators/library/generator.ts reads rootPkg.dependencies['@angular/core'] and ['rxjs'], but in the root package.json BOTH live under devDependencies (verified) → undefined → '^undefined' peers; tslib happens to sit in dependencies, which is why only some ranges rot. One-line fix: coalesce both maps, e.g. const dep = (k) => rootPkg.dependencies?.[k] ?? rootPkg.devDependencies?.[k]; and fail loudly if still undefined. No fix commit exists for the plugin since its E2a introduction (3c12680e).
Re-verified against
origin/master— NOT DONE, and there's a second bug in the same three lines.tools/workspace-plugin/src/generators/library/generator.tsstill reads all three versions fromdependenciesonly:No
devDependenciesfallback, and no loud failure when the lookup returnsundefined.The root manifest confirms the mismatch is live:
package.json:78opens"devDependencies"containing@angular/core(:92) andrxjs(:147), while"dependencies"doesn't open until:163, withtslibat:245. So two of the three resolve toundefinedand emit^undefined.Second bug, not in the ticket body:
tslib— the one that does resolve — is declared as"^2.8.1", already carrying its caret. The template then emitstslibDep: `^${tslibVersion}`→^^2.8.1. So all three peer entries are malformed, just in two different ways. Worth fixing together, since anyone touching the^undefinedlines will be looking straight at it.git logfor that file shows exactly one commit ever —438c4ac9, the E2a introduction. No fix has been attempted.Remaining: read from
dependencies ?? devDependencies(or merge both), strip any leading caret before re-adding one, and fail loudly rather than emitting a literal^undefinedinto a generatedpackage.json. Given the memory that a lib'spackage.jsonname must exactly match its import alias or consumer builds crash, a generator that silently emits malformed peer ranges is worth making noisy.