diff --git a/packages-tooling/rollup-utils.mjs b/packages-tooling/rollup-utils.mjs index 1a35eee299..7956c3ba63 100644 --- a/packages-tooling/rollup-utils.mjs +++ b/packages-tooling/rollup-utils.mjs @@ -123,7 +123,8 @@ export function getRollupConfig(pkg, configure = identity, configureTerser, post input: inputFile, external: Object.keys(pkg.dependencies ?? {}) .concat(Object.keys(pkg.devDependencies ?? {})) - .concat('os', 'path', 'fs', 'http', 'https', 'http2', 'url', 'stream'), + .concat('os', 'path', 'fs', 'http', 'https', 'http2', 'url', 'stream') + .concat('node:module', 'node:path'), output: [ { file: esmDist, diff --git a/packages-tooling/vite-plugin/src/index.ts b/packages-tooling/vite-plugin/src/index.ts index da618a1664..c4798593ba 100644 --- a/packages-tooling/vite-plugin/src/index.ts +++ b/packages-tooling/vite-plugin/src/index.ts @@ -2,6 +2,9 @@ import { IOptionalPreprocessOptions, preprocess } from '@aurelia/plugin-conventi import { createFilter, FilterPattern } from '@rollup/pluginutils'; import { resolve, dirname } from 'path'; import { promises } from 'fs'; +import { createRequire } from 'module'; + +const require = createRequire(import.meta.url); export default function au(options: { include?: FilterPattern; @@ -25,7 +28,7 @@ export default function au(options: { const devPlugin: import('vite').Plugin = { name: 'aurelia:dev-alias', config(config) { - const isDev = useDev || (!useDev && config.mode !== 'production'); + const isDev = useDev === true || (useDev == null && config.mode !== 'production'); if (!isDev) { return; } diff --git a/packages-tooling/vite-plugin/tsconfig.json b/packages-tooling/vite-plugin/tsconfig.json index fabf80f7d3..3f5d370d38 100644 --- a/packages-tooling/vite-plugin/tsconfig.json +++ b/packages-tooling/vite-plugin/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig-build.json", "compilerOptions": { + "module": "esnext", "rootDir": "src", "declarationDir": "dist/types", "outDir": "dist/cjs", diff --git a/packages/__tests__/src/1-kernel/di.invoke.spec.ts b/packages/__tests__/src/1-kernel/di.invoke.spec.ts index e0a1538e23..2d092158cc 100644 --- a/packages/__tests__/src/1-kernel/di.invoke.spec.ts +++ b/packages/__tests__/src/1-kernel/di.invoke.spec.ts @@ -125,6 +125,10 @@ describe('1-kernel/di.invoke.spec.ts', function () { assert.strictEqual(v1, 2); }); + it('throws when invoking intrinsic types', function () { + assert.throws(() => container.invoke(String)); + }); + describe('inheritance', function () { it('works with a list of keys', function () { let i = 0; diff --git a/packages/kernel/src/di.container.ts b/packages/kernel/src/di.container.ts index 9f55a9be55..7d8ba5581d 100644 --- a/packages/kernel/src/di.container.ts +++ b/packages/kernel/src/di.container.ts @@ -30,7 +30,7 @@ import { type IAllResolver, type IOptionalResolver, } from './di'; -import { ErrorNames, createMappedError } from './errors'; +import { ErrorNames, createMappedError, logError } from './errors'; const InstrinsicTypeNames = new Set('Array ArrayBuffer Boolean DataView Date Error EvalError Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Number Object Promise RangeError ReferenceError RegExp Set SharedArrayBuffer String SyntaxError TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array URIError WeakMap WeakSet'.split(' ')); // const factoryKey = 'di:factory'; @@ -365,12 +365,35 @@ export class Container implements IContainer { } public invoke(Type: Constructable, dynamicDependencies?: TDeps): T { + if (isNativeFunction(Type)) { + throw createMappedError(ErrorNames.no_construct_native_fn, Type); + } const previousContainer = currentContainer; currentContainer = this; - try { - if (isNativeFunction(Type)) { - throw createMappedError(ErrorNames.no_construct_native_fn, Type); + if (__DEV__) { + let resolvedDeps: unknown[]; + let dep: Key | undefined; + + try { + resolvedDeps = getDependencies(Type).map(_ => this.get(dep = _)); + } catch (ex) { + logError(`[DEV:aurelia] Error during construction of ${Type.name}, caused by dependency: ${String(dep)}`); + currentContainer = previousContainer; + throw ex; + } + + try { + return dynamicDependencies === void 0 + ? new Type(...resolvedDeps) + : new Type(...resolvedDeps, ...dynamicDependencies); + } catch (ex) { + logError(`[DEV:aurelia] Error during construction of ${Type.name}`); + throw ex; + } finally { + currentContainer = previousContainer; } + } + try { return dynamicDependencies === void 0 ? new Type(...getDependencies(Type).map(containerGetKey, this)) : new Type(...getDependencies(Type).map(containerGetKey, this), ...dynamicDependencies); @@ -512,6 +535,37 @@ class Factory implements IFactory { const previousContainer = currentContainer; currentContainer = container; let instance: Resolved; + /* istanbul ignore next */ + if (__DEV__) { + let resolvedDeps: unknown[]; + let dep: Key | undefined; + try { + resolvedDeps = this.dependencies.map(_ => container.get(dep = _)); + } catch (ex) { + logError(`[DEV:aurelia] Error during construction of ${this.Type.name}, caused by dependency: ${String(dep)}`); + currentContainer = previousContainer; + throw ex; + } + + try { + if (dynamicDependencies === void 0) { + instance = new this.Type(...resolvedDeps) as Resolved; + } else { + instance = new this.Type(...resolvedDeps, ...dynamicDependencies) as Resolved; + } + + if (this.transformers == null) { + return instance; + } + + return this.transformers.reduce(transformInstance, instance); + } catch (ex) { + logError(`[DEV:aurelia] Error during construction of ${this.Type.name}`); + throw ex; + } finally { + currentContainer = previousContainer; + } + } try { if (dynamicDependencies === void 0) { instance = new this.Type(...this.dependencies.map(containerGetKey, container)) as Resolved; @@ -578,6 +632,25 @@ export function resolve(...keys: A): Resolved | if (currentContainer == null) { throw createMappedError(ErrorNames.no_active_container_for_resolve, ...keys); } + /* istanbul ignore next */ + if (__DEV__) { + if (keys.length === 1) { + try { + return currentContainer.get(keys[0]); + } catch (ex) { + logError(`[DEV:aurelia] resolve() call error for: ${String(keys[0])}`); + throw ex; + } + } else { + let key: Key | undefined; + try { + return keys.map(_ => currentContainer!.get(key = _)); + } catch (ex) { + logError(`[DEV:aurelia] resolve() call error for: ${String(key)}`); + throw ex; + } + } + } return keys.length === 1 ? currentContainer.get(keys[0]) : keys.map(containerGetKey, currentContainer); diff --git a/packages/kernel/src/errors.ts b/packages/kernel/src/errors.ts index db5300e016..f3cde8047c 100644 --- a/packages/kernel/src/errors.ts +++ b/packages/kernel/src/errors.ts @@ -77,3 +77,7 @@ function pleaseHelpCreateAnIssue(title: string, body?: string) { + `https://github.com/aurelia/aurelia/issues/new?title=${encodeURIComponent(title)}` + (body != null ? `&body=${encodeURIComponent(body)}` : '&template=bug_report.md'); } + +/** @internal */ +// eslint-disable-next-line +export const logError = (...args: unknown[]) => (globalThis as any).console.error(...args); diff --git a/packages/kernel/src/functions.ts b/packages/kernel/src/functions.ts index 6dab395c92..bfe320ab1d 100644 --- a/packages/kernel/src/functions.ts +++ b/packages/kernel/src/functions.ts @@ -412,9 +412,8 @@ export const isNativeFunction = /*@__PURE__*/(function () { charCodeAt(sourceText, i - 12) === 0x74 && // t charCodeAt(sourceText, i - 13) === 0x61 && // a charCodeAt(sourceText, i - 14) === 0x6E && // n - charCodeAt(sourceText, i - 15) === 0x58 // [ + charCodeAt(sourceText, i - 15) === 0x5B // [ ); - lookup.set(fn, isNative); } return isNative;