tldraw/config/setupJest.ts
Mime Čuvalo 69a1c17b46
sdk: wires up tldraw to have licensing mechanisms (#4021)
For non-commercial usage of tldraw, this adds a watermark in the corner,
both for branding purposes and as an incentive for our enterprise
customers to purchase a license.

For commercial usage of tldraw, you add a license to the `<Tldraw
licenseKey={YOUR_LICENSE_KEY} />` component so that the watermark
doesn't show.

The license is a signed key that has various bits of information in it,
such as:
- license type
- hosts that the license is valid for
- whether it's an internal-only license
- expiry date

We check the license on load and show a watermark (or throw an error if
internal-only) if the license is not valid in a production environment.

This is a @MitjaBezensek, @Taha-Hassan-Git, @mimecuvalo joint
production! 🤜 🤛

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. We will be dogfooding on staging.tldraw.com and tldraw.com itself
before releasing this.

### Release Notes

- SDK: wires up tldraw to have licensing mechanisms.

---------

Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
2024-07-11 11:49:18 +00:00

86 lines
2.2 KiB
TypeScript

import { equals, getObjectSubset, iterableEquality, subsetEquality } from '@jest/expect-utils'
import crypto from 'crypto'
import {
matcherHint,
printDiffOrStringify,
printExpected,
printReceived,
stringify,
} from 'jest-matcher-utils'
import { TextDecoder, TextEncoder } from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder
delete global.crypto
global.crypto = crypto
Image.prototype.decode = async function () {
return true
}
function convertNumbersInObject(obj: any, roundToNearest: number) {
if (!obj) return obj
if (Array.isArray(obj)) {
return obj.map((x) => convertNumbersInObject(x, roundToNearest))
}
if (typeof obj === 'number') {
// || 0 to avoid -0
return Math.round(obj / roundToNearest) * roundToNearest || 0
}
if (typeof obj !== 'object') {
return obj
}
const r: any = {
__converted: true,
}
for (const k of Object.keys(obj)) {
r[k] = convertNumbersInObject(obj[k], roundToNearest)
}
return r
}
expect.extend({
toCloselyMatchObject(actual: any, expected: any, roundToNearest = 0.0001) {
const matcherName = 'toCloselyMatchObject'
const options = {
isNot: this.isNot,
promise: this.promise,
}
const EXPECTED_LABEL = 'Expected'
const RECEIVED_LABEL = 'Received'
const isExpand = (expand?: boolean): boolean => expand !== false
const newActualObj = convertNumbersInObject(actual, roundToNearest)
const newExpectedObj = convertNumbersInObject(expected, roundToNearest)
const pass = equals(newActualObj, newExpectedObj, [iterableEquality, subsetEquality])
const message = pass
? () =>
// eslint-disable-next-line prefer-template
matcherHint(matcherName, undefined, undefined, options) +
'\n\n' +
`Expected: not ${printExpected(expected)}` +
(stringify(expected) !== stringify(actual)
? `\nReceived: ${printReceived(actual)}`
: '')
: () =>
// eslint-disable-next-line prefer-template
matcherHint(matcherName, undefined, undefined, options) +
'\n\n' +
printDiffOrStringify(
expected,
getObjectSubset(actual, expected),
EXPECTED_LABEL,
RECEIVED_LABEL,
isExpand(this.expand)
)
return { message, pass }
},
})