Description
Caveat: I'm not sure whether I'm observing intended behaviour or not. It could be a "It Works On My Machine" kind of problem - perhaps it is not.
The symptoms suggest that platform side @types/node
isn't installed when the tests are run (perhaps that is intentional).
The error message is as follows:
We received the following error when we ran your code:
The submitted code didn't compile. We have collected the errors encountered during compilation. At this moment the error messages are not very read-friendly, but it's a start. We are working on a more helpful output.
dnd-ability-scores.ts(1,20): error TS2307: Cannot find module 'crypto' or its corresponding type declarations.
Example solution affected.
dnd-abilities-scores.ts
import crypto from 'crypto';
declare const abilitiesRollBrand: unique symbol;
type AbilitiesRoll = number & {
[abilitiesRollBrand]: true;
};
const SCORE_COUNT = 6;
const SCORE_MAX_INDEX = SCORE_COUNT - 1;
const SCORE_BITS = 4;
const SCORE_MASK = ((): number => {
let mask = 1;
for (let i = 1; i < SCORE_BITS; i += 1, mask = (mask << 1) | 1);
return mask;
})();
const SCORE_MIN = 3;
const SCORE_MAX = toScore(SCORE_MASK);
function errorScoreIndex(index: number): Error {
return new Error(`'${index}' is not a valid score index`);
}
function toScore(value: number): number {
return (SCORE_MASK & value) + SCORE_MIN;
}
function getScore(rollValues: AbilitiesRoll, index: number): number {
if (index < 0 || SCORE_MAX_INDEX < index) throw errorScoreIndex(index);
return toScore(rollValues >>> (index * SCORE_BITS));
}
function rollToScores(rollValues: AbilitiesRoll): number[] {
const scores: number[] = [];
for (
let i = 0, values = rollValues as number;
i < SCORE_COUNT;
i += 1, values >>>= SCORE_BITS
)
scores[i] = toScore(values);
return scores;
}
const targetBuffer = new Uint32Array(1);
function roll(): AbilitiesRoll {
crypto.randomFillSync(targetBuffer);
return targetBuffer[0] as AbilitiesRoll;
}
function toModifier(value: number): number {
return (value - 10) >> 1;
}
export {
roll,
rollToScores,
SCORE_MIN,
SCORE_MAX,
toModifier,
getScore,
SCORE_MAX_INDEX,
};
dnd-character.ts
import * as AbilityScores from './dnd-ability-scores';
const { roll, rollToScores, toModifier } = AbilityScores;
const HITPOINTS_INITIAL = 10;
const ABILITIES_ORDERED = [
'strength',
'dexterity',
'constitution',
'intelligence',
'wisdom',
'charisma',
] as const;
type AbilityKey = typeof ABILITIES_ORDERED[number];
type Abilities = Record<AbilityKey, number>;
type AbilityTarget = Partial<Abilities>;
function rollAbilities(): Abilities {
const scores = rollToScores(roll());
return ABILITIES_ORDERED.reduce<AbilityTarget>((target, key, i) => {
target[key] = scores[i];
return target;
}, {}) as Abilities;
}
class DnDCharacter {
#abilities: Abilities;
#hitpoints: number;
constructor() {
const abilities = rollAbilities();
this.#hitpoints = HITPOINTS_INITIAL + toModifier(abilities.constitution);
this.#abilities = abilities;
}
get strength(): number {
return this.#abilities.strength;
}
get dexterity(): number {
return this.#abilities.dexterity;
}
get constitution(): number {
return this.#abilities.constitution;
}
get intelligence(): number {
return this.#abilities.intelligence;
}
get wisdom(): number {
return this.#abilities.wisdom;
}
get charisma(): number {
return this.#abilities.charisma;
}
get hitpoints(): number {
return this.#hitpoints;
}
static generateAbilityScore(): number {
return AbilityScores.getScore(roll(), AbilityScores.SCORE_MAX_INDEX);
}
static getModifierFor(abilityValue: number): number {
return toModifier(abilityValue);
}
}
export { DnDCharacter };
Clearly the package.json
downloaded with the CLI installs @types/node
which is why no such error occurs locally.
"@types/node": "^14.17.14",
Why the h@ll are you using
crypto.randomDFillSync()
in an easy exercise.
I've stopped using Math.random()
ever since I ran into this:
Note:
Math.random()
does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely thewindow.crypto.getRandomValues()
method.
that remark may as well be a deprecation notice - i.e. one needs to also know how to use crypto.getRandomValues()
or crypto.randomFillSync()
.
Update: Using crypto
worked fine 9 days ago with the Simple Cipher exercise