@usebruno/filestore 0.12.0 → 0.13.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 (48) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/workers/worker-script.js +1 -1
  4. package/dist/cjs/workers/worker-script.js.map +1 -1
  5. package/dist/esm/index.js +1 -1
  6. package/dist/esm/index.js.map +1 -1
  7. package/dist/esm/workers/worker-script.js +1 -1
  8. package/dist/esm/workers/worker-script.js.map +1 -1
  9. package/dist/formats/bru/utils/redact-large-text-blocks.d.ts.map +1 -1
  10. package/dist/formats/yml/common/omit-headers.d.ts +3 -0
  11. package/dist/formats/yml/common/omit-headers.d.ts.map +1 -0
  12. package/dist/formats/yml/common/scripts.d.ts +3 -5
  13. package/dist/formats/yml/common/scripts.d.ts.map +1 -1
  14. package/dist/formats/yml/items/parseGrpcRequest.d.ts.map +1 -1
  15. package/dist/formats/yml/items/parseHttpRequest.d.ts.map +1 -1
  16. package/dist/formats/yml/items/stringifyGraphQLRequest.d.ts.map +1 -1
  17. package/dist/formats/yml/items/stringifyGrpcRequest.d.ts.map +1 -1
  18. package/dist/formats/yml/items/stringifyHttpRequest.d.ts.map +1 -1
  19. package/dist/formats/yml/items/stringifyWebsocketRequest.d.ts.map +1 -1
  20. package/dist/formats/yml/parseCollection.d.ts.map +1 -1
  21. package/dist/formats/yml/parseEnvironment.d.ts.map +1 -1
  22. package/dist/formats/yml/stringifyCollection.d.ts.map +1 -1
  23. package/dist/formats/yml/stringifyEnvironment.d.ts.map +1 -1
  24. package/dist/formats/yml/stringifyFolder.d.ts.map +1 -1
  25. package/package.json +8 -8
  26. package/src/formats/bru/tests/redact-large-text-blocks.spec.js +60 -0
  27. package/src/formats/bru/utils/redact-large-text-blocks.ts +4 -0
  28. package/src/formats/yml/common/omit-headers.spec.ts +16 -0
  29. package/src/formats/yml/common/omit-headers.ts +12 -0
  30. package/src/formats/yml/common/scripts.spec.ts +155 -0
  31. package/src/formats/yml/common/scripts.ts +55 -29
  32. package/src/formats/yml/grpc-round-trip.spec.ts +110 -0
  33. package/src/formats/yml/items/parseGraphQLRequest.ts +2 -2
  34. package/src/formats/yml/items/parseGrpcRequest.ts +14 -6
  35. package/src/formats/yml/items/parseHttpRequest.ts +8 -2
  36. package/src/formats/yml/items/stringifyGraphQLRequest.ts +5 -9
  37. package/src/formats/yml/items/stringifyGrpcRequest.ts +2 -1
  38. package/src/formats/yml/items/stringifyHttpRequest.ts +11 -9
  39. package/src/formats/yml/items/stringifyWebsocketRequest.ts +3 -1
  40. package/src/formats/yml/parseCollection.ts +5 -9
  41. package/src/formats/yml/parseEnvironment.spec.ts +49 -0
  42. package/src/formats/yml/parseEnvironment.ts +6 -0
  43. package/src/formats/yml/script.spec.ts +159 -0
  44. package/src/formats/yml/stringifyCollection.ts +7 -10
  45. package/src/formats/yml/stringifyEnvironment.spec.ts +58 -0
  46. package/src/formats/yml/stringifyEnvironment.ts +6 -0
  47. package/src/formats/yml/stringifyFolder.ts +3 -1
  48. package/src/maxRedirects.spec.ts +144 -0
