mirror of
https://github.com/requarks/wiki.git
synced 2026-08-26 13:17:10 -05:00
feat: scheduler history + retries + admin scheduler page (wip)
This commit is contained in:
@@ -33,6 +33,8 @@ defaults:
|
||||
workers: 3
|
||||
pollingCheck: 5
|
||||
scheduledCheck: 300
|
||||
maxRetries: 5
|
||||
retryBackoff: 60
|
||||
# DB defaults
|
||||
api:
|
||||
isEnabled: false
|
||||
|
||||
@@ -55,12 +55,13 @@ module.exports = {
|
||||
|
||||
WIKI.logger.info('Scheduler: [ STARTED ]')
|
||||
},
|
||||
async addJob ({ task, payload, waitUntil, isScheduled = false, notify = true }) {
|
||||
async addJob ({ task, payload, waitUntil, maxRetries, isScheduled = false, notify = true }) {
|
||||
try {
|
||||
await WIKI.db.knex('jobs').insert({
|
||||
task,
|
||||
useWorker: !(typeof this.tasks[task] === 'function'),
|
||||
payload,
|
||||
maxRetries: maxRetries ?? WIKI.config.scheduler.maxRetries,
|
||||
isScheduled,
|
||||
waitUntil,
|
||||
createdBy: WIKI.INSTANCE_ID
|
||||
@@ -76,6 +77,7 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
async processJob () {
|
||||
let jobId = null
|
||||
try {
|
||||
await WIKI.db.knex.transaction(async trx => {
|
||||
const jobs = await trx('jobs')
|
||||
@@ -85,19 +87,74 @@ module.exports = {
|
||||
if (jobs && jobs.length === 1) {
|
||||
const job = jobs[0]
|
||||
WIKI.logger.info(`Processing new job ${job.id}: ${job.task}...`)
|
||||
if (job.useWorker) {
|
||||
await this.workerPool.execute({
|
||||
id: job.id,
|
||||
name: job.task,
|
||||
data: job.payload
|
||||
jobId = job.id
|
||||
// -> Add to Job History
|
||||
await WIKI.db.knex('jobHistory').insert({
|
||||
id: job.id,
|
||||
task: job.task,
|
||||
state: 'active',
|
||||
useWorker: job.useWorker,
|
||||
wasScheduled: job.isScheduled,
|
||||
payload: job.payload,
|
||||
attempt: job.retries + 1,
|
||||
maxRetries: job.maxRetries,
|
||||
createdAt: job.createdAt
|
||||
}).onConflict('id').merge({
|
||||
startedAt: new Date()
|
||||
})
|
||||
// -> Start working on it
|
||||
try {
|
||||
if (job.useWorker) {
|
||||
await this.workerPool.execute({
|
||||
id: job.id,
|
||||
name: job.task,
|
||||
data: job.payload
|
||||
})
|
||||
} else {
|
||||
await this.tasks[job.task](job.payload)
|
||||
}
|
||||
// -> Update job history (success)
|
||||
await WIKI.db.knex('jobHistory').where({
|
||||
id: job.id
|
||||
}).update({
|
||||
state: 'completed',
|
||||
completedAt: new Date()
|
||||
})
|
||||
} else {
|
||||
await this.tasks[job.task](job.payload)
|
||||
WIKI.logger.info(`Completed job ${job.id}: ${job.task} [ SUCCESS ]`)
|
||||
} catch (err) {
|
||||
WIKI.logger.warn(`Failed to complete job ${job.id}: ${job.task} [ FAILED ]`)
|
||||
WIKI.logger.warn(err)
|
||||
// -> Update job history (fail)
|
||||
await WIKI.db.knex('jobHistory').where({
|
||||
id: job.id
|
||||
}).update({
|
||||
state: 'failed',
|
||||
lastErrorMessage: err.message
|
||||
})
|
||||
// -> Reschedule for retry
|
||||
if (job.retries < job.maxRetries) {
|
||||
const backoffDelay = (2 ** job.retries) * WIKI.config.scheduler.retryBackoff
|
||||
await trx('jobs').insert({
|
||||
...job,
|
||||
retries: job.retries + 1,
|
||||
waitUntil: DateTime.utc().plus({ seconds: backoffDelay }).toJSDate(),
|
||||
updatedAt: new Date()
|
||||
})
|
||||
WIKI.logger.warn(`Rescheduling new attempt for job ${job.id}: ${job.task}...`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
WIKI.logger.warn(err)
|
||||
if (jobId) {
|
||||
WIKI.db.knex('jobHistory').where({
|
||||
id: jobId
|
||||
}).update({
|
||||
state: 'interrupted',
|
||||
lastErrorMessage: err.message
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
async addScheduled () {
|
||||
|
||||
@@ -125,12 +125,16 @@ exports.up = async knex => {
|
||||
.createTable('jobHistory', table => {
|
||||
table.uuid('id').notNullable().primary()
|
||||
table.string('task').notNullable()
|
||||
table.string('state').notNullable()
|
||||
table.enum('state', ['active', 'completed', 'failed', 'interrupted']).notNullable()
|
||||
table.boolean('useWorker').notNullable().defaultTo(false)
|
||||
table.boolean('wasScheduled').notNullable().defaultTo(false)
|
||||
table.jsonb('payload')
|
||||
table.string('lastErrorMessage')
|
||||
table.integer('attempt').notNullable().defaultTo(1)
|
||||
table.integer('maxRetries').notNullable().defaultTo(0)
|
||||
table.text('lastErrorMessage')
|
||||
table.timestamp('createdAt').notNullable()
|
||||
table.timestamp('startedAt').notNullable()
|
||||
table.timestamp('completedAt').notNullable().defaultTo(knex.fn.now())
|
||||
table.timestamp('startedAt').notNullable().defaultTo(knex.fn.now())
|
||||
table.timestamp('completedAt')
|
||||
})
|
||||
// JOB SCHEDULE ------------------------
|
||||
.createTable('jobSchedule', table => {
|
||||
@@ -154,6 +158,8 @@ exports.up = async knex => {
|
||||
table.string('task').notNullable()
|
||||
table.boolean('useWorker').notNullable().defaultTo(false)
|
||||
table.jsonb('payload')
|
||||
table.integer('retries').notNullable().defaultTo(0)
|
||||
table.integer('maxRetries').notNullable().defaultTo(0)
|
||||
table.timestamp('waitUntil')
|
||||
table.boolean('isScheduled').notNullable().defaultTo(false)
|
||||
table.string('createdBy')
|
||||
|
||||
@@ -7,7 +7,6 @@ const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const { DateTime } = require('luxon')
|
||||
const graphHelper = require('../../helpers/graph')
|
||||
const cronParser = require('cron-parser')
|
||||
|
||||
module.exports = {
|
||||
Query: {
|
||||
@@ -28,33 +27,34 @@ module.exports = {
|
||||
return WIKI.config.security
|
||||
},
|
||||
async systemJobs (obj, args) {
|
||||
switch (args.type) {
|
||||
switch (args.state) {
|
||||
case 'ACTIVE': {
|
||||
// const result = await WIKI.scheduler.boss.fetch('*', 25, { includeMeta: true })
|
||||
return []
|
||||
}
|
||||
case 'COMPLETED': {
|
||||
const result = await WIKI.scheduler.boss.fetchCompleted('*', 25, { includeMeta: true })
|
||||
console.info(result)
|
||||
return result ?? []
|
||||
return []
|
||||
}
|
||||
case 'FAILED': {
|
||||
return []
|
||||
}
|
||||
case 'INTERRUPTED': {
|
||||
return []
|
||||
}
|
||||
default: {
|
||||
WIKI.logger.warn('Invalid Job Type requested.')
|
||||
WIKI.logger.warn('Invalid Job State requested.')
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
async systemScheduledJobs (obj, args) {
|
||||
const jobs = await WIKI.scheduler.boss.getSchedules()
|
||||
return jobs.map(job => ({
|
||||
id: job.name,
|
||||
name: job.name,
|
||||
cron: job.cron,
|
||||
timezone: job.timezone,
|
||||
nextExecution: cronParser.parseExpression(job.cron, { tz: job.timezone }).next(),
|
||||
createdAt: job.created_on,
|
||||
updatedAt: job.updated_on
|
||||
}))
|
||||
async systemJobsScheduled (obj, args) {
|
||||
return WIKI.db.knex('jobSchedule').orderBy('task')
|
||||
},
|
||||
async systemJobsUpcoming (obj, args) {
|
||||
return WIKI.db.knex('jobs').orderBy([
|
||||
{ column: 'waitUntil', order: 'asc', nulls: 'first' },
|
||||
{ column: 'createdAt', order: 'asc' }
|
||||
])
|
||||
}
|
||||
},
|
||||
Mutation: {
|
||||
@@ -123,15 +123,19 @@ module.exports = {
|
||||
httpsPort () {
|
||||
return WIKI.servers.servers.https ? _.get(WIKI.servers.servers.https.address(), 'port', 0) : 0
|
||||
},
|
||||
isMailConfigured () {
|
||||
return WIKI.config?.mail?.host?.length > 2
|
||||
},
|
||||
async isSchedulerHealthy () {
|
||||
const results = await WIKI.db.knex('jobHistory').count('* as total').whereIn('state', ['failed', 'interrupted']).andWhere('startedAt', '>=', DateTime.utc().minus({ days: 1 }).toISO()).first()
|
||||
return _.toSafeInteger(results?.total) === 0
|
||||
},
|
||||
latestVersion () {
|
||||
return WIKI.system.updates.version
|
||||
},
|
||||
latestVersionReleaseDate () {
|
||||
return DateTime.fromISO(WIKI.system.updates.releaseDate).toJSDate()
|
||||
},
|
||||
mailConfigured () {
|
||||
return WIKI.config?.mail?.host?.length > 2
|
||||
},
|
||||
nodeVersion () {
|
||||
return process.version.substr(1)
|
||||
},
|
||||
@@ -168,12 +172,6 @@ module.exports = {
|
||||
sslSubscriberEmail () {
|
||||
return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === 'letsencrypt' ? WIKI.config.ssl.subscriberEmail : null
|
||||
},
|
||||
telemetry () {
|
||||
return WIKI.telemetry.enabled
|
||||
},
|
||||
telemetryClientId () {
|
||||
return WIKI.config.telemetry.clientId
|
||||
},
|
||||
async upgradeCapable () {
|
||||
return !_.isNil(process.env.UPGRADE_COMPANION)
|
||||
},
|
||||
|
||||
@@ -8,9 +8,10 @@ extend type Query {
|
||||
systemInfo: SystemInfo
|
||||
systemSecurity: SystemSecurity
|
||||
systemJobs(
|
||||
type: SystemJobType!
|
||||
state: SystemJobState
|
||||
): [SystemJob]
|
||||
systemScheduledJobs: [SystemScheduledJob]
|
||||
systemJobsScheduled: [SystemJobScheduled]
|
||||
systemJobsUpcoming: [SystemJobUpcoming]
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
@@ -72,9 +73,10 @@ type SystemInfo {
|
||||
httpPort: Int
|
||||
httpRedirection: Boolean
|
||||
httpsPort: Int
|
||||
isMailConfigured: Boolean
|
||||
isSchedulerHealthy: Boolean
|
||||
latestVersion: String
|
||||
latestVersionReleaseDate: Date
|
||||
mailConfigured: Boolean
|
||||
nodeVersion: String
|
||||
operatingSystem: String
|
||||
pagesTotal: Int
|
||||
@@ -86,8 +88,6 @@ type SystemInfo {
|
||||
sslStatus: String
|
||||
sslSubscriberEmail: String
|
||||
tagsTotal: Int
|
||||
telemetry: Boolean
|
||||
telemetryClientId: String
|
||||
upgradeCapable: Boolean
|
||||
usersTotal: Int
|
||||
workingDirectory: String
|
||||
@@ -151,22 +151,46 @@ enum SystemSecurityCorsMode {
|
||||
|
||||
type SystemJob {
|
||||
id: UUID
|
||||
name: String
|
||||
priority: Int
|
||||
state: String
|
||||
task: String
|
||||
state: SystemJobState
|
||||
useWorker: Boolean
|
||||
wasScheduled: Boolean
|
||||
payload: JSON
|
||||
attempt: Int
|
||||
maxRetries: Int
|
||||
lastErrorMessage: String
|
||||
createdAt: Date
|
||||
startedAt: Date
|
||||
completedAt: Date
|
||||
}
|
||||
|
||||
type SystemScheduledJob {
|
||||
id: String
|
||||
name: String
|
||||
type SystemJobScheduled {
|
||||
id: UUID
|
||||
task: String
|
||||
cron: String
|
||||
timezone: String
|
||||
nextExecution: Date
|
||||
type: String
|
||||
payload: JSON
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
enum SystemJobType {
|
||||
type SystemJobUpcoming {
|
||||
id: UUID
|
||||
task: String
|
||||
useWorker: Boolean
|
||||
payload: JSON
|
||||
retries: Int
|
||||
maxRetries: Int
|
||||
waitUntil: Date
|
||||
isScheduled: Boolean
|
||||
createdBy: String
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
enum SystemJobState {
|
||||
ACTIVE
|
||||
COMPLETED
|
||||
FAILED
|
||||
INTERRUPTED
|
||||
}
|
||||
|
||||
+7
-1
@@ -36,5 +36,11 @@
|
||||
"dist",
|
||||
".quasar",
|
||||
"node_modules"
|
||||
]
|
||||
],
|
||||
"vueCompilerOptions": {
|
||||
"target": 3,
|
||||
"plugins": [
|
||||
"@volar/vue-language-plugin-pug"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"@intlify/vite-plugin-vue-i18n": "6.0.1",
|
||||
"@quasar/app-vite": "1.0.6",
|
||||
"@types/lodash": "4.14.184",
|
||||
"@volar/vue-language-plugin-pug": "1.0.1",
|
||||
"browserlist": "latest",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-config-standard": "17.0.0",
|
||||
|
||||
@@ -1515,7 +1515,15 @@
|
||||
"admin.scheduler.completedNone": "There are no recently completed job to display.",
|
||||
"admin.scheduler.scheduledNone": "There are no scheduled jobs at the moment.",
|
||||
"admin.scheduler.cron": "Cron",
|
||||
"admin.scheduler.nextExecutionIn": "Next run {date}",
|
||||
"admin.scheduler.nextExecution": "Next Run",
|
||||
"admin.scheduler.timezone": "Timezone"
|
||||
"admin.scheduler.createdBy": "by instance {instance}",
|
||||
"admin.scheduler.upcoming": "Upcoming",
|
||||
"admin.scheduler.failed": "Failed",
|
||||
"admin.scheduler.type": "Type",
|
||||
"admin.scheduler.createdAt": "Created",
|
||||
"admin.scheduler.updatedAt": "Last Updated",
|
||||
"common.field.task": "Task",
|
||||
"admin.scheduler.upcomingNone": "There are no upcoming job for the moment.",
|
||||
"admin.scheduler.waitUntil": "Start",
|
||||
"admin.scheduler.attempt": "Attempt",
|
||||
"admin.scheduler.useWorker": "Execution Mode"
|
||||
}
|
||||
|
||||
@@ -156,6 +156,8 @@ q-layout.admin(view='hHh Lpr lff')
|
||||
q-item-section(avatar)
|
||||
q-icon(name='img:/_assets/icons/fluent-bot.svg')
|
||||
q-item-section {{ t('admin.scheduler.title') }}
|
||||
q-item-section(side)
|
||||
status-light(:color='adminStore.info.isSchedulerHealthy ? `positive` : `warning`')
|
||||
q-item(to='/_admin/security', v-ripple, active-class='bg-primary text-white')
|
||||
q-item-section(avatar)
|
||||
q-icon(name='img:/_assets/icons/fluent-protect.svg')
|
||||
|
||||
+156
-31
@@ -18,7 +18,9 @@ q-page.admin-terminal
|
||||
:color='$q.dark.isActive ? `dark-1` : `white`'
|
||||
:options=`[
|
||||
{ label: t('admin.scheduler.scheduled'), value: 'scheduled' },
|
||||
{ label: t('admin.scheduler.completed'), value: 'completed' }
|
||||
{ label: t('admin.scheduler.upcoming'), value: 'upcoming' },
|
||||
{ label: t('admin.scheduler.completed'), value: 'completed' },
|
||||
{ label: t('admin.scheduler.failed'), value: 'failed' },
|
||||
]`
|
||||
)
|
||||
q-separator.q-mr-md(vertical)
|
||||
@@ -66,18 +68,62 @@ q-page.admin-terminal
|
||||
size='xs'
|
||||
)
|
||||
//- q-icon(name='las la-stopwatch', color='primary', size='sm')
|
||||
template(v-slot:body-cell-name='props')
|
||||
template(v-slot:body-cell-task='props')
|
||||
q-td(:props='props')
|
||||
strong {{props.value}}
|
||||
div: small.text-grey {{props.row.id}}
|
||||
template(v-slot:body-cell-cron='props')
|
||||
q-td(:props='props')
|
||||
span {{ props.value }}
|
||||
template(v-else-if='state.displayMode === `upcoming`')
|
||||
q-card.rounded-borders(
|
||||
v-if='state.upcomingJobs.length < 1'
|
||||
flat
|
||||
:class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
|
||||
)
|
||||
q-card-section.items-center(horizontal)
|
||||
q-card-section.col-auto.q-pr-none
|
||||
q-icon(name='las la-info-circle', size='sm')
|
||||
q-card-section.text-caption {{ t('admin.scheduler.upcomingNone') }}
|
||||
q-card.shadow-1(v-else)
|
||||
q-table(
|
||||
:rows='state.upcomingJobs'
|
||||
:columns='upcomingJobsHeaders'
|
||||
row-key='name'
|
||||
flat
|
||||
hide-bottom
|
||||
:rows-per-page-options='[0]'
|
||||
:loading='state.loading > 0'
|
||||
)
|
||||
template(v-slot:body-cell-id='props')
|
||||
q-td(:props='props')
|
||||
q-icon(name='las la-chess-knight', color='primary', size='sm')
|
||||
template(v-slot:body-cell-task='props')
|
||||
q-td(:props='props')
|
||||
strong {{props.value}}
|
||||
div: small.text-grey {{props.row.id}}
|
||||
template(v-slot:body-cell-waituntil='props')
|
||||
q-td(:props='props')
|
||||
span {{ props.value }}
|
||||
div: small.text-grey {{humanizeDate(props.row.waitUntil)}}
|
||||
template(v-slot:body-cell-retries='props')
|
||||
q-td(:props='props')
|
||||
span #[strong {{props.value + 1}}] #[span.text-grey / {{props.row.maxRetries}}]
|
||||
template(v-slot:body-cell-useworker='props')
|
||||
q-td(:props='props')
|
||||
template(v-if='props.value')
|
||||
q-icon(name='las la-microchip', color='brown', size='sm')
|
||||
small.q-ml-xs.text-brown Worker
|
||||
template(v-else)
|
||||
q-icon(name='las la-leaf', color='teal', size='sm')
|
||||
small.q-ml-xs.text-teal In-Process
|
||||
template(v-slot:body-cell-date='props')
|
||||
q-td(:props='props')
|
||||
i18n-t.text-caption(keypath='admin.scheduler.nextExecutionIn', tag='div')
|
||||
template(#date)
|
||||
strong {{ humanizeDate(props.value) }}
|
||||
small {{props.value}}
|
||||
span {{props.value}}
|
||||
div
|
||||
i18n-t.text-grey(keypath='admin.scheduler.createdBy', tag='small')
|
||||
template(#instance)
|
||||
strong {{props.row.createdBy}}
|
||||
template(v-else)
|
||||
q-card.rounded-borders(
|
||||
v-if='state.jobs.length < 1'
|
||||
@@ -122,8 +168,9 @@ useMeta({
|
||||
// DATA
|
||||
|
||||
const state = reactive({
|
||||
displayMode: 'scheduled',
|
||||
displayMode: 'upcoming',
|
||||
scheduledJobs: [],
|
||||
upcomingJobs: [],
|
||||
jobs: [],
|
||||
loading: 0
|
||||
})
|
||||
@@ -137,10 +184,10 @@ const scheduledJobsHeaders = [
|
||||
style: 'width: 15px; padding-right: 0;'
|
||||
},
|
||||
{
|
||||
label: t('common.field.name'),
|
||||
label: t('common.field.task'),
|
||||
align: 'left',
|
||||
field: 'name',
|
||||
name: 'name',
|
||||
field: 'task',
|
||||
name: 'task',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
@@ -148,21 +195,77 @@ const scheduledJobsHeaders = [
|
||||
align: 'left',
|
||||
field: 'cron',
|
||||
name: 'cron',
|
||||
sortable: false
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.timezone'),
|
||||
label: t('admin.scheduler.type'),
|
||||
align: 'left',
|
||||
field: 'timezone',
|
||||
name: 'timezone',
|
||||
sortable: false
|
||||
field: 'type',
|
||||
name: 'type',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.nextExecution'),
|
||||
label: t('admin.scheduler.createdAt'),
|
||||
align: 'left',
|
||||
field: 'nextExecution',
|
||||
field: 'createdAt',
|
||||
name: 'created',
|
||||
sortable: true,
|
||||
format: v => DateTime.fromISO(v).toRelative()
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.updatedAt'),
|
||||
align: 'left',
|
||||
field: 'updatedAt',
|
||||
name: 'updated',
|
||||
sortable: true,
|
||||
format: v => DateTime.fromISO(v).toRelative()
|
||||
}
|
||||
]
|
||||
|
||||
const upcomingJobsHeaders = [
|
||||
{
|
||||
align: 'center',
|
||||
field: 'id',
|
||||
name: 'id',
|
||||
sortable: false,
|
||||
style: 'width: 15px; padding-right: 0;'
|
||||
},
|
||||
{
|
||||
label: t('common.field.task'),
|
||||
align: 'left',
|
||||
field: 'task',
|
||||
name: 'task',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.waitUntil'),
|
||||
align: 'left',
|
||||
field: 'waitUntil',
|
||||
name: 'waituntil',
|
||||
sortable: true,
|
||||
format: v => DateTime.fromISO(v).toRelative()
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.attempt'),
|
||||
align: 'left',
|
||||
field: 'retries',
|
||||
name: 'retries',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.useWorker'),
|
||||
align: 'left',
|
||||
field: 'useWorker',
|
||||
name: 'useworker',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
label: t('admin.scheduler.createdAt'),
|
||||
align: 'left',
|
||||
field: 'createdAt',
|
||||
name: 'date',
|
||||
sortable: false
|
||||
sortable: true,
|
||||
format: v => DateTime.fromISO(v).toRelative()
|
||||
}
|
||||
]
|
||||
|
||||
@@ -174,33 +277,59 @@ watch(() => state.displayMode, (newValue) => {
|
||||
|
||||
// METHODS
|
||||
|
||||
function humanizeDate (val) {
|
||||
return DateTime.fromISO(val).toFormat('fff')
|
||||
}
|
||||
|
||||
async function load () {
|
||||
state.loading++
|
||||
try {
|
||||
if (state.displayMode === 'scheduled') {
|
||||
const resp = await APOLLO_CLIENT.query({
|
||||
query: gql`
|
||||
query getSystemScheduledJobs {
|
||||
systemScheduledJobs {
|
||||
query getSystemJobsScheduled {
|
||||
systemJobsScheduled {
|
||||
id
|
||||
name
|
||||
task
|
||||
cron
|
||||
timezone
|
||||
nextExecution
|
||||
type
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
fetchPolicy: 'network-only'
|
||||
})
|
||||
state.scheduledJobs = resp?.data?.systemScheduledJobs
|
||||
state.scheduledJobs = resp?.data?.systemJobsScheduled
|
||||
} else if (state.displayMode === 'upcoming') {
|
||||
const resp = await APOLLO_CLIENT.query({
|
||||
query: gql`
|
||||
query getSystemJobsUpcoming {
|
||||
systemJobsUpcoming {
|
||||
id
|
||||
task
|
||||
useWorker
|
||||
retries
|
||||
maxRetries
|
||||
waitUntil
|
||||
isScheduled
|
||||
createdBy
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
fetchPolicy: 'network-only'
|
||||
})
|
||||
state.upcomingJobs = resp?.data?.systemJobsUpcoming
|
||||
} else {
|
||||
const resp = await APOLLO_CLIENT.query({
|
||||
query: gql`
|
||||
query getSystemJobs (
|
||||
$type: SystemJobType!
|
||||
$state: SystemJobState!
|
||||
) {
|
||||
systemJobs (
|
||||
type: $type
|
||||
state: $state
|
||||
) {
|
||||
id
|
||||
name
|
||||
@@ -210,7 +339,7 @@ async function load () {
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
type: state.displayMode.toUpperCase()
|
||||
state: state.displayMode.toUpperCase()
|
||||
},
|
||||
fetchPolicy: 'network-only'
|
||||
})
|
||||
@@ -226,10 +355,6 @@ async function load () {
|
||||
state.loading--
|
||||
}
|
||||
|
||||
function humanizeDate (val) {
|
||||
return DateTime.fromISO(val).toRelative()
|
||||
}
|
||||
|
||||
// MOUNTED
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -16,7 +16,8 @@ export const useAdminStore = defineStore('admin', {
|
||||
usersTotal: 0,
|
||||
loginsPastDay: 0,
|
||||
isApiEnabled: false,
|
||||
isMailConfigured: false
|
||||
isMailConfigured: false,
|
||||
isSchedulerHealthy: false
|
||||
},
|
||||
overlay: null,
|
||||
overlayOpts: {},
|
||||
@@ -63,7 +64,8 @@ export const useAdminStore = defineStore('admin', {
|
||||
usersTotal
|
||||
currentVersion
|
||||
latestVersion
|
||||
mailConfigured
|
||||
isMailConfigured
|
||||
isSchedulerHealthy
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -74,7 +76,8 @@ export const useAdminStore = defineStore('admin', {
|
||||
this.info.currentVersion = clone(resp?.data?.systemInfo?.currentVersion ?? 'n/a')
|
||||
this.info.latestVersion = clone(resp?.data?.systemInfo?.latestVersion ?? 'n/a')
|
||||
this.info.isApiEnabled = clone(resp?.data?.apiState ?? false)
|
||||
this.info.isMailConfigured = clone(resp?.data?.systemInfo?.mailConfigured ?? false)
|
||||
this.info.isMailConfigured = clone(resp?.data?.systemInfo?.isMailConfigured ?? false)
|
||||
this.info.isSchedulerHealthy = clone(resp?.data?.systemInfo?.isSchedulerHealthy ?? false)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+310
@@ -1706,6 +1706,119 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/language-core@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/language-core@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/source-map": 1.0.1
|
||||
"@vue/reactivity": ^3.2.38
|
||||
muggle-string: ^0.1.0
|
||||
checksum: 82bf72742a0b0063df134ed63b2dc3cab07b2ea4a3d7d8bdcad2e6c81fc2163ce8169996ff97aee30c5c84649b10e3a981d7431a3b404a0b7daa1bf783d7c16b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/language-service@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/language-service@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/language-core": 1.0.1
|
||||
"@volar/shared": 1.0.1
|
||||
"@volar/source-map": 1.0.1
|
||||
"@volar/transforms": 1.0.1
|
||||
"@volar/typescript-faster": 1.0.1
|
||||
"@vue/reactivity": ^3.2.38
|
||||
vscode-html-languageservice: ^5.0.1
|
||||
vscode-json-languageservice: ^5.1.0
|
||||
vscode-languageserver-protocol: ^3.17.2
|
||||
vscode-languageserver-textdocument: ^1.0.7
|
||||
vscode-uri: ^3.0.3
|
||||
checksum: f25b09cbb67db0f48f4671cd696b61bdb1f4a1b4d841d2a85940a532c90619d57457cbdef3486cfe0702f793a870003720648eab06bca1739ab938a20aa67bfb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/pug-language-service@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/pug-language-service@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/language-service": 1.0.1
|
||||
"@volar/shared": 1.0.1
|
||||
"@volar/source-map": 1.0.1
|
||||
"@volar/transforms": 1.0.1
|
||||
muggle-string: ^0.1.0
|
||||
pug-lexer: ^5.0.1
|
||||
pug-parser: ^6.0.0
|
||||
vscode-languageserver-textdocument: ^1.0.7
|
||||
vscode-languageserver-types: ^3.17.2
|
||||
checksum: 8e9545877f7c10feaef0faccda09bbbccff8fe4512c32801d15f9a0098acf313e37b10e83157ddabbc4f7f9649239582f71df4affdcc8422c22dea7a3908b107
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/shared@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/shared@npm:1.0.1"
|
||||
dependencies:
|
||||
typesafe-path: ^0.2.1
|
||||
vscode-languageserver-protocol: ^3.17.2
|
||||
vscode-languageserver-textdocument: ^1.0.7
|
||||
vscode-uri: ^3.0.3
|
||||
checksum: 1a09e4ab140b21607bb0bf6a4ae635a94223dd23c6aae3e7e18e11c1f00b46af68b63e81cb44d2563f8acf008848c24ae865a320ee9a26cce4bd76173e56e0a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/source-map@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/source-map@npm:1.0.1"
|
||||
dependencies:
|
||||
muggle-string: ^0.1.0
|
||||
checksum: 333a00484fd667b97fb5f3a339d6a717badf0113fb9352ba042d7ed59e4a5208667362b90d5c4267e7105d187c5f038d67fef71acb9ed52c8a674b149fd3deb8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/transforms@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/transforms@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/shared": 1.0.1
|
||||
vscode-languageserver-types: ^3.17.2
|
||||
checksum: 6a4f357ee8c862dc7882c02c679378b37b9fb14c9fb5123727671c143310eb78def4c8ff1abe14dee6ac54cd0c6a067fb2a2e9e3b508519bc0fc49b630846ba6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/typescript-faster@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/typescript-faster@npm:1.0.1"
|
||||
dependencies:
|
||||
semver: ^7.3.7
|
||||
checksum: e67f47c57574b32381956fd0ff6e20b47ce376d14b10886d2ba7b7fe727d3420673e7ec7e8d53f3504aff7ec7562664e8561cbe6f69acf9b47f15176e95f8bf9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/vue-language-core@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/vue-language-core@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/language-core": 1.0.1
|
||||
"@volar/source-map": 1.0.1
|
||||
"@vue/compiler-dom": ^3.2.38
|
||||
"@vue/compiler-sfc": ^3.2.38
|
||||
"@vue/reactivity": ^3.2.38
|
||||
"@vue/shared": ^3.2.38
|
||||
minimatch: ^5.1.0
|
||||
vue-template-compiler: ^2.7.10
|
||||
checksum: 8c44d5c8ca0f160d0d36fc4bd72bffc86a4f0c786a414b08e0387ec3304daadd33be1b912debd028959318d64c9b857e4abd7efbaae9b4f37aa0e812f6c6444e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@volar/vue-language-plugin-pug@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@volar/vue-language-plugin-pug@npm:1.0.1"
|
||||
dependencies:
|
||||
"@volar/pug-language-service": 1.0.1
|
||||
"@volar/vue-language-core": 1.0.1
|
||||
checksum: 08bbac5cdc5be33dffa4d143aceff8ce0ba9b78aad388cb3ed6df3f1a7b61e0221299ea26758b8d90a20d2c9f221bbe431e9f1526fa67ebd607ba069f894a2f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-core@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/compiler-core@npm:3.2.37"
|
||||
@@ -1718,6 +1831,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-core@npm:3.2.40":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/compiler-core@npm:3.2.40"
|
||||
dependencies:
|
||||
"@babel/parser": ^7.16.4
|
||||
"@vue/shared": 3.2.40
|
||||
estree-walker: ^2.0.2
|
||||
source-map: ^0.6.1
|
||||
checksum: 2683bf13ef93701af1ca4850e887c8d4d67e5583b9c426fc2b08b5512df090bc464955f031cca9f52c11cc6ad49f1ab682011fdf3ba0b6c63b5ae8bea4e68c69
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-dom@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/compiler-dom@npm:3.2.37"
|
||||
@@ -1728,6 +1853,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-dom@npm:3.2.40, @vue/compiler-dom@npm:^3.2.38":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/compiler-dom@npm:3.2.40"
|
||||
dependencies:
|
||||
"@vue/compiler-core": 3.2.40
|
||||
"@vue/shared": 3.2.40
|
||||
checksum: d928a16ebdda9d91a579546d108c9399f8c9a5c9c976196cfefa32f10c0ecb3111233c3291ba05898def85fcfccdc71e3446b977a7cdbc0d47d5d47b0dac75a3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-sfc@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/compiler-sfc@npm:3.2.37"
|
||||
@@ -1746,6 +1881,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-sfc@npm:^3.2.38":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/compiler-sfc@npm:3.2.40"
|
||||
dependencies:
|
||||
"@babel/parser": ^7.16.4
|
||||
"@vue/compiler-core": 3.2.40
|
||||
"@vue/compiler-dom": 3.2.40
|
||||
"@vue/compiler-ssr": 3.2.40
|
||||
"@vue/reactivity-transform": 3.2.40
|
||||
"@vue/shared": 3.2.40
|
||||
estree-walker: ^2.0.2
|
||||
magic-string: ^0.25.7
|
||||
postcss: ^8.1.10
|
||||
source-map: ^0.6.1
|
||||
checksum: 96cbfd078ad9c5718afced84a1a46dfed87f61bb30ff50ebb929331470d11e672d6a090ad5766ff1e60a5287b7596be31f925af44b6b1bdf69b6f14e938ae7e2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-ssr@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/compiler-ssr@npm:3.2.37"
|
||||
@@ -1756,6 +1909,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/compiler-ssr@npm:3.2.40":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/compiler-ssr@npm:3.2.40"
|
||||
dependencies:
|
||||
"@vue/compiler-dom": 3.2.40
|
||||
"@vue/shared": 3.2.40
|
||||
checksum: 026461fcee54cf9968b1e12c32dada6dcde0a322919aa5a2c2e6e13cff7b6b2bdbc06860796895a8deef03ed1f8000e4320878576c498a1f218a62aa3e1c0bf6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/devtools-api@npm:^6.1.4":
|
||||
version: 6.1.4
|
||||
resolution: "@vue/devtools-api@npm:6.1.4"
|
||||
@@ -1783,6 +1946,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/reactivity-transform@npm:3.2.40":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/reactivity-transform@npm:3.2.40"
|
||||
dependencies:
|
||||
"@babel/parser": ^7.16.4
|
||||
"@vue/compiler-core": 3.2.40
|
||||
"@vue/shared": 3.2.40
|
||||
estree-walker: ^2.0.2
|
||||
magic-string: ^0.25.7
|
||||
checksum: b86fc29b52f2460801a3c820370104b734b33cc3a66dbe0ad389a00a62b7a1069121b1ef5dfa50ca3530cbfa98c158743eee0e25af54ca45806f9497757db8c0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/reactivity@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/reactivity@npm:3.2.37"
|
||||
@@ -1792,6 +1968,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/reactivity@npm:^3.2.38":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/reactivity@npm:3.2.40"
|
||||
dependencies:
|
||||
"@vue/shared": 3.2.40
|
||||
checksum: 927d22b424b63a14234810a3b8e4e9127b7238a7cb2fbd749180279048a109348a29fc724fd9d636a6e09b5f4c902f71c789f081d3ab9b4473faedc6a03d7865
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/runtime-core@npm:3.2.37":
|
||||
version: 3.2.37
|
||||
resolution: "@vue/runtime-core@npm:3.2.37"
|
||||
@@ -1832,6 +2017,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vue/shared@npm:3.2.40, @vue/shared@npm:^3.2.38":
|
||||
version: 3.2.40
|
||||
resolution: "@vue/shared@npm:3.2.40"
|
||||
checksum: d91a1e12ffb106a444dcb42c0a54d39f6688f98151dc3b77e8da1e7d3cfd09e1761268d11e7f920f233b43162e727d06f3af4408ef59c53ac2dce9c1d2881511
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@wry/context@npm:^0.6.0":
|
||||
version: 0.6.1
|
||||
resolution: "@wry/context@npm:0.6.1"
|
||||
@@ -2751,6 +2943,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"de-indent@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "de-indent@npm:1.0.2"
|
||||
checksum: 8deacc0f4a397a4414a0fc4d0034d2b7782e7cb4eaf34943ea47754e08eccf309a0e71fa6f56cc48de429ede999a42d6b4bca761bf91683be0095422dbf24611
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:2.6.9, debug@npm:^2.6.9":
|
||||
version: 2.6.9
|
||||
resolution: "debug@npm:2.6.9"
|
||||
@@ -4797,6 +4996,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsonc-parser@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "jsonc-parser@npm:3.2.0"
|
||||
checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsonfile@npm:^6.0.1":
|
||||
version: 6.1.0
|
||||
resolution: "jsonfile@npm:6.1.0"
|
||||
@@ -5131,6 +5337,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "minimatch@npm:5.1.0"
|
||||
dependencies:
|
||||
brace-expansion: ^2.0.1
|
||||
checksum: 15ce53d31a06361e8b7a629501b5c75491bc2b59712d53e802b1987121d91b433d73fcc5be92974fde66b2b51d8fb28d75a9ae900d249feb792bb1ba2a4f0a90
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimist@npm:^1.2.0, minimist@npm:^1.2.6":
|
||||
version: 1.2.6
|
||||
resolution: "minimist@npm:1.2.6"
|
||||
@@ -5245,6 +5460,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"muggle-string@npm:^0.1.0":
|
||||
version: 0.1.0
|
||||
resolution: "muggle-string@npm:0.1.0"
|
||||
checksum: c892cb53c9e066185913e4d6d0af71df6a2a8d8fd614903d13cd6b260c32ebc7b08ae7190a5faf3f7a25ba01cb9be34844d2a069351c090e4a6013f1eee58a50
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mute-stream@npm:0.0.8":
|
||||
version: 0.0.8
|
||||
resolution: "mute-stream@npm:0.0.8"
|
||||
@@ -6887,6 +7109,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typesafe-path@npm:^0.2.1":
|
||||
version: 0.2.1
|
||||
resolution: "typesafe-path@npm:0.2.1"
|
||||
checksum: 6f1ed2fb444939e96b018ff6a255de015572f092fbd6243eae3e2e3ebc79684695f9742d418e02c0deb572747170fd9d5da2b89d66cdaf21085bc5b3756fb507
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uglify-js@npm:^3.5.1":
|
||||
version: 3.15.3
|
||||
resolution: "uglify-js@npm:3.15.3"
|
||||
@@ -7032,6 +7261,7 @@ __metadata:
|
||||
"@tiptap/starter-kit": 2.0.0-beta.185
|
||||
"@tiptap/vue-3": 2.0.0-beta.91
|
||||
"@types/lodash": 4.14.184
|
||||
"@volar/vue-language-plugin-pug": 1.0.1
|
||||
apollo-upload-client: 17.0.0
|
||||
browser-fs-access: 0.31.0
|
||||
browserlist: latest
|
||||
@@ -7161,6 +7391,76 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-html-languageservice@npm:^5.0.1":
|
||||
version: 5.0.2
|
||||
resolution: "vscode-html-languageservice@npm:5.0.2"
|
||||
dependencies:
|
||||
vscode-languageserver-textdocument: ^1.0.7
|
||||
vscode-languageserver-types: ^3.17.2
|
||||
vscode-nls: ^5.2.0
|
||||
vscode-uri: ^3.0.4
|
||||
checksum: 11fa393f2115c1ecc9ff90502cd17c60268e2908ab0b794275d09d51587c9281d2d04897e2e6bd127d2d2b04bd229ed3211f3966eea3cdc5529999a9a1fcd1fb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-json-languageservice@npm:^5.1.0":
|
||||
version: 5.1.1
|
||||
resolution: "vscode-json-languageservice@npm:5.1.1"
|
||||
dependencies:
|
||||
jsonc-parser: ^3.2.0
|
||||
vscode-languageserver-textdocument: ^1.0.7
|
||||
vscode-languageserver-types: ^3.17.2
|
||||
vscode-nls: ^5.2.0
|
||||
vscode-uri: ^3.0.6
|
||||
checksum: ee2910c520572a0342d901b0a94f20c8db3c4cebcfb975529293df6cc7232e406e53c4a80198a6443fe12ba6e6e9513daa2e8f6d52a70fb1c7ce504d3dc44d31
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-jsonrpc@npm:8.0.2":
|
||||
version: 8.0.2
|
||||
resolution: "vscode-jsonrpc@npm:8.0.2"
|
||||
checksum: 9d055fd4c87ef1093b0eecb5370bfaf3402179b6639149b6d0f7e0bde60cf580091c7e07b0caff868f10f90331b17e7383c087217c077fdd1b5ae7bc23b72f77
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-languageserver-protocol@npm:^3.17.2":
|
||||
version: 3.17.2
|
||||
resolution: "vscode-languageserver-protocol@npm:3.17.2"
|
||||
dependencies:
|
||||
vscode-jsonrpc: 8.0.2
|
||||
vscode-languageserver-types: 3.17.2
|
||||
checksum: f4a05d3a631af315a32a3700953c2117fa4e5c44bc03764154c6605da9cbbcb50a1b01b46f11b2f6948916d01b4948bebf1a84c135fc73b27fa839c58d0847ab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-languageserver-textdocument@npm:^1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "vscode-languageserver-textdocument@npm:1.0.7"
|
||||
checksum: 6018a8b2c87aeb6441419431909e9161e9659d214814193b029ca2b30d8b097d23538e4930942ef78f1440f52c57a93f7597144736b79ba1abd9f1a53c2ffbc0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-languageserver-types@npm:3.17.2, vscode-languageserver-types@npm:^3.17.2":
|
||||
version: 3.17.2
|
||||
resolution: "vscode-languageserver-types@npm:3.17.2"
|
||||
checksum: ef2d862d22f622b64de0f428773d50a5928ec6cdd485960a7564ebe4fd4a3c8bcd956f29eb15bc45a0f353846e62f39f6c764d2ab85ce774b8724411ba84342f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-nls@npm:^5.2.0":
|
||||
version: 5.2.0
|
||||
resolution: "vscode-nls@npm:5.2.0"
|
||||
checksum: c9f43c0f85000b3008fc4a3a8fc122e580f4f0402a77186c6c0f3219ca8ac258f4893c7a563d66f097a6da09951d7f5a7e6295d3e21dcbaec707937c9089b5a8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vscode-uri@npm:^3.0.3, vscode-uri@npm:^3.0.4, vscode-uri@npm:^3.0.6":
|
||||
version: 3.0.6
|
||||
resolution: "vscode-uri@npm:3.0.6"
|
||||
checksum: 8b6a36553d089309c09f7aa2ca8dae321a1cb7ff5dcab35f0914d5155d3110722bdb6de67dcb727df15fecd83221d11bb4ab1274a9116b9ccc05b86cefe60dfc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vue-codemirror@npm:6.0.2":
|
||||
version: 6.0.2
|
||||
resolution: "vue-codemirror@npm:6.0.2"
|
||||
@@ -7235,6 +7535,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vue-template-compiler@npm:^2.7.10":
|
||||
version: 2.7.10
|
||||
resolution: "vue-template-compiler@npm:2.7.10"
|
||||
dependencies:
|
||||
de-indent: ^1.0.2
|
||||
he: ^1.2.0
|
||||
checksum: 52e4324d93ea5ecf6875c94eae99d3d4197cfb13538b6c2f5020df1776fb277e329325091c41da596b3cf1c7dabd56f50e2a538e2fc3d5ae23438d08471fdc8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vue3-otp-input@npm:0.3.6":
|
||||
version: 0.3.6
|
||||
resolution: "vue3-otp-input@npm:0.3.6"
|
||||
|
||||
Reference in New Issue
Block a user