mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
* chore: use pnpm to manage dependencies * Fix CI errors * Don't report Docker image size for external PRs * Fix pnpm-lock.yaml formatting * Fix module versions * Ignore pnpm-lock.yaml * Upgrade Cypress action for pnpm support * Set up node and pnpm before Cypress * Fix typescript issues * Include patches directory in Dockerfile * Fix Jest tests in CI * Update lockfile * Update lockfile * Clean up Dockerfile * Update pnpm-lock.yaml to reflect current package.json files * remove yarn-error.log from .gitignore * formatting * update data exploration readme * type jest.config.ts * fix @react-hook issues for jest * fix react-syntax-highlighter issues for jest * fix jest issues from query-selector-shadow-dom * fix transform ignore patterns and undo previous fixes * add missing storybook peer dependencies * fix nullish coalescing operator for storybook * reorder storybook plugins * update editor-update-tsd warning to new npm script * use legacy ssl for chromatic / node 18 compatibility * use pnpm for visual regression testing workflow * use node 16 for chromatic * add @babel/plugin-proposal-nullish-coalescing-operator as direct dependency * try fix for plugin-server * cleanup * fix comment and warning * update more comments * update playwright dockerfile * update plugin source types * conditional image size reporting * revert react-native instructions * less restrictive pnpm verions * use ref component name in line with style guide Co-authored-by: Jacob Gillespie <jacobwgillespie@gmail.com>
258 lines
7.7 KiB
TypeScript
258 lines
7.7 KiB
TypeScript
import { Hub } from '../../src/types'
|
|
import { createHub } from '../../src/utils/db/hub'
|
|
import { code } from '../../src/utils/utils'
|
|
import { transformCode } from '../../src/worker/vm/transforms'
|
|
import { resetTestDatabase } from '../helpers/sql'
|
|
|
|
jest.mock('../../src/utils/status')
|
|
|
|
describe('transforms', () => {
|
|
let hub: Hub
|
|
let closeHub: () => Promise<void>
|
|
|
|
beforeEach(async () => {
|
|
;[hub, closeHub] = await createHub()
|
|
await resetTestDatabase(`const processEvent = event => event`)
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await closeHub()
|
|
})
|
|
|
|
describe('transformCode', () => {
|
|
it('secures awaits by wrapping promises in __asyncGuard', () => {
|
|
const rawCode = code`
|
|
async function x() {
|
|
await console.log()
|
|
}
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
async function x() {
|
|
await __asyncGuard(console.log(), "await on line 2:2");
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('attaches caller information to awaits', () => {
|
|
const rawCode = code`
|
|
async function x() {
|
|
await anotherAsyncFunction('arg1', 'arg2')
|
|
}
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
async function x() {
|
|
await __asyncGuard(anotherAsyncFunction('arg1', 'arg2'), "await on line 2:2");
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('attaches caller information to awaits for anonymous functions', () => {
|
|
const rawCode = code`
|
|
async function x() {
|
|
await (async () => {console.log()})
|
|
}
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
async function x() {
|
|
await __asyncGuard(async () => {
|
|
console.log();
|
|
}, "await on line 2:2");
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('secures then calls by wrapping promises in __asyncGuard', () => {
|
|
const rawCode = code`
|
|
async function x() {}
|
|
x.then(() => null)
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
async function x() {}
|
|
__asyncGuard(x, "Promise.then on line 2:0").then(() => null);
|
|
`)
|
|
})
|
|
|
|
it('secures block for loops with timeouts', () => {
|
|
const rawCode = code`
|
|
for (let i = 0; i < i + 1; i++) {
|
|
console.log(i)
|
|
}
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
const _LP = Date.now();
|
|
for (let i = 0; i < i + 1; i++) {
|
|
if (Date.now() - _LP > 30000) throw new Error("Script execution timed out after looping for 30 seconds on line 1:0");
|
|
console.log(i);
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('secures inline for loops with timeouts', () => {
|
|
const rawCode = code`
|
|
for (let i = 0; i < i + 1; i++) console.log(i)
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
const _LP = Date.now();
|
|
for (let i = 0; i < i + 1; i++) {
|
|
if (Date.now() - _LP > 30000) throw new Error("Script execution timed out after looping for 30 seconds on line 1:0");
|
|
console.log(i);
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('secures block for loops with timeouts avoiding _LP collision', () => {
|
|
const rawCode = code`
|
|
const _LP = 0
|
|
|
|
for (let i = 0; i < i + 1; i++) {
|
|
console.log(i)
|
|
}
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
const _LP = 0;
|
|
const _LP2 = Date.now();
|
|
for (let i = 0; i < i + 1; i++) {
|
|
if (Date.now() - _LP2 > 30000) throw new Error("Script execution timed out after looping for 30 seconds on line 3:0");
|
|
console.log(i);
|
|
}
|
|
`)
|
|
})
|
|
|
|
it('transforms TypeScript to plain JavaScript', () => {
|
|
const rawCode = code`
|
|
interface Y {
|
|
a: int
|
|
b: string
|
|
}
|
|
|
|
function k({ a, b }: Y): string {
|
|
return \`a * 10 is {a * 10}, while b is just {b}\`
|
|
}
|
|
|
|
let a: int = 2
|
|
console.log(k({ a, b: 'tomato' }))
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub)
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
function k({
|
|
a,
|
|
b
|
|
}) {
|
|
return \`a * 10 is {a * 10}, while b is just {b}\`;
|
|
}
|
|
let a = 2;
|
|
console.log(k({
|
|
a,
|
|
b: 'tomato'
|
|
}));
|
|
`)
|
|
})
|
|
|
|
it('replaces imports', () => {
|
|
const rawCode = code`
|
|
import { bla, bla2, bla3 as bla4 } from 'node-fetch'
|
|
import fetch1 from 'node-fetch'
|
|
import * as fetch2 from 'node-fetch'
|
|
console.log(bla, bla2, bla4, fetch1, fetch2);
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub, { 'node-fetch': { bla: () => true } })
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
const bla = __pluginHostImports["node-fetch"]["bla"],
|
|
bla2 = __pluginHostImports["node-fetch"]["bla2"],
|
|
bla4 = __pluginHostImports["node-fetch"]["bla3"];
|
|
const fetch1 = __pluginHostImports["node-fetch"];
|
|
const fetch2 = __pluginHostImports["node-fetch"];
|
|
console.log(bla, bla2, bla4, fetch1, fetch2);
|
|
`)
|
|
})
|
|
|
|
it('only replaces provided imports', () => {
|
|
const rawCode = code`
|
|
import { kea } from 'kea'
|
|
console.log(kea)
|
|
`
|
|
|
|
expect(() => {
|
|
transformCode(rawCode, hub, { 'node-fetch': { default: () => true } })
|
|
}).toThrow("/index.ts: Cannot import 'kea'! This package is not provided by PostHog in plugins.")
|
|
})
|
|
|
|
it('replaces requires', () => {
|
|
const rawCode = code`
|
|
const fetch = require('node-fetch')
|
|
const { BigQuery } = require('@google-cloud/bigquery')
|
|
console.log(fetch, BigQuery);
|
|
`
|
|
|
|
const transformedCode = transformCode(rawCode, hub, {
|
|
'node-fetch': { bla: () => true },
|
|
'@google-cloud/bigquery': { BigQuery: () => true },
|
|
})
|
|
|
|
expect(transformedCode).toStrictEqual(code`
|
|
"use strict";
|
|
|
|
const fetch = __pluginHostImports["node-fetch"];
|
|
const {
|
|
BigQuery
|
|
} = __pluginHostImports["@google-cloud/bigquery"];
|
|
console.log(fetch, BigQuery);
|
|
`)
|
|
})
|
|
|
|
it('only replaces provided requires', () => {
|
|
const rawCode = code`
|
|
const { kea } = require('kea')
|
|
console.log(kea)
|
|
`
|
|
|
|
expect(() => {
|
|
transformCode(rawCode, hub, { 'node-fetch': { default: () => true } })
|
|
}).toThrow("/index.ts: Cannot import 'kea'! This package is not provided by PostHog in plugins.")
|
|
})
|
|
})
|
|
})
|