@itwin/core-common 5.12.0-dev.8 → 5.13.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module IpcSocket
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.serializeIpcError = serializeIpcError;
11
+ exports.rebuildIpcError = rebuildIpcError;
12
+ const core_bentley_1 = require("@itwin/core-bentley");
13
+ /**
14
+ * Serialize a value thrown by an Ipc handler into the [[IpcInvokeReturn]] `error` envelope so it can be
15
+ * transmitted across an Ipc socket via structured clone or JSON, depending on the transport.
16
+ *
17
+ * Hardens against values that can't be cloned: copies `Error`'s non-enumerable `message`/`stack`/`cause`,
18
+ * preserves `BentleyError` identity (`iTwinErrorId` and logging metadata, normalized to a JSON-safe form),
19
+ * recurses into nested `Error`s and plain objects, strips functions and class instances, and guards against cycles.
20
+ * @param err The thrown value to serialize.
21
+ * @param includeStack Whether to include `Error.stack` in the serialized output.
22
+ * @returns An [[IpcInvokeReturn]] holding the serialized `error`.
23
+ * @internal
24
+ */
25
+ function serializeIpcError(err, includeStack) {
26
+ if (!core_bentley_1.JsonUtils.isObject(err))
27
+ return { error: err };
28
+ const serialize = (e, visited = new WeakSet()) => {
29
+ if (visited.has(e))
30
+ return undefined;
31
+ visited.add(e);
32
+ try {
33
+ const serialized = { ...e };
34
+ for (const sym of Object.getOwnPropertySymbols(serialized))
35
+ delete serialized[sym]; // symbol-keyed properties cannot be structured-cloned
36
+ // `iTwinErrorId`/`loggingMetadata` are prototype getters, so `Object.keys`/spread never pick them up; resolve
37
+ // them explicitly. Shared by the top-level and metadata-nested paths below so they can't drift apart again.
38
+ const applyBentleyErrorIdentity = (be, out, sanitize) => {
39
+ out.iTwinErrorId = be.iTwinErrorId;
40
+ if (be.hasMetaData)
41
+ out.loggingMetadata = sanitize(be.loggingMetadata);
42
+ delete out._metaData;
43
+ };
44
+ if (e instanceof Error) {
45
+ serialized.message = e.message; // NB: .message and .stack are non-enumerable on Error instances
46
+ if (includeStack)
47
+ serialized.stack = e.stack;
48
+ // Error.cause is typically non-enumerable and must be copied explicitly.
49
+ if (Object.prototype.hasOwnProperty.call(e, "cause"))
50
+ serialized.cause = e.cause;
51
+ }
52
+ if (e instanceof core_bentley_1.BentleyError)
53
+ applyBentleyErrorIdentity(e, serialized, (v) => v); // loggingMetadata is sanitized once, below
54
+ // Only recurse into Error instances and plain objects — not class instances like Date or Buffer.
55
+ const shouldRecurse = (val) => val instanceof Error || (core_bentley_1.JsonUtils.isObject(val) && Object.getPrototypeOf(val) === Object.prototype);
56
+ const isSerializableLeaf = (val) => {
57
+ const t = typeof val;
58
+ return val === null || val === undefined || val instanceof Date
59
+ || t === "string" || t === "number" || t === "boolean";
60
+ };
61
+ // Recurse into arrays, Errors, and plain objects; strip anything else non-cloneable (functions, RegExp,
62
+ // Map, Set, typed arrays, other class instances) to `undefined`.
63
+ const serializeValue = (val) => {
64
+ if (Array.isArray(val)) {
65
+ // Arrays need their own cycle guard: they never pass through `serialize` below, so a self-referencing
66
+ // array would otherwise recurse via `map` forever.
67
+ if (visited.has(val))
68
+ return undefined;
69
+ visited.add(val);
70
+ try {
71
+ return val.map((item) => serializeValue(item));
72
+ }
73
+ finally {
74
+ visited.delete(val);
75
+ }
76
+ }
77
+ if (shouldRecurse(val))
78
+ return serialize(val, visited);
79
+ return isSerializableLeaf(val) ? val : undefined;
80
+ };
81
+ // `loggingMetadata` can be any shape (e.g. a `Map`/`Set` from a `GetMetaDataFunction`). Normalize it to a
82
+ // JSON-safe form so it survives every transport — raw `Map`/`Set` clone fine over Electron's structured
83
+ // clone but collapse to `{}` over the WebSocket transport, which uses `JSON.stringify`.
84
+ const sanitizeMetadataValue = (val) => {
85
+ if (val === null || val === undefined || val instanceof Date || typeof val === "string" || typeof val === "number" || typeof val === "boolean")
86
+ return val;
87
+ if (typeof val !== "object" || visited.has(val))
88
+ return undefined; // functions, symbols, or an already-visited (cyclic) value
89
+ visited.add(val);
90
+ try {
91
+ if (val instanceof Map) {
92
+ // String(k) can collide (e.g. two object keys); suffix with "#n" so entries aren't silently dropped.
93
+ const out = {};
94
+ const keyCounts = new Map();
95
+ for (const [k, v] of val) {
96
+ const baseKey = String(k);
97
+ const count = keyCounts.get(baseKey) ?? 0;
98
+ keyCounts.set(baseKey, count + 1);
99
+ out[count === 0 ? baseKey : `${baseKey}#${count}`] = sanitizeMetadataValue(v);
100
+ }
101
+ return out;
102
+ }
103
+ if (val instanceof Set)
104
+ return [...val].map(sanitizeMetadataValue);
105
+ if (Array.isArray(val))
106
+ return val.map(sanitizeMetadataValue);
107
+ if (val instanceof Error || (core_bentley_1.JsonUtils.isObject(val) && Object.getPrototypeOf(val) === Object.prototype)) {
108
+ const out = {};
109
+ for (const key of Object.keys(val))
110
+ out[key] = sanitizeMetadataValue(val[key]);
111
+ if (val instanceof Error)
112
+ out.message = val.message;
113
+ if (val instanceof core_bentley_1.BentleyError)
114
+ applyBentleyErrorIdentity(val, out, sanitizeMetadataValue);
115
+ return out;
116
+ }
117
+ return undefined; // other class instances: not cloneable across every transport
118
+ }
119
+ finally {
120
+ visited.delete(val);
121
+ }
122
+ };
123
+ if (serialized.loggingMetadata !== undefined)
124
+ serialized.loggingMetadata = sanitizeMetadataValue(serialized.loggingMetadata);
125
+ const genericStripExcludedKeys = new Set(["loggingMetadata"]);
126
+ for (const key of Object.keys(serialized)) {
127
+ if (genericStripExcludedKeys.has(key))
128
+ continue;
129
+ serialized[key] = serializeValue(serialized[key]);
130
+ }
131
+ return serialized;
132
+ }
133
+ finally {
134
+ // Remove from the stack so a sibling branch can still serialize this object.
135
+ visited.delete(e);
136
+ }
137
+ };
138
+ return { error: serialize(err) };
139
+ }
140
+ /**
141
+ * Reconstruct an `Error` from the serialized `error` produced by [[serializeIpcError]], so the Ipc caller can
142
+ * `throw` it.
143
+ *
144
+ * By default, rebuilds a plain `Error` following the `ITwinError` paradigm (identify via
145
+ * [ITwinError.isError]($bentley), since `instanceof` cannot survive marshalling across the Ipc boundary). Pass
146
+ * `typedErrorClass` for backwards compatibility to rebuild a legacy typed `BentleyError` subclass instead — the
147
+ * frontend uses this to keep rethrowing [BackendError]($common).
148
+ * @param err The serialized error object (must be an object; callers should forward non-object values as-is).
149
+ * @param typedErrorClass Optional constructor for a legacy typed error (e.g. [BackendError]($common)). Omit for
150
+ * the ITwinError paradigm.
151
+ * @returns The reconstructed `Error` to throw.
152
+ * @internal
153
+ */
154
+ function rebuildIpcError(err, typedErrorClass) {
155
+ if (typedErrorClass === undefined || !core_bentley_1.BentleyError.isError(err)) {
156
+ const rebuilt = Object.assign(new Error(), err);
157
+ // Object.assign above re-copies `err`'s own `message` (even a non-string one, e.g. `throw { message: 123 }`),
158
+ // so guard/normalize the final message *after* the assign rather than before, or this would be silently overwritten.
159
+ rebuilt.message = typeof err.message === "string" ? err.message : "unknown error";
160
+ return rebuilt;
161
+ }
162
+ const trimErr = { ...err };
163
+ delete trimErr.iTwinErrorId; // getter on the typed error; assigning would throw
164
+ delete trimErr.loggingMetadata; // getter on the typed error; assigning would throw
165
+ return Object.assign(new typedErrorClass(err.errorNumber, err.iTwinErrorId.key, err.message, err.loggingMetadata), trimErr);
166
+ }
167
+ //# sourceMappingURL=IpcErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpcErrors.js","sourceRoot":"","sources":["../../../src/ipc/IpcErrors.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module IpcSocket\n */\n\nimport { BentleyError, JsonUtils, LoggingMetaData } from \"@itwin/core-bentley\";\nimport { IpcInvokeReturn } from \"./IpcSocket\";\n\n/**\n * Serialize a value thrown by an Ipc handler into the [[IpcInvokeReturn]] `error` envelope so it can be\n * transmitted across an Ipc socket via structured clone or JSON, depending on the transport.\n *\n * Hardens against values that can't be cloned: copies `Error`'s non-enumerable `message`/`stack`/`cause`,\n * preserves `BentleyError` identity (`iTwinErrorId` and logging metadata, normalized to a JSON-safe form),\n * recurses into nested `Error`s and plain objects, strips functions and class instances, and guards against cycles.\n * @param err The thrown value to serialize.\n * @param includeStack Whether to include `Error.stack` in the serialized output.\n * @returns An [[IpcInvokeReturn]] holding the serialized `error`.\n * @internal\n */\nexport function serializeIpcError(err: unknown, includeStack: boolean): IpcInvokeReturn {\n if (!JsonUtils.isObject(err))\n return { error: err };\n\n const serialize = (e: any, visited = new WeakSet<object>()): any => {\n if (visited.has(e))\n return undefined;\n visited.add(e);\n try {\n const serialized: any = { ...e };\n\n for (const sym of Object.getOwnPropertySymbols(serialized))\n delete serialized[sym]; // symbol-keyed properties cannot be structured-cloned\n\n // `iTwinErrorId`/`loggingMetadata` are prototype getters, so `Object.keys`/spread never pick them up; resolve\n // them explicitly. Shared by the top-level and metadata-nested paths below so they can't drift apart again.\n const applyBentleyErrorIdentity = (be: BentleyError, out: any, sanitize: (v: unknown) => unknown): void => {\n out.iTwinErrorId = be.iTwinErrorId;\n if (be.hasMetaData)\n out.loggingMetadata = sanitize(be.loggingMetadata);\n delete out._metaData;\n };\n\n if (e instanceof Error) {\n serialized.message = e.message; // NB: .message and .stack are non-enumerable on Error instances\n if (includeStack)\n serialized.stack = e.stack;\n\n // Error.cause is typically non-enumerable and must be copied explicitly.\n if (Object.prototype.hasOwnProperty.call(e, \"cause\"))\n serialized.cause = (e as { cause?: unknown }).cause;\n }\n\n if (e instanceof BentleyError)\n applyBentleyErrorIdentity(e, serialized, (v) => v); // loggingMetadata is sanitized once, below\n\n // Only recurse into Error instances and plain objects — not class instances like Date or Buffer.\n const shouldRecurse = (val: any) => val instanceof Error || (JsonUtils.isObject(val) && Object.getPrototypeOf(val) === Object.prototype);\n const isSerializableLeaf = (val: unknown): boolean => {\n const t = typeof val;\n return val === null || val === undefined || val instanceof Date\n || t === \"string\" || t === \"number\" || t === \"boolean\";\n };\n // Recurse into arrays, Errors, and plain objects; strip anything else non-cloneable (functions, RegExp,\n // Map, Set, typed arrays, other class instances) to `undefined`.\n const serializeValue = (val: any): any => {\n if (Array.isArray(val)) {\n // Arrays need their own cycle guard: they never pass through `serialize` below, so a self-referencing\n // array would otherwise recurse via `map` forever.\n if (visited.has(val))\n return undefined;\n visited.add(val);\n try {\n return val.map((item) => serializeValue(item));\n } finally {\n visited.delete(val);\n }\n }\n if (shouldRecurse(val))\n return serialize(val, visited);\n return isSerializableLeaf(val) ? val : undefined;\n };\n // `loggingMetadata` can be any shape (e.g. a `Map`/`Set` from a `GetMetaDataFunction`). Normalize it to a\n // JSON-safe form so it survives every transport — raw `Map`/`Set` clone fine over Electron's structured\n // clone but collapse to `{}` over the WebSocket transport, which uses `JSON.stringify`.\n const sanitizeMetadataValue = (val: any): any => {\n if (val === null || val === undefined || val instanceof Date || typeof val === \"string\" || typeof val === \"number\" || typeof val === \"boolean\")\n return val;\n if (typeof val !== \"object\" || visited.has(val))\n return undefined; // functions, symbols, or an already-visited (cyclic) value\n\n visited.add(val);\n try {\n if (val instanceof Map) {\n // String(k) can collide (e.g. two object keys); suffix with \"#n\" so entries aren't silently dropped.\n const out: any = {};\n const keyCounts = new Map<string, number>();\n for (const [k, v] of val) {\n const baseKey = String(k);\n const count = keyCounts.get(baseKey) ?? 0;\n keyCounts.set(baseKey, count + 1);\n out[count === 0 ? baseKey : `${baseKey}#${count}`] = sanitizeMetadataValue(v);\n }\n return out;\n }\n if (val instanceof Set)\n return [...val].map(sanitizeMetadataValue);\n if (Array.isArray(val))\n return val.map(sanitizeMetadataValue);\n if (val instanceof Error || (JsonUtils.isObject(val) && Object.getPrototypeOf(val) === Object.prototype)) {\n const out: any = {};\n for (const key of Object.keys(val))\n out[key] = sanitizeMetadataValue((val as any)[key]);\n if (val instanceof Error)\n out.message = val.message;\n if (val instanceof BentleyError)\n applyBentleyErrorIdentity(val, out, sanitizeMetadataValue);\n return out;\n }\n return undefined; // other class instances: not cloneable across every transport\n } finally {\n visited.delete(val);\n }\n };\n if (serialized.loggingMetadata !== undefined)\n serialized.loggingMetadata = sanitizeMetadataValue(serialized.loggingMetadata);\n\n const genericStripExcludedKeys = new Set([\"loggingMetadata\"]);\n for (const key of Object.keys(serialized)) {\n if (genericStripExcludedKeys.has(key))\n continue;\n serialized[key] = serializeValue(serialized[key]);\n }\n\n return serialized;\n } finally {\n // Remove from the stack so a sibling branch can still serialize this object.\n visited.delete(e);\n }\n };\n\n return { error: serialize(err) };\n}\n\n/**\n * Reconstruct an `Error` from the serialized `error` produced by [[serializeIpcError]], so the Ipc caller can\n * `throw` it.\n *\n * By default, rebuilds a plain `Error` following the `ITwinError` paradigm (identify via\n * [ITwinError.isError]($bentley), since `instanceof` cannot survive marshalling across the Ipc boundary). Pass\n * `typedErrorClass` for backwards compatibility to rebuild a legacy typed `BentleyError` subclass instead — the\n * frontend uses this to keep rethrowing [BackendError]($common).\n * @param err The serialized error object (must be an object; callers should forward non-object values as-is).\n * @param typedErrorClass Optional constructor for a legacy typed error (e.g. [BackendError]($common)). Omit for\n * the ITwinError paradigm.\n * @returns The reconstructed `Error` to throw.\n * @internal\n */\nexport function rebuildIpcError(\n err: any,\n typedErrorClass?: new (errorNumber: number, name: string, message: string, getMetaData?: LoggingMetaData) => Error,\n): Error {\n if (typedErrorClass === undefined || !BentleyError.isError(err)) {\n const rebuilt = Object.assign(new Error(), err);\n // Object.assign above re-copies `err`'s own `message` (even a non-string one, e.g. `throw { message: 123 }`),\n // so guard/normalize the final message *after* the assign rather than before, or this would be silently overwritten.\n rebuilt.message = typeof err.message === \"string\" ? err.message : \"unknown error\";\n return rebuilt;\n }\n\n const trimErr: any = { ...err };\n delete trimErr.iTwinErrorId; // getter on the typed error; assigning would throw\n delete trimErr.loggingMetadata; // getter on the typed error; assigning would throw\n return Object.assign(new typedErrorClass(err.errorNumber, err.iTwinErrorId.key, err.message, err.loggingMetadata), trimErr);\n}\n"]}
@@ -0,0 +1,44 @@
1
+ /** @packageDocumentation
2
+ * @module IpcSocket
3
+ */
4
+ import { LoggingMetaData, PickAsyncMethods } from "@itwin/core-bentley";
5
+ import { IpcInvokeReturn } from "./IpcSocket";
6
+ /**
7
+ * Unwrap an [[IpcInvokeReturn]] produced by an Ipc handler: return its `result` on success, or rethrow the
8
+ * serialized `error` on failure (rebuilt via [[rebuildIpcError]]; non-object values are rethrown as-is).
9
+ *
10
+ * Shared by both Ipc directions. By default the error is rebuilt as a plain `Error` following the `ITwinError`
11
+ * paradigm (identify via [ITwinError.isError]($bentley)); the backend (`IpcHost`) uses this. A caller may pass
12
+ * `typedErrorClass` to rebuild a legacy typed error instead — the frontend (`IpcApp`) passes [BackendError]($common)
13
+ * to preserve `instanceof BackendError` for existing consumers.
14
+ * @param retVal The [[IpcInvokeReturn]] returned by the remote handler.
15
+ * @param typedErrorClass Optional constructor for a legacy typed error to build when the serialized error carries
16
+ * `BentleyError` identity (e.g. [BackendError]($common) on the frontend). Omit it for the ITwinError paradigm.
17
+ * @returns The handler's `result` value, typed as `T` (defaults to `unknown`, so untyped callers must narrow).
18
+ * @throws The reconstructed error when `retVal` carries an `error`.
19
+ * @internal
20
+ */
21
+ export declare function unwrapIpcInvokeReturn<T = unknown>(retVal: IpcInvokeReturn, typedErrorClass?: new (errorNumber: number, name: string, message: string, getMetaData?: LoggingMetaData) => Error): T;
22
+ /**
23
+ * Create a type-safe `Proxy` that routes every method access to `call`, forwarding the accessed method name and
24
+ * its arguments. Shared by the frontend (`IpcApp.makeIpcProxy`) and backend (`IpcHost.makeIpcProxy`) so both build
25
+ * their remote-interface proxies identically; each supplies a `call` bound to its own `callIpcChannel`.
26
+ * @param call Invoked with the accessed method name followed by the call arguments.
27
+ * @returns A `Proxy` exposing `K`'s async methods.
28
+ * @internal
29
+ */
30
+ export declare function createIpcProxy<K>(call: (methodName: string, ...args: any[]) => Promise<any>): PickAsyncMethods<K>;
31
+ /**
32
+ * Create the handler that an `IpcHandler` registers on its channel: it looks up `funcName` on `impl`, invokes it
33
+ * with `args`, and packages the outcome as an [[IpcInvokeReturn]] (`{ result }` on success, or a serialized `error`
34
+ * via [[serializeIpcError]] on failure). Shared by the frontend and backend `IpcHandler.register` implementations
35
+ * so method dispatch and error packaging behave identically in both directions.
36
+ * @param impl The handler instance whose methods are exposed over the channel.
37
+ * @param channelName The channel `impl` is registered on, used for diagnostic messages.
38
+ * @param includeStack Whether to include `Error.stack` in serialized errors, or a function evaluated per
39
+ * invocation to decide (the backend omits stacks when [[IpcHost.noStack]] is set, which can change at runtime).
40
+ * @returns An async dispatcher `(funcName, ...args) => Promise<IpcInvokeReturn>`.
41
+ * @internal
42
+ */
43
+ export declare function createIpcDispatcher(impl: object, channelName: string, includeStack: boolean | (() => boolean)): (funcName: string, ...args: any[]) => Promise<IpcInvokeReturn>;
44
+ //# sourceMappingURL=IpcInvoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpcInvoke.d.ts","sourceRoot":"","sources":["../../../src/ipc/IpcInvoke.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAA2B,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGjG,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,GAAG,OAAO,EAC/C,MAAM,EAAE,eAAe,EACvB,eAAe,CAAC,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,KAAK,GACjH,CAAC,CAUH;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAMjH;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,GACtC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAiBhE"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module IpcSocket
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.unwrapIpcInvokeReturn = unwrapIpcInvokeReturn;
11
+ exports.createIpcProxy = createIpcProxy;
12
+ exports.createIpcDispatcher = createIpcDispatcher;
13
+ const core_bentley_1 = require("@itwin/core-bentley");
14
+ const IModelError_1 = require("../IModelError");
15
+ const IpcErrors_1 = require("./IpcErrors");
16
+ /**
17
+ * Unwrap an [[IpcInvokeReturn]] produced by an Ipc handler: return its `result` on success, or rethrow the
18
+ * serialized `error` on failure (rebuilt via [[rebuildIpcError]]; non-object values are rethrown as-is).
19
+ *
20
+ * Shared by both Ipc directions. By default the error is rebuilt as a plain `Error` following the `ITwinError`
21
+ * paradigm (identify via [ITwinError.isError]($bentley)); the backend (`IpcHost`) uses this. A caller may pass
22
+ * `typedErrorClass` to rebuild a legacy typed error instead — the frontend (`IpcApp`) passes [BackendError]($common)
23
+ * to preserve `instanceof BackendError` for existing consumers.
24
+ * @param retVal The [[IpcInvokeReturn]] returned by the remote handler.
25
+ * @param typedErrorClass Optional constructor for a legacy typed error to build when the serialized error carries
26
+ * `BentleyError` identity (e.g. [BackendError]($common) on the frontend). Omit it for the ITwinError paradigm.
27
+ * @returns The handler's `result` value, typed as `T` (defaults to `unknown`, so untyped callers must narrow).
28
+ * @throws The reconstructed error when `retVal` carries an `error`.
29
+ * @internal
30
+ */
31
+ function unwrapIpcInvokeReturn(retVal, typedErrorClass) {
32
+ if (retVal.error === undefined)
33
+ return retVal.result; // method was successful
34
+ // remote handler threw an exception, rethrow one on this side
35
+ const err = retVal.error;
36
+ if (!core_bentley_1.JsonUtils.isObject(err)) // exception wasn't an object?
37
+ throw retVal.error; // eslint-disable-line @typescript-eslint/only-throw-error
38
+ throw (0, IpcErrors_1.rebuildIpcError)(err, typedErrorClass);
39
+ }
40
+ /**
41
+ * Create a type-safe `Proxy` that routes every method access to `call`, forwarding the accessed method name and
42
+ * its arguments. Shared by the frontend (`IpcApp.makeIpcProxy`) and backend (`IpcHost.makeIpcProxy`) so both build
43
+ * their remote-interface proxies identically; each supplies a `call` bound to its own `callIpcChannel`.
44
+ * @param call Invoked with the accessed method name followed by the call arguments.
45
+ * @returns A `Proxy` exposing `K`'s async methods.
46
+ * @internal
47
+ */
48
+ function createIpcProxy(call) {
49
+ return new Proxy({}, {
50
+ get(_target, methodName) {
51
+ return async (...args) => call(methodName, ...args);
52
+ },
53
+ });
54
+ }
55
+ /**
56
+ * Create the handler that an `IpcHandler` registers on its channel: it looks up `funcName` on `impl`, invokes it
57
+ * with `args`, and packages the outcome as an [[IpcInvokeReturn]] (`{ result }` on success, or a serialized `error`
58
+ * via [[serializeIpcError]] on failure). Shared by the frontend and backend `IpcHandler.register` implementations
59
+ * so method dispatch and error packaging behave identically in both directions.
60
+ * @param impl The handler instance whose methods are exposed over the channel.
61
+ * @param channelName The channel `impl` is registered on, used for diagnostic messages.
62
+ * @param includeStack Whether to include `Error.stack` in serialized errors, or a function evaluated per
63
+ * invocation to decide (the backend omits stacks when [[IpcHost.noStack]] is set, which can change at runtime).
64
+ * @returns An async dispatcher `(funcName, ...args) => Promise<IpcInvokeReturn>`.
65
+ * @internal
66
+ */
67
+ function createIpcDispatcher(impl, channelName, includeStack) {
68
+ const prohibitedFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf({}));
69
+ return async (funcName, ...args) => {
70
+ try {
71
+ if (prohibitedFunctions.includes(funcName))
72
+ throw new Error(`Method "${funcName}" not available for channel: ${channelName}`);
73
+ const func = impl[funcName];
74
+ if (typeof func !== "function")
75
+ throw new IModelError_1.IModelError(core_bentley_1.IModelStatus.FunctionNotFound, `Method "${impl.constructor.name}.${funcName}" not found on IpcHandler registered for channel: ${channelName}`);
76
+ return { result: await func.call(impl, ...args) };
77
+ }
78
+ catch (err) {
79
+ return (0, IpcErrors_1.serializeIpcError)(err, typeof includeStack === "function" ? includeStack() : includeStack);
80
+ }
81
+ };
82
+ }
83
+ //# sourceMappingURL=IpcInvoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IpcInvoke.js","sourceRoot":"","sources":["../../../src/ipc/IpcInvoke.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;AAsBH,sDAaC;AAUD,wCAMC;AAcD,kDAqBC;AApFD,sDAAiG;AACjG,gDAA6C;AAC7C,2CAAiE;AAGjE;;;;;;;;;;;;;;GAcG;AACH,SAAgB,qBAAqB,CACnC,MAAuB,EACvB,eAAkH;IAElH,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;QAC5B,OAAO,MAAM,CAAC,MAAW,CAAC,CAAC,wBAAwB;IAErD,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,CAAC,wBAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,8BAA8B;QAC1D,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,0DAA0D;IAEhF,MAAM,IAAA,2BAAe,EAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAI,IAA0D;IAC1F,OAAO,IAAI,KAAK,CAAC,EAAyB,EAAE;QAC1C,GAAG,CAAC,OAAO,EAAE,UAAkB;YAC7B,OAAO,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,mBAAmB,CACjC,IAAY,EACZ,WAAmB,EACnB,YAAuC;IAEvC,MAAM,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;IAElF,OAAO,KAAK,EAAE,QAAgB,EAAE,GAAG,IAAW,EAA4B,EAAE;QAC1E,IAAI,CAAC;YACH,IAAI,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,gCAAgC,WAAW,EAAE,CAAC,CAAC;YAEpF,MAAM,IAAI,GAAI,IAAY,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,OAAO,IAAI,KAAK,UAAU;gBAC5B,MAAM,IAAI,yBAAW,CAAC,2BAAY,CAAC,gBAAgB,EAAE,WAAW,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,QAAQ,qDAAqD,WAAW,EAAE,CAAC,CAAC;YAEvK,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,IAAA,6BAAiB,EAAC,GAAG,EAAE,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACpG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module IpcSocket\n */\n\nimport { IModelStatus, JsonUtils, LoggingMetaData, PickAsyncMethods } from \"@itwin/core-bentley\";\nimport { IModelError } from \"../IModelError\";\nimport { rebuildIpcError, serializeIpcError } from \"./IpcErrors\";\nimport { IpcInvokeReturn } from \"./IpcSocket\";\n\n/**\n * Unwrap an [[IpcInvokeReturn]] produced by an Ipc handler: return its `result` on success, or rethrow the\n * serialized `error` on failure (rebuilt via [[rebuildIpcError]]; non-object values are rethrown as-is).\n *\n * Shared by both Ipc directions. By default the error is rebuilt as a plain `Error` following the `ITwinError`\n * paradigm (identify via [ITwinError.isError]($bentley)); the backend (`IpcHost`) uses this. A caller may pass\n * `typedErrorClass` to rebuild a legacy typed error instead — the frontend (`IpcApp`) passes [BackendError]($common)\n * to preserve `instanceof BackendError` for existing consumers.\n * @param retVal The [[IpcInvokeReturn]] returned by the remote handler.\n * @param typedErrorClass Optional constructor for a legacy typed error to build when the serialized error carries\n * `BentleyError` identity (e.g. [BackendError]($common) on the frontend). Omit it for the ITwinError paradigm.\n * @returns The handler's `result` value, typed as `T` (defaults to `unknown`, so untyped callers must narrow).\n * @throws The reconstructed error when `retVal` carries an `error`.\n * @internal\n */\nexport function unwrapIpcInvokeReturn<T = unknown>(\n retVal: IpcInvokeReturn,\n typedErrorClass?: new (errorNumber: number, name: string, message: string, getMetaData?: LoggingMetaData) => Error,\n): T {\n if (retVal.error === undefined)\n return retVal.result as T; // method was successful\n\n // remote handler threw an exception, rethrow one on this side\n const err = retVal.error;\n if (!JsonUtils.isObject(err)) // exception wasn't an object?\n throw retVal.error; // eslint-disable-line @typescript-eslint/only-throw-error\n\n throw rebuildIpcError(err, typedErrorClass);\n}\n\n/**\n * Create a type-safe `Proxy` that routes every method access to `call`, forwarding the accessed method name and\n * its arguments. Shared by the frontend (`IpcApp.makeIpcProxy`) and backend (`IpcHost.makeIpcProxy`) so both build\n * their remote-interface proxies identically; each supplies a `call` bound to its own `callIpcChannel`.\n * @param call Invoked with the accessed method name followed by the call arguments.\n * @returns A `Proxy` exposing `K`'s async methods.\n * @internal\n */\nexport function createIpcProxy<K>(call: (methodName: string, ...args: any[]) => Promise<any>): PickAsyncMethods<K> {\n return new Proxy({} as PickAsyncMethods<K>, {\n get(_target, methodName: string) {\n return async (...args: any[]) => call(methodName, ...args);\n },\n });\n}\n\n/**\n * Create the handler that an `IpcHandler` registers on its channel: it looks up `funcName` on `impl`, invokes it\n * with `args`, and packages the outcome as an [[IpcInvokeReturn]] (`{ result }` on success, or a serialized `error`\n * via [[serializeIpcError]] on failure). Shared by the frontend and backend `IpcHandler.register` implementations\n * so method dispatch and error packaging behave identically in both directions.\n * @param impl The handler instance whose methods are exposed over the channel.\n * @param channelName The channel `impl` is registered on, used for diagnostic messages.\n * @param includeStack Whether to include `Error.stack` in serialized errors, or a function evaluated per\n * invocation to decide (the backend omits stacks when [[IpcHost.noStack]] is set, which can change at runtime).\n * @returns An async dispatcher `(funcName, ...args) => Promise<IpcInvokeReturn>`.\n * @internal\n */\nexport function createIpcDispatcher(\n impl: object,\n channelName: string,\n includeStack: boolean | (() => boolean),\n): (funcName: string, ...args: any[]) => Promise<IpcInvokeReturn> {\n const prohibitedFunctions = Object.getOwnPropertyNames(Object.getPrototypeOf({}));\n\n return async (funcName: string, ...args: any[]): Promise<IpcInvokeReturn> => {\n try {\n if (prohibitedFunctions.includes(funcName))\n throw new Error(`Method \"${funcName}\" not available for channel: ${channelName}`);\n\n const func = (impl as any)[funcName];\n if (typeof func !== \"function\")\n throw new IModelError(IModelStatus.FunctionNotFound, `Method \"${impl.constructor.name}.${funcName}\" not found on IpcHandler registered for channel: ${channelName}`);\n\n return { result: await func.call(impl, ...args) };\n } catch (err: unknown) {\n return serializeIpcError(err, typeof includeStack === \"function\" ? includeStack() : includeStack);\n }\n };\n}\n"]}
@@ -414,12 +414,25 @@ export declare class QueryBinder {
414
414
  */
415
415
  bindRange3d(indexOrName: string | number, val: LowAndHighXYZ): this;
416
416
  private static bind;
417
+ /**
418
+ * Shared implementation for [[QueryBinder.from]] and [[QueryBinder.fromSkippingNullish]].
419
+ * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of each value.
420
+ * @param skipNullish if true, entries whose value is `undefined` or `null` are skipped instead of bound as NULL.
421
+ */
422
+ private static fromImpl;
417
423
  /**
418
424
  * Allow bulk bind either parameters by index as value array or by parameter names as object.
419
- * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of reach value.
425
+ * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of each value.
420
426
  * @returns @type QueryBinder to allow fluent interface.
421
427
  */
422
428
  static from(args: any[] | object | undefined): QueryBinder;
429
+ /**
430
+ * Same as [[QueryBinder.from]], except entries whose value is `undefined` or `null` are skipped instead of bound as NULL,
431
+ * matching the legacy `ECSqlStatement.bindValues` semantics. For positional arrays, skipped positions are left unbound
432
+ * and later positions keep their 1-based index.
433
+ * @internal
434
+ */
435
+ static fromSkippingNullish(args: any[] | object | undefined): QueryBinder;
423
436
  serialize(): object;
424
437
  }
