diff --git a/.husky/check-versions.js b/.husky/check-versions.js index 40321fee..fc5d5297 100644 --- a/.husky/check-versions.js +++ b/.husky/check-versions.js @@ -1,24 +1,66 @@ import fs from 'node:fs'; import semver from 'semver'; +/** + * This script ensures that the aliased dependencies in package.json stay in sync + * with the versions defined in apiVersionMetadata. + */ + // Read package.json const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); +const apiVersionMetadata = packageJson.apiVersionMetadata; + +if (!apiVersionMetadata) { + console.error('Error: missing apiVersionMetadata in package.json'); + process.exit(1); +} + +let hasError = false; + +// Iterate through each API version defined in metadata +for (const [apiVersion, metadata] of Object.entries(apiVersionMetadata)) { + const expectedDeps = metadata.dependencies; + if (!expectedDeps) continue; -// Extract versions -const devServerDependencyVersion = packageJson.dependencies['@lwc/lwc-dev-server']; -const devServerTargetVersionRange = packageJson.apiVersionMetadata?.target?.matchingDevServerVersion; + for (const [depName, expectedRange] of Object.entries(expectedDeps)) { + // For each dependency in metadata, find its aliased counterpart in package.json dependencies + // e.g. @lwc/lwc-dev-server -> @lwc/lwc-dev-server-65.0 + const aliasName = `${depName}-${apiVersion}`; + const actualAliasValue = packageJson.dependencies[aliasName]; -if (!devServerDependencyVersion || !devServerTargetVersionRange) { - console.error('Error: missing @lwc/lwc-dev-server or matchingDevServerVersion'); - process.exit(1); // Fail the check + if (!actualAliasValue) { + console.error(`Error: Missing aliased dependency '${aliasName}' in package.json for API version ${apiVersion}`); + hasError = true; + continue; + } + + // actualAliasValue looks like "npm:@lwc/lwc-dev-server@~13.2.x" or "npm:lwc@~8.23.x" + // We want to extract the version range after the last @ + const match = actualAliasValue.match(/@([^@]+)$/); + if (!match) { + console.error(`Error: Could not parse version range from aliased dependency '${aliasName}': ${actualAliasValue}`); + hasError = true; + continue; + } + + const actualRange = match[1]; + + // Compare the range in metadata with the range in the aliased dependency + if (!semver.intersects(expectedRange, actualRange)) { + console.error( + `Error: Version mismatch for '${aliasName}'. ` + + `Expected ${expectedRange} in apiVersionMetadata, but found ${actualRange} in dependencies.`, + ); + hasError = true; + } + } } -// Compare versions -if (semver.intersects(devServerTargetVersionRange, devServerDependencyVersion)) { - process.exit(0); // Pass the check -} else { +if (hasError) { console.error( - `Error: @lwc/lwc-dev-server versions do not match between 'dependencies' and 'apiVersionMetadata' in package.json. Expected ${devServerDependencyVersion} in apiVersionMetadata > target > matchingDevServerVersion. Got ${devServerTargetVersionRange} instead. When updating the @lwc/lwc-dev-server dependency, you must ensure that it is compatible with the supported API version in this branch, then update apiVersionMetadata > target > matchingDevServerVersion to match, in order to "sign off" on this dependency change.` + '\nWhen updating LWC dependencies, you must ensure that the versions in apiVersionMetadata match the aliased dependencies in package.json.', ); - process.exit(1); // Fail the check + process.exit(1); } + +process.exit(0); diff --git a/DUAL_VERSION.md b/DUAL_VERSION.md new file mode 100644 index 00000000..7aaedf06 --- /dev/null +++ b/DUAL_VERSION.md @@ -0,0 +1,1103 @@ +# Design Proposal: Dual Version Support via NPM Aliasing + +## Problem Statement + +Currently, users must install the specific version of `@salesforce/plugin-lightning-dev` that matches their org's API version. This is because the plugin depends on specific versions of: + +- `@lwc/lwc-dev-server` +- `@lwc/sfdc-lwc-compiler` +- `lwc` + +These dependencies must match (at least in major/minor versions) the LWC runtime version running in the user's org. Since only 2 Salesforce org versions exist at any given time (Latest and Prerelease), we can support both simultaneously in a single plugin installation using NPM aliasing. + +## Goals + +1. **Eliminate version switching**: Users should be able to use a single plugin installation for both Latest and Prerelease orgs +2. **Automatic version detection**: Plugin should automatically determine which org version is being connected to +3. **Transparent operation**: User should not need to know or care about which dependency version is being used +4. **Maintainable**: Solution should be easy to update as new versions are released + +## Proposed Solution: NPM Aliasing with Runtime Branching + +### Overview + +Use NPM package aliasing to install two versions of each critical dependency side-by-side, then dynamically import the correct version at runtime based on the detected org API version. + +### Architecture + +``` +┌─────────────────────────────────────────────────────────────┐ +│ User Command │ +│ sf lightning dev component │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Org Connection Established │ +│ OrgUtils.getOrgAPIVersion(connection) │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Version Resolution (NEW) │ +│ VersionResolver.resolveVersionChannel(apiVersion) │ +│ Returns: 'latest' | 'prerelease' │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Dynamic Dependency Loading (NEW) │ +│ DependencyLoader.loadLwcServer(channel) │ +│ Imports from: @lwc/lwc-dev-server-{channel} │ +└──────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ LWC Server Started │ +│ Using correct version for org │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Implementation Details + +### 1. NPM Aliasing in package.json + +Update the dependencies section to include aliased versions: + +```json +{ + "dependencies": { + // Latest release versions (e.g., API 64.0) + "@lwc/lwc-dev-server-latest": "npm:@lwc/lwc-dev-server@~13.1.x", + "@lwc/sfdc-lwc-compiler-latest": "npm:@lwc/sfdc-lwc-compiler@~13.1.x", + "lwc-latest": "npm:lwc@~8.22.x", + + // Prerelease versions (e.g., API 65.0) + "@lwc/lwc-dev-server-prerelease": "npm:@lwc/lwc-dev-server@~13.2.x", + "@lwc/sfdc-lwc-compiler-prerelease": "npm:@lwc/sfdc-lwc-compiler@~13.2.x", + "lwc-prerelease": "npm:lwc@~8.23.x", + + // Other dependencies remain unchanged + "@inquirer/prompts": "^5.3.8" + // ... etc + } +} +``` + +**Key Points:** + +- Package aliases use a `-latest` and `-prerelease` suffix +- The actual package versions are specified after `npm:` +- Both versions are always installed in `node_modules` + +### 2. Enhanced API Version Metadata + +Expand the `apiVersionMetadata` in `package.json` to include channel information: + +```json +{ + "apiVersionMetadata": { + "channels": { + "latest": { + "supportedApiVersions": ["64.0"], + "dependencies": { + "@lwc/lwc-dev-server": "~13.1.x", + "@lwc/sfdc-lwc-compiler": "~13.1.x", + "lwc": "~8.22.x" + } + }, + "prerelease": { + "supportedApiVersions": ["65.0", "66.0"], + "dependencies": { + "@lwc/lwc-dev-server": "~13.2.x", + "@lwc/sfdc-lwc-compiler": "~13.2.x", + "lwc": "~8.23.x" + } + } + }, + "defaultChannel": "latest", + "versionToTagMappings": [ + // Keep existing mappings for backward compatibility docs + ] + } +} +``` + +### 3. New Module: VersionResolver + +Create `src/shared/versionResolver.ts`: + +```typescript +/** + * Resolves org API version to appropriate dependency channel + */ +export type VersionChannel = 'latest' | 'prerelease'; + +export interface ChannelConfig { + supportedApiVersions: string[]; + dependencies: { + [key: string]: string; + }; +} + +export class VersionResolver { + private static channelMetadata: Map | null = null; + + /** + * Loads channel metadata from package.json + */ + private static loadChannelMetadata(): Map { + if (this.channelMetadata) { + return this.channelMetadata; + } + + const packageJson = this.getPackageJson(); + const channels = packageJson.apiVersionMetadata.channels; + + this.channelMetadata = new Map(); + for (const [channel, config] of Object.entries(channels)) { + this.channelMetadata.set(channel as VersionChannel, config as ChannelConfig); + } + + return this.channelMetadata; + } + + /** + * Given an org API version, returns the appropriate channel + * + * @param orgApiVersion - The API version from the org (e.g., "65.0") + * @returns The channel to use ('latest' or 'prerelease') + * @throws Error if the API version is not supported by any channel + */ + public static resolveChannel(orgApiVersion: string): VersionChannel { + const channels = this.loadChannelMetadata(); + + for (const [channel, config] of channels.entries()) { + if (config.supportedApiVersions.includes(orgApiVersion)) { + return channel; + } + } + + // If no exact match, try to find by major.minor comparison + const orgMajorMinor = this.getMajorMinor(orgApiVersion); + for (const [channel, config] of channels.entries()) { + for (const supportedVersion of config.supportedApiVersions) { + if (this.getMajorMinor(supportedVersion) === orgMajorMinor) { + return channel; + } + } + } + + throw new Error( + `Unsupported org API version: ${orgApiVersion}. ` + `This plugin supports: ${this.getSupportedVersionsList()}` + ); + } + + /** + * Extracts major.minor from a version string (e.g., "65.0" from "65.0.1") + */ + private static getMajorMinor(version: string): string { + const parts = version.split('.'); + return `${parts[0]}.${parts[1]}`; + } + + /** + * Returns a formatted list of all supported API versions + */ + private static getSupportedVersionsList(): string { + const channels = this.loadChannelMetadata(); + const allVersions: string[] = []; + + for (const config of channels.values()) { + allVersions.push(...config.supportedApiVersions); + } + + return allVersions.join(', '); + } + + /** + * Returns the default channel from package.json + */ + public static getDefaultChannel(): VersionChannel { + const packageJson = this.getPackageJson(); + return packageJson.apiVersionMetadata.defaultChannel as VersionChannel; + } + + private static getPackageJson(): any { + // Implementation similar to OrgUtils.ensureMatchingAPIVersion + const dirname = path.dirname(url.fileURLToPath(import.meta.url)); + const packageJsonFilePath = path.resolve(dirname, '../../package.json'); + return CommonUtils.loadJsonFromFile(packageJsonFilePath); + } +} +``` + +### 4. New Module: DependencyLoader + +Create `src/shared/dependencyLoader.ts`: + +```typescript +import type { LWCServer, ServerConfig, Workspace } from '@lwc/lwc-dev-server'; +import type { VersionChannel } from './versionResolver.js'; + +/** + * Interface for dynamically loaded LWC server module + */ +interface LwcDevServerModule { + startLwcDevServer: (config: ServerConfig, logger: any) => Promise; + LWCServer: typeof LWCServer; + ServerConfig: typeof ServerConfig; + Workspace: typeof Workspace; +} + +/** + * Dynamically loads LWC dependencies based on version channel + */ +export class DependencyLoader { + private static loadedModules: Map = new Map(); + + /** + * Loads the LWC dev server module for the specified channel + * Uses dynamic import to load the aliased package at runtime + * + * @param channel - The version channel ('latest' or 'prerelease') + * @returns The loaded module + */ + public static async loadLwcDevServer(channel: VersionChannel): Promise { + // Check cache first + if (this.loadedModules.has(channel)) { + return this.loadedModules.get(channel)!; + } + + // Construct the aliased package name + const packageName = `@lwc/lwc-dev-server-${channel}`; + + try { + // Dynamic import of the aliased package + const module = (await import(packageName)) as LwcDevServerModule; + this.loadedModules.set(channel, module); + return module; + } catch (error) { + throw new Error( + `Failed to load LWC dev server for channel '${channel}'. ` + + `Package '${packageName}' could not be imported. ` + + `Error: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + /** + * Loads the LWC compiler module for the specified channel + * + * @param channel - The version channel ('latest' or 'prerelease') + * @returns The loaded compiler module + */ + public static async loadLwcCompiler(channel: VersionChannel): Promise { + const packageName = `@lwc/sfdc-lwc-compiler-${channel}`; + + try { + return await import(packageName); + } catch (error) { + throw new Error( + `Failed to load LWC compiler for channel '${channel}'. ` + + `Package '${packageName}' could not be imported. ` + + `Error: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + /** + * Loads the base LWC module for the specified channel + * + * @param channel - The version channel ('latest' or 'prerelease') + * @returns The loaded LWC module + */ + public static async loadLwc(channel: VersionChannel): Promise { + const packageName = `lwc-${channel}`; + + try { + return await import(packageName); + } catch (error) { + throw new Error( + `Failed to load LWC for channel '${channel}'. ` + + `Package '${packageName}' could not be imported. ` + + `Error: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + /** + * Clears the module cache (useful for testing) + */ + public static clearCache(): void { + this.loadedModules.clear(); + } +} +``` + +### 5. Updated OrgUtils + +Modify `src/shared/orgUtils.ts` to replace `ensureMatchingAPIVersion`: + +```typescript +/** + * Determines the version channel for the connected org + * + * @param connection - The connection to the org + * @param overrideChannel - Optional manual override from flag or env var + * @returns The version channel to use for dependencies + * @throws Error if the org version is not supported or invalid override provided + */ +public static getVersionChannel( + connection: Connection, + overrideChannel?: VersionChannel +): VersionChannel { + // Priority 1: Explicit override parameter (from --version-channel flag) + if (overrideChannel) { + Messages.getInstance().log(`Using manually specified version channel: ${overrideChannel}`); + return overrideChannel; + } + + // Priority 2: Environment variable override + const envOverride = process.env.FORCE_VERSION_CHANNEL; + if (envOverride) { + const validChannels: VersionChannel[] = ['latest', 'prerelease']; + if (validChannels.includes(envOverride as VersionChannel)) { + Messages.getInstance().log( + `Using version channel from FORCE_VERSION_CHANNEL: ${envOverride}` + ); + return envOverride as VersionChannel; + } else { + throw new Error( + `Invalid FORCE_VERSION_CHANNEL value: "${envOverride}". ` + + `Valid values are: ${validChannels.join(', ')}` + ); + } + } + + // Priority 3: Skip check for testing (legacy compatibility) + if (process.env.SKIP_API_VERSION_CHECK === 'true') { + return VersionResolver.getDefaultChannel(); + } + + // Priority 4: Automatic detection based on org version + const orgVersion = connection.version; + + try { + const channel = VersionResolver.resolveChannel(orgVersion); + Messages.getInstance().log( + `Auto-detected version channel '${channel}' for org API version ${orgVersion}` + ); + return channel; + } catch (error) { + // Enhance error with helpful message + throw new Error( + `${error instanceof Error ? error.message : String(error)}\n` + + `Your org is on API version ${orgVersion}. ` + + `Please ensure you are using the correct version of the CLI and this plugin.` + ); + } +} + +// Keep the old method but mark as deprecated for now +/** @deprecated Use getVersionChannel instead */ +public static ensureMatchingAPIVersion(connection: Connection): void { + // Implementation can call getVersionChannel and throw if it fails + this.getVersionChannel(connection); +} +``` + +### 6. Updated LWC Server Initialization + +Modify `src/lwc-dev-server/index.ts`: + +```typescript +import { Connection } from '@salesforce/core'; +import { OrgUtils } from '../shared/orgUtils.js'; +import { DependencyLoader } from '../shared/dependencyLoader.js'; +import type { VersionChannel } from '../shared/versionResolver.js'; + +export async function startLWCServer( + logger: Logger, + connection: Connection, // NEW: pass connection to determine version + rootDir: string, + token: string, + clientType: string, + serverPorts?: { httpPort: number; httpsPort: number }, + certData?: SSLCertificateData, + workspace?: Workspace, + versionChannelOverride?: VersionChannel // NEW: optional manual override +): Promise { + // NEW: Determine which version channel to use (with optional override) + const channel: VersionChannel = OrgUtils.getVersionChannel(connection, versionChannelOverride); + logger.trace(`Using version channel: ${channel}`); + + // NEW: Load the appropriate version of the dev server + const lwcDevServerModule = await DependencyLoader.loadLwcDevServer(channel); + + const config = await createLWCServerConfig(rootDir, token, clientType, serverPorts, certData, workspace); + + logger.trace(`Starting LWC Dev Server with config: ${JSON.stringify(config)}`); + + // Use the dynamically loaded startLwcDevServer function + let lwcDevServer: LWCServer | null = await lwcDevServerModule.startLwcDevServer(config, logger); + + const cleanup = (): void => { + if (lwcDevServer) { + logger.trace('Stopping LWC Dev Server'); + lwcDevServer.stopServer(); + lwcDevServer = null; + } + }; + + [ + 'exit', // normal exit flow + 'SIGINT', // when a user presses ctrl+c + 'SIGTERM', // when a user kills the process + ].forEach((signal) => process.on(signal, cleanup)); + + return lwcDevServer; +} +``` + +### 7. Update Command Files + +Each command (app.ts, component.ts, site.ts) needs to: + +1. Add the `--version-channel` flag +2. Pass the connection to startLWCServer +3. Support manual override + +```typescript +// In src/commands/lightning/dev/component.ts (and similar for app.ts, site.ts) + +import { Flags } from '@oclif/core'; + +export default class Component extends SfCommand { + public static readonly flags = { + // ... existing flags + 'version-channel': Flags.string({ + summary: 'Manually specify which version channel to use (latest or prerelease)', + description: + 'Override automatic version detection and force a specific dependency channel. ' + + 'Useful for testing and debugging. Valid values: "latest", "prerelease".', + options: ['latest', 'prerelease'], + required: false, + }), + }; + + public async run(): Promise { + const { flags } = await this.parse(Component); + + // ... existing code to get connection + const conn = flags['target-org'].getConnection(); + + // Remove or comment out the old API version check + // OrgUtils.ensureMatchingAPIVersion(conn); + + // ... existing code + + // Pass connection and optional channel override to startLWCServer + const server = await startLWCServer( + this.logger, + conn, // NEW: pass connection + projectDir, + identityToken, + 'sfdx-component', + serverPorts, + certData, + workspace, + flags['version-channel'] as VersionChannel | undefined // NEW: pass override + ); + } +} +``` + +### 8. Optional: Version Channel Caching + +For performance optimization, implement simple caching to avoid repeatedly querying the org: + +```typescript +// In src/shared/versionResolver.ts + +interface CacheEntry { + apiVersion: string; + channel: VersionChannel; + timestamp: number; +} + +export class VersionResolver { + private static channelMetadata: Map | null = null; + private static versionCache: Map = new Map(); + private static readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes + + /** + * Resolves channel with caching support + * + * @param orgId - Unique identifier for the org + * @param orgApiVersion - The API version from the org + * @returns The channel to use + */ + public static resolveChannelWithCache(orgId: string, orgApiVersion: string): VersionChannel { + // Check cache first + const cached = this.versionCache.get(orgId); + if (cached) { + const age = Date.now() - cached.timestamp; + if (age < this.CACHE_TTL_MS && cached.apiVersion === orgApiVersion) { + return cached.channel; + } + // Cache expired or version changed, remove it + this.versionCache.delete(orgId); + } + + // Resolve and cache + const channel = this.resolveChannel(orgApiVersion); + this.versionCache.set(orgId, { + apiVersion: orgApiVersion, + channel, + timestamp: Date.now(), + }); + + return channel; + } + + /** + * Clears the version cache (useful for testing or when orgs are upgraded) + */ + public static clearCache(): void { + this.versionCache.clear(); + } + + /** + * Removes a specific org from the cache + */ + public static removeCacheEntry(orgId: string): void { + this.versionCache.delete(orgId); + } + + // ... rest of existing methods +} +``` + +**Usage in OrgUtils:** + +```typescript +public static getVersionChannel( + connection: Connection, + overrideChannel?: VersionChannel +): VersionChannel { + // ... existing override logic ... + + // Use cached resolution if available + const orgId = connection.getAuthInfoFields().orgId; + const orgVersion = connection.version; + + const channel = VersionResolver.resolveChannelWithCache(orgId, orgVersion); + // ... rest of logic +} +``` + +**Note**: This caching is optional and can be added in a follow-up iteration if performance testing shows it's needed. + +## TypeScript Considerations + +### Type Definitions + +Since we're using aliased packages, TypeScript needs to know about them: + +**Option A: Use `declare module` (Simpler)** + +Create `src/types/aliased-deps.d.ts`: + +```typescript +// Declare aliased LWC dev server packages as having same types as base package +declare module '@lwc/lwc-dev-server-latest' { + export * from '@lwc/lwc-dev-server'; +} + +declare module '@lwc/lwc-dev-server-prerelease' { + export * from '@lwc/lwc-dev-server'; +} + +declare module '@lwc/sfdc-lwc-compiler-latest' { + export * from '@lwc/sfdc-lwc-compiler'; +} + +declare module '@lwc/sfdc-lwc-compiler-prerelease' { + export * from '@lwc/sfdc-lwc-compiler'; +} + +declare module 'lwc-latest' { + export * from 'lwc'; +} + +declare module 'lwc-prerelease' { + export * from 'lwc'; +} +``` + +**Option B: Use TypeScript Path Mapping (More explicit)** + +In `tsconfig.json`: + +```json +{ + "compilerOptions": { + "paths": { + "@lwc/lwc-dev-server-latest": ["./node_modules/@lwc/lwc-dev-server"], + "@lwc/lwc-dev-server-prerelease": ["./node_modules/@lwc/lwc-dev-server"], + "@lwc/sfdc-lwc-compiler-latest": ["./node_modules/@lwc/sfdc-lwc-compiler"], + "@lwc/sfdc-lwc-compiler-prerelease": ["./node_modules/@lwc/sfdc-lwc-compiler"], + "lwc-latest": ["./node_modules/lwc"], + "lwc-prerelease": ["./node_modules/lwc"] + } + } +} +``` + +**Recommendation**: Use Option A (declare module) as it's simpler and doesn't affect the build output. + +## Testing Strategy + +### Unit Tests + +1. **VersionResolver Tests** (`test/shared/versionResolver.test.ts`): + + - Test channel resolution for each supported API version + - Test error handling for unsupported versions + - Test major.minor version matching + - Test default channel retrieval + +2. **DependencyLoader Tests** (`test/shared/dependencyLoader.test.ts`): + + - Test loading each channel's dependencies + - Test caching behavior + - Test error handling for missing packages + - Mock dynamic imports to avoid actual package loading + +3. **OrgUtils Tests** (update existing): + - Test `getVersionChannel` with various API versions + - Test with `SKIP_API_VERSION_CHECK` env var + +### Integration Tests (NUTs) + +1. **Dual Version Tests** (`test/commands/lightning/dev/dualVersion.nut.ts`): + + - Test against an org with API version 64.0 (should use 'latest') + - Test against an org with API version 65.0 (should use 'prerelease') + - Verify correct dependencies are loaded + - Verify dev server starts successfully with each version + +2. **Update Existing NUTs**: + - Ensure existing NUTs work without modification + - Add assertions to verify correct channel is being used + +### Manual Testing Checklist + +- [ ] Install plugin with both dependency versions +- [ ] Connect to a Latest org (e.g., API 64.0) and verify dev server starts +- [ ] Connect to a Prerelease org (e.g., API 65.0) and verify dev server starts +- [ ] Verify hot reload works with both versions +- [ ] Test component preview with both versions +- [ ] Test app preview with both versions +- [ ] Test site preview with both versions +- [ ] Test manual override flag: `--version-channel=latest` and `--version-channel=prerelease` +- [ ] Test environment variable override: `FORCE_VERSION_CHANNEL=latest` and `FORCE_VERSION_CHANNEL=prerelease` +- [ ] Verify that flag override takes precedence over env var +- [ ] Test invalid channel values and verify error messages + +### User Documentation for Manual Override + +**Using the `--version-channel` Flag:** + +For developers who need to test with a specific version or work around automatic detection: + +```bash +# Force use of latest channel +sf lightning dev component --target-org my-org --version-channel latest + +# Force use of prerelease channel +sf lightning dev app --target-org my-org --version-channel prerelease + +# Works with all lightning dev commands +sf lightning dev site --target-org my-org --version-channel latest +``` + +**Using the `FORCE_VERSION_CHANNEL` Environment Variable:** + +For persistent override during a development session: + +```bash +# Set environment variable (bash/zsh) +export FORCE_VERSION_CHANNEL=prerelease +sf lightning dev component --target-org my-org + +# Set for single command +FORCE_VERSION_CHANNEL=latest sf lightning dev component --target-org my-org +``` + +**Override Priority (highest to lowest):** + +1. `--version-channel` flag +2. `FORCE_VERSION_CHANNEL` environment variable +3. `SKIP_API_VERSION_CHECK=true` (legacy, returns default channel) +4. Automatic detection based on org API version + +**Use Cases for Manual Override:** + +- **Testing**: Test your components with different LWC runtime versions +- **Debugging**: Isolate whether an issue is version-specific +- **Preview Upgrades**: Test with prerelease version before org upgrade +- **Workarounds**: If automatic detection fails or org metadata is incorrect +- **Development**: Plugin developers testing against specific versions + +## Migration Strategy + +### Phase 1: Implementation (1-2 weeks) + +1. Add aliased dependencies to package.json +2. Implement VersionResolver and DependencyLoader modules +3. Update OrgUtils with new getVersionChannel method +4. Update lwc-dev-server/index.ts to use dynamic loading +5. Update command files to pass connection to startLWCServer +6. Add TypeScript type declarations for aliased packages +7. Write comprehensive unit tests + +### Phase 2: Integration & Testing (1 week) + +1. Write integration tests (NUTs) +2. Manual testing with both Latest and Prerelease orgs +3. Test edge cases and error scenarios +4. Performance testing to ensure no significant overhead + +### Phase 3: Documentation & Release (1 week) + +1. Update README with new capabilities +2. Update user-facing documentation +3. Update error messages to be more helpful +4. Create migration guide for users +5. Release as major version (breaking change in how versions are handled) + +### Phase 4: Cleanup (future release) + +1. Remove deprecated `ensureMatchingAPIVersion` method +2. Remove old version-specific error messages +3. Update `versionToTagMappings` metadata (may no longer be needed) + +## Rollout Plan + +### Option A: Big Bang (Recommended) + +- Release as a new major version (e.g., v6.0.0) +- Announce that users no longer need to switch plugin versions +- Provide clear upgrade instructions +- Keep v5.x as fallback for any issues + +### Option B: Gradual + +- Release as opt-in feature with flag (e.g., `--use-dual-version`) +- Gather feedback for 1-2 releases +- Make it default behavior in next major version + +**Recommendation**: Option A - The change is transparent to users and provides immediate value. + +## Maintenance Considerations + +### Updating Versions + +When a new Salesforce release comes out: + +1. **Update package.json dependencies**: + + ```json + { + "dependencies": { + // Shift prerelease to latest + "@lwc/lwc-dev-server-latest": "npm:@lwc/lwc-dev-server@~13.2.x", + + // Update prerelease to new version + "@lwc/lwc-dev-server-prerelease": "npm:@lwc/lwc-dev-server@~13.3.x" + } + } + ``` + +2. **Update apiVersionMetadata**: + + ```json + { + "apiVersionMetadata": { + "channels": { + "latest": { + "supportedApiVersions": ["65.0"] // Previous prerelease becomes latest + }, + "prerelease": { + "supportedApiVersions": ["66.0"] // New prerelease version + } + } + } + } + ``` + +3. **Run tests** against both versions +4. **Release** new version of plugin + +### Automation Opportunities + +- Create a script to update versions in package.json +- Automate the shifting of prerelease → latest +- Set up CI/CD to test against both org types +- Create alerts when new LWC package versions are published + +### Extending to 3 Channels (Future) + +If needed, the design can easily support 3 channels. Here's how: + +**1. Update package.json:** + +```json +{ + "dependencies": { + // Previous release (n-2) + "@lwc/lwc-dev-server-previous": "npm:@lwc/lwc-dev-server@~13.1.x", + + // Latest release (n-1) + "@lwc/lwc-dev-server-latest": "npm:@lwc/lwc-dev-server@~13.2.x", + + // Prerelease (n) + "@lwc/lwc-dev-server-prerelease": "npm:@lwc/lwc-dev-server@~13.3.x" + } +} +``` + +**2. Update apiVersionMetadata:** + +```json +{ + "apiVersionMetadata": { + "channels": { + "previous": { + "supportedApiVersions": ["64.0"] + }, + "latest": { + "supportedApiVersions": ["65.0"] + }, + "prerelease": { + "supportedApiVersions": ["66.0"] + } + } + } +} +``` + +**3. Update VersionChannel type:** + +```typescript +export type VersionChannel = 'previous' | 'latest' | 'prerelease'; +``` + +**4. Update command flag options:** + +```typescript +'version-channel': Flags.string({ + options: ['previous', 'latest', 'prerelease'], + // ... +}) +``` + +**5. Update type declarations:** + +Add declarations for `@lwc/lwc-dev-server-previous`, `@lwc/sfdc-lwc-compiler-previous`, and `lwc-previous`. + +**When to use 3 channels:** + +- During transition periods when some orgs haven't upgraded yet +- When supporting extended compatibility windows +- For beta testing environments + +**Trade-offs:** + +- Increases bundle size by ~50% +- Slightly more complex maintenance +- More testing surface area + +The channel-based architecture makes this extension straightforward with minimal code changes. + +## Potential Issues & Mitigations + +### Issue 1: Type Compatibility + +**Problem**: Different versions might have incompatible TypeScript types + +**Mitigation**: + +- Use interface abstraction layer if needed +- Test compilation with both versions during CI +- Create adapter classes if APIs diverge significantly + +### Issue 2: Bundle Size + +**Problem**: Installing two versions doubles the size of LWC dependencies + +**Mitigation**: + +- These are dev dependencies, size is less critical +- Consider optional peer dependencies in future +- Monitor and document bundle size impact + +### Issue 3: Breaking Changes Between Versions + +**Problem**: Major version differences might require different code paths + +**Mitigation**: + +- Create version-specific adapters in DependencyLoader +- Use feature detection rather than version detection where possible +- Maintain compatibility layer + +### Issue 4: Debugging Complexity + +**Problem**: Bug reports might not specify which version was used + +**Mitigation**: + +- Log the channel being used in debug output +- Include channel in error messages +- Add channel info to telemetry (if applicable) + +### Issue 5: Development Environment + +**Problem**: Developers might need to test against specific versions + +**Mitigation**: + +- Add environment variable to force a specific channel (e.g., `FORCE_VERSION_CHANNEL=latest`) +- Add flag to command for testing (e.g., `--version-channel=prerelease`) +- Document development workflow + +## Alternative Approaches Considered + +### Alternative 1: Peer Dependencies + +Install dependencies as peer dependencies and let users install the correct version. + +**Pros**: Smaller plugin size, user has more control +**Cons**: Worse UX, users still need to know which version to install, defeats the purpose + +### Alternative 2: Separate Plugin Packages + +Create two separate plugins: `plugin-lightning-dev` and `plugin-lightning-dev-prerelease` + +**Pros**: Cleaner separation, no complexity in code +**Cons**: Terrible UX, users need to know which to install, doubles maintenance + +### Alternative 3: Lazy Installation + +Detect version and install correct dependencies at runtime via npm/yarn + +**Pros**: Only installs what's needed +**Cons**: Requires write access to node_modules, slow first run, complex error handling, security concerns + +### Alternative 4: Build-time Multiple Distributions + +Build two separate distributions of the plugin, one for each version + +**Pros**: No runtime overhead +**Cons**: Complex build process, doubles CI time, users still need to know which to install + +**Selected Approach**: NPM Aliasing with Runtime Branching (described above) + +- Best balance of UX and maintainability +- Transparent to users +- Manageable complexity +- Industry-standard approach + +## Success Metrics + +1. **User Experience**: Users can connect to any supported org without plugin version switching +2. **Performance**: < 100ms overhead for version resolution and dynamic loading +3. **Reliability**: No increase in error rates for dev server startup +4. **Maintenance**: Version updates can be done in < 30 minutes +5. **Adoption**: 90%+ of users upgrade to new version within 3 months + +## Decisions on Key Questions + +1. **Should we support more than 2 versions?** + + - **Decision**: Start with 2 versions (latest + prerelease) for initial implementation + - Architecture should be extensible to support 3 versions if needed in the future + - Using a channel-based approach makes this straightforward to extend + +2. **How do we handle version deprecation?** + + - **Decision**: Rotate versions with each Salesforce release cycle + - When a new release happens: prerelease → latest, new version → prerelease + - No need to maintain old versions since all orgs are upgraded + - Simple update process: update package.json dependencies and apiVersionMetadata + +3. **Should we cache the version resolution per org?** + + - **Decision**: Implement optional short-term caching + - Cache org API version in memory during command execution + - Consider adding a TTL-based cache (e.g., 5 minutes) to `.sf/` config to reduce org queries + - Cache key: org ID → { apiVersion, channel, timestamp } + - Keep implementation simple initially, can enhance if performance issues arise + +4. **Do we need a manual override flag?** + + - **Decision**: Yes, add manual override for testing and debugging + - Add flag: `--version-channel` to all commands + - Add environment variable: `FORCE_VERSION_CHANNEL` + - Useful for developers, testing, and troubleshooting edge cases + +5. **What about @lwrjs/api dependency?** + - **Decision**: No action needed - LWRJS is deprecated + - Functionality is being removed from sites + - Will be removed in future release, so don't invest in versioning it + - Keep current pinned version (0.18.3) for now + +## Next Steps + +1. **Review and iterate on this design** + + - Get feedback from team + - Address any concerns or questions + - Finalize approach + +2. **Create prototype** + + - Implement core VersionResolver and DependencyLoader + - Test dynamic loading with aliased packages + - Validate TypeScript compilation + +3. **Full implementation** + + - Follow migration strategy outlined above + - Comprehensive testing + - Documentation updates + +4. **Release and monitor** + - Release as new major version + - Monitor for issues + - Gather user feedback + +--- + +## Summary + +This design proposal introduces dual-version support for LWC dependencies using NPM aliasing and runtime branching. Key decisions have been finalized: + +✅ **Approved Approach**: NPM aliasing with 2 channels (latest + prerelease) +✅ **Extensibility**: Architecture supports 3+ channels if needed +✅ **Manual Override**: Flag (`--version-channel`) and environment variable (`FORCE_VERSION_CHANNEL`) +✅ **Caching**: Optional short-term caching with 5-minute TTL +✅ **Version Rotation**: Simple rotation model (prerelease → latest) with each release +✅ **LWRJS**: No versioning needed (deprecated, being removed) + +**Next Step**: Begin Phase 1 Implementation + +--- + +**Document Version**: 2.0 +**Last Updated**: 2025-11-05 +**Author**: Design Proposal +**Status**: ✅ Approved - Ready for Implementation diff --git a/messages/shared.utils.md b/messages/shared.utils.md index 165eed20..f8ff5eac 100644 --- a/messages/shared.utils.md +++ b/messages/shared.utils.md @@ -50,6 +50,10 @@ Couldn't find identity data while generating preview arguments Couldn't find entity ID while generating preview arguments +# error.org.api-unsupported + +Your org is on API Version %s. This version of the plugin supports only %s. Please update your plugin. + # error.no-project This command is required to run from within a Salesforce project directory. %s diff --git a/package.json b/package.json index fda58556..f5b4d35f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,13 @@ "@inquirer/prompts": "^5.3.8", "@inquirer/select": "^2.4.7", "@lwc/lwc-dev-server": "~13.3.8", + "@lwc/lwc-dev-server-65.0": "npm:@lwc/lwc-dev-server@~13.2.x", + "@lwc/lwc-dev-server-66.0": "npm:@lwc/lwc-dev-server@~13.3.x", + "@lwc/lwc-dev-server-67.0": "npm:@lwc/lwc-dev-server@~13.3.x", "@lwc/sfdc-lwc-compiler": "~13.3.8", + "@lwc/sfdc-lwc-compiler-65.0": "npm:@lwc/sfdc-lwc-compiler@~13.2.x", + "@lwc/sfdc-lwc-compiler-66.0": "npm:@lwc/sfdc-lwc-compiler@~13.3.x", + "@lwc/sfdc-lwc-compiler-67.0": "npm:@lwc/sfdc-lwc-compiler@~13.3.x", "@lwrjs/api": "0.18.3", "@oclif/core": "^4.5.6", "@salesforce/core": "^8.24.0", @@ -18,6 +24,9 @@ "axios": "^1.13.2", "glob": "^13.0.0", "lwc": "~8.27.0", + "lwc-65.0": "npm:lwc@~8.23.x", + "lwc-66.0": "npm:lwc@~8.24.x", + "lwc-67.0": "npm:lwc@~8.24.x", "node-fetch": "^3.3.2", "open": "^10.2.0", "xml2js": "^0.6.2" @@ -43,7 +52,7 @@ "typescript": "^5.5.4" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "files": [ "/lib", @@ -112,7 +121,9 @@ "access": "public" }, "resolutions": { - "cliui": "7.0.4" + "cliui": "7.0.4", + "prettier": "^3.7.4", + "pretty-quick": "^4.2.2" }, "wireit": { "build": { @@ -230,41 +241,27 @@ } }, "apiVersionMetadata": { - "x-apiVersionMetadata-comments": [ - "Refer to ApiVersionMetadata in orgUtils.ts for more details.", - "The 'target' section defines the dev server version (matchingDevServerVersion) and the API version that it can support (versionNumber).", - "The 'versionToTagMappings' section defines the mapping between released tags for our CLI plugin and the org version that each tag supports." - ], - "target": { - "versionNumber": "67.0", - "matchingDevServerVersion": "~13.3.8" + "65.0": { + "dependencies": { + "@lwc/lwc-dev-server": "~13.2.x", + "@lwc/sfdc-lwc-compiler": "~13.2.x", + "lwc": "~8.23.x" + } }, - "versionToTagMappings": [ - { - "versionNumber": "62.0", - "tagName": "v1" - }, - { - "versionNumber": "63.0", - "tagName": "v2" - }, - { - "versionNumber": "64.0", - "tagName": "v3" - }, - { - "versionNumber": "65.0", - "tagName": "latest" - }, - { - "versionNumber": "66.0", - "tagName": "prerelease" - }, - { - "versionNumber": "67.0", - "tagName": "next" + "66.0": { + "dependencies": { + "@lwc/lwc-dev-server": "~13.3.x", + "@lwc/sfdc-lwc-compiler": "~13.3.x", + "lwc": "~8.24.x" } - ] + }, + "67.0": { + "dependencies": { + "@lwc/lwc-dev-server": "~13.3.x", + "@lwc/sfdc-lwc-compiler": "~13.3.x", + "lwc": "~8.24.x" + } + } }, "exports": "./lib/index.js", "type": "module", diff --git a/src/commands/lightning/dev/app.ts b/src/commands/lightning/dev/app.ts index 4b13b309..7ce7be13 100644 --- a/src/commands/lightning/dev/app.ts +++ b/src/commands/lightning/dev/app.ts @@ -15,7 +15,7 @@ */ import path from 'node:path'; -import { Logger, Messages, SfProject } from '@salesforce/core'; +import { Logger, Messages, SfProject, Org } from '@salesforce/core'; import { AndroidAppPreviewConfig, AndroidDevice, @@ -29,6 +29,7 @@ import { Flags, SfCommand } from '@salesforce/sf-plugins-core'; import { startLWCServer } from '../../../lwc-dev-server/index.js'; import { PreviewUtils } from '../../../shared/previewUtils.js'; import { PromptUtils } from '../../../shared/promptUtils.js'; +import { MetaUtils } from '../../../shared/metaUtils.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.app'); @@ -78,6 +79,16 @@ export default class LightningDevApp extends SfCommand { const appName = flags['name']; const deviceId = flags['device-id']; + // Auto enable local dev + if (process.env.AUTO_ENABLE_LOCAL_DEV === 'true') { + try { + await MetaUtils.ensureLightningPreviewEnabled(targetOrg.getConnection(undefined)); + await MetaUtils.ensureFirstPartyCookiesNotRequired(targetOrg.getConnection(undefined)); + } catch (error) { + this.log('Error autoenabling local dev', error); + } + } + let sfdxProjectRootPath = ''; try { sfdxProjectRootPath = await SfProject.resolveProjectPath(); @@ -102,16 +113,18 @@ export default class LightningDevApp extends SfCommand { if (platform === Platform.desktop) { await this.desktopPreview( + targetOrg, sfdxProjectRootPath, serverPorts, ldpServerToken, ldpServerId, ldpServerUrl, appId, - logger + logger, ); } else { await this.mobilePreview( + targetOrg, platform, sfdxProjectRootPath, serverPorts, @@ -121,25 +134,26 @@ export default class LightningDevApp extends SfCommand { appName, appId, deviceId, - logger + logger, ); } } private async desktopPreview( + org: Org, sfdxProjectRootPath: string, serverPorts: { httpPort: number; httpsPort: number }, ldpServerToken: string, ldpServerId: string, ldpServerUrl: string, appId: string | undefined, - logger: Logger + logger: Logger, ): Promise { if (!appId) { logger.debug('No Lightning Experience application name provided.... using the default app instead.'); } - const targetOrg = PreviewUtils.getTargetOrgFromArguments(this.argv); + const targetOrgArg = PreviewUtils.getTargetOrgFromArguments(this.argv); if (ldpServerUrl.startsWith('wss')) { this.log(`\n${messages.getMessage('trust.local.dev.server')}`); @@ -149,17 +163,27 @@ export default class LightningDevApp extends SfCommand { ldpServerUrl, ldpServerId, appId, - targetOrg + targetOrgArg, ); // Start the LWC Dev Server - await startLWCServer(logger, sfdxProjectRootPath, ldpServerToken, Platform.desktop, serverPorts); + await startLWCServer( + logger, + org.getConnection(undefined), + sfdxProjectRootPath, + ldpServerToken, + Platform.desktop, + serverPorts, + undefined, + undefined, + ); // Open the browser and navigate to the right page await this.config.runCommand('org:open', launchArguments); } private async mobilePreview( + org: Org, platform: Platform.ios | Platform.android, sfdxProjectRootPath: string, serverPorts: { httpPort: number; httpsPort: number }, @@ -169,7 +193,7 @@ export default class LightningDevApp extends SfCommand { appName: string | undefined, appId: string | undefined, deviceId: string | undefined, - logger: Logger + logger: Logger, ): Promise { try { // Verify that user environment is set up for mobile (i.e. has right tooling) @@ -240,7 +264,7 @@ export default class LightningDevApp extends SfCommand { platform, logger, this.spinner, - this.progress + this.progress, ); // on iOS the bundle comes as a ZIP archive so we need to extract it first @@ -260,7 +284,16 @@ export default class LightningDevApp extends SfCommand { } // Start the LWC Dev Server - await startLWCServer(logger, sfdxProjectRootPath, ldpServerToken, platform, serverPorts, certData); + await startLWCServer( + logger, + org.getConnection(undefined), + sfdxProjectRootPath, + ldpServerToken, + platform, + serverPorts, + certData, + undefined, + ); // Launch the native app for previewing (launchMobileApp will show its own spinner) // eslint-disable-next-line camelcase @@ -268,7 +301,7 @@ export default class LightningDevApp extends SfCommand { ldpServerUrl, ldpServerId, appName, - appId + appId, ); const targetActivity = (appConfig as AndroidAppPreviewConfig)?.activity; const targetApp = targetActivity ? `${appConfig.id}/${targetActivity}` : appConfig.id; diff --git a/src/commands/lightning/dev/component.ts b/src/commands/lightning/dev/component.ts index 5f5e4974..a2f6288f 100644 --- a/src/commands/lightning/dev/component.ts +++ b/src/commands/lightning/dev/component.ts @@ -66,7 +66,7 @@ export default class LightningDevComponent extends SfCommand !!component); if (componentName) { // validate that the component exists before launching the server const match = components.find( - (component) => componentName === component.name || componentName === component.label + (component) => componentName === component.name || componentName === component.label, ); if (!match) { throw new Error(messages.getMessage('error.component-not-found', [componentName])); @@ -161,14 +161,25 @@ export default class LightningDevComponent extends SfCommand { const connection = org.getConnection(undefined); + // Auto enable local dev + if (process.env.AUTO_ENABLE_LOCAL_DEV === 'true') { + try { + await MetaUtils.ensureLightningPreviewEnabled(connection); + await MetaUtils.ensureFirstPartyCookiesNotRequired(connection); + } catch (error) { + this.log('Error autoenabling local dev', error); + } + } + const localDevEnabled = await OrgUtils.isLocalDevEnabled(connection); if (!localDevEnabled) { throw new Error(sharedMessages.getMessage('error.localdev.not.enabled')); } - OrgUtils.ensureMatchingAPIVersion(connection); - // If user doesn't specify a site, prompt the user for one if (!siteName) { const allSites = await ExperienceSite.getAllExpSites(org); @@ -96,7 +105,7 @@ export default class LightningDevSite extends SfCommand { selectedSite: ExperienceSite, getLatest: boolean, siteName: string, - guest: boolean + guest: boolean, ): Promise { let siteZip: string | undefined; @@ -182,7 +191,16 @@ export default class LightningDevSite extends SfCommand { this.log(`Local Dev Server url is ${ldpServerUrl}`); const logger = await Logger.child(this.ctor.name); - await startLWCServer(logger, sfdxProjectRootPath, ldpServerToken, Platform.desktop, serverPorts); + await startLWCServer( + logger, + connection, + sfdxProjectRootPath, + ldpServerToken, + Platform.desktop, + serverPorts, + undefined, + undefined, + ); const url = new URL(previewUrl); url.searchParams.set('aura.ldpServerUrl', ldpServerUrl); url.searchParams.set('aura.ldpServerId', ldpServerId); diff --git a/src/lwc-dev-server/index.ts b/src/lwc-dev-server/index.ts index dada38e9..58364d9e 100644 --- a/src/lwc-dev-server/index.ts +++ b/src/lwc-dev-server/index.ts @@ -15,10 +15,11 @@ */ import process from 'node:process'; -import { LWCServer, ServerConfig, startLwcDevServer, Workspace } from '@lwc/lwc-dev-server'; -import { Lifecycle, Logger, SfProject } from '@salesforce/core'; +import type { LWCServer, ServerConfig, Workspace } from '@lwc/lwc-dev-server'; +import { Connection, Lifecycle, Logger, SfProject } from '@salesforce/core'; import { SSLCertificateData } from '@salesforce/lwc-dev-mobile-core'; import { glob } from 'glob'; +import { loadLwcDevServer } from '../shared/dependencyLoader.js'; import { ConfigUtils, LOCAL_DEV_SERVER_DEFAULT_HTTP_PORT, @@ -31,7 +32,7 @@ async function createLWCServerConfig( clientType: string, serverPorts?: { httpPort: number; httpsPort: number }, certData?: SSLCertificateData, - workspace?: Workspace + workspace?: Workspace, ): Promise { const project = await SfProject.resolve(); const packageDirs = project.getPackageDirectories(); @@ -75,17 +76,23 @@ async function createLWCServerConfig( export async function startLWCServer( logger: Logger, + connection: Connection, rootDir: string, token: string, clientType: string, serverPorts?: { httpPort: number; httpsPort: number }, certData?: SSLCertificateData, - workspace?: Workspace + workspace?: Workspace, ): Promise { + const orgApiVersion = connection.version; + logger.trace(`Starting LWC server for org API version: ${orgApiVersion}`); + + const lwcDevServerModule = await loadLwcDevServer(orgApiVersion); + const config = await createLWCServerConfig(rootDir, token, clientType, serverPorts, certData, workspace); logger.trace(`Starting LWC Dev Server with config: ${JSON.stringify(config)}`); - let lwcDevServer: LWCServer | null = await startLwcDevServer(config, logger); + let lwcDevServer = (await lwcDevServerModule.startLwcDevServer(config, logger)) as LWCServer | null; const cleanup = (): void => { if (lwcDevServer) { @@ -101,5 +108,5 @@ export async function startLWCServer( 'SIGTERM', // when a user kills the process ].forEach((signal) => process.on(signal, cleanup)); - return lwcDevServer; + return lwcDevServer as LWCServer; } diff --git a/src/shared/dependencyLoader.ts b/src/shared/dependencyLoader.ts new file mode 100644 index 00000000..f604e3bc --- /dev/null +++ b/src/shared/dependencyLoader.ts @@ -0,0 +1,107 @@ +/* + * Copyright 2026, Salesforce, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Logger } from '@salesforce/core'; +import packageJsonImport from '../../package.json' with { type: 'json' }; + +type PackageJson = { + apiVersionMetadata: Record; +}; + +const packageJson = packageJsonImport as unknown as PackageJson; + +/** + * Type for dynamically loaded LWC server module + */ +export type LwcDevServerModule = { + startLwcDevServer: (config: unknown, logger: Logger) => Promise; + LWCServer: unknown; + Workspace: unknown; +}; + +/** + * Returns a formatted list of all supported API versions + */ +function getSupportedVersionsList(): string { + return Object.keys(packageJson.apiVersionMetadata).sort().join(', '); +} + +/** + * Given an org API version, returns the matched supported version string + * + * @param orgApiVersion - The API version from the org (e.g., "65.0") + * @returns The matched version string (e.g., "65.0") + * @throws Error if the API version is not supported + */ +function resolveApiVersion(orgApiVersion: string): string { + const metadata = packageJson.apiVersionMetadata; + + // Exact match + if (metadata[orgApiVersion]) { + return orgApiVersion; + } + + throw new Error(`Unsupported org API version: ${orgApiVersion}. This plugin supports: ${getSupportedVersionsList()}`); +} + +/** + * Internal helper to dynamically load an aliased dependency + */ +async function loadDependency(orgApiVersion: string, packagePrefix: string, friendlyName: string): Promise { + const version = resolveApiVersion(orgApiVersion); + const packageName = `${packagePrefix}${version}`; + + try { + return (await import(packageName)) as T; + } catch (error) { + throw new Error( + `Failed to load ${friendlyName} for version '${version}'. ` + + `Package '${packageName}' could not be imported. ` + + `Error: ${error instanceof Error ? error.message : String(error)}`, + ); + } +} + +/** + * Loads the LWC dev server module for the specified org API version + * Uses dynamic import to load the aliased package at runtime + * + * @param orgApiVersion - The API version from the org (e.g., '65.0.1') + * @returns The loaded module + */ +export async function loadLwcDevServer(orgApiVersion: string): Promise { + return loadDependency(orgApiVersion, '@lwc/lwc-dev-server-', 'LWC dev server'); +} + +/** + * Loads the LWC compiler module for the specified org API version + * + * @param orgApiVersion - The API version from the org (e.g., '65.0.1') + * @returns The loaded compiler module + */ +export async function loadLwcCompiler(orgApiVersion: string): Promise { + return loadDependency(orgApiVersion, '@lwc/sfdc-lwc-compiler-', 'LWC compiler'); +} + +/** + * Loads the base LWC module for the specified org API version + * + * @param orgApiVersion - The API version from the org (e.g., '65.0.1') + * @returns The loaded LWC module + */ +export async function loadLwc(orgApiVersion: string): Promise { + return loadDependency(orgApiVersion, 'lwc-', 'LWC'); +} diff --git a/src/shared/orgUtils.ts b/src/shared/orgUtils.ts index 44a14863..22e00e8c 100644 --- a/src/shared/orgUtils.ts +++ b/src/shared/orgUtils.ts @@ -14,13 +14,7 @@ * limitations under the License. */ -import path from 'node:path'; -import url from 'node:url'; -import { Connection, Messages } from '@salesforce/core'; -import { CommonUtils, Version } from '@salesforce/lwc-dev-mobile-core'; - -Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); -const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'shared.utils'); +import { Connection } from '@salesforce/core'; type LightningPreviewMetadataResponse = { enableLightningPreviewPref?: string; @@ -36,36 +30,7 @@ export type AppDefinition = { /** * As we go through different phases of release cycles, in order to ensure that the API version supported by * the local dev server matches with Org API versions, we rely on defining a metadata section in package.json - * - * The "apiVersionMetadata" entry in this json file defines "target" and "versionToTagMappings" sections. - * - * "target.versionNumber" defines the API version that the local dev server supports. As we pull in new versions - * of the lwc-dev-server we need to manually update "target.versionNumber" in package.json In order to ensure - * that we don't forget this step, we also have "target.matchingDevServerVersion" which is used by husky during - * the pre-commit check to ensure that we have updated the "apiVersionMetadata" section. Whenever we pull in - * a new version of lwc-dev-server in our dependencies, we must also update "target.matchingDevServerVersion" - * to the same version otherwise the pre-commit will fail. This means that, as the PR owner deliberately - * updates "target.matchingDevServerVersion", they are responsible to ensuring that the rest of the data under - * "apiVersionMetadata" is accurate. - * - * The "versionToTagMappings" section will provide a mapping between supported API version by the dev server - * and the tagged version of our plugin. We use "versionToTagMappings" to convey to the user which version of - * our plugin should they be using to match with the API version of their org (i.e which version of our plugin - * contains the lwc-dev-server dependency that can support the API version of their org). */ -type ApiVersionMetadata = { - target: { - versionNumber: string; - matchingDevServerVersion: string; - }; - versionToTagMappings: [ - { - versionNumber: string; - tagName: string; - } - ]; -}; - export class OrgUtils { /** * Given an app name, it queries the AppDefinition table in the org to find @@ -111,7 +76,7 @@ export class OrgUtils { const appMenuItemsQuery = 'SELECT Label,Description,Name FROM AppMenuItem WHERE IsAccessible=true AND IsVisible=true'; const appMenuItems = await connection.query<{ Label: string; Description: string; Name: string }>( - appMenuItemsQuery + appMenuItemsQuery, ); const appDefinitionsQuery = "SELECT DeveloperName,DurableId FROM AppDefinition WHERE UiType='Lightning'"; @@ -160,53 +125,4 @@ export class OrgUtils { } throw new Error('Could not save the app server identity token to the org.'); } - - /** - * Given a connection to an Org, it ensures that org API version matches what the local dev server expects. - * To do this, it compares the org API version with the meta data stored in package.json under apiVersionMetadata. - * If the API versions do not match then this method will throw an exception. - * - * @param connection the connection to the org - */ - public static ensureMatchingAPIVersion(connection: Connection): void { - // Testing purposes only - using this flag may cause local development to not function correctly - if (process.env.SKIP_API_VERSION_CHECK === 'true') { - return; - } - - const dirname = path.dirname(url.fileURLToPath(import.meta.url)); - const packageJsonFilePath = path.resolve(dirname, '../../package.json'); - - const pkg = CommonUtils.loadJsonFromFile(packageJsonFilePath) as { - name: string; - apiVersionMetadata: ApiVersionMetadata; - }; - const targetVersion = pkg.apiVersionMetadata.target.versionNumber; - const orgVersion = connection.version; - - if (Version.same(orgVersion, targetVersion) === false) { - let errorMessage = messages.getMessage('error.org.api-mismatch.message', [orgVersion, targetVersion]); - // Find the tag (if any) that can support this org version - const tagName = pkg.apiVersionMetadata.versionToTagMappings.find( - (info) => info.versionNumber === orgVersion - )?.tagName; - if (tagName) { - const remediation = messages.getMessage('error.org.api-mismatch.remediation', [ - tagName, - `${pkg.name}@${tagName}`, - ]); - errorMessage = `${errorMessage} ${remediation}`; - } - - // Examples of error messages are as below (where the tag name comes from apiVersionMetadata in package.json): - // - // Your org is on API version 61.0, but this version of the CLI plugin supports API version 62.0. To use the plugin with this org, you can reinstall or update the plugin using the "latest" tag. For example: "sf plugins install @salesforce/plugin-lightning-dev@latest". - // - // Your org is on API version 62.0, but this version of the CLI plugin supports API version 63.0. To use the plugin with this org, you can reinstall or update the plugin using the "next" tag. For example: "sf plugins install @salesforce/plugin-lightning-dev@next". - // - // Your org is on API version 63.0, but this version of the CLI plugin supports API version 62.0. To use the plugin with this org, you can reinstall or update the plugin using the "latest" tag. For example: "sf plugins install @salesforce/plugin-lightning-dev@latest". - - throw new Error(errorMessage); - } - } } diff --git a/src/shared/previewUtils.ts b/src/shared/previewUtils.ts index a075b35a..747acb4b 100644 --- a/src/shared/previewUtils.ts +++ b/src/shared/previewUtils.ts @@ -55,7 +55,7 @@ export class PreviewUtils { public static generateWebSocketUrlForLocalDevServer( platform: string, ports: { httpPort: number; httpsPort: number }, - logger?: Logger + logger?: Logger, ): string { return LwcDevMobileCorePreviewUtils.generateWebSocketUrlForLocalDevServer(platform, ports, logger); } @@ -98,7 +98,7 @@ export class PreviewUtils { public static async getMobileDevice( platform: Platform.ios | Platform.android, deviceId?: string, - logger?: Logger + logger?: Logger, ): Promise { let device: BaseDevice | undefined; @@ -133,7 +133,7 @@ export class PreviewUtils { public static async getLightningExperienceAppId( connection: Connection, appName?: string, - logger?: Logger + logger?: Logger, ): Promise { if (appName) { logger?.debug(`Determining App Id for ${appName}`); @@ -201,7 +201,7 @@ export class PreviewUtils { ldpServerId: string, appId?: string, targetOrg?: string, - auraMode = DevPreviewAuraMode + auraMode = DevPreviewAuraMode, ): string[] { // appPath will resolve to one of the following: // @@ -236,7 +236,7 @@ export class PreviewUtils { ldpServerUrl: string, ldpServerId: string, componentName?: string, - targetOrg?: string + targetOrg?: string, ): string[] { let appPath = `lwr/application/e/devpreview/ai/localdev-preview?ldpServerUrl=${ldpServerUrl}&ldpServerId=${ldpServerId}`; if (componentName) { @@ -267,7 +267,7 @@ export class PreviewUtils { instanceUrl: string, ldpServerUrl: string, ldpServerId: string, - componentName?: string + componentName?: string, ): string { let url = `${instanceUrl}/lwr/application/e/devpreview/ai/localdev-preview?ldpServerUrl=${ldpServerUrl}&ldpServerId=${ldpServerId}`; if (componentName) { @@ -285,7 +285,7 @@ export class PreviewUtils { * @param ldpServerId Record ID for the identity token * @param appName An optional app name for a targeted LEX app * @param appId An optional app id for a targeted LEX app - * @param auraMode An optional Aura Mode (defaults to DEVPREVIEW) + * @param auraMode An Aura Mode (defaults to DEVPREVIEW) * @returns Array of arguments to be used as custom launch arguments when launching a mobile app. */ public static generateMobileAppPreviewLaunchArguments( @@ -293,7 +293,7 @@ export class PreviewUtils { ldpServerId: string, appName?: string, appId?: string, - auraMode = DevPreviewAuraMode + auraMode = DevPreviewAuraMode, ): LaunchArgument[] { const launchArguments: LaunchArgument[] = []; @@ -336,7 +336,7 @@ export class PreviewUtils { * * @param platform A mobile platform (iOS or Android) * @param logger An optional logger to be used for logging - * @param progress An optional spinner indicator for reporting messages + * @param spinner An optional spinner indicator for reporting messages * @param progress An optional progress indicator for reporting progress * @returns The path to downloaded file. */ @@ -344,7 +344,7 @@ export class PreviewUtils { platform: Platform.ios | Platform.android, logger?: Logger, spinner?: Spinner, - progress?: Progress + progress?: Progress, ): Promise { const sfdcUrl = platform === Platform.ios @@ -396,8 +396,7 @@ export class PreviewUtils { return new Promise((resolve, reject) => { if (progress && totalSize) { - response.body?.on('data', (chunk) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + response.body?.on('data', (chunk: string) => { downloadedSize += chunk.length; const percentage = parseFloat(Math.min((downloadedSize / totalSize) * 100, 100).toFixed(1)); progress.update(percentage); @@ -438,8 +437,6 @@ export class PreviewUtils { return Promise.reject(new Error(sharedMessages.getMessage('error.localdev.not.enabled'))); } - OrgUtils.ensureMatchingAPIVersion(connection); - const appServerIdentity = await PreviewUtils.getOrCreateAppServerIdentity(connection); const ldpServerToken = appServerIdentity.identityToken; const ldpServerId = appServerIdentity.usernameToServerEntityIdMap[username]; diff --git a/src/types/aliased-deps.d.ts b/src/types/aliased-deps.d.ts new file mode 100644 index 00000000..f9834441 --- /dev/null +++ b/src/types/aliased-deps.d.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2026, Salesforce, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare module '@lwc/lwc-dev-server-65.0' { + export * from '@lwc/lwc-dev-server'; +} + +declare module '@lwc/lwc-dev-server-66.0' { + export * from '@lwc/lwc-dev-server'; +} + +declare module '@lwc/lwc-dev-server-67.0' { + export * from '@lwc/lwc-dev-server'; +} + +declare module '@lwc/sfdc-lwc-compiler-65.0' { + export * from '@lwc/sfdc-lwc-compiler'; +} + +declare module '@lwc/sfdc-lwc-compiler-66.0' { + export * from '@lwc/sfdc-lwc-compiler'; +} + +declare module '@lwc/sfdc-lwc-compiler-67.0' { + export * from '@lwc/sfdc-lwc-compiler'; +} + +declare module 'lwc-65.0' { + export * from 'lwc'; +} + +declare module 'lwc-66.0' { + export * from 'lwc'; +} + +declare module 'lwc-67.0' { + export * from 'lwc'; +} diff --git a/test/commands/lightning/dev/app.test.ts b/test/commands/lightning/dev/app.test.ts index 27dc2a77..a09bd624 100644 --- a/test/commands/lightning/dev/app.test.ts +++ b/test/commands/lightning/dev/app.test.ts @@ -62,7 +62,7 @@ describe('lightning dev app', () => { 'iPhone 15 Pro Max', DeviceType.mobile, AppleOSType.iOS, - new Version(17, 5, 0) + new Version(17, 5, 0), ); const testAndroidDevice = new AndroidDevice( 'Pixel_5_API_34', @@ -70,7 +70,7 @@ describe('lightning dev app', () => { DeviceType.mobile, AndroidOSType.googleAPIs, new Version(34, 0, 0), - false + false, ); const certData: SSLCertificateData = { derCertificate: Buffer.from('A', 'utf-8'), @@ -90,6 +90,7 @@ describe('lightning dev app', () => { testIdentityData.usernameToServerEntityIdMap[testUsername] = testLdpServerId; beforeEach(async () => { + process.env.SKIP_API_VERSION_CHECK = 'true'; stubUx($$.SANDBOX); stubSpinner($$.SANDBOX); await $$.stubAuths(testOrgData); @@ -102,7 +103,6 @@ describe('lightning dev app', () => { $$.SANDBOX.stub(Connection.prototype, 'getUsername').returns(testUsername); $$.SANDBOX.stub(PreviewUtils, 'getOrCreateAppServerIdentity').resolves(testIdentityData); $$.SANDBOX.stub(OrgUtils, 'isLocalDevEnabled').resolves(true); - $$.SANDBOX.stub(OrgUtils, 'ensureMatchingAPIVersion').returns(); MockedLightningPreviewApp = await esmock('../../../../src/commands/lightning/dev/app.js', { '../../../../src/lwc-dev-server/index.js': { @@ -112,6 +112,7 @@ describe('lightning dev app', () => { }); afterEach(() => { + delete process.env.SKIP_API_VERSION_CHECK; $$.restore(); }); @@ -151,7 +152,7 @@ describe('lightning dev app', () => { try { $$.SANDBOX.stub(OrgUtils, 'getAppDefinitionDurableId').resolves(testAppDefinition.DurableId); $$.SANDBOX.stub(PreviewUtils, 'generateWebSocketUrlForLocalDevServer').throws( - new Error('Cannot determine LDP url.') + new Error('Cannot determine LDP url.'), ); await MockedLightningPreviewApp.run(['--name', 'Sales', '-o', testOrgData.username, '-t', Platform.desktop]); } catch (err) { @@ -173,7 +174,7 @@ describe('lightning dev app', () => { it('prompts user to select lightning app when not provided', async () => { const promptStub = $$.SANDBOX.stub(PromptUtils, 'promptUserToSelectLightningExperienceApp').resolves( - testAppDefinition + testAppDefinition, ); await verifyOrgOpen(`lightning/app/${testAppDefinition.DurableId}`, Platform.desktop); expect(promptStub.calledOnce); @@ -243,7 +244,7 @@ describe('lightning dev app', () => { $$.SANDBOX.stub(LwcDevMobileCoreSetup.prototype, 'run').resolves(); $$.SANDBOX.stub(PreviewUtils, 'getMobileDevice').callsFake((platform) => - Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice) + Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice), ); await verifyMobileThrowsWhenDeviceFailsToBoot(Platform.ios); @@ -258,7 +259,7 @@ describe('lightning dev app', () => { $$.SANDBOX.stub(LwcDevMobileCoreSetup.prototype, 'run').resolves(); $$.SANDBOX.stub(PreviewUtils, 'getMobileDevice').callsFake((platform) => - Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice) + Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice), ); $$.SANDBOX.stub(AppleDevice.prototype, 'boot').resolves(); @@ -278,7 +279,7 @@ describe('lightning dev app', () => { $$.SANDBOX.stub(LwcDevMobileCoreSetup.prototype, 'run').resolves(); $$.SANDBOX.stub(PreviewUtils, 'getMobileDevice').callsFake((platform) => - Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice) + Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice), ); $$.SANDBOX.stub(PreviewUtils, 'generateSelfSignedCert').resolves(certData); @@ -313,7 +314,7 @@ describe('lightning dev app', () => { $$.SANDBOX.stub(LwcDevMobileCoreSetup.prototype, 'run').resolves(); $$.SANDBOX.stub(PreviewUtils, 'getMobileDevice').callsFake((platform) => - Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice) + Promise.resolve(platform === Platform.ios ? testIOSDevice : testAndroidDevice), ); $$.SANDBOX.stub(PreviewUtils, 'generateSelfSignedCert').resolves(certData); @@ -414,11 +415,11 @@ describe('lightning dev app', () => { expectedLdpServerUrl, testLdpServerId, 'Sales', - testAppDefinition.DurableId + testAppDefinition.DurableId, ); const downloadStub = $$.SANDBOX.stub(PreviewUtils, 'downloadSalesforceMobileAppBundle').resolves( - testBundleArchive + testBundleArchive, ); const extractStub = $$.SANDBOX.stub(CommonUtils, 'extractZIPArchive').resolves(); const installStub = diff --git a/test/shared/dependencyLoader.test.ts b/test/shared/dependencyLoader.test.ts new file mode 100644 index 00000000..e9961446 --- /dev/null +++ b/test/shared/dependencyLoader.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2026, Salesforce, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { loadLwcDevServer, loadLwcCompiler, loadLwc } from '../../src/shared/dependencyLoader.js'; + +describe('DependencyLoader', () => { + it('exists and has expected methods', () => { + expect(typeof loadLwcDevServer).to.equal('function'); + expect(typeof loadLwcCompiler).to.equal('function'); + expect(typeof loadLwc).to.equal('function'); + }); + + it('loads the aliased package (real import call)', async () => { + // This will actually try to call import() which should work since we ran yarn install. + // However, loading LWC modules in Node might still trigger ReferenceErrors if browser globals are missing. + // We use a try-catch to handle both cases and just verify the attempt was made. + try { + const module = await loadLwcDevServer('65.0'); + expect(module).to.exist; + } catch (error) { + // If it fails with a ReferenceError or similar, it's still "working" in terms of + // attempting to load the right package name. + const errorMessage = (error as Error).message; + if (errorMessage.includes('could not be imported')) { + expect(errorMessage).to.include('@lwc/lwc-dev-server-65.0'); + } else { + // Other errors (like ReferenceError: Element is not defined) mean the package WAS found and loaded + expect(errorMessage).to.not.include('could not be imported'); + } + } + }); +}); diff --git a/test/shared/previewUtils.test.ts b/test/shared/previewUtils.test.ts index bfcec0a3..3f4300e6 100644 --- a/test/shared/previewUtils.test.ts +++ b/test/shared/previewUtils.test.ts @@ -31,7 +31,7 @@ import { SSLCertificateData, Version, } from '@salesforce/lwc-dev-mobile-core'; -import { AuthInfo, Connection, Logger, Org } from '@salesforce/core'; +import { AuthInfo, Connection, Org } from '@salesforce/core'; import { PreviewUtils as LwcDevMobileCorePreviewUtils } from '@salesforce/lwc-dev-mobile-core'; import { ConfigUtils, @@ -49,7 +49,7 @@ describe('previewUtils', () => { 'iPhone 15 Pro Max', DeviceType.mobile, AppleOSType.iOS, - new Version(17, 5, 0) + new Version(17, 5, 0), ); const testAndroidDevice = new AndroidDevice( 'Pixel_5_API_34', @@ -57,7 +57,7 @@ describe('previewUtils', () => { DeviceType.mobile, AndroidOSType.googleAPIs, new Version(34, 0, 0), - false + false, ); const testUsername = 'SalesforceDeveloper'; @@ -70,7 +70,12 @@ describe('previewUtils', () => { }; testIdentityData.usernameToServerEntityIdMap[testUsername] = testLdpServerId; + beforeEach(() => { + process.env.SKIP_API_VERSION_CHECK = 'true'; + }); + afterEach(() => { + delete process.env.SKIP_API_VERSION_CHECK; $$.restore(); }); @@ -121,8 +126,8 @@ describe('previewUtils', () => { testLdpServerId, 'MyAppId', 'MyTargetOrg', - 'MyAuraMode' - ) + 'MyAuraMode', + ), ).to.deep.equal([ '--path', `lightning/app/MyAppId?0.aura.ldpServerUrl=MyLdpServerUrl&0.aura.ldpServerId=${testLdpServerId}&0.aura.mode=MyAuraMode`, @@ -143,8 +148,8 @@ describe('previewUtils', () => { testLdpServerId, 'MyAppName', 'MyAppId', - 'MyAuraMode' - ) + 'MyAuraMode', + ), ).to.deep.equal([ { name: 'LightningExperienceAppName', value: 'MyAppName' }, { name: 'LightningExperienceAppID', value: 'MyAppId' }, @@ -205,7 +210,7 @@ describe('previewUtils', () => { 'https://localhost:3333', testLdpServerId, 'myTestComponent', - 'myTargetOrg' + 'myTargetOrg', ); const parsed = parseArgs({ @@ -227,7 +232,7 @@ describe('previewUtils', () => { 'https://localhost:3333', testLdpServerId, undefined, - 'myTargetOrg' + 'myTargetOrg', ); const parsed = parseArgs({ @@ -248,7 +253,7 @@ describe('previewUtils', () => { const result = PreviewUtils.generateComponentPreviewLaunchArguments( 'https://localhost:3333', testLdpServerId, - 'myTestComponent' + 'myTestComponent', ); const parsed = parseArgs({ @@ -319,13 +324,15 @@ describe('previewUtils', () => { const generateWebSocketUrlStub = $$.SANDBOX.stub( LwcDevMobileCorePreviewUtils, - 'generateWebSocketUrlForLocalDevServer' + 'generateWebSocketUrlForLocalDevServer', ).returns(mockUrl); - const result = PreviewUtils.generateWebSocketUrlForLocalDevServer(platform, ports, {} as Logger); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + const result = PreviewUtils.generateWebSocketUrlForLocalDevServer(platform, ports, {} as any); expect(result).to.equal(mockUrl); - expect(generateWebSocketUrlStub.calledOnceWith(platform, ports, {} as Logger)).to.be.true; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any + expect(generateWebSocketUrlStub.calledOnceWith(platform, ports, {} as any)).to.be.true; }); it('initializePreviewConnection succeeds with valid org', async () => { @@ -336,7 +343,6 @@ describe('previewUtils', () => { } as Org; $$.SANDBOX.stub(OrgUtils, 'isLocalDevEnabled').resolves(true); - $$.SANDBOX.stub(OrgUtils, 'ensureMatchingAPIVersion').returns(); $$.SANDBOX.stub(PreviewUtils, 'getOrCreateAppServerIdentity').resolves(testIdentityData); const result = await PreviewUtils.initializePreviewConnection(mockOrg); @@ -391,7 +397,6 @@ describe('previewUtils', () => { }; $$.SANDBOX.stub(OrgUtils, 'isLocalDevEnabled').resolves(true); - $$.SANDBOX.stub(OrgUtils, 'ensureMatchingAPIVersion').returns(); $$.SANDBOX.stub(PreviewUtils, 'getOrCreateAppServerIdentity').resolves(identityDataWithoutEntityId); try { diff --git a/test/tsconfig.json b/test/tsconfig.json index 7183d88b..8e058f14 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -2,6 +2,9 @@ "extends": "@salesforce/dev-config/tsconfig-test-strict-esm", "include": ["./**/*.ts", "./**/*.nut.ts"], "compilerOptions": { - "skipLibCheck": true + "skipLibCheck": true, + "resolveJsonModule": true, + "module": "nodenext", + "moduleResolution": "nodenext" } } diff --git a/tsconfig.json b/tsconfig.json index 1fa9d631..8dc5c245 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "@salesforce/dev-config/tsconfig-strict-esm", "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", "outDir": "lib", "rootDir": "src", "skipLibCheck": true, - "baseUrl": "." + "baseUrl": ".", + "resolveJsonModule": true }, "include": ["./src/**/*.ts"] } diff --git a/yarn.lock b/yarn.lock index 39add557..09bd626d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -677,6 +677,27 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790" integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== +"@babel/core@7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.4.tgz#12a550b8794452df4c8b084f95003bce1742d496" + integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.4" + "@babel/parser" "^7.28.4" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.4" + "@babel/types" "^7.28.4" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/core@7.28.5", "@babel/core@^7.23.9", "@babel/core@^7.26.10", "@babel/core@^7.9.0": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" @@ -749,6 +770,17 @@ "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" +"@babel/generator@^7.28.3": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.6.tgz#48dcc65d98fcc8626a48f72b62e263d25fc3c3f1" + integrity sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw== + dependencies: + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/generator@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" @@ -932,6 +964,13 @@ dependencies: "@babel/types" "^7.28.5" +"@babel/parser@^7.28.4", "@babel/parser@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.6.tgz#f01a8885b7fa1e56dd8a155130226cd698ef13fd" + integrity sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ== + dependencies: + "@babel/types" "^7.28.6" + "@babel/plugin-syntax-decorators@7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz#ee7dd9590aeebc05f9d4c8c0560007b05979a63d" @@ -1057,6 +1096,14 @@ "@babel/types" "^7.28.5" debug "^4.3.1" +"@babel/types@7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a" + integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/types@7.28.5", "@babel/types@^7.22.10", "@babel/types@^7.26.10", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.9.0", "@babel/types@~7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" @@ -1065,6 +1112,14 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@babel/types@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.6.tgz#c3e9377f1b155005bcc4c46020e7e394e13089df" + integrity sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@commitlint/cli@^17.1.2": version "17.8.1" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-17.8.1.tgz#10492114a022c91dcfb1d84dac773abb3db76d33" @@ -1513,13 +1568,20 @@ debug "^4.3.1" minimatch "^3.1.2" -"@eslint/config-helpers@^0.4.2": +"@eslint/config-helpers@^0.4.1", "@eslint/config-helpers@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda" integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== dependencies: "@eslint/core" "^0.17.0" +"@eslint/core@^0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.16.0.tgz#490254f275ba9667ddbab344f4f0a6b7a7bd7209" + integrity sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q== + dependencies: + "@types/json-schema" "^7.0.15" + "@eslint/core@^0.17.0": version "0.17.0" resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c" @@ -1562,6 +1624,11 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.38.0": + version "9.38.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.38.0.tgz#f7aa9c7577577f53302c1d795643589d7709ebd1" + integrity sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A== + "@eslint/js@9.39.2": version "9.39.2" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.2.tgz#2d4b8ec4c3ea13c1b3748e0c97ecd766bdd80599" @@ -1577,7 +1644,7 @@ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== -"@eslint/plugin-kit@^0.4.1": +"@eslint/plugin-kit@^0.4.0", "@eslint/plugin-kit@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2" integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== @@ -2210,11 +2277,41 @@ dependencies: "@locker/shared" "0.24.6" +"@lwc/aria-reflection@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/aria-reflection/-/aria-reflection-8.23.0.tgz#b4d1f31e5f380d49e28b6dfe07c505d0657024e4" + integrity sha512-WGaMjNc84art9cYtkMf15dCKZ7M1x1yldsbqctiKOTl6mN6d7EDRaV+046EkFMkC/FwQbspWTHF9x1UGqWV8pw== + +"@lwc/aria-reflection@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/aria-reflection/-/aria-reflection-8.24.0.tgz#d8b0fd092fd6ea92d5d42a5d45e004b98ec6372b" + integrity sha512-X6wYl0omMVsElJTpi+8ntyCaOfoRjtVF27K3SnaGaNkntIby/Suz/XKJN1KKgD+hAyQtWzxEsrAbdCYani2ROQ== + "@lwc/aria-reflection@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/aria-reflection/-/aria-reflection-8.27.0.tgz#7fa9cc6652c67ed73fdaf2a2a4f29dca2c9160c2" integrity sha512-sOLY5Mm8lWscJU+aDg0/v7sX2fphwO2ZSL2b54+9gvRVgkC+2X4MboPQwTWTkCecJYgeOf1HatXhqMorkwQftg== +"@lwc/babel-plugin-component@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/babel-plugin-component/-/babel-plugin-component-8.23.0.tgz#756762acb6c5ba17f18614d8a858f377a4e55fbc" + integrity sha512-Dct16w1mSoL0gIZFNSQI6EQjOAnOkmdbCBAf2PMD7mJXQKNYYgb4RcA4BDIoZZJwe5nH7rd6q47YaeD7pdxCvg== + dependencies: + "@babel/helper-module-imports" "7.27.1" + "@lwc/errors" "8.23.0" + "@lwc/shared" "8.23.0" + line-column "~1.0.2" + +"@lwc/babel-plugin-component@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/babel-plugin-component/-/babel-plugin-component-8.24.0.tgz#89aae9ce4dfab40bde1d1d01b087a48581d42de2" + integrity sha512-WaJjoLzNqrhVUHudxv+O04OU5GRNVDfYb1s6fKDYV2VdCHRyl6LQ4v2zZmoeMbahg/S0AO4fyGWxAZS2D7Zuyw== + dependencies: + "@babel/helper-module-imports" "7.27.1" + "@lwc/errors" "8.24.0" + "@lwc/shared" "8.24.0" + line-column "~1.0.2" + "@lwc/babel-plugin-component@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/babel-plugin-component/-/babel-plugin-component-8.27.0.tgz#fc5f117b2616076169a8db5565b520dd0a61a96a" @@ -2225,6 +2322,42 @@ "@lwc/shared" "8.27.0" line-column "~1.0.2" +"@lwc/compiler@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/compiler/-/compiler-8.23.0.tgz#bc5f5406e8d71d4675cfe7276b2443544116f0a7" + integrity sha512-ejGsAR9c+Lv3Xtu6XC8RbNl7XUIt3tIES3g4r3FanrU5FHQ2fsqXdLTT2I9jxlTiKHiRnvpq49pQQLWQcUPr0Q== + dependencies: + "@babel/core" "7.28.4" + "@babel/plugin-transform-async-generator-functions" "7.28.0" + "@babel/plugin-transform-async-to-generator" "7.27.1" + "@babel/plugin-transform-class-properties" "7.27.1" + "@babel/plugin-transform-object-rest-spread" "7.28.4" + "@locker/babel-plugin-transform-unforgeables" "0.22.0" + "@lwc/babel-plugin-component" "8.23.0" + "@lwc/errors" "8.23.0" + "@lwc/shared" "8.23.0" + "@lwc/ssr-compiler" "8.23.0" + "@lwc/style-compiler" "8.23.0" + "@lwc/template-compiler" "8.23.0" + +"@lwc/compiler@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/compiler/-/compiler-8.24.0.tgz#a9227bbd9c5bcd81764fd2895b23750febf69c7d" + integrity sha512-4WlQx1b7V0HlwQY3dLJ7XNdlLPRP8AQlNsfkgkbHGi1YtLx7acFr2ttGHBimsHc4uBHdqdguQ3IQD54agfj+CQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/plugin-transform-async-generator-functions" "7.28.0" + "@babel/plugin-transform-async-to-generator" "7.27.1" + "@babel/plugin-transform-class-properties" "7.27.1" + "@babel/plugin-transform-object-rest-spread" "7.28.4" + "@locker/babel-plugin-transform-unforgeables" "0.22.0" + "@lwc/babel-plugin-component" "8.24.0" + "@lwc/errors" "8.24.0" + "@lwc/shared" "8.24.0" + "@lwc/ssr-compiler" "8.24.0" + "@lwc/style-compiler" "8.24.0" + "@lwc/template-compiler" "8.24.0" + "@lwc/compiler@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/compiler/-/compiler-8.27.0.tgz#6ec761d07d5cb369f223f341ee11e5552928d153" @@ -2243,6 +2376,13 @@ "@lwc/style-compiler" "8.27.0" "@lwc/template-compiler" "8.27.0" +"@lwc/dev-server-plugin-lex@13.2.20": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/dev-server-plugin-lex/-/dev-server-plugin-lex-13.2.20.tgz#f48e0d43f42e4316f18eb1ed26fcbfb5cff1749a" + integrity sha512-+VvN5sLILmT2KIWRolx8S9aGFV3mPqn2u78Q0g7UAXVqT2ld/4ZSfEUDVXSrTGNu+4MZbBxU31WZzeuxc8vkmA== + dependencies: + magic-string "~0.30.21" + "@lwc/dev-server-plugin-lex@13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/dev-server-plugin-lex/-/dev-server-plugin-lex-13.3.8.tgz#9a05785c11b4a5196e2f9a2eaeeb9bd707799d2a" @@ -2250,6 +2390,31 @@ dependencies: magic-string "~0.30.21" +"@lwc/dev-server-plugin-lex@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/dev-server-plugin-lex/-/dev-server-plugin-lex-13.3.9.tgz#cef2da9034b55c702b1d43d749e0b47c1299167e" + integrity sha512-FAswqYnV+ypLIWmAdpnut9UMneZtSPUQ0SMEO2+A/lqit9HAMMnKObEk7pgX2rZcNRKYeddT7hj3QuGcWeYOoA== + dependencies: + magic-string "~0.30.21" + +"@lwc/engine-core@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-core/-/engine-core-8.23.0.tgz#04ac9204140685c5d4f69cc3fe8c8bb6d7ffe4df" + integrity sha512-YFobCuGRv0me1FLhJqtSDm/WxTpRyPtdHbfBe/6AKWDFfYYPk83tcMFTTS7ndE3LrYno2aP9ABHdg5BtAl55iA== + dependencies: + "@lwc/features" "8.23.0" + "@lwc/shared" "8.23.0" + "@lwc/signals" "8.23.0" + +"@lwc/engine-core@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-core/-/engine-core-8.24.0.tgz#38c5575a7e8e48048f0d77664b667ce9f3111bff" + integrity sha512-XYMx7wmVY84g7mWzEUUo/26gN3x6/H91Naaul5jKbFJXHrf1YQTF794S+5YPI82GlZYFiDNMYKqi3FXAqvyUpQ== + dependencies: + "@lwc/features" "8.24.0" + "@lwc/shared" "8.24.0" + "@lwc/signals" "8.24.0" + "@lwc/engine-core@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/engine-core/-/engine-core-8.27.0.tgz#78ed2748c045339d51ac4a1d3ca656346f9aea2e" @@ -2259,16 +2424,46 @@ "@lwc/shared" "8.27.0" "@lwc/signals" "8.27.0" +"@lwc/engine-dom@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-dom/-/engine-dom-8.23.0.tgz#dd45d7c33a318dcdf600796478a7e03e759122df" + integrity sha512-cbMVwFkYmhFFmCpnSYBePk8wnpdhqESVFDZJqFgeR4Tb0LBVlI18gGqHn9MmjxT3SnurDp1EW/ArH8QFYJgf1g== + +"@lwc/engine-dom@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-dom/-/engine-dom-8.24.0.tgz#46985f32c9f9c0522c209b42e72d3b435c1ed7f8" + integrity sha512-H0MeTt1DEYKY98m2ZblpSazuhZzKxxChi/iM/4n4fFWtBF87AAoQtGt1fFnEPCq9D9lGmVF28YQdBjL7NNw6nQ== + "@lwc/engine-dom@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/engine-dom/-/engine-dom-8.27.0.tgz#5be044552038c84811d950c1f483115c4cdfc0b4" integrity sha512-npXl2hx6gyc7wum9wLPCzHz9J9iChiBJk1dKG3J/oY/EJiWxhaJxk0pCIhscn8/7n1wSeQ8DY4B8KeoyFpvmNw== +"@lwc/engine-server@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-server/-/engine-server-8.23.0.tgz#6675516060b8886c23e18faf92ab31b69d6c7053" + integrity sha512-h4HOYAoHWAPEwITroai8yAy6YSlqMXRLdVZNRNH/ZEXkz5Hom+h16BbnGGeGCNqZgGrm58LnCPYmmzeXIZ1aPQ== + +"@lwc/engine-server@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/engine-server/-/engine-server-8.24.0.tgz#bbf00cbc822f44d0dae605d69ea77cd09123527d" + integrity sha512-FTgKGYj1pXtiUgXyi+m5BQCe4IMVAp8eF2sRY+NGV0INrmpKfVQaFd5aakGNl27EGEnr/kWUZrY+/dbtwErIdQ== + "@lwc/engine-server@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/engine-server/-/engine-server-8.27.0.tgz#124fc02d8259f1c6b91322463926bbc51f8efdbf" integrity sha512-ArzdTenZ3MlK5fovAmQw4zJ2d4UwTC+DyFQ0lG453pj57X5KcUAjPOD/dtFoZmPqUU7UC5y85mDIelBWdryA9g== +"@lwc/errors@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/errors/-/errors-8.23.0.tgz#7c230010e197062a0eae04a4caa4abe4e7df4af3" + integrity sha512-cqziHl/aDg0pgAIm9HhNz2OrR0t08vML7+FNrqgrnaSwLgYCYp2WPNmvMjD5ZRy/bIBESwA/dCWf9Cs7Vo/ZGw== + +"@lwc/errors@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/errors/-/errors-8.24.0.tgz#348eff6a6022604273d397b624ca96800b242569" + integrity sha512-shYEI9wjVXjKNRXAMAXHMZ23jvMuJIIkctwpkzFx09PcueflwXu9NfNsUlgK8662cOvnvlpAuYvcT+G0k1/wrw== + "@lwc/errors@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/errors/-/errors-8.27.0.tgz#ffb560bfd48953d553b71a9e573ceefe7d029bfe" @@ -2290,6 +2485,20 @@ globals "~15.14.0" minimatch "~9.0.4" +"@lwc/features@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/features/-/features-8.23.0.tgz#7e0578c89dc39e62d50b732facca7e9e969539e9" + integrity sha512-Y1yVOH6LAJMWJaeUHJwjx7OHjbRxycdSSZKewhQlRTGLrmca1Rtpi31nfrRtcCdOkxfF3oPMFlPlA4ZKDyA6aA== + dependencies: + "@lwc/shared" "8.23.0" + +"@lwc/features@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/features/-/features-8.24.0.tgz#524ee89f11543996b3117e54b62fde867bbf8c44" + integrity sha512-h9FX63i6/wFUzU48jgrRxH3cmxdSZ/HRPwoR3jKb1qLKL0kKkWPF3EuRnXRgqhcD2qhFteTSAUgtwBcRFzvnSg== + dependencies: + "@lwc/shared" "8.24.0" + "@lwc/features@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/features/-/features-8.27.0.tgz#7d2a9af45c4bb4e62cc89ec102c9cd115283e881" @@ -2297,11 +2506,63 @@ dependencies: "@lwc/shared" "8.27.0" +"@lwc/lwc-dev-server-latest@npm:@lwc/lwc-dev-server@~13.2.x": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server/-/lwc-dev-server-13.2.20.tgz#fef34e855aa947a76f4f80365be9b7e2a930229b" + integrity sha512-7I3u3pINBWFvhejEjvxhLGmaGko0y4Mw9ean0mf4F9d90jX+t4SIN9rtN2In9Fi+uhmZAG66/QqqldKVul8PFQ== + dependencies: + "@lwc/lwc-dev-server-types" "13.2.20" + "@lwc/sfdc-lwc-compiler" "13.2.20" + chalk "~5.6.2" + chokidar "~3.6.0" + commander "~14.0.2" + fast-xml-parser "^5.3.0" + glob "^11.0.3" + ws "^8.18.3" + +"@lwc/lwc-dev-server-next@npm:@lwc/lwc-dev-server@~13.3.x": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server/-/lwc-dev-server-13.3.9.tgz#4e922c079738d9b0a3cba64e301a357bc479ca45" + integrity sha512-4HfMSacB0wXnn8tXjb2SIokswjEx3z5bdGQvqCuycF6RPtNel+KZE/4gBtjZtuwRHMXTO8GeyoPmFPTWLi8aVQ== + dependencies: + "@lwc/lwc-dev-server-types" "13.3.9" + "@lwc/sfdc-lwc-compiler" "13.3.9" + chalk "~5.6.2" + chokidar "~3.6.0" + commander "~14.0.2" + fast-xml-parser "^5.3.0" + glob "^11.0.3" + ws "^8.18.3" + +"@lwc/lwc-dev-server-prerelease@npm:@lwc/lwc-dev-server@~13.3.x": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server/-/lwc-dev-server-13.3.9.tgz#4e922c079738d9b0a3cba64e301a357bc479ca45" + integrity sha512-4HfMSacB0wXnn8tXjb2SIokswjEx3z5bdGQvqCuycF6RPtNel+KZE/4gBtjZtuwRHMXTO8GeyoPmFPTWLi8aVQ== + dependencies: + "@lwc/lwc-dev-server-types" "13.3.9" + "@lwc/sfdc-lwc-compiler" "13.3.9" + chalk "~5.6.2" + chokidar "~3.6.0" + commander "~14.0.2" + fast-xml-parser "^5.3.0" + glob "^11.0.3" + ws "^8.18.3" + +"@lwc/lwc-dev-server-types@13.2.20": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server-types/-/lwc-dev-server-types-13.2.20.tgz#aedf477c6b451db452c109729e13de6662fb1585" + integrity sha512-6nMFOoNvusOEjFyQ1YoXzKTGJsTdj/IcneJ3W0ac4B4xxz2twcZybeG4jXZhy970sjdWcaWpqp3Vu5kGtJsnJA== + "@lwc/lwc-dev-server-types@13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server-types/-/lwc-dev-server-types-13.3.8.tgz#43e54f846933193b7a407cbe0b78807273232c48" integrity sha512-ipcr+9KGJYa9D8F/qM817+89wH/x9x6zGDjq6o4jIvO49DFULBNXuSAxC+0zbYTALtdcsnM4YrAufciK0nwf5w== +"@lwc/lwc-dev-server-types@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server-types/-/lwc-dev-server-types-13.3.9.tgz#7f392f845552701650f60cbcc0b4893acfba0678" + integrity sha512-0FUyfDrxtvf0IdiH+ql5j78DwRiIuk5M2QJ+jIFx1OuQrProBp3s+YKLJoYffkmS3rcEYgg/+LbbtA5dba1ICQ== + "@lwc/lwc-dev-server@~13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/lwc-dev-server/-/lwc-dev-server-13.3.8.tgz#2e8215c6c91eabbc3abe08e107daa8edcdb1ba73" @@ -2316,6 +2577,19 @@ glob "^11.0.3" ws "^8.18.3" +"@lwc/metadata@13.2.20": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/metadata/-/metadata-13.2.20.tgz#ff04e6ad34eb8d6f93178d57cc5e1df6a9eb7572" + integrity sha512-Y/SfQTseaO+EqHMFV9yBtaxyUYnAA8FRHrQBfJ/y8oeS7jRr+DSyiOFHJpx5NqsyAtmx2KTjggmWow6GgfjD+A== + dependencies: + "@babel/parser" "~7.28.5" + "@babel/traverse" "~7.28.5" + "@babel/types" "~7.28.5" + "@lwc/sfdc-compiler-utils" "13.2.20" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + postcss-value-parser "~4.2.0" + "@lwc/metadata@13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/metadata/-/metadata-13.3.8.tgz#d8a126cc7b770b27c1b280dc85030d12cf78fd8d" @@ -2329,6 +2603,33 @@ postcss-selector-parser "~7.1.0" postcss-value-parser "~4.2.0" +"@lwc/metadata@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/metadata/-/metadata-13.3.9.tgz#3228facd12b0cf48b8ce59b7a2e883836b66453d" + integrity sha512-otjfamwU6zyYs/DXwyaLhavQ/PAtZ7ot3EU0ZUpcBuPgp9HKdR3aVCigfVNTh4wdYosru1uZbAkLQbHJo/15KA== + dependencies: + "@babel/parser" "~7.28.5" + "@babel/traverse" "~7.28.5" + "@babel/types" "~7.28.5" + "@lwc/sfdc-compiler-utils" "13.3.9" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + postcss-value-parser "~4.2.0" + +"@lwc/module-resolver@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/module-resolver/-/module-resolver-8.23.0.tgz#f98581796558d484516097b7b04121453846f9d1" + integrity sha512-ZqZ/402NvVswMK2HMhwH6Fmkzn19xn5Yx7VZr1QmIefKXr8OKqFSlsySujN3CSwNH9XHybyREWe4TXlkT7LHFw== + dependencies: + resolve "~1.22.10" + +"@lwc/module-resolver@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/module-resolver/-/module-resolver-8.24.0.tgz#fca4582d31af6f3f62638d84de292f0e18aaa1ce" + integrity sha512-Mqj5PCU46coyUMWZ527JC6EwEv0DdIxEJpSK5RgLjgCGdSK7NXYx2zvTnIbWiLLpcj9u82DvFs/FFJu7ixTHbA== + dependencies: + resolve "~1.22.11" + "@lwc/module-resolver@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/module-resolver/-/module-resolver-8.27.0.tgz#57cca88798846054a51a5fe872289ff4ae5fae98" @@ -2336,6 +2637,26 @@ dependencies: resolve "~1.22.11" +"@lwc/rollup-plugin@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/rollup-plugin/-/rollup-plugin-8.23.0.tgz#6821076f721f4b298b2c40d81832ffb55a37c9f6" + integrity sha512-bDlnRXWOVN4VE+/h1dj2KXuej9bED2A07CtxHPepCH4iIwpN6w+s/495zDndJgO/VppnZ3ZUiUooUrcDOrOmBA== + dependencies: + "@lwc/compiler" "8.23.0" + "@lwc/module-resolver" "8.23.0" + "@lwc/shared" "8.23.0" + "@rollup/pluginutils" "~5.3.0" + +"@lwc/rollup-plugin@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/rollup-plugin/-/rollup-plugin-8.24.0.tgz#5fb194a58563fd4f4a02d2c82c6ad56d3fe0612d" + integrity sha512-rPRDIdaw9q2A0jG03exzPmZe2YemGPgT9RCH6QPFppTl9s4MpiozLZvnyzJxLRXWIj2e3fu5Yq0o02e5EquqKw== + dependencies: + "@lwc/compiler" "8.24.0" + "@lwc/module-resolver" "8.24.0" + "@lwc/shared" "8.24.0" + "@rollup/pluginutils" "~5.3.0" + "@lwc/rollup-plugin@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/rollup-plugin/-/rollup-plugin-8.27.0.tgz#40ea66d6729661da00b70390c379208d62cb1611" @@ -2346,11 +2667,171 @@ "@lwc/shared" "8.27.0" "@rollup/pluginutils" "~5.3.0" +"@lwc/sfdc-compiler-utils@13.2.20": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-compiler-utils/-/sfdc-compiler-utils-13.2.20.tgz#1d5985a7169ce5f6192ede48405a3b53cfa3423f" + integrity sha512-IeorL44CtqnOQhqe8QHqaotOp5uWlraeRJHcRhb0Ssz32LAyIf/4rL+9nleVACfSSiKEyVnkBb7ZTo7TD1edkg== + "@lwc/sfdc-compiler-utils@13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/sfdc-compiler-utils/-/sfdc-compiler-utils-13.3.8.tgz#05f6e08902c275f6bbc96148d1cf9859cb46c34c" integrity sha512-yG7FoI3Y485tZInSft6YQpnxt2ljVGUarjdUEvPDdWNEBPG3G5dgLV94xyQc/Ny/Ji1MDjVSo8tJSIM4UJ4yvA== +"@lwc/sfdc-compiler-utils@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-compiler-utils/-/sfdc-compiler-utils-13.3.9.tgz#51ea9456415c23c4480d6862fe82073453550b1a" + integrity sha512-RVGwJOdkuhUS840RNTN2XtmUbHC6/iIxRUdVwjlM1nZL/bAloBdGzO1olqnbcsyQTey9E06lqoT2LrRH1vBJOg== + +"@lwc/sfdc-lwc-compiler-latest@npm:@lwc/sfdc-lwc-compiler@~13.2.x": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.2.20.tgz#a07a58d08098e752967a70102ff296cd700114a8" + integrity sha512-c1TNMX0lS4K8NdtfEdQSmj1gVYD3Bk+JTikWJK8VyWPN55La+2NZ1+Lf+f0bYUyFOYesJa1OTpiScGLnZzQTmQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/parser" "7.28.5" + "@babel/plugin-syntax-decorators" "7.27.1" + "@babel/preset-typescript" "7.28.5" + "@babel/traverse" "7.28.5" + "@babel/types" "7.28.5" + "@komaci/esm-generator" "260.31.0" + "@lwc/dev-server-plugin-lex" "13.2.20" + "@lwc/eslint-plugin-lwc" "3.3.0" + "@lwc/eslint-plugin-lwc-platform" "6.3.0" + "@lwc/metadata" "13.2.20" + "@lwc/sfdc-compiler-utils" "13.2.20" + "@rollup/plugin-babel" "^6.1.0" + "@rollup/plugin-replace" "^6.0.3" + "@rollup/wasm-node" "4.52.5" + "@salesforce/eslint-config-lwc" "4.1.1" + "@salesforce/eslint-plugin-lightning" "2.0.0" + "@swc/wasm" "1.14.0" + astring "~1.9.0" + doctrine "~3.0.0" + eslint "~9.38.0" + eslint-plugin-import "~2.32.0" + eslint-plugin-jest "~29.0.1" + gray-matter "~4.0.3" + line-column "~1.0.2" + magic-string "~0.30.21" + markdown-it "~14.1.0" + parse5-sax-parser "~8.0.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + terser "~5.44.0" + +"@lwc/sfdc-lwc-compiler-next@npm:@lwc/sfdc-lwc-compiler@~13.3.x": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.3.9.tgz#ec52953b75b8336bc5caa8bb06fc814e6fc74fa2" + integrity sha512-e/L6YRjIu5AboaGOLmn1yECRF5OKvzlgipraqf37iJ4qTRXyly8GSaRZZpkBEuQ9V1CI+03TadexMdQjyIuQGQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/parser" "7.28.5" + "@babel/plugin-syntax-decorators" "7.27.1" + "@babel/preset-typescript" "7.28.5" + "@babel/traverse" "7.28.5" + "@babel/types" "7.28.5" + "@komaci/esm-generator" "260.31.0" + "@lwc/dev-server-plugin-lex" "13.3.9" + "@lwc/eslint-plugin-lwc" "3.3.0" + "@lwc/eslint-plugin-lwc-platform" "6.3.0" + "@lwc/metadata" "13.3.9" + "@lwc/sfdc-compiler-utils" "13.3.9" + "@rollup/plugin-babel" "^6.1.0" + "@rollup/plugin-replace" "^6.0.3" + "@rollup/wasm-node" "4.52.5" + "@salesforce/eslint-config-lwc" "4.1.1" + "@salesforce/eslint-plugin-lightning" "2.0.0" + "@swc/wasm" "1.14.0" + astring "~1.9.0" + doctrine "~3.0.0" + eslint "~9.39.1" + eslint-plugin-import "~2.32.0" + eslint-plugin-jest "~29.0.1" + gray-matter "~4.0.3" + line-column "~1.0.2" + magic-string "~0.30.21" + markdown-it "~14.1.0" + meriyah "^5.0.0" + parse5-sax-parser "~8.0.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + terser "~5.44.0" + +"@lwc/sfdc-lwc-compiler-prerelease@npm:@lwc/sfdc-lwc-compiler@~13.3.x": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.3.9.tgz#ec52953b75b8336bc5caa8bb06fc814e6fc74fa2" + integrity sha512-e/L6YRjIu5AboaGOLmn1yECRF5OKvzlgipraqf37iJ4qTRXyly8GSaRZZpkBEuQ9V1CI+03TadexMdQjyIuQGQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/parser" "7.28.5" + "@babel/plugin-syntax-decorators" "7.27.1" + "@babel/preset-typescript" "7.28.5" + "@babel/traverse" "7.28.5" + "@babel/types" "7.28.5" + "@komaci/esm-generator" "260.31.0" + "@lwc/dev-server-plugin-lex" "13.3.9" + "@lwc/eslint-plugin-lwc" "3.3.0" + "@lwc/eslint-plugin-lwc-platform" "6.3.0" + "@lwc/metadata" "13.3.9" + "@lwc/sfdc-compiler-utils" "13.3.9" + "@rollup/plugin-babel" "^6.1.0" + "@rollup/plugin-replace" "^6.0.3" + "@rollup/wasm-node" "4.52.5" + "@salesforce/eslint-config-lwc" "4.1.1" + "@salesforce/eslint-plugin-lightning" "2.0.0" + "@swc/wasm" "1.14.0" + astring "~1.9.0" + doctrine "~3.0.0" + eslint "~9.39.1" + eslint-plugin-import "~2.32.0" + eslint-plugin-jest "~29.0.1" + gray-matter "~4.0.3" + line-column "~1.0.2" + magic-string "~0.30.21" + markdown-it "~14.1.0" + meriyah "^5.0.0" + parse5-sax-parser "~8.0.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + terser "~5.44.0" + +"@lwc/sfdc-lwc-compiler@13.2.20": + version "13.2.20" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.2.20.tgz#a07a58d08098e752967a70102ff296cd700114a8" + integrity sha512-c1TNMX0lS4K8NdtfEdQSmj1gVYD3Bk+JTikWJK8VyWPN55La+2NZ1+Lf+f0bYUyFOYesJa1OTpiScGLnZzQTmQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/parser" "7.28.5" + "@babel/plugin-syntax-decorators" "7.27.1" + "@babel/preset-typescript" "7.28.5" + "@babel/traverse" "7.28.5" + "@babel/types" "7.28.5" + "@komaci/esm-generator" "260.31.0" + "@lwc/dev-server-plugin-lex" "13.2.20" + "@lwc/eslint-plugin-lwc" "3.3.0" + "@lwc/eslint-plugin-lwc-platform" "6.3.0" + "@lwc/metadata" "13.2.20" + "@lwc/sfdc-compiler-utils" "13.2.20" + "@rollup/plugin-babel" "^6.1.0" + "@rollup/plugin-replace" "^6.0.3" + "@rollup/wasm-node" "4.52.5" + "@salesforce/eslint-config-lwc" "4.1.1" + "@salesforce/eslint-plugin-lightning" "2.0.0" + "@swc/wasm" "1.14.0" + astring "~1.9.0" + doctrine "~3.0.0" + eslint "~9.38.0" + eslint-plugin-import "~2.32.0" + eslint-plugin-jest "~29.0.1" + gray-matter "~4.0.3" + line-column "~1.0.2" + magic-string "~0.30.21" + markdown-it "~14.1.0" + parse5-sax-parser "~8.0.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + terser "~5.44.0" + "@lwc/sfdc-lwc-compiler@13.3.8", "@lwc/sfdc-lwc-compiler@~13.3.8": version "13.3.8" resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.3.8.tgz#4235ef3c2124af7b7355478a83b51f7ce9c08b7c" @@ -2389,16 +2870,104 @@ postcss-selector-parser "~7.1.0" terser "~5.44.0" +"@lwc/sfdc-lwc-compiler@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@lwc/sfdc-lwc-compiler/-/sfdc-lwc-compiler-13.3.9.tgz#ec52953b75b8336bc5caa8bb06fc814e6fc74fa2" + integrity sha512-e/L6YRjIu5AboaGOLmn1yECRF5OKvzlgipraqf37iJ4qTRXyly8GSaRZZpkBEuQ9V1CI+03TadexMdQjyIuQGQ== + dependencies: + "@babel/core" "7.28.5" + "@babel/parser" "7.28.5" + "@babel/plugin-syntax-decorators" "7.27.1" + "@babel/preset-typescript" "7.28.5" + "@babel/traverse" "7.28.5" + "@babel/types" "7.28.5" + "@komaci/esm-generator" "260.31.0" + "@lwc/dev-server-plugin-lex" "13.3.9" + "@lwc/eslint-plugin-lwc" "3.3.0" + "@lwc/eslint-plugin-lwc-platform" "6.3.0" + "@lwc/metadata" "13.3.9" + "@lwc/sfdc-compiler-utils" "13.3.9" + "@rollup/plugin-babel" "^6.1.0" + "@rollup/plugin-replace" "^6.0.3" + "@rollup/wasm-node" "4.52.5" + "@salesforce/eslint-config-lwc" "4.1.1" + "@salesforce/eslint-plugin-lightning" "2.0.0" + "@swc/wasm" "1.14.0" + astring "~1.9.0" + doctrine "~3.0.0" + eslint "~9.39.1" + eslint-plugin-import "~2.32.0" + eslint-plugin-jest "~29.0.1" + gray-matter "~4.0.3" + line-column "~1.0.2" + magic-string "~0.30.21" + markdown-it "~14.1.0" + meriyah "^5.0.0" + parse5-sax-parser "~8.0.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + terser "~5.44.0" + +"@lwc/shared@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/shared/-/shared-8.23.0.tgz#c9304f7fd8db4256094e5cbf1960dd4f027aa599" + integrity sha512-g6teckOlRJgPkqFJjjrMWoXwEbP3E0PByVIbrxfvv7gN/d8INL+TOA/Deg5ZgRMwuYUGO0Elr5rGcAK5jj/bhA== + +"@lwc/shared@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/shared/-/shared-8.24.0.tgz#2b28aae08502f7755ee6d01a5539fabf194177e2" + integrity sha512-rYgSg5NLS0M3rvX8iOOez1rFy7JjbB/MWPvIuyNi2z2W/CS7oMen1XTW7you8/d0m0kYM7b7S9gMJHzZAuekXQ== + "@lwc/shared@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/shared/-/shared-8.27.0.tgz#182d69110f980640f9bf349fe9112cb7500e7312" integrity sha512-z8KttkAScdsBhHFx6nOXo9F6RVCBPMoTOJ5DIrNZyjf1UKI03wGcBzTLfNpwFB4uxECDZm4RvOtUQ7uVhqxesg== +"@lwc/signals@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/signals/-/signals-8.23.0.tgz#c38177c9ccd20803392a99715e4770a9e9001104" + integrity sha512-mdW1i0i4RBFracnevRN8YQtkUDI/WuWHsQXGQC2kluQAveM/qmVIkvMCPfehBsMwbXpEnYneUEe58XXnuCsAvA== + +"@lwc/signals@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/signals/-/signals-8.24.0.tgz#1b27ba4635bba210f7288503a5192b9140c7b9fe" + integrity sha512-yvW4JRnAORYYrq3l3L//dG++sz5JM2HQ3lHMLpBbBKGWlLflDIUh6teApz8YUddGAyttTo4LcDAajx2HGN+Kfw== + "@lwc/signals@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/signals/-/signals-8.27.0.tgz#1028ea08b47b020a5ca0ea99017e9b5808d95178" integrity sha512-4LRajgmlTLeEE5sNxFp/PBaLUHGUTNldWzkUywSXtFWQIwyUAzovxoEzs5DFlwVuak8bFc1uEcvyBs1XW8P0Eg== +"@lwc/ssr-compiler@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/ssr-compiler/-/ssr-compiler-8.23.0.tgz#cd3ff236701824188e7b9675e927092ffb34d1b2" + integrity sha512-JucwFx+bjVsnyJnfJIbcX2DpaKO+h3vGEBlDPgI6cdaRfymtkxklxZojzc1HTcN+0XSGSiAmBcDn3MKxsNMrMQ== + dependencies: + "@babel/types" "7.28.4" + "@lwc/errors" "8.23.0" + "@lwc/shared" "8.23.0" + "@lwc/template-compiler" "8.23.0" + acorn "8.15.0" + astring "^1.9.0" + estree-toolkit "^1.7.13" + immer "^10.1.3" + meriyah "^5.0.0" + +"@lwc/ssr-compiler@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/ssr-compiler/-/ssr-compiler-8.24.0.tgz#f35793a44f63f203c14b3c1b080dcb00cb067c0f" + integrity sha512-1pnCDuMx6tUrpMKWwq3NVF10B65CILWBen/Axldg5AxIu6TVdlYoy8CbkHcpeS3+Qd9BpAAuQnkZo+RkVEmYww== + dependencies: + "@babel/types" "7.28.5" + "@lwc/errors" "8.24.0" + "@lwc/shared" "8.24.0" + "@lwc/template-compiler" "8.24.0" + acorn "8.15.0" + astring "^1.9.0" + estree-toolkit "^1.7.13" + immer "^10.2.0" + meriyah "^5.0.0" + "@lwc/ssr-compiler@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/ssr-compiler/-/ssr-compiler-8.27.0.tgz#bfd026ba6395c521095cab75588d37d4927b012b" @@ -2414,11 +2983,41 @@ immer "^11.1.0" meriyah "^5.0.0" +"@lwc/ssr-runtime@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/ssr-runtime/-/ssr-runtime-8.23.0.tgz#29da9702f09992a3cf721fa88057c53dcdd7680a" + integrity sha512-J4JSyEGX+DiBUoMIRBUTcrsc0GGI+LuczO4uSLoMIjFQJXjh5dmI058pVBYq5cCXJHTv2vbtUILzQtX3xcFb0A== + +"@lwc/ssr-runtime@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/ssr-runtime/-/ssr-runtime-8.24.0.tgz#def2b8035f6659f9dc46b0442d3cc1ba67ffbcfd" + integrity sha512-ZZezcxHFwPu244ARazQZufXirXmdN5/ExiQcCQ5dqmtrzd+daypXpUYgD3tPbhI+423YMbQbfFxceiri0kL8Tw== + "@lwc/ssr-runtime@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/ssr-runtime/-/ssr-runtime-8.27.0.tgz#d3733f6560d0205d993996e35122a9b989dfb437" integrity sha512-WLJ65Sabcmk6b6/gYS1D1V9Nc8KiY+9/N1UukEjf1XX3wbDMoursofOdb9N4nQ421tTKZipVT/4LzkWsD9cuLA== +"@lwc/style-compiler@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/style-compiler/-/style-compiler-8.23.0.tgz#508faaea6cd4b5df990cc2c0d91b5bbbe3fa905e" + integrity sha512-hIsmMgKyFQ3VSozQtHuU1BcAbbWyk/8BFygB2WdadM/cBrHfNCy+PGLofv8xkyvhDPrfbWBtwFrP9VIRXDdLNA== + dependencies: + "@lwc/shared" "8.23.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + postcss-value-parser "~4.2.0" + +"@lwc/style-compiler@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/style-compiler/-/style-compiler-8.24.0.tgz#c5b7ee9f00370c13828d0c23483ab0ff23ff5100" + integrity sha512-AtlwvAOl8siJLXSb6mxXMw89HCgRWxNhVeYEsIvmCos9HTkdhoG8PX6EYcQj8oDnYFBqe2WcR2AUYRBqwV1iig== + dependencies: + "@lwc/shared" "8.24.0" + postcss "~8.5.6" + postcss-selector-parser "~7.1.0" + postcss-value-parser "~4.2.0" + "@lwc/style-compiler@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/style-compiler/-/style-compiler-8.27.0.tgz#8cc9e37ecaaa9e23db489a37b31ea8270e6ea562" @@ -2429,11 +3028,43 @@ postcss-selector-parser "~7.1.1" postcss-value-parser "~4.2.0" +"@lwc/synthetic-shadow@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/synthetic-shadow/-/synthetic-shadow-8.23.0.tgz#b209293ac9e1b03f778b71c802c5f2095e814067" + integrity sha512-wmFB6nMKlsH47+YW+Wr3HdhPdUbHor6yPzbsai85St8+xSlrCzQWuXPWuqv6raFyHg6YnWAiF2Hf5e2h9sdCig== + +"@lwc/synthetic-shadow@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/synthetic-shadow/-/synthetic-shadow-8.24.0.tgz#08ce426ab2762c919204d9963a72575fda2bda64" + integrity sha512-46fWZMRaT7a8fbX/03sXNLB6lBM6xJtIfBivexSUyvNkoyE3iNbRDhzFjTOD1O8Gxx/crpBHaiRtzzEuzcrYtg== + "@lwc/synthetic-shadow@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/synthetic-shadow/-/synthetic-shadow-8.27.0.tgz#fe50864a8982a33c741ffedf30d3ea4c6865e465" integrity sha512-SWOnigcLTTJNm7nxObyNbMUTFw66cCFGRdEBL5j5KT5NlmzC9A2rVWrVuvdFj/h9w45tHt0lz6BzALbOv/IaHQ== +"@lwc/template-compiler@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/template-compiler/-/template-compiler-8.23.0.tgz#323ee9d6476b94421b3041ae359b32ec5bfc0d91" + integrity sha512-E24VtNe4Ej307ui8BuQncBzcd6MdzOjXjrhIOQDnGLzNnGL7I3cuGA2wVwTuV8WNrPg7JkgpJghUduEkN3kubw== + dependencies: + "@lwc/errors" "8.23.0" + "@lwc/shared" "8.23.0" + acorn "~8.15.0" + astring "~1.9.0" + he "~1.2.0" + +"@lwc/template-compiler@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/template-compiler/-/template-compiler-8.24.0.tgz#033a33fdd36debcd9b21565a59a8c97e85964c48" + integrity sha512-x4SBSvDnC75QK4P2YCkAiwbTTeEmQ5RveT7LB6sk6WYma+OiDSk8pFrj5SFrsjtOy6oDxedvIpftlrbUa+Yh0w== + dependencies: + "@lwc/errors" "8.24.0" + "@lwc/shared" "8.24.0" + acorn "~8.15.0" + astring "~1.9.0" + he "~1.2.0" + "@lwc/template-compiler@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/template-compiler/-/template-compiler-8.27.0.tgz#fda60ceda1558edd7281b6cd3f70dd77e5de7c52" @@ -2445,6 +3076,20 @@ astring "~1.9.0" he "~1.2.0" +"@lwc/types@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/types/-/types-8.23.0.tgz#f7a3dca0e4c3a6649dbaf9e41eac9f3b99a6ae86" + integrity sha512-MqRqq/eQu36/lI3MnPn4EAIW5JgYXIorlzpnQYLA6kBnViSCYcaDeJJil/FDIzKSF8HgHf7CuXVJ5MUkcXbqJw== + dependencies: + "@lwc/engine-core" "8.23.0" + +"@lwc/types@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/types/-/types-8.24.0.tgz#20c2b9b10104724f492c429dd292ed7ebb652206" + integrity sha512-yQe8VLfrnZoNxGaf13Hs4XJaqBQ8nrKEYfNHUGI9P1tNPGGr1ooNEFGQfNoBkUU7mxZomXRyOD/moUYOIRjqAw== + dependencies: + "@lwc/engine-core" "8.24.0" + "@lwc/types@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/types/-/types-8.27.0.tgz#74525197cbf82024847eee5ca872a81eebee4a1a" @@ -2452,6 +3097,16 @@ dependencies: "@lwc/engine-core" "8.27.0" +"@lwc/wire-service@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@lwc/wire-service/-/wire-service-8.23.0.tgz#c44f5197d921b5fbfa213cb954cccd11b78b9978" + integrity sha512-vAwzn6gSrC/C0FMIXUWl/Ieyg7xaY4SMoMuBiL36ChvtXfSJjHPhmeVjhMGkkGCXyDHS/3f5/9LhplaIi60EfQ== + +"@lwc/wire-service@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@lwc/wire-service/-/wire-service-8.24.0.tgz#50efa7428bccb710c6fee134ba56e0e84925f02c" + integrity sha512-hpwgttHXCCABfWOy9ChspmpMrTX3HP6fYqEb+Qp85NP52jE1YSUgnncQ/lqDZF5Xak4b2pm7wM1gR6jMDT/jmA== + "@lwc/wire-service@8.27.0": version "8.27.0" resolved "https://registry.yarnpkg.com/@lwc/wire-service/-/wire-service-8.27.0.tgz#32be7e77d23ec30f29a255b59a373b37516c08ee" @@ -3241,6 +3896,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.2.7": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" + integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== + "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" @@ -6590,6 +7250,46 @@ eslint@^8.56.0, eslint@^8.57.0: strip-ansi "^6.0.1" text-table "^0.2.0" +eslint@~9.38.0: + version "9.38.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.38.0.tgz#3957d2af804e5cf6cc503c618f60acc71acb2e7e" + integrity sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw== + dependencies: + "@eslint-community/eslint-utils" "^4.8.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.21.1" + "@eslint/config-helpers" "^0.4.1" + "@eslint/core" "^0.16.0" + "@eslint/eslintrc" "^3.3.1" + "@eslint/js" "9.38.0" + "@eslint/plugin-kit" "^0.4.0" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.2" + "@types/estree" "^1.0.6" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.6" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.4.0" + eslint-visitor-keys "^4.2.1" + espree "^10.4.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + eslint@~9.39.1: version "9.39.2" resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.2.tgz#cb60e6d16ab234c0f8369a3fe7cc87967faf4b6c" @@ -6730,21 +7430,6 @@ events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -7229,13 +7914,6 @@ get-stdin@^9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== -get-stream@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -7775,11 +8453,6 @@ https-proxy-agent@^7.0.1: agent-base "^7.0.2" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -7814,7 +8487,7 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -7824,11 +8497,21 @@ ignore@^7.0.3: resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.3.tgz#397ef9315dfe0595671eefe8b633fec6943ab733" integrity sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA== +ignore@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" + integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== +immer@^10.1.3, immer@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.2.0.tgz#88a4ce06a1af64172d254b70f7cb04df51c871b1" + integrity sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw== + immer@^11.1.0: version "11.1.3" resolved "https://registry.yarnpkg.com/immer/-/immer-11.1.3.tgz#78681e1deb6cec39753acf04eb16d7576c04f4d6" @@ -8917,6 +9600,78 @@ lunr@^2.3.9: resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== +"lwc-latest@npm:lwc@~8.23.x": + version "8.23.0" + resolved "https://registry.yarnpkg.com/lwc/-/lwc-8.23.0.tgz#1123a559700aa8bb437f54258efa1ed2be8e94f1" + integrity sha512-XeNx83aT0NZJ8ORfR4bHWIgL5m+XoDJvIX0Og+8ZAr9YYMmZJuBd83tmdhrneYXaJTaGbX54TVbvRY90k+/noA== + dependencies: + "@lwc/aria-reflection" "8.23.0" + "@lwc/babel-plugin-component" "8.23.0" + "@lwc/compiler" "8.23.0" + "@lwc/engine-core" "8.23.0" + "@lwc/engine-dom" "8.23.0" + "@lwc/engine-server" "8.23.0" + "@lwc/errors" "8.23.0" + "@lwc/features" "8.23.0" + "@lwc/module-resolver" "8.23.0" + "@lwc/rollup-plugin" "8.23.0" + "@lwc/shared" "8.23.0" + "@lwc/ssr-compiler" "8.23.0" + "@lwc/ssr-runtime" "8.23.0" + "@lwc/style-compiler" "8.23.0" + "@lwc/synthetic-shadow" "8.23.0" + "@lwc/template-compiler" "8.23.0" + "@lwc/types" "8.23.0" + "@lwc/wire-service" "8.23.0" + +"lwc-next@npm:lwc@~8.24.x": + version "8.24.0" + resolved "https://registry.yarnpkg.com/lwc/-/lwc-8.24.0.tgz#fa97aa528c58c813374ce70004af6396747a8b2a" + integrity sha512-u2l1MSulS5W1YIPkeA0ndG2vWFBgAnLGAkYGdbvhEuDdvhIJ7J/U+ftca3f67bx655y1jiBoWjiGEdUDprPcTQ== + dependencies: + "@lwc/aria-reflection" "8.24.0" + "@lwc/babel-plugin-component" "8.24.0" + "@lwc/compiler" "8.24.0" + "@lwc/engine-core" "8.24.0" + "@lwc/engine-dom" "8.24.0" + "@lwc/engine-server" "8.24.0" + "@lwc/errors" "8.24.0" + "@lwc/features" "8.24.0" + "@lwc/module-resolver" "8.24.0" + "@lwc/rollup-plugin" "8.24.0" + "@lwc/shared" "8.24.0" + "@lwc/ssr-compiler" "8.24.0" + "@lwc/ssr-runtime" "8.24.0" + "@lwc/style-compiler" "8.24.0" + "@lwc/synthetic-shadow" "8.24.0" + "@lwc/template-compiler" "8.24.0" + "@lwc/types" "8.24.0" + "@lwc/wire-service" "8.24.0" + +"lwc-prerelease@npm:lwc@~8.24.x": + version "8.24.0" + resolved "https://registry.yarnpkg.com/lwc/-/lwc-8.24.0.tgz#fa97aa528c58c813374ce70004af6396747a8b2a" + integrity sha512-u2l1MSulS5W1YIPkeA0ndG2vWFBgAnLGAkYGdbvhEuDdvhIJ7J/U+ftca3f67bx655y1jiBoWjiGEdUDprPcTQ== + dependencies: + "@lwc/aria-reflection" "8.24.0" + "@lwc/babel-plugin-component" "8.24.0" + "@lwc/compiler" "8.24.0" + "@lwc/engine-core" "8.24.0" + "@lwc/engine-dom" "8.24.0" + "@lwc/engine-server" "8.24.0" + "@lwc/errors" "8.24.0" + "@lwc/features" "8.24.0" + "@lwc/module-resolver" "8.24.0" + "@lwc/rollup-plugin" "8.24.0" + "@lwc/shared" "8.24.0" + "@lwc/ssr-compiler" "8.24.0" + "@lwc/ssr-runtime" "8.24.0" + "@lwc/style-compiler" "8.24.0" + "@lwc/synthetic-shadow" "8.24.0" + "@lwc/template-compiler" "8.24.0" + "@lwc/types" "8.24.0" + "@lwc/wire-service" "8.24.0" + lwc@~8.27.0: version "8.27.0" resolved "https://registry.yarnpkg.com/lwc/-/lwc-8.27.0.tgz#6d8ce66e0c014cf22e5a034573ae9296d6406d93" @@ -9573,7 +10328,7 @@ normalize-url@^8.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -10012,7 +10767,7 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.1: +picocolors@^1.0.1, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -10022,11 +10777,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-3.0.1.tgz#817033161def55ec9638567a2f3bbc876b3e7516" - integrity sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag== - picomatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" @@ -10141,23 +10891,23 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^2.8.8, prettier@^3.7.4: + version "3.7.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.7.4.tgz#d2f8335d4b1cec47e1c8098645411b0c9dff9c0f" + integrity sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA== -pretty-quick@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-3.3.1.tgz#cfde97fec77a8d201a0e0c9c71d9990e12587ee2" - integrity sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg== +pretty-quick@^3.3.1, pretty-quick@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-4.2.2.tgz#0fc31da666f182fe14e119905fc9829b5b85a234" + integrity sha512-uAh96tBW1SsD34VhhDmWuEmqbpfYc/B3j++5MC/6b3Cb8Ow7NJsvKFhg0eoGu2xXX+o9RkahkTK6sUdd8E7g5w== dependencies: - execa "^4.1.0" - find-up "^4.1.0" - ignore "^5.3.0" + "@pkgr/core" "^0.2.7" + ignore "^7.0.5" mri "^1.2.0" - picocolors "^1.0.0" - picomatch "^3.0.1" - tslib "^2.6.2" + picocolors "^1.1.1" + picomatch "^4.0.2" + tinyexec "^0.3.2" + tslib "^2.8.1" process-nextick-args@~2.0.0: version "2.0.1" @@ -10557,7 +11307,7 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.22 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@~1.22.11: +resolve@~1.22.10, resolve@~1.22.11: version "1.22.11" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== @@ -11444,6 +12194,11 @@ tiny-jsonc@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-jsonc/-/tiny-jsonc-1.0.2.tgz#208df4c437684199cc724f31c2b91ee39c349678" integrity sha512-f5QDAfLq6zIVSyCZQZhhyl0QS6MvAyTxgz4X4x3+EoCktNWEYJ6PeoEA97fyb98njpBNNi88ybpD7m+BDFXaCw== +tinyexec@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2" + integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== + tinyglobby@^0.2.14, tinyglobby@^0.2.9: version "0.2.14" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d" @@ -11558,7 +12313,7 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.2: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.2, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==