Resolve #5755
This commit is contained in:
parent
36b9a0d42f
commit
11cc9cbc7c
28 changed files with 195 additions and 63 deletions
|
@ -481,6 +481,8 @@ descendingOrder: "降順"
|
||||||
scratchpad: "スクラッチパッド"
|
scratchpad: "スクラッチパッド"
|
||||||
scratchpadDescription: "スクラッチパッドは、AiScriptの実験環境を提供します。Misskeyと対話するコードの記述、実行、結果の確認ができます。"
|
scratchpadDescription: "スクラッチパッドは、AiScriptの実験環境を提供します。Misskeyと対話するコードの記述、実行、結果の確認ができます。"
|
||||||
output: "出力"
|
output: "出力"
|
||||||
|
script: "スクリプト"
|
||||||
|
disablePagesScript: "Pagesのスクリプトを無効にする"
|
||||||
|
|
||||||
_theme:
|
_theme:
|
||||||
explore: "テーマを探す"
|
explore: "テーマを探す"
|
||||||
|
@ -813,6 +815,9 @@ _pages:
|
||||||
message: "押したときに表示するメッセージ"
|
message: "押したときに表示するメッセージ"
|
||||||
variable: "送信する変数"
|
variable: "送信する変数"
|
||||||
no-variable: "なし"
|
no-variable: "なし"
|
||||||
|
callAiScript: "AiScript呼び出し"
|
||||||
|
_callAiScript:
|
||||||
|
functionName: "関数名"
|
||||||
|
|
||||||
radioButton: "選択肢"
|
radioButton: "選択肢"
|
||||||
_radioButton:
|
_radioButton:
|
||||||
|
@ -975,6 +980,7 @@ _pages:
|
||||||
_splitStrByLine:
|
_splitStrByLine:
|
||||||
arg1: "テキスト"
|
arg1: "テキスト"
|
||||||
ref: "変数"
|
ref: "変数"
|
||||||
|
aiScriptVar: "AiScript変数"
|
||||||
fn: "関数"
|
fn: "関数"
|
||||||
_fn:
|
_fn:
|
||||||
slots: "スロット"
|
slots: "スロット"
|
||||||
|
|
14
migration/1586708940386-pageAiScript.ts
Normal file
14
migration/1586708940386-pageAiScript.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class pageAiScript1586708940386 implements MigrationInterface {
|
||||||
|
name = 'pageAiScript1586708940386'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "page" ADD "script" character varying(16384) NOT NULL DEFAULT ''`, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "script"`, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,7 @@
|
||||||
"@koa/cors": "3.0.0",
|
"@koa/cors": "3.0.0",
|
||||||
"@koa/multer": "2.0.2",
|
"@koa/multer": "2.0.2",
|
||||||
"@koa/router": "8.0.8",
|
"@koa/router": "8.0.8",
|
||||||
"@syuilo/aiscript": "0.1.2",
|
"@syuilo/aiscript": "0.1.4",
|
||||||
"@types/bcryptjs": "2.4.2",
|
"@types/bcryptjs": "2.4.2",
|
||||||
"@types/bull": "3.12.1",
|
"@types/bull": "3.12.1",
|
||||||
"@types/cbor": "5.0.0",
|
"@types/cbor": "5.0.0",
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default Vue.extend({
|
||||||
text: this.script.interpolate(this.value.content)
|
text: this.script.interpolate(this.value.content)
|
||||||
});
|
});
|
||||||
} else if (this.value.action === 'resetRandom') {
|
} else if (this.value.action === 'resetRandom') {
|
||||||
this.script.aiScript.updateRandomSeed(Math.random());
|
this.script.aoiScript.updateRandomSeed(Math.random());
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
} else if (this.value.action === 'pushEvent') {
|
} else if (this.value.action === 'pushEvent') {
|
||||||
this.$root.api('page-push', {
|
this.$root.api('page-push', {
|
||||||
|
@ -43,6 +43,8 @@ export default Vue.extend({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
text: this.script.interpolate(this.value.message)
|
text: this.script.interpolate(this.value.message)
|
||||||
});
|
});
|
||||||
|
} else if (this.value.action === 'callAiScript') {
|
||||||
|
this.script.callAiScript(this.value.fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
this.script.aoiScript.updatePageVar(this.value.name, this.v);
|
||||||
this.script.eval();
|
this.script.eval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,57 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import i18n from '../../i18n';
|
import { AiScript, parse, values } from '@syuilo/aiscript';
|
||||||
import { faHeart as faHeartS } from '@fortawesome/free-solid-svg-icons';
|
import { faHeart as faHeartS } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faHeart } from '@fortawesome/free-regular-svg-icons';
|
import { faHeart } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import i18n from '../../i18n';
|
||||||
import XBlock from './page.block.vue';
|
import XBlock from './page.block.vue';
|
||||||
import { ASEvaluator } from '../../scripts/aoiscript/evaluator';
|
import { ASEvaluator } from '../../scripts/aoiscript/evaluator';
|
||||||
import { collectPageVars } from '../../scripts/collect-page-vars';
|
import { collectPageVars } from '../../scripts/collect-page-vars';
|
||||||
import { url } from '../../config';
|
import { url } from '../../config';
|
||||||
|
|
||||||
class Script {
|
class Script {
|
||||||
public aiScript: ASEvaluator;
|
public aoiScript: ASEvaluator;
|
||||||
private onError: any;
|
private onError: any;
|
||||||
public vars: Record<string, any>;
|
public vars: Record<string, any>;
|
||||||
public page: Record<string, any>;
|
public page: Record<string, any>;
|
||||||
|
|
||||||
constructor(page, aiScript, onError) {
|
constructor(page, aoiScript, onError, cb) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.aiScript = aiScript;
|
this.aoiScript = aoiScript;
|
||||||
this.onError = onError;
|
this.onError = onError;
|
||||||
this.eval();
|
|
||||||
|
if (this.page.script) {
|
||||||
|
let ast;
|
||||||
|
try {
|
||||||
|
ast = parse(this.page.script);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
/*this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: 'Syntax error :('
|
||||||
|
});*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.aoiScript.aiscript.exec(ast).then(() => {
|
||||||
|
this.eval();
|
||||||
|
cb();
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
/*this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: e
|
||||||
|
});*/
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.eval();
|
||||||
|
cb();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public eval() {
|
public eval() {
|
||||||
try {
|
try {
|
||||||
this.vars = this.aiScript.evaluateVars();
|
this.vars = this.aoiScript.evaluateVars();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.onError(e);
|
this.onError(e);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +69,10 @@ class Script {
|
||||||
return v == null ? 'NULL' : v.toString();
|
return v == null ? 'NULL' : v.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public callAiScript(fn: string) {
|
||||||
|
this.aoiScript.aiscript.execFn(this.aoiScript.aiscript.scope.get(fn), []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
@ -67,14 +98,21 @@ export default Vue.extend({
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
const pageVars = this.getPageVars();
|
const pageVars = this.getPageVars();
|
||||||
this.script = new Script(this.page, new ASEvaluator(this.page.variables, pageVars, {
|
|
||||||
|
const s = new Script(this.page, new ASEvaluator(this, this.page.variables, pageVars, {
|
||||||
randomSeed: Math.random(),
|
randomSeed: Math.random(),
|
||||||
visitor: this.$store.state.i,
|
visitor: this.$store.state.i,
|
||||||
page: this.page,
|
page: this.page,
|
||||||
url: url
|
url: url
|
||||||
}), e => {
|
}), e => {
|
||||||
console.dir(e);
|
console.dir(e);
|
||||||
|
}, () => {
|
||||||
|
this.script = s;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
s.aoiScript.aiscript.scope.opts.onUpdated = (name, value) => {
|
||||||
|
s.eval();
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<option value="dialog">{{ $t('_pages.blocks._button._action.dialog') }}</option>
|
<option value="dialog">{{ $t('_pages.blocks._button._action.dialog') }}</option>
|
||||||
<option value="resetRandom">{{ $t('_pages.blocks._button._action.resetRandom') }}</option>
|
<option value="resetRandom">{{ $t('_pages.blocks._button._action.resetRandom') }}</option>
|
||||||
<option value="pushEvent">{{ $t('_pages.blocks._button._action.pushEvent') }}</option>
|
<option value="pushEvent">{{ $t('_pages.blocks._button._action.pushEvent') }}</option>
|
||||||
|
<option value="callAiScript">{{ $t('_pages.blocks._button._action.callAiScript') }}</option>
|
||||||
</mk-select>
|
</mk-select>
|
||||||
<template v-if="value.action === 'dialog'">
|
<template v-if="value.action === 'dialog'">
|
||||||
<mk-input v-model="value.content"><span>{{ $t('_pages.blocks._button._action._dialog.content') }}</span></mk-input>
|
<mk-input v-model="value.content"><span>{{ $t('_pages.blocks._button._action._dialog.content') }}</span></mk-input>
|
||||||
|
@ -20,15 +21,18 @@
|
||||||
<mk-select v-model="value.var">
|
<mk-select v-model="value.var">
|
||||||
<template #label>{{ $t('_pages.blocks._button._action._pushEvent.variable') }}</template>
|
<template #label>{{ $t('_pages.blocks._button._action._pushEvent.variable') }}</template>
|
||||||
<option :value="null">{{ $t('_pages.blocks._button._action._pushEvent.no-variable') }}</option>
|
<option :value="null">{{ $t('_pages.blocks._button._action._pushEvent.no-variable') }}</option>
|
||||||
<option v-for="v in aiScript.getVarsByType()" :value="v.name">{{ v.name }}</option>
|
<option v-for="v in aoiScript.getVarsByType()" :value="v.name">{{ v.name }}</option>
|
||||||
<optgroup :label="$t('_pages.script.pageVariables')">
|
<optgroup :label="$t('_pages.script.pageVariables')">
|
||||||
<option v-for="v in aiScript.getPageVarsByType()" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getPageVarsByType()" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
||||||
<option v-for="v in aiScript.getEnvVarsByType()" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getEnvVarsByType()" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</mk-select>
|
</mk-select>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else-if="value.action === 'callAiScript'">
|
||||||
|
<mk-input v-model="value.fn"><span>{{ $t('_pages.blocks._button._action._callAiScript.functionName') }}</span></mk-input>
|
||||||
|
</template>
|
||||||
</section>
|
</section>
|
||||||
</x-container>
|
</x-container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -53,7 +57,7 @@ export default Vue.extend({
|
||||||
value: {
|
value: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
aiScript: {
|
aoiScript: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -72,6 +76,7 @@ export default Vue.extend({
|
||||||
if (this.value.message == null) Vue.set(this.value, 'message', null);
|
if (this.value.message == null) Vue.set(this.value, 'message', null);
|
||||||
if (this.value.primary == null) Vue.set(this.value, 'primary', false);
|
if (this.value.primary == null) Vue.set(this.value, 'primary', false);
|
||||||
if (this.value.var == null) Vue.set(this.value, 'var', null);
|
if (this.value.var == null) Vue.set(this.value, 'var', null);
|
||||||
|
if (this.value.fn == null) Vue.set(this.value, 'fn', null);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,16 +10,16 @@
|
||||||
<section class="romcojzs">
|
<section class="romcojzs">
|
||||||
<mk-select v-model="value.var">
|
<mk-select v-model="value.var">
|
||||||
<template #label>{{ $t('_pages.blocks._if.variable') }}</template>
|
<template #label>{{ $t('_pages.blocks._if.variable') }}</template>
|
||||||
<option v-for="v in aiScript.getVarsByType('boolean')" :value="v.name">{{ v.name }}</option>
|
<option v-for="v in aoiScript.getVarsByType('boolean')" :value="v.name">{{ v.name }}</option>
|
||||||
<optgroup :label="$t('_pages.script.pageVariables')">
|
<optgroup :label="$t('_pages.script.pageVariables')">
|
||||||
<option v-for="v in aiScript.getPageVarsByType('boolean')" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getPageVarsByType('boolean')" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
||||||
<option v-for="v in aiScript.getEnvVarsByType('boolean')" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getEnvVarsByType('boolean')" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</mk-select>
|
</mk-select>
|
||||||
|
|
||||||
<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
|
<x-blocks class="children" v-model="value.children" :aoi-script="aoiScript"/>
|
||||||
</section>
|
</section>
|
||||||
</x-container>
|
</x-container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -45,7 +45,7 @@ export default Vue.extend({
|
||||||
value: {
|
value: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
aiScript: {
|
aoiScript: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<section class="ilrvjyvi">
|
<section class="ilrvjyvi">
|
||||||
<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
|
<x-blocks class="children" v-model="value.children" :aoi-script="aoiScript"/>
|
||||||
</section>
|
</section>
|
||||||
</x-container>
|
</x-container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -37,7 +37,7 @@ export default Vue.extend({
|
||||||
value: {
|
value: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
aiScript: {
|
aoiScript: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||||
<template #header><fa :icon="faAlignLeft"/> {{ $t('_pages.blocks.text') }}</template>
|
<template #header><fa :icon="faAlignLeft"/> {{ $t('_pages.blocks.text') }}</template>
|
||||||
|
|
||||||
<section class="ihymsbbe">
|
<section class="vckmsadr">
|
||||||
<textarea v-model="value.text"></textarea>
|
<textarea v-model="value.text"></textarea>
|
||||||
</section>
|
</section>
|
||||||
</x-container>
|
</x-container>
|
||||||
|
@ -40,7 +40,7 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.ihymsbbe {
|
.vckmsadr {
|
||||||
> textarea {
|
> textarea {
|
||||||
display: block;
|
display: block;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
@ -55,6 +55,7 @@ export default Vue.extend({
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -55,6 +55,7 @@ export default Vue.extend({
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150" swap-threshold="0.5">
|
<x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150" swap-threshold="0.5">
|
||||||
<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @input="updateItem" @remove="() => removeItem(block)" :key="block.id" :ai-script="aiScript"/>
|
<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @input="updateItem" @remove="() => removeItem(block)" :key="block.id" :aoi-script="aoiScript"/>
|
||||||
</x-draggable>
|
</x-draggable>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ export default Vue.extend({
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
aiScript: {
|
aoiScript: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<x-container :removable="removable" @remove="() => $emit('remove')" :error="error" :warn="warn" :draggable="draggable">
|
<x-container :removable="removable" @remove="() => $emit('remove')" :error="error" :warn="warn" :draggable="draggable">
|
||||||
<template #header><fa v-if="icon" :icon="icon"/> <template v-if="title">{{ title }} <span class="turmquns" v-if="typeText">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
|
<template #header><fa v-if="icon" :icon="icon"/> <template v-if="title">{{ title }} <span class="turmquns" v-if="typeText">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
|
||||||
<template #func>
|
<template #func>
|
||||||
<button @click="changeType()">
|
<button @click="changeType()" class="_button">
|
||||||
<fa :icon="faPencilAlt"/>
|
<fa :icon="faPencilAlt"/>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -24,30 +24,33 @@
|
||||||
</section>
|
</section>
|
||||||
<section v-else-if="value.type === 'ref'" class="hpdwcrvs">
|
<section v-else-if="value.type === 'ref'" class="hpdwcrvs">
|
||||||
<select v-model="value.value">
|
<select v-model="value.value">
|
||||||
<option v-for="v in aiScript.getVarsByType(getExpectedType ? getExpectedType() : null).filter(x => x.name !== name)" :value="v.name">{{ v.name }}</option>
|
<option v-for="v in aoiScript.getVarsByType(getExpectedType ? getExpectedType() : null).filter(x => x.name !== name)" :value="v.name">{{ v.name }}</option>
|
||||||
<optgroup :label="$t('_pages.script.argVariables')">
|
<optgroup :label="$t('_pages.script.argVariables')">
|
||||||
<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
|
<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$t('_pages.script.pageVariables')">
|
<optgroup :label="$t('_pages.script.pageVariables')">
|
||||||
<option v-for="v in aiScript.getPageVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getPageVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
<optgroup :label="$t('_pages.script.enviromentVariables')">
|
||||||
<option v-for="v in aiScript.getEnvVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
<option v-for="v in aoiScript.getEnvVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
</section>
|
</section>
|
||||||
|
<section v-else-if="value.type === 'aiScriptVar'" class="tbwccoaw">
|
||||||
|
<input v-model="value.value"/>
|
||||||
|
</section>
|
||||||
<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
|
<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
|
||||||
<mk-textarea v-model="slots">
|
<mk-textarea v-model="slots">
|
||||||
<span>{{ $t('_pages.script.blocks._fn.slots') }}</span>
|
<span>{{ $t('_pages.script.blocks._fn.slots') }}</span>
|
||||||
<template #desc>{{ $t('_pages.script.blocks._fn.slots-info') }}</template>
|
<template #desc>{{ $t('_pages.script.blocks._fn.slots-info') }}</template>
|
||||||
</mk-textarea>
|
</mk-textarea>
|
||||||
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`_pages.script.blocks._fn.arg1`)" :get-expected-type="() => null" :ai-script="aiScript" :fn-slots="value.value.slots" :name="name"/>
|
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`_pages.script.blocks._fn.arg1`)" :get-expected-type="() => null" :aoi-script="aoiScript" :fn-slots="value.value.slots" :name="name"/>
|
||||||
</section>
|
</section>
|
||||||
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
|
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
|
||||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
|
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aoiScript.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :aoi-script="aoiScript" :name="name" :key="i"/>
|
||||||
</section>
|
</section>
|
||||||
<section v-else class="" style="padding:16px;">
|
<section v-else class="" style="padding:16px;">
|
||||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`_pages.script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :ai-script="aiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
|
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`_pages.script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :aoi-script="aoiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
|
||||||
</section>
|
</section>
|
||||||
</x-container>
|
</x-container>
|
||||||
</template>
|
</template>
|
||||||
|
@ -85,7 +88,7 @@ export default Vue.extend({
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
aiScript: {
|
aoiScript: {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
|
@ -153,7 +156,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
if (this.value.type && this.value.type.startsWith('fn:')) {
|
if (this.value.type && this.value.type.startsWith('fn:')) {
|
||||||
const fnName = this.value.type.split(':')[1];
|
const fnName = this.value.type.split(':')[1];
|
||||||
const fn = this.aiScript.getVarByName(fnName);
|
const fn = this.aoiScript.getVarByName(fnName);
|
||||||
|
|
||||||
const empties = [];
|
const empties = [];
|
||||||
for (let i = 0; i < fn.value.slots.length; i++) {
|
for (let i = 0; i < fn.value.slots.length; i++) {
|
||||||
|
@ -199,9 +202,9 @@ export default Vue.extend({
|
||||||
deep: true
|
deep: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$watch('aiScript.variables', () => {
|
this.$watch('aoiScript.variables', () => {
|
||||||
if (this.type != null && this.value) {
|
if (this.type != null && this.value) {
|
||||||
this.error = this.aiScript.typeCheck(this.value);
|
this.error = this.aoiScript.typeCheck(this.value);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
deep: true
|
deep: true
|
||||||
|
@ -223,7 +226,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
_getExpectedType(slot: number) {
|
_getExpectedType(slot: number) {
|
||||||
return this.aiScript.getExpectedType(this.value, slot);
|
return this.aoiScript.getExpectedType(this.value, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -258,6 +261,7 @@ export default Vue.extend({
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
> textarea {
|
> textarea {
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<x-blocks class="content" v-model="content" :ai-script="aiScript"/>
|
<x-blocks class="content" v-model="content" :aoi-script="aoiScript"/>
|
||||||
|
|
||||||
<mk-button @click="add()" v-if="!readonly"><fa :icon="faPlus"/></mk-button>
|
<mk-button @click="add()" v-if="!readonly"><fa :icon="faPlus"/></mk-button>
|
||||||
</section>
|
</section>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
@input="v => updateVariable(v)"
|
@input="v => updateVariable(v)"
|
||||||
@remove="() => removeVariable(variable)"
|
@remove="() => removeVariable(variable)"
|
||||||
:key="variable.name"
|
:key="variable.name"
|
||||||
:ai-script="aiScript"
|
:aoi-script="aoiScript"
|
||||||
:name="variable.name"
|
:name="variable.name"
|
||||||
:title="variable.name"
|
:title="variable.name"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
|
@ -73,11 +73,10 @@
|
||||||
</div>
|
</div>
|
||||||
</mk-container>
|
</mk-container>
|
||||||
|
|
||||||
<mk-container :body-togglable="true" :expanded="false">
|
<mk-container :body-togglable="true" :expanded="true">
|
||||||
<template #header><fa :icon="faCode"/> {{ $t('_pages.inspector') }}</template>
|
<template #header><fa :icon="faCode"/> {{ $t('script') }}</template>
|
||||||
<div style="padding:0 32px 32px 32px;">
|
<div>
|
||||||
<mk-textarea :value="JSON.stringify(content, null, 2)" readonly tall>{{ $t('_pages.content') }}</mk-textarea>
|
<prism-editor v-model="script" :line-numbers="false" language="js"/>
|
||||||
<mk-textarea :value="JSON.stringify(variables, null, 2)" readonly tall>{{ $t('_pages.variables') }}</mk-textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</mk-container>
|
</mk-container>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,6 +85,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as XDraggable from 'vuedraggable';
|
import * as XDraggable from 'vuedraggable';
|
||||||
|
import "prismjs";
|
||||||
|
import "prismjs/themes/prism.css";
|
||||||
|
import PrismEditor from 'vue-prism-editor';
|
||||||
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
@ -108,7 +110,7 @@ export default Vue.extend({
|
||||||
i18n,
|
i18n,
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
XDraggable, XVariable, XBlocks, MkTextarea, MkContainer, MkButton, MkSelect, MkSwitch, MkInput
|
XDraggable, XVariable, XBlocks, MkTextarea, MkContainer, MkButton, MkSelect, MkSwitch, MkInput, PrismEditor
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
@ -143,7 +145,8 @@ export default Vue.extend({
|
||||||
alignCenter: false,
|
alignCenter: false,
|
||||||
hideTitleWhenPinned: false,
|
hideTitleWhenPinned: false,
|
||||||
variables: [],
|
variables: [],
|
||||||
aiScript: null,
|
aoiScript: null,
|
||||||
|
script: '',
|
||||||
showOptions: false,
|
showOptions: false,
|
||||||
url,
|
url,
|
||||||
faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode
|
faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode
|
||||||
|
@ -163,14 +166,14 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
this.aiScript = new ASTypeChecker();
|
this.aoiScript = new ASTypeChecker();
|
||||||
|
|
||||||
this.$watch('variables', () => {
|
this.$watch('variables', () => {
|
||||||
this.aiScript.variables = this.variables;
|
this.aoiScript.variables = this.variables;
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
this.$watch('content', () => {
|
this.$watch('content', () => {
|
||||||
this.aiScript.pageVars = collectPageVars(this.content);
|
this.aoiScript.pageVars = collectPageVars(this.content);
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
if (this.initPageId) {
|
if (this.initPageId) {
|
||||||
|
@ -193,6 +196,7 @@ export default Vue.extend({
|
||||||
this.currentName = this.page.name;
|
this.currentName = this.page.name;
|
||||||
this.summary = this.page.summary;
|
this.summary = this.page.summary;
|
||||||
this.font = this.page.font;
|
this.font = this.page.font;
|
||||||
|
this.script = this.page.script;
|
||||||
this.hideTitleWhenPinned = this.page.hideTitleWhenPinned;
|
this.hideTitleWhenPinned = this.page.hideTitleWhenPinned;
|
||||||
this.alignCenter = this.page.alignCenter;
|
this.alignCenter = this.page.alignCenter;
|
||||||
this.content = this.page.content;
|
this.content = this.page.content;
|
||||||
|
@ -223,6 +227,7 @@ export default Vue.extend({
|
||||||
name: this.name.trim(),
|
name: this.name.trim(),
|
||||||
summary: this.summary,
|
summary: this.summary,
|
||||||
font: this.font,
|
font: this.font,
|
||||||
|
script: this.script,
|
||||||
hideTitleWhenPinned: this.hideTitleWhenPinned,
|
hideTitleWhenPinned: this.hideTitleWhenPinned,
|
||||||
alignCenter: this.alignCenter,
|
alignCenter: this.alignCenter,
|
||||||
content: this.content,
|
content: this.content,
|
||||||
|
@ -317,7 +322,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
name = name.trim();
|
name = name.trim();
|
||||||
|
|
||||||
if (this.aiScript.isUsedName(name)) {
|
if (this.aoiScript.isUsedName(name)) {
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: this.$t('_pages.variableNameIsAlreadyUsed')
|
text: this.$t('_pages.variableNameIsAlreadyUsed')
|
||||||
|
@ -382,7 +387,7 @@ export default Vue.extend({
|
||||||
} else {
|
} else {
|
||||||
list.push({
|
list.push({
|
||||||
category: block.category,
|
category: block.category,
|
||||||
label: this.$t(`script.categories.${block.category}`),
|
label: this.$t(`_pages.script.categories.${block.category}`),
|
||||||
items: [{
|
items: [{
|
||||||
value: block.type,
|
value: block.type,
|
||||||
text: this.$t(`_pages.script.blocks.${block.type}`)
|
text: this.$t(`_pages.script.blocks.${block.type}`)
|
||||||
|
@ -394,7 +399,7 @@ export default Vue.extend({
|
||||||
const userFns = this.variables.filter(x => x.type === 'fn');
|
const userFns = this.variables.filter(x => x.type === 'fn');
|
||||||
if (userFns.length > 0) {
|
if (userFns.length > 0) {
|
||||||
list.unshift({
|
list.unshift({
|
||||||
label: this.$t(`script.categories.fn`),
|
label: this.$t(`_pages.script.categories.fn`),
|
||||||
items: userFns.map(v => ({
|
items: userFns.map(v => ({
|
||||||
value: 'fn:' + v.name,
|
value: 'fn:' + v.name,
|
||||||
text: v.name
|
text: v.name
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { faTerminal, faPlay } from '@fortawesome/free-solid-svg-icons';
|
||||||
import "prismjs";
|
import "prismjs";
|
||||||
import "prismjs/themes/prism.css";
|
import "prismjs/themes/prism.css";
|
||||||
import { faTerminal, faPlay } from '@fortawesome/free-solid-svg-icons';
|
|
||||||
import PrismEditor from 'vue-prism-editor';
|
import PrismEditor from 'vue-prism-editor';
|
||||||
import { AiScript, parse, utils, values } from '@syuilo/aiscript';
|
import { AiScript, parse, utils, values } from '@syuilo/aiscript';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
|
|
|
@ -2,6 +2,8 @@ import autobind from 'autobind-decorator';
|
||||||
import * as seedrandom from 'seedrandom';
|
import * as seedrandom from 'seedrandom';
|
||||||
import { Variable, PageVar, envVarsDef, funcDefs, Block, isFnBlock } from '.';
|
import { Variable, PageVar, envVarsDef, funcDefs, Block, isFnBlock } from '.';
|
||||||
import { version } from '../../config';
|
import { version } from '../../config';
|
||||||
|
import { AiScript, utils, parse, values } from '@syuilo/aiscript';
|
||||||
|
import { createAiScriptEnv } from '../create-aiscript-env';
|
||||||
|
|
||||||
type Fn = {
|
type Fn = {
|
||||||
slots: string[];
|
slots: string[];
|
||||||
|
@ -15,15 +17,41 @@ export class ASEvaluator {
|
||||||
private variables: Variable[];
|
private variables: Variable[];
|
||||||
private pageVars: PageVar[];
|
private pageVars: PageVar[];
|
||||||
private envVars: Record<keyof typeof envVarsDef, any>;
|
private envVars: Record<keyof typeof envVarsDef, any>;
|
||||||
|
public aiscript: AiScript;
|
||||||
|
private pageVarUpdatedCallback;
|
||||||
|
|
||||||
private opts: {
|
private opts: {
|
||||||
randomSeed: string; visitor?: any; page?: any; url?: string;
|
randomSeed: string; visitor?: any; page?: any; url?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(variables: Variable[], pageVars: PageVar[], opts: ASEvaluator['opts']) {
|
constructor(vm: any, variables: Variable[], pageVars: PageVar[], opts: ASEvaluator['opts']) {
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
this.pageVars = pageVars;
|
this.pageVars = pageVars;
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
|
this.aiscript = new AiScript({ ...createAiScriptEnv(vm, {
|
||||||
|
storageKey: 'pages:' + opts.page.id
|
||||||
|
}), ...{
|
||||||
|
'MkPages:updated': values.FN_NATIVE(([callback]) => {
|
||||||
|
this.pageVarUpdatedCallback = callback;
|
||||||
|
})
|
||||||
|
}}, {
|
||||||
|
in: (q) => {
|
||||||
|
return new Promise(ok => {
|
||||||
|
vm.$root.dialog({
|
||||||
|
title: q,
|
||||||
|
input: {}
|
||||||
|
}).then(({ canceled, result: a }) => {
|
||||||
|
ok(a);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
out: (value) => {
|
||||||
|
console.log(value);
|
||||||
|
},
|
||||||
|
log: (type, params) => {
|
||||||
|
},
|
||||||
|
maxStep: 16384
|
||||||
|
});
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
|
@ -50,6 +78,9 @@ export class ASEvaluator {
|
||||||
const pageVar = this.pageVars.find(v => v.name === name);
|
const pageVar = this.pageVars.find(v => v.name === name);
|
||||||
if (pageVar !== undefined) {
|
if (pageVar !== undefined) {
|
||||||
pageVar.value = value;
|
pageVar.value = value;
|
||||||
|
if (this.pageVarUpdatedCallback) {
|
||||||
|
this.aiscript.execFn(this.pageVarUpdatedCallback, [values.STR(name), utils.jsToVal(value)]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new AoiScriptError(`No such page var '${name}'`);
|
throw new AoiScriptError(`No such page var '${name}'`);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +141,10 @@ export class ASEvaluator {
|
||||||
return scope.getState(block.value);
|
return scope.getState(block.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (block.type === 'aiScriptVar') {
|
||||||
|
return utils.valToJs(this.aiscript.scope.get(block.value));
|
||||||
|
}
|
||||||
|
|
||||||
if (isFnBlock(block)) { // ユーザー関数定義
|
if (isFnBlock(block)) { // ユーザー関数定義
|
||||||
return {
|
return {
|
||||||
slots: block.value.slots.map(x => x.name),
|
slots: block.value.slots.map(x => x.name),
|
||||||
|
|
|
@ -95,6 +95,7 @@ export const literalDefs: Record<string, { out: any; category: string; icon: any
|
||||||
textList: { out: 'stringArray', category: 'value', icon: faList, },
|
textList: { out: 'stringArray', category: 'value', icon: faList, },
|
||||||
number: { out: 'number', category: 'value', icon: faSortNumericUp, },
|
number: { out: 'number', category: 'value', icon: faSortNumericUp, },
|
||||||
ref: { out: null, category: 'value', icon: faMagic, },
|
ref: { out: null, category: 'value', icon: faMagic, },
|
||||||
|
aiScriptVar: { out: null, category: 'value', icon: faMagic, },
|
||||||
fn: { out: 'function', category: 'value', icon: faSquareRootAlt, },
|
fn: { out: 'function', category: 'value', icon: faSquareRootAlt, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { utils, values } from '@syuilo/aiscript';
|
import { utils, values } from '@syuilo/aiscript';
|
||||||
|
|
||||||
export function createAiScriptEnv(vm, opts) {
|
export function createAiScriptEnv(vm, opts) {
|
||||||
|
let apiRequests = 0;
|
||||||
return {
|
return {
|
||||||
USER_ID: values.STR(vm.$store.state.i.id),
|
USER_ID: values.STR(vm.$store.state.i.id),
|
||||||
USER_USERNAME: values.STR(vm.$store.state.i.username),
|
USER_USERNAME: values.STR(vm.$store.state.i.username),
|
||||||
|
@ -21,6 +22,8 @@ export function createAiScriptEnv(vm, opts) {
|
||||||
return confirm.canceled ? values.FALSE : values.TRUE
|
return confirm.canceled ? values.FALSE : values.TRUE
|
||||||
}),
|
}),
|
||||||
'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => {
|
'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => {
|
||||||
|
apiRequests++;
|
||||||
|
if (apiRequests > 16) return values.NULL;
|
||||||
const res = await vm.$root.api(ep.value, utils.valToJs(param), token || null);
|
const res = await vm.$root.api(ep.value, utils.valToJs(param), token || null);
|
||||||
return utils.jsToVal(res);
|
return utils.jsToVal(res);
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -85,6 +85,12 @@ export class Page {
|
||||||
})
|
})
|
||||||
public variables: Record<string, any>[];
|
public variables: Record<string, any>[];
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 16384,
|
||||||
|
default: ''
|
||||||
|
})
|
||||||
|
public script: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* public ... 公開
|
* public ... 公開
|
||||||
* followers ... フォロワーのみ
|
* followers ... フォロワーのみ
|
||||||
|
|
|
@ -74,6 +74,7 @@ export class PageRepository extends Repository<Page> {
|
||||||
hideTitleWhenPinned: page.hideTitleWhenPinned,
|
hideTitleWhenPinned: page.hideTitleWhenPinned,
|
||||||
alignCenter: page.alignCenter,
|
alignCenter: page.alignCenter,
|
||||||
font: page.font,
|
font: page.font,
|
||||||
|
script: page.script,
|
||||||
eyeCatchingImageId: page.eyeCatchingImageId,
|
eyeCatchingImageId: page.eyeCatchingImageId,
|
||||||
eyeCatchingImage: page.eyeCatchingImageId ? await DriveFiles.pack(page.eyeCatchingImageId) : null,
|
eyeCatchingImage: page.eyeCatchingImageId ? await DriveFiles.pack(page.eyeCatchingImageId) : null,
|
||||||
attachedFiles: DriveFiles.packMany(await Promise.all(attachedFiles)),
|
attachedFiles: DriveFiles.packMany(await Promise.all(attachedFiles)),
|
||||||
|
|
|
@ -44,6 +44,10 @@ export const meta = {
|
||||||
validator: $.arr($.obj())
|
validator: $.arr($.obj())
|
||||||
},
|
},
|
||||||
|
|
||||||
|
script: {
|
||||||
|
validator: $.str,
|
||||||
|
},
|
||||||
|
|
||||||
eyeCatchingImageId: {
|
eyeCatchingImageId: {
|
||||||
validator: $.optional.nullable.type(ID),
|
validator: $.optional.nullable.type(ID),
|
||||||
},
|
},
|
||||||
|
@ -115,6 +119,7 @@ export default define(meta, async (ps, user) => {
|
||||||
summary: ps.summary,
|
summary: ps.summary,
|
||||||
content: ps.content,
|
content: ps.content,
|
||||||
variables: ps.variables,
|
variables: ps.variables,
|
||||||
|
script: ps.script,
|
||||||
eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null,
|
eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
visibility: 'public',
|
visibility: 'public',
|
||||||
|
|
|
@ -51,6 +51,10 @@ export const meta = {
|
||||||
validator: $.arr($.obj())
|
validator: $.arr($.obj())
|
||||||
},
|
},
|
||||||
|
|
||||||
|
script: {
|
||||||
|
validator: $.str,
|
||||||
|
},
|
||||||
|
|
||||||
eyeCatchingImageId: {
|
eyeCatchingImageId: {
|
||||||
validator: $.optional.nullable.type(ID),
|
validator: $.optional.nullable.type(ID),
|
||||||
},
|
},
|
||||||
|
@ -132,6 +136,7 @@ export default define(meta, async (ps, user) => {
|
||||||
summary: ps.name === undefined ? page.summary : ps.summary,
|
summary: ps.name === undefined ? page.summary : ps.summary,
|
||||||
content: ps.content,
|
content: ps.content,
|
||||||
variables: ps.variables,
|
variables: ps.variables,
|
||||||
|
script: ps.script,
|
||||||
alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter,
|
alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter,
|
||||||
hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned,
|
hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned,
|
||||||
font: ps.font === undefined ? page.font : ps.font,
|
font: ps.font === undefined ? page.font : ps.font,
|
||||||
|
|
|
@ -144,10 +144,10 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
type-detect "4.0.8"
|
type-detect "4.0.8"
|
||||||
|
|
||||||
"@syuilo/aiscript@0.1.2":
|
"@syuilo/aiscript@0.1.4":
|
||||||
version "0.1.2"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.1.2.tgz#65c42793c38707d862b3a64f5edc845789372ade"
|
resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.1.4.tgz#ff027552f32990ae3e29145ce6efe0a7a516b442"
|
||||||
integrity sha512-W0G/JuVkD9jARPhKFaaHp+59Iv+2LapQ2zKjM08hoB/6hEzHjis0uRbw07TXyughQb17iU452rp1gJEUkXV3Mg==
|
integrity sha512-SMDlBInsGTL3DOe0U394X7na0N6ryYg0RGQPPtCVhXkJpVDZiaqUe5vDO+DkRyuRlkmBbN82LWToou19j/Uv8g==
|
||||||
dependencies:
|
dependencies:
|
||||||
autobind-decorator "2.4.0"
|
autobind-decorator "2.4.0"
|
||||||
chalk "4.0.0"
|
chalk "4.0.0"
|
||||||
|
|
Loading…
Reference in a new issue