rust-store-node 3.1.0 → 4.0.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.
- package/README.md +33 -0
- package/index.d.ts +35 -2
- package/index.js +7 -1
- package/package.json +6 -6
- package/rust-store-node.darwin-arm64.node +0 -0
- package/rust-store-node.darwin-x64.node +0 -0
- package/rust-store-node.linux-arm64-gnu.node +0 -0
- package/rust-store-node.linux-x64-gnu.node +0 -0
- package/rust-store-node.win32-x64-msvc.node +0 -0
package/README.md
CHANGED
|
@@ -27,6 +27,39 @@ const plan = reg.planQuery('User{name}', {}, null); // → Mongo 命令 JSON
|
|
|
27
27
|
|
|
28
28
|
同步计算列回调经 `setFn` 注册;异步计算列(`asyncFn`)由 Host 走 `prepareQuery` / `stripQuery` 两段式执行。
|
|
29
29
|
|
|
30
|
+
## 命名规范与翻译摘要
|
|
31
|
+
|
|
32
|
+
归一实现唯一在 `core::naming`,经 `core-node` / `core-py` 透出,宿主不得重复实现。本语言(Node)归一匹配示例:实现 `orderTotal` ↔ 逻辑 `Order.total`。
|
|
33
|
+
|
|
34
|
+
<!-- SPEC:NAMING-STYLE:BEGIN -->
|
|
35
|
+
### Naming: freeform definitions, system-directed translation
|
|
36
|
+
|
|
37
|
+
Definitions (`collection`, fields, referenced relation fields, computed-column keys, `fnRef` values, index names) may use any style; the engine translates them to the target style. Contract keys (`fnRef`, `localField`, `foreignField`, `asyncFn`, `type`, ...) and the schema `name` are never translated.
|
|
38
|
+
|
|
39
|
+
| Target | Style | Example (`orderTotal`) |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| MySQL / PostgreSQL / SQLite (physical) | snake_case | `order_total` |
|
|
42
|
+
| MongoDB (physical) | camelCase | `orderTotal` |
|
|
43
|
+
| Node.js / Java / C# / Rust (code; computed columns follow) | camelCase | `orderTotal` |
|
|
44
|
+
| Go (code; computed columns follow) | PascalCase (must be exported) | `OrderTotal` |
|
|
45
|
+
| Python (code; computed columns follow) | snake_case | `order_total` |
|
|
46
|
+
|
|
47
|
+
Canonicalization (single implementation `core::naming`, re-exported by the bindings; hosts must not re-implement it): split on `_`, `-`, `.`, space and at lower/digit-to-upper boundaries; a trailing uppercase in a run followed by a lowercase starts the next token (`HTTPServer` -> `[http, server]`, `userID` -> `[user, id]`); digits stay inside a token (`order2Items` -> `[order2, items]`). Reassembly: snake = `t1_t2`, camel = `t1T2`, pascal = `T1T2`.
|
|
48
|
+
|
|
49
|
+
Two logical names in one schema that canonicalize equal (`orderTotal` vs `order_total`), or a name that canonicalizes onto a reserved contract key (e.g. `fnref`), is an error `ERR_NAME_CONFLICT:` and the service does not start (never silently overwritten).
|
|
50
|
+
<!-- SPEC:NAMING-STYLE:END -->
|
|
51
|
+
|
|
52
|
+
<!-- SPEC:FNREF:BEGIN -->
|
|
53
|
+
### Computed columns: `fnRef` binding by composite name + canonical match
|
|
54
|
+
|
|
55
|
+
Computed columns live at the schema top level, `computes: { <key>: { type, fn | asyncFn | agg, fnRef?, depends?, read? } }` (`fn` / `asyncFn` / `agg` are mutually exclusive).
|
|
56
|
+
|
|
57
|
+
- The logical `fnRef` defaults to `<schema.name>.<computed-column key>` (generated, never hand-written); since `name` is globally unique, the `fnRef` is globally unique too.
|
|
58
|
+
- Host implementations bind by canonicalization: both the implementation's name in the host language style and the schema's logical `fnRef` are canonicalized to token sequences and compared. So Node's `orderAmountLabel` and Python's `order_amount_label` bind to the same logical computed column.
|
|
59
|
+
- Reusing one implementation across schemas: write an explicit shared name (e.g. `"fnRef": "common.moneyLabel"`); naming goes from required to optional.
|
|
60
|
+
- Every declared `fnRef` must have an implementation, otherwise the service fails to start with `ERR_FN_MISSING`.
|
|
61
|
+
<!-- SPEC:FNREF:END -->
|
|
62
|
+
|
|
30
63
|
## 本地构建(开发)
|
|
31
64
|
|
|
32
65
|
产物在发布期由 `napi build --platform` 生成平台包;开发期可用 cargo 手工构建:
|
package/index.d.ts
CHANGED
|
@@ -9,6 +9,18 @@
|
|
|
9
9
|
* 与 `undefined`(未传上下文,`require_context` 开启时报错)区分。
|
|
10
10
|
*/
|
|
11
11
|
export declare function systemContext(): any
|
|
12
|
+
/** 命名归一(设计 §6.2):用户任意写法 → 全小写 token 序列。 */
|
|
13
|
+
export declare function canonical(s: string): Array<string>
|
|
14
|
+
/** token 序列 → snake_case */
|
|
15
|
+
export declare function toSnake(tokens: Array<string>): string
|
|
16
|
+
/** token 序列 → camelCase */
|
|
17
|
+
export declare function toCamel(tokens: Array<string>): string
|
|
18
|
+
/** token 序列 → PascalCase */
|
|
19
|
+
export declare function toPascal(tokens: Array<string>): string
|
|
20
|
+
/** 逻辑名 → 目标风格物理名;`target` 非法 ⇒ 抛错(禁静默回落)。 */
|
|
21
|
+
export declare function translateName(logical: string, target: string): string
|
|
22
|
+
/** 命名冲突检测(A7):一组逻辑名归一后撞名 / 撞保留键 ⇒ 抛错。 */
|
|
23
|
+
export declare function detectConflicts(names: Array<string>): void
|
|
12
24
|
export declare class Registry {
|
|
13
25
|
/** 逐条后处理文档(默认值 → 同步 fn → 递归下钻 → 权限裁剪),返回 `{doc}` */
|
|
14
26
|
processNode(gql: string, doc: any, ctx?: any | undefined | null): any
|
|
@@ -41,11 +53,11 @@ export declare class Registry {
|
|
|
41
53
|
/** 原生 SQL 语句编译:位置档透传 / 命名档 `:name` 编译 + 读写推断(C4;js 端 `rawStmtCompile`) */
|
|
42
54
|
rawStmtCompile(backend: string, text: string, params: any, isWrite?: boolean | undefined | null): any
|
|
43
55
|
/**
|
|
44
|
-
* 生成联邦计划:按 schema 的 `(
|
|
56
|
+
* 生成联邦计划:按 schema 的 `(source, database, schema)` 与数据源 kind 把一条 GQL
|
|
45
57
|
* 拆成「各源命令序列 + 内存 join 边」;Host 逐源执行命令后调 `mergeFederated`
|
|
46
58
|
*
|
|
47
59
|
* `dsConfig`:`{ "sources": { name: kind } }`(与 `init` 的数据源声明一致;
|
|
48
|
-
* `null` = 单源 Mongo)。SQL 同源跨
|
|
60
|
+
* `null` = 单源 Mongo)。SQL 同源跨 database/schema 仍下推(qualified JOIN),
|
|
49
61
|
* Mongo 跨 db 剥离为内存 join。
|
|
50
62
|
*
|
|
51
63
|
* 返回 `{v, kind:"federated", root, sources, join, postprocess, degraded, maxRowsPerSource}`;
|
|
@@ -54,6 +66,15 @@ export declare class Registry {
|
|
|
54
66
|
planFederated(gql: string, params: any, ctx?: any | undefined | null, dsConfig?: any | undefined | null): any
|
|
55
67
|
/** 合并各源结果 → 嵌套文档数组;`results` 必须与 `plan.sources` **同序同长** */
|
|
56
68
|
mergeFederated(plan: any, results: Array<any>): any
|
|
69
|
+
/**
|
|
70
|
+
* 目录语义纯规划:`store.config.json` + 目录扫描结果 → 定位后的装载项。
|
|
71
|
+
*
|
|
72
|
+
* `config` = `{sources, defs}`;`files` = `[{rel, defn}]`(`rel` = 相对 defs-root 的路径)。
|
|
73
|
+
* 返回 `[{defn, location:{source,database,schema}}]`(主在前、其后从;组间按 name 字典序)。
|
|
74
|
+
*/
|
|
75
|
+
planLoad(config: any, files: any): any
|
|
76
|
+
/** 带定位批量注册(D13 批次唯一);`items` = `[{defn, location}]`,`ctx` 缺省 = 无上下文。 */
|
|
77
|
+
registerBatch(items: any, ctx?: any | undefined | null): void
|
|
57
78
|
canRead(model: string, ctx?: any | undefined | null): boolean
|
|
58
79
|
canWrite(model: string, ctx?: any | undefined | null): boolean
|
|
59
80
|
shouldInjectOwner(model: string, ctx?: any | undefined | null): boolean
|
|
@@ -176,4 +197,16 @@ export declare class Registry {
|
|
|
176
197
|
setDenyWriteRoles(roles: Array<string>): void
|
|
177
198
|
/** 未配置姿态("open" / "closed");未知值抛错(fail-fast,对齐 setRbac) */
|
|
178
199
|
setUnconfiguredPolicy(policy: string): void
|
|
200
|
+
/**
|
|
201
|
+
* 定义层门禁策略(`closed=true` 时仅 internal 或 `roles` 白名单可注册/覆盖)。
|
|
202
|
+
* 判决唯一在 core;默认 Open(全放行,保持既有 parity)。
|
|
203
|
+
*/
|
|
204
|
+
setMetaPolicy(closed: boolean, roles: Array<string>): void
|
|
205
|
+
/**
|
|
206
|
+
* 带 ctx 的 schema 注册:定义层门禁按当前 metaPolicy 判决;`ctx` 缺省 = 无上下文。
|
|
207
|
+
* 拒绝抛 `ERR_PERMISSION:` 前缀错误(定义不变)。
|
|
208
|
+
*/
|
|
209
|
+
registerWithCtx(defn: any, ctx?: any | undefined | null): void
|
|
210
|
+
/** 只读定义层判决(`workflow` 宿主面复用;判决唯一在 core)。`ctx` 缺省 = 无上下文。 */
|
|
211
|
+
canRegister(ctx?: any | undefined | null): boolean
|
|
179
212
|
}
|
package/index.js
CHANGED
|
@@ -310,7 +310,13 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { Registry, systemContext } = nativeBinding
|
|
313
|
+
const { Registry, systemContext, canonical, toSnake, toCamel, toPascal, translateName, detectConflicts } = nativeBinding
|
|
314
314
|
|
|
315
315
|
module.exports.Registry = Registry
|
|
316
316
|
module.exports.systemContext = systemContext
|
|
317
|
+
module.exports.canonical = canonical
|
|
318
|
+
module.exports.toSnake = toSnake
|
|
319
|
+
module.exports.toCamel = toCamel
|
|
320
|
+
module.exports.toPascal = toPascal
|
|
321
|
+
module.exports.translateName = translateName
|
|
322
|
+
module.exports.detectConflicts = detectConflicts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rust-store-node",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Node.js binding (napi-rs) for the rust-store multi-backend data engine: GQL parsing, permissions, computed columns and SQL dialect translation for MongoDB, MySQL, SQLite and PostgreSQL",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
"sql.js": "^1.8.0"
|
|
69
69
|
},
|
|
70
70
|
"optionalDependencies": {
|
|
71
|
-
"rust-store-node-win32-x64-msvc": "
|
|
72
|
-
"rust-store-node-linux-x64-gnu": "
|
|
73
|
-
"rust-store-node-linux-arm64-gnu": "
|
|
74
|
-
"rust-store-node-darwin-x64": "
|
|
75
|
-
"rust-store-node-darwin-arm64": "
|
|
71
|
+
"rust-store-node-win32-x64-msvc": "4.0.0",
|
|
72
|
+
"rust-store-node-linux-x64-gnu": "4.0.0",
|
|
73
|
+
"rust-store-node-linux-arm64-gnu": "4.0.0",
|
|
74
|
+
"rust-store-node-darwin-x64": "4.0.0",
|
|
75
|
+
"rust-store-node-darwin-arm64": "4.0.0"
|
|
76
76
|
}
|
|
77
77
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|