@loom-framework/core 0.1.0-alpha.14 → 0.1.0-alpha.141
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/builtin-skills/antd/SKILL.md +266 -0
- package/builtin-skills/antv-g2-chart/SKILL.md +1067 -0
- package/builtin-skills/antv-g2-chart/references/animations/g2-animation-intro.md +176 -0
- package/builtin-skills/antv-g2-chart/references/animations/g2-animation-keyframe.md +149 -0
- package/builtin-skills/antv-g2-chart/references/animations/g2-animation-types.md +253 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-annotation.md +237 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-axis-config.md +648 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-axis-radar.md +219 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-label-config.md +174 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-legend-category.md +278 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-legend-config.md +363 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-legend-continuous.md +264 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-scrollbar.md +276 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-slider.md +333 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-title.md +149 -0
- package/builtin-skills/antv-g2-chart/references/components/g2-comp-tooltip-config.md +358 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-facet-circle.md +97 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-facet-rect.md +241 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-geo-map.md +210 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-geoview.md +143 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-repeat-matrix.md +171 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-space-flex.md +142 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-space-layer.md +149 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-timing-keyframe.md +91 -0
- package/builtin-skills/antv-g2-chart/references/compositions/g2-comp-view.md +309 -0
- package/builtin-skills/antv-g2-chart/references/concepts/g2-concept-chart-selection.md +235 -0
- package/builtin-skills/antv-g2-chart/references/concepts/g2-concept-color-theory.md +287 -0
- package/builtin-skills/antv-g2-chart/references/concepts/g2-concept-visual-channels.md +180 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-cartesian.md +131 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-fisheye.md +131 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-helix.md +141 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-parallel.md +129 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-polar.md +143 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-radial.md +214 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-theta.md +171 -0
- package/builtin-skills/antv-g2-chart/references/coordinates/g2-coord-transpose.md +195 -0
- package/builtin-skills/antv-g2-chart/references/core/g2-core-chart-init.md +266 -0
- package/builtin-skills/antv-g2-chart/references/core/g2-core-encode-channel.md +197 -0
- package/builtin-skills/antv-g2-chart/references/core/g2-core-view-composition.md +224 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-ema.md +190 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-fetch.md +167 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-filter.md +212 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-fold.md +260 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-format-tabular.md +280 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-kde.md +426 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-log.md +140 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-slice.md +147 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-sort.md +251 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-sortby.md +183 -0
- package/builtin-skills/antv-g2-chart/references/data/g2-data-transform-patterns.md +394 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-adaptive-filter.md +118 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brush-axis.md +112 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brush-filter.md +122 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brush-x-y-highlight.md +127 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brush-xy.md +118 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brush.md +184 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brushx-filter.md +170 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brushx-highlight.md +186 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brushy-filter.md +170 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-brushy-highlight.md +185 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-chart-index.md +127 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-drilldown.md +149 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-highlight-by.md +125 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-highlight.md +235 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-hover-scale.md +109 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-point-move.md +152 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-select-by.md +133 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-element-select.md +249 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-fisheye.md +117 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-legend-filter.md +130 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-legend-highlight.md +130 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-poptip.md +105 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-scrollbar-filter.md +144 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-slider-filter.md +231 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-slider-wheel.md +138 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-tooltip.md +192 -0
- package/builtin-skills/antv-g2-chart/references/interactions/g2-interaction-treemap-drilldown.md +152 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-contrast-reverse.md +170 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-exceed-adjust.md +146 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-overflow-hide.md +185 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-overflow-stroke.md +147 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-overlap-dodge-y.md +225 -0
- package/builtin-skills/antv-g2-chart/references/label-transform/g2-label-transform-overlap-hide.md +213 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-arc-diagram.md +196 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-arc-donut.md +148 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-arc-pie.md +212 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-area-basic.md +168 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-area-stacked.md +150 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-beeswarm.md +134 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-bi-directional-bar.md +297 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-box-boxplot.md +163 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-boxplot.md +340 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-bullet.md +203 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-cell-heatmap.md +370 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-chord.md +341 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-connector.md +126 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-contourline.md +243 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-density.md +457 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-distribution-curve.md +298 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-funnel.md +329 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-gantt.md +208 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-gauge.md +247 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-heatmap.md +130 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-histogram.md +186 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-image.md +129 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-interval-basic.md +528 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-interval-grouped.md +161 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-interval-normalized.md +147 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-interval-stacked.md +183 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-k-chart.md +237 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-line-basic.md +353 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-line-multi.md +156 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-linex-liney.md +176 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-link.md +134 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-liquid.md +125 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-mosaic.md +257 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-pack.md +424 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-parallel.md +195 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-partition.md +275 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-path.md +135 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-point-bubble.md +138 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-point-scatter.md +177 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-polygon.md +130 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-radar.md +231 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-radial-bar.md +226 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-range-rangey.md +253 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-rangex.md +293 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-rect.md +115 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-regression-curve.md +276 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-rose.md +182 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-sankey.md +217 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-shape.md +160 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-spiral.md +257 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-sunburst.md +327 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-text.md +309 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-tree.md +235 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-treemap.md +426 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-vector.md +108 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-venn.md +204 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-violin.md +307 -0
- package/builtin-skills/antv-g2-chart/references/marks/g2-mark-wordcloud.md +155 -0
- package/builtin-skills/antv-g2-chart/references/palette/g2-palette-category10.md +196 -0
- package/builtin-skills/antv-g2-chart/references/palette/g2-palette-category20.md +238 -0
- package/builtin-skills/antv-g2-chart/references/patterns/g2-pattern-performance.md +181 -0
- package/builtin-skills/antv-g2-chart/references/patterns/g2-pattern-responsive.md +232 -0
- package/builtin-skills/antv-g2-chart/references/patterns/g2-pattern-v4-to-v5.md +223 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-band.md +127 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-linear.md +259 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-log.md +226 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-ordinal.md +135 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-point.md +242 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-pow-sqrt.md +124 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-quantile-quantize.md +119 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-sequential.md +267 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-threshold.md +133 -0
- package/builtin-skills/antv-g2-chart/references/scales/g2-scale-time.md +159 -0
- package/builtin-skills/antv-g2-chart/references/themes/g2-theme-builtin.md +192 -0
- package/builtin-skills/antv-g2-chart/references/themes/g2-theme-custom.md +183 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-bin.md +153 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-binx.md +133 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-diffy.md +130 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-dodgex.md +90 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-flexx.md +115 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-group.md +233 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-groupcolor.md +182 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-groupx.md +265 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-groupy.md +167 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-jitter.md +149 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-jitterx.md +177 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-jittery.md +177 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-normalizey.md +83 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-pack.md +164 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-sample.md +143 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-select.md +147 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-selectx.md +179 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-selecty.md +179 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-sort-color.md +115 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-sortx.md +285 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-sorty.md +117 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-stack-enter.md +158 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-stacky.md +218 -0
- package/builtin-skills/antv-g2-chart/references/transforms/g2-transform-symmetryy.md +122 -0
- package/builtin-skills/app-skill/SKILL.md +27 -0
- package/builtin-skills/app-skill/references/data-semantics.md +44 -0
- package/builtin-skills/app-skill/references/models.md +31 -0
- package/builtin-skills/chart-visualization/SKILL.md +101 -0
- package/builtin-skills/loom/SKILL.md +213 -0
- package/builtin-skills/loom/references/README.md +211 -0
- package/builtin-skills/loom/references/dashboard.md +257 -0
- package/builtin-skills/loom/references/data-model.md +196 -0
- package/dist/adapter-base.d.ts +31 -0
- package/dist/adapter-base.d.ts.map +1 -0
- package/dist/adapter-base.js +69 -0
- package/dist/adapter-base.js.map +1 -0
- package/dist/adapter-factory.d.ts +8 -0
- package/dist/adapter-factory.d.ts.map +1 -0
- package/dist/adapter-factory.js +25 -0
- package/dist/adapter-factory.js.map +1 -0
- package/dist/adapter-filesystem.d.ts +25 -11
- package/dist/adapter-filesystem.d.ts.map +1 -1
- package/dist/adapter-filesystem.js +230 -52
- package/dist/adapter-filesystem.js.map +1 -1
- package/dist/adapter-sqlite.d.ts +9 -23
- package/dist/adapter-sqlite.d.ts.map +1 -1
- package/dist/adapter-sqlite.js +94 -55
- package/dist/adapter-sqlite.js.map +1 -1
- package/dist/backend/ai/button-resolver.d.ts +18 -0
- package/dist/backend/ai/button-resolver.d.ts.map +1 -0
- package/dist/backend/ai/button-resolver.js +58 -0
- package/dist/backend/ai/button-resolver.js.map +1 -0
- package/dist/backend/ai/engine.d.ts +60 -0
- package/dist/backend/ai/engine.d.ts.map +1 -0
- package/dist/backend/ai/engine.js +205 -0
- package/dist/backend/ai/engine.js.map +1 -0
- package/dist/backend/ai/index.d.ts +11 -0
- package/dist/backend/ai/index.d.ts.map +1 -0
- package/dist/backend/ai/index.js +8 -0
- package/dist/backend/ai/index.js.map +1 -0
- package/dist/backend/ai/output-parser.d.ts +29 -0
- package/dist/backend/ai/output-parser.d.ts.map +1 -0
- package/dist/backend/ai/output-parser.js +247 -0
- package/dist/backend/ai/output-parser.js.map +1 -0
- package/dist/backend/ai/session-manager.d.ts +103 -0
- package/dist/backend/ai/session-manager.d.ts.map +1 -0
- package/dist/backend/ai/session-manager.js +298 -0
- package/dist/backend/ai/session-manager.js.map +1 -0
- package/dist/backend/index.d.ts +61 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +166 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/observe/index.d.ts +6 -0
- package/dist/backend/observe/index.d.ts.map +1 -0
- package/dist/backend/observe/index.js +5 -0
- package/dist/backend/observe/index.js.map +1 -0
- package/dist/backend/observe/logger.d.ts +28 -0
- package/dist/backend/observe/logger.d.ts.map +1 -0
- package/dist/backend/observe/logger.js +80 -0
- package/dist/backend/observe/logger.js.map +1 -0
- package/dist/backend/observe/types.d.ts +26 -0
- package/dist/backend/observe/types.d.ts.map +1 -0
- package/dist/backend/observe/types.js +7 -0
- package/dist/backend/observe/types.js.map +1 -0
- package/dist/backend/routes/ai-config.d.ts +13 -0
- package/dist/backend/routes/ai-config.d.ts.map +1 -0
- package/dist/backend/routes/ai-config.js +170 -0
- package/dist/backend/routes/ai-config.js.map +1 -0
- package/dist/backend/routes/chat.d.ts +31 -0
- package/dist/backend/routes/chat.d.ts.map +1 -0
- package/dist/backend/routes/chat.js +428 -0
- package/dist/backend/routes/chat.js.map +1 -0
- package/dist/backend/routes/data.d.ts +14 -0
- package/dist/backend/routes/data.d.ts.map +1 -0
- package/dist/backend/routes/data.js +357 -0
- package/dist/backend/routes/data.js.map +1 -0
- package/dist/backend/routes/health.d.ts +7 -0
- package/dist/backend/routes/health.d.ts.map +1 -0
- package/dist/backend/routes/health.js +15 -0
- package/dist/backend/routes/health.js.map +1 -0
- package/dist/backend/routes/index.d.ts +12 -0
- package/dist/backend/routes/index.d.ts.map +1 -0
- package/dist/backend/routes/index.js +10 -0
- package/dist/backend/routes/index.js.map +1 -0
- package/dist/backend/routes/skills.d.ts +16 -0
- package/dist/backend/routes/skills.d.ts.map +1 -0
- package/dist/backend/routes/skills.js +590 -0
- package/dist/backend/routes/skills.js.map +1 -0
- package/dist/backend/routes/upload.d.ts +24 -0
- package/dist/backend/routes/upload.d.ts.map +1 -0
- package/dist/backend/routes/upload.js +99 -0
- package/dist/backend/routes/upload.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +12 -0
- package/dist/bin.js.map +1 -0
- package/dist/capability-generator.d.ts +21 -6
- package/dist/capability-generator.d.ts.map +1 -1
- package/dist/capability-generator.js +88 -261
- package/dist/capability-generator.js.map +1 -1
- package/dist/cli/commands/build.d.ts +11 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +170 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/data.d.ts +12 -0
- package/dist/cli/commands/data.d.ts.map +1 -0
- package/dist/cli/commands/data.js +158 -0
- package/dist/cli/commands/data.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +9 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +114 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate-capabilities.d.ts +8 -0
- package/dist/cli/commands/generate-capabilities.d.ts.map +1 -0
- package/dist/cli/commands/generate-capabilities.js +40 -0
- package/dist/cli/commands/generate-capabilities.js.map +1 -0
- package/dist/cli/commands/generate-cli-command.d.ts +8 -0
- package/dist/cli/commands/generate-cli-command.d.ts.map +1 -0
- package/dist/cli/commands/generate-cli-command.js +64 -0
- package/dist/cli/commands/generate-cli-command.js.map +1 -0
- package/dist/cli/commands/generate-dashboard.d.ts +9 -0
- package/dist/cli/commands/generate-dashboard.d.ts.map +1 -0
- package/dist/cli/commands/generate-dashboard.js +560 -0
- package/dist/cli/commands/generate-dashboard.js.map +1 -0
- package/dist/cli/commands/generate-page.d.ts +9 -0
- package/dist/cli/commands/generate-page.d.ts.map +1 -0
- package/dist/cli/commands/generate-page.js +542 -0
- package/dist/cli/commands/generate-page.js.map +1 -0
- package/dist/cli/commands/generate-skill.d.ts +8 -0
- package/dist/cli/commands/generate-skill.d.ts.map +1 -0
- package/dist/cli/commands/generate-skill.js +75 -0
- package/dist/cli/commands/generate-skill.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +6 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +19 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +320 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/observe.d.ts +9 -0
- package/dist/cli/commands/observe.d.ts.map +1 -0
- package/dist/cli/commands/observe.js +142 -0
- package/dist/cli/commands/observe.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +9 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +186 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/generators/capability-generator.d.ts +35 -0
- package/dist/cli/generators/capability-generator.d.ts.map +1 -0
- package/dist/cli/generators/capability-generator.js +115 -0
- package/dist/cli/generators/capability-generator.js.map +1 -0
- package/dist/cli/helpers/app-tsx-wiring.d.ts +22 -0
- package/dist/cli/helpers/app-tsx-wiring.d.ts.map +1 -0
- package/dist/cli/helpers/app-tsx-wiring.js +293 -0
- package/dist/cli/helpers/app-tsx-wiring.js.map +1 -0
- package/dist/cli/helpers/backup.d.ts +16 -0
- package/dist/cli/helpers/backup.d.ts.map +1 -0
- package/dist/cli/helpers/backup.js +37 -0
- package/dist/cli/helpers/backup.js.map +1 -0
- package/dist/cli/helpers/column-template.d.ts +18 -0
- package/dist/cli/helpers/column-template.d.ts.map +1 -0
- package/dist/cli/helpers/column-template.js +158 -0
- package/dist/cli/helpers/column-template.js.map +1 -0
- package/dist/cli/helpers/duration.d.ts +5 -0
- package/dist/cli/helpers/duration.d.ts.map +1 -0
- package/dist/cli/helpers/duration.js +19 -0
- package/dist/cli/helpers/duration.js.map +1 -0
- package/dist/cli/helpers/field-template.d.ts +14 -0
- package/dist/cli/helpers/field-template.d.ts.map +1 -0
- package/dist/cli/helpers/field-template.js +108 -0
- package/dist/cli/helpers/field-template.js.map +1 -0
- package/dist/cli/helpers/naming.d.ts +12 -0
- package/dist/cli/helpers/naming.d.ts.map +1 -0
- package/dist/cli/helpers/naming.js +25 -0
- package/dist/cli/helpers/naming.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/templates/backend-entry.d.ts +5 -0
- package/dist/cli/templates/backend-entry.d.ts.map +1 -0
- package/dist/cli/templates/backend-entry.js +17 -0
- package/dist/cli/templates/backend-entry.js.map +1 -0
- package/dist/cli/templates/claude-md.d.ts +20 -0
- package/dist/cli/templates/claude-md.d.ts.map +1 -0
- package/dist/cli/templates/claude-md.js +123 -0
- package/dist/cli/templates/claude-md.js.map +1 -0
- package/dist/cli/templates/frontend-entry.d.ts +11 -0
- package/dist/cli/templates/frontend-entry.d.ts.map +1 -0
- package/dist/cli/templates/frontend-entry.js +97 -0
- package/dist/cli/templates/frontend-entry.js.map +1 -0
- package/dist/cli/templates/gitignore.d.ts +5 -0
- package/dist/cli/templates/gitignore.d.ts.map +1 -0
- package/dist/cli/templates/gitignore.js +13 -0
- package/dist/cli/templates/gitignore.js.map +1 -0
- package/dist/cli/templates/index.d.ts +13 -0
- package/dist/cli/templates/index.d.ts.map +1 -0
- package/dist/cli/templates/index.js +13 -0
- package/dist/cli/templates/index.js.map +1 -0
- package/dist/cli/templates/loom-config.d.ts +13 -0
- package/dist/cli/templates/loom-config.d.ts.map +1 -0
- package/dist/cli/templates/loom-config.js +50 -0
- package/dist/cli/templates/loom-config.js.map +1 -0
- package/dist/cli/templates/package-json.d.ts +9 -0
- package/dist/cli/templates/package-json.d.ts.map +1 -0
- package/dist/cli/templates/package-json.js +41 -0
- package/dist/cli/templates/package-json.js.map +1 -0
- package/dist/cli/templates/readme.d.ts +9 -0
- package/dist/cli/templates/readme.d.ts.map +1 -0
- package/dist/cli/templates/readme.js +47 -0
- package/dist/cli/templates/readme.js.map +1 -0
- package/dist/cli/templates/tsconfig.d.ts +6 -0
- package/dist/cli/templates/tsconfig.d.ts.map +1 -0
- package/dist/cli/templates/tsconfig.js +41 -0
- package/dist/cli/templates/tsconfig.js.map +1 -0
- package/dist/cli/templates/vite-config.d.ts +5 -0
- package/dist/cli/templates/vite-config.d.ts.map +1 -0
- package/dist/cli/templates/vite-config.js +24 -0
- package/dist/cli/templates/vite-config.js.map +1 -0
- package/dist/cli/utils.d.ts +10 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +31 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/commands.d.ts +1 -5
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +0 -11
- package/dist/commands.js.map +1 -1
- package/dist/config.d.ts +439 -69
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +51 -14
- package/dist/config.js.map +1 -1
- package/dist/dashboard-config.d.ts +149 -0
- package/dist/dashboard-config.d.ts.map +1 -0
- package/dist/dashboard-config.js +40 -0
- package/dist/dashboard-config.js.map +1 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/server-bin.d.ts +12 -0
- package/dist/server-bin.d.ts.map +1 -0
- package/dist/server-bin.js +43 -0
- package/dist/server-bin.js.map +1 -0
- package/dist/types/adapter.d.ts +30 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +5 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/ai.d.ts +66 -0
- package/dist/types/ai.d.ts.map +1 -0
- package/dist/types/ai.js +5 -0
- package/dist/types/ai.js.map +1 -0
- package/dist/types/chat.d.ts +46 -0
- package/dist/types/chat.d.ts.map +1 -0
- package/dist/types/chat.js +5 -0
- package/dist/types/chat.js.map +1 -0
- package/dist/types/command.d.ts +25 -0
- package/dist/types/command.d.ts.map +1 -0
- package/dist/types/command.js +5 -0
- package/dist/types/command.js.map +1 -0
- package/dist/types/config.d.ts +59 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/dashboard.d.ts +59 -0
- package/dist/types/dashboard.d.ts.map +1 -0
- package/dist/types/dashboard.js +5 -0
- package/dist/types/dashboard.js.map +1 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/locale.d.ts +21 -0
- package/dist/types/locale.d.ts.map +1 -0
- package/dist/types/locale.js +36 -0
- package/dist/types/locale.js.map +1 -0
- package/dist/types/model.d.ts +69 -0
- package/dist/types/model.d.ts.map +1 -0
- package/dist/types/model.js +5 -0
- package/dist/types/model.js.map +1 -0
- package/dist/types.d.ts +4 -199
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -3
- package/dist/types.js.map +1 -1
- package/package.json +18 -3
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# 生成 Dashboard(数据概览页面)
|
|
2
|
+
|
|
3
|
+
Dashboard 在 `loom.config.ts` 的 `dashboards` 字段中定义,然后通过 CLI 生成页面。
|
|
4
|
+
|
|
5
|
+
## 配置 Dashboard
|
|
6
|
+
|
|
7
|
+
在 `loom.config.ts` 中添加 `dashboards` 字段:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { defineConfig } from '@loom-framework/core';
|
|
11
|
+
|
|
12
|
+
export default defineConfig({
|
|
13
|
+
project: { name: 'my-app' },
|
|
14
|
+
data: { /* ... */ },
|
|
15
|
+
dashboards: [{
|
|
16
|
+
name: 'overview',
|
|
17
|
+
description: { 'zh-CN': '数据概览', 'en-US': 'Overview' },
|
|
18
|
+
models: ['items'],
|
|
19
|
+
layout: [
|
|
20
|
+
{ row: [{ type: 'stat', title: { 'zh-CN': '总数', 'en-US': 'Total' }, model: 'items', aggregate: 'count', span: 6 }] },
|
|
21
|
+
],
|
|
22
|
+
}],
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**设计原则:**
|
|
27
|
+
- 统计卡片放第一行(一眼看到关键数字)
|
|
28
|
+
- 分布图表按业务重要性排列
|
|
29
|
+
- 趋势图放最后一行(需要更多空间)
|
|
30
|
+
- 每行不超过 4 个元素
|
|
31
|
+
- 标题用业务语言,不用字段名
|
|
32
|
+
|
|
33
|
+
### 配置 Schema
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
{
|
|
37
|
+
name: 'overview', // 必填:Dashboard 标识(同模型命名规则)
|
|
38
|
+
description: { 'zh-CN': '数据概览', 'en-US': 'Overview' }, // 可选:支持多语言
|
|
39
|
+
models: ['model_a'], // 必填:关联的数据模型名列表
|
|
40
|
+
layout: [{ // 必填:布局定义,数组每项代表一行
|
|
41
|
+
row: [{ // 每行包含一组 widget
|
|
42
|
+
type: 'stat', // 图表类型,见下方图表类型表
|
|
43
|
+
title: { 'zh-CN': '总数', 'en-US': 'Total' }, // 支持多语言
|
|
44
|
+
model: 'model_a', // 数据模型名
|
|
45
|
+
span: 6, // 可选:Col 宽度(1-24),省略则自动均分
|
|
46
|
+
aggregate: 'count', // 可选:count|sum|avg|min|max|ratio(默认 count)
|
|
47
|
+
field: 'score', // aggregate 为 sum/avg/min/max 时必填:数值字段名
|
|
48
|
+
filter: { status: 'active' }, // 可选:聚合前筛选条件
|
|
49
|
+
groupBy: 'category', // 可选:分组字段(string/enum/date/boolean)
|
|
50
|
+
crossGroupBy: 'grade', // 可选:第二分组字段,用于二维图表
|
|
51
|
+
interval: 'month' // 可选:date 字段分组粒度 day|week|month(默认 month)
|
|
52
|
+
}]
|
|
53
|
+
}]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 字段说明
|
|
58
|
+
|
|
59
|
+
| 字段 | 类型 | 说明 |
|
|
60
|
+
|------|------|------|
|
|
61
|
+
| `aggregate` | `count\|sum\|avg\|min\|max\|ratio` | 聚合方式。`ratio` = 符合 filter 条件的记录数/总记录数,用于 gauge/liquid/stat 百分比 |
|
|
62
|
+
| `field` | string | 聚合目标字段。仅 aggregate 为 sum/avg/min/max 时需要 |
|
|
63
|
+
| `filter` | object | 筛选条件,键值对。如 `{isMastered: true}` 筛选已掌握的记录 |
|
|
64
|
+
| `groupBy` | string | 主分组字段。string/enum 字段按值分组计数;boolean 字段自动映射为"是/否";date 字段按 interval 分段 |
|
|
65
|
+
| `crossGroupBy` | string | 第二分组维度。配合 groupBy 使用,产生交叉分组数据,用于二维图表 |
|
|
66
|
+
| `interval` | `day\|week\|month` | date 字段的分组粒度,仅 groupBy 指向 date 字段时有效 |
|
|
67
|
+
|
|
68
|
+
### Dashboard 级别配置
|
|
69
|
+
|
|
70
|
+
除了 `layout` 中的 widget 配置,Dashboard 还支持以下顶级配置:
|
|
71
|
+
|
|
72
|
+
| 字段 | 类型 | 说明 |
|
|
73
|
+
|------|------|------|
|
|
74
|
+
| `defaultDateField` | string | 默认日期字段名。启用后 Dashboard 顶部显示日期范围选择器,选择日期后筛选条件发送到后端(`__range` filter) |
|
|
75
|
+
| `filterDimensions` | `DashboardFilterDimension[]` | 筛选维度定义。启用后 Dashboard 顶部显示对应的筛选控件,选择的值作为 filter 发送到后端 |
|
|
76
|
+
|
|
77
|
+
#### DashboardFilterDimension
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
{
|
|
81
|
+
field: 'subject', // 必填:筛选字段名
|
|
82
|
+
label: { 'zh-CN': '科目' }, // 必填:显示标签,支持多语言
|
|
83
|
+
type: 'select', // 必填:'select'(下拉选择)| 'dateRange'(日期范围)
|
|
84
|
+
options: ['语文', '数学'], // 可选:select 类型的选项。省略则从数据中自动提取去重值
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**筛选机制:** 日期范围和 select 筛选器变更后只加载符合条件的数据,清除筛选后恢复加载全量数据。
|
|
89
|
+
|
|
90
|
+
**典型配置:**
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
dashboards: [{
|
|
94
|
+
name: 'overview',
|
|
95
|
+
models: ['wrong_questions'],
|
|
96
|
+
defaultDateField: 'createdAt', // 启用日期范围筛选
|
|
97
|
+
filterDimensions: [ // 启用下拉筛选
|
|
98
|
+
{ field: 'subject', label: { 'zh-CN': '科目', 'en-US': 'Subject' }, type: 'select' },
|
|
99
|
+
{ field: 'difficulty', label: { 'zh-CN': '难度', 'en-US': 'Difficulty' }, type: 'select' },
|
|
100
|
+
],
|
|
101
|
+
layout: [/* ... */],
|
|
102
|
+
}]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 图表类型与配置要点
|
|
106
|
+
|
|
107
|
+
#### 数值类 — 展示关键指标
|
|
108
|
+
|
|
109
|
+
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
110
|
+
|------|---------|---------|---------|---------|
|
|
111
|
+
| `stat` | 统计卡片 | — | `{ aggregate: "count" }` 或 `{ aggregate: "avg", field: "score" }` 或 `{ aggregate: "ratio", filter: { passed: true } }` | Ant Design Statistic 数值卡片 |
|
|
112
|
+
| `gauge` | 仪表盘 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: { isMastered: true } }` | G2 仪表盘(百分比进度) |
|
|
113
|
+
| `liquid` | 水波图 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: { isMastered: true } }` | G2 水波图(百分比进度) |
|
|
114
|
+
|
|
115
|
+
> **说明**:gauge 和 liquid 使用 `aggregate: "ratio"` + `filter` 来计算百分比(如掌握率 = 已掌握数/总数),ratio 自动算出 0-1 之间的值。
|
|
116
|
+
|
|
117
|
+
#### 占比类 — 展示分布构成
|
|
118
|
+
|
|
119
|
+
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
120
|
+
|------|---------|---------|---------|---------|
|
|
121
|
+
| `pie` | 饼图 | `groupBy` (enum/string) | `{ groupBy: "subject" }` | G2 饼图(分布占比) |
|
|
122
|
+
| `ring` | 环形图 | `groupBy` (boolean/enum) | `{ groupBy: "difficulty" }` 或 `{ groupBy: "isMastered" }` | G2 环形图(占比对比,boolean 自动映射"是/否") |
|
|
123
|
+
| `treemap` | 矩形树图 | `groupBy` + 可选 `crossGroupBy` | `{ groupBy: "subject" }` 或 `{ groupBy: "subject", crossGroupBy: "difficulty" }` | G2 矩形树图(层级占比,有 crossGroupBy 则两层) |
|
|
124
|
+
|
|
125
|
+
#### 对比类 — 跨类别比较
|
|
126
|
+
|
|
127
|
+
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
128
|
+
|------|---------|---------|---------|---------|
|
|
129
|
+
| `bar` | 条形图 | `groupBy` | `{ groupBy: "errorType" }` | G2 条形图(横向分类对比) |
|
|
130
|
+
| `stacked_bar` | 堆叠条形图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "errorType" }` | G2 堆叠条形图(组成+对比) |
|
|
131
|
+
| `grouped_bar` | 分组条形图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "difficulty" }` | G2 分组条形图(并列对比) |
|
|
132
|
+
| `radar` | 雷达图 | `groupBy` | `{ groupBy: "subject" }` | G2 雷达图(多维度闭合多边形) |
|
|
133
|
+
| `funnel` | 漏斗图 | `groupBy` | `{ groupBy: "errorType" }` | G2 漏斗图(阶段转化,柱条宽度反映数值) |
|
|
134
|
+
|
|
135
|
+
#### 趋势类 — 时间维度变化
|
|
136
|
+
|
|
137
|
+
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
138
|
+
|------|---------|---------|---------|---------|
|
|
139
|
+
| `line` | 折线图 | `groupBy` (date 字段) + `interval` | `{ groupBy: "createdAt", interval: "month" }` | G2 折线图(时间趋势) |
|
|
140
|
+
| `area` | 面积图 | `groupBy` (date 字段) + `interval` | `{ groupBy: "createdAt", interval: "month" }` | G2 面积图(累计趋势) |
|
|
141
|
+
|
|
142
|
+
#### 分布类 — 交叉/密度分析
|
|
143
|
+
|
|
144
|
+
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
145
|
+
|------|---------|---------|---------|---------|
|
|
146
|
+
| `scatter` | 散点图 | `groupBy` | `{ groupBy: "subject" }` | G2 散点图(相关性/分布) |
|
|
147
|
+
| `heatmap` | 热力图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "grade" }` | G2 热力图(密度/交叉分析,颜色深浅表示数量) |
|
|
148
|
+
|
|
149
|
+
## 执行 generate dashboard
|
|
150
|
+
|
|
151
|
+
配置好 `dashboards` 字段后,运行命令生成页面:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
loom generate dashboard <name>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
此命令会:
|
|
158
|
+
1. 从 `loom.config.ts` 的 `dashboards` 字段读取配置
|
|
159
|
+
2. 验证引用的模型是否存在
|
|
160
|
+
3. 生成 Dashboard TSX 页面(含 `useData` + `useChartData` + `DashboardChart`)
|
|
161
|
+
4. 自动接线 App.tsx(添加 import、navItem、switch case)
|
|
162
|
+
5. 检测 `@antv/g2` 是否已安装,未安装则自动安装
|
|
163
|
+
|
|
164
|
+
**前置依赖:** Dashboard 使用 @antv/g2 渲染图表,需在 frontend 目录安装:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
cd frontend && pnpm add @antv/g2
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## 完整配置示例
|
|
171
|
+
|
|
172
|
+
以小学生错题管理平台为例,展示所有 15 种图表的配置:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { defineConfig } from '@loom-framework/core';
|
|
176
|
+
|
|
177
|
+
export default defineConfig({
|
|
178
|
+
project: { name: 'wrong-questions' },
|
|
179
|
+
data: { /* ... */ },
|
|
180
|
+
dashboards: [{
|
|
181
|
+
name: 'overview',
|
|
182
|
+
description: { 'zh-CN': '错题数据概览', 'en-US': 'Overview' },
|
|
183
|
+
models: ['wrong_questions', 'review_plans'],
|
|
184
|
+
defaultDateField: 'createdAt',
|
|
185
|
+
filterDimensions: [
|
|
186
|
+
{ field: 'subject', label: { 'zh-CN': '科目', 'en-US': 'Subject' }, type: 'select' },
|
|
187
|
+
{ field: 'difficulty', label: { 'zh-CN': '难度', 'en-US': 'Difficulty' }, type: 'select' },
|
|
188
|
+
],
|
|
189
|
+
layout: [
|
|
190
|
+
{
|
|
191
|
+
row: [
|
|
192
|
+
{ type: 'stat', title: { 'zh-CN': '错题总数', 'en-US': 'Total Questions' }, model: 'wrong_questions', aggregate: 'count', span: 4 },
|
|
193
|
+
{ type: 'stat', title: { 'zh-CN': '掌握率', 'en-US': 'Mastery Rate' }, model: 'wrong_questions', aggregate: 'ratio', filter: { isMastered: true }, span: 4 },
|
|
194
|
+
{ type: 'gauge', title: { 'zh-CN': '掌握率仪表盘', 'en-US': 'Mastery Gauge' }, model: 'wrong_questions', aggregate: 'ratio', filter: { isMastered: true }, span: 6 },
|
|
195
|
+
{ type: 'liquid', title: { 'zh-CN': '掌握率水波图', 'en-US': 'Mastery Liquid' }, model: 'wrong_questions', aggregate: 'ratio', filter: { isMastered: true }, span: 5 },
|
|
196
|
+
{ type: 'stat', title: { 'zh-CN': '平均复习次数', 'en-US': 'Avg Reviews' }, model: 'wrong_questions', aggregate: 'avg', field: 'reviewCount', span: 5 }
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
row: [
|
|
201
|
+
{ type: 'pie', title: { 'zh-CN': '科目分布', 'en-US': 'By Subject' }, model: 'wrong_questions', groupBy: 'subject', span: 8 },
|
|
202
|
+
{ type: 'ring', title: { 'zh-CN': '难度分布', 'en-US': 'By Difficulty' }, model: 'wrong_questions', groupBy: 'difficulty', span: 8 },
|
|
203
|
+
{ type: 'bar', title: { 'zh-CN': '错误类型分布', 'en-US': 'By Error Type' }, model: 'wrong_questions', groupBy: 'errorType', span: 8 }
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
row: [
|
|
208
|
+
{ type: 'line', title: { 'zh-CN': '错题录入趋势', 'en-US': 'Questions Trend' }, model: 'wrong_questions', groupBy: 'createdAt', interval: 'month', span: 12 },
|
|
209
|
+
{ type: 'area', title: { 'zh-CN': '复习计划趋势', 'en-US': 'Review Plans Trend' }, model: 'review_plans', groupBy: 'createdAt', interval: 'month', span: 12 }
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
row: [
|
|
214
|
+
{ type: 'radar', title: { 'zh-CN': '各科目概览', 'en-US': 'Subject Overview' }, model: 'wrong_questions', groupBy: 'subject', span: 8 },
|
|
215
|
+
{ type: 'stacked_bar', title: { 'zh-CN': '科目×错误类型', 'en-US': 'Subject × Error Type' }, model: 'wrong_questions', groupBy: 'subject', crossGroupBy: 'errorType', span: 8 },
|
|
216
|
+
{ type: 'grouped_bar', title: { 'zh-CN': '科目×难度', 'en-US': 'Subject × Difficulty' }, model: 'wrong_questions', groupBy: 'subject', crossGroupBy: 'difficulty', span: 8 }
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
row: [
|
|
221
|
+
{ type: 'scatter', title: { 'zh-CN': '科目分布散点', 'en-US': 'Subject Scatter' }, model: 'wrong_questions', groupBy: 'subject', span: 8 },
|
|
222
|
+
{ type: 'funnel', title: { 'zh-CN': '错误类型漏斗', 'en-US': 'Error Type Funnel' }, model: 'wrong_questions', groupBy: 'errorType', span: 8 },
|
|
223
|
+
{ type: 'treemap', title: { 'zh-CN': '科目×难度树图', 'en-US': 'Subject × Difficulty Tree' }, model: 'wrong_questions', groupBy: 'subject', crossGroupBy: 'difficulty', span: 8 }
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
row: [
|
|
228
|
+
{ type: 'heatmap', title: { 'zh-CN': '科目×年级热力图', 'en-US': 'Subject × Grade Heatmap' }, model: 'wrong_questions', groupBy: 'subject', crossGroupBy: 'grade', span: 24 }
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
}],
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## 追加自定义图表
|
|
237
|
+
|
|
238
|
+
生成后的 Dashboard 页面是普通 TSX,可直接编辑追加图表:
|
|
239
|
+
|
|
240
|
+
1. 使用 `useChartData` / `useCrossGroupChartData` / `useTreemapChartData` 准备数据
|
|
241
|
+
2. 使用 `/antv-g2-chart` skill 生成 G2 v5 Spec 代码
|
|
242
|
+
3. 添加 `<DashboardChart spec={...} />` 组件
|
|
243
|
+
|
|
244
|
+
示例——追加一个科目×年级的堆叠柱状图:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
// 在已有的 Dashboard 页面中追加
|
|
248
|
+
const subjectGradeData = useCrossGroupChartData(wrongQuestionsList, { groupBy: 'subject', crossGroupBy: 'grade' });
|
|
249
|
+
|
|
250
|
+
<DashboardChart spec={{
|
|
251
|
+
type: 'interval',
|
|
252
|
+
data: subjectGradeData,
|
|
253
|
+
encode: { x: 'group', y: 'value', color: 'name' },
|
|
254
|
+
coordinate: { transform: [{ type: 'transpose' }] },
|
|
255
|
+
transform: [{ type: 'stackY' }],
|
|
256
|
+
}} />
|
|
257
|
+
```
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Data Model Reference
|
|
2
|
+
|
|
3
|
+
Advanced configuration for `loom.config.ts`. Full type definitions from `packages/core/src/types.ts`.
|
|
4
|
+
|
|
5
|
+
## FieldDefinition
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
{
|
|
9
|
+
name: 'status', // ^[a-zA-Z_][a-zA-Z0-9_]*$
|
|
10
|
+
type: 'string', // 'string' | 'number' | 'boolean' | 'date' | 'string[]' | 'number[]' | 'json'
|
|
11
|
+
required: true, // optional, default false
|
|
12
|
+
description: { 'zh-CN': '状态', 'en-US': 'Status' }, // optional: LocaleString, shown in generated forms
|
|
13
|
+
default: 'active', // optional: auto-filled on write if not provided
|
|
14
|
+
enum: ['active', 'inactive', 'archived'], // optional: restrict string field to allowed values (storage values)
|
|
15
|
+
enumLabels: { // optional: display labels per locale for each enum value
|
|
16
|
+
active: { 'zh-CN': '激活', 'en-US': 'Active' },
|
|
17
|
+
inactive: { 'zh-CN': '停用', 'en-US': 'Inactive' },
|
|
18
|
+
archived: { 'zh-CN': '归档', 'en-US': 'Archived' },
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## ModelSchema
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
{
|
|
27
|
+
name: 'orders', // ^[a-zA-Z][a-zA-Z0-9_]*$, will be used as React component name
|
|
28
|
+
description: { 'zh-CN': '订单记录', 'en-US': 'Order Records' }, // optional: LocaleString, shown in page heading
|
|
29
|
+
fields: [...],
|
|
30
|
+
indexes?: [{ fields: ['userId', 'status'], unique: false }],
|
|
31
|
+
adapters?: { // optional: per-model adapter override
|
|
32
|
+
filesystem: { dir: 'orders', format: 'json' | 'yaml', datePattern: 'YYYY-MM' }, // datePattern: date-partitioned sub-directories using the model's first date field
|
|
33
|
+
sqlite: { table: 'orders' },
|
|
34
|
+
},
|
|
35
|
+
crud?: { // optional: control CRUD page features (all default to true when omitted)
|
|
36
|
+
batch: true, // optional: enable batch selection and batch delete
|
|
37
|
+
export: true, // optional: enable CSV export button
|
|
38
|
+
import: true, // optional: enable CSV import button
|
|
39
|
+
deleteWithUndo: true, // optional: delete-with-undo instead of confirm dialog; set false to use confirm dialog
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## AIButtonConfig
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
aiButtons: [{
|
|
48
|
+
id: 'summarize', // required: unique identifier
|
|
49
|
+
label: { 'zh-CN': '总结', 'en-US': 'Summarize' }, // required: LocaleString, button text
|
|
50
|
+
icon: 'FileTextOutlined', // optional: Ant Design icon component name
|
|
51
|
+
prompt: '请总结以下内容', // required: supports {{var}} placeholders, replaced with current row field values
|
|
52
|
+
placement: 'wrong_questions', // optional: limit to specific model pages, comma-separated; omit for all pages
|
|
53
|
+
}]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## AIConfig
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
ai: {
|
|
60
|
+
engine: 'claude-code', // default 'claude-code'
|
|
61
|
+
claudeCode: {
|
|
62
|
+
path: '/usr/local/bin/claude', // optional: custom claude binary path
|
|
63
|
+
pluginRoot: '.claude', // optional: plugin root directory
|
|
64
|
+
timeout: 120000, // optional: command timeout in ms
|
|
65
|
+
skipPermissions: false, // optional: skip permission prompts (default: true in headless mode — Claude Code runs without interactive terminal, so permissions are skipped unless explicitly set to false)
|
|
66
|
+
models: [ // optional: available AI models
|
|
67
|
+
{
|
|
68
|
+
name: 'GLM-5.1', // required: model name, passed to --model flag
|
|
69
|
+
authToken: 'sk-xxx', // optional: ANTHROPIC_AUTH_TOKEN, passed via --settings
|
|
70
|
+
baseUrl: 'https://api.example.com', // optional: ANTHROPIC_BASE_URL, passed via --settings
|
|
71
|
+
isDefault: true, // optional: default model for new chats
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Models can be managed via the Model Management page (System Settings → Model Management) or by editing `loom.config.ts` directly. On `loom init`, the default model is auto-detected from `~/.claude/settings.json` (ANTHROPIC_MODEL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL).
|
|
79
|
+
|
|
80
|
+
## ServerConfig
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
server: {
|
|
84
|
+
port: 3000, // default 3000
|
|
85
|
+
host: '0.0.0.0',
|
|
86
|
+
cors: true, // default true
|
|
87
|
+
staticDir: './dist/frontend',
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## DataConfig
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
data: {
|
|
95
|
+
defaultAdapter: 'filesystem' | 'sqlite',
|
|
96
|
+
models: [...],
|
|
97
|
+
sqlite: { filename: 'loom.db' }, // optional, default 'loom.db'
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## UIConfig
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
ui: {
|
|
105
|
+
theme: { // optional: theme configuration
|
|
106
|
+
defaultMode: 'light', // optional: 'light' | 'dark', default 'light'
|
|
107
|
+
token: { colorPrimary: '#1677ff' }, // optional: Ant Design token overrides
|
|
108
|
+
},
|
|
109
|
+
siderCollapsed: false, // optional: sidebar collapsed by default on desktop
|
|
110
|
+
showHeader: true, // optional: show header bar (breadcrumbs + theme toggle)
|
|
111
|
+
locale: 'zh-CN', // optional: 'zh-CN' | 'en-US', default 'zh-CN'
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## RelationConfig
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
relations: [{
|
|
119
|
+
name: 'question_reviews', // required: unique relation identifier
|
|
120
|
+
label: { 'zh-CN': '复习记录', 'en-US': 'Review Records' }, // optional: LocaleString
|
|
121
|
+
from: 'wrong_questions', // required: source model name
|
|
122
|
+
to: 'review_plans', // required: target model name
|
|
123
|
+
foreignKey: 'questionId', // required: foreign key field in target model
|
|
124
|
+
type: 'hasMany', // required: 'hasOne' | 'hasMany' | 'manyToMany'
|
|
125
|
+
through: 'enrollments', // optional: pivot model for manyToMany
|
|
126
|
+
}]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Relations are displayed in the detail drawer of generated CRUD pages. `hasMany` and `manyToMany` relations show as a nested table.
|
|
130
|
+
|
|
131
|
+
## DashboardConfig
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
dashboards: [{
|
|
135
|
+
name: 'overview', // ^[a-zA-Z][a-zA-Z0-9_]*$, same naming rules as model
|
|
136
|
+
description: { 'zh-CN': '数据概览', 'en-US': 'Overview' }, // optional: LocaleString, shown in sidebar
|
|
137
|
+
models: ['items'], // required: data models included in this dashboard
|
|
138
|
+
defaultDateField: 'createdAt', // optional: default date field for date range filtering across all widgets
|
|
139
|
+
filterDimensions: [ // optional: filter bar dimensions for interactive filtering
|
|
140
|
+
{
|
|
141
|
+
field: 'status', // required: field name to filter on
|
|
142
|
+
label: { 'zh-CN': '状态', 'en-US': 'Status' }, // required: LocaleString
|
|
143
|
+
type: 'select', // required: 'select' | 'dateRange'
|
|
144
|
+
options: ['active', 'inactive'], // optional: for 'select' type, auto-derived from data if omitted
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
field: 'createdAt',
|
|
148
|
+
label: { 'zh-CN': '日期范围', 'en-US': 'Date Range' },
|
|
149
|
+
type: 'dateRange',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
layout: [{ // required: at least one row
|
|
153
|
+
row: [{ // at least one widget per row
|
|
154
|
+
type: 'stat' | 'pie' | 'ring' | 'bar' | 'line' | 'area' | 'scatter' | 'radar' | 'funnel' | 'treemap' | 'gauge' | 'liquid' | 'heatmap' | 'stacked_bar' | 'grouped_bar',
|
|
155
|
+
title: { 'zh-CN': '任务总数', 'en-US': 'Total Tasks' }, // required: LocaleString, display title
|
|
156
|
+
model: 'items', // required: data model name
|
|
157
|
+
span: 6, // optional: Ant Design Grid Col span (1-24), auto-equal-split if omitted
|
|
158
|
+
groupBy: 'status', // optional: group by field for aggregation
|
|
159
|
+
crossGroupBy: 'priority', // optional: second group-by for 2D charts (heatmap, stacked_bar, grouped_bar)
|
|
160
|
+
aggregate: 'count', // optional: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'ratio', default count
|
|
161
|
+
field: 'score', // optional: numeric field for sum/avg/min/max
|
|
162
|
+
filter: { status: 'active' }, // optional: pre-aggregation filter
|
|
163
|
+
interval: 'month', // optional: 'day' | 'week' | 'month' for date groupBy
|
|
164
|
+
dateField: 'createdAt', // optional: per-widget date field override (falls back to dashboard.defaultDateField)
|
|
165
|
+
}],
|
|
166
|
+
}],
|
|
167
|
+
}]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## useSchema Runtime API
|
|
171
|
+
|
|
172
|
+
Generated pages use `useSchema(model)` to fetch model schema and AI buttons at runtime. Schema is auto-resolved by current locale:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const { schema, loading, error } = useSchema('items');
|
|
176
|
+
// schema.fields — field definitions with resolved LocaleString (e.g. description is string, not LocaleString)
|
|
177
|
+
// schema.fields[].enumLabels — resolved to { [enumValue]: displayLabel } for current locale
|
|
178
|
+
// schema.aiButtons — AI buttons filtered by placement, label resolved to current locale
|
|
179
|
+
|
|
180
|
+
// Convert schema enum to antd formats (uses resolved enumLabels):
|
|
181
|
+
filterOptions(schema, 'status') // → [{ text: '激活', value: 'active' }, ...]
|
|
182
|
+
selectOptions(schema, 'status') // → [{ label: '激活', value: 'active' }, ...]
|
|
183
|
+
|
|
184
|
+
// Get display label for a single enum value:
|
|
185
|
+
enumLabel(schema, 'status', 'active') // → '激活'
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## LocaleString
|
|
189
|
+
|
|
190
|
+
All user-facing string fields support `LocaleString` format: `string | Record<string, string>`.
|
|
191
|
+
|
|
192
|
+
- **Simple**: `description: '科目'` — same text for all locales
|
|
193
|
+
- **Multi-locale**: `description: { 'zh-CN': '科目', 'en-US': 'Subject' }` — auto-translated on locale switch
|
|
194
|
+
- **Fallback**: requested locale → `'zh-CN'` → first available value
|
|
195
|
+
|
|
196
|
+
Supported fields: `project.description`, `ModelSchema.description`, `FieldDefinition.description`, `AIButtonConfig.label`, `DashboardConfig.description`, `DashboardWidget.title`, `RelationConfig.label`, `DashboardFilterDimension.label`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseAdapter - Shared logic for DataAdapter implementations
|
|
3
|
+
*
|
|
4
|
+
* Extracts common validation, ID generation, and schema management
|
|
5
|
+
* used by both FileSystemAdapter and SQLiteAdapter.
|
|
6
|
+
*/
|
|
7
|
+
import type { DataAdapter, DataRecord, ModelSchema, LoomConfig } from './types.js';
|
|
8
|
+
export declare abstract class BaseAdapter implements DataAdapter {
|
|
9
|
+
abstract readonly name: string;
|
|
10
|
+
protected schemas: Map<string, ModelSchema>;
|
|
11
|
+
protected config: LoomConfig;
|
|
12
|
+
constructor(config: LoomConfig);
|
|
13
|
+
abstract initialize(): Promise<void>;
|
|
14
|
+
abstract healthCheck(): Promise<boolean>;
|
|
15
|
+
abstract read(model: string, options?: import('./types.js').ReadOptions): Promise<DataRecord | DataRecord[] | null>;
|
|
16
|
+
abstract write(model: string, data: DataRecord): Promise<DataRecord>;
|
|
17
|
+
abstract update(model: string, id: string, data: DataRecord): Promise<DataRecord>;
|
|
18
|
+
abstract delete(model: string, id: string): Promise<void>;
|
|
19
|
+
/** Default count() — delegates to read(), overridden by adapters for efficiency */
|
|
20
|
+
count(model: string, options?: Omit<import('./types.js').ReadOptions, 'limit' | 'offset' | 'sort'>): Promise<number>;
|
|
21
|
+
getSchema(model: string): Promise<ModelSchema | undefined>;
|
|
22
|
+
listModels(): Promise<string[]>;
|
|
23
|
+
protected requireModel(model: string): void;
|
|
24
|
+
protected generateId(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Validate required fields and apply defaults on a record.
|
|
27
|
+
* Returns the validated record with defaults applied.
|
|
28
|
+
*/
|
|
29
|
+
protected validateAndApplyDefaults(model: string, record: DataRecord, skipIdValidation?: boolean): DataRecord;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=adapter-base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-base.d.ts","sourceRoot":"","sources":["../src/adapter-base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnF,8BAAsB,WAAY,YAAW,WAAW;IACtD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAa;IACxD,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEjB,MAAM,EAAE,UAAU;IAO9B,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,YAAY,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC;IACnH,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACpE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACjF,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzD,mFAAmF;IAC7E,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,YAAY,EAAE,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI1D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAMrC,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ3C,SAAS,CAAC,UAAU,IAAI,MAAM;IAM9B;;;OAGG;IACH,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,UAAQ,GAAG,UAAU;CA2B5G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseAdapter - Shared logic for DataAdapter implementations
|
|
3
|
+
*
|
|
4
|
+
* Extracts common validation, ID generation, and schema management
|
|
5
|
+
* used by both FileSystemAdapter and SQLiteAdapter.
|
|
6
|
+
*/
|
|
7
|
+
export class BaseAdapter {
|
|
8
|
+
schemas = new Map();
|
|
9
|
+
config;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
for (const model of config.data.models) {
|
|
13
|
+
this.schemas.set(model.name, model);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Default count() — delegates to read(), overridden by adapters for efficiency */
|
|
17
|
+
async count(model, options) {
|
|
18
|
+
const result = await this.read(model, { filter: options?.filter, id: options?.id });
|
|
19
|
+
if (Array.isArray(result))
|
|
20
|
+
return result.length;
|
|
21
|
+
return result ? 1 : 0;
|
|
22
|
+
}
|
|
23
|
+
async getSchema(model) {
|
|
24
|
+
return this.schemas.get(model);
|
|
25
|
+
}
|
|
26
|
+
async listModels() {
|
|
27
|
+
return Array.from(this.schemas.keys());
|
|
28
|
+
}
|
|
29
|
+
// ── Shared Helpers ──
|
|
30
|
+
requireModel(model) {
|
|
31
|
+
if (!this.schemas.has(model)) {
|
|
32
|
+
throw new Error(`Unknown model: ${model}. Available: ${Array.from(this.schemas.keys()).join(', ')}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
generateId() {
|
|
36
|
+
const timestamp = Date.now().toString(36);
|
|
37
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
38
|
+
return `rec_${timestamp}_${random}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate required fields and apply defaults on a record.
|
|
42
|
+
* Returns the validated record with defaults applied.
|
|
43
|
+
*/
|
|
44
|
+
validateAndApplyDefaults(model, record, skipIdValidation = false) {
|
|
45
|
+
const schema = this.schemas.get(model);
|
|
46
|
+
// Apply default values for missing fields
|
|
47
|
+
for (const field of schema.fields) {
|
|
48
|
+
if (record[field.name] === undefined && field.default !== undefined) {
|
|
49
|
+
record[field.name] = field.default;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Validate required fields
|
|
53
|
+
for (const field of schema.fields) {
|
|
54
|
+
if (skipIdValidation && field.name === 'id')
|
|
55
|
+
continue;
|
|
56
|
+
if (field.required && record[field.name] === undefined) {
|
|
57
|
+
throw new Error(`Missing required field: ${field.name}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Validate enum constraints
|
|
61
|
+
for (const field of schema.fields) {
|
|
62
|
+
if (field.enum && record[field.name] !== undefined && !field.enum.includes(record[field.name])) {
|
|
63
|
+
throw new Error(`Invalid value for field '${field.name}': ${record[field.name]}. Allowed values: ${field.enum.join(', ')}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return record;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=adapter-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-base.js","sourceRoot":"","sources":["../src/adapter-base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,OAAgB,WAAW;IAErB,OAAO,GAA6B,IAAI,GAAG,EAAE,CAAC;IAC9C,MAAM,CAAa;IAE7B,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IASD,mFAAmF;IACnF,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,OAA6E;QACtG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QACpF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC;QAChD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,uBAAuB;IAEb,YAAY,CAAC,KAAa;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,gBAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpF,CAAC;QACJ,CAAC;IACH,CAAC;IAES,UAAU;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3D,OAAO,OAAO,SAAS,IAAI,MAAM,EAAE,CAAC;IACtC,CAAC;IAED;;;OAGG;IACO,wBAAwB,CAAC,KAAa,EAAE,MAAkB,EAAE,gBAAgB,GAAG,KAAK;QAC5F,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;QAExC,0CAA0C;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACpE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;YACrC,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAS;YACtD,IAAI,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC,EAAE,CAAC;gBACzG,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9H,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates the appropriate DataAdapter based on LoomConfig.data.defaultAdapter.
|
|
5
|
+
*/
|
|
6
|
+
import type { LoomConfig, DataAdapter } from './types.js';
|
|
7
|
+
export declare function createAdapter(config: LoomConfig, projectRoot: string): DataAdapter;
|
|
8
|
+
//# sourceMappingURL=adapter-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-factory.d.ts","sourceRoot":"","sources":["../src/adapter-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAgBlF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates the appropriate DataAdapter based on LoomConfig.data.defaultAdapter.
|
|
5
|
+
*/
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { FileSystemAdapter } from './adapter-filesystem.js';
|
|
8
|
+
import { SQLiteAdapter } from './adapter-sqlite.js';
|
|
9
|
+
export function createAdapter(config, projectRoot) {
|
|
10
|
+
const adapterType = config.data.defaultAdapter || 'filesystem';
|
|
11
|
+
switch (adapterType) {
|
|
12
|
+
case 'sqlite':
|
|
13
|
+
return new SQLiteAdapter({
|
|
14
|
+
dbPath: path.join(projectRoot, 'data', config.data.sqlite?.filename ?? 'loom.db'),
|
|
15
|
+
config,
|
|
16
|
+
});
|
|
17
|
+
case 'filesystem':
|
|
18
|
+
default:
|
|
19
|
+
return new FileSystemAdapter({
|
|
20
|
+
dataDir: path.join(projectRoot, 'data'),
|
|
21
|
+
config,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=adapter-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-factory.js","sourceRoot":"","sources":["../src/adapter-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,WAAmB;IACnE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,YAAY,CAAC;IAE/D,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC;gBACvB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,SAAS,CAAC;gBACjF,MAAM;aACP,CAAC,CAAC;QACL,KAAK,YAAY,CAAC;QAClB;YACE,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;gBACvC,MAAM;aACP,CAAC,CAAC;IACP,CAAC;AACH,CAAC"}
|