mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 11:30:12 +08:00
Merge branch 'ts-analytics' of https://github.com/linux-odyssey/linux-odyssey into ts-analytics
This commit is contained in:
commit
94ae2d7df4
33 files changed
+270
-75
No files matched your search
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
*/node_modules
|
**/node_modules
|
||||||
.git
|
.git
|
||||||
*/dist
|
*/dist
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
TESTING=true
|
||||||
|
TESTING_USERNAME=alex
|
||||||
|
TESTING_PASSWORD=Alex1234
|
||||||
|
SECRET_KEY=b1d2e917-17b9-4fce-9055-082dee6ec5d6
|
||||||
+2
-1
@@ -63,9 +63,10 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ['**/tests/**/*.js', '**/tests/**/*.ts'], // Adjust the pattern to match your test files
|
files: ['**/tests/**/*.js', '**/tests/**/*.ts', '**/*.test.ts'], // Adjust the pattern to match your test files
|
||||||
rules: {
|
rules: {
|
||||||
'import/extensions': 'off', // Turn off the rule for test files
|
'import/extensions': 'off', // Turn off the rule for test files
|
||||||
|
'import/no-extraneous-dependencies': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -12,23 +12,6 @@ jobs:
|
|||||||
uses: ./.github/workflows/ci-checks.yml
|
uses: ./.github/workflows/ci-checks.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
code_review:
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Code Review GPT
|
|
||||||
uses: mattzcarey/code-review-gpt@v0.1.4-alpha
|
|
||||||
with:
|
|
||||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
||||||
MODEL: 'gpt-3.5-turbo'
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
needs: ci-checks
|
|
||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
@@ -17,15 +17,22 @@
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Run everything (frontend, backend, db, swagger, quests):
|
Run mongoDB first:
|
||||||
|
|
||||||
docker compose build
|
docker compose -f docker-compose.dev.yml up -d db
|
||||||
docker compose up -d
|
|
||||||
|
The db will automatically restarts by Docker.
|
||||||
|
|
||||||
|
Build up dependencies:
|
||||||
|
|
||||||
|
yarn build:deps
|
||||||
|
|
||||||
|
Run dev server (frontend, backend):
|
||||||
|
|
||||||
|
yarn dev
|
||||||
|
|
||||||
If you want to enable social login, you should have OAuth client token in a `.env` file:
|
If you want to enable social login, you should have OAuth client token in a `.env` file:
|
||||||
|
|
||||||
docker compose --env-file .env up -d
|
|
||||||
|
|
||||||
### Build Quest Images
|
### Build Quest Images
|
||||||
|
|
||||||
In each quest folder, there is a `game.yml` file, which is the quest definition. And a optional `Dockerfile` to overwrite the base image. If you want to include additional files, put them in a `home` folder. The files in `home` will **not** be copied to the image automatically, you have to copy them in the `Dockerfile`.
|
In each quest folder, there is a `game.yml` file, which is the quest definition. And a optional `Dockerfile` to overwrite the base image. If you want to include additional files, put them in a `home` folder. The files in `home` will **not** be copied to the image automatically, you have to copy them in the `Dockerfile`.
|
||||||
@@ -144,4 +151,3 @@ connect to other host:
|
|||||||
list sessions:
|
list sessions:
|
||||||
|
|
||||||
yarn cli list
|
yarn cli list
|
||||||
|
|
||||||
@@ -74,6 +74,7 @@ services:
|
|||||||
|
|
||||||
db:
|
db:
|
||||||
image: mongo
|
image: mongo
|
||||||
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ services:
|
|||||||
- BASE_URL=http://app-test
|
- BASE_URL=http://app-test
|
||||||
- TESTING_USERNAME=alex
|
- TESTING_USERNAME=alex
|
||||||
- TESTING_PASSWORD=Alex1234
|
- TESTING_PASSWORD=Alex1234
|
||||||
|
# - DEBUG=cypress:*
|
||||||
depends_on:
|
depends_on:
|
||||||
- app-test
|
- app-test
|
||||||
|
|
||||||
@@ -23,8 +24,9 @@ services:
|
|||||||
target: prod
|
target: prod
|
||||||
networks:
|
networks:
|
||||||
internal:
|
internal:
|
||||||
ports:
|
# Only open the port for debugging
|
||||||
- 5173:80
|
# ports:
|
||||||
|
# - 5173:80
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
|
|
||||||
@@ -71,8 +73,8 @@ services:
|
|||||||
- MONGO_USER=user
|
- MONGO_USER=user
|
||||||
- MONGO_PASS=user-password
|
- MONGO_PASS=user-password
|
||||||
- MONGO_DB=odyssey-test
|
- MONGO_DB=odyssey-test
|
||||||
ports:
|
# ports:
|
||||||
- 27017:27017
|
# - 27017:27017
|
||||||
|
|
||||||
base:
|
base:
|
||||||
image: linuxodyssey/quest-base
|
image: linuxodyssey/quest-base
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"build:quests": "yarn workspace server build:quests"
|
"build:quests": "yarn workspace server build:quests"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@jest/globals": "^29.7.0",
|
||||||
"@types/jest": "^29.5.12",
|
"@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",
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ADMIN_USERNAME=alex
|
||||||
|
ADMIN_PASSWORD=Alex1234
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
FROM node:20-alpine as build
|
FROM node:20-alpine as build
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ./package.json yarn.lock ./
|
COPY ./package.json yarn.lock tsconfig.json ./
|
||||||
COPY packages/analytics/package.json ./packages/analytics/package.json
|
COPY packages/analytics/package.json ./packages/analytics/package.json
|
||||||
COPY packages/models/package.json ./packages/models/package.json
|
COPY packages/models/package.json ./packages/models/package.json
|
||||||
RUN yarn set version berry
|
RUN yarn install --frozen-lockfile
|
||||||
RUN yarn install
|
|
||||||
ENV HOST=0.0.0.0
|
ENV HOST=0.0.0.0
|
||||||
ENV PORT=3001
|
ENV PORT=3001
|
||||||
EXPOSE 3001
|
EXPOSE 3001
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"watch": ["src"],
|
"watch": ["src", "views"],
|
||||||
"ext": "ts,handlebars,js",
|
"ext": "ts,handlebars,js",
|
||||||
"ignore": ["src/**/*.spec.ts"],
|
"ignore": ["src/**/*.spec.ts"],
|
||||||
"exec": "node --loader ts-node/esm src/index.ts"
|
"exec": "node --loader ts-node/esm src/index.js"
|
||||||
}
|
}
|
||||||
@@ -13,14 +13,19 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@linux-odyssey/models": "*",
|
"@linux-odyssey/models": "*",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-basic-auth": "^1.2.1",
|
"express-basic-auth": "^1.2.1",
|
||||||
"express-handlebars": "^7.1.2",
|
"express-handlebars": "^7.1.2",
|
||||||
"mongoose": "^8.0.3"
|
"mongoose": "^8.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@swc/core": "^1.4.2",
|
||||||
|
"@swc/helpers": "^0.5.6",
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
"@types/node": "^20.11.20",
|
"@types/node": "^20.11.20",
|
||||||
"nodemon": "^3.1.0",
|
"nodemon": "^3.1.0",
|
||||||
|
"regenerator-runtime": "^0.14.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
import dotenv from 'dotenv'
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
dotenv.config({ path: '.env.dev' })
|
||||||
|
}
|
||||||
|
|
||||||
function getOrFailed(key: string): string {
|
function getOrFailed(key: string): string {
|
||||||
if (!process.env[key]) {
|
if (!process.env[key]) {
|
||||||
throw new Error(`Missing required environment variable: ${key}`)
|
throw new Error(`Missing required environment variable: ${key}`)
|
||||||
@@ -16,13 +22,13 @@ interface Config {
|
|||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
host: process.env.HOST || 'localhost',
|
host: process.env.HOST || 'localhost',
|
||||||
port: process.env.PORT ? parseInt(process.env.PORT) : 3001,
|
port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3001,
|
||||||
db: process.env.MONGO_URL || 'mongodb://localhost:27017/odyssey-test',
|
db: process.env.MONGO_URL || 'mongodb://localhost:27017/odyssey-test',
|
||||||
username: 'a' || getOrFailed('ADMIN_USERNAME'),
|
username: getOrFailed('ADMIN_USERNAME'),
|
||||||
password: 'a' || getOrFailed('ADMIN_PASSWORD'),
|
password: getOrFailed('ADMIN_PASSWORD'),
|
||||||
baseUrl:
|
baseUrl:
|
||||||
process.env.BASE_URL ||
|
process.env.BASE_URL ||
|
||||||
`http://${process.env.HOST || 'localhost'}:${process.env.PORT ? parseInt(process.env.PORT) : 3001}`,
|
`http://${process.env.HOST || 'localhost'}:${process.env.PORT ? parseInt(process.env.PORT, 10) : 3001}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default config
|
export default config
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { questList } from '../models/quests.ts'
|
import { questList } from '../models/quests.js'
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export async function questListController(req: any, res: any) {
|
export async function questListController(req: any, res: any) {
|
||||||
const quests = await questList()
|
const quests = await questList()
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
import Pagination from '../models/pagination.ts'
|
import Pagination from '../models/pagination.ts'
|
||||||
import { userList, userDetail, idToUser } from '../models/users.js'
|
import { userList, userDetail, idToUser } from '../models/users.js'
|
||||||
|
=======
|
||||||
|
import Pagination from '../models/pagination.js'
|
||||||
|
import { userList } from '../models/users.js'
|
||||||
|
>>>>>>> bb4a11b20c8fdad8459ac3b7a0fdb8d9d9221e31
|
||||||
|
|
||||||
export async function userListController(req: any, res: any) {
|
export async function userListController(req: any, res: any) {
|
||||||
const { nextKey, order } = req.query
|
const { nextKey, order } = req.query
|
||||||
@@ -20,6 +25,7 @@ export async function userListController(req: any, res: any) {
|
|||||||
res.status(500).send('Error fetching user data')
|
res.status(500).send('Error fetching user data')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<<<<<<< HEAD
|
||||||
export async function userDetailController(req: any, res: any) {
|
export async function userDetailController(req: any, res: any) {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const sessions = await userDetail(id)
|
const sessions = await userDetail(id)
|
||||||
@@ -31,3 +37,5 @@ export async function userDetailController(req: any, res: any) {
|
|||||||
res.status(500).send('Error fetching user data')
|
res.status(500).send('Error fetching user data')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
>>>>>>> bb4a11b20c8fdad8459ac3b7a0fdb8d9d9221e31
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
@@ -9,5 +8,8 @@
|
|||||||
"allowImportingTsExtensions": true
|
"allowImportingTsExtensions": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"exclude": ["node_modules", "dist"]
|
"exclude": ["node_modules", "dist"],
|
||||||
|
"ts-node": {
|
||||||
|
"swc": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import File from '../src/file'
|
import { describe, test, expect } from '@jest/globals'
|
||||||
|
import File from '../src/file.js'
|
||||||
|
|
||||||
describe('File', () => {
|
describe('File', () => {
|
||||||
let file: File
|
let file: File
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { describe, test, expect } from '@jest/globals'
|
||||||
import FileGraph from '../src/fileGraph.js'
|
import FileGraph from '../src/fileGraph.js'
|
||||||
import FileNode from '../src/fileNode.js'
|
import FileNode from '../src/fileNode.js'
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { describe, test, expect } from '@jest/globals'
|
||||||
import { DuplicateItemError, ParentNotExistsError } from '../src/errors.js'
|
import { DuplicateItemError, ParentNotExistsError } from '../src/errors.js'
|
||||||
import FileNode from '../src/fileNode.js'
|
import FileNode from '../src/fileNode.js'
|
||||||
import { FileObject } from '../src/file.js'
|
import { FileObject } from '../src/file.js'
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { test, expect } from '@jest/globals'
|
||||||
import { isValidEmail, isValidUsername } from '../src/auth.js'
|
import { isValidEmail, isValidUsername } from '../src/auth.js'
|
||||||
|
|
||||||
test('check valid username', () => {
|
test('check valid username', () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { describe, it, expect } from '@jest/globals'
|
||||||
import { buildFileCheckCmd, File } from '../src/commands.js'
|
import { buildFileCheckCmd, File } from '../src/commands.js'
|
||||||
|
|
||||||
describe('buildFileCheckCmd function', () => {
|
describe('buildFileCheckCmd function', () => {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { describe, it, expect } from '@jest/globals'
|
||||||
import DAG from '../src/dag.js'
|
import DAG from '../src/dag.js'
|
||||||
|
|
||||||
describe('dag layers', () => {
|
describe('dag layers', () => {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import { get } from './utils/env.js'
|
|||||||
|
|
||||||
// Import dotenv and load ../.env
|
// Import dotenv and load ../.env
|
||||||
dotenv.config({ path: '../.env' })
|
dotenv.config({ path: '../.env' })
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
dotenv.config({ path: '../.env.dev' })
|
||||||
|
}
|
||||||
|
|
||||||
function getTrustProxies(key: string): string[] {
|
function getTrustProxies(key: string): string[] {
|
||||||
const value = process.env[key]
|
const value = process.env[key]
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function createContainer(name, questId) {
|
|||||||
const { hostPwd, mountQuest } = config.docker
|
const { hostPwd, mountQuest } = config.docker
|
||||||
if (!config.isProduction && hostPwd && mountQuest === questId) {
|
if (!config.isProduction && hostPwd && mountQuest === questId) {
|
||||||
logger.info('Mounting quest folder', mountQuest)
|
logger.info('Mounting quest folder', mountQuest)
|
||||||
option.HostConfig.Binds = [
|
option.HostConfig!.Binds = [
|
||||||
`${hostPwd.replace(/\\/g, '/')}/quests/${mountQuest}/home:/home/commander`,
|
`${hostPwd.replace(/\\/g, '/')}/quests/${mountQuest}/home:/home/commander`,
|
||||||
`${hostPwd.replace(/\\/g, '/')}/packages/container:/usr/local/lib/container`,
|
`${hostPwd.replace(/\\/g, '/')}/packages/container:/usr/local/lib/container`,
|
||||||
]
|
]
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ FROM cypress/browsers
|
|||||||
WORKDIR /e2e
|
WORKDIR /e2e
|
||||||
COPY package.json yarn.lock ./
|
COPY package.json yarn.lock ./
|
||||||
COPY tests/package.json ./tests/package.json
|
COPY tests/package.json ./tests/package.json
|
||||||
RUN yarn install
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
COPY quests ./quests
|
COPY quests ./quests
|
||||||
COPY tests ./tests
|
COPY tests ./tests
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
const { defineConfig } = require('cypress')
|
import { defineConfig } from 'cypress'
|
||||||
const process = require('process')
|
import process from 'process'
|
||||||
require('dotenv').config({ path: '../.env' })
|
import dotenv from 'dotenv'
|
||||||
|
import fs from 'fs' // Import fs module
|
||||||
|
|
||||||
|
dotenv.config({ path: '../.env.dev' })
|
||||||
|
dotenv.config({ path: '../.env' })
|
||||||
|
|
||||||
const getConfig = (key, defaultValue) => {
|
const getConfig = (key, defaultValue) => {
|
||||||
return process.env[key] || defaultValue
|
return process.env[key] || defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrFail = (key) => {
|
const getOrFail = (key) => {
|
||||||
const value = getConfig(key)
|
const value = getConfig(key, null)
|
||||||
if (!value) {
|
if (!value) {
|
||||||
throw new Error(`Missing required environment variable ${key}`)
|
throw new Error(`Missing required environment variable ${key}`)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = defineConfig({
|
// Check if the .env file exists
|
||||||
|
const EnableoAuth = fs.existsSync('../.env')
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
e2e: {
|
e2e: {
|
||||||
baseUrl: getConfig('BASE_URL', 'http://localhost:5173'),
|
baseUrl: getConfig('BASE_URL', 'http://localhost:5173'),
|
||||||
viewportWidth: 1920,
|
viewportWidth: 1920,
|
||||||
@@ -28,13 +35,13 @@ module.exports = defineConfig({
|
|||||||
defaultAccount: getOrFail('TESTING_USERNAME'),
|
defaultAccount: getOrFail('TESTING_USERNAME'),
|
||||||
defaultPassword: getOrFail('TESTING_PASSWORD'),
|
defaultPassword: getOrFail('TESTING_PASSWORD'),
|
||||||
isCHVersion: true,
|
isCHVersion: true,
|
||||||
|
EnableoAuth, // Add the EnableoAuth variable here
|
||||||
// google_username: process.env.GOOGLE_USERNAME,
|
// google_username: process.env.GOOGLE_USERNAME,
|
||||||
// google_password: process.env.GOOGLE_PASSWORD,
|
// google_password: process.env.GOOGLE_PASSWORD,
|
||||||
// google_client_id: process.env.GOOGLE_CLIENT_ID,
|
// google_client_id: process.env.GOOGLE_CLIENT_ID,
|
||||||
// google_client_secret: process.env.GOOGLE_CLIENT_SECRET,
|
|
||||||
// github_username: process.env.GITHUB_USERNAME,
|
// github_username: process.env.GITHUB_USERNAME,
|
||||||
// github_password: process.env.GITHUB_PASSWORD,
|
// github_password: process.env.GITHUB_PASSWORD,
|
||||||
// github_client_id: process.env.GITHUB_CLIENT_ID,
|
// github_client_id: process.env.GITHUB_CLIENT_ID,
|
||||||
// github_client_secret: process.env.GITHUB_CLIENT_SECRET,
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/// <reference types="cypress" />
|
|
||||||
export default function checkLoginUI() {
|
export default function checkLoginUI() {
|
||||||
cy.get('#title').should('contain', 'Linux Odyssey').and('be.visible')
|
cy.get('#title').should('contain', 'Linux Odyssey').and('be.visible')
|
||||||
cy.CheckPlaceholder('#password', '密碼', 'Password')
|
cy.CheckPlaceholder('#password', '密碼', 'Password')
|
||||||
@@ -37,6 +36,7 @@ describe('example helloworld app', () => {
|
|||||||
cy.CheckTextElement('#SwitchtoRegister', '註冊', 'Sign up')
|
cy.CheckTextElement('#SwitchtoRegister', '註冊', 'Sign up')
|
||||||
})
|
})
|
||||||
it('Check social account UI', () => {
|
it('Check social account UI', () => {
|
||||||
|
if (Cypress.env('EnableoAuth')) {
|
||||||
cy.CheckTextElement(
|
cy.CheckTextElement(
|
||||||
'#GoogleLogin',
|
'#GoogleLogin',
|
||||||
'以 Google 繼續',
|
'以 Google 繼續',
|
||||||
@@ -48,6 +48,7 @@ describe('example helloworld app', () => {
|
|||||||
'以 GitHub 繼續',
|
'以 GitHub 繼續',
|
||||||
'Continue with GitHub'
|
'Continue with GitHub'
|
||||||
)
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
it('Check login fail', () => {
|
it('Check login fail', () => {
|
||||||
cy.LoginWithPassword('dddd', '123456')
|
cy.LoginWithPassword('dddd', '123456')
|
||||||
@@ -96,20 +97,18 @@ describe('example helloworld app', () => {
|
|||||||
cy.CheckTextElement('#tasks', '任務', 'Tasks:')
|
cy.CheckTextElement('#tasks', '任務', 'Tasks:')
|
||||||
})
|
})
|
||||||
it('Check Terminal', () => {
|
it('Check Terminal', () => {
|
||||||
cy.get('#terminal', { timeout: 20000 }).within(($terminal) => {
|
// cy.get('#terminal', { timeout: 20000 }).within(($terminal) => {
|
||||||
cy.get($terminal).should('be.visible')
|
// cy.get($terminal).should('be.visible')
|
||||||
|
cy.get('#terminal', { timeout: 20000 }).should('be.visible')
|
||||||
cy.get('svg[data-icon="terminal"]').should('be.visible')
|
cy.get('svg[data-icon="terminal"]').should('be.visible')
|
||||||
cy.CheckTextElement('#Terminal', '終端機', 'Terminal')
|
cy.CheckTextElement('#Terminal', '終端機', 'Terminal')
|
||||||
cy.get('@Terminaltextbox')
|
cy.get('@Terminaltextbox')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('contain', 'commander:~ $')
|
.and('contain', 'commander:~ $')
|
||||||
})
|
})
|
||||||
})
|
|
||||||
it('Check Hint Part', () => {
|
it('Check Hint Part', () => {
|
||||||
cy.get('#hint', { timeout: 20000 }).within(($hint) => {
|
cy.get('#hint', { timeout: 20000 }).should('be.visible')
|
||||||
cy.get($hint).should('be.visible')
|
|
||||||
cy.get('svg[data-icon="lightbulb"]').should('be.visible')
|
cy.get('svg[data-icon="lightbulb"]').should('be.visible')
|
||||||
})
|
|
||||||
cy.CheckTextElement('#hint', '提示', 'Hint')
|
cy.CheckTextElement('#hint', '提示', 'Hint')
|
||||||
})
|
})
|
||||||
it('Check File TreeChart', () => {
|
it('Check File TreeChart', () => {
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/// <reference types="cypress" />
|
|
||||||
describe('Complete quests with only commands', () => {
|
describe('Complete quests with only commands', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.PrepareForGame()
|
cy.PrepareForGame()
|
||||||
@@ -1,7 +1,38 @@
|
|||||||
|
/* eslint-disable no-undef */
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
/// <reference types="cypress" />
|
||||||
import '@testing-library/cypress/add-commands'
|
import '@testing-library/cypress/add-commands'
|
||||||
|
|
||||||
|
declare const expect: Chai.ExpectStatic
|
||||||
|
declare global {
|
||||||
|
namespace Cypress {
|
||||||
|
interface Chainable {
|
||||||
|
LoginWithPassword(username: string, password: string): Chainable<string>
|
||||||
|
PrepareForGame(): Chainable<void>
|
||||||
|
InitTerminal(): Chainable<void>
|
||||||
|
typeInCommand(command: string): Chainable<string>
|
||||||
|
getQuestInfo(id: string): Chainable<JQuery<HTMLParagraphElement>>
|
||||||
|
checkHint(index: number, total: number): Chainable<number> // 修改類型
|
||||||
|
checkTaskInit(): Chainable<void>
|
||||||
|
waitUntilActive(last?: boolean): Chainable<void> // 注意小寫boolean,並且變量名應該是小寫
|
||||||
|
checkPending(): Chainable<void>
|
||||||
|
CompleteStageWithCommands(stagename: string): Chainable<string>
|
||||||
|
CheckTextElement(
|
||||||
|
id: string,
|
||||||
|
chText: string,
|
||||||
|
enText: string
|
||||||
|
): Chainable<string>
|
||||||
|
CheckPlaceholder(
|
||||||
|
id: string,
|
||||||
|
chText: string,
|
||||||
|
enText: string
|
||||||
|
): Chainable<string>
|
||||||
|
CheckTreeElement(element: string): Chainable<string>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Cypress.Commands.add('LoginWithPassword', (username, password) => {
|
Cypress.Commands.add('LoginWithPassword', (username, password) => {
|
||||||
cy.clearAllCookies({ domain: null })
|
cy.clearAllCookies()
|
||||||
cy.visit('/login')
|
cy.visit('/login')
|
||||||
cy.get('#username').type(username)
|
cy.get('#username').type(username)
|
||||||
cy.get('#password').type(password)
|
cy.get('#password').type(password)
|
||||||
@@ -10,7 +41,7 @@ Cypress.Commands.add('LoginWithPassword', (username, password) => {
|
|||||||
Cypress.Commands.add('PrepareForGame', () => {
|
Cypress.Commands.add('PrepareForGame', () => {
|
||||||
cy.visit('/')
|
cy.visit('/')
|
||||||
// make sure the login page is loaded
|
// make sure the login page is loaded
|
||||||
cy.url().should('satisfy', (elements) => {
|
cy.url().should('satisfy', (elements: string) => {
|
||||||
const text = elements
|
const text = elements
|
||||||
return text.includes('login') || text.includes('register')
|
return text.includes('login') || text.includes('register')
|
||||||
})
|
})
|
||||||
@@ -70,9 +101,9 @@ Cypress.Commands.add('waitUntilActive', (last = false) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (value === 'pending' && !last) {
|
if (value === 'pending' && !last) {
|
||||||
cy.log(last)
|
cy.log(`${last}`)
|
||||||
cy.typeInCommand('{enter}')
|
cy.typeInCommand('{enter}')
|
||||||
cy.waitUntilActive()
|
cy.waitUntilActive(last) // Pass `last` parameter
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -90,8 +121,7 @@ Cypress.Commands.add('CompleteStageWithCommands', (stagename) => {
|
|||||||
cy.CheckTextElement('#reset', '重來', 'Reset').click()
|
cy.CheckTextElement('#reset', '重來', 'Reset').click()
|
||||||
cy.checkTaskInit()
|
cy.checkTaskInit()
|
||||||
cy.InitTerminal()
|
cy.InitTerminal()
|
||||||
cy.readFile(`../quests/${stagename}/answer.sh`, 'utf-8').as('answers')
|
cy.readFile(`../quests/${stagename}/answer.sh`, 'utf-8').then((answers) => {
|
||||||
cy.get('@answers').then((answers) => {
|
|
||||||
const answerarr = answers.split('\n')
|
const answerarr = answers.split('\n')
|
||||||
for (const element of answerarr) {
|
for (const element of answerarr) {
|
||||||
cy.typeInCommand(`${element}{enter}`)
|
cy.typeInCommand(`${element}{enter}`)
|
||||||
@@ -109,13 +139,11 @@ Cypress.Commands.add('CompleteStageWithCommands', (stagename) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
Cypress.Commands.add('CheckTextElement', (id, chText, enText) => {
|
Cypress.Commands.add('CheckTextElement', (id, chText, enText) => {
|
||||||
cy.get(id, { timeout: 50000 }).within(($element) => {
|
|
||||||
if (Cypress.env('isCHVersion')) {
|
if (Cypress.env('isCHVersion')) {
|
||||||
cy.get($element).should('contain', chText).and('be.visible')
|
cy.get(id, { timeout: 50000 }).should('contain', chText).and('be.visible')
|
||||||
} else {
|
} else {
|
||||||
cy.get($element).should('contain', enText).and('be.visible')
|
cy.get(id, { timeout: 50000 }).should('contain', enText).and('be.visible')
|
||||||
}
|
}
|
||||||
})
|
|
||||||
})
|
})
|
||||||
Cypress.Commands.add('CheckPlaceholder', (id, chText, enText) => {
|
Cypress.Commands.add('CheckPlaceholder', (id, chText, enText) => {
|
||||||
cy.get(id)
|
cy.get(id)
|
||||||
File renamed without changes.
+9
-3
@@ -3,14 +3,20 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"type": "commonjs",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "TESTING_USERNAME=alex TESTING_PASSWORD=Alex1234 cypress run",
|
"test": "yarn cypress run",
|
||||||
"test:open": "TESTING_USERNAME=alex TESTING_PASSWORD=Alex1234 cypress open"
|
"test:open": "yarn cypress open"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@testing-library/cypress": "^10.0.1",
|
"@testing-library/cypress": "^10.0.1",
|
||||||
"cypress": "^13.5.1",
|
"cypress": "^13.5.1",
|
||||||
"dotenv": "^16.3.1"
|
"dotenv": "^16.3.1",
|
||||||
|
"ts-node": "^10.9.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/dotenv": "^8.2.0",
|
||||||
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["es5", "dom"],
|
||||||
|
"types": ["cypress", "node", "@testing-library/cypress"],
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts"],
|
||||||
|
"exclude": ["dist"]
|
||||||
|
}
|
||||||
@@ -913,6 +913,92 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
|
||||||
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
|
integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==
|
||||||
|
|
||||||
|
"@swc/core-darwin-arm64@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.2.tgz#3b5677c5b9c5a7a91d953b96cd603c94064e2835"
|
||||||
|
integrity sha512-1uSdAn1MRK5C1m/TvLZ2RDvr0zLvochgrZ2xL+lRzugLlCTlSA+Q4TWtrZaOz+vnnFVliCpw7c7qu0JouhgQIw==
|
||||||
|
|
||||||
|
"@swc/core-darwin-x64@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.2.tgz#bbc8bbf420389b12541151255a50f319cc17ef96"
|
||||||
|
integrity sha512-TYD28+dCQKeuxxcy7gLJUCFLqrwDZnHtC2z7cdeGfZpbI2mbfppfTf2wUPzqZk3gEC96zHd4Yr37V3Tvzar+lQ==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm-gnueabihf@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.2.tgz#aa9a18f130820717df08c9dd882043fc47e8d35a"
|
||||||
|
integrity sha512-Eyqipf7ZPGj0vplKHo8JUOoU1un2sg5PjJMpEesX0k+6HKE2T8pdyeyXODN0YTFqzndSa/J43EEPXm+rHAsLFQ==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-gnu@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.2.tgz#5ef1de0ca7cc3a034aa3a1c3c1794b78e6ca207e"
|
||||||
|
integrity sha512-wZn02DH8VYPv3FC0ub4my52Rttsus/rFw+UUfzdb3tHMHXB66LqN+rR0ssIOZrH6K+VLN6qpTw9VizjyoH0BxA==
|
||||||
|
|
||||||
|
"@swc/core-linux-arm64-musl@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.2.tgz#5dfd2a8c0483770a307de0ccb6019a082ff0d902"
|
||||||
|
integrity sha512-3G0D5z9hUj9bXNcwmA1eGiFTwe5rWkuL3DsoviTj73TKLpk7u64ND0XjEfO0huVv4vVu9H1jodrKb7nvln/dlw==
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-gnu@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.2.tgz#314aa76b7c1208e315e3156ab57b7188fb605bc2"
|
||||||
|
integrity sha512-LFxn9U8cjmYHw3jrdPNqPAkBGglKE3tCZ8rA7hYyp0BFxuo7L2ZcEnPm4RFpmSCCsExFH+LEJWuMGgWERoktvg==
|
||||||
|
|
||||||
|
"@swc/core-linux-x64-musl@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.2.tgz#b2b226657f6a8d48f561cb3dbe2d414cfbafe467"
|
||||||
|
integrity sha512-dp0fAmreeVVYTUcb4u9njTPrYzKnbIH0EhH2qvC9GOYNNREUu2GezSIDgonjOXkHiTCvopG4xU7y56XtXj4VrQ==
|
||||||
|
|
||||||
|
"@swc/core-win32-arm64-msvc@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.2.tgz#582f79fa328ce0f426ab8313b3d881e7315fab2f"
|
||||||
|
integrity sha512-HlVIiLMQkzthAdqMslQhDkoXJ5+AOLUSTV6fm6shFKZKqc/9cJvr4S8UveNERL9zUficA36yM3bbfo36McwnvQ==
|
||||||
|
|
||||||
|
"@swc/core-win32-ia32-msvc@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.2.tgz#15c8289e1c18857f79b9b888100ab1f871bf58f6"
|
||||||
|
integrity sha512-WCF8faPGjCl4oIgugkp+kL9nl3nUATlzKXCEGFowMEmVVCFM0GsqlmGdPp1pjZoWc9tpYanoXQDnp5IvlDSLhA==
|
||||||
|
|
||||||
|
"@swc/core-win32-x64-msvc@1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.2.tgz#c999ca7b68124d058b40a1431cdd6f56779670d5"
|
||||||
|
integrity sha512-oV71rwiSpA5xre2C5570BhCsg1HF97SNLsZ/12xv7zayGzqr3yvFALFJN8tHKpqUdCB4FGPjoP3JFdV3i+1wUw==
|
||||||
|
|
||||||
|
"@swc/core@^1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.4.2.tgz#310b0d5e93e47ca72f54150c8f9efcb434c39b17"
|
||||||
|
integrity sha512-vWgY07R/eqj1/a0vsRKLI9o9klGZfpLNOVEnrv4nrccxBgYPjcf22IWwAoaBJ+wpA7Q4fVjCUM8lP0m01dpxcg==
|
||||||
|
dependencies:
|
||||||
|
"@swc/counter" "^0.1.2"
|
||||||
|
"@swc/types" "^0.1.5"
|
||||||
|
optionalDependencies:
|
||||||
|
"@swc/core-darwin-arm64" "1.4.2"
|
||||||
|
"@swc/core-darwin-x64" "1.4.2"
|
||||||
|
"@swc/core-linux-arm-gnueabihf" "1.4.2"
|
||||||
|
"@swc/core-linux-arm64-gnu" "1.4.2"
|
||||||
|
"@swc/core-linux-arm64-musl" "1.4.2"
|
||||||
|
"@swc/core-linux-x64-gnu" "1.4.2"
|
||||||
|
"@swc/core-linux-x64-musl" "1.4.2"
|
||||||
|
"@swc/core-win32-arm64-msvc" "1.4.2"
|
||||||
|
"@swc/core-win32-ia32-msvc" "1.4.2"
|
||||||
|
"@swc/core-win32-x64-msvc" "1.4.2"
|
||||||
|
|
||||||
|
"@swc/counter@^0.1.2":
|
||||||
|
version "0.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9"
|
||||||
|
integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==
|
||||||
|
|
||||||
|
"@swc/helpers@^0.5.6":
|
||||||
|
version "0.5.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.6.tgz#d16d8566b7aea2bef90d059757e2d77f48224160"
|
||||||
|
integrity sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.4.0"
|
||||||
|
|
||||||
|
"@swc/types@^0.1.5":
|
||||||
|
version "0.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a"
|
||||||
|
integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==
|
||||||
|
|
||||||
"@testing-library/cypress@^10.0.1":
|
"@testing-library/cypress@^10.0.1":
|
||||||
version "10.0.1"
|
version "10.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-10.0.1.tgz#15abae0edb83237316ec6d07e152b71a50b38387"
|
resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-10.0.1.tgz#15abae0edb83237316ec6d07e152b71a50b38387"
|
||||||
@@ -1043,6 +1129,13 @@
|
|||||||
"@types/docker-modem" "*"
|
"@types/docker-modem" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/dotenv@^8.2.0":
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/dotenv/-/dotenv-8.2.0.tgz#5cd64710c3c98e82d9d15844375a33bf1b45d053"
|
||||||
|
integrity sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==
|
||||||
|
dependencies:
|
||||||
|
dotenv "*"
|
||||||
|
|
||||||
"@types/express-serve-static-core@^4.17.33":
|
"@types/express-serve-static-core@^4.17.33":
|
||||||
version "4.17.43"
|
version "4.17.43"
|
||||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54"
|
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54"
|
||||||
@@ -1169,6 +1262,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~5.26.4"
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
|
"@types/node@^20.11.20":
|
||||||
|
version "20.11.21"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.21.tgz#ad67e65652f7be15686e2df87a38076a81c5e9c5"
|
||||||
|
integrity sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==
|
||||||
|
dependencies:
|
||||||
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
"@types/oauth@*":
|
"@types/oauth@*":
|
||||||
version "0.9.4"
|
version "0.9.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.4.tgz#dcbab5efa2f34f312b915f80685760ccc8111e0a"
|
resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.4.tgz#dcbab5efa2f34f312b915f80685760ccc8111e0a"
|
||||||
@@ -2777,7 +2877,7 @@ dompurify@^3.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.9.tgz#b3f362f24b99f53498c75d43ecbd784b0b3ad65e"
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.9.tgz#b3f362f24b99f53498c75d43ecbd784b0b3ad65e"
|
||||||
integrity sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==
|
integrity sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==
|
||||||
|
|
||||||
dotenv@^16.3.1, dotenv@^16.4.1:
|
dotenv@*, dotenv@^16.3.1, dotenv@^16.4.1, dotenv@^16.4.5:
|
||||||
version "16.4.5"
|
version "16.4.5"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
||||||
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
||||||
@@ -5366,6 +5466,22 @@ nodemon@^3.0.1:
|
|||||||
touch "^3.1.0"
|
touch "^3.1.0"
|
||||||
undefsafe "^2.0.5"
|
undefsafe "^2.0.5"
|
||||||
|
|
||||||
|
nodemon@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.0.tgz#ff7394f2450eb6a5e96fe4180acd5176b29799c9"
|
||||||
|
integrity sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==
|
||||||
|
dependencies:
|
||||||
|
chokidar "^3.5.2"
|
||||||
|
debug "^4"
|
||||||
|
ignore-by-default "^1.0.1"
|
||||||
|
minimatch "^3.1.2"
|
||||||
|
pstree.remy "^1.1.8"
|
||||||
|
semver "^7.5.3"
|
||||||
|
simple-update-notifier "^2.0.0"
|
||||||
|
supports-color "^5.5.0"
|
||||||
|
touch "^3.1.0"
|
||||||
|
undefsafe "^2.0.5"
|
||||||
|
|
||||||
nopt@^5.0.0:
|
nopt@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
|
resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
|
||||||
@@ -5988,7 +6104,7 @@ readdirp@~3.6.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
picomatch "^2.2.1"
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
regenerator-runtime@^0.14.0:
|
regenerator-runtime@^0.14.0, regenerator-runtime@^0.14.1:
|
||||||
version "0.14.1"
|
version "0.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||||
@@ -6833,7 +6949,7 @@ tslib@2.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||||
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||||
|
|
||||||
tslib@^2.1.0, tslib@^2.6.2:
|
tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||||
|
|||||||
Reference in new issue
Block a user