This page documents the 0.4 release candidates of @nexusdi/core. The newest on npm is 0.4.0-rc.1. The documentation for 0.3.2, the current release, is at nexus.js.org. Try the release candidate.
NEXUS_BLUEPRINT_INVALID
NEXUS_BLUEPRINT_INVALID is the error that Nexus.create, Nexus.check, ship.validate() and ship.load() throw when the compiler finds one or more errors in the module graph. It lists every wiring mistake it found at once, and no constructor has run.
Reproduce NEXUS_BLUEPRINT_INVALID
The region binds ShipComputer to a class that needs ReactorCore, which no module provides, and binds SurveyDrone to a class whose constructor takes a parameter that no deps list names. Nexus.create rejects with one BlueprintError that holds both errors. Without a plugin, core prints a one-line message that starts with the code and ends with the address of this page. With errors() from @nexusdi/errors registered (npm install @nexusdi/errors@next), the same error carries the full text and its fix.
import { Nexus, Token, defineModule, isNexusError } from '@nexusdi/core';
import { provide } from '@nexusdi/core';
import { errors } from '@nexusdi/errors';
interface IReactorCore {
readonly output: number;
}
interface IShipComputer {
status(): string;
}
interface ISurveyDrone {
readonly computer: IShipComputer;
}
const REACTOR = new Token<IReactorCore>('ReactorCore');
const COMPUTER = new Token<IShipComputer>('ShipComputer');
const DRONE = new Token<ISurveyDrone>('SurveyDrone');
class QuantumComputer implements IShipComputer {
static deps = [REACTOR] as const;
constructor(private readonly reactor: IReactorCore) {}
status() {
return `Reactor output ${this.reactor.output} GW.`;
}
}
class ScoutDrone implements ISurveyDrone {
constructor(readonly computer: IShipComputer) {}
}
const Engineering = defineModule({
name: 'Engineering',
providers: [
provide(COMPUTER, { useClass: QuantumComputer }),
provide(DRONE, { useClass: ScoutDrone }),
],
});
const thin = await Nexus.create(Engineering).catch((error: unknown) => error);
if (!isNexusError(thin, 'NEXUS_BLUEPRINT_INVALID')) throw thin;
const codes = thin.errors.map((error) => error.code); // -> ['NEXUS_MISSING_DEPS', 'NEXUS_MISSING_PROVIDER']
console.log(codes);
const lines = thin.message.split('\n'); // -> ['[NEXUS_BLUEPRINT_INVALID] 2 errors. https://nexus.js.org/errors/NEXUS_BLUEPRINT_INVALID', ' [NEXUS_MISSING_DEPS] token=SurveyDrone module=Engineering arity=1 useClass=ScoutDrone. https://nexus.js.org/errors/NEXUS_MISSING_DEPS', ' [NEXUS_MISSING_PROVIDER] token=ReactorCore requester=ShipComputer module=Engineering. https://nexus.js.org/errors/NEXUS_MISSING_PROVIDER']
console.log(lines);
const full = await Nexus.create(Engineering, { plugins: [errors()] }).catch(
(error: unknown) => error,
);
if (!isNexusError(full, 'NEXUS_BLUEPRINT_INVALID')) throw full;
const text = full.message.split('\n'); // -> ['[NEXUS_BLUEPRINT_INVALID] the module graph has 2 errors; nothing was built.', ' [NEXUS_MISSING_DEPS] ScoutDrone (useClass for SurveyDrone) in Engineering takes 1 constructor parameter and has no deps.', ' Fix: add deps to the binding, declare static deps = [...] as const on ScoutDrone, or decorate it with @Injectable({ deps }).', ' [NEXUS_MISSING_PROVIDER] ShipComputer (module Engineering) depends on ReactorCore, but no provider of ReactorCore is visible in Engineering.', ' Fix: provide ReactorCore in Engineering or in a module Engineering imports.']
console.log(text);Try it: save the region as error.ts and run npx tsx error.ts. It prints three lists. The first holds the two inner codes, NEXUS_MISSING_DEPS and NEXUS_MISSING_PROVIDER. The second is core’s message: a first line that counts the errors, then one indented line per inner error. The third is the full text that errors() writes, with a Fix: line under each inner error. Then save the fix region below as fixed.ts and run npx tsx fixed.ts. It prints Reactor output 1.21 GW..
Fix NEXUS_BLUEPRINT_INVALID
NEXUS_BLUEPRINT_INVALID is fixed by fixing each inner error. Read error.errors, open the page of each inner code, and apply its fix. Here ReactorCore gets a provider and ScoutDrone declares static deps.
import { Nexus, Token, defineModule, provide } from '@nexusdi/core';
interface IReactorCore {
readonly output: number;
}
interface IShipComputer {
status(): string;
}
interface ISurveyDrone {
readonly computer: IShipComputer;
}
const REACTOR = new Token<IReactorCore>('ReactorCore');
const COMPUTER = new Token<IShipComputer>('ShipComputer');
const DRONE = new Token<ISurveyDrone>('SurveyDrone');
class FusionReactor implements IReactorCore {
readonly output = 1.21;
}
class QuantumComputer implements IShipComputer {
static deps = [REACTOR] as const;
constructor(private readonly reactor: IReactorCore) {}
status() {
return `Reactor output ${this.reactor.output} GW.`;
}
}
class ScoutDrone implements ISurveyDrone {
static deps = [COMPUTER] as const;
constructor(readonly computer: IShipComputer) {}
}
const Engineering = defineModule({
name: 'Engineering',
providers: [
provide(REACTOR, { useClass: FusionReactor }),
provide(COMPUTER, { useClass: QuantumComputer }),
provide(DRONE, { useClass: ScoutDrone, lifetime: 'transient' }),
],
});
await using ship = await Nexus.create(Engineering);
const status = ship.get(DRONE).computer.status(); // -> 'Reactor output 1.21 GW.'
console.log(status);Try it: delete the provide(REACTOR, ...) line from Engineering in fixed.ts and run it again. Nexus.create rejects with a BlueprintError that holds one error, NEXUS_MISSING_PROVIDER for ReactorCore, and the program ends with that error. The static deps on ScoutDrone stay fixed, so the other error does not return. Put the line back and the program prints Reactor output 1.21 GW. again.
Fields of BlueprintError
BlueprintError has one field. Its message lists the inner errors, one per line.
errors: every error one compilation found, in pass order. Each is aNexusErrorwith its owncode, soerror.errors.map((inner) => inner.code)lists the codes.