best-lowcode-runtime 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.js +8 -0
- package/dist/dev.js.map +2 -2
- package/dist/index.css +64 -13
- package/dist/index.css.map +3 -3
- package/dist/index.js +67 -35
- package/dist/index.js.map +3 -3
- package/dist/lowcode/BestCrudPage.d.ts +1 -1
- package/dist/lowcode/BestCrudPage.d.ts.map +1 -1
- package/dist/lowcode/index.d.ts +1 -1
- package/dist/lowcode/index.d.ts.map +1 -1
- package/dist/lowcode/schema.d.ts +4 -0
- package/dist/lowcode/schema.d.ts.map +1 -1
- package/dist/lowcode/validate.d.ts.map +1 -1
- package/dist/runtime/BestProvider.d.ts +5 -1
- package/dist/runtime/BestProvider.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/ui/BestBatchInput.d.ts +1 -1
- package/dist/ui/BestBatchInput.d.ts.map +1 -1
- package/dist/ui/BestDetail.d.ts +1 -1
- package/dist/ui/BestDetail.d.ts.map +1 -1
- package/dist/ui/BestFilePreview.d.ts +1 -1
- package/dist/ui/BestFilePreview.d.ts.map +1 -1
- package/dist/ui/BestForm.d.ts +4 -11
- package/dist/ui/BestForm.d.ts.map +1 -1
- package/dist/ui/BestLightTable.d.ts +1 -1
- package/dist/ui/BestLightTable.d.ts.map +1 -1
- package/dist/ui/BestOverlay.d.ts +2 -2
- package/dist/ui/BestOverlay.d.ts.map +1 -1
- package/dist/ui/BestSearch.d.ts +3 -2
- package/dist/ui/BestSearch.d.ts.map +1 -1
- package/dist/ui/BestStates.d.ts +3 -3
- package/dist/ui/BestStates.d.ts.map +1 -1
- package/dist/ui/BestTable.d.ts +2 -1
- package/dist/ui/BestTable.d.ts.map +1 -1
- package/package.json +8 -16
package/dist/dev.js
CHANGED
|
@@ -188,6 +188,14 @@ function validateCrudPageSchema(schema, registry) {
|
|
|
188
188
|
if (!schema.table?.columns?.length)
|
|
189
189
|
push(diagnostics, "/table/columns", "table.columns", "\u81F3\u5C11\u9700\u8981\u4E00\u5217");
|
|
190
190
|
schema.table?.columns?.forEach((column, index) => {
|
|
191
|
+
if (column.fixed !== void 0 && column.fixed !== "left" && column.fixed !== "right") {
|
|
192
|
+
push(
|
|
193
|
+
diagnostics,
|
|
194
|
+
`/table/columns/${index}/fixed`,
|
|
195
|
+
"column.fixed",
|
|
196
|
+
`\u4E0D\u652F\u6301\u7684\u56FA\u5B9A\u4F4D\u7F6E\uFF1A${column.fixed}`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
191
199
|
if (column.format && !columnFormats.has(column.format)) {
|
|
192
200
|
push(
|
|
193
201
|
diagnostics,
|
package/dist/dev.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/lowcode/schema.ts", "../src/lowcode/validate.ts", "../src/lowcode/dev.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BestFieldComponent, BestFieldRule } from '../ui/types'\n\nexport const CRUD_SCHEMA_ID = 'https://best.dev/schema/crud/v1' as const\nexport const CRUD_SCHEMA_VERSION = 1 as const\n\nexport type Condition =\n | { operator: 'equals'; field: string; value: string | number | boolean | null }\n | { operator: 'notEmpty'; field: string }\n | { operator: 'modeEquals'; value: FormMode }\n | { operator: 'and' | 'or'; conditions: Condition[] }\n | { operator: 'not'; condition: Condition }\n\nexport type FormMode = 'create' | 'edit' | 'detail'\n\nexport type FieldSchema = {\n field: string\n label: string\n component: BestFieldComponent\n placeholder?: string\n dict?: string\n required?: boolean\n disabled?: boolean\n hidden?: boolean\n maxDate?: 'today'\n span?: number\n defaultValue?: string | number | boolean | null\n rules?: BestFieldRule[]\n /** Application-specific form control registered in the BestProvider registry. */\n slot?: string\n remoteService?: string\n searchField?: string\n labelField?: string\n valueField?: string\n debounceMs?: number\n pageSize?: number\n visibleWhen?: Condition\n disabledWhen?: Condition\n /** Clears stale dependent values when this field becomes hidden. */\n clearWhenHidden?: boolean\n /** Repeated object fields, for rules such as tiered pricing. */\n itemFields?: Omit<FieldSchema, 'itemFields'>[]\n minItems?: number\n maxItems?: number\n}\n\nexport type TableColumnSchema = {\n field: string\n title: string\n dict?: string\n width?: number\n format?: 'date' | 'datetime' | 'money' | 'text'\n slot?: string\n}\n\nexport type DetailFieldSchema = {\n field: string\n label: string\n dict?: string\n span?: number\n slot?: string\n}\n\nexport type PageActionSchema = {\n id: string\n label: string\n effect: 'openCreate' | 'openDetail' | 'openEdit' | 'remove' | 'runAction' | 'slot'\n action?: string\n slot?: string\n access?: string\n confirm?: string\n}\n\nexport type CrudPageSchema = {\n $schema: typeof CRUD_SCHEMA_ID\n version: typeof CRUD_SCHEMA_VERSION\n id: string\n kind: 'crud'\n title: string\n dataSource: {\n list: string\n detail?: string\n create?: string\n update?: string\n remove?: string\n }\n search?: FieldSchema[]\n searchMode?: 'proTable' | 'bestSearch'\n form?: FieldSchema[]\n table: {\n rowKey: string | string[]\n columns: TableColumnSchema[]\n actions?: PageActionSchema[]\n scrollX?: number\n pageSize?: number\n }\n detail?: { fields: DetailFieldSchema[] }\n toolbar?: PageActionSchema[]\n meta?: {\n generatedBy?: string\n generatedAt?: string\n }\n}\n", "import type { BestRegistry } from '../runtime'\nimport {\n type Condition,\n CRUD_SCHEMA_ID,\n CRUD_SCHEMA_VERSION,\n type CrudPageSchema,\n type FieldSchema,\n type PageActionSchema\n} from './schema'\n\nexport type SchemaDiagnostic = {\n path: string\n code: string\n message: string\n}\n\nexport type SchemaValidationResult = {\n valid: boolean\n diagnostics: SchemaDiagnostic[]\n}\n\nconst fieldComponents = new Set([\n 'input',\n 'number',\n 'select',\n 'remoteSelect',\n 'date',\n 'dateRange',\n 'textarea',\n 'slot',\n 'repeatable'\n])\nconst builtInEffects = new Set([\n 'openCreate',\n 'openDetail',\n 'openEdit',\n 'remove',\n 'runAction',\n 'slot'\n])\nconst columnFormats = new Set(['date', 'datetime', 'money', 'text'])\n\nfunction push(diagnostics: SchemaDiagnostic[], path: string, code: string, message: string) {\n diagnostics.push({ path, code, message })\n}\n\nfunction validateCondition(condition: Condition, path: string, diagnostics: SchemaDiagnostic[]) {\n if (!condition || typeof condition !== 'object') {\n push(diagnostics, path, 'condition.type', '\u6761\u4EF6\u5FC5\u987B\u662F\u5BF9\u8C61')\n return\n }\n if (condition.operator === 'equals') {\n if (typeof condition.field !== 'string' || condition.field === '') {\n push(diagnostics, path, 'condition.field', 'equals \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A\u5B57\u6BB5\u540D')\n }\n return\n }\n if (condition.operator === 'notEmpty') {\n if (typeof condition.field !== 'string' || condition.field === '') {\n push(diagnostics, path, 'condition.field', 'notEmpty \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A\u5B57\u6BB5\u540D')\n }\n return\n }\n if (condition.operator === 'modeEquals') {\n return\n }\n if (\n (condition.operator === 'and' || condition.operator === 'or') &&\n !Array.isArray(condition.conditions)\n ) {\n push(diagnostics, path, 'condition.conditions', '\u7EC4\u5408\u6761\u4EF6\u5FC5\u987B\u6307\u5B9A conditions \u6570\u7EC4')\n return\n }\n if (condition.operator === 'and' || condition.operator === 'or') {\n if (condition.conditions.length === 0) {\n push(diagnostics, path, 'condition.empty', '\u7EC4\u5408\u6761\u4EF6\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5B50\u6761\u4EF6')\n }\n condition.conditions.forEach((item, index) => {\n validateCondition(item, `${path}/conditions/${index}`, diagnostics)\n })\n return\n }\n if (condition.operator === 'not') {\n if (!condition.condition) {\n push(diagnostics, path, 'condition.missing', 'not \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A condition')\n return\n }\n validateCondition(condition.condition, `${path}/condition`, diagnostics)\n return\n }\n push(diagnostics, path, 'condition.operator', `\u4E0D\u652F\u6301\u7684\u6761\u4EF6\uFF1A${(condition as { operator?: unknown }).operator}`)\n}\n\nfunction validateFields(\n fields: FieldSchema[] | undefined,\n path: string,\n registry: BestRegistry | undefined,\n diagnostics: SchemaDiagnostic[]\n) {\n const seen = new Set<string>()\n fields?.forEach((field, index) => {\n const fieldPath = `${path}/${index}`\n if (!field.field) push(diagnostics, fieldPath, 'field.missing', '\u5B57\u6BB5\u540D\u4E0D\u80FD\u4E3A\u7A7A')\n if (seen.has(field.field))\n push(diagnostics, fieldPath, 'field.duplicate', `\u5B57\u6BB5\u91CD\u590D\uFF1A${field.field}`)\n seen.add(field.field)\n if (!fieldComponents.has(field.component))\n push(diagnostics, fieldPath, 'field.component', `\u4E0D\u652F\u6301\u7684\u7EC4\u4EF6\uFF1A${field.component}`)\n if (field.dict && registry && !registry.dictionaries[field.dict]) {\n push(diagnostics, fieldPath, 'registry.dictionary', `\u672A\u6CE8\u518C\u5B57\u5178\uFF1A${field.dict}`)\n }\n if (field.component === 'remoteSelect' && !field.remoteService)\n push(diagnostics, fieldPath, 'field.remoteService', 'remoteSelect \u5FC5\u987B\u6307\u5B9A remoteService')\n if (field.remoteService && registry && !registry.services[field.remoteService])\n push(diagnostics, fieldPath, 'registry.service', `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${field.remoteService}`)\n if (field.component === 'slot' && !field.slot)\n push(diagnostics, fieldPath, 'field.slot', 'slot \u7EC4\u4EF6\u5FC5\u987B\u6307\u5B9A slot key')\n if (field.component === 'repeatable' && !field.itemFields?.length)\n push(\n diagnostics,\n fieldPath,\n 'field.repeatable',\n 'repeatable \u7EC4\u4EF6\u81F3\u5C11\u9700\u8981\u4E00\u4E2A itemFields \u5B57\u6BB5'\n )\n if (field.itemFields?.length)\n validateFields(\n field.itemFields as FieldSchema[],\n `${fieldPath}/itemFields`,\n registry,\n diagnostics\n )\n if (\n field.minItems !== undefined &&\n field.maxItems !== undefined &&\n field.minItems > field.maxItems\n )\n push(diagnostics, fieldPath, 'field.repeatable.range', 'minItems \u4E0D\u80FD\u5927\u4E8E maxItems')\n if (field.slot && registry && !registry.slots[field.slot])\n push(diagnostics, fieldPath, 'registry.slot', `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${field.slot}`)\n if (field.visibleWhen)\n validateCondition(field.visibleWhen, `${fieldPath}/visibleWhen`, diagnostics)\n if (field.disabledWhen)\n validateCondition(field.disabledWhen, `${fieldPath}/disabledWhen`, diagnostics)\n })\n}\n\nfunction validateActions(\n actions: PageActionSchema[] | undefined,\n path: string,\n registry: BestRegistry | undefined,\n hasRemoveService: boolean,\n diagnostics: SchemaDiagnostic[]\n) {\n actions?.forEach((action, index) => {\n const actionPath = `${path}/${index}`\n if (!action.id) push(diagnostics, actionPath, 'action.missing', '\u52A8\u4F5C id \u4E0D\u80FD\u4E3A\u7A7A')\n if (!builtInEffects.has(action.effect))\n push(diagnostics, actionPath, 'action.effect', `\u4E0D\u652F\u6301\u7684\u52A8\u4F5C\uFF1A${action.effect}`)\n if (action.effect === 'runAction' && !action.action)\n push(diagnostics, actionPath, 'action.key', 'runAction \u5FC5\u987B\u6307\u5B9A action key')\n if (action.effect === 'remove' && !hasRemoveService)\n push(diagnostics, actionPath, 'action.removeService', 'remove \u52A8\u4F5C\u5FC5\u987B\u914D\u7F6E dataSource.remove')\n if (action.effect === 'slot' && !action.slot)\n push(diagnostics, actionPath, 'action.slot', 'slot \u52A8\u4F5C\u5FC5\u987B\u6307\u5B9A slot key')\n if (action.action && registry && !registry.actions[action.action]) {\n push(diagnostics, actionPath, 'registry.action', `\u672A\u6CE8\u518C\u52A8\u4F5C\uFF1A${action.action}`)\n }\n if (action.slot && registry && !registry.slots[action.slot]) {\n push(diagnostics, actionPath, 'registry.slot', `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${action.slot}`)\n }\n })\n}\n\nexport function validateCrudPageSchema(\n schema: CrudPageSchema,\n registry?: BestRegistry\n): SchemaValidationResult {\n const diagnostics: SchemaDiagnostic[] = []\n if (schema.$schema !== CRUD_SCHEMA_ID)\n push(diagnostics, '/$schema', 'schema.id', `\u4EC5\u652F\u6301 ${CRUD_SCHEMA_ID}`)\n if (schema.version !== CRUD_SCHEMA_VERSION)\n push(diagnostics, '/version', 'schema.version', `\u4EC5\u652F\u6301\u7248\u672C ${CRUD_SCHEMA_VERSION}`)\n if (!schema.id) push(diagnostics, '/id', 'page.id', '\u9875\u9762 id \u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.title) push(diagnostics, '/title', 'page.title', '\u9875\u9762\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.dataSource?.list)\n push(diagnostics, '/dataSource/list', 'service.list', '\u5217\u8868\u670D\u52A1\u4E0D\u80FD\u4E3A\u7A7A')\n if (schema.dataSource?.list && registry && !registry.listServices[schema.dataSource.list]) {\n push(\n diagnostics,\n '/dataSource/list',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.list}`\n )\n }\n if (schema.dataSource?.detail && registry && !registry.services[schema.dataSource.detail]) {\n push(\n diagnostics,\n '/dataSource/detail',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.detail}`\n )\n }\n if (schema.dataSource?.create && registry && !registry.services[schema.dataSource.create]) {\n push(\n diagnostics,\n '/dataSource/create',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.create}`\n )\n }\n if (schema.dataSource?.update && registry && !registry.services[schema.dataSource.update]) {\n push(\n diagnostics,\n '/dataSource/update',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.update}`\n )\n }\n if (schema.dataSource?.remove && registry && !registry.services[schema.dataSource.remove]) {\n push(\n diagnostics,\n '/dataSource/remove',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.remove}`\n )\n }\n validateFields(schema.search, '/search', registry, diagnostics)\n validateFields(schema.form, '/form', registry, diagnostics)\n if (!schema.table?.rowKey) push(diagnostics, '/table/rowKey', 'table.rowKey', 'rowKey \u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.table?.columns?.length)\n push(diagnostics, '/table/columns', 'table.columns', '\u81F3\u5C11\u9700\u8981\u4E00\u5217')\n schema.table?.columns?.forEach((column, index) => {\n if (column.format && !columnFormats.has(column.format)) {\n push(\n diagnostics,\n `/table/columns/${index}/format`,\n 'column.format',\n `\u4E0D\u652F\u6301\u7684\u683C\u5F0F\uFF1A${column.format}`\n )\n }\n if (column.dict && registry && !registry.dictionaries[column.dict]) {\n push(\n diagnostics,\n `/table/columns/${index}/dict`,\n 'registry.dictionary',\n `\u672A\u6CE8\u518C\u5B57\u5178\uFF1A${column.dict}`\n )\n }\n if (column.slot && registry && !registry.slots[column.slot]) {\n push(\n diagnostics,\n `/table/columns/${index}/slot`,\n 'registry.slot',\n `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${column.slot}`\n )\n }\n })\n if (schema.detail !== undefined) {\n if (\n !schema.detail ||\n typeof schema.detail !== 'object' ||\n !Array.isArray(schema.detail.fields)\n ) {\n push(diagnostics, '/detail', 'detail.type', 'detail \u5FC5\u987B\u5305\u542B fields \u5BF9\u8C61\u6570\u7EC4')\n } else {\n schema.detail.fields.forEach((field, index) => {\n if (field.slot && registry && !registry.slots[field.slot])\n push(\n diagnostics,\n `/detail/fields/${index}/slot`,\n 'registry.slot',\n `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${field.slot}`\n )\n })\n }\n }\n validateActions(\n schema.table?.actions,\n '/table/actions',\n registry,\n Boolean(schema.dataSource?.remove),\n diagnostics\n )\n validateActions(\n schema.toolbar,\n '/toolbar',\n registry,\n Boolean(schema.dataSource?.remove),\n diagnostics\n )\n return { valid: diagnostics.length === 0, diagnostics }\n}\n\nexport function assertValidCrudPageSchema(schema: CrudPageSchema, registry?: BestRegistry) {\n const result = validateCrudPageSchema(schema, registry)\n if (!result.valid) {\n const message = result.diagnostics.map((item) => `${item.path}: ${item.message}`).join('\\n')\n throw new Error(`Schema \u6821\u9A8C\u5931\u8D25\uFF1A\\n${message}`)\n }\n}\n", "import type {\n CRUD_SCHEMA_ID,\n CRUD_SCHEMA_VERSION,\n CrudPageSchema,\n FieldSchema,\n PageActionSchema\n} from './schema'\nimport type { SchemaDiagnostic, SchemaValidationResult } from './validate'\nimport { validateCrudPageSchema } from './validate'\n\nconst builtInCapabilities = [\n 'builtin.effect.openCreate',\n 'builtin.effect.openDetail',\n 'builtin.effect.openEdit',\n 'builtin.effect.remove',\n 'builtin.effect.runAction',\n 'builtin.effect.slot',\n 'builtin.format.date',\n 'builtin.format.datetime',\n 'builtin.format.money',\n 'builtin.format.text',\n 'builtin.field.input',\n 'builtin.field.number',\n 'builtin.field.select',\n 'builtin.field.remoteSelect',\n 'builtin.field.date',\n 'builtin.field.dateRange',\n 'builtin.field.textarea',\n 'builtin.field.slot',\n 'builtin.field.repeatable'\n] as const\n\ntype JsonRecord = Record<string, unknown>\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction arrayOfRecords(value: unknown): JsonRecord[] | undefined {\n return Array.isArray(value) && value.every(isRecord) ? value : undefined\n}\n\nfunction diagnostic(path: string, code: string, message: string): SchemaDiagnostic {\n return { path, code, message }\n}\n\nfunction validateUnknownShape(candidate: unknown): SchemaDiagnostic[] {\n if (!isRecord(candidate)) return [diagnostic('', 'schema.type', 'Schema \u5FC5\u987B\u662F JSON \u5BF9\u8C61')]\n const diagnostics: SchemaDiagnostic[] = []\n if (!isRecord(candidate.dataSource))\n diagnostics.push(diagnostic('/dataSource', 'dataSource.type', 'dataSource \u5FC5\u987B\u662F\u5BF9\u8C61'))\n if (!isRecord(candidate.table))\n diagnostics.push(diagnostic('/table', 'table.type', 'table \u5FC5\u987B\u662F\u5BF9\u8C61'))\n for (const key of ['search', 'form'] as const) {\n if (candidate[key] !== undefined && !arrayOfRecords(candidate[key])) {\n diagnostics.push(diagnostic(`/${key}`, 'field.list', `${key} \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4`))\n }\n }\n if (isRecord(candidate.table)) {\n if (!arrayOfRecords(candidate.table.columns)) {\n diagnostics.push(diagnostic('/table/columns', 'column.list', 'columns \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n if (candidate.table.actions !== undefined && !arrayOfRecords(candidate.table.actions)) {\n diagnostics.push(diagnostic('/table/actions', 'action.list', 'actions \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n }\n if (candidate.toolbar !== undefined && !arrayOfRecords(candidate.toolbar)) {\n diagnostics.push(diagnostic('/toolbar', 'action.list', 'toolbar \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n return diagnostics\n}\n\nfunction toRuntimeSchema(candidate: JsonRecord): CrudPageSchema {\n return {\n $schema: candidate.$schema as typeof CRUD_SCHEMA_ID,\n version: candidate.version as typeof CRUD_SCHEMA_VERSION,\n id: candidate.id as string,\n kind: candidate.kind as 'crud',\n title: candidate.title as string,\n dataSource: candidate.dataSource as CrudPageSchema['dataSource'],\n search: candidate.search as FieldSchema[] | undefined,\n searchMode: candidate.searchMode as CrudPageSchema['searchMode'],\n form: candidate.form as FieldSchema[] | undefined,\n table: candidate.table as CrudPageSchema['table'],\n detail: candidate.detail as CrudPageSchema['detail'],\n toolbar: candidate.toolbar as PageActionSchema[] | undefined,\n meta: candidate.meta as CrudPageSchema['meta']\n }\n}\n\n/**\n * Server-safe development entry. It accepts unknown JSON from CLI/MCP before delegating to the\n * runtime validator, so untrusted candidates cannot trigger assumptions in typed runtime code.\n */\nexport function validateUnknownCrudPageSchema(candidate: unknown): SchemaValidationResult {\n const shapeDiagnostics = validateUnknownShape(candidate)\n if (shapeDiagnostics.length || !isRecord(candidate)) {\n return { valid: false, diagnostics: shapeDiagnostics }\n }\n return validateCrudPageSchema(toRuntimeSchema(candidate))\n}\n\n/** Serializable capabilities supplied by the current runtime without application Manifest entries. */\nexport function getBuiltinCapabilities(): string[] {\n return [...builtInCapabilities]\n}\n"],
|
|
5
|
-
"mappings": ";AAEO,IAAM,iBAAiB;AACvB,IAAM,sBAAsB;;;ACkBnC,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,QAAQ,YAAY,SAAS,MAAM,CAAC;AAEnE,SAAS,KAAK,aAAiC,MAAc,MAAc,SAAiB;AAC1F,cAAY,KAAK,EAAE,MAAM,MAAM,QAAQ,CAAC;AAC1C;AAEA,SAAS,kBAAkB,WAAsB,MAAc,aAAiC;AAC9F,MAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAC/C,SAAK,aAAa,MAAM,kBAAkB,4CAAS;AACnD;AAAA,EACF;AACA,MAAI,UAAU,aAAa,UAAU;AACnC,QAAI,OAAO,UAAU,UAAU,YAAY,UAAU,UAAU,IAAI;AACjE,WAAK,aAAa,MAAM,mBAAmB,+DAAkB;AAAA,IAC/D;AACA;AAAA,EACF;AACA,MAAI,UAAU,aAAa,YAAY;AACrC,QAAI,OAAO,UAAU,UAAU,YAAY,UAAU,UAAU,IAAI;AACjE,WAAK,aAAa,MAAM,mBAAmB,iEAAoB;AAAA,IACjE;AACA;AAAA,EACF;AACA,MAAI,UAAU,aAAa,cAAc;AACvC;AAAA,EACF;AACA,OACG,UAAU,aAAa,SAAS,UAAU,aAAa,SACxD,CAAC,MAAM,QAAQ,UAAU,UAAU,GACnC;AACA,SAAK,aAAa,MAAM,wBAAwB,0EAAwB;AACxE;AAAA,EACF;AACA,MAAI,UAAU,aAAa,SAAS,UAAU,aAAa,MAAM;AAC/D,QAAI,UAAU,WAAW,WAAW,GAAG;AACrC,WAAK,aAAa,MAAM,mBAAmB,gFAAe;AAAA,IAC5D;AACA,cAAU,WAAW,QAAQ,CAAC,MAAM,UAAU;AAC5C,wBAAkB,MAAM,GAAG,IAAI,eAAe,KAAK,IAAI,WAAW;AAAA,IACpE,CAAC;AACD;AAAA,EACF;AACA,MAAI,UAAU,aAAa,OAAO;AAChC,QAAI,CAAC,UAAU,WAAW;AACxB,WAAK,aAAa,MAAM,qBAAqB,oDAAsB;AACnE;AAAA,IACF;AACA,sBAAkB,UAAU,WAAW,GAAG,IAAI,cAAc,WAAW;AACvE;AAAA,EACF;AACA,OAAK,aAAa,MAAM,sBAAsB,6CAAW,UAAqC,QAAQ,EAAE;AAC1G;AAEA,SAAS,eACP,QACA,MACA,UACA,aACA;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,UAAQ,QAAQ,CAAC,OAAO,UAAU;AAChC,UAAM,YAAY,GAAG,IAAI,IAAI,KAAK;AAClC,QAAI,CAAC,MAAM,MAAO,MAAK,aAAa,WAAW,iBAAiB,4CAAS;AACzE,QAAI,KAAK,IAAI,MAAM,KAAK;AACtB,WAAK,aAAa,WAAW,mBAAmB,iCAAQ,MAAM,KAAK,EAAE;AACvE,SAAK,IAAI,MAAM,KAAK;AACpB,QAAI,CAAC,gBAAgB,IAAI,MAAM,SAAS;AACtC,WAAK,aAAa,WAAW,mBAAmB,6CAAU,MAAM,SAAS,EAAE;AAC7E,QAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,aAAa,MAAM,IAAI,GAAG;AAChE,WAAK,aAAa,WAAW,uBAAuB,uCAAS,MAAM,IAAI,EAAE;AAAA,IAC3E;AACA,QAAI,MAAM,cAAc,kBAAkB,CAAC,MAAM;AAC/C,WAAK,aAAa,WAAW,uBAAuB,qDAAiC;AACvF,QAAI,MAAM,iBAAiB,YAAY,CAAC,SAAS,SAAS,MAAM,aAAa;AAC3E,WAAK,aAAa,WAAW,oBAAoB,uCAAS,MAAM,aAAa,EAAE;AACjF,QAAI,MAAM,cAAc,UAAU,CAAC,MAAM;AACvC,WAAK,aAAa,WAAW,cAAc,oDAAsB;AACnE,QAAI,MAAM,cAAc,gBAAgB,CAAC,MAAM,YAAY;AACzD;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACF,QAAI,MAAM,YAAY;AACpB;AAAA,QACE,MAAM;AAAA,QACN,GAAG,SAAS;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AACF,QACE,MAAM,aAAa,UACnB,MAAM,aAAa,UACnB,MAAM,WAAW,MAAM;AAEvB,WAAK,aAAa,WAAW,0BAA0B,4CAAwB;AACjF,QAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,MAAM,MAAM,IAAI;AACtD,WAAK,aAAa,WAAW,iBAAiB,uCAAS,MAAM,IAAI,EAAE;AACrE,QAAI,MAAM;AACR,wBAAkB,MAAM,aAAa,GAAG,SAAS,gBAAgB,WAAW;AAC9E,QAAI,MAAM;AACR,wBAAkB,MAAM,cAAc,GAAG,SAAS,iBAAiB,WAAW;AAAA,EAClF,CAAC;AACH;AAEA,SAAS,gBACP,SACA,MACA,UACA,kBACA,aACA;AACA,WAAS,QAAQ,CAAC,QAAQ,UAAU;AAClC,UAAM,aAAa,GAAG,IAAI,IAAI,KAAK;AACnC,QAAI,CAAC,OAAO,GAAI,MAAK,aAAa,YAAY,kBAAkB,0CAAY;AAC5E,QAAI,CAAC,eAAe,IAAI,OAAO,MAAM;AACnC,WAAK,aAAa,YAAY,iBAAiB,6CAAU,OAAO,MAAM,EAAE;AAC1E,QAAI,OAAO,WAAW,eAAe,CAAC,OAAO;AAC3C,WAAK,aAAa,YAAY,cAAc,+CAA2B;AACzE,QAAI,OAAO,WAAW,YAAY,CAAC;AACjC,WAAK,aAAa,YAAY,wBAAwB,+DAAiC;AACzF,QAAI,OAAO,WAAW,UAAU,CAAC,OAAO;AACtC,WAAK,aAAa,YAAY,eAAe,oDAAsB;AACrE,QAAI,OAAO,UAAU,YAAY,CAAC,SAAS,QAAQ,OAAO,MAAM,GAAG;AACjE,WAAK,aAAa,YAAY,mBAAmB,uCAAS,OAAO,MAAM,EAAE;AAAA,IAC3E;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,MAAM,OAAO,IAAI,GAAG;AAC3D,WAAK,aAAa,YAAY,iBAAiB,uCAAS,OAAO,IAAI,EAAE;AAAA,IACvE;AAAA,EACF,CAAC;AACH;AAEO,SAAS,uBACd,QACA,UACwB;AACxB,QAAM,cAAkC,CAAC;AACzC,MAAI,OAAO,YAAY;AACrB,SAAK,aAAa,YAAY,aAAa,sBAAO,cAAc,EAAE;AACpE,MAAI,OAAO,YAAY;AACrB,SAAK,aAAa,YAAY,kBAAkB,kCAAS,mBAAmB,EAAE;AAChF,MAAI,CAAC,OAAO,GAAI,MAAK,aAAa,OAAO,WAAW,0CAAY;AAChE,MAAI,CAAC,OAAO,MAAO,MAAK,aAAa,UAAU,cAAc,kDAAU;AACvE,MAAI,CAAC,OAAO,YAAY;AACtB,SAAK,aAAa,oBAAoB,gBAAgB,kDAAU;AAClE,MAAI,OAAO,YAAY,QAAQ,YAAY,CAAC,SAAS,aAAa,OAAO,WAAW,IAAI,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,IAAI;AAAA,IACjC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,iBAAe,OAAO,QAAQ,WAAW,UAAU,WAAW;AAC9D,iBAAe,OAAO,MAAM,SAAS,UAAU,WAAW;AAC1D,MAAI,CAAC,OAAO,OAAO,OAAQ,MAAK,aAAa,iBAAiB,gBAAgB,iCAAa;AAC3F,MAAI,CAAC,OAAO,OAAO,SAAS;AAC1B,SAAK,aAAa,kBAAkB,iBAAiB,sCAAQ;AAC/D,SAAO,OAAO,SAAS,QAAQ,CAAC,QAAQ,UAAU;AAChD,QAAI,OAAO,UAAU,CAAC,cAAc,IAAI,OAAO,MAAM,GAAG;AACtD;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,6CAAU,OAAO,MAAM;AAAA,MACzB;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,aAAa,OAAO,IAAI,GAAG;AAClE;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,uCAAS,OAAO,IAAI;AAAA,MACtB;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,MAAM,OAAO,IAAI,GAAG;AAC3D;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,uCAAS,OAAO,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI,OAAO,WAAW,QAAW;AAC/B,QACE,CAAC,OAAO,UACR,OAAO,OAAO,WAAW,YACzB,CAAC,MAAM,QAAQ,OAAO,OAAO,MAAM,GACnC;AACA,WAAK,aAAa,WAAW,eAAe,iEAAyB;AAAA,IACvE,OAAO;AACL,aAAO,OAAO,OAAO,QAAQ,CAAC,OAAO,UAAU;AAC7C,YAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,MAAM,MAAM,IAAI;AACtD;AAAA,YACE;AAAA,YACA,kBAAkB,KAAK;AAAA,YACvB;AAAA,YACA,uCAAS,MAAM,IAAI;AAAA,UACrB;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACA;AAAA,IACE,OAAO,OAAO;AAAA,IACd;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,YAAY,MAAM;AAAA,IACjC;AAAA,EACF;AACA;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,YAAY,MAAM;AAAA,IACjC;AAAA,EACF;AACA,SAAO,EAAE,OAAO,YAAY,WAAW,GAAG,YAAY;AACxD;;;
|
|
4
|
+
"sourcesContent": ["import type { BestFieldComponent, BestFieldRule } from '../ui/types'\n\nexport const CRUD_SCHEMA_ID = 'https://best.dev/schema/crud/v1' as const\nexport const CRUD_SCHEMA_VERSION = 1 as const\n\nexport type Condition =\n | { operator: 'equals'; field: string; value: string | number | boolean | null }\n | { operator: 'notEmpty'; field: string }\n | { operator: 'modeEquals'; value: FormMode }\n | { operator: 'and' | 'or'; conditions: Condition[] }\n | { operator: 'not'; condition: Condition }\n\nexport type FormMode = 'create' | 'edit' | 'detail'\n\nexport type FieldSchema = {\n field: string\n label: string\n component: BestFieldComponent\n placeholder?: string\n dict?: string\n required?: boolean\n disabled?: boolean\n hidden?: boolean\n maxDate?: 'today'\n span?: number\n defaultValue?: string | number | boolean | null\n rules?: BestFieldRule[]\n /** Application-specific form control registered in the BestProvider registry. */\n slot?: string\n remoteService?: string\n searchField?: string\n labelField?: string\n valueField?: string\n debounceMs?: number\n pageSize?: number\n visibleWhen?: Condition\n disabledWhen?: Condition\n /** Clears stale dependent values when this field becomes hidden. */\n clearWhenHidden?: boolean\n /** Repeated object fields, for rules such as tiered pricing. */\n itemFields?: Omit<FieldSchema, 'itemFields'>[]\n minItems?: number\n maxItems?: number\n}\n\nexport type TableColumnSchema = {\n field: string\n title: string\n dict?: string\n width?: number\n fixed?: 'left' | 'right'\n format?: 'date' | 'datetime' | 'money' | 'text'\n slot?: string\n}\n\nexport type DetailFieldSchema = {\n field: string\n label: string\n dict?: string\n span?: number\n slot?: string\n}\n\nexport type PageActionButtonType = 'primary' | 'default' | 'link' | 'text' | 'dashed'\n\nexport type PageActionSchema = {\n id: string\n label: string\n effect: 'openCreate' | 'openDetail' | 'openEdit' | 'remove' | 'runAction' | 'slot'\n action?: string\n slot?: string\n access?: string\n confirm?: string\n /** Visual button style; omitted actions use the runtime area default. */\n buttonType?: PageActionButtonType\n}\n\nexport type CrudPageSchema = {\n $schema: typeof CRUD_SCHEMA_ID\n version: typeof CRUD_SCHEMA_VERSION\n id: string\n kind: 'crud'\n title: string\n dataSource: {\n list: string\n detail?: string\n create?: string\n update?: string\n remove?: string\n }\n search?: FieldSchema[]\n searchMode?: 'proTable' | 'bestSearch'\n form?: FieldSchema[]\n table: {\n rowKey: string | string[]\n columns: TableColumnSchema[]\n actions?: PageActionSchema[]\n scrollX?: number\n pageSize?: number\n }\n detail?: { fields: DetailFieldSchema[] }\n toolbar?: PageActionSchema[]\n meta?: {\n generatedBy?: string\n generatedAt?: string\n }\n}\n", "import type { BestRegistry } from '../runtime'\nimport {\n type Condition,\n CRUD_SCHEMA_ID,\n CRUD_SCHEMA_VERSION,\n type CrudPageSchema,\n type FieldSchema,\n type PageActionSchema\n} from './schema'\n\nexport type SchemaDiagnostic = {\n path: string\n code: string\n message: string\n}\n\nexport type SchemaValidationResult = {\n valid: boolean\n diagnostics: SchemaDiagnostic[]\n}\n\nconst fieldComponents = new Set([\n 'input',\n 'number',\n 'select',\n 'remoteSelect',\n 'date',\n 'dateRange',\n 'textarea',\n 'slot',\n 'repeatable'\n])\nconst builtInEffects = new Set([\n 'openCreate',\n 'openDetail',\n 'openEdit',\n 'remove',\n 'runAction',\n 'slot'\n])\nconst columnFormats = new Set(['date', 'datetime', 'money', 'text'])\n\nfunction push(diagnostics: SchemaDiagnostic[], path: string, code: string, message: string) {\n diagnostics.push({ path, code, message })\n}\n\nfunction validateCondition(condition: Condition, path: string, diagnostics: SchemaDiagnostic[]) {\n if (!condition || typeof condition !== 'object') {\n push(diagnostics, path, 'condition.type', '\u6761\u4EF6\u5FC5\u987B\u662F\u5BF9\u8C61')\n return\n }\n if (condition.operator === 'equals') {\n if (typeof condition.field !== 'string' || condition.field === '') {\n push(diagnostics, path, 'condition.field', 'equals \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A\u5B57\u6BB5\u540D')\n }\n return\n }\n if (condition.operator === 'notEmpty') {\n if (typeof condition.field !== 'string' || condition.field === '') {\n push(diagnostics, path, 'condition.field', 'notEmpty \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A\u5B57\u6BB5\u540D')\n }\n return\n }\n if (condition.operator === 'modeEquals') {\n return\n }\n if (\n (condition.operator === 'and' || condition.operator === 'or') &&\n !Array.isArray(condition.conditions)\n ) {\n push(diagnostics, path, 'condition.conditions', '\u7EC4\u5408\u6761\u4EF6\u5FC5\u987B\u6307\u5B9A conditions \u6570\u7EC4')\n return\n }\n if (condition.operator === 'and' || condition.operator === 'or') {\n if (condition.conditions.length === 0) {\n push(diagnostics, path, 'condition.empty', '\u7EC4\u5408\u6761\u4EF6\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5B50\u6761\u4EF6')\n }\n condition.conditions.forEach((item, index) => {\n validateCondition(item, `${path}/conditions/${index}`, diagnostics)\n })\n return\n }\n if (condition.operator === 'not') {\n if (!condition.condition) {\n push(diagnostics, path, 'condition.missing', 'not \u6761\u4EF6\u5FC5\u987B\u6307\u5B9A condition')\n return\n }\n validateCondition(condition.condition, `${path}/condition`, diagnostics)\n return\n }\n push(diagnostics, path, 'condition.operator', `\u4E0D\u652F\u6301\u7684\u6761\u4EF6\uFF1A${(condition as { operator?: unknown }).operator}`)\n}\n\nfunction validateFields(\n fields: FieldSchema[] | undefined,\n path: string,\n registry: BestRegistry | undefined,\n diagnostics: SchemaDiagnostic[]\n) {\n const seen = new Set<string>()\n fields?.forEach((field, index) => {\n const fieldPath = `${path}/${index}`\n if (!field.field) push(diagnostics, fieldPath, 'field.missing', '\u5B57\u6BB5\u540D\u4E0D\u80FD\u4E3A\u7A7A')\n if (seen.has(field.field))\n push(diagnostics, fieldPath, 'field.duplicate', `\u5B57\u6BB5\u91CD\u590D\uFF1A${field.field}`)\n seen.add(field.field)\n if (!fieldComponents.has(field.component))\n push(diagnostics, fieldPath, 'field.component', `\u4E0D\u652F\u6301\u7684\u7EC4\u4EF6\uFF1A${field.component}`)\n if (field.dict && registry && !registry.dictionaries[field.dict]) {\n push(diagnostics, fieldPath, 'registry.dictionary', `\u672A\u6CE8\u518C\u5B57\u5178\uFF1A${field.dict}`)\n }\n if (field.component === 'remoteSelect' && !field.remoteService)\n push(diagnostics, fieldPath, 'field.remoteService', 'remoteSelect \u5FC5\u987B\u6307\u5B9A remoteService')\n if (field.remoteService && registry && !registry.services[field.remoteService])\n push(diagnostics, fieldPath, 'registry.service', `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${field.remoteService}`)\n if (field.component === 'slot' && !field.slot)\n push(diagnostics, fieldPath, 'field.slot', 'slot \u7EC4\u4EF6\u5FC5\u987B\u6307\u5B9A slot key')\n if (field.component === 'repeatable' && !field.itemFields?.length)\n push(\n diagnostics,\n fieldPath,\n 'field.repeatable',\n 'repeatable \u7EC4\u4EF6\u81F3\u5C11\u9700\u8981\u4E00\u4E2A itemFields \u5B57\u6BB5'\n )\n if (field.itemFields?.length)\n validateFields(\n field.itemFields as FieldSchema[],\n `${fieldPath}/itemFields`,\n registry,\n diagnostics\n )\n if (\n field.minItems !== undefined &&\n field.maxItems !== undefined &&\n field.minItems > field.maxItems\n )\n push(diagnostics, fieldPath, 'field.repeatable.range', 'minItems \u4E0D\u80FD\u5927\u4E8E maxItems')\n if (field.slot && registry && !registry.slots[field.slot])\n push(diagnostics, fieldPath, 'registry.slot', `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${field.slot}`)\n if (field.visibleWhen)\n validateCondition(field.visibleWhen, `${fieldPath}/visibleWhen`, diagnostics)\n if (field.disabledWhen)\n validateCondition(field.disabledWhen, `${fieldPath}/disabledWhen`, diagnostics)\n })\n}\n\nfunction validateActions(\n actions: PageActionSchema[] | undefined,\n path: string,\n registry: BestRegistry | undefined,\n hasRemoveService: boolean,\n diagnostics: SchemaDiagnostic[]\n) {\n actions?.forEach((action, index) => {\n const actionPath = `${path}/${index}`\n if (!action.id) push(diagnostics, actionPath, 'action.missing', '\u52A8\u4F5C id \u4E0D\u80FD\u4E3A\u7A7A')\n if (!builtInEffects.has(action.effect))\n push(diagnostics, actionPath, 'action.effect', `\u4E0D\u652F\u6301\u7684\u52A8\u4F5C\uFF1A${action.effect}`)\n if (action.effect === 'runAction' && !action.action)\n push(diagnostics, actionPath, 'action.key', 'runAction \u5FC5\u987B\u6307\u5B9A action key')\n if (action.effect === 'remove' && !hasRemoveService)\n push(diagnostics, actionPath, 'action.removeService', 'remove \u52A8\u4F5C\u5FC5\u987B\u914D\u7F6E dataSource.remove')\n if (action.effect === 'slot' && !action.slot)\n push(diagnostics, actionPath, 'action.slot', 'slot \u52A8\u4F5C\u5FC5\u987B\u6307\u5B9A slot key')\n if (action.action && registry && !registry.actions[action.action]) {\n push(diagnostics, actionPath, 'registry.action', `\u672A\u6CE8\u518C\u52A8\u4F5C\uFF1A${action.action}`)\n }\n if (action.slot && registry && !registry.slots[action.slot]) {\n push(diagnostics, actionPath, 'registry.slot', `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${action.slot}`)\n }\n })\n}\n\nexport function validateCrudPageSchema(\n schema: CrudPageSchema,\n registry?: BestRegistry\n): SchemaValidationResult {\n const diagnostics: SchemaDiagnostic[] = []\n if (schema.$schema !== CRUD_SCHEMA_ID)\n push(diagnostics, '/$schema', 'schema.id', `\u4EC5\u652F\u6301 ${CRUD_SCHEMA_ID}`)\n if (schema.version !== CRUD_SCHEMA_VERSION)\n push(diagnostics, '/version', 'schema.version', `\u4EC5\u652F\u6301\u7248\u672C ${CRUD_SCHEMA_VERSION}`)\n if (!schema.id) push(diagnostics, '/id', 'page.id', '\u9875\u9762 id \u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.title) push(diagnostics, '/title', 'page.title', '\u9875\u9762\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.dataSource?.list)\n push(diagnostics, '/dataSource/list', 'service.list', '\u5217\u8868\u670D\u52A1\u4E0D\u80FD\u4E3A\u7A7A')\n if (schema.dataSource?.list && registry && !registry.listServices[schema.dataSource.list]) {\n push(\n diagnostics,\n '/dataSource/list',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.list}`\n )\n }\n if (schema.dataSource?.detail && registry && !registry.services[schema.dataSource.detail]) {\n push(\n diagnostics,\n '/dataSource/detail',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.detail}`\n )\n }\n if (schema.dataSource?.create && registry && !registry.services[schema.dataSource.create]) {\n push(\n diagnostics,\n '/dataSource/create',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.create}`\n )\n }\n if (schema.dataSource?.update && registry && !registry.services[schema.dataSource.update]) {\n push(\n diagnostics,\n '/dataSource/update',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.update}`\n )\n }\n if (schema.dataSource?.remove && registry && !registry.services[schema.dataSource.remove]) {\n push(\n diagnostics,\n '/dataSource/remove',\n 'registry.service',\n `\u672A\u6CE8\u518C\u670D\u52A1\uFF1A${schema.dataSource.remove}`\n )\n }\n validateFields(schema.search, '/search', registry, diagnostics)\n validateFields(schema.form, '/form', registry, diagnostics)\n if (!schema.table?.rowKey) push(diagnostics, '/table/rowKey', 'table.rowKey', 'rowKey \u4E0D\u80FD\u4E3A\u7A7A')\n if (!schema.table?.columns?.length)\n push(diagnostics, '/table/columns', 'table.columns', '\u81F3\u5C11\u9700\u8981\u4E00\u5217')\n schema.table?.columns?.forEach((column, index) => {\n if (column.fixed !== undefined && column.fixed !== 'left' && column.fixed !== 'right') {\n push(\n diagnostics,\n `/table/columns/${index}/fixed`,\n 'column.fixed',\n `\u4E0D\u652F\u6301\u7684\u56FA\u5B9A\u4F4D\u7F6E\uFF1A${column.fixed}`\n )\n }\n if (column.format && !columnFormats.has(column.format)) {\n push(\n diagnostics,\n `/table/columns/${index}/format`,\n 'column.format',\n `\u4E0D\u652F\u6301\u7684\u683C\u5F0F\uFF1A${column.format}`\n )\n }\n if (column.dict && registry && !registry.dictionaries[column.dict]) {\n push(\n diagnostics,\n `/table/columns/${index}/dict`,\n 'registry.dictionary',\n `\u672A\u6CE8\u518C\u5B57\u5178\uFF1A${column.dict}`\n )\n }\n if (column.slot && registry && !registry.slots[column.slot]) {\n push(\n diagnostics,\n `/table/columns/${index}/slot`,\n 'registry.slot',\n `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${column.slot}`\n )\n }\n })\n if (schema.detail !== undefined) {\n if (\n !schema.detail ||\n typeof schema.detail !== 'object' ||\n !Array.isArray(schema.detail.fields)\n ) {\n push(diagnostics, '/detail', 'detail.type', 'detail \u5FC5\u987B\u5305\u542B fields \u5BF9\u8C61\u6570\u7EC4')\n } else {\n schema.detail.fields.forEach((field, index) => {\n if (field.slot && registry && !registry.slots[field.slot])\n push(\n diagnostics,\n `/detail/fields/${index}/slot`,\n 'registry.slot',\n `\u672A\u6CE8\u518C\u63D2\u69FD\uFF1A${field.slot}`\n )\n })\n }\n }\n validateActions(\n schema.table?.actions,\n '/table/actions',\n registry,\n Boolean(schema.dataSource?.remove),\n diagnostics\n )\n validateActions(\n schema.toolbar,\n '/toolbar',\n registry,\n Boolean(schema.dataSource?.remove),\n diagnostics\n )\n return { valid: diagnostics.length === 0, diagnostics }\n}\n\nexport function assertValidCrudPageSchema(schema: CrudPageSchema, registry?: BestRegistry) {\n const result = validateCrudPageSchema(schema, registry)\n if (!result.valid) {\n const message = result.diagnostics.map((item) => `${item.path}: ${item.message}`).join('\\n')\n throw new Error(`Schema \u6821\u9A8C\u5931\u8D25\uFF1A\\n${message}`)\n }\n}\n", "import type {\n CRUD_SCHEMA_ID,\n CRUD_SCHEMA_VERSION,\n CrudPageSchema,\n FieldSchema,\n PageActionSchema\n} from './schema'\nimport type { SchemaDiagnostic, SchemaValidationResult } from './validate'\nimport { validateCrudPageSchema } from './validate'\n\nconst builtInCapabilities = [\n 'builtin.effect.openCreate',\n 'builtin.effect.openDetail',\n 'builtin.effect.openEdit',\n 'builtin.effect.remove',\n 'builtin.effect.runAction',\n 'builtin.effect.slot',\n 'builtin.format.date',\n 'builtin.format.datetime',\n 'builtin.format.money',\n 'builtin.format.text',\n 'builtin.field.input',\n 'builtin.field.number',\n 'builtin.field.select',\n 'builtin.field.remoteSelect',\n 'builtin.field.date',\n 'builtin.field.dateRange',\n 'builtin.field.textarea',\n 'builtin.field.slot',\n 'builtin.field.repeatable'\n] as const\n\ntype JsonRecord = Record<string, unknown>\n\nfunction isRecord(value: unknown): value is JsonRecord {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction arrayOfRecords(value: unknown): JsonRecord[] | undefined {\n return Array.isArray(value) && value.every(isRecord) ? value : undefined\n}\n\nfunction diagnostic(path: string, code: string, message: string): SchemaDiagnostic {\n return { path, code, message }\n}\n\nfunction validateUnknownShape(candidate: unknown): SchemaDiagnostic[] {\n if (!isRecord(candidate)) return [diagnostic('', 'schema.type', 'Schema \u5FC5\u987B\u662F JSON \u5BF9\u8C61')]\n const diagnostics: SchemaDiagnostic[] = []\n if (!isRecord(candidate.dataSource))\n diagnostics.push(diagnostic('/dataSource', 'dataSource.type', 'dataSource \u5FC5\u987B\u662F\u5BF9\u8C61'))\n if (!isRecord(candidate.table))\n diagnostics.push(diagnostic('/table', 'table.type', 'table \u5FC5\u987B\u662F\u5BF9\u8C61'))\n for (const key of ['search', 'form'] as const) {\n if (candidate[key] !== undefined && !arrayOfRecords(candidate[key])) {\n diagnostics.push(diagnostic(`/${key}`, 'field.list', `${key} \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4`))\n }\n }\n if (isRecord(candidate.table)) {\n if (!arrayOfRecords(candidate.table.columns)) {\n diagnostics.push(diagnostic('/table/columns', 'column.list', 'columns \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n if (candidate.table.actions !== undefined && !arrayOfRecords(candidate.table.actions)) {\n diagnostics.push(diagnostic('/table/actions', 'action.list', 'actions \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n }\n if (candidate.toolbar !== undefined && !arrayOfRecords(candidate.toolbar)) {\n diagnostics.push(diagnostic('/toolbar', 'action.list', 'toolbar \u5FC5\u987B\u662F\u5BF9\u8C61\u6570\u7EC4'))\n }\n return diagnostics\n}\n\nfunction toRuntimeSchema(candidate: JsonRecord): CrudPageSchema {\n return {\n $schema: candidate.$schema as typeof CRUD_SCHEMA_ID,\n version: candidate.version as typeof CRUD_SCHEMA_VERSION,\n id: candidate.id as string,\n kind: candidate.kind as 'crud',\n title: candidate.title as string,\n dataSource: candidate.dataSource as CrudPageSchema['dataSource'],\n search: candidate.search as FieldSchema[] | undefined,\n searchMode: candidate.searchMode as CrudPageSchema['searchMode'],\n form: candidate.form as FieldSchema[] | undefined,\n table: candidate.table as CrudPageSchema['table'],\n detail: candidate.detail as CrudPageSchema['detail'],\n toolbar: candidate.toolbar as PageActionSchema[] | undefined,\n meta: candidate.meta as CrudPageSchema['meta']\n }\n}\n\n/**\n * Server-safe development entry. It accepts unknown JSON from CLI/MCP before delegating to the\n * runtime validator, so untrusted candidates cannot trigger assumptions in typed runtime code.\n */\nexport function validateUnknownCrudPageSchema(candidate: unknown): SchemaValidationResult {\n const shapeDiagnostics = validateUnknownShape(candidate)\n if (shapeDiagnostics.length || !isRecord(candidate)) {\n return { valid: false, diagnostics: shapeDiagnostics }\n }\n return validateCrudPageSchema(toRuntimeSchema(candidate))\n}\n\n/** Serializable capabilities supplied by the current runtime without application Manifest entries. */\nexport function getBuiltinCapabilities(): string[] {\n return [...builtInCapabilities]\n}\n"],
|
|
5
|
+
"mappings": ";AAEO,IAAM,iBAAiB;AACvB,IAAM,sBAAsB;;;ACkBnC,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,QAAQ,YAAY,SAAS,MAAM,CAAC;AAEnE,SAAS,KAAK,aAAiC,MAAc,MAAc,SAAiB;AAC1F,cAAY,KAAK,EAAE,MAAM,MAAM,QAAQ,CAAC;AAC1C;AAEA,SAAS,kBAAkB,WAAsB,MAAc,aAAiC;AAC9F,MAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAC/C,SAAK,aAAa,MAAM,kBAAkB,4CAAS;AACnD;AAAA,EACF;AACA,MAAI,UAAU,aAAa,UAAU;AACnC,QAAI,OAAO,UAAU,UAAU,YAAY,UAAU,UAAU,IAAI;AACjE,WAAK,aAAa,MAAM,mBAAmB,+DAAkB;AAAA,IAC/D;AACA;AAAA,EACF;AACA,MAAI,UAAU,aAAa,YAAY;AACrC,QAAI,OAAO,UAAU,UAAU,YAAY,UAAU,UAAU,IAAI;AACjE,WAAK,aAAa,MAAM,mBAAmB,iEAAoB;AAAA,IACjE;AACA;AAAA,EACF;AACA,MAAI,UAAU,aAAa,cAAc;AACvC;AAAA,EACF;AACA,OACG,UAAU,aAAa,SAAS,UAAU,aAAa,SACxD,CAAC,MAAM,QAAQ,UAAU,UAAU,GACnC;AACA,SAAK,aAAa,MAAM,wBAAwB,0EAAwB;AACxE;AAAA,EACF;AACA,MAAI,UAAU,aAAa,SAAS,UAAU,aAAa,MAAM;AAC/D,QAAI,UAAU,WAAW,WAAW,GAAG;AACrC,WAAK,aAAa,MAAM,mBAAmB,gFAAe;AAAA,IAC5D;AACA,cAAU,WAAW,QAAQ,CAAC,MAAM,UAAU;AAC5C,wBAAkB,MAAM,GAAG,IAAI,eAAe,KAAK,IAAI,WAAW;AAAA,IACpE,CAAC;AACD;AAAA,EACF;AACA,MAAI,UAAU,aAAa,OAAO;AAChC,QAAI,CAAC,UAAU,WAAW;AACxB,WAAK,aAAa,MAAM,qBAAqB,oDAAsB;AACnE;AAAA,IACF;AACA,sBAAkB,UAAU,WAAW,GAAG,IAAI,cAAc,WAAW;AACvE;AAAA,EACF;AACA,OAAK,aAAa,MAAM,sBAAsB,6CAAW,UAAqC,QAAQ,EAAE;AAC1G;AAEA,SAAS,eACP,QACA,MACA,UACA,aACA;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,UAAQ,QAAQ,CAAC,OAAO,UAAU;AAChC,UAAM,YAAY,GAAG,IAAI,IAAI,KAAK;AAClC,QAAI,CAAC,MAAM,MAAO,MAAK,aAAa,WAAW,iBAAiB,4CAAS;AACzE,QAAI,KAAK,IAAI,MAAM,KAAK;AACtB,WAAK,aAAa,WAAW,mBAAmB,iCAAQ,MAAM,KAAK,EAAE;AACvE,SAAK,IAAI,MAAM,KAAK;AACpB,QAAI,CAAC,gBAAgB,IAAI,MAAM,SAAS;AACtC,WAAK,aAAa,WAAW,mBAAmB,6CAAU,MAAM,SAAS,EAAE;AAC7E,QAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,aAAa,MAAM,IAAI,GAAG;AAChE,WAAK,aAAa,WAAW,uBAAuB,uCAAS,MAAM,IAAI,EAAE;AAAA,IAC3E;AACA,QAAI,MAAM,cAAc,kBAAkB,CAAC,MAAM;AAC/C,WAAK,aAAa,WAAW,uBAAuB,qDAAiC;AACvF,QAAI,MAAM,iBAAiB,YAAY,CAAC,SAAS,SAAS,MAAM,aAAa;AAC3E,WAAK,aAAa,WAAW,oBAAoB,uCAAS,MAAM,aAAa,EAAE;AACjF,QAAI,MAAM,cAAc,UAAU,CAAC,MAAM;AACvC,WAAK,aAAa,WAAW,cAAc,oDAAsB;AACnE,QAAI,MAAM,cAAc,gBAAgB,CAAC,MAAM,YAAY;AACzD;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACF,QAAI,MAAM,YAAY;AACpB;AAAA,QACE,MAAM;AAAA,QACN,GAAG,SAAS;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AACF,QACE,MAAM,aAAa,UACnB,MAAM,aAAa,UACnB,MAAM,WAAW,MAAM;AAEvB,WAAK,aAAa,WAAW,0BAA0B,4CAAwB;AACjF,QAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,MAAM,MAAM,IAAI;AACtD,WAAK,aAAa,WAAW,iBAAiB,uCAAS,MAAM,IAAI,EAAE;AACrE,QAAI,MAAM;AACR,wBAAkB,MAAM,aAAa,GAAG,SAAS,gBAAgB,WAAW;AAC9E,QAAI,MAAM;AACR,wBAAkB,MAAM,cAAc,GAAG,SAAS,iBAAiB,WAAW;AAAA,EAClF,CAAC;AACH;AAEA,SAAS,gBACP,SACA,MACA,UACA,kBACA,aACA;AACA,WAAS,QAAQ,CAAC,QAAQ,UAAU;AAClC,UAAM,aAAa,GAAG,IAAI,IAAI,KAAK;AACnC,QAAI,CAAC,OAAO,GAAI,MAAK,aAAa,YAAY,kBAAkB,0CAAY;AAC5E,QAAI,CAAC,eAAe,IAAI,OAAO,MAAM;AACnC,WAAK,aAAa,YAAY,iBAAiB,6CAAU,OAAO,MAAM,EAAE;AAC1E,QAAI,OAAO,WAAW,eAAe,CAAC,OAAO;AAC3C,WAAK,aAAa,YAAY,cAAc,+CAA2B;AACzE,QAAI,OAAO,WAAW,YAAY,CAAC;AACjC,WAAK,aAAa,YAAY,wBAAwB,+DAAiC;AACzF,QAAI,OAAO,WAAW,UAAU,CAAC,OAAO;AACtC,WAAK,aAAa,YAAY,eAAe,oDAAsB;AACrE,QAAI,OAAO,UAAU,YAAY,CAAC,SAAS,QAAQ,OAAO,MAAM,GAAG;AACjE,WAAK,aAAa,YAAY,mBAAmB,uCAAS,OAAO,MAAM,EAAE;AAAA,IAC3E;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,MAAM,OAAO,IAAI,GAAG;AAC3D,WAAK,aAAa,YAAY,iBAAiB,uCAAS,OAAO,IAAI,EAAE;AAAA,IACvE;AAAA,EACF,CAAC;AACH;AAEO,SAAS,uBACd,QACA,UACwB;AACxB,QAAM,cAAkC,CAAC;AACzC,MAAI,OAAO,YAAY;AACrB,SAAK,aAAa,YAAY,aAAa,sBAAO,cAAc,EAAE;AACpE,MAAI,OAAO,YAAY;AACrB,SAAK,aAAa,YAAY,kBAAkB,kCAAS,mBAAmB,EAAE;AAChF,MAAI,CAAC,OAAO,GAAI,MAAK,aAAa,OAAO,WAAW,0CAAY;AAChE,MAAI,CAAC,OAAO,MAAO,MAAK,aAAa,UAAU,cAAc,kDAAU;AACvE,MAAI,CAAC,OAAO,YAAY;AACtB,SAAK,aAAa,oBAAoB,gBAAgB,kDAAU;AAClE,MAAI,OAAO,YAAY,QAAQ,YAAY,CAAC,SAAS,aAAa,OAAO,WAAW,IAAI,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,IAAI;AAAA,IACjC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,MAAI,OAAO,YAAY,UAAU,YAAY,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,GAAG;AACzF;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,uCAAS,OAAO,WAAW,MAAM;AAAA,IACnC;AAAA,EACF;AACA,iBAAe,OAAO,QAAQ,WAAW,UAAU,WAAW;AAC9D,iBAAe,OAAO,MAAM,SAAS,UAAU,WAAW;AAC1D,MAAI,CAAC,OAAO,OAAO,OAAQ,MAAK,aAAa,iBAAiB,gBAAgB,iCAAa;AAC3F,MAAI,CAAC,OAAO,OAAO,SAAS;AAC1B,SAAK,aAAa,kBAAkB,iBAAiB,sCAAQ;AAC/D,SAAO,OAAO,SAAS,QAAQ,CAAC,QAAQ,UAAU;AAChD,QAAI,OAAO,UAAU,UAAa,OAAO,UAAU,UAAU,OAAO,UAAU,SAAS;AACrF;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,yDAAY,OAAO,KAAK;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,OAAO,UAAU,CAAC,cAAc,IAAI,OAAO,MAAM,GAAG;AACtD;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,6CAAU,OAAO,MAAM;AAAA,MACzB;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,aAAa,OAAO,IAAI,GAAG;AAClE;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,uCAAS,OAAO,IAAI;AAAA,MACtB;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,YAAY,CAAC,SAAS,MAAM,OAAO,IAAI,GAAG;AAC3D;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB;AAAA,QACA,uCAAS,OAAO,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI,OAAO,WAAW,QAAW;AAC/B,QACE,CAAC,OAAO,UACR,OAAO,OAAO,WAAW,YACzB,CAAC,MAAM,QAAQ,OAAO,OAAO,MAAM,GACnC;AACA,WAAK,aAAa,WAAW,eAAe,iEAAyB;AAAA,IACvE,OAAO;AACL,aAAO,OAAO,OAAO,QAAQ,CAAC,OAAO,UAAU;AAC7C,YAAI,MAAM,QAAQ,YAAY,CAAC,SAAS,MAAM,MAAM,IAAI;AACtD;AAAA,YACE;AAAA,YACA,kBAAkB,KAAK;AAAA,YACvB;AAAA,YACA,uCAAS,MAAM,IAAI;AAAA,UACrB;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACA;AAAA,IACE,OAAO,OAAO;AAAA,IACd;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,YAAY,MAAM;AAAA,IACjC;AAAA,EACF;AACA;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,YAAY,MAAM;AAAA,IACjC;AAAA,EACF;AACA,SAAO,EAAE,OAAO,YAAY,WAAW,GAAG,YAAY;AACxD;;;ACjSA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,SAAS,SAAS,OAAqC;AACrD,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACrE;AAEA,SAAS,eAAe,OAA0C;AAChE,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,QAAQ,IAAI,QAAQ;AACjE;AAEA,SAAS,WAAW,MAAc,MAAc,SAAmC;AACjF,SAAO,EAAE,MAAM,MAAM,QAAQ;AAC/B;AAEA,SAAS,qBAAqB,WAAwC;AACpE,MAAI,CAAC,SAAS,SAAS,EAAG,QAAO,CAAC,WAAW,IAAI,eAAe,6CAAoB,CAAC;AACrF,QAAM,cAAkC,CAAC;AACzC,MAAI,CAAC,SAAS,UAAU,UAAU;AAChC,gBAAY,KAAK,WAAW,eAAe,mBAAmB,2CAAkB,CAAC;AACnF,MAAI,CAAC,SAAS,UAAU,KAAK;AAC3B,gBAAY,KAAK,WAAW,UAAU,cAAc,sCAAa,CAAC;AACpE,aAAW,OAAO,CAAC,UAAU,MAAM,GAAY;AAC7C,QAAI,UAAU,GAAG,MAAM,UAAa,CAAC,eAAe,UAAU,GAAG,CAAC,GAAG;AACnE,kBAAY,KAAK,WAAW,IAAI,GAAG,IAAI,cAAc,GAAG,GAAG,6CAAU,CAAC;AAAA,IACxE;AAAA,EACF;AACA,MAAI,SAAS,UAAU,KAAK,GAAG;AAC7B,QAAI,CAAC,eAAe,UAAU,MAAM,OAAO,GAAG;AAC5C,kBAAY,KAAK,WAAW,kBAAkB,eAAe,oDAAiB,CAAC;AAAA,IACjF;AACA,QAAI,UAAU,MAAM,YAAY,UAAa,CAAC,eAAe,UAAU,MAAM,OAAO,GAAG;AACrF,kBAAY,KAAK,WAAW,kBAAkB,eAAe,oDAAiB,CAAC;AAAA,IACjF;AAAA,EACF;AACA,MAAI,UAAU,YAAY,UAAa,CAAC,eAAe,UAAU,OAAO,GAAG;AACzE,gBAAY,KAAK,WAAW,YAAY,eAAe,oDAAiB,CAAC;AAAA,EAC3E;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,WAAuC;AAC9D,SAAO;AAAA,IACL,SAAS,UAAU;AAAA,IACnB,SAAS,UAAU;AAAA,IACnB,IAAI,UAAU;AAAA,IACd,MAAM,UAAU;AAAA,IAChB,OAAO,UAAU;AAAA,IACjB,YAAY,UAAU;AAAA,IACtB,QAAQ,UAAU;AAAA,IAClB,YAAY,UAAU;AAAA,IACtB,MAAM,UAAU;AAAA,IAChB,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,SAAS,UAAU;AAAA,IACnB,MAAM,UAAU;AAAA,EAClB;AACF;AAMO,SAAS,8BAA8B,WAA4C;AACxF,QAAM,mBAAmB,qBAAqB,SAAS;AACvD,MAAI,iBAAiB,UAAU,CAAC,SAAS,SAAS,GAAG;AACnD,WAAO,EAAE,OAAO,OAAO,aAAa,iBAAiB;AAAA,EACvD;AACA,SAAO,uBAAuB,gBAAgB,SAAS,CAAC;AAC1D;AAGO,SAAS,yBAAmC;AACjD,SAAO,CAAC,GAAG,mBAAmB;AAChC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.css
CHANGED
|
@@ -1,16 +1,67 @@
|
|
|
1
|
+
/* src/ui/BestSearch.module.less */
|
|
2
|
+
.best-lowcode-search {
|
|
3
|
+
margin-bottom: 16px;
|
|
4
|
+
padding: 16px;
|
|
5
|
+
background: #fff;
|
|
6
|
+
border: 1px solid #f0f0f0;
|
|
7
|
+
border-radius: 8px;
|
|
8
|
+
}
|
|
9
|
+
.best-lowcode-search .ant-form-item {
|
|
10
|
+
margin-bottom: 16px;
|
|
11
|
+
}
|
|
12
|
+
.best-lowcode-search .ant-form-item-label > label {
|
|
13
|
+
color: rgba(0, 0, 0, 0.88);
|
|
14
|
+
font-size: 14px;
|
|
15
|
+
}
|
|
16
|
+
.best-lowcode-search .ant-form-item-control-input {
|
|
17
|
+
min-height: 32px;
|
|
18
|
+
}
|
|
19
|
+
|
|
1
20
|
/* src/ui/BestTable.module.less */
|
|
2
|
-
.
|
|
3
|
-
:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
.best-lowcode-table .ant-table-wrapper {
|
|
22
|
+
border: 1px solid #f0f0f0;
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
.best-lowcode-table .ant-table-wrapper .ant-table.ant-table-medium .ant-table-thead > tr > th {
|
|
27
|
+
background: #fafafa;
|
|
28
|
+
color: rgba(0, 0, 0, 0.88);
|
|
29
|
+
font-weight: 600;
|
|
30
|
+
white-space: nowrap !important;
|
|
31
|
+
padding: 6px 16px;
|
|
32
|
+
line-height: 28px;
|
|
33
|
+
border-bottom: 0;
|
|
34
|
+
box-shadow: inset 0 -1px #f0f0f0;
|
|
35
|
+
}
|
|
36
|
+
.best-lowcode-table .ant-table-wrapper .ant-table.ant-table-medium .ant-table-tbody > tr > td.ant-table-cell {
|
|
37
|
+
padding: 6px 16px;
|
|
38
|
+
line-height: 28px;
|
|
39
|
+
height: 40px;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
white-space: normal;
|
|
42
|
+
overflow-wrap: break-word;
|
|
43
|
+
border-bottom: 0;
|
|
44
|
+
box-shadow: inset 0 -1px #f0f0f0;
|
|
45
|
+
}
|
|
46
|
+
.best-lowcode-table .ant-table-tbody > tr > td .ant-btn {
|
|
47
|
+
height: 28px;
|
|
48
|
+
min-height: 28px;
|
|
49
|
+
padding-block: 0;
|
|
50
|
+
line-height: 26px;
|
|
51
|
+
}
|
|
52
|
+
.best-lowcode-table .ant-table-cell-fix-right-first::after {
|
|
53
|
+
box-shadow: inset -8px 0 8px -8px rgba(0, 0, 0, 0.15);
|
|
54
|
+
}
|
|
55
|
+
.best-lowcode-table .ant-pro-card-body {
|
|
56
|
+
padding: 12px;
|
|
57
|
+
}
|
|
58
|
+
.best-lowcode-table .ant-pro-query-filter-actions .ant-form-item-label {
|
|
59
|
+
display: none;
|
|
60
|
+
}
|
|
61
|
+
.best-lowcode-table .ant-pro-query-filter-actions {
|
|
62
|
+
height: 100%;
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
justify-content: flex-end;
|
|
15
66
|
}
|
|
16
67
|
/*# sourceMappingURL=index.css.map */
|
package/dist/index.css.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/ui/BestTable.module.less"],
|
|
4
|
-
"sourcesContent": [".
|
|
5
|
-
"mappings": ";AAAA,CAAC;AACC,UAAQ,CAAC;
|
|
3
|
+
"sources": ["../src/ui/BestSearch.module.less", "../src/ui/BestTable.module.less"],
|
|
4
|
+
"sourcesContent": [".best-lowcode-search {\n margin-bottom: 16px;\n padding: 16px;\n background: #fff;\n border: 1px solid #f0f0f0;\n border-radius: 8px;\n}\n\n.best-lowcode-search .ant-form-item {\n margin-bottom: 16px;\n}\n\n.best-lowcode-search .ant-form-item-label > label {\n color: rgba(0, 0, 0, 0.88);\n font-size: 14px;\n}\n\n.best-lowcode-search .ant-form-item-control-input {\n min-height: 32px;\n}\n", ".best-lowcode-table .ant-table-wrapper {\n border: 1px solid #f0f0f0;\n border-radius: 4px;\n overflow: hidden;\n}\n\n.best-lowcode-table .ant-table-wrapper .ant-table.ant-table-medium .ant-table-thead > tr > th {\n background: #fafafa;\n color: rgba(0, 0, 0, 0.88);\n font-weight: 600;\n white-space: nowrap !important;\n padding: 6px 16px;\n line-height: 28px;\n border-bottom: 0;\n box-shadow: inset 0 -1px #f0f0f0;\n}\n\n.best-lowcode-table .ant-table-wrapper .ant-table.ant-table-medium .ant-table-tbody > tr > td.ant-table-cell {\n padding: 6px 16px;\n line-height: 28px;\n height: 40px;\n box-sizing: border-box;\n white-space: normal;\n overflow-wrap: break-word;\n border-bottom: 0;\n box-shadow: inset 0 -1px #f0f0f0;\n}\n\n/* Keep action controls from increasing the table row beyond the compact 40px rhythm. */\n.best-lowcode-table .ant-table-tbody > tr > td .ant-btn {\n height: 28px;\n min-height: 28px;\n padding-block: 0;\n line-height: 26px;\n}\n\n.best-lowcode-table .ant-table-cell-fix-right-first::after {\n box-shadow: inset -8px 0 8px -8px rgba(0, 0, 0, 0.15);\n}\n\n.best-lowcode-table .ant-pro-card-body {\n padding: 12px;\n}\n\n.best-lowcode-table .ant-pro-query-filter-actions .ant-form-item-label {\n display: none;\n}\n\n.best-lowcode-table .ant-pro-query-filter-actions {\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,CAAC;AACC,iBAAe;AACf,WAAS;AACT,cAAY;AACZ,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACjB;AAEA,CARC,oBAQoB,CAAC;AACpB,iBAAe;AACjB;AAEA,CAZC,oBAYoB,CAAC,oBAAoB,EAAE;AAC1C,SAAO,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACrB,aAAW;AACb;AAEA,CAjBC,oBAiBoB,CAAC;AACpB,cAAY;AACd;;;ACnBA,CAAC,mBAAmB,CAAC;AACjB,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,YAAU;AACd;AAEA,CANC,mBAMmB,CANC,kBAMkB,CAAC,SAAS,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,GAAG,EAAE;AACvF,cAAY;AACZ,SAAO,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACrB,eAAa;AACb,eAAa;AACb,WAAS,IAAI;AACb,eAAa;AACb,iBAAe;AACf,cAAY,MAAM,EAAE,KAAK;AAC7B;AAEA,CAjBC,mBAiBmB,CAjBC,kBAiBkB,CAXC,SAWS,CAXC,iBAWiB,CAAC,gBAAgB,EAAE,GAAG,EAAE,EAAE,CAAC;AAC1F,WAAS,IAAI;AACb,eAAa;AACb,UAAQ;AACR,cAAY;AACZ,eAAa;AACb,iBAAe;AACf,iBAAe;AACf,cAAY,MAAM,EAAE,KAAK;AAC7B;AAGA,CA7BC,mBA6BmB,CAZgD,gBAY/B,EAAE,GAAG,EAAE,GAAG,CAAC;AAC5C,UAAQ;AACR,cAAY;AACZ,iBAAe;AACf,eAAa;AACjB;AAEA,CApCC,mBAoCmB,CAAC,8BAA8B;AAC/C,cAAY,MAAM,KAAK,EAAE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACpD;AAEA,CAxCC,mBAwCmB,CAAC;AACjB,WAAS;AACb;AAEA,CA5CC,mBA4CmB,CAAC,6BAA6B,CAAC;AAC/C,WAAS;AACb;AAEA,CAhDC,mBAgDmB,CAJC;AAKjB,UAAQ;AACR,WAAS;AACT,kBAAgB;AAChB,mBAAiB;AACrB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -57,15 +57,34 @@ var defaultTheme = {
|
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
var BestRuntimeContext = createContext(emptyRegistry);
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
listServices:
|
|
63
|
-
services:
|
|
64
|
-
dictionaries:
|
|
65
|
-
actions:
|
|
66
|
-
slots:
|
|
67
|
-
access:
|
|
60
|
+
function composeBestRegistry(...layers) {
|
|
61
|
+
const result = {
|
|
62
|
+
listServices: {},
|
|
63
|
+
services: {},
|
|
64
|
+
dictionaries: {},
|
|
65
|
+
actions: {},
|
|
66
|
+
slots: {},
|
|
67
|
+
access: emptyRegistry.access
|
|
68
68
|
};
|
|
69
|
+
const groups = ["listServices", "services", "dictionaries", "actions", "slots"];
|
|
70
|
+
for (const layer of layers) {
|
|
71
|
+
for (const group of groups) {
|
|
72
|
+
for (const [key, value] of Object.entries(layer[group] ?? {})) {
|
|
73
|
+
if (Object.hasOwn(result[group], key)) {
|
|
74
|
+
throw new Error(`Registry key \u91CD\u590D\uFF1A${group}.${key}`);
|
|
75
|
+
}
|
|
76
|
+
result[group][key] = value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (layer.access) {
|
|
80
|
+
const previousAccess = result.access;
|
|
81
|
+
result.access = (key) => previousAccess(key) && layer.access?.(key) !== false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
function createBestRegistry(registry = {}) {
|
|
87
|
+
return composeBestRegistry(registry);
|
|
69
88
|
}
|
|
70
89
|
function BestProvider({ children, registry, theme }) {
|
|
71
90
|
const value = useMemo(() => createBestRegistry(registry), [registry]);
|
|
@@ -518,18 +537,23 @@ function FormFields({ fields, form, initialValues, mode = "create" }) {
|
|
|
518
537
|
}) });
|
|
519
538
|
}
|
|
520
539
|
function toAntRules(rules) {
|
|
521
|
-
return rules?.map(
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
540
|
+
return rules?.map(
|
|
541
|
+
(rule) => Object.fromEntries(
|
|
542
|
+
Object.entries({
|
|
543
|
+
required: rule.required,
|
|
544
|
+
type: rule.type === "string" ? void 0 : rule.type,
|
|
545
|
+
min: rule.min ?? rule.minLength,
|
|
546
|
+
max: rule.max ?? rule.maxLength,
|
|
547
|
+
pattern: safeRegExp(rule.pattern),
|
|
548
|
+
message: rule.message,
|
|
549
|
+
validator: rule.type === "integer" ? async (_, value) => {
|
|
550
|
+
if (value === void 0 || value === null || value === "") return;
|
|
551
|
+
if (!Number.isInteger(Number(value)))
|
|
552
|
+
throw new Error(rule.message ?? "\u8BF7\u8F93\u5165\u6574\u6570");
|
|
553
|
+
} : void 0
|
|
554
|
+
}).filter(([, value]) => value !== void 0)
|
|
555
|
+
)
|
|
556
|
+
);
|
|
533
557
|
}
|
|
534
558
|
function safeRegExp(pattern) {
|
|
535
559
|
if (!pattern) return void 0;
|
|
@@ -988,7 +1012,7 @@ function BestSearchBody({
|
|
|
988
1012
|
layout: "vertical",
|
|
989
1013
|
onFinish: (values) => onSearch(values),
|
|
990
1014
|
onValuesChange: (_, values) => onChange?.(values),
|
|
991
|
-
|
|
1015
|
+
className: "best-lowcode-search",
|
|
992
1016
|
children: /* @__PURE__ */ jsxs3(Row, { gutter: 16, align: "bottom", children: [
|
|
993
1017
|
fields.filter((field) => !field.hidden).map((field) => /* @__PURE__ */ jsx8(Col, { span: field.span ?? 6, children: /* @__PURE__ */ jsx8(Form2.Item, { label: field.label, name: field.field, rules: toAntRules(field.rules), children: /* @__PURE__ */ jsx8(FieldControl, { field }) }) }, field.field)),
|
|
994
1018
|
/* @__PURE__ */ jsx8(Col, { children: /* @__PURE__ */ jsxs3(Form2.Item, { children: [
|
|
@@ -997,10 +1021,10 @@ function BestSearchBody({
|
|
|
997
1021
|
Button3,
|
|
998
1022
|
{
|
|
999
1023
|
onClick: () => {
|
|
1000
|
-
syncValues(form,
|
|
1001
|
-
valueSignatureRef.current = JSON.stringify(
|
|
1002
|
-
onChange?.(
|
|
1003
|
-
onReset?.();
|
|
1024
|
+
syncValues(form, initialValues, fields);
|
|
1025
|
+
valueSignatureRef.current = JSON.stringify(initialValues);
|
|
1026
|
+
onChange?.(initialValues);
|
|
1027
|
+
onReset?.(initialValues);
|
|
1004
1028
|
},
|
|
1005
1029
|
style: { marginInlineStart: 8 },
|
|
1006
1030
|
children: "\u91CD\u7F6E"
|
|
@@ -1030,11 +1054,6 @@ function BestError({ description = "\u52A0\u8F7D\u5931\u8D25" }) {
|
|
|
1030
1054
|
import {
|
|
1031
1055
|
ProTable
|
|
1032
1056
|
} from "@ant-design/pro-components";
|
|
1033
|
-
|
|
1034
|
-
// src/ui/BestTable.module.less
|
|
1035
|
-
var BestTable_module_default = {};
|
|
1036
|
-
|
|
1037
|
-
// src/ui/BestTable.tsx
|
|
1038
1057
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1039
1058
|
var defaultSearch = {
|
|
1040
1059
|
layout: "vertical",
|
|
@@ -1059,7 +1078,7 @@ function BestTable({
|
|
|
1059
1078
|
ProTable,
|
|
1060
1079
|
{
|
|
1061
1080
|
...props,
|
|
1062
|
-
className: [
|
|
1081
|
+
className: ["best-lowcode-table", className].filter(Boolean).join(" "),
|
|
1063
1082
|
columns,
|
|
1064
1083
|
options: false,
|
|
1065
1084
|
search: mergeSearch(defaultSearch, search),
|
|
@@ -1352,6 +1371,14 @@ function validateCrudPageSchema(schema, registry) {
|
|
|
1352
1371
|
if (!schema.table?.columns?.length)
|
|
1353
1372
|
push(diagnostics, "/table/columns", "table.columns", "\u81F3\u5C11\u9700\u8981\u4E00\u5217");
|
|
1354
1373
|
schema.table?.columns?.forEach((column, index) => {
|
|
1374
|
+
if (column.fixed !== void 0 && column.fixed !== "left" && column.fixed !== "right") {
|
|
1375
|
+
push(
|
|
1376
|
+
diagnostics,
|
|
1377
|
+
`/table/columns/${index}/fixed`,
|
|
1378
|
+
"column.fixed",
|
|
1379
|
+
`\u4E0D\u652F\u6301\u7684\u56FA\u5B9A\u4F4D\u7F6E\uFF1A${column.fixed}`
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1355
1382
|
if (column.format && !columnFormats.has(column.format)) {
|
|
1356
1383
|
push(
|
|
1357
1384
|
diagnostics,
|
|
@@ -1514,6 +1541,7 @@ function toTableColumn(column, dictionary, slots) {
|
|
|
1514
1541
|
search: false,
|
|
1515
1542
|
title: column.title,
|
|
1516
1543
|
width: column.width,
|
|
1544
|
+
fixed: column.fixed,
|
|
1517
1545
|
valueEnum,
|
|
1518
1546
|
renderText: column.format && !slot && !column.dict ? (value) => formatCrudValue(value, column.format) : void 0,
|
|
1519
1547
|
render: slot ? (_value, record) => slots[slot]?.({
|
|
@@ -1686,9 +1714,12 @@ function BestCrudPage({ adapter, className, schema }) {
|
|
|
1686
1714
|
});
|
|
1687
1715
|
configuredColumns.push(...searchColumns.values());
|
|
1688
1716
|
if (!schema.table.actions?.length) return configuredColumns;
|
|
1717
|
+
const actionColumnWidth = Math.max(160, schema.table.actions.length * 80 + 32);
|
|
1689
1718
|
configuredColumns.push({
|
|
1690
1719
|
title: "\u64CD\u4F5C",
|
|
1691
1720
|
valueType: "option",
|
|
1721
|
+
fixed: "right",
|
|
1722
|
+
width: actionColumnWidth,
|
|
1692
1723
|
render: (_, record) => schema.table.actions?.map((action) => /* @__PURE__ */ jsx11(ActionButton, { action, record, onExecute: handleAction }, action.id))
|
|
1693
1724
|
});
|
|
1694
1725
|
return configuredColumns;
|
|
@@ -1779,10 +1810,10 @@ function BestCrudPage({ adapter, className, schema }) {
|
|
|
1779
1810
|
fields: searchFields,
|
|
1780
1811
|
value: query,
|
|
1781
1812
|
defaultValues: searchDefaultValues,
|
|
1782
|
-
onReset: () => {
|
|
1783
|
-
queryRef.current =
|
|
1813
|
+
onReset: (values) => {
|
|
1814
|
+
queryRef.current = values;
|
|
1784
1815
|
queryStateRef.current = { ...queryStateRef.current, userTouched: true };
|
|
1785
|
-
setQuery(
|
|
1816
|
+
setQuery(values);
|
|
1786
1817
|
actionRef.current?.reload();
|
|
1787
1818
|
},
|
|
1788
1819
|
onSearch: (values) => {
|
|
@@ -1853,7 +1884,7 @@ function BestCrudPage({ adapter, className, schema }) {
|
|
|
1853
1884
|
return /* @__PURE__ */ jsx11(
|
|
1854
1885
|
Button4,
|
|
1855
1886
|
{
|
|
1856
|
-
type: "link",
|
|
1887
|
+
type: action.buttonType ?? "link",
|
|
1857
1888
|
onClick: () => {
|
|
1858
1889
|
void onExecute(action, record);
|
|
1859
1890
|
},
|
|
@@ -1881,6 +1912,7 @@ export {
|
|
|
1881
1912
|
CRUD_SCHEMA_ID,
|
|
1882
1913
|
CRUD_SCHEMA_VERSION,
|
|
1883
1914
|
assertValidCrudPageSchema,
|
|
1915
|
+
composeBestRegistry,
|
|
1884
1916
|
createBestCrudAdapter,
|
|
1885
1917
|
createBestRegistry,
|
|
1886
1918
|
normalizeBestValues,
|