mirror of
https://github.com/hanzoai/insights-js.git
synced 2026-10-30 18:34:19 +00:00
Decomplect the half-finished fork so the dependency graph has ONE source with no posthog package identity, living under github.com/hanzoinsights. LAYER 1 (package identity): rename straggler package.json names — @posthog/next->@hanzo/insights-next (Next.js SDK; distinct from the existing @hanzo/insights-nextjs config helper), @posthog/mcp->@hanzo/insights-mcp, @posthog/plugin-utils->@hanzo/insights-plugin-utils, @posthog/react-slim->@hanzo/react-slim, @posthog-tooling/release-> @hanzo/insights-tooling-release, and the @posthog/rrweb* family->@hanzo/rrweb* (matching the already-published @hanzo/rrweb*@0.0.47 + minimumReleaseAgeExclude). Repoint every repository.url/homepage/bugs to github.com/hanzoinsights/insights-js and rebrand the PostHog author/description identity to Hanzo AI. LAYER 2 (cross-package imports): rewrite every internal @posthog/* import to its @hanzo/insights*|@hanzo/rrweb* equivalent and the bare module specifiers posthog-js->@hanzo/insights, posthog-node->@hanzo/insights-node, mirrored in package.json deps + the pnpm-lock importer keys. Result: 0 @posthog/* specifiers in packages/tooling/examples/playground source. LAYER 4 (wire protocol) PRESERVED: window.posthog global, ph_* keys, $-prefixed event names, distinct_id, /decide, /e/, /flags, and the __PosthogExtensions__ hook are left unchanged — the Insights server expects them. Also repair pre-existing fork merge damage that blocked compilation (unrelated to naming; identical to origin/main): restore the @hanzo/insights-core ./process subpath (spawn-local/utils, re-matching the published artifact), the lost constructor/var declarations in core + node clients, the mangled external-scripts-loader, the missing TreeShakeable/isPlainError imports, the DeviceId enum member, and stale ../posthog-core-stateless module paths. 26/34 turbo build tasks now pass; remaining failures (browser/react-native and their dependents) are pre-existing fork damage, not rebrand-caused.
112 lines
4.8 KiB
TypeScript
112 lines
4.8 KiB
TypeScript
/**
|
|
* @vitest-environment jsdom
|
|
*/
|
|
import { describe, it, beforeEach, expect } from 'vitest';
|
|
import { mediaSelectorPlugin, pseudoClassPlugin } from '../src/css';
|
|
import postcss, { type AcceptedPlugin } from 'postcss';
|
|
import { JSDOM } from 'jsdom';
|
|
import { splitCssText, stringifyStylesheet } from './../src/utils';
|
|
import { applyCssSplits } from './../src/rebuild';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import type {
|
|
serializedElementNodeWithId,
|
|
BuildCache,
|
|
textNode,
|
|
} from '../src/types';
|
|
import { NodeType } from '@hanzo/rrweb-types';
|
|
import { Window } from 'happy-dom';
|
|
|
|
describe('css parser', () => {
|
|
function parse(plugin: AcceptedPlugin, input: string): string {
|
|
const ast = postcss([plugin]).process(input, {});
|
|
return ast.css;
|
|
}
|
|
|
|
describe('mediaSelectorPlugin', () => {
|
|
it('selectors without device remain unchanged', () => {
|
|
const cssText =
|
|
'@media only screen and (min-width: 1200px) { .a { width: 10px; }}';
|
|
expect(parse(mediaSelectorPlugin, cssText)).toEqual(cssText);
|
|
});
|
|
|
|
it('can adapt media rules to replay context', () => {
|
|
[
|
|
['min', 'width'],
|
|
['min', 'height'],
|
|
['max', 'width'],
|
|
['max', 'height'],
|
|
].forEach(([first, second]) => {
|
|
expect(
|
|
parse(
|
|
mediaSelectorPlugin,
|
|
`@media only screen and (${first}-device-${second}: 1200px) { .a { width: 10px; }}`,
|
|
),
|
|
).toEqual(
|
|
`@media only screen and (${first}-${second}: 1200px) { .a { width: 10px; }}`,
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('pseudoClassPlugin', () => {
|
|
it('parses nested commas in selectors correctly', () => {
|
|
const cssText =
|
|
'body > ul :is(li:not(:first-of-type) a.current, li:not(:first-of-type).active a) {background: red;}';
|
|
expect(parse(pseudoClassPlugin, cssText)).toEqual(cssText);
|
|
});
|
|
|
|
it("doesn't ignore :hover within :is brackets", () => {
|
|
const cssText =
|
|
'body > ul :is(li:not(:first-of-type) a:hover, li:not(:first-of-type).active a) {background: red;}';
|
|
expect(parse(pseudoClassPlugin, cssText))
|
|
.toEqual(`body > ul :is(li:not(:first-of-type) a:hover, li:not(:first-of-type).active a),
|
|
body > ul :is(li:not(:first-of-type) a.\\:hover, li:not(:first-of-type).active a) {background: red;}`);
|
|
});
|
|
|
|
it('should parse selector with comma nested inside ()', () => {
|
|
const cssText =
|
|
'[_nghost-ng-c4172599085]:not(.fit-content).aim-select:hover:not(:disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--invalid, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--active) { border-color: rgb(84, 84, 84); }';
|
|
expect(parse(pseudoClassPlugin, cssText))
|
|
.toEqual(`[_nghost-ng-c4172599085]:not(.fit-content).aim-select:hover:not(:disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--invalid, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--active),
|
|
[_nghost-ng-c4172599085]:not(.fit-content).aim-select.\\:hover:not(:disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--invalid, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--active) { border-color: rgb(84, 84, 84); }`);
|
|
});
|
|
|
|
it('ignores ( in strings', () => {
|
|
const cssText =
|
|
'li[attr="weirdly("] a:hover, li[attr="weirdly)"] a {background-color: red;}';
|
|
expect(parse(pseudoClassPlugin, cssText))
|
|
.toEqual(`li[attr="weirdly("] a:hover, li[attr="weirdly)"] a,
|
|
li[attr="weirdly("] a.\\:hover {background-color: red;}`);
|
|
});
|
|
|
|
it('ignores escaping in strings', () => {
|
|
const cssText = `li[attr="weirder\\"("] a:hover, li[attr="weirder\\")"] a {background-color: red;}`;
|
|
expect(parse(pseudoClassPlugin, cssText))
|
|
.toEqual(`li[attr="weirder\\"("] a:hover, li[attr="weirder\\")"] a,
|
|
li[attr="weirder\\"("] a.\\:hover {background-color: red;}`);
|
|
});
|
|
|
|
it('preserves escaped \\:hover in class names while transforming real :hover pseudo-class', () => {
|
|
const cssText = '.escaped\\:hover\\:classname:hover { color: red; }';
|
|
expect(parse(pseudoClassPlugin, cssText)).toEqual(
|
|
`.escaped\\:hover\\:classname:hover,
|
|
.escaped\\:hover\\:classname.\\:hover { color: red; }`,
|
|
);
|
|
});
|
|
|
|
it('leaves selectors unchanged when they only contain escaped \\:hover', () => {
|
|
const cssText = '.escaped\\:hover\\:classname { color: white; }';
|
|
expect(parse(pseudoClassPlugin, cssText)).toEqual(cssText);
|
|
});
|
|
|
|
it('ignores comma in string', () => {
|
|
const cssText = 'li[attr="has,comma"] a:hover {background: red;}';
|
|
expect(parse(pseudoClassPlugin, cssText)).toEqual(
|
|
`li[attr="has,comma"] a:hover,
|
|
li[attr="has,comma"] a.\\:hover {background: red;}`,
|
|
);
|
|
});
|
|
});
|
|
});
|