@embroider/core
Advanced tools
Comparing version 3.4.9 to 3.4.10-unstable.0d42d71
{ | ||
"name": "@embroider/core", | ||
"version": "3.4.9", | ||
"version": "3.4.10-unstable.0d42d71", | ||
"private": false, | ||
@@ -19,2 +19,5 @@ "description": "A build system for EmberJS applications.", | ||
], | ||
"scripts": { | ||
"test": "jest" | ||
}, | ||
"dependencies": { | ||
@@ -24,2 +27,5 @@ "@babel/core": "^7.14.5", | ||
"@babel/traverse": "^7.14.5", | ||
"@embroider/macros": "1.16.2-unstable.0d42d71", | ||
"@embroider/reverse-exports": "0.1.1-unstable.0d42d71", | ||
"@embroider/shared-internals": "2.6.1-unstable.0d42d71", | ||
"assert-never": "^1.2.1", | ||
@@ -32,2 +38,3 @@ "babel-plugin-ember-template-compilation": "^2.1.1", | ||
"debug": "^4.3.2", | ||
"escape-string-regexp": "^4.0.0", | ||
"fast-sourcemap-concat": "^1.4.0", | ||
@@ -43,8 +50,9 @@ "filesize": "^10.0.7", | ||
"resolve-package-path": "^4.0.1", | ||
"resolve.exports": "^2.0.2", | ||
"typescript-memoize": "^1.0.1", | ||
"walk-sync": "^3.0.0", | ||
"@embroider/macros": "1.16.1", | ||
"@embroider/shared-internals": "2.6.0" | ||
"walk-sync": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"@embroider/sample-transforms": "workspace:*", | ||
"@embroider/test-support": "workspace:*", | ||
"@glimmer/syntax": "^0.84.2", | ||
@@ -56,4 +64,4 @@ "@glint/template": "^1.0.0", | ||
"@types/fs-extra": "^9.0.12", | ||
"@types/js-string-escape": "^1.0.0", | ||
"@types/jsdom": "^16.2.11", | ||
"@types/js-string-escape": "^1.0.0", | ||
"@types/lodash": "^4.14.170", | ||
@@ -65,12 +73,7 @@ "@types/node": "^15.12.2", | ||
"tmp": "^0.1.0", | ||
"typescript": "^5.1.6", | ||
"@embroider/sample-transforms": "0.0.0", | ||
"@embroider/test-support": "0.36.0" | ||
"typescript": "^5.4.5" | ||
}, | ||
"engines": { | ||
"node": "12.* || 14.* || >= 16" | ||
}, | ||
"scripts": { | ||
"test": "jest" | ||
} | ||
} | ||
} |
@@ -23,3 +23,3 @@ import type { Package, AddonPackage } from '@embroider/shared-internals'; | ||
}; | ||
constructor(engine: Engine, appFiles: Set<string>, fastbootFiles: Set<string>, resolvableExtensions: RegExp, podModulePrefix?: string); | ||
constructor(engine: Engine, appFiles: Set<string>, fastbootFiles: Set<string>, resolvableExtensions: RegExp, staticAppPathsPattern: RegExp | undefined, podModulePrefix?: string); | ||
private handleClassicRouteFile; | ||
@@ -31,7 +31,6 @@ private handlePodsRouteFile; | ||
package: Package; | ||
addons: Set<AddonPackage>; | ||
parent: Engine | undefined; | ||
sourcePath: string; | ||
addons: Map<AddonPackage, string>; | ||
isApp: boolean; | ||
modulePrefix: string; | ||
appRelativePath: string; | ||
} |
@@ -6,3 +6,3 @@ "use strict"; | ||
class AppFiles { | ||
constructor(engine, appFiles, fastbootFiles, resolvableExtensions, podModulePrefix) { | ||
constructor(engine, appFiles, fastbootFiles, resolvableExtensions, staticAppPathsPattern, podModulePrefix) { | ||
this.engine = engine; | ||
@@ -25,3 +25,3 @@ let tests = []; | ||
} | ||
for (let addon of engine.addons) { | ||
for (let addon of engine.addons.keys()) { | ||
let appJS = addon.meta['app-js']; | ||
@@ -84,3 +84,10 @@ if (appJS) { | ||
} | ||
otherAppFiles.push(relativePath); | ||
if (staticAppPathsPattern) { | ||
if (!staticAppPathsPattern.test(relativePath)) { | ||
otherAppFiles.push(relativePath); | ||
} | ||
} | ||
else { | ||
otherAppFiles.push(relativePath); | ||
} | ||
} | ||
@@ -87,0 +94,0 @@ this.tests = tests; |
export { Packager, PackagerConstructor, Variant, applyVariantToBabelConfig, getAppMeta, getPackagerCacheDir, } from './packager'; | ||
export { HTMLEntrypoint, BundleSummary } from './html-entrypoint'; | ||
export { default as Stage } from './stage'; | ||
export { Asset, EmberAsset, ImplicitAssetPaths } from './asset'; | ||
export { default as Options, optionsWithDefaults } from './options'; | ||
@@ -10,3 +9,3 @@ export { default as toBroccoliPlugin } from './to-broccoli-plugin'; | ||
export { todo, unsupported, warn, debug, expectWarning, throwOnWarnings } from './messages'; | ||
export { Resolver, Options as ResolverOptions, ModuleRequest, Resolution, ResolverFunction, SyncResolverFunction, } from './module-resolver'; | ||
export { Resolver, Options as ResolverOptions, ModuleRequest, Resolution } from './module-resolver'; | ||
export { ResolverLoader } from './resolver-loader'; | ||
@@ -13,0 +12,0 @@ export { virtualContent } from './virtual-content'; |
@@ -11,5 +11,2 @@ import type { Package } from '@embroider/shared-internals'; | ||
}; | ||
activeAddons: { | ||
[packageName: string]: string; | ||
}; | ||
resolvableExtensions: string[]; | ||
@@ -19,6 +16,9 @@ appRoot: string; | ||
modulePrefix: string; | ||
splitAtRoutes?: (RegExp | string)[]; | ||
podModulePrefix?: string; | ||
amdCompatibility: Required<UserOptions['amdCompatibility']>; | ||
autoRun: boolean; | ||
staticAppPaths: string[]; | ||
} | ||
interface EngineConfig { | ||
export interface EngineConfig { | ||
packageName: string; | ||
@@ -28,2 +28,3 @@ activeAddons: { | ||
root: string; | ||
canResolveFromFile: string; | ||
}[]; | ||
@@ -37,4 +38,5 @@ fastbootFiles: { | ||
root: string; | ||
isLazy: boolean; | ||
} | ||
export interface ModuleRequest { | ||
export interface ModuleRequest<Res extends Resolution = Resolution> { | ||
readonly specifier: string; | ||
@@ -44,2 +46,5 @@ readonly fromFile: string; | ||
readonly meta: Record<string, unknown> | undefined; | ||
readonly debugType: string; | ||
readonly isNotFound: boolean; | ||
readonly resolvedTo: Res | undefined; | ||
alias(newSpecifier: string): this; | ||
@@ -49,20 +54,24 @@ rehome(newFromFile: string): this; | ||
withMeta(meta: Record<string, any> | undefined): this; | ||
notFound(): this; | ||
defaultResolve(): Promise<Res>; | ||
resolveTo(resolution: Res): this; | ||
} | ||
export type Resolution<T = unknown, E = unknown> = { | ||
type: 'found'; | ||
filename: string; | ||
isVirtual: boolean; | ||
result: T; | ||
} | { | ||
type: 'ignored'; | ||
result: T; | ||
} | { | ||
type: 'not_found'; | ||
err: E; | ||
}; | ||
export type ResolverFunction<R extends ModuleRequest = ModuleRequest, Res extends Resolution = Resolution> = (request: R) => Promise<Res>; | ||
export type SyncResolverFunction<R extends ModuleRequest = ModuleRequest, Res extends Resolution = Resolution> = (request: R) => Res; | ||
export declare class Resolver { | ||
readonly options: Options; | ||
constructor(options: Options); | ||
beforeResolve<R extends ModuleRequest>(request: R): R; | ||
resolve<Req extends ModuleRequest, Res extends Resolution>(request: Req, defaultResolve: ResolverFunction<Req, Res>): Promise<Res>; | ||
resolveSync<Req extends ModuleRequest, Res extends Resolution>(request: Req, defaultResolve: SyncResolverFunction<Req, Res>): Res; | ||
private internalResolve; | ||
nodeResolve(specifier: string, fromFile: string): { | ||
private beforeResolve; | ||
resolve<ResolveResolution extends Resolution>(request: ModuleRequest<ResolveResolution>): Promise<ResolveResolution>; | ||
nodeResolve(specifier: string, fromFile: string): Promise<{ | ||
type: 'virtual'; | ||
@@ -77,3 +86,3 @@ filename: string; | ||
err: Error; | ||
}; | ||
}>; | ||
get packageCache(): RewrittenPackageCache; | ||
@@ -84,3 +93,9 @@ private logicalPackage; | ||
private handleImplicitModules; | ||
private handleEntrypoint; | ||
private handleTestEntrypoint; | ||
private handleRouteEntrypoint; | ||
private handleImplicitTestScripts; | ||
private handleTestSupportStyles; | ||
private handleGlobalsCompat; | ||
private handleVendorStyles; | ||
private resolveHelper; | ||
@@ -99,6 +114,8 @@ private resolveComponent; | ||
private handleRenaming; | ||
private handleVendor; | ||
private resolveWithinMovedPackage; | ||
private preHandleExternal; | ||
private locateActiveAddon; | ||
private external; | ||
fallbackResolve<R extends ModuleRequest>(request: R): R; | ||
private fallbackResolve; | ||
private getEntryFromMergeMap; | ||
@@ -111,2 +128,1 @@ private withResolvableExtensions; | ||
} | ||
export {}; |
@@ -18,3 +18,4 @@ "use strict"; | ||
const assert_never_1 = __importDefault(require("assert-never")); | ||
const resolve_1 = __importDefault(require("resolve")); | ||
const reverse_exports_1 = __importDefault(require("@embroider/reverse-exports")); | ||
const resolve_exports_1 = require("resolve.exports"); | ||
const virtual_content_1 = require("./virtual-content"); | ||
@@ -24,49 +25,45 @@ const typescript_memoize_1 = require("typescript-memoize"); | ||
const fs_1 = require("fs"); | ||
const node_resolve_1 = require("./node-resolve"); | ||
const virtual_route_entrypoint_1 = require("./virtual-route-entrypoint"); | ||
const debug = (0, debug_1.default)('embroider:resolver'); | ||
// Using a formatter makes this work lazy so nothing happens when we aren't | ||
// logging. It is unfortunate that formatters are a globally mutable config and | ||
// you can only use single character names, but oh well. | ||
debug_1.default.formatters.p = (s) => { | ||
let cwd = process.cwd(); | ||
if (s.startsWith(cwd)) { | ||
return s.slice(cwd.length + 1); | ||
} | ||
return s; | ||
}; | ||
function logTransition(reason, before, after = before) { | ||
if (after.isVirtual) { | ||
debug(`virtualized %s in %s because %s`, before.specifier, before.fromFile, reason); | ||
debug(`[%s:virtualized] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile); | ||
} | ||
else if (after.resolvedTo) { | ||
debug(`[%s:resolvedTo] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile); | ||
} | ||
else if (before.specifier !== after.specifier) { | ||
if (before.fromFile !== after.fromFile) { | ||
debug(`aliased and rehomed: %s to %s, from %s to %s because %s`, before.specifier, after.specifier, before.fromFile, after.fromFile, reason); | ||
debug(`[%s:aliased and rehomed] %s to %s\n because %s\n from %p\n to %p`, before.debugType, before.specifier, after.specifier, reason, before.fromFile, after.fromFile); | ||
} | ||
else { | ||
debug(`aliased: %s to %s in %s because`, before.specifier, after.specifier, before.fromFile, reason); | ||
debug(`[%s:aliased] %s to %s\n because %s`, before.debugType, before.specifier, after.specifier, reason); | ||
} | ||
} | ||
else if (before.fromFile !== after.fromFile) { | ||
debug(`rehomed: %s from %s to %s because`, before.specifier, before.fromFile, after.fromFile, reason); | ||
debug(`[%s:rehomed] %s, because %s\n from %p\n to %p`, before.debugType, before.specifier, reason, before.fromFile, after.fromFile); | ||
} | ||
else if (after.isNotFound) { | ||
debug(`[%s:not-found] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile); | ||
} | ||
else { | ||
debug(`unchanged: %s in %s because %s`, before.specifier, before.fromFile, reason); | ||
debug(`[%s:unchanged] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile); | ||
} | ||
return after; | ||
} | ||
function isTerminal(request) { | ||
return request.isVirtual || request.isNotFound || Boolean(request.resolvedTo); | ||
} | ||
const compatPattern = /#embroider_compat\/(?<type>[^\/]+)\/(?<rest>.*)/; | ||
class NodeModuleRequest { | ||
constructor(specifier, fromFile, isVirtual, meta) { | ||
this.specifier = specifier; | ||
this.fromFile = fromFile; | ||
this.isVirtual = isVirtual; | ||
this.meta = meta; | ||
} | ||
alias(specifier) { | ||
return new NodeModuleRequest(specifier, this.fromFile, false, this.meta); | ||
} | ||
rehome(fromFile) { | ||
if (this.fromFile === fromFile) { | ||
return this; | ||
} | ||
else { | ||
return new NodeModuleRequest(this.specifier, fromFile, false, this.meta); | ||
} | ||
} | ||
virtualize(filename) { | ||
return new NodeModuleRequest(filename, this.fromFile, true, this.meta); | ||
} | ||
withMeta(meta) { | ||
return new NodeModuleRequest(this.specifier, this.fromFile, this.isVirtual, meta); | ||
} | ||
} | ||
class Resolver { | ||
@@ -76,3 +73,3 @@ constructor(options) { | ||
} | ||
beforeResolve(request) { | ||
async beforeResolve(request) { | ||
if (request.specifier === '@embroider/macros') { | ||
@@ -85,6 +82,16 @@ // the macros package is always handled directly within babel (not | ||
} | ||
if (request.specifier === 'require') { | ||
return this.external('early require', request, request.specifier); | ||
} | ||
request = this.handleFastbootSwitch(request); | ||
request = this.handleGlobalsCompat(request); | ||
request = await this.handleGlobalsCompat(request); | ||
request = this.handleImplicitModules(request); | ||
request = this.handleImplicitTestScripts(request); | ||
request = this.handleVendorStyles(request); | ||
request = this.handleTestSupportStyles(request); | ||
request = this.handleEntrypoint(request); | ||
request = this.handleTestEntrypoint(request); | ||
request = this.handleRouteEntrypoint(request); | ||
request = this.handleRenaming(request); | ||
request = this.handleVendor(request); | ||
// we expect the specifier to be app relative at this point - must be after handleRenaming | ||
@@ -103,32 +110,11 @@ request = this.generateFastbootSwitch(request); | ||
// rules. | ||
// | ||
// Depending on the plugin architecture you're working in, it may be easier to | ||
// call beforeResolve and fallbackResolve directly, in which case matching the | ||
// details of the recursion to what this method does are your responsibility. | ||
async resolve(request, defaultResolve) { | ||
let gen = this.internalResolve(request, defaultResolve); | ||
let out = gen.next(); | ||
while (!out.done) { | ||
out = gen.next(await out.value); | ||
async resolve(request) { | ||
request = await this.beforeResolve(request); | ||
if (request.resolvedTo) { | ||
return request.resolvedTo; | ||
} | ||
return out.value; | ||
} | ||
// synchronous alternative to resolve() above. Because our own internals are | ||
// all synchronous, you can use this if your defaultResolve function is | ||
// synchronous. | ||
resolveSync(request, defaultResolve) { | ||
let gen = this.internalResolve(request, defaultResolve); | ||
let out = gen.next(); | ||
while (!out.done) { | ||
out = gen.next(out.value); | ||
} | ||
return out.value; | ||
} | ||
// Our core implementation is a generator so it can power both resolve() and | ||
// resolveSync() | ||
*internalResolve(request, defaultResolve) { | ||
request = this.beforeResolve(request); | ||
let resolution = yield defaultResolve(request); | ||
let resolution = await request.defaultResolve(); | ||
switch (resolution.type) { | ||
case 'found': | ||
case 'ignored': | ||
return resolution; | ||
@@ -140,3 +126,3 @@ case 'not_found': | ||
} | ||
let nextRequest = this.fallbackResolve(request); | ||
let nextRequest = await this.fallbackResolve(request); | ||
if (nextRequest === request) { | ||
@@ -146,12 +132,15 @@ // no additional fallback is available. | ||
} | ||
if (nextRequest.resolvedTo) { | ||
return nextRequest.resolvedTo; | ||
} | ||
if (nextRequest.fromFile === request.fromFile && nextRequest.specifier === request.specifier) { | ||
throw new Error('Bug Discovered! New request is not === original request but has the same fromFile and specifier. This will likely create a loop.'); | ||
} | ||
if (nextRequest.isVirtual) { | ||
// virtual requests are terminal, there is no more beforeResolve or | ||
// fallbackResolve around them. The defaultResolve is expected to know how | ||
// to implement them. | ||
return yield defaultResolve(nextRequest); | ||
if (nextRequest.isVirtual || nextRequest.isNotFound) { | ||
// virtual and NotFound requests are terminal, there is no more | ||
// beforeResolve or fallbackResolve around them. The defaultResolve is | ||
// expected to know how to implement them. | ||
return nextRequest.defaultResolve(); | ||
} | ||
return yield* this.internalResolve(nextRequest, defaultResolve); | ||
return this.resolve(nextRequest); | ||
} | ||
@@ -161,36 +150,4 @@ // Use standard NodeJS resolving, with our required compatibility rules on | ||
// defaultResolve already configured to be "do the normal node thing". | ||
nodeResolve(specifier, fromFile) { | ||
let resolution = this.resolveSync(new NodeModuleRequest(specifier, fromFile, false, undefined), request => { | ||
if (request.isVirtual) { | ||
return { | ||
type: 'found', | ||
result: { | ||
type: 'virtual', | ||
content: (0, virtual_content_1.virtualContent)(request.specifier, this), | ||
filename: request.specifier, | ||
}, | ||
}; | ||
} | ||
try { | ||
let filename = resolve_1.default.sync(request.specifier, { | ||
basedir: (0, path_1.dirname)(request.fromFile), | ||
extensions: this.options.resolvableExtensions, | ||
}); | ||
return { type: 'found', result: { type: 'real', filename } }; | ||
} | ||
catch (err) { | ||
if (err.code !== 'MODULE_NOT_FOUND') { | ||
throw err; | ||
} | ||
return { type: 'not_found', err }; | ||
} | ||
}); | ||
switch (resolution.type) { | ||
case 'not_found': | ||
return resolution; | ||
case 'found': | ||
return resolution.result; | ||
default: | ||
throw (0, assert_never_1.default)(resolution); | ||
} | ||
async nodeResolve(specifier, fromFile) { | ||
return (0, node_resolve_1.nodeResolve)(this, specifier, fromFile); | ||
} | ||
@@ -212,2 +169,5 @@ get packageCache() { | ||
generateFastbootSwitch(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
@@ -230,3 +190,5 @@ if (!pkg) { | ||
if (fastbootFile.shadowedFilename) { | ||
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {}); | ||
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), { | ||
configFile: false, | ||
}); | ||
let switchFile = (0, virtual_content_1.fastbootSwitch)(candidate, (0, path_1.resolve)(pkg.root, 'package.json'), names); | ||
@@ -250,2 +212,5 @@ if (switchFile === request.fromFile) { | ||
var _a; | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
let match = (0, virtual_content_1.decodeFastbootSwitch)(request.fromFile); | ||
@@ -289,3 +254,3 @@ if (!match) { | ||
if ((entry === null || entry === void 0 ? void 0 : entry.type) === 'both') { | ||
return logTransition('matched addon entry', request, request.alias(entry[section].localPath).rehome((0, path_1.resolve)(entry[section].packageRoot, 'package.json'))); | ||
return logTransition('matched addon entry', request, request.alias(entry[section].specifier).rehome(entry[section].fromFile)); | ||
} | ||
@@ -296,2 +261,5 @@ } | ||
handleImplicitModules(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
let im = (0, virtual_content_1.decodeImplicitModules)(request.specifier); | ||
@@ -314,3 +282,99 @@ if (!im) { | ||
} | ||
handleGlobalsCompat(request) { | ||
handleEntrypoint(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = ['@embroider/core/entrypoint', '/@embroider/core/entrypoint', './@embroider/core/entrypoint']; | ||
if (!candidates.some(c => request.specifier.startsWith(c + '/') || request.specifier === c)) { | ||
return request; | ||
} | ||
const result = /\.?\/?@embroider\/core\/entrypoint(?:\/(?<packageName>.*))?/.exec(request.specifier); | ||
if (!result) { | ||
// TODO make a better error | ||
throw new Error('entrypoint does not match pattern' + request.specifier); | ||
} | ||
const { packageName } = result.groups; | ||
const requestingPkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if (!(requestingPkg === null || requestingPkg === void 0 ? void 0 : requestingPkg.isV2Ember())) { | ||
throw new Error(`bug: found entrypoint import in non-ember package at ${request.fromFile}`); | ||
} | ||
let pkg; | ||
if (packageName) { | ||
pkg = this.packageCache.resolve(packageName, requestingPkg); | ||
} | ||
else { | ||
pkg = requestingPkg; | ||
} | ||
return logTransition('entrypoint', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-entrypoint.js'))); | ||
} | ||
handleTestEntrypoint(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = [ | ||
'@embroider/core/test-entrypoint', | ||
'/@embroider/core/test-entrypoint', | ||
'./@embroider/core/test-entrypoint', | ||
]; | ||
if (!candidates.some(c => request.specifier === c)) { | ||
return request; | ||
} | ||
const pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if (!(pkg === null || pkg === void 0 ? void 0 : pkg.isV2Ember()) || !pkg.isV2App()) { | ||
throw new Error(`bug: found test entrypoint import from somewhere other than the top-level app engine: ${request.fromFile}`); | ||
} | ||
return logTransition('test-entrypoint', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-test-entrypoint.js'))); | ||
} | ||
handleRouteEntrypoint(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
let routeName = (0, virtual_route_entrypoint_1.decodePublicRouteEntrypoint)(request.specifier); | ||
if (!routeName) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if (!(pkg === null || pkg === void 0 ? void 0 : pkg.isV2Ember())) { | ||
throw new Error(`bug: found entrypoint import in non-ember package at ${request.fromFile}`); | ||
} | ||
return logTransition('route entrypoint', request, request.virtualize((0, virtual_route_entrypoint_1.encodeRouteEntrypoint)(pkg.root, routeName))); | ||
} | ||
handleImplicitTestScripts(request) { | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = [ | ||
'@embroider/core/test-support.js', | ||
'/@embroider/core/test-support.js', | ||
'./@embroider/core/test-support.js', | ||
]; | ||
if (!candidates.includes(request.specifier)) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) { | ||
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/test-support.js. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`); | ||
} | ||
return logTransition('test-support', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-test-support.js'))); | ||
} | ||
handleTestSupportStyles(request) { | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = [ | ||
'@embroider/core/test-support.css', | ||
'/@embroider/core/test-support.css', | ||
'./@embroider/core/test-support.css', | ||
]; | ||
if (!candidates.includes(request.specifier)) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) { | ||
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/test-support.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`); | ||
} | ||
return logTransition('test-support-styles', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-test-support-styles.css'))); | ||
} | ||
async handleGlobalsCompat(request) { | ||
if (isTerminal(request)) { | ||
return request; | ||
} | ||
let match = compatPattern.exec(request.specifier); | ||
@@ -339,2 +403,14 @@ if (!match) { | ||
} | ||
handleVendorStyles(request) { | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = ['@embroider/core/vendor.css', '/@embroider/core/vendor.css', './@embroider/core/vendor.css']; | ||
if (!candidates.includes(request.specifier)) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if (!pkg || !this.options.engines.some(e => e.root === (pkg === null || pkg === void 0 ? void 0 : pkg.root))) { | ||
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app or Engine. The top-level Ember app is the only one that has support for @embroider/core/vendor.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`); | ||
} | ||
return logTransition('vendor-styles', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-vendor-styles.css'))); | ||
} | ||
resolveHelper(path, inEngine, request) { | ||
@@ -344,3 +420,3 @@ let target = this.parseGlobalPath(path, inEngine); | ||
} | ||
resolveComponent(path, inEngine, request) { | ||
async resolveComponent(path, inEngine, request) { | ||
let target = this.parseGlobalPath(path, inEngine); | ||
@@ -351,5 +427,8 @@ let hbsModule = null; | ||
for (let candidate of this.componentTemplateCandidates(target.packageName)) { | ||
let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from); | ||
if (resolution.type === 'real') { | ||
hbsModule = resolution.filename; | ||
let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`; | ||
let resolution = await this.resolve(request.alias(candidateSpecifier).rehome(target.from).withMeta({ | ||
runtimeFallback: false, | ||
})); | ||
if (resolution.type === 'found') { | ||
hbsModule = resolution; | ||
break; | ||
@@ -360,8 +439,11 @@ } | ||
for (let candidate of this.componentJSCandidates(target.packageName)) { | ||
let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from); | ||
let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`; | ||
let resolution = await this.resolve(request.alias(candidateSpecifier).rehome(target.from).withMeta({ | ||
runtimeFallback: false, | ||
})); | ||
// .hbs is a resolvable extension for us, so we need to exclude it here. | ||
// It matches as a priority lower than .js, so finding an .hbs means | ||
// there's definitely not a .js. | ||
if (resolution.type === 'real' && !resolution.filename.endsWith('.hbs')) { | ||
jsModule = resolution.filename; | ||
if (resolution.type === 'found' && !resolution.filename.endsWith('.hbs')) { | ||
jsModule = resolution; | ||
break; | ||
@@ -371,6 +453,6 @@ } | ||
if (hbsModule) { | ||
return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule, jsModule))); | ||
return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule.filename, jsModule === null || jsModule === void 0 ? void 0 : jsModule.filename))); | ||
} | ||
else if (jsModule) { | ||
return logTransition(`resolveComponent found only JS`, request, request.alias(jsModule).rehome(target.from)); | ||
return logTransition(`resolving to resolveComponent found only JS`, request, request.resolveTo(jsModule)); | ||
} | ||
@@ -381,3 +463,3 @@ else { | ||
} | ||
resolveHelperOrComponent(path, inEngine, request) { | ||
async resolveHelperOrComponent(path, inEngine, request) { | ||
// resolveHelper just rewrites our request to one that should target the | ||
@@ -387,5 +469,7 @@ // component, so here to resolve the ambiguity we need to actually resolve | ||
let helperCandidate = this.resolveHelper(path, inEngine, request); | ||
let helperMatch = this.nodeResolve(helperCandidate.specifier, helperCandidate.fromFile); | ||
if (helperMatch.type === 'real') { | ||
return logTransition('ambiguous case matched a helper', request, helperCandidate); | ||
let helperMatch = await this.resolve(request.alias(helperCandidate.specifier).rehome(helperCandidate.fromFile).withMeta({ | ||
runtimeFallback: false, | ||
})); | ||
if (helperMatch.type === 'found') { | ||
return logTransition('resolve to ambiguous case matched a helper', request, request.resolveTo(helperMatch)); | ||
} | ||
@@ -395,3 +479,3 @@ // unlike resolveHelper, resolveComponent already does pre-resolution in | ||
// colocation.≥ | ||
let componentMatch = this.resolveComponent(path, inEngine, request); | ||
let componentMatch = await this.resolveComponent(path, inEngine, request); | ||
if (componentMatch !== request) { | ||
@@ -421,2 +505,3 @@ return logTransition('ambiguous case matched a cmoponent', request, componentMatch); | ||
yield { prefix: '/components/', suffix: '' }; | ||
yield { prefix: '/components/', suffix: '/index' }; | ||
yield { prefix: '/components/', suffix: '/component' }; | ||
@@ -440,6 +525,6 @@ let pods = this.podPrefix(inPackageName); | ||
if (parts.length > 1 && parts[0].length > 0) { | ||
return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') }; | ||
return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'package.json') }; | ||
} | ||
else { | ||
return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') }; | ||
return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'package.json') }; | ||
} | ||
@@ -476,4 +561,4 @@ } | ||
'app-js': { | ||
localPath: inAddonName, | ||
packageRoot: addon.root, | ||
specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName), | ||
fromFile: addonConfig.canResolveFromFile, | ||
fromPackageName: addon.name, | ||
@@ -491,4 +576,4 @@ }, | ||
'app-js': { | ||
localPath: inAddonName, | ||
packageRoot: addon.root, | ||
specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName), | ||
fromFile: addonConfig.canResolveFromFile, | ||
fromPackageName: addon.name, | ||
@@ -517,4 +602,4 @@ }, | ||
'fastboot-js': { | ||
localPath: inAddonName, | ||
packageRoot: addon.root, | ||
specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName), | ||
fromFile: addonConfig.canResolveFromFile, | ||
fromPackageName: addon.name, | ||
@@ -532,4 +617,4 @@ }, | ||
'fastboot-js': { | ||
localPath: inAddonName, | ||
packageRoot: addon.root, | ||
specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName), | ||
fromFile: addonConfig.canResolveFromFile, | ||
fromPackageName: addon.name, | ||
@@ -556,3 +641,3 @@ }, | ||
handleRewrittenPackages(request) { | ||
if (request.isVirtual) { | ||
if (isTerminal(request)) { | ||
return request; | ||
@@ -576,6 +661,2 @@ } | ||
catch (err) { | ||
// this is not the place to report resolution failures. If the thing | ||
// doesn't resolve, we're just not interested in redirecting it for | ||
// backward-compat, that's all. The rest of the system will take care of | ||
// reporting a failure to resolve (or handling it a different way) | ||
if (err.code !== 'MODULE_NOT_FOUND') { | ||
@@ -596,5 +677,17 @@ throw err; | ||
else if (originalRequestingPkg !== requestingPkg) { | ||
// in this case, the requesting package is moved but its destination is | ||
// not, so we need to rehome the request back to the original location. | ||
return logTransition('outbound request from moved package', request, request.withMeta({ wasMovedTo: request.fromFile }).rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json'))); | ||
if (targetPkg) { | ||
// in this case, the requesting package is moved but its destination is | ||
// not, so we need to rehome the request back to the original location. | ||
return logTransition('outbound request from moved package', request, request | ||
// setting meta here because if this fails, we want the fallback | ||
// logic to revert our rehome and continue from the *moved* package. | ||
.withMeta({ originalFromFile: request.fromFile }) | ||
.rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json'))); | ||
} | ||
else { | ||
// requesting package was moved and we failed to find its target. We | ||
// can't let that accidentally succeed in the defaultResolve because we | ||
// could escape the moved package system. | ||
return logTransition('missing outbound request from moved package', request, request.notFound()); | ||
} | ||
} | ||
@@ -604,3 +697,3 @@ return request; | ||
handleRenaming(request) { | ||
if (request.isVirtual) { | ||
if (isTerminal(request)) { | ||
return request; | ||
@@ -638,11 +731,45 @@ } | ||
} | ||
if (pkg.meta['auto-upgraded'] && pkg.name === packageName) { | ||
// we found a self-import, resolve it for them. Only auto-upgraded | ||
// packages get this help, v2 packages are natively supposed to make their | ||
// own modules resolvable, and we want to push them all to do that | ||
// correctly. | ||
return logTransition(`v1 self-import`, request, request.alias(request.specifier.replace(pkg.name, '.')).rehome((0, path_1.resolve)(pkg.root, 'package.json'))); | ||
if (pkg.name === packageName) { | ||
// we found a self-import | ||
if (pkg.meta['auto-upgraded']) { | ||
// auto-upgraded packages always get automatically adjusted. They never | ||
// supported fancy package.json exports features so this direct mapping | ||
// to the root is always right. | ||
// "my-package/foo" -> "./foo" | ||
// "my-package" -> "./" (this can't be just "." because node's require.resolve doesn't reliable support that) | ||
let selfImportPath = request.specifier === pkg.name ? './' : request.specifier.replace(pkg.name, '.'); | ||
return logTransition(`v1 self-import`, request, request.alias(selfImportPath).rehome((0, path_1.resolve)(pkg.root, 'package.json'))); | ||
} | ||
else { | ||
// v2 packages are supposed to use package.json `exports` to enable | ||
// self-imports, but not all build tools actually follow the spec. This | ||
// is a workaround for badly behaved packagers. | ||
// | ||
// Known upstream bugs this works around: | ||
// - https://github.com/vitejs/vite/issues/9731 | ||
if (pkg.packageJSON.exports) { | ||
let found = (0, resolve_exports_1.exports)(pkg.packageJSON, request.specifier, { | ||
browser: true, | ||
conditions: ['default', 'imports'], | ||
}); | ||
if (found === null || found === void 0 ? void 0 : found[0]) { | ||
return logTransition(`v2 self-import with package.json exports`, request, request.alias(found === null || found === void 0 ? void 0 : found[0]).rehome((0, path_1.resolve)(pkg.root, 'package.json'))); | ||
} | ||
} | ||
} | ||
} | ||
return request; | ||
} | ||
handleVendor(request) { | ||
//TODO move the extra forwardslash handling out into the vite plugin | ||
const candidates = ['@embroider/core/vendor.js', '/@embroider/core/vendor.js', './@embroider/core/vendor.js']; | ||
if (!candidates.includes(request.specifier)) { | ||
return request; | ||
} | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) { | ||
throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/vendor.js. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`); | ||
} | ||
return logTransition('vendor', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-vendor.js'))); | ||
} | ||
resolveWithinMovedPackage(request, pkg) { | ||
@@ -653,2 +780,3 @@ let levels = ['..']; | ||
} | ||
let originalFromFile = request.fromFile; | ||
let newRequest = request.rehome((0, path_1.resolve)(pkg.root, ...levels, 'moved-package-target.js')); | ||
@@ -658,8 +786,8 @@ if (newRequest === request) { | ||
} | ||
return newRequest.withMeta({ | ||
resolvedWithinPackage: pkg.root, | ||
}); | ||
// setting meta because if this fails, we want the fallback to pick up back | ||
// in the original requesting package. | ||
return newRequest.withMeta({ originalFromFile }); | ||
} | ||
preHandleExternal(request) { | ||
if (request.isVirtual) { | ||
if (isTerminal(request)) { | ||
return request; | ||
@@ -697,3 +825,11 @@ } | ||
if (logicalLocation) { | ||
return logTransition('beforeResolve: relative import in app-js', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName))); | ||
return logTransition('beforeResolve: relative import in app-js', request, request | ||
.alias('./' + path_1.posix.join((0, path_1.dirname)(logicalLocation.inAppName), request.specifier)) | ||
// it's important that we're rehoming this to the root of the engine | ||
// (which we know really exists), and not to a subdir like | ||
// logicalLocation.inAppName (which might not physically exist), | ||
// because some environments (including node's require.resolve) will | ||
// refuse to do resolution from a notional path that doesn't | ||
// physically exist. | ||
.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json'))); | ||
} | ||
@@ -713,7 +849,7 @@ return request; | ||
// emberVirtualPeerDeps, like "@glimmer/component" etc. | ||
if (!this.options.activeAddons[packageName]) { | ||
throw new Error(`${pkg.name} is trying to import the app's ${packageName} package, but it seems to be missing`); | ||
let addon = this.locateActiveAddon(packageName); | ||
if (!addon) { | ||
throw new Error(`${pkg.name} is trying to import the emberVirtualPeerDep "${packageName}", but it seems to be missing`); | ||
} | ||
let newHome = (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json'); | ||
return logTransition(`emberVirtualPeerDeps in v2 addon`, request, request.rehome(newHome)); | ||
return logTransition(`emberVirtualPeerDeps`, request, request.rehome(addon.canResolveFromFile)); | ||
} | ||
@@ -749,2 +885,18 @@ // if this file is part of an addon's app-js, it's really the logical | ||
} | ||
locateActiveAddon(packageName) { | ||
if (packageName === this.options.modulePrefix) { | ||
// the app itself is something that addon's can classically resolve if they know it's name. | ||
return { | ||
root: this.options.appRoot, | ||
canResolveFromFile: (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json'), | ||
}; | ||
} | ||
for (let engine of this.options.engines) { | ||
for (let addon of engine.activeAddons) { | ||
if (addon.name === packageName) { | ||
return addon; | ||
} | ||
} | ||
} | ||
} | ||
external(label, request, specifier) { | ||
@@ -782,4 +934,7 @@ if (this.options.amdCompatibility === 'cjs') { | ||
} | ||
fallbackResolve(request) { | ||
async fallbackResolve(request) { | ||
var _a, _b, _c; | ||
if (request.isVirtual) { | ||
throw new Error('Build tool bug detected! Fallback resolve should never see a virtual request. It is expected that the defaultResolve for your bundler has already resolved this request'); | ||
} | ||
if (request.specifier === '@embroider/macros') { | ||
@@ -792,4 +947,3 @@ // the macros package is always handled directly within babel (not | ||
} | ||
let { specifier, fromFile } = request; | ||
if (compatPattern.test(specifier)) { | ||
if (compatPattern.test(request.specifier)) { | ||
// Some kinds of compat requests get rewritten into other things | ||
@@ -810,22 +964,16 @@ // deterministically. For example, "#embroider_compat/helpers/whatever" | ||
} | ||
if (fromFile.endsWith('moved-package-target.js')) { | ||
if (!((_a = request.meta) === null || _a === void 0 ? void 0 : _a.resolvedWithinPackage)) { | ||
throw new Error(`bug: embroider resolver's meta is not propagating`); | ||
} | ||
fromFile = (0, path_1.resolve)((_b = request.meta) === null || _b === void 0 ? void 0 : _b.resolvedWithinPackage, 'package.json'); | ||
} | ||
let pkg = this.packageCache.ownerOfFile(fromFile); | ||
let pkg = this.packageCache.ownerOfFile(request.fromFile); | ||
if (!pkg) { | ||
return logTransition('no identifiable owningPackage', request); | ||
} | ||
// if we rehomed this request to its un-rewritten location in order to try | ||
// to do the defaultResolve from there, now we refer back to the rewritten | ||
// location because that's what we want to use when asking things like | ||
// isV2Ember() | ||
// meta.originalFromFile gets set when we want to try to rehome a request | ||
// but then come back to the original location here in the fallback when the | ||
// rehomed request fails | ||
let movedPkg = this.packageCache.maybeMoved(pkg); | ||
if (movedPkg !== pkg) { | ||
if (!((_c = request.meta) === null || _c === void 0 ? void 0 : _c.wasMovedTo)) { | ||
let originalFromFile = (_a = request.meta) === null || _a === void 0 ? void 0 : _a.originalFromFile; | ||
if (typeof originalFromFile !== 'string') { | ||
throw new Error(`bug: embroider resolver's meta is not propagating`); | ||
} | ||
fromFile = request.meta.wasMovedTo; | ||
request = request.rehome(originalFromFile); | ||
pkg = movedPkg; | ||
@@ -836,3 +984,3 @@ } | ||
} | ||
let packageName = (0, shared_internals_1.packageName)(specifier); | ||
let packageName = (0, shared_internals_1.packageName)(request.specifier); | ||
if (!packageName) { | ||
@@ -844,3 +992,3 @@ // this is a relative import | ||
// means we may need to satisfy the request via app tree merging. | ||
let appJSMatch = this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier))); | ||
let appJSMatch = await this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(request.fromFile), request.specifier))); | ||
if (appJSMatch) { | ||
@@ -859,9 +1007,12 @@ return logTransition('fallbackResolve: relative appJsMatch', request, appJSMatch); | ||
// auto-upgraded packages can fall back to the set of known active addons | ||
if (pkg.meta['auto-upgraded'] && this.options.activeAddons[packageName]) { | ||
const rehomed = this.resolveWithinMovedPackage(request, this.packageCache.get(this.options.activeAddons[packageName])); | ||
if (rehomed !== request) { | ||
return logTransition(`activeAddons`, request, rehomed); | ||
if (pkg.meta['auto-upgraded']) { | ||
let addon = this.locateActiveAddon(packageName); | ||
if (addon) { | ||
const rehomed = request.rehome(addon.canResolveFromFile); | ||
if (rehomed !== request) { | ||
return logTransition(`activeAddons`, request, rehomed); | ||
} | ||
} | ||
} | ||
let logicalLocation = this.reverseSearchAppTree(pkg, fromFile); | ||
let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile); | ||
if (logicalLocation) { | ||
@@ -872,7 +1023,13 @@ // the requesting file is in an addon's appTree. We didn't succeed in | ||
// app. | ||
return logTransition('fallbackResolve: retry from logical home of app-js file', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName))); | ||
return logTransition('fallbackResolve: retry from logical home of app-js file', request, | ||
// it might look more precise to rehome into logicalLocation.inAppName | ||
// rather than package.json. But that logical location may not actually | ||
// exist, and some systems (including node's require.resolve) will be | ||
// mad about trying to resolve from notional paths that don't really | ||
// exist. | ||
request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json'))); | ||
} | ||
let targetingEngine = this.engineConfig(packageName); | ||
if (targetingEngine) { | ||
let appJSMatch = this.searchAppTree(request, targetingEngine, specifier.replace(packageName, '.')); | ||
let appJSMatch = await this.searchAppTree(request, targetingEngine, request.specifier.replace(packageName, '.')); | ||
if (appJSMatch) { | ||
@@ -882,3 +1039,3 @@ return logTransition('fallbackResolve: non-relative appJsMatch', request, appJSMatch); | ||
} | ||
if (pkg.meta['auto-upgraded']) { | ||
if (pkg.meta['auto-upgraded'] && ((_c = (_b = request.meta) === null || _b === void 0 ? void 0 : _b.runtimeFallback) !== null && _c !== void 0 ? _c : true)) { | ||
// auto-upgraded packages can fall back to attempting to find dependencies at | ||
@@ -888,3 +1045,3 @@ // runtime. Native v2 packages can only get this behavior in the | ||
// externals. | ||
return this.external('v1 catch-all fallback', request, specifier); | ||
return this.external('v1 catch-all fallback', request, request.specifier); | ||
} | ||
@@ -896,3 +1053,3 @@ else { | ||
if (shared_internals_1.emberVirtualPackages.has(packageName)) { | ||
return this.external('emberVirtualPackages', request, specifier); | ||
return this.external('emberVirtualPackages', request, request.specifier); | ||
} | ||
@@ -924,3 +1081,3 @@ } | ||
} | ||
searchAppTree(request, engine, inEngineSpecifier) { | ||
async searchAppTree(request, engine, inEngineSpecifier) { | ||
let matched = this.getEntryFromMergeMap(inEngineSpecifier, engine.root); | ||
@@ -931,15 +1088,13 @@ switch (matched === null || matched === void 0 ? void 0 : matched.entry.type) { | ||
case 'app-only': | ||
return request | ||
.alias(matched.entry['app-js'].localPath) | ||
.rehome((0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json')); | ||
return request.alias(matched.entry['app-js'].specifier).rehome(matched.entry['app-js'].fromFile); | ||
case 'fastboot-only': | ||
return request | ||
.alias(matched.entry['fastboot-js'].localPath) | ||
.rehome((0, path_1.resolve)(matched.entry['fastboot-js'].packageRoot, 'package.json')); | ||
return request.alias(matched.entry['fastboot-js'].specifier).rehome(matched.entry['fastboot-js'].fromFile); | ||
case 'both': | ||
let foundAppJS = this.nodeResolve(matched.entry['app-js'].localPath, (0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json')); | ||
if (foundAppJS.type !== 'real') { | ||
let foundAppJS = await this.resolve(request.alias(matched.entry['app-js'].specifier).rehome(matched.entry['app-js'].fromFile).withMeta({ | ||
runtimeFallback: false, | ||
})); | ||
if (foundAppJS.type !== 'found') { | ||
throw new Error(`${matched.entry['app-js'].fromPackageName} declared ${inEngineSpecifier} in packageJSON.ember-addon.app-js, but that module does not exist`); | ||
} | ||
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), {}); | ||
let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), { configFile: false }); | ||
return request.virtualize((0, virtual_content_1.fastbootSwitch)(matched.matched, (0, path_1.resolve)(engine.root, 'package.json'), names)); | ||
@@ -946,0 +1101,0 @@ } |
import type { Resolver } from '.'; | ||
export declare function virtualContent(filename: string, resolver: Resolver): string; | ||
export interface VirtualContentResult { | ||
src: string; | ||
watches: string[]; | ||
} | ||
export declare function virtualContent(filename: string, resolver: Resolver): VirtualContentResult; | ||
export declare function virtualExternalESModule(specifier: string, exports: string[] | undefined): string; | ||
export declare function virtualExternalCJSModule(specifier: string): string; | ||
export declare function virtualPairComponent(hbsModule: string, jsModule: string | null): string; | ||
export declare function virtualPairComponent(hbsModule: string, jsModule: string | undefined): string; | ||
export declare function fastbootSwitch(specifier: string, fromFile: string, names: Set<string>): string; | ||
@@ -7,0 +11,0 @@ export declare function decodeFastbootSwitch(filename: string): { |
@@ -7,2 +7,9 @@ "use strict"; | ||
const js_handlebars_1 = require("./js-handlebars"); | ||
const virtual_test_support_1 = require("./virtual-test-support"); | ||
const virtual_test_support_styles_1 = require("./virtual-test-support-styles"); | ||
const virtual_vendor_1 = require("./virtual-vendor"); | ||
const virtual_vendor_styles_1 = require("./virtual-vendor-styles"); | ||
const virtual_entrypoint_1 = require("./virtual-entrypoint"); | ||
const virtual_test_entrypoint_1 = require("./virtual-test-entrypoint"); | ||
const virtual_route_entrypoint_1 = require("./virtual-route-entrypoint"); | ||
const externalESPrefix = '/@embroider/ext-es/'; | ||
@@ -19,2 +26,14 @@ const externalCJSPrefix = '/@embroider/ext-cjs/'; | ||
} | ||
let entrypoint = (0, virtual_entrypoint_1.decodeEntrypoint)(filename); | ||
if (entrypoint) { | ||
return (0, virtual_entrypoint_1.renderEntrypoint)(resolver, entrypoint); | ||
} | ||
let testEntrypoint = (0, virtual_test_entrypoint_1.decodeTestEntrypoint)(filename); | ||
if (testEntrypoint) { | ||
return (0, virtual_test_entrypoint_1.renderTestEntrypoint)(resolver, testEntrypoint); | ||
} | ||
let routeEntrypoint = (0, virtual_route_entrypoint_1.decodeRouteEntrypoint)(filename); | ||
if (routeEntrypoint) { | ||
return (0, virtual_route_entrypoint_1.renderRouteEntrypoint)(resolver, routeEntrypoint); | ||
} | ||
let extern = decodeVirtualExternalESModule(filename); | ||
@@ -30,3 +49,3 @@ if (extern) { | ||
if (fb) { | ||
return fastbootSwitchTemplate(fb); | ||
return renderFastbootSwitchTemplate(fb); | ||
} | ||
@@ -37,2 +56,18 @@ let im = decodeImplicitModules(filename); | ||
} | ||
let isVendor = (0, virtual_vendor_1.decodeVirtualVendor)(filename); | ||
if (isVendor) { | ||
return (0, virtual_vendor_1.renderVendor)(filename, resolver); | ||
} | ||
let isImplicitTestScripts = (0, virtual_test_support_1.decodeImplicitTestScripts)(filename); | ||
if (isImplicitTestScripts) { | ||
return (0, virtual_test_support_1.renderImplicitTestScripts)(filename, resolver); | ||
} | ||
let isVendorStyles = (0, virtual_vendor_styles_1.decodeVirtualVendorStyles)(filename); | ||
if (isVendorStyles) { | ||
return (0, virtual_vendor_styles_1.renderVendorStyles)(filename, resolver); | ||
} | ||
let isTestSupportStyles = (0, virtual_test_support_styles_1.decodeTestSupportStyles)(filename); | ||
if (isTestSupportStyles) { | ||
return (0, virtual_test_support_styles_1.renderTestSupportStyles)(filename, resolver); | ||
} | ||
throw new Error(`not an @embroider/core virtual file: ${filename}`); | ||
@@ -58,10 +93,19 @@ } | ||
`); | ||
function renderESExternalShim({ moduleName, exports }) { | ||
return externalESShim({ | ||
moduleName, | ||
default: exports.includes('default'), | ||
names: exports.filter(n => n !== 'default'), | ||
}); | ||
function renderESExternalShim({ moduleName, exports, }) { | ||
return { | ||
src: externalESShim({ | ||
moduleName, | ||
default: exports.includes('default'), | ||
names: exports.filter(n => n !== 'default'), | ||
}), | ||
watches: [], | ||
}; | ||
} | ||
const pairedComponentShim = (0, js_handlebars_1.compile)(` | ||
function pairedComponentShim(params) { | ||
return { | ||
src: pairedComponentShimTemplate(params), | ||
watches: [], | ||
}; | ||
} | ||
const pairedComponentShimTemplate = (0, js_handlebars_1.compile)(` | ||
import { setComponentTemplate } from "@ember/component"; | ||
@@ -79,3 +123,3 @@ import template from "{{{js-string-escape relativeHBSModule}}}"; | ||
if (exports) { | ||
return externalESPrefix + specifier + `?exports=${exports.join(',')}`; | ||
return externalESPrefix + specifier + `/exports=${exports.join(',')}`; | ||
} | ||
@@ -94,8 +138,8 @@ else { | ||
let exports = []; | ||
let url = new URL(filename.slice(externalESPrefix.length), 'http://example.com'); | ||
let nameString = url.searchParams.get('exports'); | ||
let components = filename.split('/exports='); | ||
let nameString = components[1]; | ||
if (nameString) { | ||
exports = nameString.split(','); | ||
} | ||
let moduleName = url.pathname.slice(1); | ||
let moduleName = components[0].slice(externalESPrefix.length); | ||
return { moduleName, exports }; | ||
@@ -166,2 +210,8 @@ } | ||
exports.decodeFastbootSwitch = decodeFastbootSwitch; | ||
function renderFastbootSwitchTemplate(params) { | ||
return { | ||
src: fastbootSwitchTemplate(params), | ||
watches: [], | ||
}; | ||
} | ||
const fastbootSwitchTemplate = (0, js_handlebars_1.compile)(` | ||
@@ -203,4 +253,4 @@ import { macroCondition, getGlobalConfig, importSync } from '@embroider/macros'; | ||
} | ||
let lazyModules = []; | ||
let eagerModules = []; | ||
let ownModules = []; | ||
let dependencyModules = []; | ||
let deps = pkg.dependencies.sort(orderAddons); | ||
@@ -238,3 +288,3 @@ for (let dep of deps) { | ||
runtime = runtime.split(path_1.sep).join('/'); | ||
lazyModules.push({ | ||
ownModules.push({ | ||
runtime, | ||
@@ -248,16 +298,28 @@ buildtime: path_1.posix.join(packageName, name), | ||
if (!dep.isEngine()) { | ||
eagerModules.push(path_1.posix.join(dep.name, `-embroider-${type}.js`)); | ||
dependencyModules.push(path_1.posix.join(dep.name, `-embroider-${type}.js`)); | ||
} | ||
} | ||
return implicitModulesTemplate({ lazyModules, eagerModules }); | ||
return { src: implicitModulesTemplate({ ownModules, dependencyModules }), watches: [] }; | ||
} | ||
const implicitModulesTemplate = (0, js_handlebars_1.compile)(` | ||
import { importSync as i } from '@embroider/macros'; | ||
let d = window.define; | ||
{{#each lazyModules as |module|}} | ||
d("{{js-string-escape module.runtime}}", function(){ return i("{{js-string-escape module.buildtime}}");}); | ||
{{#each dependencyModules as |module index|}} | ||
import dep{{index}} from "{{js-string-escape module}}"; | ||
{{/each}} | ||
{{#each eagerModules as |module|}} | ||
import "{{js-string-escape module}}"; | ||
{{#each ownModules as |module index|}} | ||
import * as own{{index}} from "{{js-string-escape module.buildtime}}"; | ||
{{/each}} | ||
export default Object.assign({}, | ||
{{#each dependencyModules as |module index|}} | ||
dep{{index}}, | ||
{{/each}} | ||
{ | ||
{{#each ownModules as |module index|}} | ||
"{{js-string-escape module.runtime}}": own{{index}}, | ||
{{/each}} | ||
} | ||
); | ||
`); | ||
@@ -288,24 +350,39 @@ // meta['renamed-modules'] has mapping from classic filename to real filename. | ||
} | ||
const renderCJSExternalShim = (0, js_handlebars_1.compile)(` | ||
{{#if (eq moduleName "require")}} | ||
const m = window.requirejs; | ||
{{else}} | ||
const m = window.require("{{{js-string-escape moduleName}}}"); | ||
{{/if}} | ||
{{!- | ||
There are plenty of hand-written AMD defines floating around | ||
that lack this, and they will break when other build systems | ||
encounter them. | ||
function renderCJSExternalShim(params) { | ||
return { | ||
src: renderCJSExternalShimTemplate(params), | ||
watches: [], | ||
}; | ||
} | ||
const renderCJSExternalShimTemplate = (0, js_handlebars_1.compile)(` | ||
module.exports = new Proxy({}, { | ||
get(target, prop) { | ||
As far as I can tell, Ember's loader was already treating this | ||
case as a module, so in theory we aren't breaking anything by | ||
marking it as such when other packagers come looking. | ||
{{!- our proxy always presents as ES module so that we can intercept "get('default')" -}} | ||
if (prop === '__esModule') { | ||
return true; | ||
} | ||
todo: get review on this part. | ||
-}} | ||
if (m.default && !m.__esModule) { | ||
m.__esModule = true; | ||
} | ||
module.exports = m; | ||
{{#if (eq moduleName "require")}} | ||
const m = window.requirejs; | ||
{{else}} | ||
const m = window.require("{{{js-string-escape moduleName}}}"); | ||
{{/if}} | ||
{{!- | ||
There are plenty of hand-written AMD defines floating around | ||
that lack an __esModule declaration. | ||
As far as I can tell, Ember's loader was already treating the Boolean(m.default)===true | ||
case as a module, so in theory we aren't breaking anything by | ||
treating it as such when other packagers come looking. | ||
-}} | ||
if (prop === 'default' && !m.__esModule && !m.default) { | ||
return m; | ||
} | ||
return m[prop]; | ||
} | ||
}); | ||
`); | ||
//# sourceMappingURL=virtual-content.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
478823
82
4222
27
2
17
+ Addedescape-string-regexp@^4.0.0
+ Addedresolve.exports@^2.0.2
+ Added@embroider/macros@1.16.2-unstable.0d42d71(transitive)
+ Added@embroider/reverse-exports@0.1.1-unstable.0d42d71(transitive)
+ Added@embroider/shared-internals@2.6.1-unstable.0d42d71(transitive)
+ Addedescape-string-regexp@4.0.0(transitive)
+ Addedresolve.exports@2.0.3(transitive)
- Removed@embroider/macros@1.16.1(transitive)
- Removed@embroider/shared-internals@2.6.0(transitive)