425
438
  /** @internal */
@@ -1 +1 @@
1
- {"version":3,"file":"ConcurrentQuery.d.ts","sourceRoot":"","sources":["../../src/ConcurrentQuery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConcurrentQuery.d.ts","sourceRoot":"","sources":["../../src/ConcurrentQuery.ts"],"names":[],"mappings":"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"}
@@ -531,27 +531,49 @@ export class QueryBinder {
531
531
  }
532
532
  }
533
533
  /**
534
- * Allow bulk bind either parameters by index as value array or by parameter names as object.
535
- * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of reach value.
536
- * @returns @type QueryBinder to allow fluent interface.
534
+ * Shared implementation for [[QueryBinder.from]] and [[QueryBinder.fromSkippingNullish]].
535
+ * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of each value.
536
+ * @param skipNullish if true, entries whose value is `undefined` or `null` are skipped instead of bound as NULL.
537
537
  */
538
- static from(args) {
538
+ static fromImpl(args, skipNullish) {
539
539
  const params = new QueryBinder();
540
540
  if (typeof args === "undefined")
541
541
  return params;
542
+ const shouldBind = (val) => !skipNullish || (val !== undefined && val !== null);
542
543
  if (Array.isArray(args)) {
543
544
  let i = 1;
544
545
  for (const val of args) {
545
- this.bind(params, i++, val);
546
+ const index = i++;
547
+ if (shouldBind(val))
548
+ this.bind(params, index, val);
546
549
  }
547
550
  }
548
551
  else {
549
552
  for (const prop of Object.getOwnPropertyNames(args)) {
550
- this.bind(params, prop, args[prop]);
553
+ const val = args[prop];
554
+ if (shouldBind(val))
555
+ this.bind(params, prop, val);
551
556
  }
552
557
  }
553
558
  return params;
554
559
  }
560
+ /**
561
+ * Allow bulk bind either parameters by index as value array or by parameter names as object.
562
+ * @param args if array of values is provided then array index is used as index. If object is provided then object property name is used as parameter name of each value.
563
+ * @returns @type QueryBinder to allow fluent interface.
564
+ */
565
+ static from(args) {
566
+ return this.fromImpl(args, false);
567
+ }
568
+ /**
569
+ * Same as [[QueryBinder.from]], except entries whose value is `undefined` or `null` are skipped instead of bound as NULL,
570
+ * matching the legacy `ECSqlStatement.bindValues` semantics. For positional arrays, skipped positions are left unbound
571
+ * and later positions keep their 1-based index.
572
+ * @internal
573
+ */
574
+ static fromSkippingNullish(args) {
575
+ return this.fromImpl(args, true);
576
+ }
555
577
  serialize() {
556
578
  return this._args;
557
579
  }