69a1c17b46
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>
86 lines
2.2 KiB
TypeScript
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 }
|
|
},
|
|
})
|