@dotcms/react 0.0.1-alpha.11 → 0.0.1-alpha.12

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.
Files changed (41) hide show
  1. package/index.esm.d.ts +1 -0
  2. package/index.esm.js +1928 -0
  3. package/package.json +30 -27
  4. package/src/lib/components/Column/Column.d.ts +5 -0
  5. package/src/lib/components/Container/Container.d.ts +5 -0
  6. package/src/lib/components/DotcmsLayout/{DotcmsLayout.tsx → DotcmsLayout.d.ts} +3 -17
  7. package/src/lib/components/PageProvider/{PageProvider.tsx → PageProvider.d.ts} +1 -12
  8. package/src/lib/components/Row/Row.d.ts +25 -0
  9. package/src/lib/contexts/PageContext.d.ts +3 -0
  10. package/src/lib/hooks/useDotcmsEditor.d.ts +2 -0
  11. package/src/lib/hooks/{useDotcmsPageContext.tsx → useDotcmsPageContext.d.ts} +1 -7
  12. package/src/lib/mocks/mockPageContext.d.ts +7 -0
  13. package/src/lib/utils/utils.d.ts +22 -0
  14. package/.babelrc +0 -12
  15. package/.eslintrc.json +0 -18
  16. package/jest.config.ts +0 -11
  17. package/project.json +0 -51
  18. package/src/lib/components/Column/Column.module.css +0 -99
  19. package/src/lib/components/Column/Column.spec.tsx +0 -78
  20. package/src/lib/components/Column/Column.tsx +0 -45
  21. package/src/lib/components/Container/Container.module.css +0 -7
  22. package/src/lib/components/Container/Container.spec.tsx +0 -82
  23. package/src/lib/components/Container/Container.tsx +0 -106
  24. package/src/lib/components/DotcmsLayout/DotcmsLayout.module.css +0 -7
  25. package/src/lib/components/DotcmsLayout/DotcmsLayout.spec.tsx +0 -41
  26. package/src/lib/components/PageProvider/PageProvider.module.css +0 -7
  27. package/src/lib/components/PageProvider/PageProvider.spec.tsx +0 -54
  28. package/src/lib/components/Row/Row.module.css +0 -5
  29. package/src/lib/components/Row/Row.spec.tsx +0 -92
  30. package/src/lib/components/Row/Row.tsx +0 -51
  31. package/src/lib/contexts/PageContext.tsx +0 -5
  32. package/src/lib/hooks/useDotcmsEditor.spec.ts +0 -56
  33. package/src/lib/hooks/useDotcmsEditor.ts +0 -29
  34. package/src/lib/hooks/useDotcmsPageContext.spec.tsx +0 -43
  35. package/src/lib/mocks/mockPageContext.tsx +0 -84
  36. package/src/lib/utils/utils.ts +0 -69
  37. package/tsconfig.json +0 -20
  38. package/tsconfig.lib.json +0 -23
  39. package/tsconfig.spec.json +0 -20
  40. /package/src/{index.ts → index.d.ts} +0 -0
  41. /package/src/lib/mocks/{index.ts → index.d.ts} +0 -0
