mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-06 03:20:13 +08:00
Refactor packages (#101)
This commit is contained in:
35 files changed
+161
-121
No files matched your search
@@ -40,6 +40,12 @@ module.exports = {
|
|||||||
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
||||||
'import/prefer-default-export': 'off',
|
'import/prefer-default-export': 'off',
|
||||||
'no-restricted-syntax': ['off', 'ForOfStatement'],
|
'no-restricted-syntax': ['off', 'ForOfStatement'],
|
||||||
|
'lines-between-class-members': [
|
||||||
|
'error',
|
||||||
|
'always',
|
||||||
|
{ exceptAfterSingleLine: true },
|
||||||
|
],
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
|
||||||
@@ -55,4 +61,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['**/tests/**/*.js', '**/tests/**/*.ts'], // Adjust the pattern to match your test files
|
||||||
|
rules: {
|
||||||
|
'import/extensions': 'off', // Turn off the rule for test files
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
+4
-2
@@ -2,6 +2,8 @@
|
|||||||
// const { jsWithTs: tsjPreset } = require('ts-jest/presets')
|
// const { jsWithTs: tsjPreset } = require('ts-jest/presets')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
preset: 'ts-jest/presets/js-with-ts',
|
preset: 'ts-jest/presets/default-esm',
|
||||||
testEnvironment: 'node',
|
moduleNameMapper: {
|
||||||
|
'^(\\.{1,2}/.*)\\.js$': '$1', // Redirect .js imports to .ts files
|
||||||
|
},
|
||||||
}
|
}
|
||||||
+2
-2
@@ -20,7 +20,7 @@
|
|||||||
"cli": "yarn workspace client start",
|
"cli": "yarn workspace client start",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"format": "prettier --ignore-path .prettierignore --write app server",
|
"format": "prettier --ignore-path .prettierignore --write app server",
|
||||||
"test": "yarn jest",
|
"test": "yarn node --experimental-vm-modules --no-warnings $(yarn bin jest)",
|
||||||
"test:e2e": "yarn workspace tests test",
|
"test:e2e": "yarn workspace tests test",
|
||||||
"test:open": "yarn workspace tests test:open",
|
"test:open": "yarn workspace tests test:open",
|
||||||
"analytics": "yarn workspace analytics dev",
|
"analytics": "yarn workspace analytics dev",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"build:quests": "yarn workspace server build:quests"
|
"build:quests": "yarn workspace server build:quests"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^20.10.4",
|
"@types/node": "^20.10.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
||||||
"@typescript-eslint/parser": "^6.14.0",
|
"@typescript-eslint/parser": "^6.14.0",
|
||||||
|
|||||||
File renamed without changes.
@@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable lines-between-class-members */
|
|
||||||
import { basename } from './utils.js'
|
import { basename } from './utils.js'
|
||||||
|
|
||||||
interface FileObject {
|
export interface FileObject {
|
||||||
path: string
|
path: string
|
||||||
type: string
|
type: string
|
||||||
discovered: boolean
|
discovered: boolean
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
|
import { FileObject } from './file.js'
|
||||||
import FileNode from './fileNode.js'
|
import FileNode from './fileNode.js'
|
||||||
|
|
||||||
|
export interface Event {
|
||||||
|
add?: FileObject[]
|
||||||
|
remove?: FileObject[]
|
||||||
|
discover?: FileObject[]
|
||||||
|
}
|
||||||
|
|
||||||
export default class FileGraph extends FileNode {
|
export default class FileGraph extends FileNode {
|
||||||
add(files) {
|
add(files: FileObject[]) {
|
||||||
// Logic to add the file node to the graph
|
// Logic to add the file node to the graph
|
||||||
// You can implement the logic to find the appropriate location in the file graph
|
// You can implement the logic to find the appropriate location in the file graph
|
||||||
// If the file node already exists, throw an error
|
// If the file node already exists, throw an error
|
||||||
@@ -11,7 +18,7 @@ export default class FileGraph extends FileNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(files) {
|
remove(files: FileObject[]) {
|
||||||
// Logic to remove a file node from the graph
|
// Logic to remove a file node from the graph
|
||||||
// If the file node is a folder, also remove all children
|
// If the file node is a folder, also remove all children
|
||||||
// If the file node doesn't exist, throw an error
|
// If the file node doesn't exist, throw an error
|
||||||
@@ -21,7 +28,7 @@ export default class FileGraph extends FileNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
discover(eventFiles) {
|
discover(eventFiles: FileObject[]) {
|
||||||
// Logic to handle the discover event
|
// Logic to handle the discover event
|
||||||
// Overwrite the file graph with the provided files
|
// Overwrite the file graph with the provided files
|
||||||
// Remove file nodes that don't exist anymore and add new ones
|
// Remove file nodes that don't exist anymore and add new ones
|
||||||
@@ -35,7 +42,7 @@ export default class FileGraph extends FileNode {
|
|||||||
this.merge(newNode)
|
this.merge(newNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEvent(event) {
|
handleEvent(event: Event) {
|
||||||
// eslint-disable-next-line default-case
|
// eslint-disable-next-line default-case
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !!event.add:
|
case !!event.add:
|
||||||
@@ -1,19 +1,25 @@
|
|||||||
import File from './file.js'
|
import File, { FileObject } from './file.js'
|
||||||
import {
|
import {
|
||||||
DuplicateItemError,
|
DuplicateItemError,
|
||||||
ParentNotExistsError,
|
ParentNotExistsError,
|
||||||
FileNotExistsError,
|
FileNotExistsError,
|
||||||
} from './errors.js'
|
} from './errors.js'
|
||||||
import { basename, dirname } from './utils.js'
|
import { dirname } from './utils.js'
|
||||||
|
|
||||||
export default class FileNode extends File {
|
export default class FileNode extends File {
|
||||||
constructor(file) {
|
children: FileNode[]
|
||||||
|
|
||||||
|
constructor(file: FileObject | FileNode) {
|
||||||
super(file)
|
super(file)
|
||||||
this.children = []
|
this.children = []
|
||||||
if (file.children) this.children = file.children.map((f) => new FileNode(f))
|
if ((<FileNode>file).children)
|
||||||
|
this.children = (<FileNode>file).children.map((f) => new FileNode(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
addChild(fileInput, { makeParents } = {}) {
|
addChild(
|
||||||
|
fileInput: FileObject,
|
||||||
|
{ makeParents }: { makeParents?: boolean } = {}
|
||||||
|
) {
|
||||||
const file = new FileNode(fileInput)
|
const file = new FileNode(fileInput)
|
||||||
if (file.path === this.path) {
|
if (file.path === this.path) {
|
||||||
throw new DuplicateItemError(
|
throw new DuplicateItemError(
|
||||||
@@ -39,7 +45,6 @@ export default class FileNode extends File {
|
|||||||
} else if (makeParents) {
|
} else if (makeParents) {
|
||||||
const parent = new FileNode({
|
const parent = new FileNode({
|
||||||
path: parentPath,
|
path: parentPath,
|
||||||
name: basename(parentPath),
|
|
||||||
type: 'folder',
|
type: 'folder',
|
||||||
discovered: false,
|
discovered: false,
|
||||||
children: [file],
|
children: [file],
|
||||||
@@ -53,7 +58,7 @@ export default class FileNode extends File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeChild(fileToRemove) {
|
removeChild(fileToRemove: FileObject) {
|
||||||
const file = new FileNode(fileToRemove)
|
const file = new FileNode(fileToRemove)
|
||||||
const parentPath = dirname(file.path)
|
const parentPath = dirname(file.path)
|
||||||
|
|
||||||
@@ -73,7 +78,7 @@ export default class FileNode extends File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge(fileNode) {
|
merge(fileNode: FileNode) {
|
||||||
// Merge the children of the provided file node into this node
|
// Merge the children of the provided file node into this node
|
||||||
// If a child already exists, merge the children of that child
|
// If a child already exists, merge the children of that child
|
||||||
// If a child does not exist, add it to this node
|
// If a child does not exist, add it to this node
|
||||||
@@ -88,7 +93,7 @@ export default class FileNode extends File {
|
|||||||
if (existingChild) {
|
if (existingChild) {
|
||||||
existingChild.merge(child)
|
existingChild.merge(child)
|
||||||
} else {
|
} else {
|
||||||
this.children.push(child)
|
this.children.push(new FileNode(child))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -112,14 +117,12 @@ export default class FileNode extends File {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Cannot merge file nodes with different paths',
|
`Cannot merge file nodes with different paths: ${this.path}, ${fileNode.path}`
|
||||||
this.path,
|
|
||||||
fileNode.path
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toString(level = 0) {
|
toString(level = 0): string {
|
||||||
let { name } = this
|
let { name } = this
|
||||||
const indent = ' '.repeat(level)
|
const indent = ' '.repeat(level)
|
||||||
name = `${indent}${name}`
|
name = `${indent}${name}`
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export { default as File } from './file.js'
|
|
||||||
export { default as FileNode } from './fileNode.js'
|
|
||||||
export { default as FileGraph } from './fileGraph.js'
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export { default as File, FileObject } from './file.js'
|
||||||
|
export { default as FileNode } from './fileNode.js'
|
||||||
|
export { default as FileGraph, Event } from './fileGraph.js'
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export function dirname(path) {
|
export function dirname(path: string) {
|
||||||
const parts = path.split('/')
|
const parts = path.split('/')
|
||||||
if (parts.length <= 2) {
|
if (parts.length <= 2) {
|
||||||
return '/'
|
return '/'
|
||||||
@@ -7,7 +7,7 @@ export function dirname(path) {
|
|||||||
return parts.join('/')
|
return parts.join('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function basename(path) {
|
export function basename(path: string): string {
|
||||||
const parts = path.split('/')
|
const parts = path.split('/')
|
||||||
return parts.pop()
|
return parts.pop() ?? ''
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -6,10 +6,7 @@ export { default as Session } from './session.js'
|
|||||||
export { default as Command } from './command.js'
|
export { default as Command } from './command.js'
|
||||||
export { default as UserProfile } from './userProfile.js'
|
export { default as UserProfile } from './userProfile.js'
|
||||||
|
|
||||||
export default async function connectDB(uri) {
|
export default async function connectDB(uri: string) {
|
||||||
const db = await mongoose.connect(uri, {
|
const db = await mongoose.connect(uri)
|
||||||
useNewUrlParser: true,
|
|
||||||
useUnifiedTopology: true,
|
|
||||||
})
|
|
||||||
return db.connection.getClient()
|
return db.connection.getClient()
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
|
|||||||
export function isValidUsername(username) {
|
export function isValidUsername(username: string): boolean {
|
||||||
// check if the username is between 1 and 32 characters
|
// check if the username is between 1 and 32 characters
|
||||||
if (username.length > 32) {
|
if (username.length > 32) {
|
||||||
return false
|
return false
|
||||||
@@ -29,7 +29,7 @@ export function isValidUsername(username) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidEmail(email) {
|
export function isValidEmail(email: string): boolean {
|
||||||
// Define a regular expression pattern for a valid email address.
|
// Define a regular expression pattern for a valid email address.
|
||||||
const emailPattern = /^[\w-.+]+@([\w][\w-]*\.)+[\w-]{2,}$/
|
const emailPattern = /^[\w-.+]+@([\w][\w-]*\.)+[\w-]{2,}$/
|
||||||
|
|
||||||
@@ -3,14 +3,21 @@ const fileTypes = {
|
|||||||
folder: '-d',
|
folder: '-d',
|
||||||
link: '-L',
|
link: '-L',
|
||||||
socket: '-S',
|
socket: '-S',
|
||||||
|
unknown: '-e',
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitizePath(path) {
|
export type FileType = keyof typeof fileTypes
|
||||||
|
|
||||||
|
export type File = {
|
||||||
|
path: string
|
||||||
|
type: FileType
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizePath(path: string): string {
|
||||||
return path.replace(/[^a-zA-Z0-9._/-]/g, '')
|
return path.replace(/[^a-zA-Z0-9._/-]/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
export function buildFileCheckCmd(file: File): string[] {
|
||||||
export function buildFileCheckCmd(file) {
|
|
||||||
const { path, type } = file
|
const { path, type } = file
|
||||||
return ['test', fileTypes[type] || '-e', sanitizePath(path)]
|
return ['test', fileTypes[type] || '-e', sanitizePath(path)]
|
||||||
}
|
}
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
export default class DAG {
|
|
||||||
#nodes = new Map()
|
|
||||||
|
|
||||||
#edges = new Set()
|
|
||||||
|
|
||||||
#layers = []
|
|
||||||
|
|
||||||
constructor(nodes) {
|
|
||||||
this.#nodes = new Map(nodes.map((node) => [node._id, node]))
|
|
||||||
this.#edges = new Set()
|
|
||||||
this.#nodes.forEach((_, id) => {
|
|
||||||
this.#setLayer(id)
|
|
||||||
this.#addEdges(id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getNode(id) {
|
|
||||||
return this.#nodes.get(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
getNodes() {
|
|
||||||
return Array.from(this.#nodes.values())
|
|
||||||
}
|
|
||||||
|
|
||||||
getEdges() {
|
|
||||||
return this.#edges
|
|
||||||
}
|
|
||||||
|
|
||||||
getEdgesArray() {
|
|
||||||
return Array.from(this.#edges.values())
|
|
||||||
}
|
|
||||||
|
|
||||||
getLayers() {
|
|
||||||
return this.#layers
|
|
||||||
}
|
|
||||||
|
|
||||||
getLayer(id) {
|
|
||||||
const node = this.getNode(id)
|
|
||||||
if (!node) {
|
|
||||||
throw new Error(`Node ${id} not found`)
|
|
||||||
}
|
|
||||||
return this.#layers[node.layer - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
#setLayer(id) {
|
|
||||||
const node = this.getNode(id)
|
|
||||||
if (!node) {
|
|
||||||
throw new Error(`Node ${id} not found`)
|
|
||||||
}
|
|
||||||
if (node.layer !== undefined) {
|
|
||||||
return node.layer
|
|
||||||
}
|
|
||||||
const previousLayer = node.requirements.map((rId) => this.#setLayer(rId))
|
|
||||||
node.layer = Math.max(...previousLayer, 0) + 1
|
|
||||||
if (this.#layers.length < node.layer) {
|
|
||||||
this.#layers.push(1)
|
|
||||||
} else {
|
|
||||||
this.#layers[node.layer - 1] += 1
|
|
||||||
}
|
|
||||||
node.index = this.#layers[node.layer - 1]
|
|
||||||
return node.layer
|
|
||||||
}
|
|
||||||
|
|
||||||
#addEdges(id) {
|
|
||||||
const node = this.getNode(id)
|
|
||||||
if (!node) {
|
|
||||||
throw new Error(`Node ${id} not found`)
|
|
||||||
}
|
|
||||||
node.requirements.forEach((rId) => {
|
|
||||||
this.#edges.add([rId, id])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
interface Node {
|
||||||
|
_id: string
|
||||||
|
requirements: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class DAG {
|
||||||
|
private nodes = new Map()
|
||||||
|
private edges = new Set()
|
||||||
|
private layers: number[] = []
|
||||||
|
|
||||||
|
constructor(nodes: Node[]) {
|
||||||
|
this.nodes = new Map(nodes.map((node) => [node._id, node]))
|
||||||
|
this.edges = new Set()
|
||||||
|
this.nodes.forEach((_, id) => {
|
||||||
|
this.setLayer(id)
|
||||||
|
this.addEdges(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getNode(id: string) {
|
||||||
|
return this.nodes.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
getNodes() {
|
||||||
|
return Array.from(this.nodes.values())
|
||||||
|
}
|
||||||
|
|
||||||
|
getEdges() {
|
||||||
|
return this.edges
|
||||||
|
}
|
||||||
|
|
||||||
|
getEdgesArray() {
|
||||||
|
return Array.from(this.edges.values())
|
||||||
|
}
|
||||||
|
|
||||||
|
getLayers() {
|
||||||
|
return this.layers
|
||||||
|
}
|
||||||
|
|
||||||
|
getLayer(id: string) {
|
||||||
|
const node = this.getNode(id)
|
||||||
|
if (!node) {
|
||||||
|
throw new Error(`Node ${id} not found`)
|
||||||
|
}
|
||||||
|
return this.layers[node.layer - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
private setLayer(id: string) {
|
||||||
|
const node = this.getNode(id)
|
||||||
|
if (!node) {
|
||||||
|
throw new Error(`Node ${id} not found`)
|
||||||
|
}
|
||||||
|
if (node.layer !== undefined) {
|
||||||
|
return node.layer
|
||||||
|
}
|
||||||
|
const previousLayer = node.requirements.map((rId: string) =>
|
||||||
|
this.setLayer(rId)
|
||||||
|
)
|
||||||
|
node.layer = Math.max(...previousLayer, 0) + 1
|
||||||
|
if (this.layers.length < node.layer) {
|
||||||
|
this.layers.push(1)
|
||||||
|
} else {
|
||||||
|
this.layers[node.layer - 1] += 1
|
||||||
|
}
|
||||||
|
node.index = this.layers[node.layer - 1]
|
||||||
|
return node.layer
|
||||||
|
}
|
||||||
|
|
||||||
|
addEdges(id: string) {
|
||||||
|
const node = this.getNode(id)
|
||||||
|
if (!node) {
|
||||||
|
throw new Error(`Node ${id} not found`)
|
||||||
|
}
|
||||||
|
node.requirements.forEach((rId: string) => {
|
||||||
|
this.edges.add([rId, id])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
@@ -1,8 +1,11 @@
|
|||||||
import { buildFileCheckCmd } from '../src/commands'
|
import { buildFileCheckCmd, File } from '../src/commands'
|
||||||
|
|
||||||
describe('buildFileCheckCmd function', () => {
|
describe('buildFileCheckCmd function', () => {
|
||||||
it('builds the file check command correctly', () => {
|
it('builds the file check command correctly', () => {
|
||||||
const testcases = [
|
const testcases: {
|
||||||
|
input: File
|
||||||
|
output: string[]
|
||||||
|
}[] = [
|
||||||
{
|
{
|
||||||
input: { path: '/etc/passwd', type: 'file' },
|
input: { path: '/etc/passwd', type: 'file' },
|
||||||
output: ['test', '-f', '/etc/passwd'],
|
output: ['test', '-f', '/etc/passwd'],
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "./dist"
|
"outDir": "./dist",
|
||||||
|
"allowJs": false
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"exclude": ["node_modules", "dist"]
|
"exclude": ["node_modules", "dist"]
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ async function deactivateSessions(user, quest) {
|
|||||||
return deleteContainer(session.containerId)
|
return deleteContainer(session.containerId)
|
||||||
.catch((err) => logger.error('Failed to delete container', err))
|
.catch((err) => logger.error('Failed to delete container', err))
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
session.status = 'inactive'
|
return Session.findByIdAndUpdate(session._id, {
|
||||||
session.containerId = null
|
$set: { status: 'inactive', containerId: null },
|
||||||
return session.save()
|
}).catch((err) => logger.error('Failed to update session', err))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-1
@@ -8,6 +8,8 @@
|
|||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"outDir": "dist"
|
"outDir": "dist",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1460,7 +1460,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/jest@npm:^29.5.11":
|
"@types/jest@npm:^29.5.12":
|
||||||
version: 29.5.12
|
version: 29.5.12
|
||||||
resolution: "@types/jest@npm:29.5.12"
|
resolution: "@types/jest@npm:29.5.12"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -6512,7 +6512,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "linux-odyssey@workspace:."
|
resolution: "linux-odyssey@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/jest": "npm:^29.5.11"
|
"@types/jest": "npm:^29.5.12"
|
||||||
"@types/node": "npm:^20.10.4"
|
"@types/node": "npm:^20.10.4"
|
||||||
"@typescript-eslint/eslint-plugin": "npm:^6.14.0"
|
"@typescript-eslint/eslint-plugin": "npm:^6.14.0"
|
||||||
"@typescript-eslint/parser": "npm:^6.14.0"
|
"@typescript-eslint/parser": "npm:^6.14.0"
|
||||||
|
|||||||
Reference in new issue
Block a user