@nocobase/plugin-data-source-manager 2.2.0-alpha.7 → 2.2.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/skills/data-metadata/SKILLS.md +6 -0
- package/dist/ai/skills/data-query/SKILLS.md +54 -17
- package/dist/ai/skills/data-query/tools/dataSourceQuery.js +1 -1
- package/dist/externalVersion.js +12 -12
- package/dist/locale/en-US.json +2 -2
- package/dist/locale/zh-CN.json +2 -2
- package/dist/node_modules/zod/package.json +1 -1
- package/package.json +2 -2
|
@@ -16,6 +16,12 @@ You are a professional data model metadata assistant for NocoBase.
|
|
|
16
16
|
|
|
17
17
|
You help users explore and understand existing database schemas, including collection definitions, field metadata, and relationships.
|
|
18
18
|
|
|
19
|
+
# Mandatory Collection Resolution Gate
|
|
20
|
+
|
|
21
|
+
When the user's request names a collection, table, dataset, or business object, first compare it with collection names and titles from `getCollectionNames`.
|
|
22
|
+
|
|
23
|
+
If there is no exact match, stop and ask the user to confirm a candidate. Until confirmed, do not call `getCollectionMetadata` for candidate collections and do not use field compatibility, naming prefixes, or `searchFieldMetadata` suggested results to justify a collection choice.
|
|
24
|
+
|
|
19
25
|
# Primary Workflows
|
|
20
26
|
|
|
21
27
|
This skill focuses on reading and exploring existing data models, not creating or modifying them.
|
|
@@ -14,6 +14,37 @@ You are a professional data query assistant for NocoBase.
|
|
|
14
14
|
|
|
15
15
|
You help users inspect schemas, retrieve records, and run aggregate queries on NocoBase collections.
|
|
16
16
|
|
|
17
|
+
# Mandatory Query Safety Gates
|
|
18
|
+
|
|
19
|
+
These gates have higher priority than every workflow, example, heuristic, and tool description in this skill.
|
|
20
|
+
|
|
21
|
+
They apply before any call to `dataQuery`, `dataSourceQuery`, `dataSourceCounting`, or any chart/report tool that depends on queried data.
|
|
22
|
+
|
|
23
|
+
## Collection Resolution
|
|
24
|
+
|
|
25
|
+
Confirmed means exactly one of:
|
|
26
|
+
|
|
27
|
+
- exact match to a user-provided collection `name` from `getCollectionNames`
|
|
28
|
+
- exact match to a user-provided collection `title` from `getCollectionNames`
|
|
29
|
+
- explicit user confirmation after you list candidate collections
|
|
30
|
+
- direct user-provided internal collection name that was verified by `getCollectionNames`
|
|
31
|
+
|
|
32
|
+
Exact match may ignore case and may normalize spaces, underscores, and hyphens for comparison only. It must not use partial words, shared prefixes, synonyms, translated meanings, relation names, field compatibility, or business plausibility.
|
|
33
|
+
|
|
34
|
+
If the user's collection label has no exact match, this is a hard stop. You must ask the user to confirm the intended collection before any data query, aggregation, raw record query, counting query, chart generation, or narrative answer based on data. Do not continue even if one candidate has all required fields.
|
|
35
|
+
|
|
36
|
+
`searchFieldMetadata` results with `kind="suggested_results"` are unconfirmed candidates only. They never confirm `collectionName`.
|
|
37
|
+
|
|
38
|
+
## Fresh Data
|
|
39
|
+
|
|
40
|
+
Database query results are only valid for answering the current user message that triggered the tool call. The underlying database may change between user messages.
|
|
41
|
+
|
|
42
|
+
For every new user message that asks for records, counts, summaries, statistics, rankings, trends, charts, reports, or any answer based on current database content, you must call `dataQuery`, `dataSourceQuery`, or `dataSourceCounting` again before answering.
|
|
43
|
+
|
|
44
|
+
Do not answer a new user message from historical tool results, previous assistant messages, cached query outputs, or earlier conversation context. Historical results may only help you understand what was asked before; they must not be treated as current data.
|
|
45
|
+
|
|
46
|
+
Within one assistant response, you may use the query results you just obtained for that same user message.
|
|
47
|
+
|
|
17
48
|
# Primary Workflows
|
|
18
49
|
|
|
19
50
|
This skill focuses on safe read-only data access.
|
|
@@ -33,6 +64,8 @@ When the user does not provide an exact collection or field name, or when this i
|
|
|
33
64
|
9. Only then run a data tool.
|
|
34
65
|
10. Even if the user already mentions a collection name such as `date_boundary_cases` or a common field such as `createdAt`, verify them with the loaded `data-metadata` workflow before the first real query when the collection has not yet been confirmed in the current conversation.
|
|
35
66
|
|
|
67
|
+
The Mandatory Query Safety Gates above must be satisfied before any data tool call.
|
|
68
|
+
|
|
36
69
|
Do not guess collection names, measure aliases, or dotted relation paths.
|
|
37
70
|
|
|
38
71
|
## Raw Record Query
|
|
@@ -94,26 +127,29 @@ Use `dataSourceCounting` only for a simple total when grouped output is unnecess
|
|
|
94
127
|
4. For metrics, put aggregate definitions in `measures`.
|
|
95
128
|
5. Use aliases when the user clearly needs stable output keys.
|
|
96
129
|
6. For dotted relation fields, prefer the exact field path confirmed from metadata, such as `createdBy.nickname`.
|
|
97
|
-
7.
|
|
98
|
-
8.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
11.
|
|
130
|
+
7. For `dataSourceQuery`, `fields` controls which values are returned. `appends` only loads relation data and does not select returned fields by itself.
|
|
131
|
+
8. When returning relation field values, put the dotted relation paths in `fields` and the root relation names in `appends`; for example, use `fields: ["plain_field", "relation_field.display_field"]` with `appends: ["relation_field"]`.
|
|
132
|
+
9. Do not put only root relation names in `appends` when the user asks for relation attributes. Without the dotted paths in `fields`, those relation attributes will not be returned.
|
|
133
|
+
10. Default row limit is 50 and the tool caps the limit at 100.
|
|
134
|
+
11. Always follow the same frontend date filter contract used by NocoBase filters.
|
|
135
|
+
11.1. `filter` and `having` must be structured objects, not JSON-encoded strings.
|
|
136
|
+
12. Supported date operators are exactly `$dateOn`, `$dateNotOn`, `$dateBefore`, `$dateAfter`, `$dateNotBefore`, `$dateNotAfter`, `$dateBetween`, `$empty`, and `$notEmpty`.
|
|
137
|
+
13. For calendar-style date filtering, do not generate `$gte`, `$gt`, `$lte`, `$lt`, or custom operator names.
|
|
138
|
+
14. Allowed value shapes are:
|
|
103
139
|
- for `$dateOn`, `$dateNotOn`, `$dateBefore`, `$dateAfter`, `$dateNotBefore`, `$dateNotAfter`: `YYYY-MM-DD`, `YYYY-MM`, `YYYY`, a relative period object, or an exact datetime string only when the user explicitly wants timestamp comparison
|
|
104
140
|
- for `$dateBetween`: `["YYYY-MM-DD", "YYYY-MM-DD"]` or a relative period object
|
|
105
141
|
- for `$empty` and `$notEmpty`: no value
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
142
|
+
15. Relative period objects must use exactly these `type` values: `today`, `yesterday`, `tomorrow`, `thisWeek`, `lastWeek`, `nextWeek`, `thisMonth`, `lastMonth`, `nextMonth`, `thisQuarter`, `lastQuarter`, `nextQuarter`, `thisYear`, `lastYear`, `nextYear`, `past`, `next`.
|
|
143
|
+
16. If `type` is `past` or `next`, the object must also include `number` as a positive integer and `unit` as one of `day`, `week`, `month`, `quarter`, `year`.
|
|
144
|
+
17. For day, week, month, quarter, year, and common relative-period queries, prefer frontend date filters such as `{ createdAt: { $dateOn: "2026-04" } }`, `{ createdAt: { $dateOn: { type: "thisMonth" } } }`, or `{ createdAt: { $dateBetween: ["2026-04-01", "2026-04-30"] } }`.
|
|
145
|
+
18. Do not expand calendar queries into UTC boundary expressions such as `createdAt >= 2026-04-01T00:00:00.000Z` and `< 2026-05-01T00:00:00.000Z`.
|
|
146
|
+
19. For fields such as `createdAt` and `updatedAt`, still prefer the frontend date operators above for calendar queries instead of UTC boundary expansion.
|
|
147
|
+
20. Only inspect field type when the user explicitly asks for an exact timestamp comparison rather than a calendar period.
|
|
148
|
+
21. If an exact timestamp comparison is required, keep the operator frontend-compatible and choose the value format that matches the field semantics:
|
|
113
149
|
- timezone-aware datetime fields: ISO 8601 timestamp strings such as `2026-04-10T12:00:00.000Z`
|
|
114
150
|
- `datetimeNoTz` fields: timezone-free local datetime strings such as `2026-04-10 12:00:00`
|
|
115
151
|
- `dateOnly` fields: date-only strings without time components
|
|
116
|
-
|
|
152
|
+
22. Do not provide a timezone parameter yourself. The runtime request timezone is already supplied by the system.
|
|
117
153
|
|
|
118
154
|
# Available Tools
|
|
119
155
|
|
|
@@ -231,9 +267,10 @@ Action: Call dataSourceCounting with collectionName="users", filter={ status: {
|
|
|
231
267
|
User: "Show monthly revenue by salesperson"
|
|
232
268
|
Action:
|
|
233
269
|
1. Call getSkill with skillName="data-metadata".
|
|
234
|
-
2. Call getCollectionNames /
|
|
235
|
-
3.
|
|
236
|
-
4. Call
|
|
270
|
+
2. Call getCollectionNames to resolve the collection by exact name/title match. If there is no exact match, ask the user to confirm a candidate before continuing.
|
|
271
|
+
3. Use searchFieldMetadata only to find candidate fields or candidate collections; suggested_results do not confirm a collection.
|
|
272
|
+
4. Call getCollectionMetadata if date or relation paths are unclear.
|
|
273
|
+
5. Call dataQuery with the confirmed collection and fields.
|
|
237
274
|
```
|
|
238
275
|
|
|
239
276
|
# Notes
|
|
@@ -52,7 +52,7 @@ var dataSourceQuery_default = (0, import_ai.defineTools)({
|
|
|
52
52
|
},
|
|
53
53
|
definition: {
|
|
54
54
|
name: "dataSourceQuery",
|
|
55
|
-
description:
|
|
55
|
+
description: 'Use dataSource, collectionName, and collection fields to query data from the database. The filter argument must be a structured object, not a JSON string. To return relation attributes, include dotted relation paths in fields and root relation names in appends, such as fields: ["relation_field.display_field"] with appends: ["relation_field"].',
|
|
56
56
|
schema: import_common.ArgSchema
|
|
57
57
|
},
|
|
58
58
|
invoke: async (ctx, args) => {
|
package/dist/externalVersion.js
CHANGED
|
@@ -8,18 +8,18 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
|
-
"@nocobase/client": "2.2.0-alpha.
|
|
11
|
+
"@nocobase/client": "2.2.0-alpha.8",
|
|
12
12
|
"react": "18.2.0",
|
|
13
|
-
"@nocobase/plugin-acl": "2.2.0-alpha.
|
|
14
|
-
"@nocobase/utils": "2.2.0-alpha.
|
|
15
|
-
"@nocobase/flow-engine": "2.2.0-alpha.
|
|
16
|
-
"@nocobase/client-v2": "2.2.0-alpha.
|
|
17
|
-
"@nocobase/ai": "2.2.0-alpha.
|
|
18
|
-
"@nocobase/server": "2.2.0-alpha.
|
|
19
|
-
"@nocobase/data-source-manager": "2.2.0-alpha.
|
|
13
|
+
"@nocobase/plugin-acl": "2.2.0-alpha.8",
|
|
14
|
+
"@nocobase/utils": "2.2.0-alpha.8",
|
|
15
|
+
"@nocobase/flow-engine": "2.2.0-alpha.8",
|
|
16
|
+
"@nocobase/client-v2": "2.2.0-alpha.8",
|
|
17
|
+
"@nocobase/ai": "2.2.0-alpha.8",
|
|
18
|
+
"@nocobase/server": "2.2.0-alpha.8",
|
|
19
|
+
"@nocobase/data-source-manager": "2.2.0-alpha.8",
|
|
20
20
|
"lodash": "4.18.1",
|
|
21
|
-
"@nocobase/acl": "2.2.0-alpha.
|
|
22
|
-
"@nocobase/database": "2.2.0-alpha.
|
|
21
|
+
"@nocobase/acl": "2.2.0-alpha.8",
|
|
22
|
+
"@nocobase/database": "2.2.0-alpha.8",
|
|
23
23
|
"@ant-design/icons": "5.6.1",
|
|
24
24
|
"antd": "5.24.2",
|
|
25
25
|
"react-router-dom": "6.30.1",
|
|
@@ -28,9 +28,9 @@ module.exports = {
|
|
|
28
28
|
"react-i18next": "11.18.6",
|
|
29
29
|
"@emotion/css": "11.13.0",
|
|
30
30
|
"ahooks": "3.7.8",
|
|
31
|
-
"@nocobase/actions": "2.2.0-alpha.
|
|
31
|
+
"@nocobase/actions": "2.2.0-alpha.8",
|
|
32
32
|
"sequelize": "6.35.2",
|
|
33
|
-
"@nocobase/test": "2.2.0-alpha.
|
|
33
|
+
"@nocobase/test": "2.2.0-alpha.8",
|
|
34
34
|
"@formily/antd-v5": "1.2.3",
|
|
35
35
|
"@formily/core": "2.3.7",
|
|
36
36
|
"@formily/reactive": "2.3.7",
|
package/dist/locale/en-US.json
CHANGED
|
@@ -329,8 +329,8 @@
|
|
|
329
329
|
"ai.tools.dataSourceCounting.about": "Use dataSource, collectionName, and collection fields to query data from the database, get total count of records",
|
|
330
330
|
"ai.tools.dataQuery.args.datasource": "Data source key",
|
|
331
331
|
"ai.tools.dataQuery.args.collectionName": "Collection name",
|
|
332
|
-
"ai.tools.dataQuery.args.fields": "Fields to be
|
|
333
|
-
"ai.tools.dataQuery.args.appends": "
|
|
332
|
+
"ai.tools.dataQuery.args.fields": "Fields to be returned. To return relation attributes, include dotted relation paths here, such as relation_field.display_field.",
|
|
333
|
+
"ai.tools.dataQuery.args.appends": "Relation fields to load. This only loads associations and does not select returned fields by itself. For relation attributes, also include dotted paths in fields; for example, use appends: [\"relation_field\"] with fields: [\"relation_field.display_field\"].",
|
|
334
334
|
"ai.tools.dataQuery.args.sort": "Sort field names. By default, they are in ascending order. A minus sign before the field name indicates descending order",
|
|
335
335
|
"ai.tools.dataQuery.args.offset": "Offset of records to be queried",
|
|
336
336
|
"ai.tools.dataQuery.args.limit": "Maximum number of records to be queried",
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -329,8 +329,8 @@
|
|
|
329
329
|
"ai.tools.dataSourceCounting.about": "使用 dataSource、collectionName 和 collection fields 从数据库中获取记录总数",
|
|
330
330
|
"ai.tools.dataQuery.args.datasource": "数据源标识",
|
|
331
331
|
"ai.tools.dataQuery.args.collectionName": "数据表名称",
|
|
332
|
-
"ai.tools.dataQuery.args.fields": "
|
|
333
|
-
"ai.tools.dataQuery.args.appends": "
|
|
332
|
+
"ai.tools.dataQuery.args.fields": "需要返回的字段。返回关联字段属性时,必须在这里填写点路径,例如 relation_field.display_field。",
|
|
333
|
+
"ai.tools.dataQuery.args.appends": "需要加载的关联字段。这里只负责加载关联数据,不会自动选择返回字段。返回关联字段属性时,还必须在 fields 中填写点路径;例如 appends: [\"relation_field\"] 要配合 fields: [\"relation_field.display_field\"]。",
|
|
334
334
|
"ai.tools.dataQuery.args.sort": "排序字段名称,默认升序。字段名前加减号表示降序",
|
|
335
335
|
"ai.tools.dataQuery.args.offset": "查询记录的偏移量",
|
|
336
336
|
"ai.tools.dataQuery.args.limit": "查询记录的最大数量",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-07-
|
|
1
|
+
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-07-12T22:52:47.488Z"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-data-source-manager",
|
|
3
|
-
"version": "2.2.0-alpha.
|
|
3
|
+
"version": "2.2.0-alpha.8",
|
|
4
4
|
"main": "dist/server/index.js",
|
|
5
5
|
"displayName": "Data source manager",
|
|
6
6
|
"displayName.ru-RU": "Менеджер управления источниками данных",
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"keywords": [
|
|
23
23
|
"Data model tools"
|
|
24
24
|
],
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "810c81e5963966bda7ec03b6453a3a80fe60e027",
|
|
26
26
|
"license": "Apache-2.0"
|
|
27
27
|
}
|