-
Notifications
You must be signed in to change notification settings - Fork 6
🎉 @ast-grep/all-langs #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThis update introduces a new package, Changes
Sequence Diagram(s)sequenceDiagram
participant Consumer
participant AllLangsPkg as @ast-grep/all-langs
participant Langs as Individual Language Modules
Consumer->>AllLangsPkg: import { Lang, langs } from '@ast-grep/all-langs'
AllLangsPkg->>Langs: Re-export all supported language modules
Consumer->>AllLangsPkg: Use Lang enum/type and langs registry
Assessment against linked issues
Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
packages/all/langs.d.ts (1)
1-9
: Enhance Type-Safety oflangs
Declaration
Currently the mapping usesDynamicLangRegistrations[string]
, which yields a broad union of all registrations. To tighten the type, consider indexing by theLang
union directly:-export declare const langs: Readonly< - Record<Lang, DynamicLangRegistrations[string]> -> +export declare const langs: Readonly< + Record<Lang, DynamicLangRegistrations[Lang]> +>This ensures each key in
langs
precisely maps to its corresponding registration type.packages/all/lang.js (1)
1-31
: Consider Migrating to TypeScript for Stronger Typing
Defining theLang
enum in plain JavaScript with a separate.d.ts
can lead to mismatches over time. You may want to convert this file to TypeScript (e.g.,lang.ts
) and export a trueenum
oras const
object. That approach would eliminate the need for parallel.d.ts
files and improve maintainability and type safety.packages/all/package.json (2)
18-21
: Enforce Node.js engine version for consistency.
Given that CI/workflows now require Node.js ≥ 21, consider adding an"engines": { "node": ">=21" }
field to guard against incompatible runtimes.
52-57
: Consider adding subpath exports for granular imports.
If consumers ever need to import modules directly (e.g.import { Lang } from '@ast-grep/all-langs/lang'
), you could extend theexports
field with entries for./lang
and./langs
.packages/all/jsconfig.json (1)
27-30
: SpecifyoutDir
to isolate build artifacts.
With"composite": true
and emit options enabled (declaration
,sourceMap
, etc.), it’s recommended to set an"outDir"
(for example,"dist"
). This prevents emitted files from polluting the source tree and supports cleaner composite builds.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (16)
.changeset/green-turtles-jump.md
(1 hunks).github/workflows/ci.yml
(1 hunks).github/workflows/release.yml
(2 hunks).vscode/extensions.json
(1 hunks).vscode/settings.json
(1 hunks)packages/all/.gitignore
(1 hunks)packages/all/index.d.ts
(1 hunks)packages/all/index.js
(1 hunks)packages/all/jsconfig.json
(1 hunks)packages/all/lang.d.ts
(1 hunks)packages/all/lang.js
(1 hunks)packages/all/lang.test.js
(1 hunks)packages/all/langs.d.ts
(1 hunks)packages/all/langs.js
(1 hunks)packages/all/langs.test.js
(1 hunks)packages/all/package.json
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: HerringtonDarkholme
PR: ast-grep/langs#65
File: packages/typescript/index.js:6-6
Timestamp: 2025-04-10T19:47:06.210Z
Learning: In ast-grep, TypeScript and TSX are treated as two separate languages, each with their own language package, rather than TypeScript supporting both .ts and .tsx extensions in a single package.
🧬 Code Graph Analysis (6)
packages/all/langs.test.js (2)
packages/all/langs.js (2)
langs
(32-59)langs
(32-59)packages/all/lang.js (2)
Lang
(4-31)Lang
(4-31)
packages/all/lang.js (1)
packages/all/lang.d.ts (1)
Lang
(33-33)
packages/all/lang.test.js (2)
packages/all/lang.js (2)
Lang
(4-31)Lang
(4-31)packages/all/lang.d.ts (1)
Lang
(33-33)
packages/all/langs.d.ts (3)
packages/all/langs.js (2)
langs
(32-59)langs
(32-59)packages/all/lang.js (2)
Lang
(4-31)Lang
(4-31)packages/all/lang.d.ts (1)
Lang
(33-33)
packages/all/lang.d.ts (1)
packages/all/lang.js (2)
Lang
(4-31)Lang
(4-31)
packages/all/langs.js (1)
packages/all/lang.js (2)
Lang
(4-31)Lang
(4-31)
🔇 Additional comments (25)
packages/all/.gitignore (1)
1-1
: Ignorenode_modules
directory as expected
The new.gitignore
entry correctly prevents thenode_modules
folder in thepackages/all
package from being committed..vscode/extensions.json (1)
1-3
: Recommend Biome extension for consistent formatting
This workspace recommendation ofbiomejs.biome
aligns with the project's formatting standards and will prompt users to install the correct formatter..vscode/settings.json (1)
1-6
: Configure Biome as default formatter
The settings file correctly sets"biomejs.biome"
as the default formatter for JavaScript, JSON, JSONC, and TypeScript, and limits the minimap width to improve readability..changeset/green-turtles-jump.md (1)
1-6
: Patch release configuration looks correct
The changeset properly declares the new@ast-grep/all-langs
package as a patch update, following the repository’s changeset conventions..github/workflows/release.yml (2)
44-44
: Ensure Consistent Node.js Version in Prebuild Job
Thenode-version: ">= 21"
update aligns the prebuild environment with CI requirements. Confirm that all downstream scripts and dependencies are compatible with Node.js 21+ features.
78-78
: Ensure Consistent Node.js Version in Package Job
The same version constraint in the package job maintains consistency across workflows. No further changes needed here.packages/all/index.d.ts (1)
1-2
: Re-export Entry Points
The declaration file cleanly re-exports bothlang.js
andlangs.js
, providing a single entry point for TypeScript consumers of the package.packages/all/index.js (1)
1-2
: Re-export Entry Points
This module correctly consolidates exports fromlang.js
andlangs.js
into one entry point, simplifying imports for end users.packages/all/langs.test.js (4)
6-7
: Good setup for language registrationRegistering all dynamic languages before running tests using
registerDynamicLanguage(langs)
is a clean approach. This ensures all tests have access to the complete language set.
9-14
: Good test structure for newly supported languageThe test for Dart as a newly supported language correctly checks that the root node kind is 'program', verifying the parser is working as expected.
23-28
: Good test coverage for built-in languageTesting TypeScript as a built-in language ensures compatibility with core language support.
1-5
: Good imports and structureThe imports are clean and well-organized, correctly bringing in both the testing utilities and the language modules being tested.
packages/all/langs.js (3)
1-27
: Clean organization of language module importsThe imports are well-organized and follow a consistent pattern, importing each language module from its respective package.
29-31
: Good documentationThe JSDoc comment clearly describes what the
langs
object represents.
32-59
: Well-structured language mappingThe
langs
object effectively maps each language key from theLang
enum to its corresponding imported module. UsingObject.freeze()
ensures immutability, which is good practice.This implementation fulfills the PR objective of consolidating all language registrations in a single package for easier usage.
packages/all/lang.test.js (3)
5-31
: Good backward compatibility referenceDefining a frozen
previous
object with the language set from@ast-grep/[email protected]
provides a clear reference point for backwards compatibility testing. The commented outYaml
entry might indicate a language that was previously supported but is now excluded.
33-36
: Good backwards compatibility testThis test ensures that the new
Lang
enum remains compatible with the previous version, which is essential for maintaining API stability.
38-40
: Good current compatibility testTesting compatibility with the current built-in enum from
@ast-grep/napi
ensures alignment between the new package and the core library.packages/all/lang.d.ts (3)
1-3
: Clear documentationThe JSDoc comment clearly describes what the
Lang
enum represents.
4-31
: Well-defined TypeScript declarationThe
Lang
constant is correctly declared as a readonly object with all supported language identifiers, matching the JS implementation. This provides proper type safety when using the enum.
33-33
: Good type extractionThe
Lang
type is correctly defined as a union of all string literal values from theLang
object. This creates a proper string literal union type that can be used for type checking language identifiers.packages/all/package.json (3)
3-3
: Verify package version before release.
The version is currently set to"0.0.0"
, which appears to be a placeholder. Please bump this to an appropriate version (e.g.,0.1.0
or1.0.0
) prior to publishing.
22-50
: Confirm completeness of language dependencies.
This list should mirror every officially supported@ast-grep/lang-*
package (including TSX and TypeScript as separate entries). Please verify that no languages have been omitted.
1-60
: Overall package.json looks solid.
Metadata, file globs, module mappings, and the dependency declarations align with the PR objectives of aggregating all@ast-grep
languages under one package.packages/all/jsconfig.json (1)
1-65
: Comprehensive TypeScript configuration.
Thejsconfig.json
provides strict type checking, accurate module resolution (NodeNext), and robust compiler options that fit the needs of a unified language‐registry package.
@@ -21,6 +21,7 @@ jobs: | |||
uses: actions/setup-node@v4 | |||
with: | |||
cache: pnpm | |||
node-version: ">= 21" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Validate Node.js version range in CI
Please confirm that the actions/setup-node
action supports the semver range ">= 21"
. Also ensure that the release workflow (.github/workflows/release.yml
) has been updated in the same way for consistency.
🏁 Script executed:
#!/bin/bash
# Verify Node.js version configuration in CI and release workflows
rg -n 'actions/setup-node' -C2 .github/workflows/ci.yml .github/workflows/release.yml
Length of output: 924
🌐 Web query:
Does GitHub actions/setup-node support semver ranges for the "node-version" input?
💡 Result:
Support for Semver Ranges in actions/setup-node
Yes, the GitHub Actions actions/setup-node
action supports Semantic Versioning (semver) ranges for the node-version
input.
Details
-
The
node-version
input accepts semver range notations, allowing you to specify versions like'14.x'
,'16'
,'>=16.0.0'
, and similar patterns. For example:'16.x'
will use the latest available patch version of Node.js 16.'>=18.0.0'
will resolve to the latest version matching the range[2][4][6].
-
This is explicitly supported in the official documentation and examples:
The action will first check the local cache for a semver match. If unable to find a specific version in the cache, the action will attempt to download a version of Node.js[2][1][4].
-
You can also use other accepted notations such as:
'lts/*'
for the latest LTS version'latest'
for the most recent Node.js release- Specific versions like
'16.13.0'
- Nightly and canary build notations[2][5]
-
The
setup-node
action internally uses semver resolution logic to pick the appropriate Node.js version based on the provided range, and this is compatible with the NPM ecosystem’snode-semver
parser[3][4].
Example Usage
- uses: actions/setup-node@v4
with:
node-version: '18.x' # Latest 18.x patch
or
- uses: actions/setup-node@v4
with:
node-version: '>=16.0.0' # Latest version >= 16.0.0
Version Files and Ranges
- The action also supports specifying the Node.js version via a file (
.nvmrc
,.node-version
,package.json
). If a semver range is provided in these files (e.g., viaengines.node
inpackage.json
), that will be used as the version specification[1][6].
Summary Table
Syntax Example | Result |
---|---|
'16.x' |
Latest patch of Node.js 16 |
'>=18.0.0' |
Latest available Node.js >= 18.0.0 |
'lts/*' |
Latest LTS version |
'latest' |
Latest published Node.js version |
'14' , '14.x' |
Latest patch of Node.js 14 |
In conclusion, use semver ranges or aliases as the node-version
input for flexibility in your GitHub Actions workflows[2][4][5][6].
Citations:
- 1: https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md
- 2: https://github.com/actions/setup-node
- 3: https://github.com/npm/node-semver
- 4: Please document the '14.x' notation? actions/setup-node#521
- 5: https://github.com/marketplace/actions/setup-node-js-environment
- 6: https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-nodejs
- 7: https://httptoolkit.com/blog/automatic-npm-publish-gha/
- 8: Action timing out when new node versions are released actions/setup-node#132
- 9: https://github.com/guardian/actions-setup-node
- 10: https://github.com/tj/n
🌐 Web query:
What input parameters does actions/setup-node@v4 accept (e.g., node-version vs version)?
💡 Result:
Input Parameters for actions/setup-node@v4
actions/setup-node@v4 provides a range of input parameters to configure Node.js environments in GitHub Actions workflows. Below are the primary and advanced inputs you can use, with notes on precedence and intended use:
Core Version Selection Inputs
-
node-version
Specifies the Node.js version to use (accepts SemVer, aliases likelts/*
,latest
,nightly
, or canary builds).
Example:with: node-version: '18'
If both
node-version
andnode-version-file
are provided,node-version
takes precedence[1][2][6][9]. -
node-version-file
Path to a file containing the Node.js version (e.g.,.nvmrc
,.node-version
,.tool-versions
, orpackage.json
).
Example:with: node-version-file: '.nvmrc'
Notable behavior: In a
package.json
, it checksvolta.node
first, thenengines.node
ifvolta.node
is unspecified[1][6].
Update and Architecture Controls
-
check-latest
Boolean (true
orfalse
). Iftrue
, downloads the latest available version matching the specification, bypassing local cache. Defaults tofalse
, which favors cached versions for performance[1][6][9].
Example:with: check-latest: true
-
architecture
Target CPU architecture for Node.js (e.g.,x86
,x64
,arm64
). Defaults to the system architecture if unspecified[2][6][9].
Example:with: architecture: 'x64'
Caching and Authentication (Advanced)
-
cache
Specifies dependency manager to cache (npm
,yarn
,pnpm
, or''
to disable)[2][6]. -
cache-dependency-path
Sets the path to lock file(s) for cache key calculation (used if lock file is not in root). -
registry-url and scope
Used to set up npm registry authentication, particularly with private registries. -
token
Custom token for publishing/authenticating with npm/GitHub package registries.
Summary Table
Parameter | Purpose/Example Value | Notes |
---|---|---|
node-version | '18' , 'lts/*' , '16.13.0' |
Main version selector; takes precedence over node-version-file . |
node-version-file | '.nvmrc' , 'package.json' |
Uses version specified in file. |
check-latest | true , false |
Download the latest version if true. Default: false . |
architecture | 'x64' , 'arm64' |
Target CPU architecture. |
cache | 'npm' , 'yarn' , 'pnpm' |
Enable caching of dependencies. |
cache-dependency-path | 'frontend/yarn.lock' |
Path(s) for dependency lock file(s). |
registry-url | 'https://npm.pkg.github.com' |
Custom registry URL. |
scope | '@my-org' |
Npm scope for authentication. |
token | '${{ secrets.NPM_TOKEN }}' |
Token for private registry auth. |
No version
Input
- The parameter is named
node-version
(not justversion
). There is noversion
input; always usenode-version
when specifying the desired Node.js release[2][9].
Example Usage
- uses: actions/setup-node@v4
with:
node-version: '20'
check-latest: true
architecture: 'x64'
cache: 'npm'
References
- For a full list and the most current details, consult the official documentation[1][2][6][9].
- The action supports multiple advanced workflows, including dependency caching, multi-architecture builds, and custom registry authentication.
In summary:
Use node-version
to specify the Node.js version (not version
). node-version-file
can be used to read the version from a file, but is overridden by a direct node-version
input. Additional parameters provide update, architecture, caching, and authentication controls for your workflow[1][2][6][9].
Citations:
- 1: https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md
- 2: https://github.com/actions/setup-node
- 3: https://cr88.hashnode.dev/optimizing-cicd-pipelines-leveraging-caching-in-github-actions
- 4: https://forgejo.org/docs/latest/user/actions/
- 5: https://developer.harness.io/docs/continuous-integration/use-ci/use-drone-plugins/ci-github-action-step/
- 6: https://cicube.io/workflow-hub/github-action-setup-node/
- 7: https://v17.angular.io/guide/signal-inputs
- 8: https://www.youtube.com/watch?v=gRPIPiiTH-c
- 9: https://github.com/marketplace/actions/setup-node-js-environment
- 10: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
Update release workflow to use node-version
input
The actions/setup-node@v4
action does support SemVer ranges (e.g. ">= 21"
) via the node-version
input. Your CI workflow already uses:
with:
node-version: ">= 21"
cache: pnpm
However, in your release workflow you’re still using the wrong parameter (version: 9
) in two places. Please update both steps in .github/workflows/release.yml
to:
- with:
- version: 9
- cache: pnpm
+ with:
+ node-version: ">= 21"
+ cache: pnpm
– once at line 39 (and its corresponding cache block) and again at line 73.
Ensure you’re using node-version
(not version
) for consistency with the CI workflow and the action’s documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the package.json files for Node.js requirements
echo "Checking package.json files for Node.js engine requirements:"
find . -name "package.json" -type f -exec grep -l "\"engines\"" {} \; | xargs cat 2>/dev/null | grep -A5 "\"engines\"" || echo "No engines field found"
echo -e "\nChecking all-langs package.json:"
cat packages/all/package.json | grep -A20 "dependencies" || echo "Could not find dependencies section"
echo -e "\nChecking release workflow file:"
cat .github/workflows/release.yml | grep -A10 "setup-node" || echo "No setup-node configuration found"
Length of output: 2101
🏁 Script executed:
#!/bin/bash
# Let's check for potential Node.js version requirements in the project or PR
# Check if there are any ESM features or other Node.js 21+ specific features in the new package
echo "Checking all-langs source files for potential Node.js 21+ features:"
find packages/all/src -type f -name "*.ts" -exec cat {} \; | grep -E "(import|export) type|import \{.*\} from"
# Check existing Node.js version in package.json at root level
echo -e "\nChecking root package.json for any Node.js related configuration:"
cat package.json | grep -E "\"(node|engines|volta)\"" -A3 -B3 || echo "No Node.js config found"
# Check if the Nodejs version constraint already exists in release workflow
echo -e "\nChecking if release workflow already has Node.js version constraint:"
grep -n "node-version" .github/workflows/release.yml
Length of output: 1218
🏁 Script executed:
#!/bin/bash
# Let's check more context about this PR
# Check the commit message when Node.js 21 was added to CI workflow
echo "Checking commit history for Node.js version changes:"
git log -p -- .github/workflows/ci.yml | grep -A10 -B10 "node-version" | head -30
# Check if there was discussion about Node.js version requirements in issues or PRs
echo -e "\nChecking for any Node.js version discussions in PRs:"
gh pr list --limit 20 --json title,url | jq '.[] | select(.title | test("node|Node|nodejs|version|v[0-9]+") | .url)'
# Check if any dependencies require Node.js 21+
echo -e "\nChecking package.json files for dependencies that might require Node.js 21+:"
find . -name "package.json" -type f -exec cat {} \; | grep -E "\"@types/node|node-api-headers|napi-rs"
# Let's see the current branch name and if it's related to Node.js version
echo -e "\nCurrent branch info:"
git branch --show-current
Length of output: 910
@HerringtonDarkholme Based on what I found, this change does appear to be useful for consistency:
- Your release workflow already has
node-version: ">= 21"
specified - The project uses
@types/node
version 22.14.1 (which corresponds to Node.js 22 APIs) - The code uses Node.js built-in test module (
node:test
) and ES module features
While there's no explicit engines
field in package.json defining Node.js requirements, maintaining the same Node.js version constraint across both CI and release workflows ensures consistency in your build environments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, @coderabbitai getting confused at pnpm/action-setup@v4
vs actions/setup-node@v4
. The version: 9
parameter is for setting up pnpm
(not Node), but it's saying to use node-version
there, which is wrong.
The code it highlighted as wrong, this one;
with:
version: 9
cache: pnpm
simply does not exist. This is the real code:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Set up NodeJS
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ">= 21"
which is correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NatoBoram You're absolutely right, and I apologize for the confusion! I completely mixed up the two different actions:
pnpm/action-setup@v4
- correctly usesversion: 9
for pnpm versionactions/setup-node@v4
- correctly usesnode-version: ">= 21"
for Node.js version
Your code is indeed correct as shown. Thanks for the clarification and for pointing out this mistake. I'll make sure to be more careful distinguishing between different actions and their parameters in the future.
(_/)
(•ㅅ•)
/ づ ♡
28a7703
to
c298021
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/all/src/lang.test.ts (2)
3-3
: Consider using a consistent file extension approach in imports.You're importing from "./lang.ts" with the explicit .ts extension. While this works, it's generally recommended to use extension-less imports for TypeScript files to improve compatibility with different module resolution strategies.
-import { Lang } from "./lang.ts" +import { Lang } from "./lang"
6-31
: Good approach for compatibility testing with previous versions.The frozen
previous
object effectively creates a snapshot of supported languages in@ast-grep/[email protected]
, providing a clear reference point for backward compatibility testing.However, there's an inconsistency in string quote style at line 30 for 'Yaml'.
- Yaml: 'Yaml', + Yaml: "Yaml",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (8)
packages/all/.gitignore
(1 hunks)packages/all/package.json
(1 hunks)packages/all/src/index.ts
(1 hunks)packages/all/src/lang.test.ts
(1 hunks)packages/all/src/lang.ts
(1 hunks)packages/all/src/langs.test.ts
(1 hunks)packages/all/src/langs.ts
(1 hunks)packages/all/tsconfig.json
(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- packages/all/src/index.ts
- packages/all/src/langs.ts
- packages/all/tsconfig.json
- packages/all/src/lang.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/all/.gitignore
- packages/all/package.json
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: HerringtonDarkholme
PR: ast-grep/langs#65
File: packages/typescript/index.js:6-6
Timestamp: 2025-04-10T19:47:06.210Z
Learning: In ast-grep, TypeScript and TSX are treated as two separate languages, each with their own language package, rather than TypeScript supporting both .ts and .tsx extensions in a single package.
🧬 Code Graph Analysis (2)
packages/all/src/lang.test.ts (1)
packages/all/src/lang.ts (2)
Lang
(4-32)Lang
(37-37)
packages/all/src/langs.test.ts (2)
packages/all/src/langs.ts (1)
langs
(100-128)packages/all/src/lang.ts (2)
Lang
(4-32)Lang
(37-37)
🔇 Additional comments (3)
packages/all/src/lang.test.ts (1)
33-41
: Well-structured compatibility tests.These tests effectively verify that the new
Lang
enum maintains compatibility with both the previous language set and the current@ast-grep/napi
language set. This will help prevent breaking changes when users migrate to the consolidated package.packages/all/src/langs.test.ts (2)
11-16
: Good test coverage for newly supported language.Testing Dart as a newly supported language is valuable to ensure the integration works correctly. The test structure is clear and focused on verifying the fundamental parsing capability.
18-30
: Comprehensive test strategy covering different language types.Testing a representative sample of languages (newly supported, previously supported, and built-in) provides good coverage to ensure the consolidation works across all language types. The tests follow a consistent pattern which makes them easy to understand and maintain.
describe("langs", () => { | ||
// @ts-expect-error Type `StaticLangRegistration` is missing the following | ||
// properties from type `LangRegistration`: `libraryPath`, `extensions`. | ||
before(() => registerDynamicLanguage(langs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Consider fixing type definitions instead of suppressing errors.
Using @ts-expect-error
is a temporary solution but fixing the underlying type issue would be better for long-term maintenance. The comment indicates that StaticLangRegistration
is missing properties from LangRegistration
. This could be addressed by extending the type definition.
🏁 Script executed:
#!/bin/bash
# Looking for the definition of StaticLangRegistration and LangRegistration
rg -A 5 "StaticLangRegistration|LangRegistration" --type ts
Length of output: 2974
Enhance static‐language type definitions
File: packages/all/src/langs.test.ts
Lines: 6–9
The TS error here is because your langs
object (typed via StaticLangRegistration
in packages/all/src/langs.ts) doesn’t include the libraryPath
and extensions
fields required by LangRegistration
(from @ast-grep/napi/types/registerDynamicLang.js
). Rather than silencing this with @ts-expect-error
, please update the static‐lang types so that langs
is a valid LangRegistration
map:
- In packages/all/src/langs.ts, extend your
StaticLangRegistration
union (or theStaticLangRegistrations
interface) to include the missinglibraryPath
andextensions
properties, so thatpasses type‐checking without suppression.registerDynamicLanguage(langs)
- Alternatively, introduce a wrapper or cast that explicitly merges in those fields at compile time, instead of relying on
@ts-expect-error
.
This will remove the need to disable type‐checking and improve long-term maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a valid concern. if we need error suppression here, does it also mean users need it as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
I need to better understand the type incompatibility between StaticLangRegistration
and what registerDynamicLanguage
expects.
@HerringtonDarkholme This is an excellent point. If we need to suppress type errors in our own tests, users will likely encounter the same issues when trying to use the package as documented. Let me check how the types are defined to provide a proper solution.
🏁 Script executed:
#!/bin/bash
# Look at the StaticLangRegistration and langs definitions
cat packages/all/src/langs.ts
# Check the imported types from @ast-grep/napi
rg "LangRegistration" --type=typescript -A 10 -B 10
# Check the PR description or documentation about how users are expected to use this package
rg -i "register.*langs" --type=markdown
Length of output: 3245
@HerringtonDarkholme You've raised an excellent concern. If our tests need to suppress type errors with @ts-expect-error
, users will indeed face the same issues when trying to use this package, creating a poor developer experience.
Let me examine the exact types to understand what's happening and suggest a proper solution.
🏁 Script executed:
#!/bin/bash
# Let's examine what the LangRegistration type in the napi package defines
fd -t file "registerDynamicLang.js" --exec cat {}
# Let's check sample files from the language packages to see how they're structured
find packages -name "*.js" -path "*/lang-*" | grep -v "node_modules" | head -n 1 | xargs cat
# Let's also check the PR description to see how users are expected to use this package
grep -r -i "registerDynamicLanguage" --include="*.md" .
Length of output: 4619
@HerringtonDarkholme I'm trying to find the exact definition of LangRegistration
to better understand what's missing from our types. Let me dig deeper.
🏁 Script executed:
#!/bin/bash
# Let's try to find the actual definition of LangRegistration to understand the type mismatch
find node_modules -type f -name "*.d.ts" | xargs grep -l "LangRegistration" | xargs cat
# Let's also check if we have access to node_modules/@ast-grep/napi to find these types
ls -la node_modules/@ast-grep/napi/types/ 2>/dev/null || echo "Directory not found"
# Check a sample language package to understand how the lang registrations are structured
find packages -path "*/lang-*" -name "index.js" | head -n 1 | xargs cat
Length of output: 300
@HerringtonDarkholme You're absolutely right - this issue would affect users too. If we need to use @ts-expect-error
in our own tests, users will face the same typing issues.
Looking at the code, we can see:
- Each language package export doesn't fully satisfy what
registerDynamicLanguage
expects - The error tells us that
libraryPath
andextensions
properties are required
I propose three potential solutions:
-
Create a wrapper function that adapts the types appropriately:
// In langs.ts export function registerAllLangs() { // @ts-expect-error - we handle this internally so users don't have to return registerDynamicLanguage(langs); }
-
Modify the
StaticLangRegistrations
interface to ensure type compatibility:interface StaticLangRegistrations extends DynamicLangRegistrations { // existing properties... }
-
Create an adapter that maps each language to a compatible format:
export const registerReadyLangs = Object.entries(langs).reduce((acc, [key, value]) => { acc[key] = { ...value, // Add missing properties here if needed }; return acc; }, {} as DynamicLangRegistrations);
Option #1 is simplest and would hide the typing issue from users entirely. This would be my recommendation since it provides the best developer experience.
🏁 Script executed:
#!/bin/bash
# Let's look at one of the language packages more closely
find packages -path "*/lang-*/src" -type d | head -n 1 | xargs find -name "*.ts" | xargs cat
# Let's check what's in the main PR file to understand what users are supposed to do
cat packages/all/package.json
Length of output: 24088
@HerringtonDarkholme You've identified an important issue. Yes, the error suppression would be necessary for users too, which creates a poor developer experience. I've examined the code in detail, and here's what's happening:
-
Each language package exports a registration object with required properties:
type LanguageRegistration = { libraryPath: string extensions: string[] languageSymbol?: string metaVarChar?: string expandoChar?: string }
-
The
StaticLangRegistration
type is defined as a union of all language modules, which means TypeScript only preserves common properties across all union members. -
When passing
langs
toregisterDynamicLanguage()
, TypeScript can't guarantee all required properties exist on every union member.
Proposed solutions:
-
Add a helper function (recommended):
// In langs.ts export function registerAllLangs() { // @ts-expect-error - we handle this internally so users don't have to return registerDynamicLanguage(langs); }
-
Modify the StaticLangRegistration interface to enforce the required properties:
interface StaticLangRegistration { libraryPath: string extensions: string[] // other common properties... } type LangModule = | typeof angular | typeof bash | /* other modules */ interface StaticLangRegistrations { // Define as before but ensure each value matches StaticLangRegistration }
-
Create an adapter at runtime:
export const registerReadyLangs = Object.fromEntries( Object.entries(langs).map(([lang, reg]) => { // Validate that required properties exist if (!('libraryPath' in reg) || !('extensions' in reg)) { throw new Error(`Language ${lang} is missing required properties`); } return [lang, reg]; }) );
I recommend option #1 as it's the simplest and provides the best developer experience.
🧬 Code Graph Analysis Results
Relevant snippets for understanding packages/all/src/langs.test.ts
and the user comment:
File: packages/all/src/lang.ts
Lines 4-37
export const Lang = {
Angular: "Angular",
Bash: "Bash",
C: "C",
Cpp: "Cpp",
CSharp: "CSharp",
Css: "Css",
Dart: "Dart",
Elixir: "Elixir",
Go: "Go",
Haskell: "Haskell",
Html: "Html",
Java: "Java",
JavaScript: "JavaScript",
Json: "Json",
Kotlin: "Kotlin",
Lua: "Lua",
Php: "Php",
Python: "Python",
Ruby: "Ruby",
Rust: "Rust",
Scala: "Scala",
Sql: "Sql",
Swift: "Swift",
Toml: "Toml",
Tsx: "Tsx",
TypeScript: "TypeScript",
Yaml: "Yaml",
} as const
export type Lang = (typeof Lang)[keyof typeof Lang]
- Defines a constant
Lang
object enumerating supported language names as string literals. - Defines a TypeScript type
Lang
as the union of all language string literal values. - This is the source of the
Lang
enum used in the test file.
File: packages/all/src/langs.ts
Lines 100-128
export const langs: StaticLangRegistrations = {
[Lang.Angular]: angular,
[Lang.Bash]: bash,
[Lang.C]: c,
[Lang.Cpp]: cpp,
[Lang.CSharp]: csharp,
[Lang.Css]: css,
[Lang.Dart]: dart,
[Lang.Elixir]: elixir,
[Lang.Go]: go,
[Lang.Haskell]: haskell,
[Lang.Html]: html,
[Lang.Java]: java,
[Lang.JavaScript]: javascript,
[Lang.Json]: json,
[Lang.Kotlin]: kotlin,
[Lang.Lua]: lua,
[Lang.Php]: php,
[Lang.Python]: python,
[Lang.Ruby]: ruby,
[Lang.Rust]: rust,
[Lang.Scala]: scala,
[Lang.Sql]: sql,
[Lang.Swift]: swift,
[Lang.Toml]: toml,
[Lang.Tsx]: tsx,
[Lang.TypeScript]: typescript,
[Lang.Yaml]: yaml,
}
- Exports
langs
, an object mapping language names (fromLang
) to their respective static language registration objects. - This object is passed to
registerDynamicLanguage
in the test setup. - Each language registration likely contains metadata such as
libraryPath
andextensions
(referenced in the test file's@ts-expect-error
comment).
These snippets provide context on:
- The
Lang
enum used in the tests. - The
langs
object registered dynamically before tests run. - The possible reason for the TypeScript error suppression in the test file related to missing properties in language registrations.
No other code snippets appear directly relevant to the test file or the user comment about error suppression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, users would need it
The proper fix would be to declare the type once somewhere exported and import it in those packages instead of having every package declare it independently. This way, any update would be felt across the monorepo instantly
The helper function is something I wanted to do, but then it somehow didn't work when I installed the package somewhere else to test it
But then it also means that, currently, if someone wants to use registerDynamicLanguage
, they'll face this issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
"@types/node": "22.14.1", | ||
"typescript": "^5.8.3" | ||
}, | ||
"type": "module", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to think if we want to ship ESM by default. I prefer to do that but other modules are currently in CJS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh they are? I didn't notice!
So this isn't exactly what I had in mind at first in #71. What I imagined was just being able to call a single function and having all built-in languages registered at once. When I tested it, the languages don't register if the registration is done in a dependency, which is weird. I don't know what could be causing this, but even if the registration is made in the main package, a lib that re-exports the big
DynamicLangRegistrations
is welcome.Using this package, we go from something like this:
To this:
And I think it's close enough.
There's the potential issue of this thing bring written in pure JS +Moved to TypeScript. Much simpler..d.ts
files, which makes the typing of the exportedlangs
extremely brittle. We can see in the issue in the first TypeScript example. Maybe it would be better to write it in TypeScript?langs
object with all first-party supported languagesLang
enum with the names of all first-party supported languagesSummary by CodeRabbit
New Features
@ast-grep/all-langs
package, providing unified access to all officially supported languages.Tests
Chores
.gitignore
handling for package source directories.