diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..6af03ce3 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/settings.json b/.vscode/settings.json index f5b11207..f844d69f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,9 @@ "EJSON", "healthbar", "healthbars", + "meteortesting", "nearley", + "ngraph", "uncomputed", "walkdown" ] diff --git a/app/.github/pull_request_template.md b/app/.github/pull_request_template.md deleted file mode 100644 index 78e990e6..00000000 --- a/app/.github/pull_request_template.md +++ /dev/null @@ -1,16 +0,0 @@ -# Checklists - -## Adding features - -- [ ] My new pull request has zero code changes -- [ ] I have described the feature I intend to work on -- [ ] I have described how I intend to implement the feature -- [ ] I will wait for comment from the project's maintainers before submitting code changes - -## Fixing bugs -- [ ] I have performed a self-review of my code -- [ ] I have included a link to the relevant github issue or discord post in the description - -# Description - -`Detailed description of your changes` diff --git a/app/.gitignore b/app/.gitignore index e4ba5ce6..67d0a229 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -3,6 +3,9 @@ .demeteorized .cache .vscode +.coverage +.nyc_output +.DS_Store fileStorage settings.json public/components diff --git a/app/.meteor/packages b/app/.meteor/packages index 3d996c5d..9a26a0c2 100644 --- a/app/.meteor/packages +++ b/app/.meteor/packages @@ -51,3 +51,5 @@ zodern:types zodern:fix-async-stubs typescript ecmascript +lmieulet:meteor-legacy-coverage +lmieulet:meteor-coverage diff --git a/app/.meteor/versions b/app/.meteor/versions index 0e4403f3..4332f7f0 100644 --- a/app/.meteor/versions +++ b/app/.meteor/versions @@ -52,6 +52,8 @@ inter-process-messaging@0.1.1 lai:collection-extensions@0.4.0 launch-screen@2.0.0 littledata:synced-cron@1.5.1 +lmieulet:meteor-coverage@4.1.0 +lmieulet:meteor-legacy-coverage@0.2.0 localstorage@1.2.0 logging@1.3.3 mdg:validated-method@1.3.0 diff --git a/app/imports/api/engine/action/applyProperties/applyActionProperty.test.ts b/app/imports/api/engine/action/applyProperties/applyActionProperty.test.ts index a6785ef0..bc2e7c37 100644 --- a/app/imports/api/engine/action/applyProperties/applyActionProperty.test.ts +++ b/app/imports/api/engine/action/applyProperties/applyActionProperty.test.ts @@ -1,5 +1,6 @@ import { assert } from 'chai'; import { + allLogContent, allMutations, allUpdates, createTestCreature, @@ -7,12 +8,13 @@ import { removeAllCreaturesAndProps, runActionById } from '/imports/api/engine/action/functions/actionEngineTest.testFn'; -import { Mutation, Update } from '/imports/api/engine/action/tasks/TaskResult'; +import { LogContent, Mutation, Update } from '/imports/api/engine/action/tasks/TaskResult'; import Alea from 'alea'; const [ - creatureId, targetCreatureId, targetCreature2Id, - emptyActionId, attackActionId, usesActionId, attackMissId, + creatureId, targetCreatureId, targetCreature2Id, emptyActionId, selfActionId, attackActionId, + usesActionId, attackMissId, attackNoTargetId, usesResourcesActionId, ammoId, resourceAttId, consumeAmmoId, + consumeResourceId, noUsesActionId, insufficientResourcesActionId ] = randomIds; const actionTestCreature = { @@ -22,6 +24,13 @@ const actionTestCreature = { { _id: emptyActionId, type: 'action', + summary: { text: 'Summary text 1 + 1 = {1 + 1}' } + }, + // Attack that targets self + { + _id: selfActionId, + type: 'action', + target: 'self', }, // Attack that hits { @@ -35,6 +44,12 @@ const actionTestCreature = { type: 'action', attackRoll: { calculation: '-5' }, }, + // Attack that has no target + { + _id: attackNoTargetId, + type: 'action', + attackRoll: { calculation: '1' }, + }, // Disable crits { type: 'attribute', @@ -56,6 +71,57 @@ const actionTestCreature = { usesUsed: 1, reset: 'longRest', }, + // Not enough uses + { + _id: noUsesActionId, + type: 'action', + uses: { calculation: '5' }, + usesUsed: 5, + reset: 'longRest', + }, + // Uses Resources + { + _id: ammoId, + type: 'item', + quantity: 12, + tags: ['ammo'] + }, + { + _id: resourceAttId, + type: 'attribute', + name: 'Resource Name', + attributeType: 'stat', + baseValue: { calculation: '7' }, + variableName: 'resourceVar', + }, + { + _id: usesResourcesActionId, + type: 'action', + resources: { + itemsConsumed: [{ + _id: consumeAmmoId, + tag: 'ammo', + quantity: { calculation: '3' }, + itemId: ammoId, + }], + attributesConsumed: [{ + _id: consumeResourceId, + variableName: 'resourceVar', + quantity: { calculation: '2' }, + }] + } + }, + { + _id: insufficientResourcesActionId, + type: 'action', + resources: { + attributesConsumed: [{ + _id: consumeResourceId, + variableName: 'resourceVar', + quantity: { calculation: '9001' }, + }] + } + } ], } @@ -106,11 +172,43 @@ describe('Apply Action Properties', function () { const action = await runActionById(emptyActionId); assert.exists(action); assert.deepEqual(allMutations(action), [{ - contents: [{ name: 'Action' }], + contents: [{ + name: 'Action', + value: 'Summary text 1 + 1 = 2', + }], targetIds: [], }]); }); + it('should target self when set', async function () { + const action = await runActionById(selfActionId); + assert.exists(action); + assert.deepEqual(allMutations(action), [{ + contents: [{ + name: 'Action', + }], + targetIds: [creatureId], + }]); + }); + + it('should make attack rolls against no targets', async function () { + const action = await runActionById(attackNoTargetId, []); + const expectedMutations: Mutation[] = [ + { + contents: [{ name: 'Action' }], + targetIds: [], + }, { + contents: [{ + name: 'To Hit', + value: '1d20 [10] + 1\n**11**', + inline: true, + }], + targetIds: [], + } + ]; + assert.deepEqual(allMutations(action), expectedMutations); + }) + it('should make attack rolls against multiple creatures', async function () { const action = await runActionById(attackActionId, [ targetCreatureId, @@ -151,6 +249,19 @@ describe('Apply Action Properties', function () { assert.deepEqual(allUpdates(action), expectedUpdates); }); + it('should fail to make attacks that have no uses left', async function () { + const action = await runActionById(noUsesActionId, [targetCreatureId]); + const expectedContent: LogContent[] = [ + { + name: 'Action' + }, { + name: 'Error', + value: 'Action does not have enough uses left' + } + ] + assert.deepEqual(allLogContent(action), expectedContent); + }); + it('should make attack rolls that miss', async function () { const action = await runActionById(attackMissId, [targetCreatureId]); const expectedMutations: Mutation[] = [ @@ -169,4 +280,59 @@ describe('Apply Action Properties', function () { assert.deepEqual(allMutations(action), expectedMutations); }); + it('actions should consume resources', async function () { + const action = await runActionById(usesResourcesActionId, []); + const expectedMutations: Mutation[] = [ + { + contents: [{ name: 'Action' }], + targetIds: [] + }, + { + contents: [{ + inline: true, + name: 'Attribute damaged', + value: '−2 Resource Name', + }], + targetIds: [creatureId], + updates: [{ + inc: { + damage: 2, + value: -2 + }, + propId: resourceAttId, + type: 'attribute' + }], + }, + { + targetIds: [], + updates: [ + { + inc: { + quantity: -3 + }, + propId: ammoId, + type: 'item', + } + ] + } + ]; + assert.deepEqual(allMutations(action), expectedMutations); + }); + + it('should handle insufficient resources', async function () { + const action = await runActionById(insufficientResourcesActionId, []); + const expectedMutations: Mutation[] = [ + { + contents: [{ + name: 'Action' + }, { + name: 'Error', + value: 'This creature doesn\'t have sufficient resources to perform this action', + }], + targetIds: [], + }, + ]; + assert.deepEqual(allMutations(action), expectedMutations); + }); + }); diff --git a/app/imports/api/engine/action/applyProperties/applyActionProperty.ts b/app/imports/api/engine/action/applyProperties/applyActionProperty.ts index 8934427e..5069236f 100644 --- a/app/imports/api/engine/action/applyProperties/applyActionProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyActionProperty.ts @@ -21,33 +21,36 @@ export default async function applyActionProperty( const targetIds = prop.target === 'self' ? [action.creatureId] : task.targetIds; //Log the name and summary, check that the property has enough resources to fire - const content: LogContent = { name: getPropertyTitle(prop) }; if (prop.summary?.text) { await recalculateInlineCalculations(prop.summary, action, 'reduce', userInput); - content.value = prop.summary.value; } - if (prop.silent) content.silenced = true; - result.appendLog(content, targetIds); + result.appendLog({ + name: getPropertyTitle(prop), + ...prop.summary && { value: prop.summary.value }, + ...prop.silent && { silenced: true }, + }, targetIds); // Check Uses if (prop.usesLeft <= 0) { - if (!prop.silent) result.appendLog({ + result.appendLog({ name: 'Error', - value: `${prop.name || 'action'} does not have enough uses left`, + value: `${getPropertyTitle(prop)} does not have enough uses left`, + ...prop.silent && { silenced: true }, }, targetIds); return; } // Check Resources if (prop.insufficientResources) { - if (!prop.silent) result.appendLog({ + result.appendLog({ name: 'Error', value: 'This creature doesn\'t have sufficient resources to perform this action', + ...prop.silent && { silenced: true }, }, targetIds); return; } - spendResources(action, prop, targetIds, result, userInput); + await spendResources(action, prop, targetIds, result, userInput); const attack: CalculatedField = prop.attackRoll || prop.attackRollBonus; diff --git a/app/imports/api/engine/action/tasks/applyDamagePropTask.ts b/app/imports/api/engine/action/tasks/applyDamagePropTask.ts index ea5b3487..a7533c24 100644 --- a/app/imports/api/engine/action/tasks/applyDamagePropTask.ts +++ b/app/imports/api/engine/action/tasks/applyDamagePropTask.ts @@ -5,10 +5,12 @@ import { applyTriggers } from '/imports/api/engine/action/functions/applyTaskGro import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope'; import getPropertyTitle from '/imports/api/utility/getPropertyTitle'; import { getSingleProperty } from '/imports/api/engine/loadCreatures'; +import numberToSignedString from '/imports/api/utility/numberToSignedString'; export default async function applyDamagePropTask( task: DamagePropTask, action: EngineAction, result: TaskResult, userInput ): Promise { + const prop = task.prop; if (task.targetIds.length > 1) { @@ -22,7 +24,7 @@ export default async function applyDamagePropTask( // Set the scope properties result.pushScope = {}; - if (prop.operation === 'increment') { + if (operation === 'increment') { if (value >= 0) { result.pushScope['~damage'] = { value }; } else { @@ -67,7 +69,7 @@ export default async function applyDamagePropTask( value: `${statName}${operation === 'set' ? ' set to' : ''}` + ` ${value}`, inline: true, - silenced: prop.silent, + ...prop.silent && { silenced: true }, }, task.targetIds); } @@ -98,7 +100,7 @@ export default async function applyDamagePropTask( name: title, value: `${getPropertyTitle(targetProp)} set to ${value}`, inline: true, - silenced: prop.silent, + ...prop.silent && { silenced: true }, }] }); } else if (operation === 'increment') { @@ -120,10 +122,10 @@ export default async function applyDamagePropTask( type: targetProp.type, }], contents: [{ - name: 'Attribute damage', - value: `${getPropertyTitle(targetProp)} ${value}`, + name: 'Attribute damaged', + value: `${numberToSignedString(-value)} ${getPropertyTitle(targetProp)}`, inline: true, - silenced: prop.silent, + ...prop.silent && { silenced: true }, }] }); } diff --git a/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts b/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts index 4097991f..6a178f65 100644 --- a/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts +++ b/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts @@ -43,11 +43,13 @@ export default async function applyItemAsAmmoTask(task: ItemAsAmmoTask, action: type: 'item', }], // Log the item name as a heading if it has child properties to apply - contents: itemChildren.length ? [{ - name: getPropertyTitle(item) || 'Ammo', - inline: false, - silenced: prop.silent, - }] : undefined, + ...itemChildren.length && { + contents: [{ + name: getPropertyTitle(item) || 'Ammo', + inline: false, + silenced: prop.silent, + }] + }, }); await applyTriggers(action, item, [action.creatureId], 'ammo.after', userInput); diff --git a/app/imports/api/engine/action/tasks/applyTask.ts b/app/imports/api/engine/action/tasks/applyTask.ts index a33f9e76..91a0b23b 100644 --- a/app/imports/api/engine/action/tasks/applyTask.ts +++ b/app/imports/api/engine/action/tasks/applyTask.ts @@ -53,7 +53,7 @@ export default async function applyTask( // Create a result an push it to the action results, pass it to the apply function to modify const result = new TaskResult(task.prop._id, task.targetIds); - result.scope[`#${prop.type}`] = prop; + result.scope[`#${prop.type}`] = { _propId: prop._id }; action.results.push(result); // Apply the property diff --git a/app/imports/parser/parseTree/call.ts b/app/imports/parser/parseTree/call.ts index 17fbe058..3f90d9b5 100644 --- a/app/imports/parser/parseTree/call.ts +++ b/app/imports/parser/parseTree/call.ts @@ -1,4 +1,3 @@ -console.log('call.ts imports') import error from '/imports/parser/parseTree/error'; import constant from '/imports/parser/parseTree/constant'; import functions, { ParserFunction } from '/imports/parser/functions'; diff --git a/app/package-lock.json b/app/package-lock.json index ee57feb2..17a46a80 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1512,6 +1512,15 @@ "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, + "@types/simpl-schema": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/@types/simpl-schema/-/simpl-schema-1.12.7.tgz", + "integrity": "sha512-GhXOCJqKcDeawYoIe4Jly7C5ePR3Uh3jaswb1U+Ruh1x7EtZqOJMMyxnoVvJUIl5b+v7yoFs4RVny/ZowyXBDw==", + "dev": true, + "requires": { + "@types/meteor": "*" + } + }, "@types/sizzle": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", diff --git a/app/package.json b/app/package.json index f264c12a..504e3eb6 100644 --- a/app/package.json +++ b/app/package.json @@ -13,6 +13,8 @@ "debug": "meteor --inspect", "bundle-viz": "meteor --extra-packages bundle-visualizer --production", "test": "meteor test --driver-package meteortesting:mocha --port 3001", + "test:coverage": "COVERAGE=1 COVERAGE_OUT_LCOVONLY=1 COVERAGE_OUT_REMAP=1 COVERAGE_APP_FOLDER=$PWD/ meteor test --once --driver-package meteortesting:mocha", + "test:watch:coverage": "COVERAGE=1 COVERAGE_OUT_LCOVONLY=1 COVERAGE_OUT_REMAP=1 COVERAGE_APP_FOLDER=$PWD/ TEST_WATCH=1 meteor test --driver-package meteortesting:mocha", "build": "meteor build ../build --architecture os.linux.x86_64" }, "engines": { @@ -68,6 +70,7 @@ "devDependencies": { "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", + "@types/simpl-schema": "^1.12.7", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vue/compiler-dom": "^3.4.19", diff --git a/app/tsconfig.json b/app/tsconfig.json index e6cc6b2b..93b1feab 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -1,9 +1,11 @@ { "compilerOptions": { - "module": "ESNext", + "module": "esNext", "moduleResolution": "Node", - "target": "ES2020", - "jsx": "react", + "target": "es2018", + "lib": ["esnext", "dom"], + "jsx": "preserve", + "strict": true, "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": ".", @@ -22,15 +24,19 @@ "meteor/aldeed:collection2": [ "packages/collection2/collection2.js" ] - } + }, + "resolveJsonModule": true, + "types": ["node", "mocha"], + "esModuleInterop": true, }, "vueCompilerOptions": { - "target": 2 // For Vue version <= 2.6.14 + "target": 2 }, "exclude": [ "node_modules", "**/node_modules/*", - ".meteor" + ".meteor", + "./packages/**" ], "typeAcquisition": { "include": [ diff --git a/node_modules/@types/nearley/LICENSE b/node_modules/@types/nearley/LICENSE deleted file mode 100644 index 9e841e7a..00000000 --- a/node_modules/@types/nearley/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/node_modules/@types/nearley/README.md b/node_modules/@types/nearley/README.md deleted file mode 100644 index 9a5f1a3c..00000000 --- a/node_modules/@types/nearley/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Installation -> `npm install --save @types/nearley` - -# Summary -This package contains type definitions for nearley (https://github.com/Hardmath123/nearley#readme). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/nearley. - -### Additional Details - * Last updated: Tue, 07 Nov 2023 09:09:39 GMT - * Dependencies: none - -# Credits -These definitions were written by [Nikita Litvin](https://github.com/deltaidea), and [BendingBender](https://github.com/BendingBender). diff --git a/node_modules/@types/nearley/index.d.ts b/node_modules/@types/nearley/index.d.ts deleted file mode 100644 index 5cca1013..00000000 --- a/node_modules/@types/nearley/index.d.ts +++ /dev/null @@ -1,108 +0,0 @@ -export as namespace nearley; - -export class Parser { - /** - * Reserved token for indicating a parse fail. - */ - static fail: {}; - - grammar: Grammar; - options: ParserOptions; - lexer: Lexer; - lexerState?: LexerState | undefined; - current: number; - /** - * An array of possible parsings. Each element is the thing returned by your grammar. - * - * Note that this is undefined before the first feed() call. - * It isn't typed as `any[] | undefined` to spare you the null checks when it's definitely an array. - */ - results: any[]; - - constructor(grammar: Grammar, options?: ParserOptions); - - /** - * The Parser object can be fed data in parts with .feed(data). - * You can then find an array of parsings with the .results property. - * If results is empty, then there are no parsings. - * If results contains multiple values, then that combination is ambiguous. - * - * @throws If there are no possible parsings, nearley will throw an error - * whose offset property is the index of the offending token. - */ - feed(chunk: string): this; - finish(): any[]; - restore(column: { [key: string]: any; lexerState: LexerState }): void; - save(): { [key: string]: any; lexerState: LexerState }; -} - -export interface ParserOptions { - keepHistory?: boolean | undefined; - lexer?: Lexer | undefined; -} - -export class Rule { - static highestId: number; - - id: number; - name: string; - symbols: any[]; - postprocess?: Postprocessor | undefined; - - constructor(name: string, symbols: any[], postprocess?: Postprocessor); - - toString(withCursorAt?: number): string; -} - -export class Grammar { - static fromCompiled(rules: CompiledRules): Grammar; - - rules: Rule[]; - start: string; - byName: { [ruleName: string]: Rule[] }; - lexer?: Lexer | undefined; - - constructor(rules: Rule[]); -} - -export interface CompiledRules { - Lexer?: Lexer | undefined; - ParserStart: string; - ParserRules: ParserRule[]; -} - -export interface ParserRule { - name: string; - symbols: any[]; - postprocess?: Postprocessor | undefined; -} - -export type Postprocessor = (data: any[], reference?: number, wantedBy?: {}) => void; - -export interface Lexer { - /** - * Sets the internal buffer to data, and restores line/col/state info taken from save(). - */ - reset(data: string, state?: LexerState): void; - /** - * Returns e.g. {type, value, line, col, …}. Only the value attribute is required. - */ - next(): Token | undefined; - /** - * Returns an object describing the current line/col etc. This allows us - * to preserve this information between feed() calls, and also to support Parser#rewind(). - * The exact structure is lexer-specific; nearley doesn't care what's in it. - */ - save(): LexerState; - /** - * Returns a string with an error message describing the line/col of the offending token. - * You might like to include a preview of the line in question. - */ - formatError(token: Token, message: string): string; -} - -export type Token = string | { value: string }; - -export interface LexerState { - [x: string]: any; -} diff --git a/node_modules/@types/nearley/package.json b/node_modules/@types/nearley/package.json deleted file mode 100644 index 72c1d0bd..00000000 --- a/node_modules/@types/nearley/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "_from": "@types/nearley", - "_id": "@types/nearley@2.11.5", - "_inBundle": false, - "_integrity": "sha512-dM7TrN0bVxGGXTYGx4YhGear8ysLO5SOuouAWM9oltjQ3m9oYa13qi8Z1DJp5zxVMPukvQdsrnZmgzpeuTSEQA==", - "_location": "/@types/nearley", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "@types/nearley", - "name": "@types/nearley", - "escapedName": "@types%2fnearley", - "scope": "@types", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/@types/nearley/-/nearley-2.11.5.tgz", - "_shasum": "9087e1634e1c90efb25d661390702381789685cb", - "_spec": "@types/nearley", - "_where": "/Users/stef/github/DiceCloud", - "bugs": { - "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues" - }, - "bundleDependencies": false, - "contributors": [ - { - "name": "Nikita Litvin", - "url": "https://github.com/deltaidea" - }, - { - "name": "BendingBender", - "url": "https://github.com/BendingBender" - } - ], - "dependencies": {}, - "deprecated": false, - "description": "TypeScript definitions for nearley", - "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/nearley", - "license": "MIT", - "main": "", - "name": "@types/nearley", - "repository": { - "type": "git", - "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git", - "directory": "types/nearley" - }, - "scripts": {}, - "typeScriptVersion": "4.5", - "types": "index.d.ts", - "typesPublisherContentHash": "2b82830a1a87ef19e588c4f6dcd1c00fde50afd7c9dc5bd8233b054f436578d4", - "version": "2.11.5" -} diff --git a/package-lock.json b/package-lock.json index 4cd093cc..0dd68c16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,6 +2,12 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, "@types/nearley": { "version": "2.11.5", "resolved": "https://registry.npmjs.org/@types/nearley/-/nearley-2.11.5.tgz",