Skip to content

feat: get version from deno.json instead of fetching latest#1046

Open
guitavano wants to merge 1 commit intomainfrom
feat/run-version-from-deno-json
Open

feat: get version from deno.json instead of fetching latest#1046
guitavano wants to merge 1 commit intomainfrom
feat/run-version-from-deno-json

Conversation

@guitavano
Copy link
Copy Markdown
Contributor

@guitavano guitavano commented Feb 2, 2026

Summary

  • Read @deco/deco or @deco/dev version from the project deno.json imports instead of fetching the latest version from JSR
  • This ensures the script uses the same version the project is already configured to use
  • Falls back to major version "1" if unable to read or parse the deno.json

Test plan

  • Run the script in a project with @deco/deco in deno.json
  • Run the script in a project with @deco/dev in deno.json
  • Run the script in a project without deco imports (should fallback to "1")

Summary by cubic

Use the @deco/deco or @deco/dev version from deno.json imports instead of fetching the latest from JSR. This aligns the run script with the project's configured version and removes a network dependency.

  • Refactors
    • Read version from deno.json imports (supports @deco/deco and @deco/dev).
    • Parse jsr specifiers and strip leading ^ when present.
    • Fallback to major "1" if deno.json is missing or parsing fails.
    • Removed meta.json fetch and timeout; import now uses the resolved version.

Written for commit 6d4af22. Summary will update on new commits.

Summary by CodeRabbit

  • Refactor
    • Improved startup performance by switching from remote version fetching to local configuration-based version resolution.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 2, 2026

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 1.135.1 update
  • 🎉 for Minor 1.136.0 update
  • 🚀 for Major 2.0.0 update

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

The pull request modifies scripts/run.ts to replace remote version resolution via meta.json with local version extraction from deno.json. A new getVersionFromDenoJson function reads the local configuration, parses JSR specifiers for @deco/deco or @deco/dev packages, and determines the version for dynamic import, removing remote fetch operations and timing metrics in the process.

Changes

Cohort / File(s) Summary
Script version resolution
scripts/run.ts
Replaces remote meta.json fetch with local deno.json parsing via new getVersionFromDenoJson function. Removes AbortController timeout, performance timing, and fetch-related logging. Maintains fallback to version "1" and console warnings on parse failures.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Local reads beat network calls so slow,
deno.json now guides where scripts shall go,
No more waiting for meta to arrive,
Just parse and import—let speed thrive! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: replacing remote version fetching with local deno.json reading, which is the primary focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/run-version-from-deno-json

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="scripts/run.ts">

<violation number="1" location="scripts/run.ts:20">
P2: The regex captures the last `@` segment even when the specifier has no version (e.g., `jsr:@deco/deco`), resulting in `version = "deco/deco"` and an invalid import. Use a pattern that only captures when a version `@...` is present after the package name.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread scripts/run.ts
}

// Extract version from jsr:@deco/deco@1.133.2 or jsr:@deco/dev@1.133.4
const match = specifier.match(/@([^@]+)$/);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The regex captures the last @ segment even when the specifier has no version (e.g., jsr:@deco/deco), resulting in version = "deco/deco" and an invalid import. Use a pattern that only captures when a version @... is present after the package name.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/run.ts, line 20:

<comment>The regex captures the last `@` segment even when the specifier has no version (e.g., `jsr:@deco/deco`), resulting in `version = "deco/deco"` and an invalid import. Use a pattern that only captures when a version `@...` is present after the package name.</comment>