@@ -1 +1 @@
1
- {"version":3,"file":"redact-large-text-blocks.d.ts","sourceRoot":"","sources":["../../../../src/formats/bru/utils/redact-large-text-blocks.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAyED,eAAO,MAAM,wBAAwB,YAAa,MAAM,KAAG,eAoC1D,CAAC;AAEF,eAAO,MAAM,qBAAqB,yBAA0B,aAAa,EAAE,MAoB1E,CAAC"}
1
+ {"version":3,"file":"redact-large-text-blocks.d.ts","sourceRoot":"","sources":["../../../../src/formats/bru/utils/redact-large-text-blocks.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AA6ED,eAAO,MAAM,wBAAwB,YAAa,MAAM,KAAG,eAoC1D,CAAC;AAEF,eAAO,MAAM,qBAAqB,yBAA0B,aAAa,EAAE,MAoB1E,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Trim omitHeaders; return undefined when there is nothing to save. */
2
+ export declare const normalizeOmitHeaders: (omitHeaders: unknown) => string[] | undefined;
3
+ //# sourceMappingURL=omit-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"omit-headers.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/common/omit-headers.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,gBAAiB,OAAO,KAAG,MAAM,EAAE,GAAG,SAUtE,CAAC"}
@@ -3,12 +3,10 @@ import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types
3
3
  import type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
4
4
  import type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
5
5
  import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
6
- export declare const toOpenCollectionScripts: (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined) => Scripts | undefined;
6
+ import type { Script as BrunoScript } from '@usebruno/schema-types/common/scripts';
7
+ export declare const toOpenCollectionScripts: (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined, allowedKeys: string[]) => Scripts | undefined;
7
8
  export declare const toBrunoScripts: (scripts: Scripts | null | undefined) => {
8
- script?: {
9
- req?: string;
10
- res?: string;
11
- };
9
+ script?: BrunoScript;
12
10
  tests?: string;
13
11
  } | undefined;
14
12
  //# sourceMappingURL=scripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scripts.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/common/scripts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AACpG,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,IAAI,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAC3G,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAE5F,eAAO,MAAM,uBAAuB,YAAa,kBAAkB,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,KAAG,OAAO,GAAG,SAuBhK,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,OAAO,GAAG,IAAI,GAAG,SAAS,KAAG;IACnE,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SA6BH,CAAC"}
1
+ {"version":3,"file":"scripts.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/common/scripts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkC,OAAO,EAAE,MAAM,sCAAsC,CAAC;AACpG,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AACpG,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,IAAI,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAC3G,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEnF,eAAO,MAAM,uBAAuB,YAAa,kBAAkB,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,eAAe,MAAM,EAAE,KAAG,OAAO,GAAG,SA6BvL,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,OAAO,GAAG,IAAI,GAAG,SAAS,KAAG;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SAgDH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseGrpcRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/parseGrpcRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAoC,MAAM,qCAAqC,CAAC;AAkCzG,QAAA,MAAM,gBAAgB,cAAe,WAAW,KAAG,SAkGlD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"parseGrpcRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/parseGrpcRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAoC,MAAM,qCAAqC,CAAC;AAkCzG,QAAA,MAAM,gBAAgB,cAAe,WAAW,KAAG,SA0GlD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseHttpRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/parseHttpRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAE3H,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,qCAAqC,CAAC;AAcxF,QAAA,MAAM,gBAAgB,cAAe,WAAW,KAAG,SAoLlD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"parseHttpRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/parseHttpRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAE3H,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,qCAAqC,CAAC;AAexF,QAAA,MAAM,gBAAgB,cAAe,WAAW,KAAG,SAyLlD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyGraphQLRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyGraphQLRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAoB3H,QAAA,MAAM,uBAAuB,SAAU,SAAS,KAAG,MAkJlD,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"stringifyGraphQLRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyGraphQLRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAqB3H,QAAA,MAAM,uBAAuB,SAAU,SAAS,KAAG,MA6IlD,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyGrpcRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyGrpcRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAehF,QAAA,MAAM,oBAAoB,SAAU,SAAS,KAAG,MAqH/C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"stringifyGrpcRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyGrpcRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAgBhF,QAAA,MAAM,oBAAoB,SAAU,SAAS,KAAG,MAqH/C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyHttpRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyHttpRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAsB3H,QAAA,MAAM,oBAAoB,SAAU,SAAS,KAAG,MA6M/C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"stringifyHttpRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyHttpRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAA6C,MAAM,wCAAwC,CAAC;AAwB3H,QAAA,MAAM,oBAAoB,SAAU,SAAS,KAAG,MA6M/C,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyWebsocketRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyWebsocketRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAchF,QAAA,MAAM,yBAAyB,SAAU,SAAS,KAAG,MA8GpD,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"stringifyWebsocketRequest.d.ts","sourceRoot":"","sources":["../../../../src/formats/yml/items/stringifyWebsocketRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAehF,QAAA,MAAM,yBAAyB,SAAU,SAAS,KAAG,MA+GpD,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseCollection.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/parseCollection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAU3E,UAAU,gBAAgB;IACxB,cAAc,EAAE,UAAU,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED,QAAA,MAAM,eAAe,cAAe,MAAM,KAAG,gBAqO5C,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"parseCollection.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/parseCollection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAW3E,UAAU,gBAAgB;IACxB,cAAc,EAAE,UAAU,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED,QAAA,MAAM,eAAe,cAAe,MAAM,KAAG,gBAgO5C,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseEnvironment.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/parseEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,gBAAgB,EAC/B,mBAAmB,IAAI,wBAAwB,EAC/C,yBAAyB,IAAI,8BAA8B,EAE5D,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAUvF,eAAO,MAAM,2BAA2B,cAAe,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,KAAG,CAAC,wBAAwB,GAAG,8BAA8B,CAAC,EAgDpK,CAAC;AAgCF,QAAA,MAAM,gBAAgB,cAAe,MAAM,KAAG,gBAqB7C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"parseEnvironment.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/parseEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,gBAAgB,EAC/B,mBAAmB,IAAI,wBAAwB,EAC/C,yBAAyB,IAAI,8BAA8B,EAE5D,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAWvF,eAAO,MAAM,2BAA2B,cAAe,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,KAAG,CAAC,wBAAwB,GAAG,8BAA8B,CAAC,EAgDpK,CAAC;AAgCF,QAAA,MAAM,gBAAgB,cAAe,MAAM,KAAG,gBA0B7C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyCollection.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyCollection.ts"],"names":[],"mappings":"AAmEA,QAAA,MAAM,mBAAmB,mBAAoB,GAAG,eAAe,GAAG,KAAG,MA0OpE,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"stringifyCollection.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyCollection.ts"],"names":[],"mappings":"AAqEA,QAAA,MAAM,mBAAmB,mBAAoB,GAAG,eAAe,GAAG,KAAG,MAqOpE,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyEnvironment.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,gBAAgB,EAC/B,mBAAmB,IAAI,wBAAwB,EAC/C,yBAAyB,IAAI,8BAA8B,EAE5D,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAMvF,eAAO,MAAM,oCAAoC,cAAe,CAAC,wBAAwB,GAAG,8BAA8B,CAAC,EAAE,KAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,GAAG,SA2C/J,CAAC;AA8BF,QAAA,MAAM,oBAAoB,gBAAiB,gBAAgB,KAAG,MA2B7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"stringifyEnvironment.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,gBAAgB,EAC/B,mBAAmB,IAAI,wBAAwB,EAC/C,yBAAyB,IAAI,8BAA8B,EAE5D,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAOvF,eAAO,MAAM,oCAAoC,cAAe,CAAC,wBAAwB,GAAG,8BAA8B,CAAC,EAAE,KAAG,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,GAAG,SA2C/J,CAAC;AA8BF,QAAA,MAAM,oBAAoB,gBAAiB,gBAAgB,KAAG,MAgC7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stringifyFolder.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyFolder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAmC3E,QAAA,MAAM,eAAe,eAAgB,UAAU,KAAG,MA2EjD,CAAC;AACF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"stringifyFolder.d.ts","sourceRoot":"","sources":["../../../src/formats/yml/stringifyFolder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAoC3E,QAAA,MAAM,eAAe,eAAgB,UAAU,KAAG,MA4EjD,CAAC;AACF,eAAe,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usebruno/filestore",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -29,11 +29,11 @@
29
29
  "@types/jest": "^29.5.11",
30
30
  "@types/lodash": "^4.14.191",
31
31
  "@types/node": "^24.1.0",
32
- "@opencollection/types": "0.12.0",
33
- "@usebruno/schema-types": "0.8.0",
32
+ "@opencollection/types": "0.14.0",
33
+ "@usebruno/schema-types": "0.9.0",
34
34
  "babel-jest": "^29.7.0",
35
35
  "jest": "^29.2.0",
36
- "nanoid": "3.3.8",
36
+ "nanoid": "3.3.18",
37
37
  "rimraf": "^3.0.2",
38
38
  "rollup": "3.30.0",
39
39
  "rollup-plugin-dts": "^5.0.0",
@@ -46,10 +46,10 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@types/nanoid": "^2.1.0",
49
- "@usebruno/common": "0.25.0",
50
- "@usebruno/lang": "0.39.0",
51
- "ajv": "^8.17.1",
49
+ "@usebruno/common": "0.26.0",
50
+ "@usebruno/lang": "0.40.0",
51
+ "ajv": "^8.18.0",
52
52
  "lodash": "4.18.1",
53
- "yaml": "^2.3.4"
53
+ "yaml": "2.3.4"
54
54
  }
55
55
  }
@@ -92,6 +92,53 @@ body:graphql:vars {
92
92
  }
93
93
  `;
94
94
 
95
+ const grpcBru = `meta {
96
+ name: gRPC Test
97
+ type: grpc
98
+ seq: 1
99
+ }
100
+
101
+ grpc {
102
+ url: grpc://localhost:50051
103
+ method: /hello.Greeter/SayHello
104
+ methodType: unary
105
+ }
106
+
107
+ body:grpc {
108
+ name: message 1
109
+ content: '''
110
+ {
111
+ "greeting": "hi"
112
+ }
113
+ '''
114
+ }
115
+
116
+ script:grpc:before-call-start {
117
+ const startedAt = 1;
118
+ if (startedAt) {
119
+ bru.setVar("startedAt", startedAt);
120
+ }
121
+ }
122
+
123
+ script:grpc:after-call-end {
124
+ bru.setVar("endedAt", 2);
125
+ }
126
+
127
+ script:grpc:before-message-send {
128
+ bru.setVar("sentAt", bru.grpc.request.message.timestamp);
129
+ }
130
+
131
+ script:grpc:after-message-receive {
132
+ bru.setVar("receivedAt", bru.grpc.response.message.timestamp);
133
+ }
134
+
135
+ tests {
136
+ test("hook ran", function() {
137
+ expect(bru.getVar("startedAt")).to.equal(1);
138
+ });
139
+ }
140
+ `;
141
+
95
142
  const xmlSparqlBru = `meta {
96
143
  name: Others
97
144
  type: http
@@ -296,6 +343,8 @@ describe('redactLargeBruTextBlocks', () => {
296
343
  ['request with bodies, scripts, tests, docs', requestBru],
297
344
  ['graphql query + variables', graphqlBru],
298
345
  ['xml + sparql bodies', xmlSparqlBru],
346
+ ['grpc request with lifecycle hooks', grpcBru],
347
+ ['CRLF grpc request with lifecycle hooks', toCRLF(grpcBru)],
299
348
  ['CRLF request', toCRLF(requestBru)],
300
349
  ['leading + trailing blank lines in body', blankLinesBru],
301
350
  ['CRLF leading + trailing blank lines', toCRLF(blankLinesBru)],
@@ -333,6 +382,17 @@ describe('redactLargeBruTextBlocks', () => {
333
382
  });
334
383
  });
335
384
 
385
+ it('extracts the grpc lifecycle hooks and leaves the dictionary message block in place', () => {
386
+ const { skeleton, blocks } = redactLargeBruTextBlocks(grpcBru);
387
+ // all four lifecycle hooks + tests; `body:grpc` is a dictionary and stays in the skeleton
388
+ expect(blocks.length).toBe(5);
389
+ expect(skeleton.length).toBeLessThan(grpcBru.length);
390
+ blocks.forEach((block) => {
391
+ expect(skeleton).toContain(block.token);
392
+ expect(skeleton).not.toContain(block.value);
393
+ });
394
+ });
395
+
336
396
  it('keeps the skeleton bounded regardless of block size', () => {
337
397
  const blob = 'x'.repeat(4 * 1024 * 1024);
338
398
  const bru = `meta {
@@ -20,6 +20,10 @@ const BLOCK_TAGS = [
20
20
  'body:sparql',
21
21
  'script:pre-request',
22
22
  'script:post-response',
23
+ 'script:grpc:before-call-start',
24
+ 'script:grpc:before-message-send',
25
+ 'script:grpc:after-message-receive',
26
+ 'script:grpc:after-call-end',
23
27
  'tests',
24
28
  'docs',
25
29
  'body'
@@ -0,0 +1,16 @@
1
+ import { normalizeOmitHeaders } from './omit-headers';
2
+
3
+ describe('normalizeOmitHeaders', () => {
4
+ it('normalizes valid omitHeaders lists', () => {
5
+ expect(normalizeOmitHeaders([' User-Agent ', 'Accept-Encoding'])).toEqual(['User-Agent', 'Accept-Encoding']);
6
+ expect(normalizeOmitHeaders(['User-Agent', ''])).toEqual(['User-Agent']);
7
+ expect(normalizeOmitHeaders([null, 42, ' User-Agent '])).toEqual(['User-Agent']);
8
+ });
9
+
10
+ it('returns undefined for empty or invalid input', () => {
11
+ expect(normalizeOmitHeaders(undefined)).toBeUndefined();
12
+ expect(normalizeOmitHeaders([])).toBeUndefined();
13
+ expect(normalizeOmitHeaders(['', ' '])).toBeUndefined();
14
+ expect(normalizeOmitHeaders(null)).toBeUndefined();
15
+ });
16
+ });
@@ -0,0 +1,12 @@
1
+ /** Trim omitHeaders; return undefined when there is nothing to save. */
2
+ export const normalizeOmitHeaders = (omitHeaders: unknown): string[] | undefined => {
3
+ if (!Array.isArray(omitHeaders) || !omitHeaders.length) {
4
+ return undefined;
5
+ }
6
+
7
+ const names = omitHeaders
8
+ .map((name) => (typeof name === 'string' ? name.trim() : ''))
9
+ .filter((name) => name.length > 0);
10
+
11
+ return names.length ? names : undefined;
12
+ };
@@ -0,0 +1,155 @@
1
+ import { toOpenCollectionScripts, toBrunoScripts } from './scripts';
2
+ import { HTTP_SCRIPT_KEYS, GRPC_SCRIPT_KEYS } from '@usebruno/common';
3
+
4
+ describe('toOpenCollectionScripts', () => {
5
+ it('returns undefined when there is nothing to write', () => {
6
+ expect(toOpenCollectionScripts(null, HTTP_SCRIPT_KEYS)).toBeUndefined();
7
+ expect(toOpenCollectionScripts(undefined, HTTP_SCRIPT_KEYS)).toBeUndefined();
8
+ expect(toOpenCollectionScripts({} as any, HTTP_SCRIPT_KEYS)).toBeUndefined();
9
+ expect(toOpenCollectionScripts({ script: { req: null, res: null }, tests: null } as any, HTTP_SCRIPT_KEYS)).toBeUndefined();
10
+ });
11
+
12
+ it('writes req/res as before-request/after-response for the http keys', () => {
13
+ const out = toOpenCollectionScripts(
14
+ { script: { req: 'pre()', res: 'post()' } } as any,
15
+ HTTP_SCRIPT_KEYS
16
+ );
17
+
18
+ expect(out).toEqual([
19
+ { type: 'before-request', code: 'pre()' },
20
+ { type: 'after-response', code: 'post()' }
21
+ ]);
22
+ });
23
+
24
+ it('writes the grpc lifecycle hooks for the grpc keys', () => {
25
+ const out = toOpenCollectionScripts(
26
+ {
27
+ script: {
28
+ beforeCallStart: 'before()',
29
+ beforeMessageSend: 'beforeSend()',
30
+ afterMessageReceive: 'afterReceive()',
31
+ afterCallEnd: 'after()'
32
+ }
33
+ } as any,
34
+ GRPC_SCRIPT_KEYS
35
+ );
36
+
37
+ expect(out).toEqual([
38
+ { type: 'grpc:before-call-start', code: 'before()' },
39
+ { type: 'grpc:before-message-send', code: 'beforeSend()' },
40
+ { type: 'grpc:after-message-receive', code: 'afterReceive()' },
41
+ { type: 'grpc:after-call-end', code: 'after()' }
42
+ ]);
43
+ });
44
+
45
+ it('drops script slots outside the allowed keys', () => {
46
+ const script = {
47
+ req: 'pre()',
48
+ res: 'post()',
49
+ beforeCallStart: 'before()',
50
+ beforeMessageSend: 'beforeSend()',
51
+ afterMessageReceive: 'afterReceive()',
52
+ afterCallEnd: 'after()'
53
+ };
54
+
55
+ expect(toOpenCollectionScripts({ script } as any, HTTP_SCRIPT_KEYS)).toEqual([
56
+ { type: 'before-request', code: 'pre()' },
57
+ { type: 'after-response', code: 'post()' }
58
+ ]);
59
+ expect(toOpenCollectionScripts({ script } as any, GRPC_SCRIPT_KEYS)).toEqual([
60
+ { type: 'grpc:before-call-start', code: 'before()' },
61
+ { type: 'grpc:before-message-send', code: 'beforeSend()' },
62
+ { type: 'grpc:after-message-receive', code: 'afterReceive()' },
63
+ { type: 'grpc:after-call-end', code: 'after()' }
64
+ ]);
65
+ });
66
+
67
+ it('returns undefined when every populated slot is gated out', () => {
68
+ expect(toOpenCollectionScripts({ script: { beforeCallStart: 'before()' } } as any, HTTP_SCRIPT_KEYS)).toBeUndefined();
69
+ expect(toOpenCollectionScripts({ script: { beforeMessageSend: 'beforeSend()' } } as any, HTTP_SCRIPT_KEYS)).toBeUndefined();
70
+ expect(toOpenCollectionScripts({ script: { req: 'pre()' } } as any, GRPC_SCRIPT_KEYS)).toBeUndefined();
71
+ });
72
+
73
+ it('trims code and skips whitespace-only scripts', () => {
74
+ const out = toOpenCollectionScripts(
75
+ { script: { req: ' pre() ', res: ' \n ' }, tests: ' test() ' } as any,
76
+ HTTP_SCRIPT_KEYS
77
+ );
78
+
79
+ expect(out).toEqual([
80
+ { type: 'before-request', code: 'pre()' },
81
+ { type: 'tests', code: 'test()' }
82
+ ]);
83
+ });
84
+
85
+ it('writes tests regardless of the allowed keys', () => {
86
+ expect(toOpenCollectionScripts({ tests: 'test()' } as any, HTTP_SCRIPT_KEYS)).toEqual([
87
+ { type: 'tests', code: 'test()' }
88
+ ]);
89
+ expect(toOpenCollectionScripts({ tests: 'test()' } as any, GRPC_SCRIPT_KEYS)).toEqual([
90
+ { type: 'tests', code: 'test()' }
91
+ ]);
92
+ });
93
+ });
94
+
95
+ describe('toBrunoScripts', () => {
96
+ it('returns undefined for null / empty input', () => {
97
+ expect(toBrunoScripts(null)).toBeUndefined();
98
+ expect(toBrunoScripts(undefined)).toBeUndefined();
99
+ expect(toBrunoScripts([])).toBeUndefined();
100
+ });
101
+
102
+ it('maps every known script type to its bruno script slot', () => {
103
+ expect(
104
+ toBrunoScripts([
105
+ { type: 'before-request', code: 'pre()' },
106
+ { type: 'after-response', code: 'post()' },
107
+ { type: 'grpc:before-call-start', code: 'before()' },
108
+ { type: 'grpc:after-call-end', code: 'after()' },
109
+ { type: 'grpc:before-message-send', code: 'beforeSend()' },
110
+ { type: 'grpc:after-message-receive', code: 'afterReceive()' },
111
+ { type: 'tests', code: 'test()' }
112
+ ])
113
+ ).toEqual({
114
+ script: {
115
+ req: 'pre()',
116
+ res: 'post()',
117
+ beforeCallStart: 'before()',
118
+ afterCallEnd: 'after()',
119
+ beforeMessageSend: 'beforeSend()',
120
+ afterMessageReceive: 'afterReceive()'
121
+ },
122
+ tests: 'test()'
123
+ });
124
+ });
125
+
126
+ it('skips entries with no code and returns undefined when none remain', () => {
127
+ expect(
128
+ toBrunoScripts([
129
+ { type: 'before-request', code: '' },
130
+ { type: 'grpc:before-call-start', code: 'before()' }
131
+ ])
132
+ ).toEqual({ script: { beforeCallStart: 'before()' } });
133
+
134
+ expect(toBrunoScripts([{ type: 'before-request', code: '' }])).toBeUndefined();
135
+ });
136
+
137
+ it('ignores unrecognized script types', () => {
138
+ expect(toBrunoScripts([{ type: 'grpc:on-message', code: 'nope()' } as any])).toBeUndefined();
139
+ expect(
140
+ toBrunoScripts([
141
+ { type: 'grpc:on-message', code: 'nope()' } as any,
142
+ { type: 'before-request', code: 'pre()' }
143
+ ])
144
+ ).toEqual({ script: { req: 'pre()' } });
145
+ });
146
+
147
+ it('keeps the last script when a type repeats', () => {
148
+ expect(
149
+ toBrunoScripts([
150
+ { type: 'grpc:before-call-start', code: 'first()' },
151
+ { type: 'grpc:before-call-start', code: 'second()' }
152
+ ])
153
+ ).toEqual({ script: { beforeCallStart: 'second()' } });
154
+ });
155
+ });
@@ -1,24 +1,31 @@
1
- import type { Scripts, Script } from '@opencollection/types/common/scripts';
1
+ import type { Script as OpenCollectionScript, Scripts } from '@opencollection/types/common/scripts';
2
2
  import type { FolderRequest as BrunoFolderRequest } from '@usebruno/schema-types/collection/folder';
3
3
  import type { HttpRequest as BrunoHttpRequest } from '@usebruno/schema-types/requests/http';
4
4
  import type { WebSocketRequest as BrunoWebSocketRequest } from '@usebruno/schema-types/requests/websocket';
5
5
  import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
6
+ import type { Script as BrunoScript } from '@usebruno/schema-types/common/scripts';
6
7
 
7
- export const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined): Scripts | undefined => {
8
+ export const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpRequest | BrunoWebSocketRequest | BrunoGrpcRequest | null | undefined, allowedKeys: string[]): Scripts | undefined => {
8
9
  const ocScripts: Scripts = [];
10
+ const script = request?.script as BrunoScript | null | undefined;
11
+
12
+ const pushScript = (key: keyof BrunoScript, type: OpenCollectionScript['type'], code: string | null | undefined) => {
13
+ if (!allowedKeys.includes(key)) {
14
+ return;
15
+ }
16
+ if (!code?.trim().length) {
17
+ return;
18
+ }
19
+ ocScripts.push({ type, code: code.trim() });
20
+ };
21
+
22
+ pushScript('req', 'before-request', script?.req);
23
+ pushScript('res', 'after-response', script?.res);
24
+ pushScript('beforeCallStart', 'grpc:before-call-start', script?.beforeCallStart);
25
+ pushScript('beforeMessageSend', 'grpc:before-message-send', script?.beforeMessageSend);
26
+ pushScript('afterMessageReceive', 'grpc:after-message-receive', script?.afterMessageReceive);
27
+ pushScript('afterCallEnd', 'grpc:after-call-end', script?.afterCallEnd);
9
28
 
10
- if (request?.script?.req?.trim().length) {
11
- ocScripts.push({
12
- type: 'before-request',
13
- code: request.script.req.trim()
14
- });
15
- }
16
- if (request?.script?.res?.trim().length) {
17
- ocScripts.push({
18
- type: 'after-response',
19
- code: request.script.res.trim()
20
- });
21
- }
22
29
  if (request?.tests?.trim().length) {
23
30
  ocScripts.push({
24
31
  type: 'tests',
@@ -30,7 +37,7 @@ export const toOpenCollectionScripts = (request: BrunoFolderRequest | BrunoHttpR
30
37
  };
31
38
 
32
39
  export const toBrunoScripts = (scripts: Scripts | null | undefined): {
33
- script?: { req?: string; res?: string };
40
+ script?: BrunoScript;
34
41
  tests?: string;
35
42
  } | undefined => {
36
43
  if (!scripts || !Array.isArray(scripts) || scripts.length === 0) {
@@ -38,25 +45,44 @@ export const toBrunoScripts = (scripts: Scripts | null | undefined): {
38
45
  }
39
46
 
40
47
  const brunoScripts: {
41
- script?: { req?: string; res?: string };
48
+ script?: BrunoScript;
42
49
  tests?: string;
43
50
  } = {};
44
51
 
45
- for (const script of scripts) {
46
- if (script.type === 'before-request' && script.code) {
47
- if (!brunoScripts.script) {
48
- brunoScripts.script = {};
49
- }
50
- brunoScripts.script.req = script.code;
52
+ const setScript = (key: keyof BrunoScript, code: string) => {
53
+ if (!brunoScripts.script) {
54
+ brunoScripts.script = {};
51
55
  }
52
- if (script.type === 'after-response' && script.code) {
53
- if (!brunoScripts.script) {
54
- brunoScripts.script = {};
55
- }
56
- brunoScripts.script.res = script.code;
56
+ brunoScripts.script[key] = code;
57
+ };
58
+
59
+ for (const script of scripts) {
60
+ if (!script.code) {
61
+ continue;
57
62
  }
58
- if (script.type === 'tests' && script.code) {
59
- brunoScripts.tests = script.code;
63
+
64
+ switch (script.type) {
65
+ case 'before-request':
66
+ setScript('req', script.code);
67
+ break;
68
+ case 'after-response':
69
+ setScript('res', script.code);
70
+ break;
71
+ case 'grpc:before-call-start':
72
+ setScript('beforeCallStart', script.code);
73
+ break;
74
+ case 'grpc:before-message-send':
75
+ setScript('beforeMessageSend', script.code);
76
+ break;
77
+ case 'grpc:after-message-receive':
78
+ setScript('afterMessageReceive', script.code);
79
+ break;
80
+ case 'grpc:after-call-end':
81
+ setScript('afterCallEnd', script.code);
82
+ break;
83
+ case 'tests':
84
+ brunoScripts.tests = script.code;
85
+ break;
60
86
  }
61
87
  }
62
88
 
@@ -0,0 +1,110 @@
1
+ import type { GrpcRequest as BrunoGrpcRequest } from '@usebruno/schema-types/requests/grpc';
2
+ import stringifyItem from './stringifyItem';
3
+ import parseItem from './parseItem';
4
+
5
+ const parseGrpcItem = (yml: string) => parseItem(yml).request as BrunoGrpcRequest;
6
+
7
+ const grpcItem = (script: Record<string, string | null>, tests: string | null = null) => ({
8
+ uid: 'i1',
9
+ type: 'grpc-request',
10
+ name: 'say hello',
11
+ seq: 1,
12
+ request: {
13
+ url: 'grpc://localhost:50051',
14
+ method: '/hello.Greeter/SayHello',
15
+ methodType: 'unary',
16
+ headers: [],
17
+ auth: { mode: 'none' },
18
+ body: { mode: 'grpc', grpc: [{ name: 'message 1', content: '{}' }] },
19
+ script,
20
+ tests,
21
+ vars: { req: [], res: [] },
22
+ assertions: []
23
+ }
24
+ }) as any;
25
+
26
+ describe('grpc lifecycle hooks — stringify/parse round trip', () => {
27
+ it('writes every hook as a grpc-prefixed script type and reads them back', () => {
28
+ const yml = stringifyItem(grpcItem({
29
+ beforeCallStart: 'bru.setVar("a", 1);',
30
+ afterCallEnd: 'bru.setVar("b", 2);',
31
+ beforeMessageSend: 'bru.setVar("c", 3);',
32
+ afterMessageReceive: 'bru.setVar("d", 4);'
33
+ }));
34
+
35
+ expect(yml).toContain('grpc:before-call-start');
36
+ expect(yml).toContain('grpc:after-call-end');
37
+ expect(yml).toContain('grpc:before-message-send');
38
+ expect(yml).toContain('grpc:after-message-receive');
39
+
40
+ const { script } = parseGrpcItem(yml);
41
+ expect(script!.beforeCallStart).toBe('bru.setVar("a", 1);');
42
+ expect(script!.afterCallEnd).toBe('bru.setVar("b", 2);');
43
+ expect(script!.beforeMessageSend).toBe('bru.setVar("c", 3);');
44
+ expect(script!.afterMessageReceive).toBe('bru.setVar("d", 4);');
45
+ });
46
+
47
+ it('preserves a multiline hook verbatim', () => {
48
+ const beforeCallStart = ['const now = 1;', 'if (now) {', ' bru.setVar("startedAt", now);', '}'].join('\n');
49
+
50
+ const yml = stringifyItem(grpcItem({ beforeCallStart, afterCallEnd: null }));
51
+ const { script } = parseGrpcItem(yml);
52
+
53
+ expect(script!.beforeCallStart).toBe(beforeCallStart);
54
+ });
55
+
56
+ it('round-trips one hook without inventing the others', () => {
57
+ const yml = stringifyItem(grpcItem({ beforeCallStart: null, afterCallEnd: 'bru.setVar("b", 2);' }));
58
+
59
+ expect(yml).not.toContain('grpc:before-call-start');
60
+ expect(yml).not.toContain('grpc:before-message-send');
61
+ expect(yml).not.toContain('grpc:after-message-receive');
62
+
63
+ const { script } = parseGrpcItem(yml);
64
+ expect(script!.beforeCallStart).toBeNull();
65
+ expect(script!.afterCallEnd).toBe('bru.setVar("b", 2);');
66
+ expect(script!.beforeMessageSend).toBeNull();
67
+ expect(script!.afterMessageReceive).toBeNull();
68
+ });
69
+
70
+ it('writes no scripts block when every hook is empty', () => {
71
+ const yml = stringifyItem(grpcItem({
72
+ beforeCallStart: null,
73
+ afterCallEnd: ' ',
74
+ beforeMessageSend: null,
75
+ afterMessageReceive: ' '
76
+ }));
77
+
78
+ expect(yml).not.toContain('scripts:');
79
+
80
+ const { script } = parseGrpcItem(yml);
81
+ expect(script!.beforeCallStart).toBeNull();
82
+ expect(script!.afterCallEnd).toBeNull();
83
+ expect(script!.beforeMessageSend).toBeNull();
84
+ expect(script!.afterMessageReceive).toBeNull();
85
+ });
86
+
87
+ it('keeps tests alongside the hooks', () => {
88
+ const yml = stringifyItem(
89
+ grpcItem({ beforeCallStart: 'bru.setVar("a", 1);', afterCallEnd: null }, 'test("ok", () => {});')
90
+ );
91
+
92
+ const request = parseGrpcItem(yml);
93
+ expect(request.script!.beforeCallStart).toBe('bru.setVar("a", 1);');
94
+ expect(request.tests).toBe('test("ok", () => {});');
95
+ });
96
+
97
+ it('survives a second round trip unchanged', () => {
98
+ const item = grpcItem({
99
+ beforeCallStart: 'bru.setVar("a", 1);',
100
+ afterCallEnd: 'bru.setVar("b", 2);',
101
+ beforeMessageSend: 'bru.setVar("c", 3);',
102
+ afterMessageReceive: 'bru.setVar("d", 4);'
103
+ });
104
+
105
+ const firstPass = stringifyItem(item);
106
+ const secondPass = stringifyItem(parseItem(firstPass));
107
+
108
+ expect(secondPass).toBe(firstPass);
109
+ });
110
+ });