|
1 | 1 | import { AdminForthPlugin, AdminForthDataTypes } from "adminforth"; |
2 | 2 | import type { IAdminForth, AdminForthResource } from "adminforth"; |
3 | 3 | import type { PluginOptions } from './types.js'; |
| 4 | +import Validator from 'jsonschema'; |
4 | 5 |
|
5 | 6 | export default class JsonFormPlugin extends AdminForthPlugin { |
6 | 7 | options: PluginOptions; |
@@ -61,5 +62,58 @@ export default class JsonFormPlugin extends AdminForthPlugin { |
61 | 62 |
|
62 | 63 | column.components.create = formComponent; |
63 | 64 | column.components.edit = formComponent; |
| 65 | + |
| 66 | + if (!resourceConfig.hooks) { |
| 67 | + resourceConfig.hooks = {}; |
| 68 | + } |
| 69 | + if (!resourceConfig.hooks.create) { |
| 70 | + resourceConfig.hooks.create = {}; |
| 71 | + } |
| 72 | + if (!resourceConfig.hooks.edit) { |
| 73 | + resourceConfig.hooks.edit = {}; |
| 74 | + } |
| 75 | + |
| 76 | + const pushHook = (hooks: { beforeSave?: any }, fn: any) => { |
| 77 | + if (Array.isArray(hooks.beforeSave)) { |
| 78 | + hooks.beforeSave.push(fn); |
| 79 | + } else if (hooks.beforeSave) { |
| 80 | + hooks.beforeSave = [hooks.beforeSave, fn]; |
| 81 | + } else { |
| 82 | + hooks.beforeSave = [fn]; |
| 83 | + } |
| 84 | + }; |
| 85 | + |
| 86 | + pushHook(resourceConfig.hooks.create, async ({ record }: { record: any }) => { |
| 87 | + return this.validateRecord(record); |
| 88 | + }); |
| 89 | + pushHook(resourceConfig.hooks.edit, async ({ updates }: { updates: any }) => { |
| 90 | + if (!(this.options.fieldName in updates)) { |
| 91 | + return { ok: true }; |
| 92 | + } |
| 93 | + return this.validateRecord(updates); |
| 94 | + }); |
| 95 | + } |
| 96 | + |
| 97 | + validateRecord(record: any): { ok: boolean; error?: string } { |
| 98 | + const value = record?.[this.options.fieldName]; |
| 99 | + |
| 100 | + if (value === undefined || value === null) { |
| 101 | + return { ok: true }; |
| 102 | + } |
| 103 | + |
| 104 | + const validator = new Validator.Validator(); |
| 105 | + const result = validator.validate(value, this.options.schema, { nestedErrors: true }); |
| 106 | + |
| 107 | + if (!result.valid) { |
| 108 | + const message = result.errors |
| 109 | + .map((e) => `${e.property.replace(/^instance/, this.options.fieldName)} ${e.message}`) |
| 110 | + .join('; '); |
| 111 | + return { |
| 112 | + ok: false, |
| 113 | + error: `[JsonForm] Invalid value for "${this.options.fieldName}": ${message}`, |
| 114 | + }; |
| 115 | + } |
| 116 | + |
| 117 | + return { ok: true }; |
64 | 118 | } |
65 | 119 | } |
0 commit comments