@pushwoosh/smart-components-kit 1.3.35 → 1.3.37

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,59 +1,63 @@
1
1
  {
2
2
  "name": "@pushwoosh/smart-components-kit",
3
+ "version": "1.3.37",
4
+ "description": "Stateful, data-connected React components shared by Pushwoosh micro-frontends",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://gitlab.corp.pushwoosh.com/frontend/frontend-monorepo.git",
8
+ "directory": "packages/smart-components"
9
+ },
3
10
  "main": "index.js",
4
11
  "module": "index.js",
5
12
  "types": "index.d.ts",
6
13
  "sideEffects": false,
7
14
  "publishConfig": {
8
- "access": "public"
9
- },
10
- "scripts": {
11
- "start": "npm run playground",
12
- "dev": "`pushwoosh-engine app:command:dev`",
13
- "build": "pushwoosh-engine lib:build",
14
- "playground": "`pushwoosh-engine lib:command:playground`",
15
- "check": "npm run check:lint && npm run check:types && npm run test",
16
- "check:lint": "echo \"Run check:lint\" && NODE_ENV=production eslint src",
17
- "check:lint-fix": "echo \"Run check:lint\" && NODE_ENV=production eslint src --fix",
18
- "check:types": "echo \"Run check:types\" && pushwoosh-engine lib:check-types",
19
- "test": "echo \"Run test\" && vitest run"
20
- },
21
- "pre-commit": "check",
22
- "engines": {
23
- "node": ">= 24",
24
- "npm": ">= 7"
15
+ "access": "public",
16
+ "directory": "dist"
25
17
  },
26
18
  "dependencies": {
27
19
  "@floating-ui/react-dom": "^2.1.2",
28
- "@pushwoosh/dumb-components": "^2.1.1",
29
- "@pushwoosh/kit-constants": "^2.0.0",
30
- "@pushwoosh/kit-helpers": "^4.12.5",
20
+ "@pushwoosh/dumb-components": "^2.9.13",
21
+ "@pushwoosh/kit-constants": "^2.1.0",
22
+ "@pushwoosh/kit-helpers": "^4.12.7",
31
23
  "@pushwoosh/kit-icons": "^2.3.3",
32
- "@pushwoosh/kit-typography": "^1.8.5",
24
+ "@pushwoosh/kit-typography": "^1.8.7",
33
25
  "@pushwoosh/rpc-v2-http-api-data": "^0.2.151",
34
- "@pushwoosh/spa-context": "^1.7.1",
26
+ "@pushwoosh/spa-context": "^1.8.1",
35
27
  "idb-keyval": "^6.2.2",
36
28
  "jwt-decode": "^4.0.0",
37
29
  "react-hook-form": "^7.68.0",
38
30
  "react-router-dom": "^5.3.4"
39
31
  },
40
32
  "devDependencies": {
41
- "@pushwoosh/frontend-builder-engine": "^3.1.0",
33
+ "@pushwoosh/frontend-builder-engine": "^3.1.4",
42
34
  "@svgr/webpack": "^8.1.0",
43
- "@types/react": "^18.3.5",
44
- "@types/react-dom": "^18.3.0",
35
+ "@types/node": "^24.19.1",
36
+ "@types/react": "^18.3.31",
37
+ "@types/react-dom": "^18.3.7",
45
38
  "@types/react-router-dom": "^5.3.3",
46
39
  "@types/styled-components": "^5.1.34",
47
40
  "@types/webpack-env": "^1.18.8",
48
- "pre-commit": "^1.2.2",
49
41
  "react": "^18.3.1",
50
42
  "react-dom": "^18.3.1",
51
43
  "styled-components": "^5.3.11",
52
- "vitest": "^3.2.4"
44
+ "vitest": "^4.1.10"
53
45
  },
54
46
  "peerDependencies": {
55
47
  "react": "^18.0.0",
56
48
  "react-dom": "^18.0.0"
57
49
  },
