Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

This PR allows the wrangler types command to run without requiring a Wrangler config file, addressing a common pain point for developers who want to generate runtime types without a full project setup.

Changes

Added two new command-line arguments:

  • --compatibility-date: Specifies the compatibility date for runtime types (defaults to the latest date supported by the installed workerd)
  • --compatibility-flags: Specifies compatibility flags for runtime types

When no config file is detected:

  • The command will automatically use the latest workerd compatibility date if --compatibility-date is not provided
  • --include-env is automatically set to false (only runtime types are generated, not project-specific environment types)
  • Users can still provide compatibility settings via command-line arguments

Key Implementation Details

  1. Config file detection: The handler now wraps config reading in a try-catch block. If no config is explicitly specified via -c, missing config files are treated as "no config" rather than an error.

  2. Fallback chain: For compatibility settings, the code follows this priority:

    • Command-line arguments (--compatibility-date, --compatibility-flags)
    • Config file settings (if config exists)
    • Default workerd compatibility date (if no config and no args)
  3. Type safety: Added proper handling for config being undefined throughout the handler using optional chaining.

  4. Backward compatibility: When a user explicitly specifies a config file with -c that doesn't exist, the command still errors as before.

Testing

Added 4 new test cases covering:

  • Generating runtime types without config when --compatibility-date is provided
  • Using default workerd compatibility date when no config and no args
  • Supporting --compatibility-flags argument without config
  • Verifying includeEnv is set to false when no config exists

All 49 existing tests continue to pass.

Areas for Review

⚠️ Important areas to review:

  1. Type coercion on line 247-248 and 293-295: Using .map(String) to convert yargs' (string | number)[] to string[]. This is duplicated in two places - consider if this should be extracted to a helper.

  2. Behavior change for configs without compatibility_date: Previously this would error in generateRuntimeTypes. Now it falls back to the default workerd date with a warning (lines 251-261). This is a breaking change that should be documented.

  3. Config detection logic (lines 137-159): Verify the logic correctly distinguishes between "no config file found" vs "user explicitly specified a config file that doesn't exist".

  4. Optional chaining throughout: Ensure all code paths properly handle config being undefined, especially in generateEnvTypes and when accessing config.configPath.


Link to Devin run: https://app.devin.ai/sessions/d05913dfe4fc454cbcd10f3734baeb68
Requested by: [email protected]

  • Tests
    • Tests included
  • Public documentation
    • Documentation not necessary because: This is a new feature that will be documented in the changeset and users can discover via wrangler types --help
  • Wrangler V3 Backport
    • Not necessary because: This is a new feature (minor version bump)

Add --compatibility-date and --compatibility-flags arguments to the
wrangler types command, making the config file optional. When no config
file is detected, the command will:
- Use the latest workerd compatibility date by default
- Set includeEnv to false (only generate runtime types)
- Accept compatibility settings via command-line arguments

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@changeset-bot
Copy link

changeset-bot bot commented Nov 12, 2025

🦋 Changeset detected

Latest commit: 36e79e8

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 12, 2025

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@11247

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@11247

miniflare

npm i https://pkg.pr.new/miniflare@11247

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@11247

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@11247

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@11247

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@11247

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@11247

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@11247

wrangler

npm i https://pkg.pr.new/wrangler@11247

commit: 36e79e8

Comment on lines 164 to 174
// Get the maximum compatibility date supported by the installed workerd
const miniflareEntry = require.resolve("miniflare");
const miniflareRequire = module.createRequire(miniflareEntry);
const miniflareWorkerd = miniflareRequire("workerd") as {
compatibilityDate: string;
};
args.compatibilityDate = miniflareWorkerd.compatibilityDate;
logger.log(
`No config file detected. Using the installed Workers runtime's latest supported date: ${args.compatibilityDate}\n`
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a utility function for this called getDevCompatibilityDate(). Use that instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Replaced the manual workerd resolution with getDevCompatibilityDate() in both locations (lines 149-154 and 224-228).

Comment on lines 133 to 158
let config: Config | undefined;
const secondaryConfigs: Config[] = [];
if (Array.isArray(args.config)) {
config = readConfig({ ...args, config: args.config[0] });
for (const configPath of args.config.slice(1)) {
secondaryConfigs.push(readConfig({ config: configPath }));
let hasConfigFile = false;

try {
if (Array.isArray(args.config)) {
config = readConfig({ ...args, config: args.config[0] });
for (const configPath of args.config.slice(1)) {
secondaryConfigs.push(readConfig({ config: configPath }));
}
} else {
config = readConfig(args);
}
} else {
config = readConfig(args);

if (
config.configPath &&
fs.existsSync(config.configPath) &&
!fs.statSync(config.configPath).isDirectory()
) {
hasConfigFile = true;
}
} catch (error) {
if (args.config) {
throw error;
}
config = undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is all a bit overkill. readConfig() won't throw if no config file exists

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Simplified the config reading logic by removing the try-catch block and fs checks. Now using const hasConfigFile = Boolean(config.configPath) to detect if a config file exists (lines 137-146).

let compatibilityDate =
args.compatibilityDate ?? config?.compatibility_date;
const compatibilityFlags =
args.compatibilityFlags?.map(String) ??
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't need a .map(String)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Removed .map(String) and used a type assertion instead: compatibilityFlags as string[] (lines 229-230 and 235).

Comment on lines 251 to 263
if (!compatibilityDate) {
const miniflareEntry = require.resolve("miniflare");
const miniflareRequire = module.createRequire(miniflareEntry);
const miniflareWorkerd = miniflareRequire("workerd") as {
compatibilityDate: string;
};
compatibilityDate = miniflareWorkerd.compatibilityDate;
if (hasConfigFile) {
logger.warn(
`No compatibility_date was specified. Using the installed Workers runtime's latest supported date: ${compatibilityDate}`
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

At this point there should always be a compat date. Remove this check

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Removed the entire if (!compatibilityDate) check since getDevCompatibilityDate() now guarantees a compatibility date is always returned (lines 224-228).

devin-ai-integration bot and others added 2 commits November 12, 2025 22:08
- Use getDevCompatibilityDate() utility instead of manual workerd resolution
- Simplify config reading by removing unnecessary try-catch and fs checks
- Remove .map(String) from compatibilityFlags (use type assertion instead)
- Remove redundant if (!compatibilityDate) check
- Remove unused node:module import

Co-Authored-By: [email protected] <[email protected]>
- Add type assertion to handle yargs array type (string | number)[]
- Ensure compatibilityFlags is typed as string[] for getNodeCompat()
- Provide default empty array when compatibilityFlags is undefined

Co-Authored-By: [email protected] <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

1 participant