@reproapp/node-sdk 0.0.18 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reproapp/node-sdk",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Repro Nest SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,8 +12,8 @@
12
12
  "build": "tsc -p tsconfig.json",
13
13
  "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput",
14
14
  "prepublishOnly": "npm run build",
15
- "test": "npm run build && node test/unawaited.test.js && node test/integration-unawaited.js && node test/request-flush-timing.test.js && node test/request-manifest-priority.test.js && node test/runtime-no-double-invoke.test.js && node test/express-trace-http-args.test.js && node test/trace-batch-size.test.js && node test/sdk-background-priority.test.js && node test/ingest-queue-retention.test.js && node test/ingest-timeout.test.js && node -r ./tracer/register test/promise-map.test.js && node test/disable-subtree.test.js && node test/circular-capture.test.js && node test/wrap-plugin-arrow-args.test.js && node test/privacy-runtime-policy.test.js && node test/runtime-privacy-materialization.test.js && node test/kafka-runtime-privacy-policy.test.js",
16
- "test:containers": "npm run build && node test/runtime-no-double-invoke.testcontainers.test.js"
15
+ "test": "npm run build && node test/unawaited.test.js && node test/integration-unawaited.js && node test/request-flush-timing.test.js && node test/request-manifest-priority.test.js && node test/runtime-no-double-invoke.test.js && node test/express-trace-http-args.test.js && node test/trace-batch-size.test.js && node test/sdk-background-priority.test.js && node test/ingest-queue-retention.test.js && node test/ingest-timeout.test.js && node -r ./tracer/register test/promise-map.test.js && node test/disable-subtree.test.js && node test/circular-capture.test.js && node test/wrap-plugin-arrow-args.test.js && node test/wrap-plugin-super-call.test.js && node test/privacy-runtime-policy.test.js && node test/runtime-privacy-materialization.test.js && node test/kafka-runtime-privacy-policy.test.js",
16
+ "test:containers": "npm run build && node test/runtime-no-double-invoke.testcontainers.test.js && node test/wrap-plugin-super-call.testcontainers.test.js"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "express": "^5.1.0",
@@ -7,7 +7,7 @@ const { trace } = require('../tracer/runtime');
7
7
  async function startMongo() {
8
8
  return new GenericContainer('mongo:7')
9
9
  .withExposedPorts(27017)
10
- .withTmpFs({ '/data/db': 'rw,noexec,nosuid,size=256m' })
10
+ .withTmpFs({ '/data/db': 'rw,noexec,nosuid,size=1g' })
11
11
  .withCommand(['mongod', '--bind_ip_all', '--setParameter', 'diagnosticDataCollectionEnabled=false'])
12
12
  .withWaitStrategy(Wait.forListeningPorts())
13
13
  .start();
@@ -0,0 +1,80 @@
1
+ const assert = require('assert');
2
+ const vm = require('vm');
3
+ const babel = require('@babel/core');
4
+ const makeWrapPlugin = require('../tracer/wrap-plugin');
5
+ require('../tracer/runtime');
6
+
7
+ function transform(source, filename) {
8
+ return babel.transformSync(source, {
9
+ filename,
10
+ plugins: [makeWrapPlugin(filename, {})],
11
+ parserOpts: { sourceType: 'script', plugins: ['typescript'] },
12
+ generatorOpts: { retainLines: true },
13
+ }).code;
14
+ }
15
+
16
+ function loadInstrumentedModule(source, filename) {
17
+ const code = transform(source, filename);
18
+ const module = { exports: {} };
19
+ const context = {
20
+ module,
21
+ exports: module.exports,
22
+ require,
23
+ console,
24
+ __trace: global.__trace,
25
+ __repro_call: global.__repro_call,
26
+ Promise,
27
+ Buffer,
28
+ setTimeout,
29
+ clearTimeout,
30
+ setImmediate,
31
+ clearImmediate,
32
+ };
33
+
34
+ vm.runInNewContext(code, context, { filename });
35
+ return { exports: module.exports, code };
36
+ }
37
+
38
+ function toPlainJson(value) {
39
+ return JSON.parse(JSON.stringify(value));
40
+ }
41
+
42
+ async function main() {
43
+ const filename = '/tmp/wrap-plugin-super-call.fixture.js';
44
+ const { exports: mod, code } = loadInstrumentedModule(`
45
+ class BaseNotificationGenerator {
46
+ async resolveNotificationConfig(params) {
47
+ return { source: 'base', params };
48
+ }
49
+ }
50
+
51
+ class SubjectNotificationGenerator extends BaseNotificationGenerator {
52
+ async resolveNotificationConfig(params, preloaded) {
53
+ return preloaded
54
+ ? Promise.resolve(preloaded)
55
+ : super.resolveNotificationConfig(params);
56
+ }
57
+ }
58
+
59
+ module.exports = { SubjectNotificationGenerator };
60
+ `, filename);
61
+
62
+ assert(!code.includes('= super'), `transformed code must not assign super into a temp:\n${code}`);
63
+
64
+ const generator = new mod.SubjectNotificationGenerator();
65
+ assert.deepStrictEqual(
66
+ toPlainJson(await generator.resolveNotificationConfig({ id: 'S_1' }, null)),
67
+ { source: 'base', params: { id: 'S_1' } },
68
+ );
69
+ assert.deepStrictEqual(
70
+ toPlainJson(await generator.resolveNotificationConfig({ id: 'S_2' }, { source: 'preloaded' })),
71
+ { source: 'preloaded' },
72
+ );
73
+
74
+ console.log('wrap-plugin super call OK');
75
+ }
76
+
77
+ main().catch((error) => {
78
+ console.error(error);
79
+ process.exitCode = 1;
80
+ });
@@ -0,0 +1,116 @@
1
+ const assert = require('assert');
2
+ const vm = require('vm');
3
+ const babel = require('@babel/core');
4
+ const mongoose = require('mongoose');
5
+ const { GenericContainer, Wait } = require('testcontainers');
6
+
7
+ const makeWrapPlugin = require('../tracer/wrap-plugin');
8
+ require('../tracer/runtime');
9
+
10
+ function transform(source, filename) {
11
+ return babel.transformSync(source, {
12
+ filename,
13
+ plugins: [makeWrapPlugin(filename, {})],
14
+ parserOpts: { sourceType: 'script', plugins: ['typescript'] },
15
+ generatorOpts: { retainLines: true },
16
+ }).code;
17
+ }
18
+
19
+ function loadInstrumentedModule(source, filename) {
20
+ const code = transform(source, filename);
21
+ const module = { exports: {} };
22
+ const context = {
23
+ module,
24
+ exports: module.exports,
25
+ require,
26
+ console,
27
+ __trace: global.__trace,
28
+ __repro_call: global.__repro_call,
29
+ Promise,
30
+ Buffer,
31
+ setTimeout,
32
+ clearTimeout,
33
+ setImmediate,
34
+ clearImmediate,
35
+ };
36
+
37
+ vm.runInNewContext(code, context, { filename });
38
+ return module.exports;
39
+ }
40
+
41
+ function toPlainJson(value) {
42
+ return JSON.parse(JSON.stringify(value));
43
+ }
44
+
45
+ async function startMongo() {
46
+ return new GenericContainer('mongo:7')
47
+ .withExposedPorts(27017)
48
+ .withTmpFs({ '/data/db': 'rw,noexec,nosuid,size=1g' })
49
+ .withCommand(['mongod', '--bind_ip_all', '--setParameter', 'diagnosticDataCollectionEnabled=false'])
50
+ .withWaitStrategy(Wait.forListeningPorts())
51
+ .start();
52
+ }
53
+
54
+ async function main() {
55
+ let container;
56
+ let connection;
57
+
58
+ try {
59
+ container = await startMongo();
60
+ const uri = `mongodb://${container.getHost()}:${container.getMappedPort(27017)}/repro_node_sdk_super_test`;
61
+ connection = await mongoose.createConnection(uri).asPromise();
62
+ const Notification = connection.model('Notification', new mongoose.Schema({
63
+ name: { type: String, required: true },
64
+ }));
65
+
66
+ const { SubjectNotificationGenerator } = loadInstrumentedModule(`
67
+ class BaseNotificationGenerator {
68
+ constructor(model) {
69
+ this.model = model;
70
+ }
71
+
72
+ async resolveNotificationConfig(params) {
73
+ await this.model.create({ name: params.name });
74
+ return { source: 'base', name: params.name };
75
+ }
76
+ }
77
+
78
+ class SubjectNotificationGenerator extends BaseNotificationGenerator {
79
+ async resolveNotificationConfig(params, preloaded) {
80
+ return preloaded
81
+ ? Promise.resolve(preloaded)
82
+ : super.resolveNotificationConfig(params);
83
+ }
84
+ }
85
+
86
+ module.exports = { SubjectNotificationGenerator };
87
+ `, '/tmp/wrap-plugin-super-call-container.fixture.js');
88
+
89
+ const generator = new SubjectNotificationGenerator(Notification);
90
+ assert.deepStrictEqual(
91
+ toPlainJson(await generator.resolveNotificationConfig({ name: 'created-through-super' }, null)),
92
+ { source: 'base', name: 'created-through-super' },
93
+ );
94
+ assert.deepStrictEqual(
95
+ toPlainJson(await generator.resolveNotificationConfig({ name: 'not-created' }, { source: 'preloaded' })),
96
+ { source: 'preloaded' },
97
+ );
98
+
99
+ assert.strictEqual(await Notification.countDocuments({ name: 'created-through-super' }), 1);
100
+ assert.strictEqual(await Notification.countDocuments({ name: 'not-created' }), 0);
101
+
102
+ console.log('wrap-plugin super call testcontainers OK');
103
+ } finally {
104
+ if (connection) {
105
+ await connection.close().catch(() => {});
106
+ }
107
+ if (container) {
108
+ await container.stop().catch(() => {});
109
+ }
110
+ }
111
+ }
112
+
113
+ main().catch((error) => {
114
+ console.error(error);
115
+ process.exitCode = 1;
116
+ });
@@ -49,6 +49,13 @@ module.exports = function makeWrapPlugin(filenameForMeta, opts = {}) {
49
49
  return '';
50
50
  }
51
51
 
52
+ function isSuperMemberCall(callee) {
53
+ if (!callee) return false;
54
+ if (t.isMemberExpression(callee) && t.isSuper(callee.object)) return true;
55
+ if (t.isOptionalMemberExpression && t.isOptionalMemberExpression(callee) && t.isSuper(callee.object)) return true;
56
+ return false;
57
+ }
58
+
52
59
  const obj = kv => t.objectExpression(
53
60
  Object.entries(kv)
54
61
  .filter(([, v]) => v != null)
@@ -451,6 +458,7 @@ module.exports = function makeWrapPlugin(filenameForMeta, opts = {}) {
451
458
  if (t.isIdentifier(n.callee, { name: '__awaiter' })) return;
452
459
  if (t.isIdentifier(n.callee, { name: '__generator' })) return;
453
460
  if (t.isSuper(n.callee)) return;
461
+ if (isSuperMemberCall(n.callee)) return;
454
462
  if (t.isImport(n.callee)) return;
455
463
 
456
464
  if (t.isMemberExpression(n.callee) && t.isIdentifier(n.callee.object, { name: '__trace' })) {
@@ -559,6 +567,7 @@ module.exports = function makeWrapPlugin(filenameForMeta, opts = {}) {
559
567
  if (t.isIdentifier(n.callee, { name: '__awaiter' })) return;
560
568
  if (t.isIdentifier(n.callee, { name: '__generator' })) return;
561
569
  if (t.isSuper(n.callee)) return;
570
+ if (isSuperMemberCall(n.callee)) return;
562
571
  if (t.isImport(n.callee)) return;
563
572
 
564
573
  const loc = n.loc?.start || null;