@fluidframework/debugger 2.90.0 → 2.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/fluidDebugger.d.ts +1 -1
  3. package/dist/fluidDebugger.d.ts.map +1 -1
  4. package/dist/fluidDebugger.js.map +1 -1
  5. package/dist/fluidDebuggerController.d.ts +4 -3
  6. package/dist/fluidDebuggerController.d.ts.map +1 -1
  7. package/dist/fluidDebuggerController.js +4 -4
  8. package/dist/fluidDebuggerController.js.map +1 -1
  9. package/dist/fluidDebuggerUi.d.ts +1 -1
  10. package/dist/fluidDebuggerUi.d.ts.map +1 -1
  11. package/dist/fluidDebuggerUi.js +25 -25
  12. package/dist/fluidDebuggerUi.js.map +1 -1
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/legacy.d.ts +1 -1
  17. package/dist/messageSchema.d.ts +1 -1
  18. package/dist/messageSchema.d.ts.map +1 -1
  19. package/dist/messageSchema.js.map +1 -1
  20. package/dist/public.d.ts +1 -1
  21. package/dist/sanitize.js.map +1 -1
  22. package/dist/sanitizer.d.ts +1 -1
  23. package/dist/sanitizer.d.ts.map +1 -1
  24. package/dist/sanitizer.js +52 -50
  25. package/dist/sanitizer.js.map +1 -1
  26. package/eslint.config.mts +13 -4
  27. package/internal.d.ts +1 -1
  28. package/legacy.d.ts +1 -1
  29. package/lib/fluidDebugger.d.ts +1 -1
  30. package/lib/fluidDebugger.d.ts.map +1 -1
  31. package/lib/fluidDebugger.js.map +1 -1
  32. package/lib/fluidDebuggerController.d.ts +4 -3
  33. package/lib/fluidDebuggerController.d.ts.map +1 -1
  34. package/lib/fluidDebuggerController.js +4 -4
  35. package/lib/fluidDebuggerController.js.map +1 -1
  36. package/lib/fluidDebuggerUi.d.ts +1 -1
  37. package/lib/fluidDebuggerUi.d.ts.map +1 -1
  38. package/lib/fluidDebuggerUi.js +25 -25
  39. package/lib/fluidDebuggerUi.js.map +1 -1
  40. package/lib/index.d.ts +2 -2
  41. package/lib/index.d.ts.map +1 -1
  42. package/lib/index.js.map +1 -1
  43. package/lib/legacy.d.ts +1 -1
  44. package/lib/messageSchema.d.ts +1 -1
  45. package/lib/messageSchema.d.ts.map +1 -1
  46. package/lib/messageSchema.js.map +1 -1
  47. package/lib/public.d.ts +1 -1
  48. package/lib/sanitize.js.map +1 -1
  49. package/lib/sanitizer.d.ts +1 -1
  50. package/lib/sanitizer.d.ts.map +1 -1
  51. package/lib/sanitizer.js +52 -50
  52. package/lib/sanitizer.js.map +1 -1
  53. package/package.json +14 -23
  54. package/src/fluidDebugger.ts +1 -1
  55. package/src/fluidDebuggerController.ts +10 -8
  56. package/src/fluidDebuggerUi.ts +26 -26
  57. package/src/index.ts +2 -2
  58. package/src/messageSchema.ts +1 -1
  59. package/src/sanitize.ts +1 -1
  60. package/src/sanitizer.ts +49 -47
  61. package/tsconfig.json +1 -1
package/dist/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" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outDir ./dist" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export {}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH;;;;;;;;;;;;;GAaG;AAEH,sDAAyB;AACzB,gEAAmC;AAInC,iDAA2C;AAE3C,SAAS,UAAU;IAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CACV,iGAAiG,CACjG,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,SAAkB,EAAE,MAAe;IACrE,MAAM,KAAK,GAAG,iBAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAgC,CAAC;IAElE,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAE3C,iBAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,IAAI;IACZ,IAAI,sBAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,sBAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,IAAI,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACpC,4DAA4D;YAC5D,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;IACD,UAAU,EAAE,CAAC;AACd,CAAC;AAED,IAAI,EAAE,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport fs from \"node:fs\";\nimport process from \"node:process\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { Sanitizer } from \"./sanitizer.js\";\n\nfunction printUsage(): void {\n\tconsole.log(\"Usage:\");\n\tconsole.log(\" node sanitize [--full | --noBail] <input>\");\n\tconsole.log(\"Where\");\n\tconsole.log(\" [--full] - scrub fully (result cannot be loaded in Fluid Preview)\");\n\tconsole.log(\n\t\t\" [--noBail] - don't bail out when encountering an unknown message format (it won't be scrubbed\",\n\t);\n\tconsole.log(\" <input> - file path to message.json - file downloaded by FluidFetch tool\");\n\tconsole.log(\"Note: <input> is sanitized in place\");\n\tprocess.exit(-1);\n}\n\nfunction Sanitize(msgPath: string, fullScrub: boolean, noBail: boolean): void {\n\tconst input = fs.readFileSync(msgPath, { encoding: \"utf-8\" });\n\tconst messages = JSON.parse(input) as ISequencedDocumentMessage[];\n\n\tconst sanitizer = new Sanitizer(messages, fullScrub, noBail, true);\n\tconst cleanMessages = sanitizer.sanitize();\n\n\tfs.writeFileSync(msgPath, JSON.stringify(cleanMessages, undefined, 2));\n\n\tconsole.log(\"Done.\");\n}\n\nfunction main(): void {\n\tif (process.argv.length === 3) {\n\t\t// Non null asserting here because of the length check above\n\t\treturn Sanitize(process.argv[2]!, false, false);\n\t}\n\tif (process.argv.length === 4) {\n\t\t// Non null asserting here because of the length check above\n\t\tif (process.argv[2] === \"--full\") {\n\t\t\treturn Sanitize(process.argv[3]!, true, false);\n\t\t}\n\t\tif (process.argv[2] === \"--noBail\") {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\treturn Sanitize(process.argv[3]!, false, true);\n\t\t}\n\t}\n\tprintUsage();\n}\n\nmain();\n"]}
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAEH;;;;;;;;;;;;;GAaG;AAEH,sDAAyB;AACzB,gEAAmC;AAInC,iDAA2C;AAE3C,SAAS,UAAU;IAClB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CACV,iGAAiG,CACjG,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,SAAkB,EAAE,MAAe;IACrE,MAAM,KAAK,GAAG,iBAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAgC,CAAC;IAElE,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAE3C,iBAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,IAAI;IACZ,IAAI,sBAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,sBAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,IAAI,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YACpC,4DAA4D;YAC5D,OAAO,QAAQ,CAAC,sBAAO,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;IACD,UAAU,EAAE,CAAC;AACd,CAAC;AAED,IAAI,EAAE,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport fs from \"node:fs\";\nimport process from \"node:process\";\n\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { Sanitizer } from \"./sanitizer.js\";\n\nfunction printUsage(): void {\n\tconsole.log(\"Usage:\");\n\tconsole.log(\" node sanitize [--full | --noBail] <input>\");\n\tconsole.log(\"Where\");\n\tconsole.log(\" [--full] - scrub fully (result cannot be loaded in Fluid Preview)\");\n\tconsole.log(\n\t\t\" [--noBail] - don't bail out when encountering an unknown message format (it won't be scrubbed\",\n\t);\n\tconsole.log(\" <input> - file path to message.json - file downloaded by FluidFetch tool\");\n\tconsole.log(\"Note: <input> is sanitized in place\");\n\tprocess.exit(-1);\n}\n\nfunction Sanitize(msgPath: string, fullScrub: boolean, noBail: boolean): void {\n\tconst input = fs.readFileSync(msgPath, { encoding: \"utf-8\" });\n\tconst messages = JSON.parse(input) as ISequencedDocumentMessage[];\n\n\tconst sanitizer = new Sanitizer(messages, fullScrub, noBail, true);\n\tconst cleanMessages = sanitizer.sanitize();\n\n\tfs.writeFileSync(msgPath, JSON.stringify(cleanMessages, undefined, 2));\n\n\tconsole.log(\"Done.\");\n}\n\nfunction main(): void {\n\tif (process.argv.length === 3) {\n\t\t// Non null asserting here because of the length check above\n\t\treturn Sanitize(process.argv[2]!, false, false);\n\t}\n\tif (process.argv.length === 4) {\n\t\t// Non null asserting here because of the length check above\n\t\tif (process.argv[2] === \"--full\") {\n\t\t\treturn Sanitize(process.argv[3]!, true, false);\n\t\t}\n\t\tif (process.argv[2] === \"--noBail\") {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\treturn Sanitize(process.argv[3]!, false, true);\n\t\t}\n\t}\n\tprintUsage();\n}\n\nmain();\n"]}
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
5
+ import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
6
6
  import * as Validator from "jsonschema";
