@cubejs-backend/native 0.30.42 → 0.30.43

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.30.43](https://github.com/cube-js/cube.js/compare/v0.30.42...v0.30.43) (2022-07-28)
7
+
8
+
9
+ ### Features
10
+
11
+ * **cubesql:** Security Context switching (Row Access) ([731e1ab](https://github.com/cube-js/cube.js/commit/731e1ab6d9362fb9a1857f5276e22a565f79781c))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.30.42](https://github.com/cube-js/cube.js/compare/v0.30.41...v0.30.42) (2022-07-27)
7
18
 
8
19
  **Note:** Version bump only for package @cubejs-backend/native
@@ -1,26 +1,41 @@
1
- export interface Request {
1
+ export interface BaseMeta {
2
+ protocol: string;
3
+ apiType: string;
4
+ appName?: string;
5
+ }
6
+ export interface LoadRequestMeta extends BaseMeta {
7
+ changeUser?: string;
8
+ }
9
+ export interface Request<Meta> {
2
10
  id: string;
3
- meta: any;
11
+ meta: Meta;
12
+ }
13
+ export interface CheckAuthResponse {
14
+ password: string | null;
15
+ superuser: boolean;
4
16
  }
5
17
  export interface CheckAuthPayload {
6
- request: Request;
18
+ request: Request<undefined>;
7
19
  user: string | null;
8
20
  }
21
+ export interface SessionContext {
22
+ user: string | null;
23
+ superuser: boolean;
24
+ }
9
25
  export interface LoadPayload {
10
- request: Request;
11
- user: string;
26
+ request: Request<LoadRequestMeta>;
27
+ session: SessionContext;
12
28
  query: any;
13
- meta?: Map<string, string>;
14
29
  }
15
30
  export interface MetaPayload {
16
- request: Request;
17
- user: string | null;
31
+ request: Request<undefined>;
32
+ session: SessionContext;
18
33
  }
19
34
  export declare type SQLInterfaceOptions = {
20
35
  port?: number;
21
36
  pgPort?: number;
22
37
  nonce?: string;
23
- checkAuth: (payload: CheckAuthPayload) => unknown | Promise<unknown>;
38
+ checkAuth: (payload: CheckAuthPayload) => CheckAuthResponse | Promise<CheckAuthResponse>;
24
39
  load: (payload: LoadPayload) => unknown | Promise<unknown>;
25
40
  meta: (payload: MetaPayload) => unknown | Promise<unknown>;
26
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../js/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAC,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,GAAG,CAAC;IACX,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAC,IAAI,CAAA;CACpB;AAED,oBAAY,mBAAmB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D,CAAC;AAiBF,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAkCD,aAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,eAAO,MAAM,WAAW,mBAAoB,GAAG,KAAK,OAAO,YAAY,QAAQ,KAAG,IAGjF,CAAA;AAED,oBAAY,oBAAoB,GAAG;IAAE,UAAU,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,iBAAiB,YAAmB,mBAAmB,KAAG,QAAQ,oBAAoB,CAwBlG,CAAC;AAEF,eAAO,MAAM,iBAAiB,aAAoB,oBAAoB,KAAG,QAAQ,IAAI,CAMpF,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../js/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IAErB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAE7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,OAAO,CAAC,IAAI;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAC,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;CAC3B;AAED,oBAAY,mBAAmB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzF,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D,CAAC;AAiBF,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAkCD,aAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,eAAO,MAAM,WAAW,mBAAoB,GAAG,KAAK,OAAO,YAAY,QAAQ,KAAG,IAGjF,CAAA;AAED,oBAAY,oBAAoB,GAAG;IAAE,UAAU,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,iBAAiB,YAAmB,mBAAmB,KAAG,QAAQ,oBAAoB,CAwBlG,CAAC;AAEF,eAAO,MAAM,iBAAiB,aAAoB,oBAAoB,KAAG,QAAQ,IAAI,CAMpF,CAAA"}
package/dist/js/index.js CHANGED
@@ -21,7 +21,6 @@ function isSupported() {
21
21
  }
22
22
  exports.isSupported = isSupported;
23
23
  function wrapNativeFunctionWithChannelCallback(fn) {
24
- const native = loadNative();
25
24
  return async (extra, channel) => {
26
25
  try {
27
26
  const result = await fn(JSON.parse(extra));
@@ -38,11 +37,13 @@ function wrapNativeFunctionWithChannelCallback(fn) {
38
37
  }
39
38
  }
40
39
  catch (e) {
40
+ if (process.env.CUBEJS_NATIVE_INTERNAL_DEBUG) {
41
+ console.debug("[js] channel.reject", {
42
+ e
43
+ });
44
+ }
41
45
  channel.reject(e.message || 'Unknown JS exception');
42
46
  // throw e;
43
- console.debug("[js] channel.reject", {
44
- e
45
- });
46
47
  }
47
48
  };
48
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../js/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../js/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubejs-backend/native",
3
- "version": "0.30.42",
3
+ "version": "0.30.43",
4
4
  "author": "Cube Dev, Inc.",
5
5
  "description": "Native module for Cube.js (binding to Rust codebase)",
6
6
  "main": "dist/js/index.js",
@@ -18,6 +18,7 @@
18
18
  "install": "node-pre-gyp install || echo 'Your system is not supported by @cubejs-backend/native, some feature will be unavailable.'",
19
19
  "upload-binary-cross": "mkdir -p native && cp index.node native/index.node && node-pre-gyp package --target_arch=$PACKAGE_TARGET_ARCH --target_platform=$PACKAGE_TARGET_PLATFORM --target_libc=$PACKAGE_TARGET_LIBC && node-pre-gyp-github publish",
20
20
  "upload-binary": "mkdir -p native && cp index.node native/index.node && node-pre-gyp package && node-pre-gyp-github publish",
21
+ "test:server": "CUBEJS_NATIVE_INTERNAL_DEBUG=true CUBESQL_LOG_LEVEL=trace CUBESQL_PG_PORT=5555 node test/server.js",
21
22
  "test:unit": "jest --forceExit test",
22
23
  "test:cargo": "cargo test"
23
24
  },
@@ -37,7 +38,7 @@
37
38
  "typescript": "~4.1.5"
38
39
  },
39
40
  "dependencies": {
40
- "@cubejs-backend/cubesql": "^0.30.42",
41
+ "@cubejs-backend/cubesql": "^0.30.43",
41
42
  "@mapbox/node-pre-gyp": "^1"
42
43
  },
43
44
  "binary": {
@@ -60,5 +61,5 @@
60
61
  "publishConfig": {
61
62
  "access": "public"
62
63
  },
63
- "gitHead": "7500c4565a250aefa3b15b31096118952e7a9ff0"
64
+ "gitHead": "52877ac0ea70657a49f155b5b68bee53ef779bd5"
64
65
  }