<file context>
@@ -1,29 +1,37 @@
+    }
+
+    // Extract version from jsr:@deco/deco@1.133.2 or jsr:@deco/dev@1.133.4
+    const match = specifier.match(/@([^@]+)$/);
+    if (!match) {
+      console.warn("Could not parse version from specifier, falling back to major version");
</file context>
Suggested change
const match = specifier.match(/@([^@]+)$/);
const match = specifier.match(/@[^@]+@([^/]+)$/);
Fix with Cubic

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@scripts/run.ts`:
- Around line 11-27: The code is failing to parse JSR specifiers and still uses
a hardcoded package name; update the parsing to extract both package and version
from the found specifier (the variable specifier) using a pattern like
/^jsr:([^@]+)@(.+)$/ so you get packageName = match[1] and version = match[2].
Strip a leading ^ from version as you already do, log the version, and use the
parsed packageName (not the hardcoded "@deco/deco") when performing the dynamic
import or any further resolution; ensure checks still handle missing/invalid
specifier by falling back to the major version "1".
🧹 Nitpick comments (1)
scripts/run.ts (1)

7-9: Consider supporting JSONC format for better robustness (optional improvement).

The code already handles JSON parse errors gracefully with a try-catch fallback, but if deno.json ever uses comments or trailing commas, or if the repo switches to deno.jsonc, the fallback to version "1" will silently occur. For more robust version detection, consider using a JSONC parser and/or checking deno.jsonc as an alternative when deno.json is missing.

Comment thread scripts/run.ts
Comment on lines +11 to +27
// Try @deco/deco first, then @deco/dev
const specifier = imports["@deco/deco"] ?? imports["@deco/dev"];

if (!specifier || !specifier.startsWith("jsr:")) {
console.warn("No jsr specifier found, falling back to major version");
return "1";
}

// Extract version from jsr:@deco/deco@1.133.2 or jsr:@deco/dev@1.133.4
const match = specifier.match(/@([^@]+)$/);
if (!match) {
console.warn("Could not parse version from specifier, falling back to major version");
return "1";
}

const version = match[1].replace(/^\^/, ""); // Remove ^ if present
console.log(`%cusing version ${version} from deno.json`, "color: gray");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n scripts/run.ts

Repository: deco-cx/deco

Length of output: 1583


🏁 Script executed:

cat -n deno.json

Repository: deco-cx/deco

Length of output: 4414


🏁 Script executed:

# Check for deno.jsonc or other deno config files
fd -e jsonc -e json | grep -i deno

Repository: deco-cx/deco

Length of output: 97


🏁 Script executed:

# Search for `@deco/deco` or `@deco/dev` usage in deno.json* files
rg -n --glob 'deno.json*' '@deco/(deco|dev)' || echo "No matches found"

Repository: deco-cx/deco

Length of output: 200


🏁 Script executed:

# Test the regex pattern against potential specifiers
python3 << 'EOF'
import re

regex = r"/@([^@]+)$"
test_cases = [
    "jsr:`@deco/deco`@1.133.2",
    "jsr:`@deco/dev`@1.133.4",
    "jsr:`@deco/deco`@1.2.3/subpath",
    "jsr:`@deco/deco`@^1.2.3",
    "jsr:`@deco/deco`",
]

for spec in test_cases:
    match = re.search(regex, spec)
    if match:
        print(f"✓ {spec:35} → captures: '{match.group(1)}'")
    else:
        print(f"✗ {spec:35} → NO MATCH")
EOF

Repository: deco-cx/deco

Length of output: 300


Fix package name resolution and JSR specifier parsing.

The current implementation has critical bugs:

  1. Broken regex: The pattern /@([^@]+)$/ requires a / before the final @, but JSR specifiers like jsr:@deco/deco@1.133.2 don't have this format. The regex will never match, causing the function to always return the fallback version "1".

  2. Package name mismatch: The hardcoded packageName = "@deco/deco" on line 3 is never updated based on which specifier is actually found on line 12. If imports["@deco/dev"] is configured, the code will still import @deco/deco.

Extract both the package name and version from the specifier and use the actually-found package name in the dynamic import.

Proposed fix
-const packageName = "@deco/deco";
+const DEFAULT_PACKAGE = "@deco/deco";

-const getVersionFromDenoJson = async (): Promise<string> => {
+const getPackageAndVersionFromDenoJson = async (): Promise<{
+  packageName: string;
+  version: string;
+}> => {
   try {
     const denoJsonPath = `${Deno.cwd()}/deno.json`;
     const denoJson = JSON.parse(await Deno.readTextFile(denoJsonPath));
     const imports = denoJson.imports ?? {};

     // Try `@deco/deco` first, then `@deco/dev`
     const specifier = imports["@deco/deco"] ?? imports["@deco/dev"];

     if (!specifier || !specifier.startsWith("jsr:")) {
       console.warn("No jsr specifier found, falling back to major version");
-      return "1";
+      return { packageName: DEFAULT_PACKAGE, version: "1" };
     }

-    // Extract version from jsr:`@deco/deco`@1.133.2 or jsr:`@deco/dev`@1.133.4
-    const match = specifier.match(/@([^@]+)$/);
+    // Extract package + version from jsr:`@deco/deco`@1.133.2
+    const match = specifier.match(/^jsr:(@[^@/]+\/[^@/]+)@([^/]+)(?:\/.*)?$/);
     if (!match) {
       console.warn("Could not parse version from specifier, falling back to major version");
-      return "1";
+      return { packageName: DEFAULT_PACKAGE, version: "1" };
     }

-    const version = match[1].replace(/^\^/, ""); // Remove ^ if present
+    const [, packageName, rawVersion] = match;
+    const version = rawVersion.replace(/^\^/, ""); // Remove ^ if present
     console.log(`%cusing version ${version} from deno.json`, "color: gray");
-    return version;
+    return { packageName, version };
   } catch (err) {
     console.warn("Could not read deno.json", err, "falling back to major version");
-    return "1";
+    return { packageName: DEFAULT_PACKAGE, version: "1" };
   }
 };

-const version = await getVersionFromDenoJson();
+const { packageName, version } = await getPackageAndVersionFromDenoJson();

 await import(`jsr:${packageName}@${version}/scripts/run`);
🤖 Prompt for AI Agents
In `@scripts/run.ts` around lines 11 - 27, The code is failing to parse JSR
specifiers and still uses a hardcoded package name; update the parsing to
extract both package and version from the found specifier (the variable
specifier) using a pattern like /^jsr:([^@]+)@(.+)$/ so you get packageName =
match[1] and version = match[2]. Strip a leading ^ from version as you already
do, log the version, and use the parsed packageName (not the hardcoded
"@deco/deco") when performing the dynamic import or any further resolution;
ensure checks still handle missing/invalid specifier by falling back to the
major version "1".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant