microsoft-graph-client 1.0.33 → 1.0.34

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.
@@ -1,17 +1,68 @@
1
1
  /**
2
- * Utilities for working with OData queries
2
+ * Utilities for building OData query parameter values that the Microsoft Graph
3
+ * SDK won't mangle.
4
+ *
5
+ * There are TWO distinct escaping layers when you put a user-supplied string
6
+ * inside an OData filter clause that gets sent to Graph as a query parameter:
7
+ *
8
+ * 1. OData literal escaping — single quotes inside a string literal must be
9
+ * doubled, otherwise the OData parser breaks. This is `escapeODataLiteral`.
10
+ *
11
+ * 2. URL encoding of reserved characters — the Microsoft Graph SDK's
12
+ * `.filter()` and `.query()` builders DO NOT URL-encode the *value* of
13
+ * query parameters. As a result, characters like `&`, `+`, `#`, `?` get
14
+ * passed through verbatim and break the URL parsing on the server side.
15
+ *
16
+ * Empirically verified 2026-04-07: a topic filter for `'fm & fd'` failed
17
+ * with `Invalid filter clause: There is an unterminated string literal at
18
+ * position 28 in 'contains(tolower(topic), 'fm'.` because the SDK sent
19
+ * `?$filter=...'fm & fd'...` and the server parsed the `&` as a query
20
+ * param separator. See test/probe-encoding.mts for the verification.
21
+ *
22
+ * Use `escapeODataLiteral` when you control the URL building yourself (rare).
23
+ * Use `odataFilterValue` when you're going through the SDK's `.filter()` /
24
+ * `.query()` methods, which is what every API class in this package does.
25
+ *
26
+ * @see https://learn.microsoft.com/en-us/graph/filter-query-parameter
27
+ */
28
+ /**
29
+ * Escapes single quotes in an OData string literal.
30
+ *
31
+ * Use this only if you are constructing a fully-formed URL yourself and your
32
+ * URL builder will handle URL encoding separately. In most cases, prefer
33
+ * `odataFilterValue` which combines both layers.
34
+ *
35
+ * @example
36
+ * escapeODataLiteral("Let's Talk") // → "Let''s Talk"
3
37
  */
38
+ export declare function escapeODataLiteral(value: string): string;
4
39
  /**
5
- * Escapes a string for use in OData filter expressions.
6
- * Single quotes are escaped by doubling them (' → '').
40
+ * Prepares a string for safe use as an OData filter value passed through the
41
+ * Microsoft Graph SDK's `.filter()` builder.
42
+ *
43
+ * Applies BOTH escaping layers:
44
+ * 1. OData literal escape (`'` → `''`)
45
+ * 2. URL-encode the result so reserved characters don't break the request URL
7
46
  *
8
- * @param value - The string to escape
9
- * @returns The escaped string safe for OData filters
47
+ * @example
48
+ * // Building a topic filter:
49
+ * const value = odataFilterValue("FM & FD");
50
+ * client.api('/me/chats').filter(`contains(tolower(topic), '${value}')`).get();
51
+ * // The SDK sends: ?$filter=contains(tolower(topic), 'fm%20%26%20fd')
10
52
  *
11
53
  * @example
12
- * // "Let's Talk" "Let''s Talk"
13
- * const escaped = escapeODataString("Let's Talk");
14
- * const filter = `contains(topic, '${escaped}')`;
54
+ * // Filtering by a name with an apostrophe:
55
+ * const value = odataFilterValue("O'Brien");
56
+ * client.api('/me/chats').filter(`contains(displayName, '${value}')`).get();
57
+ * // → 'O%27%27Brien' (literal escape gives O''Brien, URL encode gives O%27%27Brien)
58
+ */
59
+ export declare function odataFilterValue(value: string): string;
60
+ /**
61
+ * @deprecated Use `escapeODataLiteral` (same behavior) for the literal escape,
62
+ * or `odataFilterValue` for the combined literal-escape + URL-encode that you
63
+ * almost always want when going through the Graph SDK builders.
64
+ *
65
+ * Kept temporarily for backwards compatibility with the old name.
15
66
  */
16
67
  export declare function escapeODataString(value: string): string;
17
68
  //# sourceMappingURL=odata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"odata.d.ts","sourceRoot":"","sources":["../../src/utils/odata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"odata.d.ts","sourceRoot":"","sources":["../../src/utils/odata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -1,19 +1,74 @@
