@fluidframework/app-insights-logger 2.118.1 → 3.0.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.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,42 @@
1
1
  # @fluid-internal/app-insights-logger
2
2
 
3
- ## 2.118.0
3
+ ## 3.0.0
4
4
 
5
- Dependency updates only.
5
+ ### Minor Changes
6
6
 
7
- ## 2.117.0
7
+ - Removal of direct CommonJS support ([#28124](https://github.com/microsoft/FluidFramework/pull/28124)) [0f84e3b8878](https://github.com/microsoft/FluidFramework/commit/0f84e3b8878a5e75b2253976d98fd963bbd9db88)
8
8
 
9
- Dependency updates only.
9
+ Direct `require()` import is no longer directly supported.
10
+ Package is transpiled as ECMAScript Module.
11
+
12
+ See [Removal of direct CommonJS support in v3.0](https://github.com/microsoft/FluidFramework/issues/27444) for more information.
13
+
14
+ - Require modern TypeScript module resolution ([#27970](https://github.com/microsoft/FluidFramework/pull/27970)) [325e2016ca9](https://github.com/microsoft/FluidFramework/commit/325e2016ca9978d4a1f7552c97ba34feac9df41f)
15
+
16
+ Fluid Framework Client packages no longer include type declaration compatibility entrypoints for TypeScript's legacy Node10 resolution mode (`"moduleResolution": "node"` or `"node10"`).
17
+ Applications upgrading to Fluid Framework 3.0 must use one of the following supported configurations:
18
+ - `"module": "Node16"` with `"moduleResolution": "Node16"`
19
+ - `"module": "NodeNext"` with `"moduleResolution": "NodeNext"`
20
+ - `"module": "ESNext"` with `"moduleResolution": "Bundler"`
21
+
22
+ Existing public package entrypoints exposed through `package.json` exports, including `/alpha`, `/beta`, and `/legacy`, remain available under supported module resolution modes.
23
+
24
+ See [Removal of Node10 resolutions in v3.0](https://github.com/microsoft/FluidFramework/issues/27457) for more information.
25
+
26
+ - Client packages now target ES2022 ([#27846](https://github.com/microsoft/FluidFramework/pull/27846)) [91c78541bdd](https://github.com/microsoft/FluidFramework/commit/91c78541bddcbca5d6c5f357b023eeaee617d885)
27
+
28
+ The TypeScript compilation `target` and `lib` for the Fluid Framework client packages have been raised from ES2021/ES2020 to **ES2022**.
29
+ The published JavaScript now uses ES2022 language features (with correspondingly less down-leveling), so consuming these packages requires a runtime that supports ES2022.
30
+ All actively supported Node.js versions and evergreen browsers already meet this requirement.
31
+
32
+ Note that Fluid Framework has not officially supported targets older than ES2022 since before 2.0: this is documented in [ClientRequirements.md](https://github.com/microsoft/FluidFramework/blob/main/ClientRequirements.md) as well as the README for every client package.
33
+
34
+ It is possible this change could impact users of less up to date JavaScript runtimes.
35
+ Impacted users can use a tool like [babel](https://babeljs.io/) to transpile out unsupported language features.
36
+
37
+ - Build with TypeScript 6 ([#28052](https://github.com/microsoft/FluidFramework/pull/28052)) [7ab015c49de](https://github.com/microsoft/FluidFramework/commit/7ab015c49deec84833cdfe1fb5e1606b901f6e81)
38
+
39
+ FluidFramework Client SDK is now built using TypeScript 6. Consumers should build with TypeScript v6 or v7 or compatible tooling.
10
40
 
11
41
  ## 2.116.0
12
42
 
package/README.md CHANGED
@@ -18,15 +18,15 @@ In our case, we are sending custom metrics. [Learn more about Azure App Insights
18
18
 
19
19
  ## Using Fluid Framework libraries
20
20
 
21
- When taking a dependency on a Fluid Framework library's public APIs, we recommend using a `^` (caret) version range, such as `^1.3.4`.
22
- While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
23
- library consumers should always prefer `^`.
21
+ For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
22
+ For example, use `^1.3.4`.
24
23
 
25
- If using any of Fluid Framework's unstable APIs (for example, its `beta` APIs), we recommend using a more constrained version range, such as `~`.
24
+ For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
25
+ For example, use a `~` version range.
26
26
 
27
27
  ## Installation
28
28
 
29
- To get started, install the package by running the following command:
29
+ Run this command to install the package:
30
30
 
31
31
  ```bash
32
32
  npm i @fluidframework/app-insights-logger
@@ -34,16 +34,16 @@ npm i @fluidframework/app-insights-logger
34
34
 
35
35
  ## Importing from this package
36
36
 
37
- This package leverages [package.json exports](https://nodejs.org/api/packages.html#exports) to separate its APIs by support level.
38
- For more information on the related support guarantees, see [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
37
+ This package uses [package.json exports](https://nodejs.org/api/packages.html#exports) to separate APIs by support level.
38
+ For information about the support guarantees, read [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
39
39
 
40
- To access the `public` ([SemVer](https://semver.org/)) APIs, import via `@fluidframework/app-insights-logger` like normal.
40
+ Import the `public` APIs from `@fluidframework/app-insights-logger`.
41
41
 
42
- To access the `beta` APIs, import via `@fluidframework/app-insights-logger/beta`.
42
+ Import the `beta` APIs from `@fluidframework/app-insights-logger/beta`.
43
43
 
44
44
  ## API Documentation
45
45
 
46
- API documentation for **@fluidframework/app-insights-logger** is available at <https://fluidframework.com/docs/apis/app-insights-logger>.
46
+ Read the **@fluidframework/app-insights-logger** API documentation at <https://fluidframework.com/docs/apis/app-insights-logger>.
47
47
 
48
48
  <!-- prettier-ignore-end -->
49
49
 
@@ -109,62 +109,69 @@ From the Azure web portal, navigate to your app insights instance. Now, go to th
109
109
 
110
110
  ## Minimum Client Requirements
111
111
 
112
- These are the platform requirements for the current version of Fluid Framework Client Packages.
113
- These requirements err on the side of being too strict since within a major version they can be relaxed over time, but not made stricter.
114
- For Long Term Support (LTS) versions this can require supporting these platforms for several years.
112
+ Fluid Framework client libraries support the platforms in this document.
113
+ These requirements are intentionally restrictive.
114
+ Within a major version series, we can relax these requirements, but we cannot make them stricter.
115
+ For a Long Term Support (LTS) version, we might need to support these platforms for several years.
115
116
 
116
- It is likely that other configurations will work, but they are not supported: if they stop working, we do not consider that a bug.
117
- If you would benefit from support for something not listed here, file an issue and the product team will evaluate your request.
118
- When making such a request please include if the configuration already works (and thus the request is just that it becomes officially supported), or if changes are required to get it working.
117
+ Other configurations can work, but Fluid Framework does not support them.
118
+ If an unsupported configuration stops working, we do not classify this as a bug.
119
+ To request support for a configuration that is not listed, file an issue.
120
+ The product team will evaluate your request.
121
+ In the issue, specify the current status of the configuration:
122
+
123
+ - The configuration works but needs official support.
124
+ - The configuration does not work and requires changes.
119
125
 
120
126
  ### Supported Runtimes
121
127
 
122
- - NodeJs ^22.22.2 except that we will drop support for it [when NodeJs 22 loses its upstream support on 2027-04-30](https://github.com/nodejs/release#release-schedule), and will support a newer LTS version of NodeJS at least 1 year before 22 is end-of-life.
123
- - Running Fluid in a Node.js environment with the `--no-experimental-fetch` flag is not supported.
124
- - Modern browsers supporting the es2022 standard library: in response to asks we can add explicit support for using babel to polyfill to target specific standards or runtimes (meaning we can avoid/remove use of things that don't polyfill robustly, but otherwise target modern standards).
128
+ - Fluid Framework supports Node.js versions 22 and 24 while they receive [upstream support](https://nodejs.org/en/about/previous-releases).
129
+ - Fluid Framework will stop support for version 22 [when upstream support ends on 2027-04-30](https://github.com/nodejs/release#release-schedule).
130
+ - Fluid Framework does not support Node.js with the `--no-experimental-fetch` flag.
131
+ - Fluid Framework supports modern browsers that support the ES2022 standard library.
125
132
 
126
133
  ### Supported Tools
127
134
 
128
- - TypeScript 5.4:
129
- - All [`strict`](https://www.typescriptlang.org/tsconfig) options are supported.
130
- - [`strictNullChecks`](https://www.typescriptlang.org/tsconfig) is required.
131
- - [Configuration options deprecated in 5.0](https://github.com/microsoft/TypeScript/issues/51909) are not supported.
132
- - `exactOptionalPropertyTypes` is currently not fully supported.
133
- If used, narrowing members of Fluid Framework types types using `in`, `Reflect.has`, `Object.hasOwn` or `Object.prototype.hasOwnProperty` should be avoided as they may incorrectly exclude `undefined` from the possible values in some cases.
135
+ - [TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0):
136
+ - Fluid Framework supports all [`strict`](https://www.typescriptlang.org/tsconfig) options.
137
+ - Set the build targets (`lib`, `target`) to `ES2022` or later.
138
+ - Enable [`strictNullChecks`](https://www.typescriptlang.org/tsconfig).
139
+ - Fluid Framework does not support [configuration options deprecated in TypeScript 6.0](https://typescriptdocs.com/release-notes/TypeScript%206.0#breaking-changes-and-deprecations-in-typescript-6-0).
140
+ - Fluid Framework does not fully support `exactOptionalPropertyTypes`.
141
+ If you enable this option, do not use `in`, `Reflect.has`, `Object.hasOwn`, or `Object.prototype.hasOwnProperty` to narrow members of Fluid Framework types.
142
+ These methods can incorrectly exclude `undefined` from the possible values.
134
143
  - [webpack](https://webpack.js.org/) 5
135
- - We are not intending to be prescriptive about what bundler to use.
136
- Other bundlers which can handle ES Modules should work, but webpack is the only one we actively test.
144
+ - We do not require a specific bundler.
145
+ Other bundlers that handle ES Modules can work, but we actively test only webpack.
137
146
 
138
147
  ### Module Resolution
139
148
 
140
- [`Node16`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) resolution should be used with TypeScript compilerOptions to follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
141
- Node10 resolution is not supported as it does not support Fluid Framework's API structuring pattern that is used to distinguish stable APIs from those that are in development.
149
+ In TypeScript `compilerOptions`, use [`Node16`, `Node20`, `NodeNext`, or `Bundler`](https://www.typescriptlang.org/tsconfig#moduleResolution) module resolution.
150
+ These settings follow the [Node.js v12+ ESM Resolution and Loading algorithm](https://nodejs.github.io/nodejs.dev/en/api/v20/esm/#resolution-and-loading-algorithm).
151
+
152
+ Do not use `Node10` module resolution.
142
153
 
143
154
  ### Module Formats
144
155
 
145
156
  - ES Modules:
146
- ES Modules are the preferred way to consume our client packages (including in NodeJs) and consuming our client packages from ES Modules is fully supported.
147
- - CommonJs:
148
- Consuming our client packages as CommonJs is supported only in NodeJS and only for the cases listed below.
149
- This is done to accommodate some workflows without good ES Module support.
150
- If you have a workflow you would like included in this list, file an issue.
151
- Once this list of workflows motivating CommonJS support is empty, we may drop support for CommonJS one year after notice of the change is posted here.
152
-
153
- - Testing with Jest (which lacks [stable ESM support](https://jestjs.io/docs/ecmascript-modules) due to [unstable APIs in NodeJs](https://github.com/nodejs/node/issues/37648))
157
+ Use ES Modules to consume Fluid Framework client packages, including in Node.js.
158
+ - CommonJS:
159
+ Fluid Framework does not officially support CommonJS in version 3.0 or later.
154
160
 
155
161
  ## Contribution Guidelines
156
162
 
157
- There are many ways to [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid.
163
+ You can [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid Framework in these ways:
158
164
 
159
- - Participate in Q&A in our [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
160
- - [Submit bugs](https://github.com/microsoft/FluidFramework/issues) and help us verify fixes as they are checked in.
161
- - Review the [source code changes](https://github.com/microsoft/FluidFramework/pulls).
165
+ - Answer questions in [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
166
+ - [Submit bug reports](https://github.com/microsoft/FluidFramework/issues) and help verify fixes.
167
+ - Review [source code changes](https://github.com/microsoft/FluidFramework/pulls).
162
168
  - [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
163
169
 
164
- Detailed instructions for working in the repo can be found in the [Wiki](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
170
+ For detailed instructions, read the [repo documentation](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Home.md).
165
171
 
166
- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
167
- For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
172
+ This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
173
+ For more information, read the [Code of Conduct frequently asked questions](https://opensource.microsoft.com/codeofconduct/faq/).
174
+ For questions or comments, contact [opencode@microsoft.com](mailto:opencode@microsoft.com).
168
175
 
169
176
  This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
170
177
  Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
@@ -172,13 +179,9 @@ Use of Microsoft trademarks or logos in modified versions of this project must n
172
179
 
173
180
  ## Help
174
181
 
175
- Not finding what you're looking for in this README?
176
- Check out [fluidframework.com](https://fluidframework.com/docs/).
177
-
178
- Still not finding what you're looking for?
179
- Please [file an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
182
+ Read the [Fluid Framework documentation](https://fluidframework.com/docs/) for information about Fluid Framework concepts and APIs.
180
183
 
181
- Thank you!
184
+ To request information that the documentation does not contain, [create an issue](https://github.com/microsoft/FluidFramework/blob/main/docs/content/Contributing/Submitting-Bugs-and-Feature-Requests.md).
182
185
 
183
186
  ## Trademark
184
187
 
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
+ "extends": "<projectFolder>/../../../../common/build/build-common/api-extractor-model.esm.json"
4
+ }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
- "extends": "../../../../common/build/build-common/api-extractor-base.esm.no-legacy.json",
3
+ "extends": "<projectFolder>/../../../../common/build/build-common/api-extractor-report-base.esm.json",
4
+ "mainEntryPointFilePath": "<projectFolder>/lib/beta.d.ts",
4
5
  "messages": {
5
6
  // The following overrides are workarounds for API-Extractor incorrectly running analysis on our application
6
7
  // insights dependency.
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.createLogger = void 0;
7
+ exports.createLogger = createLogger;
8
8
  /**
9
9
  * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}
10
10
  * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.
@@ -14,6 +14,13 @@ exports.createLogger = void 0;
14
14
  * @sealed
15
15
  */
16
16
  class FluidAppInsightsLogger {
17
+ /**
18
+ * The Azure ApplicationInsights client utilized by this logger.
19
+ * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()
20
+ * or else logging will not occur.
21
+ */
22
+ baseLoggingClient;
23
+ config;
17
24
  constructor(client, config) {
18
25
  this.baseLoggingClient = client;
19
26
  // Deep copy config to prevent issues if user mutates the object they passed in
@@ -179,5 +186,4 @@ class FluidAppInsightsLogger {
179
186
  function createLogger(client, config) {
180
187
  return new FluidAppInsightsLogger(client, config);
181
188
  }
182
- exports.createLogger = createLogger;
183
189
  //# sourceMappingURL=fluidAppInsightsLogger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAppInsightsLogger.js","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * The configuration object for creating the logger via {@link createLogger}.\n * @beta\n */\nexport interface FluidAppInsightsLoggerConfig {\n\t/**\n\t * This Configuration defines how filtering will be applied to Fluid telemetry events flowing through the logger.\n\t * This determines which events will be sent to Azure App Insights.\n\t */\n\tfiltering: {\n\t\t/**\n\t\t * Determines whether all telemetry events are sent or not sent by default and whether filters will exclude matching telemetry events or include them.\n\t\t *\n\t\t * \"inclusive\" mode means all logs are NOT SENT by default and only the events that match at least one or more specified filters WILL be sent (included).\n\t\t *\n\t\t * \"exclusive\" mode means all logs ARE SENT by default and only the events that match at least one or more specified filters WILL NOT be sent (excluded).\n\t\t */\n\t\tmode: \"inclusive\" | \"exclusive\";\n\t\t/**\n\t\t * Controls the filtering of log events.\n\t\t *\n\t\t * @remarks Leaving this undefined will be treated as an empty array.\n\t\t *\n\t\t * In order for the filters to be valid they must meet the following conditions:\n\t\t *\n\t\t * 1. There must not be any two filters with the same `namespacePattern`.\n\t\t *\n\t\t * 2. All {@link NamespaceFilter} must not have any defined `namespacePatternException` that is not a child of the parent `namespacePattern`\n\t\t */\n\t\tfilters?: TelemetryFilter[];\n\t};\n}\n\n/**\n * A filter used to match against the category of a telemetry event\n * @beta\n */\nexport interface CategoryFilter {\n\t/**\n\t * The categories of telemetry events that this filter applies to\n\t */\n\tcategories: TelemetryEventCategory[];\n}\n\n/**\n * A filter used to match against the namespaces of a telemetry event\n * @beta\n */\nexport interface NamespaceFilter {\n\t/**\n\t * The namespace pattern to filter telemetry events.\n\t *\n\t * @remarks This will match namespaces that start with the given string. It is not a Regex pattern.\n\t * @example\n\t * \"perf:latency\" will match any namespace starting with \"perf:latency\"\n\t */\n\tnamespacePattern: string;\n\t/**\n\t * A list of namespace patterns to explicitly exclude from the filter.\n\t *\n\t * @example\n\t * If you have a namespacePattern of \"perf:latency\" but want to exclude\n\t * events from \"perf:latency:ops\", you would add \"perf:latency:ops\" to this list.\n\t */\n\tnamespacePatternExceptions?: Set<string>;\n}\n\n/**\n * Object used with an {@link FluidAppInsightsLoggerConfig}\n * to define a filter with logic for matching it to telemetry events.\n * Filters can include either a category, namespace or both types of filters; a valid filter must have at least one defined.\n * Not definining the `categories` filter array is the same as providing an array with all possible categories.\n *\n * Events must satisify the following rules for a telemetry filter:\n *\n * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n *\n * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n *\n * 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.\n *\n * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n * @example\n * With the following configuration, an event `{ namespace: \"A.B.C\", categories: [\"generic\"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific\n * ```\n * const logger = new FluidAppInsightsLogger(appInsightsClient, {\n *\t\t\tfiltering: {\n *\t\t\t\tmode: \"inclusive\",\n *\t\t\t\tfilters: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B\",\n *\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n *\t\t\t\t\t\tcategories: [\"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t],\n *\t\t\t},\n *\t\t});\n * ```\n * @beta\n */\nexport type TelemetryFilter =\n\t| CategoryFilter\n\t| NamespaceFilter\n\t| (CategoryFilter & NamespaceFilter);\n\n/**\n * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n * or else logging will not occur.\n *\n * @sealed\n */\nclass FluidAppInsightsLogger implements ITelemetryBaseLogger {\n\t/**\n\t * The Azure ApplicationInsights client utilized by this logger.\n\t * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n\t * or else logging will not occur.\n\t */\n\tprivate readonly baseLoggingClient: ApplicationInsights;\n\tprivate readonly config: FluidAppInsightsLoggerConfig;\n\tpublic constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig) {\n\t\tthis.baseLoggingClient = client;\n\t\t// Deep copy config to prevent issues if user mutates the object they passed in\n\t\tthis.config = config\n\t\t\t? structuredClone(config)\n\t\t\t: {\n\t\t\t\t\tfiltering: {\n\t\t\t\t\t\tmode: \"exclusive\",\n\t\t\t\t\t\tfilters: [],\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\tif (this.config.filtering.filters) {\n\t\t\tthis.validateFilters(this.config.filtering.filters);\n\t\t\t// Sort filters by longest namespace first.\n\t\t\tthis.config.filtering.filters.sort((a, b) => {\n\t\t\t\tconst namespaceALength =\n\t\t\t\t\t\"namespacePattern\" in a && a.namespacePattern !== undefined\n\t\t\t\t\t\t? a.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\tconst namespaceBLength =\n\t\t\t\t\t\"namespacePattern\" in b && b.namespacePattern !== undefined\n\t\t\t\t\t\t? b.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\treturn namespaceBLength - namespaceALength;\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Routes Fluid telemetry events to the trackEvent App Insights API.\n\t * This method also uses the provided {@link FluidAppInsightsLoggerConfig} to\n\t * determine whether an event should be sent or not.\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tif (this.shouldSendEvent(event)) {\n\t\t\tthis.baseLoggingClient.trackEvent({\n\t\t\t\tname: event.eventName,\n\t\t\t\tproperties: event,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate shouldSendEvent(event: ITelemetryBaseEvent): boolean {\n\t\t// No events should be sent by default in \"inclusive\" mode, and all events should be\n\t\t// sent by default in \"exclusive\" mode.\n\t\tlet shouldSendEvent = this.config.filtering.mode === \"inclusive\" ? false : true;\n\t\tif (this.doesEventMatchFilter(event)) {\n\t\t\t// If the event does match a filter, in \"inclusive\" filter mode that means it should\n\t\t\t// be sent (included). In \"exclusive\" mode the opposite is true.\n\t\t\tshouldSendEvent = this.config.filtering.mode === \"inclusive\" ? true : false;\n\t\t}\n\t\treturn shouldSendEvent;\n\t}\n\n\t/**\n\t * Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.\n\t *\n\t * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n\t * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n\t *\n\t * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n\t *\n\t * 3. If only `categories` or a `namespace` is provided, the event should match either one of them.\n\t *\n\t * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n\t *\n\t * @param event - The telemetry event to check against the filters.\n\t *\n\t * @returns `true` if the event matches any filter, otherwise `false`.\n\t */\n\tprivate doesEventMatchFilter(event: ITelemetryBaseEvent): boolean {\n\t\tfor (const filter of this.config.filtering.filters ?? []) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (event.eventName.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t// Found matching namespace pattern, since filters are ordered in most specific first,\n\t\t\t\t\t// this is the most specific, relevant matching filter for the event.\n\n\t\t\t\t\t// By default, if no categories are defined then any category is a valid match.\n\t\t\t\t\tlet doesFilterCategoriesMatch = true;\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"categories\" in filter &&\n\t\t\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\t\t\tfilter.categories.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdoesFilterCategoriesMatch = false;\n\t\t\t\t\t\tconst matchingCategory = filter.categories.find(\n\t\t\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdoesFilterCategoriesMatch = matchingCategory ? true : false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\t\t// The most specific, relevant filter matches so no need to attempt to evaluate against other filters\n\t\t\t\t\t\t// as long as the events namespace does not match any defined namespace exception.\n\t\t\t\t\t\tif (filter.namespacePatternExceptions !== undefined) {\n\t\t\t\t\t\t\tfor (const patternException of filter.namespacePatternExceptions) {\n\t\t\t\t\t\t\t\tif (event.eventName.startsWith(patternException)) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Filter only has categories defined\n\t\t\telse if (\n\t\t\t\t\"categories\" in filter &&\n\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\tfilter.categories.length > 0\n\t\t\t) {\n\t\t\t\tconst doesFilterCategoriesMatch = filter.categories.find(\n\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t);\n\n\t\t\t\t// This filter specified no namespaces but it has a category match.\n\t\t\t\t// Since filters are ordered by most specific first, we know that no previous\n\t\t\t\t// filters with namespaces matched so we can return true.\n\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.\n\t *\n\t * @throws An Error if there are two filters with duplicate namespace patterns or a filter with a pattern exception that is not a child of the parent pattern.\n\t */\n\tprivate validateFilters(filters: TelemetryFilter[]): void {\n\t\tconst uniqueFilterNamespaces = new Set<string>();\n\n\t\tfor (const filter of filters) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (uniqueFilterNamespaces.has(filter.namespacePattern)) {\n\t\t\t\t\tthrow new Error(\"Cannot have duplicate namespace pattern filters\");\n\t\t\t\t} else {\n\t\t\t\t\tuniqueFilterNamespaces.add(filter.namespacePattern);\n\t\t\t\t}\n\n\t\t\t\tfor (const patternException of filter.namespacePatternExceptions ?? []) {\n\t\t\t\t\tif (!patternException.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\"categories\" in filter && filter.categories !== undefined) {\n\t\t\t\t// These are filters that only contain \"categories\". For the purpose of this validation logic, we are treating filters\n\t\t\t\t// that does not contain a defined namespace as the the same as a blank \"\" namespace pattern (which will match any event).\n\t\t\t\tif (uniqueFilterNamespaces.has(\"\")) {\n\t\t\t\t\tthrow new Error(\"Cannot have multiple filters that only define categories\");\n\t\t\t\t}\n\t\t\t\tuniqueFilterNamespaces.add(\"\");\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid filter does not have either a namespace or a category.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n *\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),\n * or else logging will not occur.\n *\n * @beta\n */\nexport function createLogger(\n\tclient: ApplicationInsights,\n\tconfig?: FluidAppInsightsLoggerConfig,\n): ITelemetryBaseLogger {\n\treturn new FluidAppInsightsLogger(client, config);\n}\n"]}
1
+ {"version":3,"file":"fluidAppInsightsLogger.js","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAqUH,oCAKC;AAzMD;;;;;;;GAOG;AACH,MAAM,sBAAsB;IAC3B;;;;OAIG;IACc,iBAAiB,CAAsB;IACvC,MAAM,CAA+B;IACtD,YAAmB,MAA2B,EAAE,MAAqC;QACpF,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;QAChC,+EAA+E;QAC/E,IAAI,CAAC,MAAM,GAAG,MAAM;YACnB,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC;YACzB,CAAC,CAAC;gBACA,SAAS,EAAE;oBACV,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,EAAE;iBACX;aACD,CAAC;QAEJ,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACpD,2CAA2C;YAC3C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC3C,MAAM,gBAAgB,GACrB,kBAAkB,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,KAAK,SAAS;oBAC1D,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM;oBAC3B,CAAC,CAAC,CAAC,CAAC;gBACN,MAAM,gBAAgB,GACrB,kBAAkB,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,KAAK,SAAS;oBAC1D,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM;oBAC3B,CAAC,CAAC,CAAC,CAAC;gBACN,OAAO,gBAAgB,GAAG,gBAAgB,CAAC;YAC5C,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,IAAI,CAAC,KAA0B;QACrC,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;gBACjC,IAAI,EAAE,KAAK,CAAC,SAAS;gBACrB,UAAU,EAAE,KAAK;aACjB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEO,eAAe,CAAC,KAA0B;QACjD,oFAAoF;QACpF,uCAAuC;QACvC,IAAI,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAChF,IAAI,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,oFAAoF;YACpF,gEAAgE;YAChE,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7E,CAAC;QACD,OAAO,eAAe,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,oBAAoB,CAAC,KAA0B;QACtD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC1D,IAAI,kBAAkB,IAAI,MAAM,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBAC3E,IAAI,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBACzD,sFAAsF;oBACtF,qEAAqE;oBAErE,+EAA+E;oBAC/E,IAAI,yBAAyB,GAAG,IAAI,CAAC;oBACrC,IACC,YAAY,IAAI,MAAM;wBACtB,MAAM,CAAC,UAAU,KAAK,SAAS;wBAC/B,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAC3B,CAAC;wBACF,yBAAyB,GAAG,KAAK,CAAC;wBAClC,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAC9C,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CACzC,CAAC;wBACF,yBAAyB,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;oBAC7D,CAAC;oBAED,IAAI,yBAAyB,EAAE,CAAC;wBAC/B,qGAAqG;wBACrG,kFAAkF;wBAClF,IAAI,MAAM,CAAC,0BAA0B,KAAK,SAAS,EAAE,CAAC;4BACrD,KAAK,MAAM,gBAAgB,IAAI,MAAM,CAAC,0BAA0B,EAAE,CAAC;gCAClE,IAAI,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;oCAClD,OAAO,KAAK,CAAC;gCACd,CAAC;4BACF,CAAC;wBACF,CAAC;wBACD,OAAO,IAAI,CAAC;oBACb,CAAC;yBAAM,CAAC;wBACP,OAAO,KAAK,CAAC;oBACd,CAAC;gBACF,CAAC;YACF,CAAC;YACD,qCAAqC;iBAChC,IACJ,YAAY,IAAI,MAAM;gBACtB,MAAM,CAAC,UAAU,KAAK,SAAS;gBAC/B,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAC3B,CAAC;gBACF,MAAM,yBAAyB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CACvD,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CACzC,CAAC;gBAEF,mEAAmE;gBACnE,6EAA6E;gBAC7E,yDAAyD;gBACzD,IAAI,yBAAyB,EAAE,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACb,CAAC;qBAAM,CAAC;oBACP,SAAS;gBACV,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACb,CAAC;QACF,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,OAA0B;QACjD,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAU,CAAC;QAEjD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,kBAAkB,IAAI,MAAM,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBAC3E,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBACzD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACpE,CAAC;qBAAM,CAAC;oBACP,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBACrD,CAAC;gBAED,KAAK,MAAM,gBAAgB,IAAI,MAAM,CAAC,0BAA0B,IAAI,EAAE,EAAE,CAAC;oBACxE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAC3D,MAAM,IAAI,KAAK,CACd,uFAAuF,CACvF,CAAC;oBACH,CAAC;gBACF,CAAC;YACF,CAAC;iBAAM,IAAI,YAAY,IAAI,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACtE,sHAAsH;gBACtH,0HAA0H;gBAC1H,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACpC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC7E,CAAC;gBACD,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACnF,CAAC;QACF,CAAC;IACF,CAAC;CACD;AAED;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAC3B,MAA2B,EAC3B,MAAqC;IAErC,OAAO,IAAI,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * The configuration object for creating the logger via {@link createLogger}.\n * @beta\n */\nexport interface FluidAppInsightsLoggerConfig {\n\t/**\n\t * This Configuration defines how filtering will be applied to Fluid telemetry events flowing through the logger.\n\t * This determines which events will be sent to Azure App Insights.\n\t */\n\tfiltering: {\n\t\t/**\n\t\t * Determines whether all telemetry events are sent or not sent by default and whether filters will exclude matching telemetry events or include them.\n\t\t *\n\t\t * \"inclusive\" mode means all logs are NOT SENT by default and only the events that match at least one or more specified filters WILL be sent (included).\n\t\t *\n\t\t * \"exclusive\" mode means all logs ARE SENT by default and only the events that match at least one or more specified filters WILL NOT be sent (excluded).\n\t\t */\n\t\tmode: \"inclusive\" | \"exclusive\";\n\t\t/**\n\t\t * Controls the filtering of log events.\n\t\t *\n\t\t * @remarks Leaving this undefined will be treated as an empty array.\n\t\t *\n\t\t * In order for the filters to be valid they must meet the following conditions:\n\t\t *\n\t\t * 1. There must not be any two filters with the same `namespacePattern`.\n\t\t *\n\t\t * 2. All {@link NamespaceFilter} must not have any defined `namespacePatternException` that is not a child of the parent `namespacePattern`\n\t\t */\n\t\tfilters?: TelemetryFilter[];\n\t};\n}\n\n/**\n * A filter used to match against the category of a telemetry event\n * @beta\n */\nexport interface CategoryFilter {\n\t/**\n\t * The categories of telemetry events that this filter applies to\n\t */\n\tcategories: TelemetryEventCategory[];\n}\n\n/**\n * A filter used to match against the namespaces of a telemetry event\n * @beta\n */\nexport interface NamespaceFilter {\n\t/**\n\t * The namespace pattern to filter telemetry events.\n\t *\n\t * @remarks This will match namespaces that start with the given string. It is not a Regex pattern.\n\t * @example\n\t * \"perf:latency\" will match any namespace starting with \"perf:latency\"\n\t */\n\tnamespacePattern: string;\n\t/**\n\t * A list of namespace patterns to explicitly exclude from the filter.\n\t *\n\t * @example\n\t * If you have a namespacePattern of \"perf:latency\" but want to exclude\n\t * events from \"perf:latency:ops\", you would add \"perf:latency:ops\" to this list.\n\t */\n\tnamespacePatternExceptions?: Set<string>;\n}\n\n/**\n * Object used with an {@link FluidAppInsightsLoggerConfig}\n * to define a filter with logic for matching it to telemetry events.\n * Filters can include either a category, namespace or both types of filters; a valid filter must have at least one defined.\n * Not definining the `categories` filter array is the same as providing an array with all possible categories.\n *\n * Events must satisify the following rules for a telemetry filter:\n *\n * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n *\n * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n *\n * 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.\n *\n * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n * @example\n * With the following configuration, an event `{ namespace: \"A.B.C\", categories: [\"generic\"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific\n * ```\n * const logger = new FluidAppInsightsLogger(appInsightsClient, {\n *\t\t\tfiltering: {\n *\t\t\t\tmode: \"inclusive\",\n *\t\t\t\tfilters: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B\",\n *\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n *\t\t\t\t\t\tcategories: [\"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t],\n *\t\t\t},\n *\t\t});\n * ```\n * @beta\n */\nexport type TelemetryFilter =\n\t| CategoryFilter\n\t| NamespaceFilter\n\t| (CategoryFilter & NamespaceFilter);\n\n/**\n * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n * or else logging will not occur.\n *\n * @sealed\n */\nclass FluidAppInsightsLogger implements ITelemetryBaseLogger {\n\t/**\n\t * The Azure ApplicationInsights client utilized by this logger.\n\t * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n\t * or else logging will not occur.\n\t */\n\tprivate readonly baseLoggingClient: ApplicationInsights;\n\tprivate readonly config: FluidAppInsightsLoggerConfig;\n\tpublic constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig) {\n\t\tthis.baseLoggingClient = client;\n\t\t// Deep copy config to prevent issues if user mutates the object they passed in\n\t\tthis.config = config\n\t\t\t? structuredClone(config)\n\t\t\t: {\n\t\t\t\t\tfiltering: {\n\t\t\t\t\t\tmode: \"exclusive\",\n\t\t\t\t\t\tfilters: [],\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\tif (this.config.filtering.filters) {\n\t\t\tthis.validateFilters(this.config.filtering.filters);\n\t\t\t// Sort filters by longest namespace first.\n\t\t\tthis.config.filtering.filters.sort((a, b) => {\n\t\t\t\tconst namespaceALength =\n\t\t\t\t\t\"namespacePattern\" in a && a.namespacePattern !== undefined\n\t\t\t\t\t\t? a.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\tconst namespaceBLength =\n\t\t\t\t\t\"namespacePattern\" in b && b.namespacePattern !== undefined\n\t\t\t\t\t\t? b.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\treturn namespaceBLength - namespaceALength;\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Routes Fluid telemetry events to the trackEvent App Insights API.\n\t * This method also uses the provided {@link FluidAppInsightsLoggerConfig} to\n\t * determine whether an event should be sent or not.\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tif (this.shouldSendEvent(event)) {\n\t\t\tthis.baseLoggingClient.trackEvent({\n\t\t\t\tname: event.eventName,\n\t\t\t\tproperties: event,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate shouldSendEvent(event: ITelemetryBaseEvent): boolean {\n\t\t// No events should be sent by default in \"inclusive\" mode, and all events should be\n\t\t// sent by default in \"exclusive\" mode.\n\t\tlet shouldSendEvent = this.config.filtering.mode === \"inclusive\" ? false : true;\n\t\tif (this.doesEventMatchFilter(event)) {\n\t\t\t// If the event does match a filter, in \"inclusive\" filter mode that means it should\n\t\t\t// be sent (included). In \"exclusive\" mode the opposite is true.\n\t\t\tshouldSendEvent = this.config.filtering.mode === \"inclusive\" ? true : false;\n\t\t}\n\t\treturn shouldSendEvent;\n\t}\n\n\t/**\n\t * Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.\n\t *\n\t * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n\t * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n\t *\n\t * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n\t *\n\t * 3. If only `categories` or a `namespace` is provided, the event should match either one of them.\n\t *\n\t * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n\t *\n\t * @param event - The telemetry event to check against the filters.\n\t *\n\t * @returns `true` if the event matches any filter, otherwise `false`.\n\t */\n\tprivate doesEventMatchFilter(event: ITelemetryBaseEvent): boolean {\n\t\tfor (const filter of this.config.filtering.filters ?? []) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (event.eventName.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t// Found matching namespace pattern, since filters are ordered in most specific first,\n\t\t\t\t\t// this is the most specific, relevant matching filter for the event.\n\n\t\t\t\t\t// By default, if no categories are defined then any category is a valid match.\n\t\t\t\t\tlet doesFilterCategoriesMatch = true;\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"categories\" in filter &&\n\t\t\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\t\t\tfilter.categories.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdoesFilterCategoriesMatch = false;\n\t\t\t\t\t\tconst matchingCategory = filter.categories.find(\n\t\t\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdoesFilterCategoriesMatch = matchingCategory ? true : false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\t\t// The most specific, relevant filter matches so no need to attempt to evaluate against other filters\n\t\t\t\t\t\t// as long as the events namespace does not match any defined namespace exception.\n\t\t\t\t\t\tif (filter.namespacePatternExceptions !== undefined) {\n\t\t\t\t\t\t\tfor (const patternException of filter.namespacePatternExceptions) {\n\t\t\t\t\t\t\t\tif (event.eventName.startsWith(patternException)) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Filter only has categories defined\n\t\t\telse if (\n\t\t\t\t\"categories\" in filter &&\n\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\tfilter.categories.length > 0\n\t\t\t) {\n\t\t\t\tconst doesFilterCategoriesMatch = filter.categories.find(\n\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t);\n\n\t\t\t\t// This filter specified no namespaces but it has a category match.\n\t\t\t\t// Since filters are ordered by most specific first, we know that no previous\n\t\t\t\t// filters with namespaces matched so we can return true.\n\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.\n\t *\n\t * @throws An Error if there are two filters with duplicate namespace patterns or a filter with a pattern exception that is not a child of the parent pattern.\n\t */\n\tprivate validateFilters(filters: TelemetryFilter[]): void {\n\t\tconst uniqueFilterNamespaces = new Set<string>();\n\n\t\tfor (const filter of filters) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (uniqueFilterNamespaces.has(filter.namespacePattern)) {\n\t\t\t\t\tthrow new Error(\"Cannot have duplicate namespace pattern filters\");\n\t\t\t\t} else {\n\t\t\t\t\tuniqueFilterNamespaces.add(filter.namespacePattern);\n\t\t\t\t}\n\n\t\t\t\tfor (const patternException of filter.namespacePatternExceptions ?? []) {\n\t\t\t\t\tif (!patternException.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\"categories\" in filter && filter.categories !== undefined) {\n\t\t\t\t// These are filters that only contain \"categories\". For the purpose of this validation logic, we are treating filters\n\t\t\t\t// that does not contain a defined namespace as the the same as a blank \"\" namespace pattern (which will match any event).\n\t\t\t\tif (uniqueFilterNamespaces.has(\"\")) {\n\t\t\t\t\tthrow new Error(\"Cannot have multiple filters that only define categories\");\n\t\t\t\t}\n\t\t\t\tuniqueFilterNamespaces.add(\"\");\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid filter does not have either a namespace or a category.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n *\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),\n * or else logging will not occur.\n *\n * @beta\n */\nexport function createLogger(\n\tclient: ApplicationInsights,\n\tconfig?: FluidAppInsightsLoggerConfig,\n): ITelemetryBaseLogger {\n\treturn new FluidAppInsightsLogger(client, config);\n}\n"]}
package/lib/beta.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outDir ./lib" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  /**
@@ -11,6 +11,13 @@
11
11
  * @sealed
12
12
  */
13
13
  class FluidAppInsightsLogger {
14
+ /**
15
+ * The Azure ApplicationInsights client utilized by this logger.
16
+ * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()
17
+ * or else logging will not occur.
18
+ */
19
+ baseLoggingClient;
20
+ config;
14
21
  constructor(client, config) {
15
22
  this.baseLoggingClient = client;
16
23
  // Deep copy config to prevent issues if user mutates the object they passed in
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAppInsightsLogger.js","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * The configuration object for creating the logger via {@link createLogger}.\n * @beta\n */\nexport interface FluidAppInsightsLoggerConfig {\n\t/**\n\t * This Configuration defines how filtering will be applied to Fluid telemetry events flowing through the logger.\n\t * This determines which events will be sent to Azure App Insights.\n\t */\n\tfiltering: {\n\t\t/**\n\t\t * Determines whether all telemetry events are sent or not sent by default and whether filters will exclude matching telemetry events or include them.\n\t\t *\n\t\t * \"inclusive\" mode means all logs are NOT SENT by default and only the events that match at least one or more specified filters WILL be sent (included).\n\t\t *\n\t\t * \"exclusive\" mode means all logs ARE SENT by default and only the events that match at least one or more specified filters WILL NOT be sent (excluded).\n\t\t */\n\t\tmode: \"inclusive\" | \"exclusive\";\n\t\t/**\n\t\t * Controls the filtering of log events.\n\t\t *\n\t\t * @remarks Leaving this undefined will be treated as an empty array.\n\t\t *\n\t\t * In order for the filters to be valid they must meet the following conditions:\n\t\t *\n\t\t * 1. There must not be any two filters with the same `namespacePattern`.\n\t\t *\n\t\t * 2. All {@link NamespaceFilter} must not have any defined `namespacePatternException` that is not a child of the parent `namespacePattern`\n\t\t */\n\t\tfilters?: TelemetryFilter[];\n\t};\n}\n\n/**\n * A filter used to match against the category of a telemetry event\n * @beta\n */\nexport interface CategoryFilter {\n\t/**\n\t * The categories of telemetry events that this filter applies to\n\t */\n\tcategories: TelemetryEventCategory[];\n}\n\n/**\n * A filter used to match against the namespaces of a telemetry event\n * @beta\n */\nexport interface NamespaceFilter {\n\t/**\n\t * The namespace pattern to filter telemetry events.\n\t *\n\t * @remarks This will match namespaces that start with the given string. It is not a Regex pattern.\n\t * @example\n\t * \"perf:latency\" will match any namespace starting with \"perf:latency\"\n\t */\n\tnamespacePattern: string;\n\t/**\n\t * A list of namespace patterns to explicitly exclude from the filter.\n\t *\n\t * @example\n\t * If you have a namespacePattern of \"perf:latency\" but want to exclude\n\t * events from \"perf:latency:ops\", you would add \"perf:latency:ops\" to this list.\n\t */\n\tnamespacePatternExceptions?: Set<string>;\n}\n\n/**\n * Object used with an {@link FluidAppInsightsLoggerConfig}\n * to define a filter with logic for matching it to telemetry events.\n * Filters can include either a category, namespace or both types of filters; a valid filter must have at least one defined.\n * Not definining the `categories` filter array is the same as providing an array with all possible categories.\n *\n * Events must satisify the following rules for a telemetry filter:\n *\n * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n *\n * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n *\n * 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.\n *\n * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n * @example\n * With the following configuration, an event `{ namespace: \"A.B.C\", categories: [\"generic\"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific\n * ```\n * const logger = new FluidAppInsightsLogger(appInsightsClient, {\n *\t\t\tfiltering: {\n *\t\t\t\tmode: \"inclusive\",\n *\t\t\t\tfilters: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B\",\n *\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n *\t\t\t\t\t\tcategories: [\"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t],\n *\t\t\t},\n *\t\t});\n * ```\n * @beta\n */\nexport type TelemetryFilter =\n\t| CategoryFilter\n\t| NamespaceFilter\n\t| (CategoryFilter & NamespaceFilter);\n\n/**\n * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n * or else logging will not occur.\n *\n * @sealed\n */\nclass FluidAppInsightsLogger implements ITelemetryBaseLogger {\n\t/**\n\t * The Azure ApplicationInsights client utilized by this logger.\n\t * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n\t * or else logging will not occur.\n\t */\n\tprivate readonly baseLoggingClient: ApplicationInsights;\n\tprivate readonly config: FluidAppInsightsLoggerConfig;\n\tpublic constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig) {\n\t\tthis.baseLoggingClient = client;\n\t\t// Deep copy config to prevent issues if user mutates the object they passed in\n\t\tthis.config = config\n\t\t\t? structuredClone(config)\n\t\t\t: {\n\t\t\t\t\tfiltering: {\n\t\t\t\t\t\tmode: \"exclusive\",\n\t\t\t\t\t\tfilters: [],\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\tif (this.config.filtering.filters) {\n\t\t\tthis.validateFilters(this.config.filtering.filters);\n\t\t\t// Sort filters by longest namespace first.\n\t\t\tthis.config.filtering.filters.sort((a, b) => {\n\t\t\t\tconst namespaceALength =\n\t\t\t\t\t\"namespacePattern\" in a && a.namespacePattern !== undefined\n\t\t\t\t\t\t? a.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\tconst namespaceBLength =\n\t\t\t\t\t\"namespacePattern\" in b && b.namespacePattern !== undefined\n\t\t\t\t\t\t? b.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\treturn namespaceBLength - namespaceALength;\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Routes Fluid telemetry events to the trackEvent App Insights API.\n\t * This method also uses the provided {@link FluidAppInsightsLoggerConfig} to\n\t * determine whether an event should be sent or not.\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tif (this.shouldSendEvent(event)) {\n\t\t\tthis.baseLoggingClient.trackEvent({\n\t\t\t\tname: event.eventName,\n\t\t\t\tproperties: event,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate shouldSendEvent(event: ITelemetryBaseEvent): boolean {\n\t\t// No events should be sent by default in \"inclusive\" mode, and all events should be\n\t\t// sent by default in \"exclusive\" mode.\n\t\tlet shouldSendEvent = this.config.filtering.mode === \"inclusive\" ? false : true;\n\t\tif (this.doesEventMatchFilter(event)) {\n\t\t\t// If the event does match a filter, in \"inclusive\" filter mode that means it should\n\t\t\t// be sent (included). In \"exclusive\" mode the opposite is true.\n\t\t\tshouldSendEvent = this.config.filtering.mode === \"inclusive\" ? true : false;\n\t\t}\n\t\treturn shouldSendEvent;\n\t}\n\n\t/**\n\t * Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.\n\t *\n\t * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n\t * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n\t *\n\t * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n\t *\n\t * 3. If only `categories` or a `namespace` is provided, the event should match either one of them.\n\t *\n\t * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n\t *\n\t * @param event - The telemetry event to check against the filters.\n\t *\n\t * @returns `true` if the event matches any filter, otherwise `false`.\n\t */\n\tprivate doesEventMatchFilter(event: ITelemetryBaseEvent): boolean {\n\t\tfor (const filter of this.config.filtering.filters ?? []) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (event.eventName.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t// Found matching namespace pattern, since filters are ordered in most specific first,\n\t\t\t\t\t// this is the most specific, relevant matching filter for the event.\n\n\t\t\t\t\t// By default, if no categories are defined then any category is a valid match.\n\t\t\t\t\tlet doesFilterCategoriesMatch = true;\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"categories\" in filter &&\n\t\t\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\t\t\tfilter.categories.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdoesFilterCategoriesMatch = false;\n\t\t\t\t\t\tconst matchingCategory = filter.categories.find(\n\t\t\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdoesFilterCategoriesMatch = matchingCategory ? true : false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\t\t// The most specific, relevant filter matches so no need to attempt to evaluate against other filters\n\t\t\t\t\t\t// as long as the events namespace does not match any defined namespace exception.\n\t\t\t\t\t\tif (filter.namespacePatternExceptions !== undefined) {\n\t\t\t\t\t\t\tfor (const patternException of filter.namespacePatternExceptions) {\n\t\t\t\t\t\t\t\tif (event.eventName.startsWith(patternException)) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Filter only has categories defined\n\t\t\telse if (\n\t\t\t\t\"categories\" in filter &&\n\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\tfilter.categories.length > 0\n\t\t\t) {\n\t\t\t\tconst doesFilterCategoriesMatch = filter.categories.find(\n\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t);\n\n\t\t\t\t// This filter specified no namespaces but it has a category match.\n\t\t\t\t// Since filters are ordered by most specific first, we know that no previous\n\t\t\t\t// filters with namespaces matched so we can return true.\n\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.\n\t *\n\t * @throws An Error if there are two filters with duplicate namespace patterns or a filter with a pattern exception that is not a child of the parent pattern.\n\t */\n\tprivate validateFilters(filters: TelemetryFilter[]): void {\n\t\tconst uniqueFilterNamespaces = new Set<string>();\n\n\t\tfor (const filter of filters) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (uniqueFilterNamespaces.has(filter.namespacePattern)) {\n\t\t\t\t\tthrow new Error(\"Cannot have duplicate namespace pattern filters\");\n\t\t\t\t} else {\n\t\t\t\t\tuniqueFilterNamespaces.add(filter.namespacePattern);\n\t\t\t\t}\n\n\t\t\t\tfor (const patternException of filter.namespacePatternExceptions ?? []) {\n\t\t\t\t\tif (!patternException.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\"categories\" in filter && filter.categories !== undefined) {\n\t\t\t\t// These are filters that only contain \"categories\". For the purpose of this validation logic, we are treating filters\n\t\t\t\t// that does not contain a defined namespace as the the same as a blank \"\" namespace pattern (which will match any event).\n\t\t\t\tif (uniqueFilterNamespaces.has(\"\")) {\n\t\t\t\t\tthrow new Error(\"Cannot have multiple filters that only define categories\");\n\t\t\t\t}\n\t\t\t\tuniqueFilterNamespaces.add(\"\");\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid filter does not have either a namespace or a category.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n *\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),\n * or else logging will not occur.\n *\n * @beta\n */\nexport function createLogger(\n\tclient: ApplicationInsights,\n\tconfig?: FluidAppInsightsLoggerConfig,\n): ITelemetryBaseLogger {\n\treturn new FluidAppInsightsLogger(client, config);\n}\n"]}
1
+ {"version":3,"file":"fluidAppInsightsLogger.js","sourceRoot":"","sources":["../src/fluidAppInsightsLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport type { ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\n/**\n * The categories FF uses when instrumenting the code.\n *\n * generic - Informational log event\n *\n * error - Error log event, ideally 0 of these are logged during a session\n *\n * performance - Includes duration, and often has _start, _end, or _cancel suffixes for activity tracking\n * @beta\n */\nexport type TelemetryEventCategory = \"generic\" | \"error\" | \"performance\";\n\n/**\n * The configuration object for creating the logger via {@link createLogger}.\n * @beta\n */\nexport interface FluidAppInsightsLoggerConfig {\n\t/**\n\t * This Configuration defines how filtering will be applied to Fluid telemetry events flowing through the logger.\n\t * This determines which events will be sent to Azure App Insights.\n\t */\n\tfiltering: {\n\t\t/**\n\t\t * Determines whether all telemetry events are sent or not sent by default and whether filters will exclude matching telemetry events or include them.\n\t\t *\n\t\t * \"inclusive\" mode means all logs are NOT SENT by default and only the events that match at least one or more specified filters WILL be sent (included).\n\t\t *\n\t\t * \"exclusive\" mode means all logs ARE SENT by default and only the events that match at least one or more specified filters WILL NOT be sent (excluded).\n\t\t */\n\t\tmode: \"inclusive\" | \"exclusive\";\n\t\t/**\n\t\t * Controls the filtering of log events.\n\t\t *\n\t\t * @remarks Leaving this undefined will be treated as an empty array.\n\t\t *\n\t\t * In order for the filters to be valid they must meet the following conditions:\n\t\t *\n\t\t * 1. There must not be any two filters with the same `namespacePattern`.\n\t\t *\n\t\t * 2. All {@link NamespaceFilter} must not have any defined `namespacePatternException` that is not a child of the parent `namespacePattern`\n\t\t */\n\t\tfilters?: TelemetryFilter[];\n\t};\n}\n\n/**\n * A filter used to match against the category of a telemetry event\n * @beta\n */\nexport interface CategoryFilter {\n\t/**\n\t * The categories of telemetry events that this filter applies to\n\t */\n\tcategories: TelemetryEventCategory[];\n}\n\n/**\n * A filter used to match against the namespaces of a telemetry event\n * @beta\n */\nexport interface NamespaceFilter {\n\t/**\n\t * The namespace pattern to filter telemetry events.\n\t *\n\t * @remarks This will match namespaces that start with the given string. It is not a Regex pattern.\n\t * @example\n\t * \"perf:latency\" will match any namespace starting with \"perf:latency\"\n\t */\n\tnamespacePattern: string;\n\t/**\n\t * A list of namespace patterns to explicitly exclude from the filter.\n\t *\n\t * @example\n\t * If you have a namespacePattern of \"perf:latency\" but want to exclude\n\t * events from \"perf:latency:ops\", you would add \"perf:latency:ops\" to this list.\n\t */\n\tnamespacePatternExceptions?: Set<string>;\n}\n\n/**\n * Object used with an {@link FluidAppInsightsLoggerConfig}\n * to define a filter with logic for matching it to telemetry events.\n * Filters can include either a category, namespace or both types of filters; a valid filter must have at least one defined.\n * Not definining the `categories` filter array is the same as providing an array with all possible categories.\n *\n * Events must satisify the following rules for a telemetry filter:\n *\n * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n *\n * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n *\n * 3. If only `categories` or a `namespace` is provided, the event should just match the with whatever was defined.\n *\n * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n * @example\n * With the following configuration, an event `{ namespace: \"A.B.C\", categories: [\"generic\"] }` will not be sent despite matching the first, less specific filter because it did not match the second filter which was the most relevant and specific\n * ```\n * const logger = new FluidAppInsightsLogger(appInsightsClient, {\n *\t\t\tfiltering: {\n *\t\t\t\tmode: \"inclusive\",\n *\t\t\t\tfilters: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B\",\n *\t\t\t\t\t\tcategories: [\"generic\", \"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t\t{\n *\t\t\t\t\t\tnamespacePattern: \"A:B:C\",\n *\t\t\t\t\t\tcategories: [\"error\"],\n *\t\t\t\t\t},\n *\t\t\t\t],\n *\t\t\t},\n *\t\t});\n * ```\n * @beta\n */\nexport type TelemetryFilter =\n\t| CategoryFilter\n\t| NamespaceFilter\n\t| (CategoryFilter & NamespaceFilter);\n\n/**\n * An implementation of {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n * or else logging will not occur.\n *\n * @sealed\n */\nclass FluidAppInsightsLogger implements ITelemetryBaseLogger {\n\t/**\n\t * The Azure ApplicationInsights client utilized by this logger.\n\t * The ApplicationInsights instance MUST be initialized with client.loadAppInsights()\n\t * or else logging will not occur.\n\t */\n\tprivate readonly baseLoggingClient: ApplicationInsights;\n\tprivate readonly config: FluidAppInsightsLoggerConfig;\n\tpublic constructor(client: ApplicationInsights, config?: FluidAppInsightsLoggerConfig) {\n\t\tthis.baseLoggingClient = client;\n\t\t// Deep copy config to prevent issues if user mutates the object they passed in\n\t\tthis.config = config\n\t\t\t? structuredClone(config)\n\t\t\t: {\n\t\t\t\t\tfiltering: {\n\t\t\t\t\t\tmode: \"exclusive\",\n\t\t\t\t\t\tfilters: [],\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\tif (this.config.filtering.filters) {\n\t\t\tthis.validateFilters(this.config.filtering.filters);\n\t\t\t// Sort filters by longest namespace first.\n\t\t\tthis.config.filtering.filters.sort((a, b) => {\n\t\t\t\tconst namespaceALength =\n\t\t\t\t\t\"namespacePattern\" in a && a.namespacePattern !== undefined\n\t\t\t\t\t\t? a.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\tconst namespaceBLength =\n\t\t\t\t\t\"namespacePattern\" in b && b.namespacePattern !== undefined\n\t\t\t\t\t\t? b.namespacePattern.length\n\t\t\t\t\t\t: 0;\n\t\t\t\treturn namespaceBLength - namespaceALength;\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Routes Fluid telemetry events to the trackEvent App Insights API.\n\t * This method also uses the provided {@link FluidAppInsightsLoggerConfig} to\n\t * determine whether an event should be sent or not.\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tif (this.shouldSendEvent(event)) {\n\t\t\tthis.baseLoggingClient.trackEvent({\n\t\t\t\tname: event.eventName,\n\t\t\t\tproperties: event,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate shouldSendEvent(event: ITelemetryBaseEvent): boolean {\n\t\t// No events should be sent by default in \"inclusive\" mode, and all events should be\n\t\t// sent by default in \"exclusive\" mode.\n\t\tlet shouldSendEvent = this.config.filtering.mode === \"inclusive\" ? false : true;\n\t\tif (this.doesEventMatchFilter(event)) {\n\t\t\t// If the event does match a filter, in \"inclusive\" filter mode that means it should\n\t\t\t// be sent (included). In \"exclusive\" mode the opposite is true.\n\t\t\tshouldSendEvent = this.config.filtering.mode === \"inclusive\" ? true : false;\n\t\t}\n\t\treturn shouldSendEvent;\n\t}\n\n\t/**\n\t * Checks if a given telemetry event conforms to any of the provided {@link TelemetryFilter} rules.\n\t *\n\t * 1. The event must match the requirements of the most specific relevant filter to it. This takes precedence over a more generic filter.\n\t * The less categories and longer the namespace within a filter, the more specific it is. Definining no categories is equivalant to defining all categories.\n\t *\n\t * 2. If a {@link TelemetryFilter} specifies both `categories` and a `namespace`, the event must match both.\n\t *\n\t * 3. If only `categories` or a `namespace` is provided, the event should match either one of them.\n\t *\n\t * 4. If a `namespace` pattern exception is specified in the {@link TelemetryFilter}, the event should not match the exception pattern.\n\t *\n\t * @param event - The telemetry event to check against the filters.\n\t *\n\t * @returns `true` if the event matches any filter, otherwise `false`.\n\t */\n\tprivate doesEventMatchFilter(event: ITelemetryBaseEvent): boolean {\n\t\tfor (const filter of this.config.filtering.filters ?? []) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (event.eventName.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t// Found matching namespace pattern, since filters are ordered in most specific first,\n\t\t\t\t\t// this is the most specific, relevant matching filter for the event.\n\n\t\t\t\t\t// By default, if no categories are defined then any category is a valid match.\n\t\t\t\t\tlet doesFilterCategoriesMatch = true;\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"categories\" in filter &&\n\t\t\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\t\t\tfilter.categories.length > 0\n\t\t\t\t\t) {\n\t\t\t\t\t\tdoesFilterCategoriesMatch = false;\n\t\t\t\t\t\tconst matchingCategory = filter.categories.find(\n\t\t\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdoesFilterCategoriesMatch = matchingCategory ? true : false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\t\t// The most specific, relevant filter matches so no need to attempt to evaluate against other filters\n\t\t\t\t\t\t// as long as the events namespace does not match any defined namespace exception.\n\t\t\t\t\t\tif (filter.namespacePatternExceptions !== undefined) {\n\t\t\t\t\t\t\tfor (const patternException of filter.namespacePatternExceptions) {\n\t\t\t\t\t\t\t\tif (event.eventName.startsWith(patternException)) {\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Filter only has categories defined\n\t\t\telse if (\n\t\t\t\t\"categories\" in filter &&\n\t\t\t\tfilter.categories !== undefined &&\n\t\t\t\tfilter.categories.length > 0\n\t\t\t) {\n\t\t\t\tconst doesFilterCategoriesMatch = filter.categories.find(\n\t\t\t\t\t(category) => category === event.category,\n\t\t\t\t);\n\n\t\t\t\t// This filter specified no namespaces but it has a category match.\n\t\t\t\t// Since filters are ordered by most specific first, we know that no previous\n\t\t\t\t// filters with namespaces matched so we can return true.\n\t\t\t\tif (doesFilterCategoriesMatch) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Checks an array of telemetry filters for any issues, merges redundant filters, and returns a fully validated array.\n\t *\n\t * @throws An Error if there are two filters with duplicate namespace patterns or a filter with a pattern exception that is not a child of the parent pattern.\n\t */\n\tprivate validateFilters(filters: TelemetryFilter[]): void {\n\t\tconst uniqueFilterNamespaces = new Set<string>();\n\n\t\tfor (const filter of filters) {\n\t\t\tif (\"namespacePattern\" in filter && filter.namespacePattern !== undefined) {\n\t\t\t\tif (uniqueFilterNamespaces.has(filter.namespacePattern)) {\n\t\t\t\t\tthrow new Error(\"Cannot have duplicate namespace pattern filters\");\n\t\t\t\t} else {\n\t\t\t\t\tuniqueFilterNamespaces.add(filter.namespacePattern);\n\t\t\t\t}\n\n\t\t\t\tfor (const patternException of filter.namespacePatternExceptions ?? []) {\n\t\t\t\t\tif (!patternException.startsWith(filter.namespacePattern)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"Cannot have a namespace pattern exception that is not a child of the parent namespace\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\"categories\" in filter && filter.categories !== undefined) {\n\t\t\t\t// These are filters that only contain \"categories\". For the purpose of this validation logic, we are treating filters\n\t\t\t\t// that does not contain a defined namespace as the the same as a blank \"\" namespace pattern (which will match any event).\n\t\t\t\tif (uniqueFilterNamespaces.has(\"\")) {\n\t\t\t\t\tthrow new Error(\"Cannot have multiple filters that only define categories\");\n\t\t\t\t}\n\t\t\t\tuniqueFilterNamespaces.add(\"\");\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid filter does not have either a namespace or a category.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Creates an {@link @fluidframework/core-interfaces#ITelemetryBaseLogger}\n * that routes Fluid telemetry events to Azure App Insights using the App Insights trackEvent API.\n *\n * The provided ApplicationInsights instance MUST be initialized with client.loadAppInsights(),\n * or else logging will not occur.\n *\n * @beta\n */\nexport function createLogger(\n\tclient: ApplicationInsights,\n\tconfig?: FluidAppInsightsLoggerConfig,\n): ITelemetryBaseLogger {\n\treturn new FluidAppInsightsLogger(client, config);\n}\n"]}
package/lib/public.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outDir ./lib" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/app-insights-logger",
3
- "version": "2.118.1",
3
+ "version": "3.0.1",
4
4
  "description": "Contains a Fluid logging client that sends telemetry events to Azure App Insights",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -14,46 +14,32 @@
14
14
  "type": "module",
15
15
  "exports": {
16
16
  ".": {
17
- "import": {
18
- "types": "./lib/public.d.ts",
19
- "default": "./lib/index.js"
20
- },
21
- "require": {
22
- "types": "./dist/public.d.ts",
23
- "default": "./dist/index.js"
17
+ "types": "./lib/public.d.ts",
18
+ "default": "./lib/index.js",
19
+ "internal-entrypoint-generation": {
20
+ "types": "./dist/public.d.ts"
24
21
  }
25
22
  },
26
23
  "./beta": {
27
- "import": {
28
- "types": "./lib/beta.d.ts",
29
- "default": "./lib/index.js"
30
- },
31
- "require": {
32
- "types": "./dist/beta.d.ts",
33
- "default": "./dist/index.js"
24
+ "types": "./lib/beta.d.ts",
25
+ "default": "./lib/index.js",
26
+ "internal-entrypoint-generation": {
27
+ "types": "./dist/beta.d.ts"
34
28
  }
35
29
  },
36
30
  "./internal": {
37
- "import": {
38
- "types": "./lib/index.d.ts",
39
- "default": "./lib/index.js"
40
- },
41
- "require": {
42
- "types": "./dist/index.d.ts",
43
- "default": "./dist/index.js"
44
- }
31
+ "types": "./lib/index.d.ts",
32
+ "default": "./lib/index.js"
45
33
  }
46
34
  },
47
- "main": "lib/index.js",
48
- "types": "lib/public.d.ts",
49
35
  "dependencies": {
50
- "@fluidframework/core-interfaces": "~2.118.1",
36
+ "@fluidframework/core-interfaces": "~3.0.1",
51
37
  "@microsoft/applicationinsights-web": "^2.8.11"
52
38
  },
53
39
  "devDependencies": {
54
40
  "@arethetypeswrong/cli": "^0.18.5",
55
41
  "@biomejs/biome": "~2.4.5",
56
- "@fluid-internal/mocha-test-setup": "~2.118.1",
42
+ "@fluid-internal/mocha-test-setup": "~3.0.1",
57
43
  "@fluid-tools/build-cli": "^0.67.0",
58
44
  "@fluidframework/app-insights-logger-previous": "npm:@fluidframework/app-insights-logger@2.116.0",
59
45
  "@fluidframework/build-common": "^2.0.3",
@@ -67,7 +53,7 @@
67
53
  "cross-env": "^10.1.0",
68
54
  "eslint": "~9.39.1",
69
55
  "eslint-config-prettier": "~10.1.8",
70
- "eslint-plugin-jest": "~29.5.0",
56
+ "eslint-plugin-jest": "~29.16.0",
71
57
  "eslint-plugin-react": "~7.37.5",
72
58
  "eslint-plugin-react-hooks": "~7.0.1",
73
59
  "jiti": "^2.6.1",
@@ -75,7 +61,7 @@
75
61
  "rimraf": "^6.1.3",
76
62
  "sinon": "^18.0.1",
77
63
  "tslib": "^2.8.1",
78
- "typescript": "~5.4.5"
64
+ "typescript": "~6.0.3"
79
65
  },
80
66
  "fluid": {
81
67
  "browser": {
@@ -93,17 +79,19 @@
93
79
  },
94
80
  "scripts": {
95
81
  "build": "fluid-build . --task build",
82
+ "build:api-reports": "api-extractor run --local --config api-extractor/api-extractor-report.json",
83
+ "build:cjs": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../../common/build/build-common/src/cjs/package.json ./dist",
96
84
  "build:commonjs": "fluid-build . --task commonjs",
97
85
  "build:compile": "fluid-build . --task compile",
98
- "build:docs": "api-extractor run --local",
86
+ "build:docs": "api-extractor run --local --config api-extractor/api-extractor-model.json",
99
87
  "build:entrypoints": "fluid-build . --task build:entrypoints",
100
88
  "build:entrypoints:cjs": "flub generate entrypoints --resolutionConditions require --outDir ./dist",
101
- "build:entrypoints:esm": "flub generate entrypoints --outDir ./lib --node10TypeCompat",
102
- "build:esnext": "tsc --project ./tsconfig.json",
89
+ "build:entrypoints:esm": "flub generate entrypoints --outDir ./lib",
90
+ "build:esm": "tsc --project ./tsconfig.json",
103
91
  "build:test": "concurrently npm:build:test:esm npm:build:test:cjs",
104
92
  "build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
105
93
  "build:test:esm": "tsc --project ./src/test/tsconfig.json",
106
- "check:are-the-types-wrong": "attw --pack .",
94
+ "check:are-the-types-wrong": "attw --pack . --profile esm-only",
107
95
  "check:biome": "biome check .",
108
96
  "check:exports": "concurrently \"npm:check:exports:*\"",
109
97
  "check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
@@ -112,7 +100,9 @@
112
100
  "check:exports:esm:beta": "api-extractor run --config api-extractor/api-extractor-lint-beta.esm.json",
113
101
  "check:exports:esm:public": "api-extractor run --config api-extractor/api-extractor-lint-public.esm.json",
114
102
  "check:format": "npm run check:biome",
115
- "ci:build:docs": "api-extractor run",
103
+ "check:types:inexactOptionalPropertyTypes": "tsc --project ./tsconfig.json --noEmit --exactOptionalPropertyTypes false --skipLibCheck --emitDeclarationOnly false --tsBuildInfoFile ./tsconfig.inexactOptionalPropertyTypes.tsbuildinfo",
104
+ "ci:build:api-reports": "api-extractor run --config api-extractor/api-extractor-report.json",
105
+ "ci:build:docs": "api-extractor run --config api-extractor/api-extractor-model.json",
116
106
  "clean": "rimraf --glob _api-extractor-temp coverage dist lib {alpha,beta,internal,legacy}.d.ts nyc \"**/*.tsbuildinfo\" \"**/*.build.log\"",
117
107
  "eslint": "eslint --quiet src",
118
108
  "eslint:fix": "eslint --quiet src --fix",
@@ -127,7 +117,6 @@
127
117
  "test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS mocha",
128
118
  "test:mocha:esm": "mocha",
129
119
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
130
- "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../../common/build/build-common/src/cjs/package.json ./dist",
131
120
  "typetests:gen": "flub generate typetests --dir . -v"
132
121
  }
133
122
  }
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../../../common/build/build-common/tsconfig.node16.json",
2
+ "extends": "../../../../common/build/build-common/tsconfig.node20.json",
3
3
  "include": ["src/**/*"],
4
4
  "exclude": ["src/test/**/*"],
5
5
  "compilerOptions": {
package/beta.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/beta.js";
package/internal.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/index.js";