@@ -1,106 +0,0 @@
1
- import { useContext } from 'react';
2
-
3
- import { PageContext } from '../../contexts/PageContext';
4
- import { getContainersData } from '../../utils/utils';
5
- import { PageProviderContext } from '../PageProvider/PageProvider';
6
-
7
- const FAKE_CONTENLET = {
8
- identifier: 'TEMP_EMPTY_CONTENTLET',
9
- title: 'TEMP_EMPTY_CONTENTLET',
10
- contentType: 'TEMP_EMPTY_CONTENTLET_TYPE',
11
- inode: 'TEMPY_EMPTY_CONTENTLET_INODE',
12
- widgetTitle: 'TEMP_EMPTY_CONTENTLET',
13
- onNumberOfPages: 1
14
- };
15
-
16
- function EmptyContainer() {
17
- return (
18
- <div
19
- data-testid="empty-container"
20
- style={{
21
- width: '100%',
22
- backgroundColor: '#ECF0FD',
23
- display: 'flex',
24
- justifyContent: 'center',
25
- alignItems: 'center',
26
- color: '#030E32',
27
- height: '10rem'
28
- }}>
29
- This container is empty.
30
- </div>
31
- );
32
- }
33
-
34
- function NoContent({ contentType }: { readonly contentType: string }) {
35
- return <div data-testid="no-component">No Component for {contentType}</div>;
36
- }
37
-
38
- export interface ContainerProps {
39
- readonly containerRef: PageProviderContext['layout']['body']['rows'][0]['columns'][0]['containers'][0];
40
- }
41
-
42
- export function Container({ containerRef }: ContainerProps) {
43
- const { isInsideEditor } = useContext(PageContext) as PageProviderContext;
44
-
45
- const { identifier, uuid } = containerRef;
46
-
47
- // Get the containers from the global context
48
- const { containers, components } = useContext<PageProviderContext | null>(
49
- PageContext
50
- ) as PageProviderContext;
51
-
52
- const { acceptTypes, contentlets, maxContentlets, variantId, path } = getContainersData(
53
- containers,
54
- containerRef
55
- );
56
-
57
- const updatedContentlets =
58
- contentlets.length === 0 && isInsideEditor ? [FAKE_CONTENLET] : contentlets;
59
-
60
- const container = {
61
- acceptTypes,
62
- identifier: path ?? identifier,
63
- maxContentlets,
64
- variantId,
65
- uuid
66
- };
67
-
68
- const renderContentlets = updatedContentlets.map((contentlet) => {
69
- const ContentTypeComponent = components[contentlet.contentType] || NoContent;
70
-
71
- const Component =
72
- contentlet.identifier === 'TEMP_EMPTY_CONTENTLET'
73
- ? EmptyContainer
74
- : ContentTypeComponent;
75
-
76
- return isInsideEditor ? (
77
- <div
78
- data-dot-object="contentlet"
79
- data-dot-identifier={contentlet.identifier}
80
- data-dot-title={contentlet.widgetTitle || contentlet.title}
81
- data-dot-inode={contentlet.inode}
82
- data-dot-type={contentlet.contentType}
83
- data-dot-container={JSON.stringify(container)}
84
- data-dot-on-number-of-pages={contentlet.onNumberOfPages}
85
- key={contentlet.identifier}>
86
- <Component {...contentlet} />
87
- </div>
88
- ) : (
89
- <Component {...contentlet} key={contentlet.identifier} />
90
- );
91
- });
92
-
93
- return isInsideEditor ? (
94
- <div
95
- data-dot-object="container"
96
- data-dot-accept-types={acceptTypes}
97
- data-dot-identifier={path ?? identifier}
98
- data-max-contentlets={maxContentlets}
99
- data-uuid={uuid}>
100
- {renderContentlets}
101
- </div>
102
- ) : (
103
- // eslint-disable-next-line react/jsx-no-useless-fragment
104
- <>{renderContentlets}</>
105
- );
106
- }
@@ -1,7 +0,0 @@
1
- /*
2
- * Replace this with your own classes
3
- *
4
- * e.g.
5
- * .container {
6
- * }
7
- */
@@ -1,41 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- import { render, screen } from '@testing-library/react';
3
- import { ElementRef, ForwardRefExoticComponent } from 'react';
4
-
5
- import { DotcmsLayout } from './DotcmsLayout';
6
-
7
- import { mockPageContext } from '../../mocks/mockPageContext';
8
-
9
- jest.mock('../Row/Row', () => {
10
- const { forwardRef } = jest.requireActual('react');
11
-
12
- return {
13
- Row: forwardRef(
14
- (
15
- { children }: { children: JSX.Element },
16
- ref: ElementRef<ForwardRefExoticComponent<unknown>>
17
- ) => (
18
- <div data-testid="mockRow" ref={ref}>
19
- {children}
20
- </div>
21
- )
22
- )
23
- };
24
- });
25
-
26
- jest.mock('../PageProvider/PageProvider', () => {
27
- return {
28
- PageProvider: ({ children }: { children: JSX.Element }) => (
29
- <div data-testid="mockPageProvider">{children}</div>
30
- )
31
- };
32
- });
33
-
34
- describe('DotcmsLayout', () => {
35
- it('renders correctly with PageProvider and rows', () => {
36
- render(<DotcmsLayout entity={{ ...mockPageContext, isInsideEditor: true }} />);
37
- expect(screen.getAllByTestId('mockRow').length).toBe(
38
- mockPageContext.layout.body.rows.length
39
- );
40
- });
41
- });
@@ -1,7 +0,0 @@
1
- /*
2
- * Replace this with your own classes
3
- *
4
- * e.g.
5
- * .container {
6
- * }
7
- */
@@ -1,54 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
- import React from 'react';
3
-
4
- import '@testing-library/jest-dom';
5
- import { PageProvider } from './PageProvider';
6
-
7
- import { PageContext } from '../../contexts/PageContext';
8
-
9
- const MockChildComponent = () => {
10
- const context = React.useContext(PageContext);
11
-
12
- return <div data-testid="mockChild">{JSON.stringify(context?.page.title)}</div>;
13
- };
14
-
15
- describe('PageProvider', () => {
16
- const mockEntity = {
17
- page: {
18
- title: 'Test Page',
19
- identifier: 'test-page-1'
20
- }
21
- // ... add other context properties as needed
22
- };
23
-
24
- it('provides the context to its children', () => {
25
- render(
26
- <PageProvider entity={mockEntity}>
27
- <MockChildComponent />
28
- </PageProvider>
29
- );
30
- expect(screen.getByTestId('mockChild')).toHaveTextContent(mockEntity.page.title);
31
- });
32
-
33
- it('updates context when entity changes', () => {
34
- const { rerender } = render(
35
- <PageProvider entity={mockEntity}>
36
- <MockChildComponent />
37
- </PageProvider>
38
- );
39
- // Change the context
40
- const newEntity = {
41
- ...mockEntity,
42
- page: {
43
- ...mockEntity.page,
44
- title: 'Updated Test Page'
45
- }
46
- };
47
- rerender(
48
- <PageProvider entity={newEntity}>
49
- <MockChildComponent />
50
- </PageProvider>
51
- );
52
- expect(screen.getByTestId('mockChild')).toHaveTextContent(newEntity.page.title);
53
- });
54
- });
@@ -1,5 +0,0 @@
1
- .row {
2
- display: grid;
3
- grid-template-columns: repeat(12, 1fr);
4
- gap: 1rem;
5
- }
@@ -1,92 +0,0 @@
1
- import { render, screen } from '@testing-library/react';
2
-
3
- import { Row } from './Row';
4
-
5
- import { MockContextRender } from '../../mocks/mockPageContext';
6
- import { ColumnProps } from '../Column/Column';
7
- import { PageProviderContext } from '../PageProvider/PageProvider';
8
-
9
- import '@testing-library/jest-dom';
10
-
11
- jest.mock('../Column/Column', () => {
12
- return {
13
- Column: ({ column }: ColumnProps) => (
14
- <div data-testid="mockColumn">{JSON.stringify(column)}</div>
15
- )
16
- };
17
- });
18
-
19
- describe('Row', () => {
20
- const mockRowData: PageProviderContext['layout']['body']['rows'][0] = {
21
- columns: [
22
- {
23
- width: 60,
24
- leftOffset: 2,
25
- containers: [
26
- {
27
- identifier: '123',
28
- uuid: '1'
29
- }
30
- ],
31
- styleClass: ''
32
- },
33
- {
34
- width: 20,
35
- leftOffset: 0,
36
- containers: [
37
- {
38
- identifier: '456',
39
- uuid: '2'
40
- }
41
- ],
42
- styleClass: ''
43
- }
44
- ],
45
- styleClass: ''
46
- };
47
-
48
- describe('row is inside editor', () => {
49
- beforeEach(() => {
50
- render(
51
- <MockContextRender mockContext={{ isInsideEditor: true }}>
52
- <Row row={mockRowData} />
53
- </MockContextRender>
54
- );
55
- });
56
-
57
- it('should set the data-dot attribute', () => {
58
- expect(screen.getByTestId('row')).toHaveAttribute('data-dot', 'row');
59
- });
60
-
61
- it('renders the correct number of mock columns', () => {
62
- const mockColumns = screen.getAllByTestId('mockColumn');
63
- expect(mockColumns.length).toBe(mockRowData.columns.length);
64
- });
65
-
66
- it('passes the correct props to each mock Column', () => {
67
- mockRowData.columns.forEach((column, index) => {
68
- expect(screen.getAllByTestId('mockColumn')[index].innerHTML).toBe(
69
- JSON.stringify(column)
70
- );
71
- });
72
- });
73
-
74
- it('renders the correct number of columns', () => {
75
- const columns = screen.getAllByTestId('mockColumn');
76
- expect(columns.length).toBe(mockRowData.columns.length);
77
- });
78
- });
79
- describe('row is not inside editor', () => {
80
- beforeEach(() => {
81
- render(
82
- <MockContextRender mockContext={{ isInsideEditor: false }}>
83
- <Row row={mockRowData} />
84
- </MockContextRender>
85
- );
86
- });
87
-
88
- it('should not have dot attr', () => {
89
- expect(screen.queryByTestId('row')).toBeNull();
90
- });
91
- });
92
- });
@@ -1,51 +0,0 @@
1
- import { forwardRef, useContext } from 'react';
2
-
3
- import styles from './row.module.css';
4
-
5
- import { PageContext } from '../../contexts/PageContext';
6
- import { combineClasses } from '../../utils/utils';
7
- import { Column } from '../Column/Column';
8
- import { PageProviderContext } from '../PageProvider/PageProvider';
9
-
10
- /**
11
- * Props for the row component
12
- *
13
- * @interface RowProps
14
- *
15
- */
16
- export interface RowProps {
17
- /**
18
- * Row data
19
- *
20
- * @type {PageProviderContext['layout']['body']['rows'][0]}
21
- * @memberof RowProps
22
- */
23
- row: PageProviderContext['layout']['body']['rows'][0];
24
- }
25
-
26
- /**
27
- * Renders a row
28
- *
29
- * @category Components
30
- * @param {React.ForwardedRef<HTMLDivElement, RowProps>} ref
31
- * @return {*}
32
- */
33
- export const Row = forwardRef<HTMLDivElement, RowProps>((props: RowProps, ref) => {
34
- const { isInsideEditor } = useContext<PageProviderContext | null>(
35
- PageContext
36
- ) as PageProviderContext;
37
-
38
- const { row } = props;
39
-
40
- const combinedClasses = combineClasses([styles.row, row.styleClass]);
41
-
42
- const rowProps = isInsideEditor ? { 'data-dot': 'row', 'data-testid': 'row', ref } : {};
43
-
44
- return (
45
- <div {...rowProps} className={combinedClasses}>
46
- {row.columns.map((column, index) => (
47
- <Column key={index} column={column} />
48
- ))}
49
- </div>
50
- );
51
- });
@@ -1,5 +0,0 @@
1
- import { createContext } from 'react';
2
-
3
- import { PageProviderContext } from '../components/PageProvider/PageProvider';
4
-
5
- export const PageContext = createContext<PageProviderContext | null>(null);
@@ -1,56 +0,0 @@
1
- import { renderHook } from '@testing-library/react-hooks';
2
-
3
- import * as dotcmsClient from '@dotcms/client';
4
-
5
- import { useDotcmsEditor } from './useDotcmsEditor';
6
-
7
- describe('useDotcmsEditor', () => {
8
- let isInsideEditorSpy: jest.SpyInstance<boolean>;
9
- let initEditorSpy: jest.SpyInstance<void>;
10
- let destroyEditorSpy: jest.SpyInstance<void>;
11
-
12
- beforeEach(() => {
13
- isInsideEditorSpy = jest.spyOn(dotcmsClient, 'isInsideEditor');
14
- initEditorSpy = jest.spyOn(dotcmsClient, 'initEditor');
15
- destroyEditorSpy = jest.spyOn(dotcmsClient, 'destroyEditor');
16
- });
17
-
18
- afterEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should call initEditor when inside editor', () => {
23
- isInsideEditorSpy.mockReturnValueOnce(true);
24
-
25
- renderHook(() => useDotcmsEditor());
26
-
27
- expect(initEditorSpy).toHaveBeenCalled();
28
- });
29
-
30
- it('should call destroyEditor on unmount when inside editor', () => {
31
- isInsideEditorSpy.mockReturnValueOnce(true);
32
-
33
- const { unmount } = renderHook(() => useDotcmsEditor());
34
-
35
- unmount();
36
-
37
- expect(destroyEditorSpy).toHaveBeenCalled();
38
- });
39
-
40
- it('should not call initEditor or destroyEditor when outside editor', () => {
41
- isInsideEditorSpy.mockReturnValueOnce(false);
42
-
43
- renderHook(() => useDotcmsEditor());
44
-
45
- expect(initEditorSpy).not.toHaveBeenCalled();
46
- expect(destroyEditorSpy).not.toHaveBeenCalled();
47
- });
48
-
49
- it('should call initEditor with options', () => {
50
- isInsideEditorSpy.mockReturnValueOnce(true);
51
-
52
- renderHook(() => useDotcmsEditor({ onReload: jest.fn() }));
53
-
54
- expect(initEditorSpy).toHaveBeenCalledWith({ onReload: expect.any(Function) });
55
- });
56
- });
@@ -1,29 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- import {
4
- DotCMSPageEditorConfig,
5
- destroyEditor,
6
- initEditor,
7
- isInsideEditor,
8
- updateNavigation
9
- } from '@dotcms/client';
10
- export const useDotcmsEditor = (config?: DotCMSPageEditorConfig) => {
11
- const [isInsideEditorPage, setIsInsideEditorPage] = useState(false);
12
- useEffect(() => {
13
- const insideEditor = isInsideEditor();
14
- if (insideEditor) {
15
- initEditor(config);
16
- updateNavigation(config?.pathname || '/');
17
- }
18
-
19
- setIsInsideEditorPage(insideEditor);
20
-
21
- return () => {
22
- if (insideEditor) {
23
- destroyEditor();
24
- }
25
- };
26
- }, [config]);
27
-
28
- return isInsideEditorPage;
29
- };
@@ -1,43 +0,0 @@
1
- import { renderHook } from '@testing-library/react-hooks';
2
- import { ReactNode } from 'react';
3
-
4
- import { useDotcmsPageContext } from './useDotcmsPageContext'; // Adjust the import path based on your file structure.
5
-
6
- import { PageProviderContext } from '../components/PageProvider/PageProvider';
7
- import { PageContext } from '../contexts/PageContext';
8
-
9
- const mockContextValue: PageProviderContext = {
10
- components: {},
11
- containers: {},
12
- layout: {
13
- header: false,
14
- footer: false,
15
- body: {
16
- rows: []
17
- }
18
- },
19
- page: {
20
- title: 'Test Page',
21
- identifier: 'test-page'
22
- },
23
- viewAs: {
24
- language: {
25
- id: 'en'
26
- },
27
- persona: {
28
- keyTag: 'persona'
29
- }
30
- }
31
- };
32
-
33
- describe('useDotcmsPageContext', () => {
34
- it('returns the context value', () => {
35
- const { result } = renderHook(() => useDotcmsPageContext(), {
36
- wrapper: ({ children }: { children: ReactNode }) => (
37
- <PageContext.Provider value={mockContextValue}>{children}</PageContext.Provider>
38
- )
39
- });
40
-
41
- expect(result.current).toEqual(mockContextValue);
42
- });
43
- });
@@ -1,84 +0,0 @@
1
- import { PageProvider, PageProviderContext } from '../components/PageProvider/PageProvider';
2
-
3
- export const mockPageContext: PageProviderContext = {
4
- layout: {
5
- header: true,
6
- footer: true,
7
- body: {
8
- rows: [
9
- {
10
- styleClass: 'row',
11
- columns: [
12
- {
13
- styleClass: 'col-md-12',
14
- width: 6,
15
- leftOffset: 3,
16
- containers: [
17
- {
18
- identifier: 'container-1',
19
- uuid: 'uuid-1'
20
- }
21
- ]
22
- }
23
- ]
24
- }
25
- ]
26
- }
27
- },
28
- containers: {
29
- 'container-1': {
30
- container: {
31
- path: 'path/to/container',
32
- identifier: 'container-1',
33
- maxContentlets: 100,
34
- parentPermissionable: {}
35
- },
36
- containerStructures: [
37
- {
38
- contentTypeVar: 'content-type-1'
39
- }
40
- ],
41
- contentlets: {
42
- 'uuid-1': [
43
- {
44
- contentType: 'content-type-1',
45
- identifier: 'contentlet-1',
46
- title: 'Contentlet 1',
47
- inode: 'inode-1',
48
- onNumberOfPages: 1
49
- }
50
- ]
51
- }
52
- },
53
- 'container-2': {
54
- container: {
55
- path: 'path/to/container',
56
- identifier: 'container-2',
57
- maxContentlets: 100,
58
- parentPermissionable: {}
59
- },
60
- containerStructures: [
61
- {
62
- contentTypeVar: 'content-type-2'
63
- }
64
- ],
65
- contentlets: {
66
- 'uuid-2': []
67
- }
68
- }
69
- },
70
- page: { identifier: 'page-1', title: 'Hello Page' },
71
- viewAs: { language: { id: 'en' }, persona: { keyTag: 'persona-1' } },
72
- components: {},
73
- isInsideEditor: false
74
- };
75
-
76
- export const MockContextRender = ({
77
- children,
78
- mockContext
79
- }: {
80
- children: JSX.Element;
81
- mockContext: Partial<PageProviderContext>;
82
- }) => {
83
- return <PageProvider entity={mockContext}>{children}</PageProvider>;
84
- };
@@ -1,69 +0,0 @@
1
- import { ContainerData, PageProviderContext } from '../components/PageProvider/PageProvider';
2
-
3
- const endClassMap: Record<number, string> = {
4
- 1: 'col-end-1',
5
- 2: 'col-end-2',
6
- 3: 'col-end-3',
7
- 4: 'col-end-4',
8
- 5: 'col-end-5',
9
- 6: 'col-end-6',
10
- 7: 'col-end-7',
11
- 8: 'col-end-8',
12
- 9: 'col-end-9',
13
- 10: 'col-end-10',
14
- 11: 'col-end-11',
15
- 12: 'col-end-12',
16
- 13: 'col-end-13'
17
- };
18
-
19
- const startClassMap: Record<number, string> = {
20
- 1: 'col-start-1',
21
- 2: 'col-start-2',
22
- 3: 'col-start-3',
23
- 4: 'col-start-4',
24
- 5: 'col-start-5',
25
- 6: 'col-start-6',
26
- 7: 'col-start-7',
27
- 8: 'col-start-8',
28
- 9: 'col-start-9',
29
- 10: 'col-start-10',
30
- 11: 'col-start-11',
31
- 12: 'col-start-12'
32
- };
33
-
34
- export const getContainersData = (
35
- containers: ContainerData,
36
- containerRef: PageProviderContext['layout']['body']['rows'][0]['columns'][0]['containers'][0]
37
- ) => {
38
- const { identifier, uuid } = containerRef;
39
-
40
- const { containerStructures, container } = containers[identifier];
41
-
42
- // Get the variant id
43
- const { variantId } = container?.parentPermissionable || {};
44
-
45
- // Get accepts types of content types for this container
46
- const acceptTypes = containerStructures.map((structure) => structure.contentTypeVar).join(',');
47
-
48
- // Get the contentlets for "this" container
49
- const contentlets = containers[identifier].contentlets[`uuid-${uuid}`];
50
-
51
- return {
52
- ...containers[identifier].container,
53
- acceptTypes,
54
- contentlets,
55
- variantId
56
- };
57
- };
58
-
59
- export const combineClasses = (classes: string[]) => classes.filter(Boolean).join(' ');
60
-
61
- export const getPositionStyleClasses = (start: number, end: number) => {
62
- const startClass = startClassMap[start];
63
- const endClass = endClassMap[end];
64
-
65
- return {
66
- startClass,
67
- endClass
68
- };
69
- };
package/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "jsx": "react-jsx",
4
- "allowJs": false,
5
- "esModuleInterop": false,
6
- "allowSyntheticDefaultImports": true,
7
- "strict": true
8
- },
9
- "files": [],
10
- "include": [],
11
- "references": [
12
- {
13
- "path": "./tsconfig.lib.json"
14
- },
15
- {
16
- "path": "./tsconfig.spec.json"
17
- }
18
- ],
19
- "extends": "../../../tsconfig.base.json"
20
- }