58
- "version": "1.3.35"
59
- }
50
+ "engines": {
51
+ "node": ">= 24"
52
+ },
53
+ "scripts": {
54
+ "start": "pnpm run playground",
55
+ "build": "pushwoosh-engine lib:build",
56
+ "playground": "`pushwoosh-engine lib:command:playground`",
57
+ "check": "pnpm run check:lint && pnpm run check:types && pnpm run test",
58
+ "check:lint": "echo \"Run check:lint\" && NODE_ENV=production eslint src",
59
+ "check:lint-fix": "echo \"Run check:lint\" && NODE_ENV=production eslint src --fix",
60
+ "check:types": "echo \"Run check:types\" && pushwoosh-engine lib:check-types",
61
+ "test": "echo \"Run test\" && vitest run"
62
+ }
63
+ }
@@ -1 +0,0 @@
1
- export {};
@@ -1,59 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { parseContent } from './parseContent';
3
- // Compact projection: `**bold**` becomes [bold] so a case reads as one line.
4
- function sketch(blocks) {
5
- return blocks.map(block => {
6
- const lines = block.lines.map(line => line.nodes.map(node => node.type === 'bold' ? `[${node.value}]` : node.value).join(''));
7
- return block.type === 'list' ? `ul: ${lines.join(' | ')}` : `p: ${lines.join(' / ')}`;
8
- });
9
- }
10
- describe('parseContent', () => {
11
- it('splits paragraphs on a blank line', () => {
12
- expect(sketch(parseContent('first\n\nsecond'))).toEqual(['p: first', 'p: second']);
13
- });
14
- it('keeps a single newline inside one paragraph', () => {
15
- expect(sketch(parseContent('first\nsecond'))).toEqual(['p: first / second']);
16
- });
17
- it('collects consecutive bullets into one list', () => {
18
- expect(sketch(parseContent('- one\n- two\n- three'))).toEqual(['ul: one | two | three']);
19
- });
20
- it('reads bold inside a list item', () => {
21
- expect(sketch(parseContent('- plain **loud**'))).toEqual(['ul: plain [loud]']);
22
- });
23
- it('separates a lead-in line from the bullets that follow it', () => {
24
- expect(sketch(parseContent('what changed:\n- one\n- two\nand that is all'))).toEqual(['p: what changed:', 'ul: one | two', 'p: and that is all']);
25
- });
26
- it('treats three or more newlines as a single paragraph break', () => {
27
- expect(sketch(parseContent('first\n\n\n\nsecond'))).toEqual(['p: first', 'p: second']);
28
- });
29
- it('ignores blank lines around the content', () => {
30
- expect(sketch(parseContent('\n\n text \n\n'))).toEqual(['p: text']);
31
- });
32
- it('leaves a lone asterisk as text', () => {
33
- expect(sketch(parseContent('2 * 3 = 6'))).toEqual(['p: 2 * 3 = 6']);
34
- });
35
- it('does not read `* ` as a bullet marker', () => {
36
- expect(sketch(parseContent('* one\n* two'))).toEqual(['p: * one / * two']);
37
- });
38
- it('leaves an unclosed bold marker as text', () => {
39
- expect(sketch(parseContent('**loud and then not'))).toEqual(['p: **loud and then not']);
40
- });
41
- it('leaves an empty bold marker as text', () => {
42
- expect(sketch(parseContent('nothing **** here'))).toEqual(['p: nothing **** here']);
43
- });
44
- it('reads several bold runs in one line', () => {
45
- expect(sketch(parseContent('**a** and **b**'))).toEqual(['p: [a] and [b]']);
46
- });
47
- it('leaves HTML as text', () => {
48
- expect(sketch(parseContent('<b>test</b>'))).toEqual(['p: <b>test</b>']);
49
- });
50
- it('returns nothing for empty or blank content', () => {
51
- expect(parseContent('')).toEqual([]);
52
- expect(parseContent(' \n \n')).toEqual([]);
53
- });
54
- it('gives every block, line and node a unique id', () => {
55
- const blocks = parseContent('lead **in**\n- one **two**\n- three\n\ntail');
56
- const ids = blocks.flatMap(block => [block.id, ...block.lines.flatMap(line => [line.id, ...line.nodes.map(node => node.id)])]);
57
- expect(new Set(ids).size).toBe(ids.length);
58
- });
59
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,48 +0,0 @@
1
- import { createElement } from 'react';
2
- import { renderToStaticMarkup } from 'react-dom/server';
3
- import { ServerStyleSheet } from 'styled-components';
4
- import { describe, expect, it } from 'vitest';
5
- import { Table } from './styles';
6
- const render = () => {
7
- const sheet = new ServerStyleSheet();
8
- try {
9
- const html = renderToStaticMarkup(sheet.collectStyles(createElement(Table, {
10
- columns: '1fr 340px',
11
- width: '100%',
12
- isBordered: true
13
- })));
14
- return {
15
- html,
16
- css: sheet.getStyleTags()
17
- };
18
- } finally {
19
- sheet.seal();
20
- }
21
- };
22
- describe('Table', () => {
23
- it('denies columns and isBordered in shouldForwardProp, which SC 6 uses instead of isPropValid', () => {
24
- const {
25
- shouldForwardProp
26
- } = Table;
27
- expect(shouldForwardProp?.('columns')).toBe(false);
28
- expect(shouldForwardProp?.('isBordered')).toBe(false);
29
- expect(shouldForwardProp?.('width')).toBe(true);
30
- });
31
- it('does not forward columns and isBordered to the DOM', () => {
32
- const {
33
- html
34
- } = render();
35
- expect(html).not.toMatch(/columns=/i);
36
- expect(html).not.toMatch(/isbordered=/i);
37
- });
38
- it('keeps width as a DOM attribute', () => {
39
- expect(render().html).toContain('width="100%"');
40
- });
41
- it('still styles from columns and isBordered', () => {
42
- const {
43
- css
44
- } = render();
45
- expect(css).toContain('--table-columns:1fr 340px');
46
- expect(css).toMatch(/border:1px solid/);
47
- });
48
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,49 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { isStaffImpersonation } from './isStaffImpersonation';
3
- function tokenWith(claims) {
4
- const payload = Buffer.from(JSON.stringify(claims)).toString('base64url');
5
- return `eyJhbGciOiJub25lIn0.${payload}.signature`;
6
- }
7
- function clientWith(token) {
8
- return {
9
- getAccessToken: async () => {
10
- if (token instanceof Error) {
11
- throw token;
12
- }
13
- return token;
14
- }
15
- };
16
- }
17
- describe('isStaffImpersonation', () => {
18
- it('is false for a plain client login', async () => {
19
- await expect(isStaffImpersonation(clientWith(tokenWith({
20
- account_id: 42
21
- })))).resolves.toBe(false);
22
- });
23
- it('is true for staff impersonation without parent_user_id', async () => {
24
- await expect(isStaffImpersonation(clientWith(tokenWith({
25
- is_su: true
26
- })))).resolves.toBe(true);
27
- });
28
- it('is true for staff impersonation with parent_user_id "0"', async () => {
29
- await expect(isStaffImpersonation(clientWith(tokenWith({
30
- is_su: true,
31
- parent_user_id: '0'
32
- })))).resolves.toBe(true);
33
- });
34
- it('is false for a client switched into their own child account', async () => {
35
- await expect(isStaffImpersonation(clientWith(tokenWith({
36
- is_su: true,
37
- parent_user_id: '77123'
38
- })))).resolves.toBe(false);
39
- });
40
- it('is false when the token carries no claims at all', async () => {
41
- await expect(isStaffImpersonation(clientWith(tokenWith({})))).resolves.toBe(false);
42
- });
43
- it('is false for a garbage token', async () => {
44
- await expect(isStaffImpersonation(clientWith('not-a-jwt'))).resolves.toBe(false);
45
- });
46
- it('is false when there is no token to read', async () => {
47
- await expect(isStaffImpersonation(clientWith(new Error('Unauthorized!')))).resolves.toBe(false);
48
- });
49
- });