Migrate npm detectors from Newtonsoft.Json to System.Text.Json#1572
Migrate npm detectors from Newtonsoft.Json to System.Text.Json#1572JamieMagee merged 7 commits intomainfrom
Newtonsoft.Json to System.Text.Json#1572Conversation
024756a to
a099889
Compare
|
👋 Hi! It looks like you modified some files in the
If none of the above scenarios apply, feel free to ignore this comment 🙂 |
56a1717 to
b2d4f8e
Compare
a099889 to
966e66d
Compare
ec4fb32 to
1bfb72a
Compare
966e66d to
57b8ce0
Compare
There was a problem hiding this comment.
Pull request overview
This PR completes the migration of npm detectors from Newtonsoft.Json to System.Text.Json as part of project-wide migration effort #231. The changes introduce strongly-typed models for package.json deserialization and refactor all npm detector classes to use System.Text.Json APIs.
Key changes:
- Introduced
PackageJsonmodel with custom JSON converters for polymorphic fields (author, workspaces, engines) - Refactored all npm detector base classes and implementations to use typed models instead of
JToken/JProperty - Updated utility methods to accept typed parameters instead of Newtonsoft.Json types
- Configured
JsonSerializerOptionswithAllowTrailingCommas=truefor npm JSON compatibility
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/Microsoft.ComponentDetection.Orchestrator.Tests/Experiments/LinuxApplicationLayerExperimentTests.cs | Added #nullable disable directive for consistency with existing test patterns |
| test/Microsoft.ComponentDetection.Detectors.Tests/NpmUtilitiesTests.cs | Updated tests to use new typed API signatures; removed Newtonsoft.Json imports and JProperty-based test data |
| src/Microsoft.ComponentDetection.Detectors/npm/NpmLockfileDetectorBase.cs | Refactored to use JsonDocument for lockfile parsing; introduced ProcessLockfile abstract method replacing JToken-based processing |
| src/Microsoft.ComponentDetection.Detectors/npm/NpmLockfile3Detector.cs | Implemented new ProcessLockfile method using PackageLockV3Package models; replaced JProperty traversal with typed dictionary lookups |
| src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentUtilities.cs | Updated GetTypedComponent to accept typed parameters; refactored TryGetAllPackageJsonDependencies to use PackageJson model |
| src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetectorWithRoots.cs | Implemented new ProcessLockfile method using PackageLockV1Dependency models; replaced JProperty-based dependency traversal |
| src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs | Refactored to deserialize PackageJson directly; simplified author and engines handling using typed properties |
| src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonWorkspacesConverter.cs | New custom converter handling workspaces as array or object with packages field |
| src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonEnginesConverter.cs | New custom converter handling engines as object or array (for malformed files) |
| src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonAuthorConverter.cs | New custom converter parsing author as string (with regex) or object |
| src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonAuthor.cs | New model representing package.json author field |
| src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJson.cs | New model representing package.json structure with all relevant fields |
Comments suppressed due to low confidence (1)
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentUtilities.cs:76
- These 'if' statements can be combined.
if (versionString is not null && Uri.TryCreate(versionString, UriKind.Absolute, out var parsedUri))
{
if (string.Equals(npmRegistryHost, parsedUri.Host, StringComparison.OrdinalIgnoreCase))
{
return TryParseNpmRegistryVersion(packageName, parsedUri, out version);
}
}
src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonEnginesConverter.cs
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonWorkspacesConverter.cs
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonAuthorConverter.cs
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetectorWithRoots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetectorWithRoots.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/NpmLockfile3Detector.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentUtilities.cs:76
- These 'if' statements can be combined.
if (versionString is not null && Uri.TryCreate(versionString, UriKind.Absolute, out var parsedUri))
{
if (string.Equals(npmRegistryHost, parsedUri.Host, StringComparison.OrdinalIgnoreCase))
{
return TryParseNpmRegistryVersion(packageName, parsedUri, out version);
}
}
src/Microsoft.ComponentDetection.Detectors/npm/Contracts/PackageJsonAuthorConverter.cs
Show resolved
Hide resolved
...icrosoft.ComponentDetection.Detectors.Tests/npm/Contracts/PackageJsonAuthorConverterTests.cs
Show resolved
Hide resolved
...icrosoft.ComponentDetection.Detectors.Tests/npm/Contracts/PackageJsonAuthorConverterTests.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentUtilities.cs:76
- These 'if' statements can be combined.
if (versionString is not null && Uri.TryCreate(versionString, UriKind.Absolute, out var parsedUri))
{
if (string.Equals(npmRegistryHost, parsedUri.Host, StringComparison.OrdinalIgnoreCase))
{
return TryParseNpmRegistryVersion(packageName, parsedUri, out version);
}
}
jpinz
left a comment
There was a problem hiding this comment.
Just a few nits. Also, I recently ran into an issue on dependabot-core that has to do with pnpm lockfiles, I don't think I saw anything here for pnpm, only npm and yarn. Obviously not a requirement for this PR just wanted to have it down somewhere.
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/npm/NpmComponentDetector.cs
Outdated
Show resolved
Hide resolved
Replace `Newtonsoft.Json` usage in npm detector classes with `System.Text.Json`, continuing the project-wide migration effort. Changes: - Add `PackageJson` model and related types for deserializing `package.json` files - Add custom `JsonConverters` for polymorphic fields (`author`, `workspaces`, `engines`) - Refactor `NpmComponentUtilities` to use typed parameters instead of `JProperty` - Refactor `NpmLockfileDetectorBase` to use `JsonDocument` for lockfile parsing - Update `NpmComponentDetector` to use `PackageJson` model - Update `NpmComponentDetectorWithRoots` to use `PackageLockV1Dependency` model - Update `NpmLockfile3Detector` to use `PackageLockV3Package` model - Update `NpmUtilitiesTests` to use new API signatures The existing `PackageLock` contract models (V1, V2, V3) already used `System.Text.Json`, so this change leverages those models and adds the missing `PackageJson` model. `JsonSerializerOptions` configured with `AllowTrailingCommas=true` to handle npm's JSON format which sometimes includes trailing commas.
Move closing brace for `devDependencies` inside the if block in `CreatePackageJsonFileContent` to avoid generating invalid JSON when there are no dev dependencies. `System.Text.Json` is stricter than `Newtonsoft.Json` and throws on trailing characters.
Add named capture group for URL in the author regex pattern and extract it in the converter. Previously, URLs in strings like "John Doe <email> (https://example.com)" were matched but not assigned to the Url property.
Flatten nested if statements into a single guard clause for improved readability.
7492749 to
2b1ac67
Compare
Replace
Newtonsoft.Jsonusage in npm detector classes withSystem.Text.Json, continuing the project-wide migration effort #231Changes:
PackageJsonmodel and related types for deserializingpackage.jsonfilesJsonConvertersfor polymorphic fields (author,workspaces,engines)NpmComponentUtilitiesto use typed parameters instead ofJPropertyNpmLockfileDetectorBaseto useJsonDocumentfor lockfile parsingNpmComponentDetectorto usePackageJsonmodelNpmComponentDetectorWithRootsto usePackageLockV1DependencymodelNpmLockfile3Detectorto usePackageLockV3PackagemodelNpmUtilitiesTeststo use new API signaturesThe existing
PackageLockcontract models (V1, V2, V3) already usedSystem.Text.Json, so this change leverages those models and adds the missingPackageJsonmodel.JsonSerializerOptionsconfigured withAllowTrailingCommas=trueto handle npm's JSON format which sometimes includes trailing commas.