7
7
  declare enum TextType {
8
8
  Generic = 0,
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../src/sanitizer.ts"],"names":[],"mappings":"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"}
package/dist/sanitizer.js CHANGED
@@ -106,8 +106,8 @@ class ChunkedOpProcessor {
106
106
  parsed = parsed.contents;
107
107
  }
108
108
  }
109
- catch (e) {
110
- this.debugMsg(e);
109
+ catch (error) {
110
+ this.debugMsg(error);
111
111
  this.debugMsg(message.contents);
112
112
  }
113
113
  this.validateSchemaFn(parsed, messageSchema_js_1.chunkedOpContentsSchema);
@@ -129,9 +129,9 @@ class ChunkedOpProcessor {
129
129
  try {
130
130
  return JSON.parse(contentsString);
131
131
  }
132
- catch (e) {
132
+ catch (error) {
133
133
  this.debugMsg(contentsString);
134
- this.debugMsg(e);
134
+ this.debugMsg(error);
135
135
  return undefined;
136
136
  }
137
137
  }
@@ -149,9 +149,9 @@ class ChunkedOpProcessor {
149
149
  stringified = JSON.stringify(contents);
150
150
  (0, internal_1.assert)(stringified.length <= this.concatenatedLength, 0x089 /* "Stringified length of chunk contents > total starting length" */);
151
151
  }
152
- catch (e) {
153
- this.debugMsg(e);
154
- throw e;
152
+ catch (error) {
153
+ this.debugMsg(error);
154
+ throw error;
155
155
  }
156
156
  for (let i = 0; i < this.messages.length; i++) {
157
157
  const substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);
@@ -173,8 +173,8 @@ class ChunkedOpProcessor {
173
173
  stringifiedParsedContents = JSON.stringify(parsedContents);
174
174
  }
175
175
  }
176
- catch (e) {
177
- this.debugMsg(e);
176
+ catch (error) {
177
+ this.debugMsg(error);
178
178
  }
179
179
  message.contents = stringifiedParsedContents;
180
180
  }
@@ -188,7 +188,7 @@ class ChunkedOpProcessor {
188
188
  this.concatenatedLength = 0;
189
189
  }
190
190
  isPendingProcessing() {
191
- return this.messages.length !== 0;
191
+ return this.messages.length > 0;
192
192
  }
193
193
  }
194
194
  class Sanitizer {
@@ -255,9 +255,9 @@ class Sanitizer {
255
255
  getRandomText(len) {
256
256
  let str = "";
257
257
  while (str.length < len) {
258
- str = str + Math.random().toString(36).substring(2);
258
+ str = str + Math.random().toString(36).slice(2);
259
259
  }
260
- return str.substr(0, len);
260
+ return str.slice(0, Math.max(0, len));
261
261
  }
262
262
  /**
263
263
  * Replace text with garbage. FluidObject types are not replaced when not under
@@ -306,7 +306,7 @@ class Sanitizer {
306
306
  return input;
307
307
  }
308
308
  const keys = Object.keys(input);
309
- keys.forEach((key) => {
309
+ for (const key of keys) {
310
310
  if (this.fullScrub || !excludedKeys.has(key)) {
311
311
  const value = input[key];
312
312
  if (typeof value === "string") {
@@ -319,7 +319,7 @@ class Sanitizer {
319
319
  input[key] = this.replaceObject(value, excludedKeys);
320
320
  }
321
321
  }
322
- });
322
+ }
323
323
  return input;
324
324
  }
325
325
  /**
@@ -350,26 +350,23 @@ class Sanitizer {
350
350
  }
351
351
  try {
352
352
  let data = JSON.parse(message.data);
353
- if (!this.objectMatchesSchema(data, messageSchema_js_1.joinDataSchema)) {
354
- data = this.replaceAny(data);
355
- }
356
- else {
353
+ if (this.objectMatchesSchema(data, messageSchema_js_1.joinDataSchema)) {
357
354
  const user = data.detail.user;
358
355
  user.id = this.replaceText(user.id, TextType.Email);
359
356
  user.email = this.replaceText(user.email, TextType.Email);
360
357
  user.name = this.replaceText(user.name, TextType.Name);
361
358
  }
359
+ else {
360
+ data = this.replaceAny(data);
361
+ }
362
362
  message.data = JSON.stringify(data);
363
363
  }
364
- catch (e) {
365
- this.debugMsg(e);
364
+ catch (error) {
365
+ this.debugMsg(error);
366
366
  }
367
367
  }
368
368
  fixPropose(message) {
369
- if (!this.objectMatchesSchema(message.contents, messageSchema_js_1.proposeContentsSchema)) {
370
- message.contents = this.replaceAny(message.contents);
371
- }
372
- else {
369
+ if (this.objectMatchesSchema(message.contents, messageSchema_js_1.proposeContentsSchema)) {
373
370
  if (typeof message.contents === "string") {
374
371
  try {
375
372
  const data = JSON.parse(message.contents);
@@ -383,8 +380,8 @@ class Sanitizer {
383
380
  }
384
381
  }
385
382
  }
386
- catch (e) {
387
- this.debugMsg(e);
383
+ catch (error) {
384
+ this.debugMsg(error);
388
385
  }
389
386
  }
390
387
  else {
@@ -393,9 +390,12 @@ class Sanitizer {
393
390
  }
394
391
  }
395
392
  }
393
+ else {
394
+ message.contents = this.replaceAny(message.contents);
395
+ }
396
396
  }
397
397
  fixAttachEntries(entries) {
398
- entries.forEach((element) => {
398
+ for (const element of entries) {
399
399
  // Tree type
400
400
  if (element.value.entries) {
401
401
  this.fixAttachEntries(element.value.entries);
@@ -409,11 +409,11 @@ class Sanitizer {
409
409
  element.value.contents = JSON.stringify(data);
410
410
  }
411
411
  }
412
- catch (e) {
413
- this.debugMsg(e);
412
+ catch (error) {
413
+ this.debugMsg(error);
414
414
  }
415
415
  }
416
- });
416
+ }
417
417
  }
418
418
  /**
419
419
  * Fix the content of an attach in place
@@ -421,16 +421,16 @@ class Sanitizer {
421
421
  */
422
422
  fixAttachContents(contents) {
423
423
  (0, internal_1.assert)(typeof contents === "object", 0x08b /* "Unexpected type on contents for fix of an attach!" */);
424
- if (!this.objectMatchesSchema(contents, messageSchema_js_1.attachContentsSchema)) {
425
- this.replaceObject(contents);
426
- }
427
- else {
424
+ if (this.objectMatchesSchema(contents, messageSchema_js_1.attachContentsSchema)) {
428
425
  if (this.fullScrub) {
429
426
  contents.id = this.replaceText(contents.id, TextType.FluidObject);
430
427
  contents.type = this.replaceText(contents.type, TextType.FluidObject);
431
428
  }
432
429
  this.fixAttachEntries(contents.snapshot.entries);
433
430
  }
431
+ else {
432
+ this.replaceObject(contents);
433
+ }
434
434
  }
435
435
  /**
436
436
  * Fix an attach message at the root level or a ContainerMessageType attach. Attach
@@ -450,8 +450,8 @@ class Sanitizer {
450
450
  this.fixAttachContents(data);
451
451
  message.contents = JSON.stringify(data);
452
452
  }
453
- catch (e) {
454
- this.debugMsg(e);
453
+ catch (error) {
454
+ this.debugMsg(error);
455
455
  return;
456
456
  }
457
457
  }
@@ -474,10 +474,7 @@ class Sanitizer {
474
474
  */
475
475
  fixOpContentsObject(contents) {
476
476
  // do replacement
477
- if (!this.objectMatchesSchema(contents, messageSchema_js_1.opContentsSchema)) {
478
- this.replaceAny(contents);
479
- }
480
- else {
477
+ if (this.objectMatchesSchema(contents, messageSchema_js_1.opContentsSchema)) {
481
478
  if (this.fullScrub) {
482
479
  contents.address = this.replaceText(contents.address, TextType.FluidObject);
483
480
  }
@@ -492,8 +489,8 @@ class Sanitizer {
492
489
  this.fixAttachContents(data);
493
490
  contents.contents.content = JSON.stringify(data);
494
491
  }
495
- catch (e) {
496
- this.debugMsg(e);
492
+ catch (error) {
493
+ this.debugMsg(error);
497
494
  }
498
495
  }
499
496
  else {
@@ -515,9 +512,9 @@ class Sanitizer {
515
512
  if (this.fullScrub) {
516
513
  innerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);
517
514
  }
518
- innerContent.contents.ops.forEach((deltaOp) => {
515
+ for (const deltaOp of innerContent.contents.ops) {
519
516
  this.fixDeltaOp(deltaOp);
520
- });
517
+ }
521
518
  }
522
519
  else if (this.validator.validate(innerContent, messageSchema_js_1.opContentsMergeTreeDeltaOpSchema).valid) {
523
520
  // merge tree delta op
@@ -541,6 +538,9 @@ class Sanitizer {
541
538
  this.objectMatchesSchema(contents, false);
542
539
  }
543
540
  }
541
+ else {
542
+ this.replaceAny(contents);
543
+ }
544
544
  }
545
545
  fixOp(message) {
546
546
  // handle case where contents is stringified json
@@ -549,8 +549,8 @@ class Sanitizer {
549
549
  try {
550
550
  msgContents = JSON.parse(message.contents);
551
551
  }
552
- catch (e) {
553
- this.debugMsg(e);
552
+ catch (error) {
553
+ this.debugMsg(error);
554
554
  return;
555
555
  }
556
556
  }
@@ -595,8 +595,8 @@ class Sanitizer {
595
595
  try {
596
596
  message.contents = JSON.stringify(msgContents);
597
597
  }
598
- catch (e) {
599
- this.debugMsg(e);
598
+ catch (error) {
599
+ this.debugMsg(error);
600
600
  return;
601
601
  }
602
602
  }
@@ -649,10 +649,12 @@ class Sanitizer {
649
649
  case "noClient":
650
650
  case "summarize":
651
651
  case "summaryAck":
652
- case "summaryNack":
652
+ case "summaryNack": {
653
653
  break;
654
- default:
654
+ }
655
+ default: {
655
656
  this.debugMsg(`Unexpected op type ${message.type}`);
657
+ }
656
658
  }
657
659
  });
658
660
  // make sure we don't miss an incomplete chunked op at the end
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.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\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(e);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t\tthrow e;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length !== 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).substring(2);\n\t\t}\n\t\treturn str.substr(0, len);\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tkeys.forEach((key) => {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (!this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t} else {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (e) {\n\t\t\tthis.debugMsg(e);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t} else {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tentries.forEach((element) => {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (!this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tthis.replaceObject(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (!this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tthis.replaceAny(contents);\n\t\t} else {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tthis.debugMsg(e);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tinnerContent.contents.ops.forEach((deltaOp) => {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t});\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (e) {\n\t\t\t\tthis.debugMsg(e);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
1
+ {"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../src/sanitizer.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\n/**\n * This tool cleans up a message.json file downloaded through fluid-fetch to remove\n * user content and user identifying information. Enough information can be retained\n * to allow loading through Fluid Preview, or everything can be scrubbed so that only\n * replay-tool can read the result. Anonymous identifying information such as client\n * IDs are always retained. Object keys are NOT scrubbed, including those that are\n * nested within values (only leaf values are scrubbed).\n *\n * Note: While user content/information is scrubbed, it should not be assumed to be\n * fully anonymized because certain meta-information (such as word lengths and\n * consistent replacement) are preserved.\n *\n * Messages must match known structures when scrubbing for Fluid Preview.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport * as Validator from \"jsonschema\";\n\nimport {\n\tattachContentsSchema,\n\tchunkedOpContentsSchema,\n\tjoinContentsSchema,\n\tjoinDataSchema,\n\topContentsMapSchema,\n\topContentsMergeTreeDeltaOpSchema,\n\topContentsMergeTreeGroupOpSchema,\n\topContentsRegisterCollectionSchema,\n\topContentsSchema,\n\tproposeContentsSchema,\n} from \"./messageSchema.js\";\n\nenum TextType {\n\tGeneric,\n\tEmail,\n\tName,\n\tFluidObject,\n\tMapKey,\n}\n\n// Workaround to jsonschema package not supporting \"false\" as a schema\n// that matches nothing\nconst falseResult = {\n\tvalid: false,\n\ttoString: () => {\n\t\treturn \"Unmatched format\";\n\t},\n};\n\n/**\n * Class that takes chunkedOp messages and can provide their concatenated\n * contents along with re-write sanitized content in-place back into the\n * messages. Assumes sanitized messages are always less than or equal in\n * size to the original message.\n */\nclass ChunkedOpProcessor {\n\t/**\n\t * Message references so we can replace their contents in-place. These can\n\t * be top-level chunkedOp messages, or top-level op messages with a chunkedOp\n\t * within the contents\n\t */\n\tprivate messages = new Array<any>();\n\t/**\n\t * The messages' parsed contents for processing. Should parallel the\n\t * messages member\n\t */\n\tprivate parsedMessageContents = new Array<any>();\n\tprivate writtenBack = false;\n\t/**\n\t * keep track of the total starting length to make sure we don't somehow end\n\t * up with more content than we started with (meaning we may not be able to\n\t * write it back)\n\t */\n\tprivate concatenatedLength = 0;\n\n\tconstructor(\n\t\treadonly validateSchemaFn: (object: any, schema: any) => boolean,\n\t\treadonly debug: boolean,\n\t) {}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\taddMessage(message: any): void {\n\t\tthis.messages.push(message);\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(message.contents);\n\t\t\tif (message.type === \"op\") {\n\t\t\t\t// nested within a regular op\n\t\t\t\t// need to go deeper to get the desired contents\n\t\t\t\tparsed = parsed.contents;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(error);\n\t\t\tthis.debugMsg(message.contents);\n\t\t}\n\t\tthis.validateSchemaFn(parsed, chunkedOpContentsSchema);\n\t\tthis.parsedMessageContents.push(parsed);\n\t}\n\n\thasAllMessages(): boolean {\n\t\tconst lastMsgContents = this.parsedMessageContents[this.parsedMessageContents.length - 1];\n\t\treturn (\n\t\t\tlastMsgContents.chunkId !== undefined &&\n\t\t\tlastMsgContents.chunkId === lastMsgContents.totalChunks\n\t\t);\n\t}\n\n\t/**\n\t * Gets the concatenated contents of all the messages parsed as JSON.\n\t */\n\tgetConcatenatedContents(): any {\n\t\tconst contentsString = this.parsedMessageContents.reduce(\n\t\t\t(previousValue: string, currentValue: any) => {\n\t\t\t\treturn previousValue + (currentValue.contents as string);\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\n\t\tthis.concatenatedLength = contentsString.length;\n\t\ttry {\n\t\t\treturn JSON.parse(contentsString);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(contentsString);\n\t\t\tthis.debugMsg(error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Write back sanitized contents into the messages. The contents are\n\t * stringified, split up, and written in place to the messages that\n\t * were added earlier. The number of messages is preserved.\n\t * @param contents - Sanitized contents to write back\n\t */\n\twriteSanitizedContents(contents: any): void {\n\t\t// Write back a chunk size equal to the original\n\t\tconst chunkSize = this.parsedMessageContents[0].contents.length;\n\n\t\tlet stringified: string;\n\t\ttry {\n\t\t\tstringified = JSON.stringify(contents);\n\t\t\tassert(\n\t\t\t\tstringified.length <= this.concatenatedLength,\n\t\t\t\t0x089 /* \"Stringified length of chunk contents > total starting length\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tfor (let i = 0; i < this.messages.length; i++) {\n\t\t\tconst substring = stringified.substring(i * chunkSize, (i + 1) * chunkSize);\n\n\t\t\tconst parsedContents = this.parsedMessageContents[i];\n\t\t\tparsedContents.contents = substring;\n\t\t\tconst message = this.messages[i];\n\n\t\t\tlet stringifiedParsedContents;\n\t\t\ttry {\n\t\t\t\t// for nested chunkedOps, we need to recreate the extra nesting layer\n\t\t\t\t// we removed earlier when adding the message\n\t\t\t\tif (message.type === \"op\") {\n\t\t\t\t\tconst nestingLayer = {\n\t\t\t\t\t\ttype: \"chunkedOp\",\n\t\t\t\t\t\tcontents: parsedContents,\n\t\t\t\t\t};\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(nestingLayer);\n\t\t\t\t} else {\n\t\t\t\t\tstringifiedParsedContents = JSON.stringify(parsedContents);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.debugMsg(error);\n\t\t\t}\n\n\t\t\tmessage.contents = stringifiedParsedContents;\n\t\t}\n\n\t\tthis.writtenBack = true;\n\t}\n\n\treset(): void {\n\t\tassert(\n\t\t\tthis.writtenBack,\n\t\t\t0x08a /* \"resetting ChunkedOpProcessor that never wrote back its contents\" */,\n\t\t);\n\t\tthis.messages = new Array<any>();\n\t\tthis.parsedMessageContents = new Array<any>();\n\t\tthis.writtenBack = false;\n\t\tthis.concatenatedLength = 0;\n\t}\n\n\tisPendingProcessing(): boolean {\n\t\treturn this.messages.length > 0;\n\t}\n}\n\nexport class Sanitizer {\n\treadonly validator = new Validator.Validator();\n\t// Represents the keys used to store Fluid object identifiers, snapshot info,\n\t// and other string fields that should not be replaced in contents blobs to\n\t// ensure the messages are still usable\n\treadonly defaultExcludedKeys = new Set<string>();\n\t// Represents the keys used by merge-tree ops their \"seg\" property, where other\n\t// keys represent user information\n\treadonly mergeTreeExcludedKeys = new Set<string>();\n\t// Map of user information to what it was replaced with. Used to ensure the same\n\t// data have the same replacements\n\treadonly replacementMap = new Map<string, string>();\n\n\t/**\n\t * Validate that the provided message matches the provided schema.\n\t * For a full scrub, warn and continue (scrubber should fully sanitize unexpected\n\t * fields for ops), otherwise throw an error because we cannot be sure user\n\t * information is being sufficiently sanitized.\n\t */\n\tobjectMatchesSchema = (object: any, schema: any): boolean => {\n\t\tconst result = schema === false ? falseResult : this.validator.validate(object, schema);\n\t\tif (!result.valid) {\n\t\t\tconst errorMsg = `Bad msg fmt:\\n${result.toString()}\\n${JSON.stringify(\n\t\t\t\tobject,\n\t\t\t\tundefined,\n\t\t\t\t2,\n\t\t\t)}`;\n\n\t\t\tif (this.fullScrub || this.noBail) {\n\t\t\t\tthis.debugMsg(errorMsg);\n\t\t\t} else {\n\t\t\t\tthrow new Error(errorMsg);\n\t\t\t}\n\t\t}\n\t\treturn result.valid;\n\t};\n\n\treadonly chunkProcessor: ChunkedOpProcessor;\n\n\tconstructor(\n\t\treadonly messages: ISequencedDocumentMessage[],\n\t\treadonly fullScrub: boolean,\n\t\treadonly noBail: boolean,\n\t\treadonly debug: boolean = false,\n\t) {\n\t\tthis.defaultExcludedKeys.add(\"type\");\n\t\tthis.defaultExcludedKeys.add(\"id\");\n\t\tthis.defaultExcludedKeys.add(\"pkg\");\n\t\tthis.defaultExcludedKeys.add(\"snapshotFormatVersion\");\n\t\tthis.defaultExcludedKeys.add(\"packageVersion\");\n\t\tthis.mergeTreeExcludedKeys.add(\"nodeType\");\n\t\tthis.chunkProcessor = new ChunkedOpProcessor(this.objectMatchesSchema, debug);\n\t}\n\n\tdebugMsg(msg: any): void {\n\t\tif (this.debug) {\n\t\t\tconsole.error(msg);\n\t\t}\n\t}\n\n\tisFluidObjectKey(key: string): boolean {\n\t\treturn key === \"type\" || key === \"id\";\n\t}\n\n\tgetRandomText(len: number): string {\n\t\tlet str = \"\";\n\t\twhile (str.length < len) {\n\t\t\tstr = str + Math.random().toString(36).slice(2);\n\t\t}\n\t\treturn str.slice(0, Math.max(0, len));\n\t}\n\n\treadonly wordTokenRegex = /\\S+/g;\n\n\treadonly replaceRandomTextFn = (match: string): string => {\n\t\tif (this.replacementMap.has(match)) {\n\t\t\treturn this.replacementMap.get(match)!;\n\t\t}\n\n\t\tconst replacement = this.getRandomText(match.length);\n\t\tthis.replacementMap.set(match, replacement);\n\t\treturn replacement;\n\t};\n\n\t/**\n\t * Replace text with garbage. FluidObject types are not replaced when not under\n\t * full scrub mode. All other text is replaced consistently.\n\t */\n\treplaceText(input?: string, type: TextType = TextType.Generic): string | undefined {\n\t\tif (input === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (type === TextType.FluidObject) {\n\t\t\tif (this.replacementMap.has(input)) {\n\t\t\t\treturn this.replacementMap.get(input)!;\n\t\t\t}\n\n\t\t\tconst replacement = this.fullScrub ? this.getRandomText(input.length) : input;\n\n\t\t\tthis.replacementMap.set(input, replacement);\n\t\t\treturn replacement;\n\t\t}\n\n\t\treturn input.replace(this.wordTokenRegex, this.replaceRandomTextFn);\n\t}\n\n\treplaceArray(input: any[]): any[] {\n\t\tfor (let i = 0; i < input.length; i++) {\n\t\t\tconst value = input[i];\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tinput[i] = this.replaceText(value);\n\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\tinput[i] = this.replaceArray(value);\n\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\tinput[i] = this.replaceObject(value);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * (sort of) recurses down the values of a JSON object to sanitize all its strings\n\t * (only checks strings, arrays, and objects)\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceObject(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tinput: object | null,\n\t\texcludedKeys: Set<string> = this.defaultExcludedKeys,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): object | null {\n\t\t// File might contain actual nulls\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tconst keys = Object.keys(input);\n\t\tfor (const key of keys) {\n\t\t\tif (this.fullScrub || !excludedKeys.has(key)) {\n\t\t\t\tconst value = input[key];\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\tinput[key] = this.replaceText(\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tthis.isFluidObjectKey(key) ? TextType.FluidObject : TextType.Generic,\n\t\t\t\t\t);\n\t\t\t\t} else if (Array.isArray(value)) {\n\t\t\t\t\tinput[key] = this.replaceArray(value);\n\t\t\t\t} else if (typeof value === \"object\") {\n\t\t\t\t\tinput[key] = this.replaceObject(value, excludedKeys);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t}\n\n\t/**\n\t * Replacement on an unknown type or a parsed root level object\n\t * without a key\n\t * @param input - The object to sanitize\n\t * @param excludedKeys - object keys for which to skip replacement when not in fullScrub\n\t */\n\treplaceAny(input: any, excludedKeys: Set<string> = this.defaultExcludedKeys): any {\n\t\tif (input === null || input === undefined) {\n\t\t\treturn input;\n\t\t}\n\n\t\tif (typeof input === \"string\") {\n\t\t\treturn this.replaceText(input);\n\t\t} else if (Array.isArray(input)) {\n\t\t\treturn this.replaceArray(input);\n\t\t} else if (typeof input === \"object\") {\n\t\t\treturn this.replaceObject(input, excludedKeys);\n\t\t}\n\n\t\t// Don't run replacement on any other types\n\t\treturn input;\n\t}\n\n\tfixJoin(message: any): void {\n\t\tif (!this.objectMatchesSchema(message.contents, joinContentsSchema)) {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\n\t\ttry {\n\t\t\tlet data = JSON.parse(message.data);\n\t\t\tif (this.objectMatchesSchema(data, joinDataSchema)) {\n\t\t\t\tconst user = data.detail.user;\n\t\t\t\tuser.id = this.replaceText(user.id, TextType.Email);\n\t\t\t\tuser.email = this.replaceText(user.email, TextType.Email);\n\t\t\t\tuser.name = this.replaceText(user.name, TextType.Name);\n\t\t\t} else {\n\t\t\t\tdata = this.replaceAny(data);\n\t\t\t}\n\n\t\t\tmessage.data = JSON.stringify(data);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(error);\n\t\t}\n\t}\n\n\tfixPropose(message: any): void {\n\t\tif (this.objectMatchesSchema(message.contents, proposeContentsSchema)) {\n\t\t\tif (typeof message.contents === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\t\tconst pkg = data.value?.package;\n\t\t\t\t\t\tif (pkg?.name) {\n\t\t\t\t\t\t\tpkg.name = this.replaceText(pkg.name, TextType.FluidObject);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {\n\t\t\t\t\t\t\tpkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.debugMsg(error);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tmessage.contents.value = this.replaceText(\n\t\t\t\t\t\tmessage.contents.value,\n\t\t\t\t\t\tTextType.FluidObject,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tmessage.contents = this.replaceAny(message.contents);\n\t\t}\n\t}\n\n\tfixAttachEntries(entries: any[]): void {\n\t\tfor (const element of entries) {\n\t\t\t// Tree type\n\t\t\tif (element.value.entries) {\n\t\t\t\tthis.fixAttachEntries(element.value.entries);\n\t\t\t} else {\n\t\t\t\t// Blob (leaf) type\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof element.value.contents === \"string\") {\n\t\t\t\t\t\tlet data = JSON.parse(element.value.contents);\n\t\t\t\t\t\tdata = this.replaceObject(data);\n\t\t\t\t\t\telement.value.contents = JSON.stringify(data);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.debugMsg(error);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fix the content of an attach in place\n\t * @param contents - contents object to fix\n\t */\n\tfixAttachContents(contents: any): any {\n\t\tassert(\n\t\t\ttypeof contents === \"object\",\n\t\t\t0x08b /* \"Unexpected type on contents for fix of an attach!\" */,\n\t\t);\n\t\tif (this.objectMatchesSchema(contents, attachContentsSchema)) {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.id = this.replaceText(contents.id, TextType.FluidObject);\n\t\t\t\tcontents.type = this.replaceText(contents.type, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tthis.fixAttachEntries(contents.snapshot.entries);\n\t\t} else {\n\t\t\tthis.replaceObject(contents);\n\t\t}\n\t}\n\n\t/**\n\t * Fix an attach message at the root level or a ContainerMessageType attach. Attach\n\t * messages found within an op message should instead have their contents parsed out\n\t * and sent to fixAttachContents.\n\t * @param message - The attach message to fix\n\t * @param withinOp - If the message is from within an op message (as opposed to being\n\t * an attach message at the root level). Root level attach messages have \"snapshot\"\n\t * under a \"contents\" key, whereas attach messages from within an op message have it\n\t * under a \"content\" key\n\t */\n\tfixAttach(message: any): void {\n\t\t// Handle case where contents is stringified json\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tconst data = JSON.parse(message.contents);\n\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\tmessage.contents = JSON.stringify(data);\n\t\t\t} catch (error) {\n\t\t\t\tthis.debugMsg(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.fixAttachContents(message.contents);\n\t\t}\n\t}\n\n\tfixDeltaOp(deltaOp: any): void {\n\t\tdeltaOp.seg =\n\t\t\ttypeof deltaOp.seg === \"string\"\n\t\t\t\t? this.replaceText(deltaOp.seg)\n\t\t\t\t: this.replaceObject(deltaOp.seg, this.mergeTreeExcludedKeys);\n\t}\n\n\t/**\n\t * Fix the contents object for an op message. Does not do extra type handling. Does\n\t * not handle special container message types like \"attach\", \"component\", and\n\t * \"chunkedOp\" (these should be handled by the caller)\n\t * @param contents - The contents object for an op message. If it was a string in the\n\t * message, it must have been converted to an object first\n\t */\n\tfixOpContentsObject(contents: any): void {\n\t\t// do replacement\n\t\tif (this.objectMatchesSchema(contents, opContentsSchema)) {\n\t\t\tif (this.fullScrub) {\n\t\t\t\tcontents.address = this.replaceText(contents.address, TextType.FluidObject);\n\t\t\t}\n\n\t\t\tconst innerContent = contents.contents.content;\n\t\t\tassert(\n\t\t\t\tinnerContent !== undefined,\n\t\t\t\t0x08c /* \"innerContent for fixing op contents is undefined!\" */,\n\t\t\t);\n\t\t\tif (contents.contents.type === \"attach\") {\n\t\t\t\t// attach op\n\t\t\t\t// handle case where inner content is stringified json\n\t\t\t\tif (typeof contents.contents.content === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(contents.contents.content);\n\t\t\t\t\t\tthis.fixAttachContents(data);\n\t\t\t\t\t\tcontents.contents.content = JSON.stringify(data);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthis.debugMsg(error);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.fixAttachContents(contents.contents.content);\n\t\t\t\t}\n\t\t\t} else if (this.validator.validate(innerContent, opContentsMapSchema).valid) {\n\t\t\t\t// map op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeGroupOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree group op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tfor (const deltaOp of innerContent.contents.ops) {\n\t\t\t\t\tthis.fixDeltaOp(deltaOp);\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsMergeTreeDeltaOpSchema).valid\n\t\t\t) {\n\t\t\t\t// merge tree delta op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t}\n\t\t\t\tthis.fixDeltaOp(innerContent.contents);\n\t\t\t} else if (\n\t\t\t\tthis.validator.validate(innerContent, opContentsRegisterCollectionSchema).valid\n\t\t\t) {\n\t\t\t\t// register collection op\n\t\t\t\tif (this.fullScrub) {\n\t\t\t\t\tinnerContent.address = this.replaceText(innerContent.address, TextType.FluidObject);\n\t\t\t\t\tinnerContent.contents.key = this.replaceText(\n\t\t\t\t\t\tinnerContent.contents.key,\n\t\t\t\t\t\tTextType.MapKey,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (innerContent.contents.value !== undefined) {\n\t\t\t\t\tinnerContent.contents.value.value = this.replaceAny(\n\t\t\t\t\t\tinnerContent.contents.value.value,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// message contents don't match any known op format\n\t\t\t\tthis.objectMatchesSchema(contents, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.replaceAny(contents);\n\t\t}\n\t}\n\n\tfixOp(message: any): void {\n\t\t// handle case where contents is stringified json\n\t\tlet msgContents;\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmsgContents = JSON.parse(message.contents);\n\t\t\t} catch (error) {\n\t\t\t\tthis.debugMsg(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tmsgContents = message.contents;\n\t\t}\n\n\t\t// handle container message types\n\t\tswitch (msgContents.type) {\n\t\t\tcase \"attach\": {\n\t\t\t\t// this one is like a regular attach op, except its contents aren't nested as deep\n\t\t\t\t// run fixAttach directly and return\n\t\t\t\tthis.fixAttach(msgContents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\t// this one functionally nests its contents one layer deeper\n\t\t\t\t// bring up the contents object and continue as usual\n\t\t\t\tthis.fixOpContentsObject(msgContents.contents);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"chunkedOp\": {\n\t\t\t\t// this is a (regular?) op split into multiple parts due to size, e.g. because it\n\t\t\t\t// has an attached image, and where the chunkedOp is within the top-level op's contents\n\t\t\t\t// (as opposed to being at the top-level). The contents of the chunks need to be\n\t\t\t\t// concatenated to form the complete stringified json object\n\t\t\t\t// Early return here to skip re-stringify because no changes are made until the last\n\t\t\t\t// chunk, and the ChunkedOpProcessor will handle everything at that point\n\t\t\t\treturn this.fixChunkedOp(message);\n\t\t\t}\n\t\t\tcase \"blobAttach\": {\n\t\t\t\t// TODO: handle this properly once blob api is used\n\t\t\t\tthis.debugMsg(\"TODO: blobAttach ops are skipped/unhandled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// A regular op\n\t\t\t\tthis.fixOpContentsObject(msgContents);\n\t\t\t}\n\t\t}\n\n\t\t// re-stringify the json if needed\n\t\tif (typeof message.contents === \"string\") {\n\t\t\ttry {\n\t\t\t\tmessage.contents = JSON.stringify(msgContents);\n\t\t\t} catch (error) {\n\t\t\t\tthis.debugMsg(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fixes a chunked operation by reassembling and sanitizing the message chunks.\n\t *\n\t * @param message - The top-level chunkedOp message or a top-level op message\n\t * with a chunkedOp inside its contents\n\t */\n\tfixChunkedOp(message: any): void {\n\t\tthis.chunkProcessor.addMessage(message);\n\t\tif (!this.chunkProcessor.hasAllMessages()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = this.chunkProcessor.getConcatenatedContents();\n\t\tthis.fixOpContentsObject(contents);\n\n\t\tthis.chunkProcessor.writeSanitizedContents(contents);\n\t\tthis.chunkProcessor.reset();\n\t}\n\n\tsanitize(): ISequencedDocumentMessage[] {\n\t\tlet seq = 0;\n\n\t\ttry {\n\t\t\tthis.messages.map((message) => {\n\t\t\t\tseq = message.sequenceNumber;\n\t\t\t\t// message types from protocol-definitions' protocol.ts\n\t\t\t\tswitch (message.type) {\n\t\t\t\t\tcase \"join\": {\n\t\t\t\t\t\tthis.fixJoin(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"propose\": {\n\t\t\t\t\t\tthis.fixPropose(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"attach\": {\n\t\t\t\t\t\tthis.fixAttach(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"op\": {\n\t\t\t\t\t\tthis.fixOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"chunkedOp\": {\n\t\t\t\t\t\tthis.fixChunkedOp(message);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"noop\":\n\t\t\t\t\tcase \"leave\":\n\t\t\t\t\tcase \"noClient\":\n\t\t\t\t\tcase \"summarize\":\n\t\t\t\t\tcase \"summaryAck\":\n\t\t\t\t\tcase \"summaryNack\": {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthis.debugMsg(`Unexpected op type ${message.type}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// make sure we don't miss an incomplete chunked op at the end\n\t\t\tassert(\n\t\t\t\t!this.chunkProcessor.isPendingProcessing(),\n\t\t\t\t0x08d /* \"After sanitize, pending incomplete ops!\" */,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.debugMsg(`Error while processing sequenceNumber ${seq}`);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.messages;\n\t}\n}\n"]}
package/eslint.config.mts CHANGED
@@ -4,17 +4,26 @@
4
4
  */
5
5
 
6
6
  import type { Linter } from "eslint";
7
- import { minimalDeprecated } from "../../../common/build/eslint-config-fluid/flat.mts";
7
+ import { recommended } from "../../../common/build/eslint-config-fluid/flat.mts";
8
8
 
9
9
  const config: Linter.Config[] = [
10
- ...minimalDeprecated,
10
+ ...recommended,
11
11
  {
12
12
  rules: {
13
+ "@rushstack/no-new-null": "off",
14
+ "@typescript-eslint/explicit-module-boundary-types": "off",
15
+ "@typescript-eslint/no-explicit-any": "off",
13
16
  "@typescript-eslint/no-non-null-assertion": "off",
14
- "@typescript-eslint/no-use-before-define": "off",
17
+ "@typescript-eslint/no-unsafe-argument": "off",
18
+ "@typescript-eslint/no-unsafe-assignment": "off",
19
+ "@typescript-eslint/no-unsafe-member-access": "off",
15
20
  "@typescript-eslint/strict-boolean-expressions": "off",
16
21
  "import-x/no-nodejs-modules": "off",
17
- "no-inner-declarations": "off",
22
+ "unicorn/no-null": "off",
23
+ "unicorn/no-process-exit": "off",
24
+ "unicorn/prefer-spread": "off",
25
+ "unicorn/prefer-string-slice": "off",
26
+ "unicorn/text-encoding-identifier-case": "off",
18
27
  },
19
28
  },
20
29
  ];
package/internal.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" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export * from "./lib/index.js";
package/legacy.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" in @fluid-tools/build-cli.
8
+ * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export * from "./lib/legacy.js";
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IDocumentService, IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
5
+ import type { IDocumentService, IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
6
6
  /**
7
7
  * @legacy
8
8
  * @beta
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebugger.d.ts","sourceRoot":"","sources":["../src/fluidDebugger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,MAAM,6CAA6C,CAAC;AASrD;;;GAGG;AAEH,yBAAiB,aAAa,CAAC;IAC9B;;;;;;OAMG;IACH,SAAsB,iBAAiB,CACtC,eAAe,EAAE,gBAAgB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;IAED;;;;;OAKG;IACH,SAAsB,wBAAwB,CAC7C,sBAAsB,EAAE,uBAAuB,GAC7C,OAAO,CAAC,uBAAuB,CAAC,CAMlC;CAQD"}
1
+ {"version":3,"file":"fluidDebugger.d.ts","sourceRoot":"","sources":["../src/fluidDebugger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,MAAM,6CAA6C,CAAC;AASrD;;;GAGG;AAEH,yBAAiB,aAAa,CAAC;IAC9B;;;;;;OAMG;IACH,SAAsB,iBAAiB,CACtC,eAAe,EAAE,gBAAgB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;IAED;;;;;OAKG;IACH,SAAsB,wBAAwB,CAC7C,sBAAsB,EAAE,uBAAuB,GAC7C,OAAO,CAAC,uBAAuB,CAAC,CAMlC;CAQD"}
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebugger.js","sourceRoot":"","sources":["../src/fluidDebugger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,qBAAqB,EACrB,4BAA4B,GAC5B,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;GAGG;AACH,2DAA2D;AAC3D,MAAM,KAAW,aAAa,CAwC7B;AAxCD,WAAiB,aAAa;IAC7B;;;;;;OAMG;IACI,KAAK,UAAU,iBAAiB,CACtC,eAAiC;QAEjC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,eAAe,CAAC;QACxB,CAAC;QACD,OAAO,qBAAqB,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC;IARqB,+BAAiB,oBAQtC,CAAA;IAED;;;;;OAKG;IACI,KAAK,UAAU,wBAAwB,CAC7C,sBAA+C;QAE/C,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,sBAAsB,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,4BAA4B,CAAC,sBAAsB,EAAE,UAAU,CAAC,CAAC;IAC7E,CAAC;IARqB,sCAAwB,2BAQ7C,CAAA;IAED;;;OAGG;IACH,MAAM,mBAAmB,GAAG,GAAiC,EAAE,CAC9D,qBAAqB,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAC9E,CAAC,EAxCgB,aAAa,KAAb,aAAa,QAwC7B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tReplayDocumentService,\n\tReplayDocumentServiceFactory,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { DebugReplayController } from \"./fluidDebuggerController.js\";\nimport { DebuggerUI } from \"./fluidDebuggerUi.js\";\n\n/**\n * @legacy\n * @beta\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace FluidDebugger {\n\t/**\n\t * Creates document service wrapper that pops up Debugger window and allows user to play ops one by one.\n\t * User can chose to start with any snapshot\n\t * If pop-ups are disabled, we continue without debugger.\n\t * @param documentService - original document service to use to fetch ops / snapshots.\n\t * @internal\n\t */\n\texport async function createFromService(\n\t\tdocumentService: IDocumentService,\n\t): Promise<IDocumentService> {\n\t\tconst controller = createFluidDebugger();\n\t\tif (!controller) {\n\t\t\treturn documentService;\n\t\t}\n\t\treturn ReplayDocumentService.create(documentService, controller);\n\t}\n\n\t/**\n\t * Creates a document service factory wrapper that enables debugging with a debugger window.\n\t *\n\t * @legacy\n\t * @beta\n\t */\n\texport async function createFromServiceFactory(\n\t\tdocumentServiceFactory: IDocumentServiceFactory,\n\t): Promise<IDocumentServiceFactory> {\n\t\tconst controller = createFluidDebugger();\n\t\tif (!controller) {\n\t\t\treturn documentServiceFactory;\n\t\t}\n\t\treturn new ReplayDocumentServiceFactory(documentServiceFactory, controller);\n\t}\n\n\t/**\n\t * Binds DebuggerUI & DebugReplayController together\n\t * These classes do not know each other and talk through interfaces\n\t */\n\tconst createFluidDebugger = (): DebugReplayController | null =>\n\t\tDebugReplayController.create((controller) => DebuggerUI.create(controller));\n}\n"]}
1
+ {"version":3,"file":"fluidDebugger.js","sourceRoot":"","sources":["../src/fluidDebugger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,qBAAqB,EACrB,4BAA4B,GAC5B,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;GAGG;AACH,2DAA2D;AAC3D,MAAM,KAAW,aAAa,CAwC7B;AAxCD,WAAiB,aAAa;IAC7B;;;;;;OAMG;IACI,KAAK,UAAU,iBAAiB,CACtC,eAAiC;QAEjC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,eAAe,CAAC;QACxB,CAAC;QACD,OAAO,qBAAqB,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC;IARqB,+BAAiB,oBAQtC,CAAA;IAED;;;;;OAKG;IACI,KAAK,UAAU,wBAAwB,CAC7C,sBAA+C;QAE/C,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,OAAO,sBAAsB,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,4BAA4B,CAAC,sBAAsB,EAAE,UAAU,CAAC,CAAC;IAC7E,CAAC;IARqB,sCAAwB,2BAQ7C,CAAA;IAED;;;OAGG;IACH,MAAM,mBAAmB,GAAG,GAAiC,EAAE,CAC9D,qBAAqB,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAC9E,CAAC,EAxCgB,aAAa,KAAb,aAAa,QAwC7B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tReplayDocumentService,\n\tReplayDocumentServiceFactory,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport { DebugReplayController } from \"./fluidDebuggerController.js\";\nimport { DebuggerUI } from \"./fluidDebuggerUi.js\";\n\n/**\n * @legacy\n * @beta\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace FluidDebugger {\n\t/**\n\t * Creates document service wrapper that pops up Debugger window and allows user to play ops one by one.\n\t * User can chose to start with any snapshot\n\t * If pop-ups are disabled, we continue without debugger.\n\t * @param documentService - original document service to use to fetch ops / snapshots.\n\t * @internal\n\t */\n\texport async function createFromService(\n\t\tdocumentService: IDocumentService,\n\t): Promise<IDocumentService> {\n\t\tconst controller = createFluidDebugger();\n\t\tif (!controller) {\n\t\t\treturn documentService;\n\t\t}\n\t\treturn ReplayDocumentService.create(documentService, controller);\n\t}\n\n\t/**\n\t * Creates a document service factory wrapper that enables debugging with a debugger window.\n\t *\n\t * @legacy\n\t * @beta\n\t */\n\texport async function createFromServiceFactory(\n\t\tdocumentServiceFactory: IDocumentServiceFactory,\n\t): Promise<IDocumentServiceFactory> {\n\t\tconst controller = createFluidDebugger();\n\t\tif (!controller) {\n\t\t\treturn documentServiceFactory;\n\t\t}\n\t\treturn new ReplayDocumentServiceFactory(documentServiceFactory, controller);\n\t}\n\n\t/**\n\t * Binds DebuggerUI & DebugReplayController together\n\t * These classes do not know each other and talk through interfaces\n\t */\n\tconst createFluidDebugger = (): DebugReplayController | null =>\n\t\tDebugReplayController.create((controller) => DebuggerUI.create(controller));\n}\n"]}
@@ -3,9 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { Deferred } from "@fluidframework/core-utils/internal";
6
- import { IDocumentService, IDocumentStorageService, ISnapshotTree, IVersion, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
- import { ReadDocumentStorageServiceBase, ReplayController } from "@fluidframework/replay-driver/internal";
8
- import { IDebuggerController, IDebuggerUI } from "./fluidDebuggerUi.js";
6
+ import type { IDocumentService, IDocumentStorageService, ISnapshotTree, IVersion, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
+ import type { ReadDocumentStorageServiceBase } from "@fluidframework/replay-driver/internal";
8
+ import { ReplayController } from "@fluidframework/replay-driver/internal";
9
+ import type { IDebuggerController, IDebuggerUI } from "./fluidDebuggerUi.js";
9
10
  /**
10
11
  * @internal
11
12
  */