mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
feat: add exceptions to stage
This commit is contained in:
1 parent
56d96cf7a0
commit
66ce015f0e
6 files changed
+86
-1
No files matched your search
@@ -28,5 +28,6 @@ module.exports = {
|
||||
'no-plusplus': 'off',
|
||||
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
||||
'import/prefer-default-export': 'off',
|
||||
'no-restricted-syntax': ['off', 'ForOfStatement'],
|
||||
},
|
||||
}
|
||||
@@ -35,6 +35,26 @@ conditionSchema.add({
|
||||
not: conditionSchema,
|
||||
})
|
||||
|
||||
const exceptionSchema = new Schema({
|
||||
condition: {
|
||||
type: conditionSchema,
|
||||
required: false,
|
||||
},
|
||||
catchAll: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
responses: {
|
||||
type: [responseSchema],
|
||||
required: true,
|
||||
},
|
||||
hints: {
|
||||
type: [String],
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const stageSchema = new Schema({
|
||||
id: {
|
||||
type: String,
|
||||
@@ -66,6 +86,10 @@ const stageSchema = new Schema({
|
||||
type: [String],
|
||||
required: true,
|
||||
},
|
||||
exceptions: {
|
||||
type: [exceptionSchema],
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const Quest = model(
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM linuxodyssey/quest-base
|
||||
|
||||
COPY home ${HOME}
|
||||
+22
-1
@@ -1,6 +1,27 @@
|
||||
title: 複製檔案
|
||||
instruction: |
|
||||
複製檔案
|
||||
在這個關卡中,你將學習如何複製檔案。
|
||||
|
||||
requirements:
|
||||
- create
|
||||
|
||||
stages:
|
||||
- id: start
|
||||
task: 輸入 `echo start` 來開始
|
||||
condition:
|
||||
output:
|
||||
- start
|
||||
exceptions:
|
||||
- condition:
|
||||
command:
|
||||
- ^echo$
|
||||
responses:
|
||||
- type: narrative
|
||||
content:
|
||||
- 你忘記輸入 `start` 了嗎?
|
||||
- 請輸入 `echo start` 來開始
|
||||
- catchAll: true
|
||||
responses:
|
||||
- type: narrative
|
||||
content:
|
||||
- 請輸入 `echo start` 來開始
|
||||
@@ -97,6 +97,19 @@ export default class CommandHandler extends SessionHandler {
|
||||
return matches.some((m) => m === true)
|
||||
}
|
||||
|
||||
async checkException(stage) {
|
||||
const exceptions = stage.exceptions || []
|
||||
for (const exception of exceptions) {
|
||||
console.log(exception)
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (exception.condition && (await this.isMatch(exception.condition))) {
|
||||
return exception
|
||||
}
|
||||
if (exception.catchAll) return exception
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
async run() {
|
||||
this.quest = await Quest.findById(this.session.quest)
|
||||
const stages = this.getStages()
|
||||
@@ -114,6 +127,14 @@ export default class CommandHandler extends SessionHandler {
|
||||
|
||||
const stage = stages.find((_, i) => matches[i])
|
||||
if (!stage) {
|
||||
for (const s of stages) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const exception = await this.checkException(s)
|
||||
if (exception) {
|
||||
console.log('Got exception', exception)
|
||||
return this.executeException(exception)
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
const response = this.execute(stage)
|
||||
|
||||
@@ -63,4 +63,19 @@ export default class SessionHandler {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
executeException(exception) {
|
||||
const { hints, responses } = exception
|
||||
if (hints && hints.length > 0) this.session.hints.push(hints)
|
||||
|
||||
return {
|
||||
responses,
|
||||
hints,
|
||||
callback: () => {
|
||||
if (hints && hints.length > 0)
|
||||
pushToSession(this.session.id, 'hints', hints)
|
||||
pushToSession(this.session.id, 'status', this.session.status)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user