1
1
  /**
2
- * Utilities for working with OData queries
2
+ * Utilities for building OData query parameter values that the Microsoft Graph
3
+ * SDK won't mangle.
4
+ *
5
+ * There are TWO distinct escaping layers when you put a user-supplied string
6
+ * inside an OData filter clause that gets sent to Graph as a query parameter:
7
+ *
8
+ * 1. OData literal escaping — single quotes inside a string literal must be
9
+ * doubled, otherwise the OData parser breaks. This is `escapeODataLiteral`.
10
+ *
11
+ * 2. URL encoding of reserved characters — the Microsoft Graph SDK's
12
+ * `.filter()` and `.query()` builders DO NOT URL-encode the *value* of
13
+ * query parameters. As a result, characters like `&`, `+`, `#`, `?` get
14
+ * passed through verbatim and break the URL parsing on the server side.
15
+ *
16
+ * Empirically verified 2026-04-07: a topic filter for `'fm & fd'` failed
17
+ * with `Invalid filter clause: There is an unterminated string literal at
18
+ * position 28 in 'contains(tolower(topic), 'fm'.` because the SDK sent
19
+ * `?$filter=...'fm & fd'...` and the server parsed the `&` as a query
20
+ * param separator. See test/probe-encoding.mts for the verification.
21
+ *
22
+ * Use `escapeODataLiteral` when you control the URL building yourself (rare).
23
+ * Use `odataFilterValue` when you're going through the SDK's `.filter()` /
24
+ * `.query()` methods, which is what every API class in this package does.
25
+ *
26
+ * @see https://learn.microsoft.com/en-us/graph/filter-query-parameter
3
27
  */
4
28
  /**
5
- * Escapes a string for use in OData filter expressions.
6
- * Single quotes are escaped by doubling them (' → '').
29
+ * Escapes single quotes in an OData string literal.
7
30
  *
8
- * @param value - The string to escape
9
- * @returns The escaped string safe for OData filters
31
+ * Use this only if you are constructing a fully-formed URL yourself and your
32
+ * URL builder will handle URL encoding separately. In most cases, prefer
33
+ * `odataFilterValue` which combines both layers.
10
34
  *
11
35
  * @example
12
- * // "Let's Talk" → "Let''s Talk"
13
- * const escaped = escapeODataString("Let's Talk");
14
- * const filter = `contains(topic, '${escaped}')`;
36
+ * escapeODataLiteral("Let's Talk") // → "Let''s Talk"
15
37
  */
16
- export function escapeODataString(value) {
38
+ export function escapeODataLiteral(value) {
17
39
  return value.replace(/'/g, "''");
18
40
  }
41
+ /**
42
+ * Prepares a string for safe use as an OData filter value passed through the
43
+ * Microsoft Graph SDK's `.filter()` builder.
44
+ *
45
+ * Applies BOTH escaping layers:
46
+ * 1. OData literal escape (`'` → `''`)
47
+ * 2. URL-encode the result so reserved characters don't break the request URL
48
+ *
49
+ * @example
50
+ * // Building a topic filter:
51
+ * const value = odataFilterValue("FM & FD");
52
+ * client.api('/me/chats').filter(`contains(tolower(topic), '${value}')`).get();
53
+ * // The SDK sends: ?$filter=contains(tolower(topic), 'fm%20%26%20fd')
54
+ *
55
+ * @example
56
+ * // Filtering by a name with an apostrophe:
57
+ * const value = odataFilterValue("O'Brien");
58
+ * client.api('/me/chats').filter(`contains(displayName, '${value}')`).get();
59
+ * // → 'O%27%27Brien' (literal escape gives O''Brien, URL encode gives O%27%27Brien)
60
+ */
61
+ export function odataFilterValue(value) {
62
+ return encodeURIComponent(escapeODataLiteral(value));
63
+ }
64
+ /**
65
+ * @deprecated Use `escapeODataLiteral` (same behavior) for the literal escape,
66
+ * or `odataFilterValue` for the combined literal-escape + URL-encode that you
67
+ * almost always want when going through the Graph SDK builders.
68
+ *
69
+ * Kept temporarily for backwards compatibility with the old name.
70
+ */
71
+ export function escapeODataString(value) {
72
+ return escapeODataLiteral(value);
73
+ }
19
74
  //# sourceMappingURL=odata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"odata.js","sourceRoot":"","sources":["../../src/utils/odata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"odata.js","sourceRoot":"","sources":["../../src/utils/odata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microsoft-graph-client",
3
- "version": "1.0.33",
3
+ "version": "1.0.34",
4
4
  "publish": true,
5
5
  "description": "TypeScript client library for Microsoft Graph API with built-in authentication",
6
6
  "type": "module",