refactor: replace hand-rolled helpers with the library calls that already ship - #414
Merged
Merged
Conversation
Contributor
File size check0 over a hard cap (fails), 30 warning(s).
Split the file, wrap the line, shorten or exempt the comment, or list the path in 5 managed file(s) skipped; repo-platform owns them. |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The refactors preserve supported behavior and are backed by comprehensive validation and test coverage.
Review effort: Balanced
Findings: None
What changed in this PR
Replaces custom helpers with standard library APIs and consolidates duplicated utilities without changing supported behavior.
Changes:
- Uses native path, equality, query, set, and regex helpers.
- Centralizes shared value lookup and environment error construction.
- Updates ES library typings while retaining the ES2022 target.
| File | Description |
|---|---|
tsconfig.json |
Enables ES2025 API typings. |
.github/scripts/gen-action-docs.ts |
Uses RegExp.escape. |
.github/scripts/gen-docs.ts |
Uses RegExp.escape. |
.github/scripts/lib/generated-regions.ts |
Removes the custom regex escaping helper. |
src/discovery/central.ts |
Uses Node path APIs for YAML filenames. |
src/engine/validate.ts |
Reuses path lookup and Zod path formatting. |
src/sections/contract/endpoints.ts |
Uses URLSearchParams. |
src/sections/contract/live.ts |
Uses Zod path formatting. |
src/sections/contract/permissions.ts |
Uses Set.isSubsetOf. |
src/sections/custom_properties/index.ts |
Uses native set comparison. |
src/sections/environments/branch-policies.ts |
Reuses the shared failure builder. |
src/sections/environments/endpoints.ts |
Adds the shared failure builder. |
src/sections/environments/protection-rules.ts |
Reuses the shared failure builder. |
src/sections/rulesets/schema.ts |
Uses Zod path formatting. |
src/sections/secret_scanning_custom_patterns/index.ts |
Uses strict deep equality. |
src/sections/secret_scanning_custom_patterns/schema.ts |
Uses Zod path formatting. |
src/sections/shared/list-section.ts |
Exports the shared own-property lookup. |
test/docs/markdown.ts |
Uses native regex escaping. |
test/e2e/foundation.test.ts |
Uses native regex escaping. |
test/flows/snapshot.test.ts |
Uses native regex escaping. |
test/scripts/release-pipeline.test.ts |
Uses native regex escaping. |
test/sections/docs-registry.test.ts |
Uses native regex escaping. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…eady ship zod issue paths render through z.core.toDotPath at the four sites that each spelled their own join, so a key with a non-word character reads as ["my-key"] instead of .my-key. The secret scanning pattern comparison uses isDeepStrictEqual from node:util instead of JSON.stringify equality. The two set-equality helpers use Set.prototype.isSubsetOf, and the tsconfig lib moves from ES2022 to ES2025 for its types while the target stays ES2022. The REST query string is built by URLSearchParams, which writes a space as + where encodeURIComponent wrote %20; GitHub decodes both. Central-mode file names go through extname and parse from node:path instead of a YAML extension regex. valueAt has one home in the shared list-section module, the two environments modules share one unreconcilable message builder, and the generator scripts call RegExp.escape instead of a local escapeRe.
Vivswan
force-pushed
the
wt/lib-swaps
branch
from
September 22, 2026 09:53
42d050a to
ec6d9ed
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Six hand-rolled helpers become the library call that already ships, and three duplicated helpers get one home each.
Before / After
Same input, same output for everything the code receives today, except these three.
labels[1].color has no empty state,rulesets[0].rules[0]: parameters.grouping_strategy: ...,(body)) renders the same.+(application/x-www-form-urlencoded); GitHub decodes+and%20alike. It also percent-encodes!'()~, which decode the same.extname, so a file named exactly.ymlis ignored with the not-a-YAML warning instead of failing as the empty slug.How
lib: ES2022 -> ES2025 for theSet.prototype.isSubsetOfandRegExp.escapetypes;targetstays ES2022. Node 22.14 (theenginesfloor) shipsisSubsetOf;RegExp.escapeis called only from.github/scriptsandtest/, which run under bun 1.4.2 (.bun-version).unreconcilablehome isenvironments/endpoints.tsbecause it imported nothing from its sibling modules, so it cannot close a cycle with them; a first draft innested.tsmade a runtime cycle (nested.ts imports both callers), which the review caught.Proof
bun test test/engine test/sections test/discovery test/github test/scripts test/docs test/flows/snapshot.test.ts test/e2e/foundation.test.ts-> 2826 pass, 0 fail (rerun after the rebase onto the folded test layout); no test assertion edited.bun run test:e2e --sections custom_properties,secret_scanning_custom_patterns,rulesets-> 42/42; the full e2e once, because validate.ts renders every section's parse messages -> 368/368.bun -e 'import "./src/sections/environments/branch-policies.ts"; import "./src/sections/environments/protection-rules.ts"'succeeds (it threw on the nested.ts draft).Technical details
Per-swap unchanged-output evidence (old expression vs new, same input):
Line accounting (
git diff --numstat origin/main...HEAD, 22 files, +85/-119):Reviewer note, deliberately left as is:
src/cli/actions.tshand-rolls@actions/core's workflow-command escaping andsetOutputheredoc by recorded decision (bundle weight;@actions/coreis a devDependency).src/discovery/discover.tscompileExcludePatternvspath.matchesGlob: matchesGlob changes the exclude semantics (case-insensitive,*crossing/); candidate only.src/github/api.tsClientAnswertri-state vs a neverthrowResultat 55 sites: design-level, the owner's call.src/regex-escape copies (secret_scanning_custom_patterns/compilable-form.ts,discovery/discover.ts) stay: Node 22.14, whichenginesadmits, lacksRegExp.escape.src/plain-data.tswould be a closer conceptual home forvalueAt, but the sections layer may not import it under architecture.yml; recorded, not built.libbump adds no ES2025 type to any public signature; the package smoke still compiles the consumer at target es2022.Codex rubber-duck: two passes; the first found the nested.ts import cycle, the second clean.
BEGIN_COMMIT_OVERRIDE
refactor: replace hand-rolled helpers with the library calls that already ship
zod issue paths render through z.core.toDotPath at the four sites that each spelled their own join, so a key with a non-word character reads as ["my-key"] instead of .my-key.
The secret scanning pattern comparison uses isDeepStrictEqual from node:util instead of JSON.stringify equality.
The two set-equality helpers use Set.prototype.isSubsetOf, and the tsconfig lib moves from ES2022 to ES2025 for its types while the target stays ES2022.
The REST query string is built by URLSearchParams, which writes a space as + where encodeURIComponent wrote %20; GitHub decodes both.
Central-mode file names go through extname and parse from node:path instead of a YAML extension regex.
valueAt has one home in the shared list-section module, the two environments modules share one unreconcilable message builder, and the generator scripts call RegExp.escape instead of a local escapeRe.
END_COMMIT_OVERRIDE