@nbreak/vue 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["EXTENSION_TYPES","BUILTIN_PROPERTY_FIELD_TYPES","extensionRegistry","SchemaFormRenderer","PropertyFieldRenderer","extensionRegistry","EXTENSION_TYPES","eventBus","extensionRegistry","EXTENSION_TYPES"],"sources":["../../src/propertyFieldRegistry.js","../../src/composables/useDataScreen.js","../../src/components/PropertyFieldRenderer.vue","../../src/components/SchemaFormRenderer.vue","../../src/plugin.js","../../src/composables/useExtensionRegistry.js","../../src/index.js"],"sourcesContent":["/**\n * @nbreak/vue - 属性字段编辑器注册表\n *\n * 管理所有属性字段类型对应的编辑器组件\n * 内置类型由 SchemaFormRenderer 默认处理,扩展类型从此注册表获取\n */\n\nimport {\n PROPERTY_FIELD_TYPES,\n EXTENSION_TYPES,\n BUILTIN_PROPERTY_FIELD_TYPES,\n} from '@nbreak/shared';\n\nclass PropertyFieldRegistry {\n constructor() {\n this.editors = new Map(); // fieldType -> { editor, options }\n this.serializers = new Map(); // fieldType -> { serialize, deserialize, defaultValue }\n }\n\n /**\n * 注册属性字段编辑器\n * @param {string} fieldType - 字段类型\n * @param {Object|Function} editor - Vue 组件\n * @param {Object} [options]\n * @param {Function} [options.defaultValue]\n * @param {Function} [options.serialize]\n * @param {Function} [options.deserialize]\n */\n register(fieldType, editor, options = {}) {\n if (this.editors.has(fieldType)) {\n console.warn(`[DataScreen] 属性字段 \"${fieldType}\" 已注册,覆盖`);\n }\n this.editors.set(fieldType, editor);\n if (options.defaultValue || options.serialize || options.deserialize) {\n this.serializers.set(fieldType, {\n defaultValue: options.defaultValue || (() => null),\n serialize: options.serialize || (v => v),\n deserialize: options.deserialize || (v => v),\n });\n }\n }\n\n /**\n * 从扩展定义注册\n */\n registerFromExtension(extension) {\n if (!extension || extension.type !== EXTENSION_TYPES.PROPERTY_FIELD) return;\n const def = extension.definition;\n if (!def) return;\n this.register(def.fieldType, def.editor, {\n defaultValue: def.defaultValue,\n serialize: def.serialize,\n deserialize: def.deserialize,\n });\n }\n\n /**\n * 获取编辑器\n */\n get(fieldType) {\n return this.editors.get(fieldType) || null;\n }\n\n /**\n * 检查是否存在\n */\n has(fieldType) {\n return this.editors.has(fieldType);\n }\n\n /**\n * 是否为内置类型\n */\n isBuiltin(fieldType) {\n return BUILTIN_PROPERTY_FIELD_TYPES.includes(fieldType);\n }\n\n /**\n * 获取序列化器\n */\n getSerializer(fieldType) {\n return this.serializers.get(fieldType) || {\n defaultValue: () => null,\n serialize: v => v,\n deserialize: v => v,\n };\n }\n\n /**\n * 获取所有已注册字段类型\n */\n getAllTypes() {\n return Array.from(this.editors.keys());\n }\n\n /**\n * 清空\n */\n clear() {\n this.editors.clear();\n this.serializers.clear();\n }\n\n /**\n * 获取数量\n */\n size() {\n return this.editors.size;\n }\n}\n\nexport { PropertyFieldRegistry };\nexport const propertyFieldRegistry = new PropertyFieldRegistry();\nexport default PropertyFieldRegistry;\n","/**\n * @nbreak/vue - useDataScreen composable\n *\n * 提供全局配置访问与扩展操作能力\n */\nimport { inject, getCurrentInstance } from 'vue';\nimport { extensionRegistry } from '@nbreak/core';\nimport { propertyFieldRegistry } from '../propertyFieldRegistry.js';\n\nexport const DATASCREEN_INJECTION_KEY = Symbol('datascreen');\n\n/**\n * 获取 DataScreen 全局配置\n */\nexport function useDataScreen() {\n const instance = getCurrentInstance();\n const config = instance?.appContext.config.globalProperties.$datascreen ||\n inject(DATASCREEN_INJECTION_KEY, null);\n\n return {\n config,\n extensionRegistry,\n propertyFieldRegistry,\n registerExtension: (ext) => extensionRegistry.register(ext),\n unregisterExtension: (name) => extensionRegistry.unregister(name),\n };\n}\n","<template>\n <div class=\"ds-property-field\">\n <component\n v-if=\"editorComponent\"\n :is=\"editorComponent\"\n :modelValue=\"innerValue\"\n :field=\"field\"\n :props=\"propsData\"\n :placeholder=\"field.placeholder || ''\"\n @update:modelValue=\"onUpdate\"\n />\n <div v-else class=\"ds-property-field-fallback\">\n <input\n :value=\"innerValue\"\n @input=\"onInputFallback\"\n :placeholder=\"field.placeholder || field.label || ''\"\n class=\"ds-property-field-input\"\n />\n <small v-if=\"!isBuiltin\" class=\"ds-property-field-warning\">\n 未知字段类型: {{ field.type }}\n </small>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, ref, watch } from 'vue';\nimport { propertyFieldRegistry } from '../propertyFieldRegistry.js';\n\nconst props = defineProps({\n modelValue: { default: null },\n field: { type: Object, required: true },\n propsData: { type: Object, default: () => ({}) },\n});\n\nconst emit = defineEmits(['update:modelValue']);\n\nconst innerValue = ref(props.modelValue);\n\nwatch(() => props.modelValue, (val) => {\n innerValue.value = val;\n});\n\nconst isBuiltin = computed(() => propertyFieldRegistry.isBuiltin(props.field.type));\nconst editorComponent = computed(() => propertyFieldRegistry.get(props.field.type));\n\nfunction onUpdate(val) {\n innerValue.value = val;\n emit('update:modelValue', val);\n}\n\nfunction onInputFallback(e) {\n const val = e.target.value;\n onUpdate(val);\n}\n</script>\n\n<style scoped>\n.ds-property-field {\n width: 100%;\n}\n\n.ds-property-field-fallback {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ds-property-field-input {\n width: 100%;\n padding: 4px 8px;\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 4px;\n background: rgba(0,0,0,0.15);\n color: inherit;\n font-size: 13px;\n}\n\n.ds-property-field-input:focus {\n outline: none;\n border-color: #1890ff;\n}\n\n.ds-property-field-warning {\n color: #faad14;\n font-size: 11px;\n}\n</style>\n","<template>\n <div class=\"ds-schema-form\">\n <div\n v-for=\"group in groupedFields\"\n :key=\"group.name\"\n class=\"ds-schema-form-group\"\n >\n <div class=\"ds-schema-form-group-title\">{{ group.name }}</div>\n <div class=\"ds-schema-form-group-fields\">\n <div\n v-for=\"field in group.fields\"\n :key=\"field.key\"\n v-show=\"isFieldVisible(field)\"\n class=\"ds-schema-form-field\"\n >\n <label class=\"ds-schema-form-label\">\n {{ field.label }}\n <span v-if=\"field.required\" class=\"ds-schema-form-required\">*</span>\n </label>\n <PropertyFieldRenderer\n :modelValue=\"getFieldValue(field.key)\"\n :field=\"field\"\n :propsData=\"propsData\"\n @update:modelValue=\"(val) => setFieldValue(field.key, val)\"\n />\n <small v-if=\"field.description\" class=\"ds-schema-form-description\">\n {{ field.description }}\n </small>\n <small v-if=\"errors[field.key]\" class=\"ds-schema-form-error\">\n {{ errors[field.key] }}\n </small>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { computed, ref, watch } from 'vue';\nimport { groupFields, getNestedValue, setNestedValue, isFieldVisible, validateField } from '@nbreak/shared';\nimport PropertyFieldRenderer from './PropertyFieldRenderer.vue';\n\nconst props = defineProps({\n schema: { type: Array, default: () => [] },\n modelValue: { type: Object, default: () => ({}) },\n propsData: { type: Object, default: () => ({}) },\n context: { type: Object, default: () => ({}) },\n});\n\nconst emit = defineEmits(['update:modelValue', 'validate']);\n\nconst errors = ref({});\n\nconst groupedFields = computed(() => groupFields(props.schema));\n\nwatch(() => props.modelValue, (val) => {\n validate(val);\n}, { deep: true });\n\nfunction getFieldValue(key) {\n return getNestedValue(props.modelValue, key);\n}\n\nfunction setFieldValue(key, value) {\n const newObj = { ...props.modelValue };\n setNestedValue(newObj, key, value);\n emit('update:modelValue', newObj);\n}\n\nfunction isFieldVisibleLocal(field) {\n return isFieldVisible(field, props.modelValue, { ...props.context, propsData: props.propsData });\n}\n\nfunction validate(data = props.modelValue) {\n const errs = {};\n for (const field of props.schema) {\n if (!isFieldVisibleLocal(field)) continue;\n const value = getFieldValue(field.key);\n const result = validateField(field, value);\n if (result !== true) {\n errs[field.key] = result;\n }\n }\n errors.value = errs;\n emit('validate', { valid: Object.keys(errs).length === 0, errors: errs });\n return Object.keys(errs).length === 0;\n}\n\ndefineExpose({ validate });\n</script>\n\n<style scoped>\n.ds-schema-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.ds-schema-form-group {\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.ds-schema-form-group-title {\n padding: 8px 12px;\n background: rgba(255,255,255,0.04);\n font-size: 12px;\n font-weight: 600;\n color: rgba(255,255,255,0.85);\n}\n\n.ds-schema-form-group-fields {\n padding: 8px 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ds-schema-form-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ds-schema-form-label {\n font-size: 12px;\n color: rgba(255,255,255,0.75);\n}\n\n.ds-schema-form-required {\n color: #f5222d;\n margin-left: 2px;\n}\n\n.ds-schema-form-description {\n font-size: 11px;\n color: rgba(255,255,255,0.45);\n}\n\n.ds-schema-form-error {\n font-size: 11px;\n color: #f5222d;\n}\n</style>\n","/**\n * @nbreak/vue - Vue 插件主入口\n *\n * 提供 app.use(DataScreenVue, { extensions, builtin, runtime }) 集成能力\n *\n * 注意:Vue 的 app.use() 不会 await async install,因此提供:\n * 1. DataScreenVuePlugin - 同步插件(注册全局组件、注入配置)\n * 2. setupDataScreen(app, options) - 异步 setup,await 后再 mount\n *\n * 对标:\n * - DataV 嵌入式 SDK\n * - Superset 的 @superset-ui/core + @superset-ui/vue\n */\nimport { extensionRegistry, pluginSystem, eventBus } from '@nbreak/core';\nimport { EXTENSION_TYPES, EXTENSION_STATUS } from '@nbreak/shared';\nimport { propertyFieldRegistry } from './propertyFieldRegistry.js';\nimport { DATASCREEN_INJECTION_KEY } from './composables/useDataScreen.js';\nimport SchemaFormRenderer from './components/SchemaFormRenderer.vue';\nimport PropertyFieldRenderer from './components/PropertyFieldRenderer.vue';\n\n/**\n * 异步 setup:加载扩展并注册\n * 应用方应在 app.mount() 之前 await 此函数\n *\n * @param {import('vue').App} app\n * @param {Object} [options]\n * @param {Array} [options.extensions] - 静态扩展数组\n * @param {Object} [options.builtin] - 启用内置包 { components, themes, datasources }\n * @param {Object} [options.runtime] - 运行时加载配置\n * @param {boolean} [options.autoRegisterComponents=true] - 自动注册组件扩展为全局组件\n */\nexport async function setupDataScreen(app, options = {}) {\n const {\n extensions = [],\n builtin = {},\n runtime: runtimeConfig = null,\n autoRegisterComponents = true,\n } = options;\n\n const config = {\n extensions: [],\n builtin,\n runtime: runtimeConfig,\n version: '0.1.0',\n };\n app.config.globalProperties.$datascreen = config;\n app.provide(DATASCREEN_INJECTION_KEY, config);\n\n // 注册全局组件\n app.component('SchemaFormRenderer', SchemaFormRenderer);\n app.component('PropertyFieldRenderer', PropertyFieldRenderer);\n\n // 加载内置包\n if (builtin.themes) {\n try {\n const themesPkg = await import('@nbreak/themes');\n const themeExtensions = themesPkg.extensions || (themesPkg.default ? themesPkg.default.extensions || [] : []);\n for (const ext of themeExtensions) {\n await extensionRegistry.register(ext);\n }\n console.log(`[DataScreen Vue] 已加载内置主题包 (${themeExtensions.length} 个)`);\n } catch (e) {\n console.warn('[DataScreen Vue] 内置主题包加载失败:', e.message);\n }\n }\n\n if (builtin.datasources) {\n try {\n const dsPkg = await import('@nbreak/datasources');\n const dsExtensions = dsPkg.extensions || (dsPkg.default ? dsPkg.default.extensions || [] : []);\n for (const ext of dsExtensions) {\n await extensionRegistry.register(ext);\n }\n console.log(`[DataScreen Vue] 已加载内置数据源包 (${dsExtensions.length} 个)`);\n } catch (e) {\n console.warn('[DataScreen Vue] 内置数据源包加载失败:', e.message);\n }\n }\n\n if (builtin.ui || builtin.components) {\n try {\n const uiPkg = await import('@nbreak/ui');\n const uiExtensions = uiPkg.extensions || (uiPkg.default ? uiPkg.default.extensions || [] : []);\n for (const ext of uiExtensions) {\n await extensionRegistry.register(ext);\n if (autoRegisterComponents && ext.type === EXTENSION_TYPES.COMPONENT) {\n const def = ext.definition;\n if (def && def.component) {\n app.component(def.type, def.component);\n }\n }\n }\n console.log(`[DataScreen Vue] 已加载内置组件包 (${uiExtensions.length} 个)`);\n } catch (e) {\n console.warn('[DataScreen Vue] 内置组件包加载失败:', e.message);\n }\n }\n\n // 注册静态扩展\n for (const ext of extensions) {\n await extensionRegistry.register(ext);\n config.extensions.push(ext.name);\n\n if (ext.type === EXTENSION_TYPES.PROPERTY_FIELD) {\n propertyFieldRegistry.registerFromExtension(ext);\n }\n\n if (autoRegisterComponents && ext.type === EXTENSION_TYPES.COMPONENT) {\n const def = ext.definition;\n if (def && def.component) {\n app.component(def.type, def.component);\n }\n }\n }\n\n // 运行时加载\n if (runtimeConfig) {\n try {\n const { loadExtensions, setHostVersion } = await import('@nbreak/runtime-loader');\n setHostVersion(config.version);\n\n if (runtimeConfig.manifestRegistry) {\n const { manifestRegistry } = await import('@nbreak/runtime-loader');\n manifestRegistry.addSource(runtimeConfig.manifestRegistry);\n\n if (runtimeConfig.autoLoad) {\n await manifestRegistry.sync();\n const results = await loadExtensions(manifestRegistry.getAll());\n const success = results.filter(r => r.success).length;\n const failed = results.filter(r => !r.success).length;\n console.log(`[DataScreen Vue] 运行时扩展加载: ${success} 成功, ${failed} 失败`);\n\n for (const result of results) {\n if (result.success && result.extension?.type === EXTENSION_TYPES.PROPERTY_FIELD) {\n propertyFieldRegistry.registerFromExtension(result.extension);\n }\n }\n }\n }\n } catch (e) {\n console.warn('[DataScreen Vue] 运行时加载器初始化失败:', e.message);\n }\n }\n\n console.log(`[DataScreen Vue] setup 完成 (扩展: ${extensionRegistry.size()} 个)`);\n return config;\n}\n\n/**\n * 同步 Vue 插件(仅注册全局组件和注入配置,不加载扩展)\n * 如需加载扩展,请使用 setupDataScreen()\n */\nexport const DataScreenVuePlugin = {\n name: 'DataScreenVue',\n version: '0.1.0',\n\n install(app, options = {}) {\n const config = {\n extensions: [],\n builtin: options.builtin || {},\n runtime: options.runtime || null,\n version: '0.1.0',\n };\n app.config.globalProperties.$datascreen = config;\n app.provide(DATASCREEN_INJECTION_KEY, config);\n app.component('SchemaFormRenderer', SchemaFormRenderer);\n app.component('PropertyFieldRenderer', PropertyFieldRenderer);\n\n // 如果传入了 extensions,同步注册(不 await,fire-and-forget)\n if (options.extensions) {\n for (const ext of options.extensions) {\n extensionRegistry.register(ext);\n if (options.autoRegisterComponents !== false && ext.type === EXTENSION_TYPES.COMPONENT) {\n const def = ext.definition;\n if (def && def.component) {\n app.component(def.type, def.component);\n }\n }\n if (ext.type === EXTENSION_TYPES.PROPERTY_FIELD) {\n propertyFieldRegistry.registerFromExtension(ext);\n }\n }\n }\n },\n};\n\nexport default DataScreenVuePlugin;\n","/**\n * @nbreak/vue - useExtensionRegistry composable\n *\n * 提供 Vue 响应式访问扩展注册表的能力\n */\nimport { ref, computed, onUnmounted } from 'vue';\nimport { extensionRegistry, eventBus, EXTENSION_TYPES } from '@nbreak/core';\n\n/**\n * Vue 响应式访问扩展注册表\n */\nexport function useExtensionRegistry() {\n const refreshTick = ref(0);\n\n const refresh = () => { refreshTick.value++; };\n\n const unsubscribe = eventBus.on('extension:registered', refresh);\n const unsubscribe2 = eventBus.on('extension:unregistered', refresh);\n const unsubscribe3 = eventBus.on('extension:enabled', refresh);\n const unsubscribe4 = eventBus.on('extension:disabled', refresh);\n\n onUnmounted(() => {\n unsubscribe();\n unsubscribe2();\n unsubscribe3();\n unsubscribe4();\n });\n\n const allExtensions = computed(() => {\n refreshTick.value;\n return extensionRegistry.getAll();\n });\n\n const components = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.COMPONENT);\n });\n\n const themes = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.THEME);\n });\n\n const datasources = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.DATASOURCE);\n });\n\n const templates = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.TEMPLATE);\n });\n\n const actions = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.ACTION);\n });\n\n const propertyFields = computed(() => {\n refreshTick.value;\n return extensionRegistry.getByType(EXTENSION_TYPES.PROPERTY_FIELD);\n });\n\n return {\n allExtensions,\n components,\n themes,\n datasources,\n templates,\n actions,\n propertyFields,\n getExtension: (type, name) => extensionRegistry.get(type, name),\n hasExtension: (name) => extensionRegistry.has(name),\n };\n}\n","/**\n * @nbreak/vue - 入口\n *\n * 提供:\n * - DataScreenVuePlugin(默认导出,app.use() 集成)\n * - SchemaFormRenderer(统一配置面板渲染器)\n * - PropertyFieldRenderer(字段渲染器)\n * - useExtensionRegistry / useDataScreen composables\n * - propertyFieldRegistry(字段类型注册表)\n * - re-export core 全部 API\n */\n\n// Vue 插件\nexport { DataScreenVuePlugin as default, DataScreenVuePlugin, setupDataScreen } from './plugin.js';\n\n// 组件\nexport { default as SchemaFormRenderer } from './components/SchemaFormRenderer.vue';\nexport { default as PropertyFieldRenderer } from './components/PropertyFieldRenderer.vue';\n\n// Composables\nexport { useExtensionRegistry } from './composables/useExtensionRegistry.js';\nexport { useDataScreen, DATASCREEN_INJECTION_KEY } from './composables/useDataScreen.js';\n\n// 属性字段注册表\nexport { propertyFieldRegistry, PropertyFieldRegistry } from './propertyFieldRegistry.js';\n\n// Core re-export(便于应用方一处导入)\nexport {\n extensionRegistry,\n pluginSystem,\n eventBus,\n EventBus,\n PluginSystem,\n ExtensionRegistry,\n EXTENSION_TYPES,\n EXTENSION_STATUS,\n PROPERTY_FIELD_TYPES,\n COMPONENT_CATEGORIES,\n HOOK_NAMES,\n} from '@nbreak/core';\n\n// SDK re-export\nexport {\n defineComponentExtension,\n defineThemeExtension,\n defineDataSourceExtension,\n defineTemplateExtension,\n defineActionExtension,\n definePropertyFieldExtension,\n defineExtension,\n registerExtensions,\n} from '@nbreak/sdk';\n\n// Runtime loader re-export\nexport {\n loadExtension,\n loadExtensions,\n unloadExtension,\n manifestRegistry,\n} from '@nbreak/runtime-loader';\n\n// Shared re-export\nexport {\n definePropertyField,\n definePropertyGroup,\n groupFields,\n resolveDefaults,\n getNestedValue,\n setNestedValue,\n isFieldVisible,\n validateField,\n validateManifest,\n createManifest,\n} from '@nbreak/shared';\n\n// 版本信息\nexport const VERSION = '0.1.0';\nexport const PACKAGE_NAME = '@nbreak/vue';\n"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+
2
+ .ds-property-field[data-v-93e4a7cd] {
3
+ width: 100%;
4
+ }
5
+ .ds-property-field-fallback[data-v-93e4a7cd] {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 4px;
9
+ }
10
+ .ds-property-field-input[data-v-93e4a7cd] {
11
+ width: 100%;
12
+ padding: 4px 8px;
13
+ border: 1px solid rgba(255,255,255,0.15);
14
+ border-radius: 4px;
15
+ background: rgba(0,0,0,0.15);
16
+ color: inherit;
17
+ font-size: 13px;
18
+ }
19
+ .ds-property-field-input[data-v-93e4a7cd]:focus {
20
+ outline: none;
21
+ border-color: #1890ff;
22
+ }
23
+ .ds-property-field-warning[data-v-93e4a7cd] {
24
+ color: #faad14;
25
+ font-size: 11px;
26
+ }
27
+
28
+ .ds-schema-form[data-v-e5ecc246] {
29
+ display: flex;
30
+ flex-direction: column;
31
+ gap: 12px;
32
+ }
33
+ .ds-schema-form-group[data-v-e5ecc246] {
34
+ border: 1px solid rgba(255,255,255,0.08);
35
+ border-radius: 6px;
36
+ overflow: hidden;
37
+ }
38
+ .ds-schema-form-group-title[data-v-e5ecc246] {
39
+ padding: 8px 12px;
40
+ background: rgba(255,255,255,0.04);
41
+ font-size: 12px;
42
+ font-weight: 600;
43
+ color: rgba(255,255,255,0.85);
44
+ }
45
+ .ds-schema-form-group-fields[data-v-e5ecc246] {
46
+ padding: 8px 12px;
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: 10px;
50
+ }
51
+ .ds-schema-form-field[data-v-e5ecc246] {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: 4px;
55
+ }
56
+ .ds-schema-form-label[data-v-e5ecc246] {
57
+ font-size: 12px;
58
+ color: rgba(255,255,255,0.75);
59
+ }
60
+ .ds-schema-form-required[data-v-e5ecc246] {
61
+ color: #f5222d;
62
+ margin-left: 2px;
63
+ }
64
+ .ds-schema-form-description[data-v-e5ecc246] {
65
+ font-size: 11px;
66
+ color: rgba(255,255,255,0.45);
67
+ }
68
+ .ds-schema-form-error[data-v-e5ecc246] {
69
+ font-size: 11px;
70
+ color: #f5222d;
71
+ }
72
+ /*$vite$:1*/
@@ -0,0 +1,487 @@
1
+ import { COMPONENT_CATEGORIES, EXTENSION_STATUS, EXTENSION_TYPES, EXTENSION_TYPES as EXTENSION_TYPES$1, EventBus, ExtensionRegistry, HOOK_NAMES, PROPERTY_FIELD_TYPES, PluginSystem, eventBus, eventBus as eventBus$1, extensionRegistry, extensionRegistry as extensionRegistry$1, pluginSystem } from "@nbreak/core";
2
+ import { BUILTIN_PROPERTY_FIELD_TYPES, EXTENSION_TYPES as EXTENSION_TYPES$2, createManifest, definePropertyField, definePropertyGroup, getNestedValue, getNestedValue as getNestedValue$1, groupFields, groupFields as groupFields$1, isFieldVisible, isFieldVisible as isFieldVisible$1, resolveDefaults, setNestedValue, setNestedValue as setNestedValue$1, validateField, validateField as validateField$1, validateManifest } from "@nbreak/shared";
3
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, getCurrentInstance, inject, onUnmounted, openBlock, ref, renderList, resolveDynamicComponent, toDisplayString, unref, vShow, watch, withDirectives } from "vue";
4
+ import { defineActionExtension, defineComponentExtension, defineDataSourceExtension, defineExtension, definePropertyFieldExtension, defineTemplateExtension, defineThemeExtension, registerExtensions } from "@nbreak/sdk";
5
+ import { loadExtension, loadExtensions, manifestRegistry, unloadExtension } from "@nbreak/runtime-loader";
6
+ //#region src/propertyFieldRegistry.js
7
+ /**
8
+ * @nbreak/vue - 属性字段编辑器注册表
9
+ *
10
+ * 管理所有属性字段类型对应的编辑器组件
11
+ * 内置类型由 SchemaFormRenderer 默认处理,扩展类型从此注册表获取
12
+ */
13
+ var PropertyFieldRegistry = class {
14
+ constructor() {
15
+ this.editors = /* @__PURE__ */ new Map();
16
+ this.serializers = /* @__PURE__ */ new Map();
17
+ }
18
+ /**
19
+ * 注册属性字段编辑器
20
+ * @param {string} fieldType - 字段类型
21
+ * @param {Object|Function} editor - Vue 组件
22
+ * @param {Object} [options]
23
+ * @param {Function} [options.defaultValue]
24
+ * @param {Function} [options.serialize]
25
+ * @param {Function} [options.deserialize]
26
+ */
27
+ register(fieldType, editor, options = {}) {
28
+ if (this.editors.has(fieldType)) console.warn(`[DataScreen] 属性字段 "${fieldType}" 已注册,覆盖`);
29
+ this.editors.set(fieldType, editor);
30
+ if (options.defaultValue || options.serialize || options.deserialize) this.serializers.set(fieldType, {
31
+ defaultValue: options.defaultValue || (() => null),
32
+ serialize: options.serialize || ((v) => v),
33
+ deserialize: options.deserialize || ((v) => v)
34
+ });
35
+ }
36
+ /**
37
+ * 从扩展定义注册
38
+ */
39
+ registerFromExtension(extension) {
40
+ if (!extension || extension.type !== EXTENSION_TYPES$2.PROPERTY_FIELD) return;
41
+ const def = extension.definition;
42
+ if (!def) return;
43
+ this.register(def.fieldType, def.editor, {
44
+ defaultValue: def.defaultValue,
45
+ serialize: def.serialize,
46
+ deserialize: def.deserialize
47
+ });
48
+ }
49
+ /**
50
+ * 获取编辑器
51
+ */
52
+ get(fieldType) {
53
+ return this.editors.get(fieldType) || null;
54
+ }
55
+ /**
56
+ * 检查是否存在
57
+ */
58
+ has(fieldType) {
59
+ return this.editors.has(fieldType);
60
+ }
61
+ /**
62
+ * 是否为内置类型
63
+ */
64
+ isBuiltin(fieldType) {
65
+ return BUILTIN_PROPERTY_FIELD_TYPES.includes(fieldType);
66
+ }
67
+ /**
68
+ * 获取序列化器
69
+ */
70
+ getSerializer(fieldType) {
71
+ return this.serializers.get(fieldType) || {
72
+ defaultValue: () => null,
73
+ serialize: (v) => v,
74
+ deserialize: (v) => v
75
+ };
76
+ }
77
+ /**
78
+ * 获取所有已注册字段类型
79
+ */
80
+ getAllTypes() {
81
+ return Array.from(this.editors.keys());
82
+ }
83
+ /**
84
+ * 清空
85
+ */
86
+ clear() {
87
+ this.editors.clear();
88
+ this.serializers.clear();
89
+ }
90
+ /**
91
+ * 获取数量
92
+ */
93
+ size() {
94
+ return this.editors.size;
95
+ }
96
+ };
97
+ var propertyFieldRegistry = new PropertyFieldRegistry();
98
+ //#endregion
99
+ //#region src/composables/useDataScreen.js
100
+ /**
101
+ * @nbreak/vue - useDataScreen composable
102
+ *
103
+ * 提供全局配置访问与扩展操作能力
104
+ */
105
+ var DATASCREEN_INJECTION_KEY = Symbol("datascreen");
106
+ /**
107
+ * 获取 DataScreen 全局配置
108
+ */
109
+ function useDataScreen() {
110
+ return {
111
+ config: getCurrentInstance()?.appContext.config.globalProperties.$datascreen || inject(DATASCREEN_INJECTION_KEY, null),
112
+ extensionRegistry: extensionRegistry$1,
113
+ propertyFieldRegistry,
114
+ registerExtension: (ext) => extensionRegistry$1.register(ext),
115
+ unregisterExtension: (name) => extensionRegistry$1.unregister(name)
116
+ };
117
+ }
118
+ //#endregion
119
+ //#region \0plugin-vue:export-helper
120
+ var _plugin_vue_export_helper_default = (sfc, props) => {
121
+ const target = sfc.__vccOpts || sfc;
122
+ for (const [key, val] of props) target[key] = val;
123
+ return target;
124
+ };
125
+ //#endregion
126
+ //#region src/components/PropertyFieldRenderer.vue
127
+ var _hoisted_1$1 = { class: "ds-property-field" };
128
+ var _hoisted_2$1 = {
129
+ key: 1,
130
+ class: "ds-property-field-fallback"
131
+ };
132
+ var _hoisted_3$1 = ["value", "placeholder"];
133
+ var _hoisted_4$1 = {
134
+ key: 0,
135
+ class: "ds-property-field-warning"
136
+ };
137
+ var PropertyFieldRenderer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
138
+ __name: "PropertyFieldRenderer",
139
+ props: {
140
+ modelValue: { default: null },
141
+ field: {
142
+ type: Object,
143
+ required: true
144
+ },
145
+ propsData: {
146
+ type: Object,
147
+ default: () => ({})
148
+ }
149
+ },
150
+ emits: ["update:modelValue"],
151
+ setup(__props, { emit: __emit }) {
152
+ const props = __props;
153
+ const emit = __emit;
154
+ const innerValue = ref(props.modelValue);
155
+ watch(() => props.modelValue, (val) => {
156
+ innerValue.value = val;
157
+ });
158
+ const isBuiltin = computed(() => propertyFieldRegistry.isBuiltin(props.field.type));
159
+ const editorComponent = computed(() => propertyFieldRegistry.get(props.field.type));
160
+ function onUpdate(val) {
161
+ innerValue.value = val;
162
+ emit("update:modelValue", val);
163
+ }
164
+ function onInputFallback(e) {
165
+ const val = e.target.value;
166
+ onUpdate(val);
167
+ }
168
+ return (_ctx, _cache) => {
169
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [editorComponent.value ? (openBlock(), createBlock(resolveDynamicComponent(editorComponent.value), {
170
+ key: 0,
171
+ modelValue: innerValue.value,
172
+ field: __props.field,
173
+ props: __props.propsData,
174
+ placeholder: __props.field.placeholder || "",
175
+ "onUpdate:modelValue": onUpdate
176
+ }, null, 8, [
177
+ "modelValue",
178
+ "field",
179
+ "props",
180
+ "placeholder"
181
+ ])) : (openBlock(), createElementBlock("div", _hoisted_2$1, [createElementVNode("input", {
182
+ value: innerValue.value,
183
+ onInput: onInputFallback,
184
+ placeholder: __props.field.placeholder || __props.field.label || "",
185
+ class: "ds-property-field-input"
186
+ }, null, 40, _hoisted_3$1), !isBuiltin.value ? (openBlock(), createElementBlock("small", _hoisted_4$1, " 未知字段类型: " + toDisplayString(__props.field.type), 1)) : createCommentVNode("", true)]))]);
187
+ };
188
+ }
189
+ }, [["__scopeId", "data-v-93e4a7cd"]]);
190
+ //#endregion
191
+ //#region src/components/SchemaFormRenderer.vue
192
+ var _hoisted_1 = { class: "ds-schema-form" };
193
+ var _hoisted_2 = { class: "ds-schema-form-group-title" };
194
+ var _hoisted_3 = { class: "ds-schema-form-group-fields" };
195
+ var _hoisted_4 = { class: "ds-schema-form-label" };
196
+ var _hoisted_5 = {
197
+ key: 0,
198
+ class: "ds-schema-form-required"
199
+ };
200
+ var _hoisted_6 = {
201
+ key: 0,
202
+ class: "ds-schema-form-description"
203
+ };
204
+ var _hoisted_7 = {
205
+ key: 1,
206
+ class: "ds-schema-form-error"
207
+ };
208
+ var SchemaFormRenderer_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
209
+ __name: "SchemaFormRenderer",
210
+ props: {
211
+ schema: {
212
+ type: Array,
213
+ default: () => []
214
+ },
215
+ modelValue: {
216
+ type: Object,
217
+ default: () => ({})
218
+ },
219
+ propsData: {
220
+ type: Object,
221
+ default: () => ({})
222
+ },
223
+ context: {
224
+ type: Object,
225
+ default: () => ({})
226
+ }
227
+ },
228
+ emits: ["update:modelValue", "validate"],
229
+ setup(__props, { expose: __expose, emit: __emit }) {
230
+ const props = __props;
231
+ const emit = __emit;
232
+ const errors = ref({});
233
+ const groupedFields = computed(() => groupFields$1(props.schema));
234
+ watch(() => props.modelValue, (val) => {
235
+ validate(val);
236
+ }, { deep: true });
237
+ function getFieldValue(key) {
238
+ return getNestedValue$1(props.modelValue, key);
239
+ }
240
+ function setFieldValue(key, value) {
241
+ const newObj = { ...props.modelValue };
242
+ setNestedValue$1(newObj, key, value);
243
+ emit("update:modelValue", newObj);
244
+ }
245
+ function isFieldVisibleLocal(field) {
246
+ return isFieldVisible$1(field, props.modelValue, {
247
+ ...props.context,
248
+ propsData: props.propsData
249
+ });
250
+ }
251
+ function validate(data = props.modelValue) {
252
+ const errs = {};
253
+ for (const field of props.schema) {
254
+ if (!isFieldVisibleLocal(field)) continue;
255
+ const result = validateField$1(field, getFieldValue(field.key));
256
+ if (result !== true) errs[field.key] = result;
257
+ }
258
+ errors.value = errs;
259
+ emit("validate", {
260
+ valid: Object.keys(errs).length === 0,
261
+ errors: errs
262
+ });
263
+ return Object.keys(errs).length === 0;
264
+ }
265
+ __expose({ validate });
266
+ return (_ctx, _cache) => {
267
+ return openBlock(), createElementBlock("div", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(groupedFields.value, (group) => {
268
+ return openBlock(), createElementBlock("div", {
269
+ key: group.name,
270
+ class: "ds-schema-form-group"
271
+ }, [createElementVNode("div", _hoisted_2, toDisplayString(group.name), 1), createElementVNode("div", _hoisted_3, [(openBlock(true), createElementBlock(Fragment, null, renderList(group.fields, (field) => {
272
+ return withDirectives((openBlock(), createElementBlock("div", {
273
+ key: field.key,
274
+ class: "ds-schema-form-field"
275
+ }, [
276
+ createElementVNode("label", _hoisted_4, [createTextVNode(toDisplayString(field.label) + " ", 1), field.required ? (openBlock(), createElementBlock("span", _hoisted_5, "*")) : createCommentVNode("", true)]),
277
+ createVNode(PropertyFieldRenderer_default, {
278
+ modelValue: getFieldValue(field.key),
279
+ field,
280
+ propsData: __props.propsData,
281
+ "onUpdate:modelValue": (val) => setFieldValue(field.key, val)
282
+ }, null, 8, [
283
+ "modelValue",
284
+ "field",
285
+ "propsData",
286
+ "onUpdate:modelValue"
287
+ ]),
288
+ field.description ? (openBlock(), createElementBlock("small", _hoisted_6, toDisplayString(field.description), 1)) : createCommentVNode("", true),
289
+ errors.value[field.key] ? (openBlock(), createElementBlock("small", _hoisted_7, toDisplayString(errors.value[field.key]), 1)) : createCommentVNode("", true)
290
+ ])), [[vShow, unref(isFieldVisible$1)(field)]]);
291
+ }), 128))])]);
292
+ }), 128))]);
293
+ };
294
+ }
295
+ }, [["__scopeId", "data-v-e5ecc246"]]);
296
+ //#endregion
297
+ //#region src/plugin.js
298
+ /**
299
+ * @nbreak/vue - Vue 插件主入口
300
+ *
301
+ * 提供 app.use(DataScreenVue, { extensions, builtin, runtime }) 集成能力
302
+ *
303
+ * 注意:Vue 的 app.use() 不会 await async install,因此提供:
304
+ * 1. DataScreenVuePlugin - 同步插件(注册全局组件、注入配置)
305
+ * 2. setupDataScreen(app, options) - 异步 setup,await 后再 mount
306
+ *
307
+ * 对标:
308
+ * - DataV 嵌入式 SDK
309
+ * - Superset 的 @superset-ui/core + @superset-ui/vue
310
+ */
311
+ /**
312
+ * 异步 setup:加载扩展并注册
313
+ * 应用方应在 app.mount() 之前 await 此函数
314
+ *
315
+ * @param {import('vue').App} app
316
+ * @param {Object} [options]
317
+ * @param {Array} [options.extensions] - 静态扩展数组
318
+ * @param {Object} [options.builtin] - 启用内置包 { components, themes, datasources }
319
+ * @param {Object} [options.runtime] - 运行时加载配置
320
+ * @param {boolean} [options.autoRegisterComponents=true] - 自动注册组件扩展为全局组件
321
+ */
322
+ async function setupDataScreen(app, options = {}) {
323
+ const { extensions = [], builtin = {}, runtime: runtimeConfig = null, autoRegisterComponents = true } = options;
324
+ const config = {
325
+ extensions: [],
326
+ builtin,
327
+ runtime: runtimeConfig,
328
+ version: "0.1.0"
329
+ };
330
+ app.config.globalProperties.$datascreen = config;
331
+ app.provide(DATASCREEN_INJECTION_KEY, config);
332
+ app.component("SchemaFormRenderer", SchemaFormRenderer_default);
333
+ app.component("PropertyFieldRenderer", PropertyFieldRenderer_default);
334
+ if (builtin.themes) try {
335
+ const themesPkg = await import("@nbreak/themes");
336
+ const themeExtensions = themesPkg.extensions || (themesPkg.default ? themesPkg.default.extensions || [] : []);
337
+ for (const ext of themeExtensions) await extensionRegistry$1.register(ext);
338
+ console.log(`[DataScreen Vue] 已加载内置主题包 (${themeExtensions.length} 个)`);
339
+ } catch (e) {
340
+ console.warn("[DataScreen Vue] 内置主题包加载失败:", e.message);
341
+ }
342
+ if (builtin.datasources) try {
343
+ const dsPkg = await import("@nbreak/datasources");
344
+ const dsExtensions = dsPkg.extensions || (dsPkg.default ? dsPkg.default.extensions || [] : []);
345
+ for (const ext of dsExtensions) await extensionRegistry$1.register(ext);
346
+ console.log(`[DataScreen Vue] 已加载内置数据源包 (${dsExtensions.length} 个)`);
347
+ } catch (e) {
348
+ console.warn("[DataScreen Vue] 内置数据源包加载失败:", e.message);
349
+ }
350
+ if (builtin.ui || builtin.components) try {
351
+ const uiPkg = await import("@nbreak/ui");
352
+ const uiExtensions = uiPkg.extensions || (uiPkg.default ? uiPkg.default.extensions || [] : []);
353
+ for (const ext of uiExtensions) {
354
+ await extensionRegistry$1.register(ext);
355
+ if (autoRegisterComponents && ext.type === EXTENSION_TYPES$2.COMPONENT) {
356
+ const def = ext.definition;
357
+ if (def && def.component) app.component(def.type, def.component);
358
+ }
359
+ }
360
+ console.log(`[DataScreen Vue] 已加载内置组件包 (${uiExtensions.length} 个)`);
361
+ } catch (e) {
362
+ console.warn("[DataScreen Vue] 内置组件包加载失败:", e.message);
363
+ }
364
+ for (const ext of extensions) {
365
+ await extensionRegistry$1.register(ext);
366
+ config.extensions.push(ext.name);
367
+ if (ext.type === EXTENSION_TYPES$2.PROPERTY_FIELD) propertyFieldRegistry.registerFromExtension(ext);
368
+ if (autoRegisterComponents && ext.type === EXTENSION_TYPES$2.COMPONENT) {
369
+ const def = ext.definition;
370
+ if (def && def.component) app.component(def.type, def.component);
371
+ }
372
+ }
373
+ if (runtimeConfig) try {
374
+ const { loadExtensions, setHostVersion } = await import("@nbreak/runtime-loader");
375
+ setHostVersion(config.version);
376
+ if (runtimeConfig.manifestRegistry) {
377
+ const { manifestRegistry } = await import("@nbreak/runtime-loader");
378
+ manifestRegistry.addSource(runtimeConfig.manifestRegistry);
379
+ if (runtimeConfig.autoLoad) {
380
+ await manifestRegistry.sync();
381
+ const results = await loadExtensions(manifestRegistry.getAll());
382
+ const success = results.filter((r) => r.success).length;
383
+ const failed = results.filter((r) => !r.success).length;
384
+ console.log(`[DataScreen Vue] 运行时扩展加载: ${success} 成功, ${failed} 失败`);
385
+ for (const result of results) if (result.success && result.extension?.type === EXTENSION_TYPES$2.PROPERTY_FIELD) propertyFieldRegistry.registerFromExtension(result.extension);
386
+ }
387
+ }
388
+ } catch (e) {
389
+ console.warn("[DataScreen Vue] 运行时加载器初始化失败:", e.message);
390
+ }
391
+ console.log(`[DataScreen Vue] setup 完成 (扩展: ${extensionRegistry$1.size()} 个)`);
392
+ return config;
393
+ }
394
+ /**
395
+ * 同步 Vue 插件(仅注册全局组件和注入配置,不加载扩展)
396
+ * 如需加载扩展,请使用 setupDataScreen()
397
+ */
398
+ var DataScreenVuePlugin = {
399
+ name: "DataScreenVue",
400
+ version: "0.1.0",
401
+ install(app, options = {}) {
402
+ const config = {
403
+ extensions: [],
404
+ builtin: options.builtin || {},
405
+ runtime: options.runtime || null,
406
+ version: "0.1.0"
407
+ };
408
+ app.config.globalProperties.$datascreen = config;
409
+ app.provide(DATASCREEN_INJECTION_KEY, config);
410
+ app.component("SchemaFormRenderer", SchemaFormRenderer_default);
411
+ app.component("PropertyFieldRenderer", PropertyFieldRenderer_default);
412
+ if (options.extensions) for (const ext of options.extensions) {
413
+ extensionRegistry$1.register(ext);
414
+ if (options.autoRegisterComponents !== false && ext.type === EXTENSION_TYPES$2.COMPONENT) {
415
+ const def = ext.definition;
416
+ if (def && def.component) app.component(def.type, def.component);
417
+ }
418
+ if (ext.type === EXTENSION_TYPES$2.PROPERTY_FIELD) propertyFieldRegistry.registerFromExtension(ext);
419
+ }
420
+ }
421
+ };
422
+ //#endregion
423
+ //#region src/composables/useExtensionRegistry.js
424
+ /**
425
+ * @nbreak/vue - useExtensionRegistry composable
426
+ *
427
+ * 提供 Vue 响应式访问扩展注册表的能力
428
+ */
429
+ /**
430
+ * Vue 响应式访问扩展注册表
431
+ */
432
+ function useExtensionRegistry() {
433
+ const refreshTick = ref(0);
434
+ const refresh = () => {
435
+ refreshTick.value++;
436
+ };
437
+ const unsubscribe = eventBus$1.on("extension:registered", refresh);
438
+ const unsubscribe2 = eventBus$1.on("extension:unregistered", refresh);
439
+ const unsubscribe3 = eventBus$1.on("extension:enabled", refresh);
440
+ const unsubscribe4 = eventBus$1.on("extension:disabled", refresh);
441
+ onUnmounted(() => {
442
+ unsubscribe();
443
+ unsubscribe2();
444
+ unsubscribe3();
445
+ unsubscribe4();
446
+ });
447
+ return {
448
+ allExtensions: computed(() => {
449
+ refreshTick.value;
450
+ return extensionRegistry$1.getAll();
451
+ }),
452
+ components: computed(() => {
453
+ refreshTick.value;
454
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.COMPONENT);
455
+ }),
456
+ themes: computed(() => {
457
+ refreshTick.value;
458
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.THEME);
459
+ }),
460
+ datasources: computed(() => {
461
+ refreshTick.value;
462
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.DATASOURCE);
463
+ }),
464
+ templates: computed(() => {
465
+ refreshTick.value;
466
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.TEMPLATE);
467
+ }),
468
+ actions: computed(() => {
469
+ refreshTick.value;
470
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.ACTION);
471
+ }),
472
+ propertyFields: computed(() => {
473
+ refreshTick.value;
474
+ return extensionRegistry$1.getByType(EXTENSION_TYPES$1.PROPERTY_FIELD);
475
+ }),
476
+ getExtension: (type, name) => extensionRegistry$1.get(type, name),
477
+ hasExtension: (name) => extensionRegistry$1.has(name)
478
+ };
479
+ }
480
+ //#endregion
481
+ //#region src/index.js
482
+ var VERSION = "0.1.0";
483
+ var PACKAGE_NAME = "@nbreak/vue";
484
+ //#endregion
485
+ export { COMPONENT_CATEGORIES, DATASCREEN_INJECTION_KEY, DataScreenVuePlugin, DataScreenVuePlugin as default, EXTENSION_STATUS, EXTENSION_TYPES, EventBus, ExtensionRegistry, HOOK_NAMES, PACKAGE_NAME, PROPERTY_FIELD_TYPES, PluginSystem, PropertyFieldRegistry, PropertyFieldRenderer_default as PropertyFieldRenderer, SchemaFormRenderer_default as SchemaFormRenderer, VERSION, createManifest, defineActionExtension, defineComponentExtension, defineDataSourceExtension, defineExtension, definePropertyField, definePropertyFieldExtension, definePropertyGroup, defineTemplateExtension, defineThemeExtension, eventBus, extensionRegistry, getNestedValue, groupFields, isFieldVisible, loadExtension, loadExtensions, manifestRegistry, pluginSystem, propertyFieldRegistry, registerExtensions, resolveDefaults, setNestedValue, setupDataScreen, unloadExtension, useDataScreen, useExtensionRegistry, validateField, validateManifest };
486
+
487
+ //# sourceMappingURL=index.js.map