docusaurus-plugin-generate-schema-docs 1.2.0 → 1.4.0
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/README.md +70 -6
- package/__tests__/ExampleDataLayer.test.js +91 -155
- package/__tests__/__fixtures__/static/schemas/add-to-cart-event.json +4 -15
- package/__tests__/__fixtures__/static/schemas/anchor/parent-event-anchor.json +29 -0
- package/__tests__/__fixtures__/static/schemas/choice-event.json +72 -0
- package/__tests__/__fixtures__/static/schemas/components/dataLayer.json +52 -54
- package/__tests__/__fixtures__/static/schemas/components/product.json +124 -210
- package/__tests__/__fixtures__/static/schemas/nested/child-event.json +10 -0
- package/__tests__/__fixtures__/static/schemas/nested/grandchild-a.json +9 -0
- package/__tests__/__fixtures__/static/schemas/nested/grandchild-b.json +9 -0
- package/__tests__/__fixtures__/static/schemas/nested/parent-event.json +7 -0
- package/__tests__/__fixtures__/static/schemas/root-any-of-event.json +34 -0
- package/__tests__/__fixtures__/static/schemas/root-choice-event.json +36 -0
- package/__tests__/__fixtures__/validateSchemas/circular-schema.json +6 -6
- package/__tests__/__fixtures__/validateSchemas/components/referenced.json +9 -7
- package/__tests__/__fixtures__/validateSchemas/invalid-example-schema.json +7 -7
- package/__tests__/__fixtures__/validateSchemas/main-schema-with-missing-ref.json +7 -7
- package/__tests__/__fixtures__/validateSchemas/main-schema-with-ref.json +7 -7
- package/__tests__/__fixtures__/validateSchemas/no-example-schema.json +11 -11
- package/__tests__/__fixtures__/validateSchemas/schema-A.json +5 -5
- package/__tests__/__fixtures__/validateSchemas/schema-B.json +5 -5
- package/__tests__/__fixtures__/validateSchemas/valid-schema.json +7 -7
- package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/add-to-cart-event.json +44 -0
- package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/dataLayer.json +56 -0
- package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/product.json +125 -0
- package/__tests__/__fixtures_versioned__/static/schemas/next/add-to-cart-event.json +44 -0
- package/__tests__/__fixtures_versioned__/static/schemas/next/components/dataLayer.json +56 -0
- package/__tests__/__fixtures_versioned__/static/schemas/next/components/product.json +125 -0
- package/__tests__/__fixtures_versioned__/versions.json +1 -0
- package/__tests__/__snapshots__/ExampleDataLayer.test.js.snap +117 -0
- package/__tests__/__snapshots__/generateEventDocs.anchor.test.js.snap +79 -0
- package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +98 -0
- package/__tests__/__snapshots__/generateEventDocs.test.js.snap +129 -16
- package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +59 -0
- package/__tests__/components/FoldableRows.test.js +330 -0
- package/__tests__/components/PropertiesTable.test.js +67 -17
- package/__tests__/components/PropertyRow.test.js +471 -51
- package/__tests__/components/SchemaJsonViewer.test.js +23 -19
- package/__tests__/components/SchemaRows.test.js +96 -66
- package/__tests__/components/SchemaViewer.test.js +34 -17
- package/__tests__/components/TableHeader.test.js +12 -12
- package/__tests__/generateEventDocs.anchor.test.js +71 -0
- package/__tests__/generateEventDocs.nested.test.js +80 -0
- package/__tests__/generateEventDocs.test.js +77 -71
- package/__tests__/generateEventDocs.versioned.test.js +69 -0
- package/__tests__/helpers/buildExampleFromSchema.test.js +160 -160
- package/__tests__/helpers/example-helper.test.js +71 -0
- package/__tests__/helpers/file-system.test.js +44 -0
- package/__tests__/helpers/getConstraints.test.js +93 -48
- package/__tests__/helpers/loadSchema.test.js +11 -5
- package/__tests__/helpers/path-helpers.test.js +34 -0
- package/__tests__/helpers/processSchema.test.js +42 -22
- package/__tests__/helpers/schema-processing.test.js +82 -0
- package/__tests__/helpers/schemaToExamples.test.js +56 -0
- package/__tests__/helpers/schemaToTableData.filtering.test.js +65 -0
- package/__tests__/helpers/schemaToTableData.hierarchicalLines.test.js +539 -0
- package/__tests__/helpers/schemaToTableData.test.js +217 -0
- package/__tests__/helpers/update-schema-ids.test.js +107 -0
- package/__tests__/update-schema-ids.test.js +39 -0
- package/__tests__/validateSchemas.test.js +125 -88
- package/components/ExampleDataLayer.js +68 -28
- package/components/FoldableRows.js +164 -0
- package/components/PropertiesTable.js +24 -6
- package/components/PropertiesTable.module.css +27 -0
- package/components/PropertyRow.js +168 -60
- package/components/SchemaJsonViewer.js +6 -6
- package/components/SchemaRows.css +242 -14
- package/components/SchemaRows.js +24 -41
- package/components/SchemaViewer.js +20 -14
- package/components/TableHeader.js +12 -12
- package/components/WordWrapButton.js +31 -0
- package/components/wordWrapButton.module.css +8 -0
- package/generateEventDocs.js +142 -61
- package/helpers/buildExampleFromSchema.js +60 -72
- package/helpers/choice-index-template.js +22 -0
- package/helpers/example-helper.js +41 -0
- package/helpers/file-system.js +32 -0
- package/helpers/getConstraints.js +44 -44
- package/helpers/loadSchema.js +2 -2
- package/helpers/path-helpers.js +22 -0
- package/helpers/processSchema.js +19 -19
- package/helpers/{mdx-template.js → schema-doc-template.js} +20 -13
- package/helpers/schema-processing.js +77 -0
- package/helpers/schemaToExamples.js +99 -0
- package/helpers/schemaToTableData.js +312 -0
- package/helpers/update-schema-ids.js +47 -0
- package/index.js +153 -55
- package/package.json +1 -1
- package/validateSchemas.js +56 -71
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ npm install --save docusaurus-plugin-generate-schema-docs
|
|
|
29
29
|
'docusaurus-plugin-generate-schema-docs',
|
|
30
30
|
{
|
|
31
31
|
// Options if any
|
|
32
|
+
dataLayerName: 'customDataLayer',
|
|
32
33
|
},
|
|
33
34
|
],
|
|
34
35
|
],
|
|
@@ -36,6 +37,8 @@ npm install --save docusaurus-plugin-generate-schema-docs
|
|
|
36
37
|
};
|
|
37
38
|
```
|
|
38
39
|
|
|
40
|
+
The `dataLayerName` option allows you to customize the name of the data layer variable in the generated examples. If not provided, it defaults to `dataLayer`.
|
|
41
|
+
|
|
39
42
|
2. Place your JSON schemas in the `schemas` directory at the root of your project.
|
|
40
43
|
|
|
41
44
|
## CLI Commands
|
|
@@ -45,7 +48,7 @@ npm install --save docusaurus-plugin-generate-schema-docs
|
|
|
45
48
|
To generate the documentation from your schemas, run the following command:
|
|
46
49
|
|
|
47
50
|
```bash
|
|
48
|
-
|
|
51
|
+
npm run gen-docs
|
|
49
52
|
```
|
|
50
53
|
|
|
51
54
|
This will generate MDX files in the `docs/events` directory.
|
|
@@ -55,17 +58,78 @@ This will generate MDX files in the `docs/events` directory.
|
|
|
55
58
|
To validate your schemas, run the following command:
|
|
56
59
|
|
|
57
60
|
```bash
|
|
58
|
-
|
|
61
|
+
npm run validate-schemas
|
|
59
62
|
```
|
|
60
63
|
|
|
61
64
|
This will validate the schemas in the `schemas` directory.
|
|
62
65
|
|
|
66
|
+
### Update Schema IDs
|
|
67
|
+
|
|
68
|
+
When using versioning, you can update the `$id` of your versioned schemas by running:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm run update-schema-ids
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This command will update the `$id` of all schemas in the versioned directories.
|
|
75
|
+
|
|
63
76
|
## How it Works
|
|
64
77
|
|
|
65
78
|
The plugin reads your JSON schemas, dereferences any `$ref` properties, and merges `allOf` properties. It then generates an MDX file for each schema, which uses custom React components to render the schema details.
|
|
66
79
|
|
|
67
80
|
The validation script builds an example from each schema and validates it against the schema itself, ensuring your examples are always in sync with your schemas.
|
|
68
81
|
|
|
82
|
+
## Schema Composition (anyOf, oneOf)
|
|
83
|
+
|
|
84
|
+
The plugin has special handling for `anyOf` and `oneOf` keywords in your JSON schemas.
|
|
85
|
+
|
|
86
|
+
### `anyOf`
|
|
87
|
+
|
|
88
|
+
When `anyOf` is used, the plugin will render a dropdown menu in the documentation that allows users to switch between the different sub-schemas. This is useful for representing properties that can have multiple different structures.
|
|
89
|
+
|
|
90
|
+
### `oneOf`
|
|
91
|
+
|
|
92
|
+
Similar to `anyOf`, `oneOf` will also render a dropdown menu.
|
|
93
|
+
|
|
94
|
+
#### `oneOf` at the Root Level
|
|
95
|
+
|
|
96
|
+
A special behavior is triggered when `oneOf` is used at the root level of a schema file. If a schema's top-level definition is a `oneOf` array, the plugin will generate a directory structure that reflects the choices.
|
|
97
|
+
|
|
98
|
+
For example, given a schema `my-event.json` with a `oneOf` at the root, where each item in the `oneOf` array is a reference to another schema file (e.g., `option-a.json`, `option-b.json`), the plugin will generate the following structure:
|
|
99
|
+
|
|
100
|
+
- `docs/events/my-event/`: A directory for the parent schema.
|
|
101
|
+
- `docs/events/my-event/index.mdx`: An index page for `my-event`.
|
|
102
|
+
- `docs/events/my-event/option-a.mdx`: A page for the first option.
|
|
103
|
+
- `docs/events/my-event/option-b.mdx`: A page for the second option.
|
|
104
|
+
|
|
105
|
+
This creates a nested navigation structure in Docusaurus, which is useful for grouping related events or entities under a single menu item.
|
|
106
|
+
|
|
107
|
+
## Versioning
|
|
108
|
+
|
|
109
|
+
This plugin supports documentation and schema versioning, integrated with Docusaurus's native versioning system.
|
|
110
|
+
|
|
111
|
+
### Enabling Versioning
|
|
112
|
+
|
|
113
|
+
To enable versioning, you need to:
|
|
114
|
+
|
|
115
|
+
1. **Enable Docusaurus Versioning**: Follow the [Docusaurus documentation](https://docusaurus.io/docs/versioning) to enable versioning for your site. This typically involves creating a `versions.json` file.
|
|
116
|
+
|
|
117
|
+
2. **Organize Your Schemas**: Create a versioned directory structure for your schemas. Instead of placing your schemas in `static/schemas`, you should have:
|
|
118
|
+
- `static/schemas/next`: For the "current" or "next" version of your schemas.
|
|
119
|
+
- `static/schemas/<version>`: For each version of your schemas (e.g., `static/schemas/1.1.1`).
|
|
120
|
+
|
|
121
|
+
When versioning is enabled, the plugin will automatically detect the `versions.json` file and generate documentation for each version, as well as for the `current` version.
|
|
122
|
+
|
|
123
|
+
### Non-Versioned Mode
|
|
124
|
+
|
|
125
|
+
If you do not have a `versions.json` file in your `siteDir`, the plugin will run in non-versioned mode. It will read your schemas from `static/schemas` and generate documentation in `docs/events`.
|
|
126
|
+
|
|
127
|
+
### Schema `$id` Versioning
|
|
128
|
+
|
|
129
|
+
When using the versioning feature, the plugin will automatically update the `$id` of your schemas to include the version number. For example, if your site's `url` is `https://example.com` and you have a schema `my-event.json` in version `1.0.0`, the `$id` will be updated to `https://example.com/schemas/1.0.0/my-event.json`.
|
|
130
|
+
|
|
131
|
+
This is done automatically by the plugin. However, if you need to update the `$id`s of your schemas manually, you can use the `update-schema-ids.js` script located in the plugin's `helpers` directory.
|
|
132
|
+
|
|
69
133
|
## Partials
|
|
70
134
|
|
|
71
135
|
You can provide additional content to the generated documentation pages by creating partial files. Partials are Markdown files that can be automatically included in the generated pages.
|
|
@@ -74,8 +138,8 @@ You can provide additional content to the generated documentation pages by creat
|
|
|
74
138
|
|
|
75
139
|
Partials must be named after the schema file they correspond to. For a schema named `my-event.json`, the partials would be:
|
|
76
140
|
|
|
77
|
-
|
|
78
|
-
|
|
141
|
+
- `my-event.mdx`: This partial is rendered directly after the schema's main description.
|
|
142
|
+
- `my-event_bottom.mdx`: This partial is rendered at the very bottom of the page.
|
|
79
143
|
|
|
80
144
|
### Location
|
|
81
145
|
|
|
@@ -85,8 +149,8 @@ Place your partial files in the `/docs/partials` directory at the root of your d
|
|
|
85
149
|
|
|
86
150
|
If you have a schema `add-to-cart-event.json`, you can create the following files:
|
|
87
151
|
|
|
88
|
-
|
|
89
|
-
|
|
152
|
+
- `docs/partials/add-to-cart-event.mdx`: For content to appear after the description.
|
|
153
|
+
- `docs/partials/add-to-cart-event_bottom.mdx`: For content to appear at the bottom.
|
|
90
154
|
|
|
91
155
|
## Contributing
|
|
92
156
|
|
|
@@ -1,169 +1,105 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom';
|
|
4
|
-
import ExampleDataLayer, {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import ExampleDataLayer, {
|
|
5
|
+
findClearableProperties,
|
|
6
|
+
} from '../components/ExampleDataLayer';
|
|
7
|
+
import choiceEventSchema from './__fixtures__/static/schemas/choice-event.json';
|
|
8
8
|
|
|
9
|
+
// Mock the CodeBlock to make assertions on its content easier
|
|
9
10
|
jest.mock('@theme/CodeBlock', () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
return function CodeBlock({ children, language }) {
|
|
12
|
+
return <pre data-language={language}>{children}</pre>;
|
|
13
|
+
};
|
|
13
14
|
});
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
it('should render correctly with a simple schema', () => {
|
|
21
|
-
const schema = {
|
|
22
|
-
type: 'object',
|
|
23
|
-
properties: {
|
|
24
|
-
event: { type: 'string', examples: ['test_event'] },
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
const example = { event: 'test_event' };
|
|
28
|
-
buildExampleFromSchema.mockReturnValue(example);
|
|
29
|
-
|
|
30
|
-
const { container } = render(<ExampleDataLayer schema={schema} />);
|
|
31
|
-
|
|
32
|
-
expect(buildExampleFromSchema).toHaveBeenCalledWith(schema);
|
|
33
|
-
const codeElement = container.querySelector('pre');
|
|
34
|
-
expect(codeElement.textContent).toMatchInlineSnapshot(`
|
|
35
|
-
"window.dataLayer.push({
|
|
36
|
-
"event": "test_event"
|
|
37
|
-
});"
|
|
38
|
-
`);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should render correctly with properties to reset', () => {
|
|
42
|
-
const schema = {
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
ecommerce: {
|
|
46
|
-
'x-gtm-clear': true,
|
|
47
|
-
type: 'object',
|
|
48
|
-
properties: { items: { type: 'array' } },
|
|
49
|
-
},
|
|
50
|
-
user_id: { type: 'string' }
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
const example = {
|
|
54
|
-
ecommerce: { items: [{ item_name: 'donuts' }] },
|
|
55
|
-
user_id: '123'
|
|
56
|
-
};
|
|
57
|
-
buildExampleFromSchema.mockReturnValue(example);
|
|
58
|
-
|
|
59
|
-
const { container } = render(<ExampleDataLayer schema={schema} />);
|
|
60
|
-
|
|
61
|
-
expect(buildExampleFromSchema).toHaveBeenCalledWith(schema);
|
|
62
|
-
|
|
63
|
-
const codeElement = container.querySelector('pre');
|
|
64
|
-
expect(codeElement.textContent).toMatchInlineSnapshot(`
|
|
65
|
-
"window.dataLayer.push({
|
|
66
|
-
"ecommerce": null
|
|
16
|
+
jest.mock('@theme/Tabs', () => {
|
|
17
|
+
return function Tabs({ children }) {
|
|
18
|
+
return <div data-testid="tabs">{children}</div>;
|
|
19
|
+
};
|
|
67
20
|
});
|
|
68
|
-
window.dataLayer.push({
|
|
69
|
-
"ecommerce": {
|
|
70
|
-
"items": [
|
|
71
|
-
{
|
|
72
|
-
"item_name": "donuts"
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
|
-
"user_id": "123"
|
|
77
|
-
});"
|
|
78
|
-
`);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should render correctly with an empty schema', () => {
|
|
82
|
-
const schema = {};
|
|
83
|
-
const example = {};
|
|
84
|
-
buildExampleFromSchema.mockReturnValue(example);
|
|
85
|
-
|
|
86
|
-
const { container } = render(<ExampleDataLayer schema={schema} />);
|
|
87
21
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
properties: {
|
|
97
|
-
ecommerce: {
|
|
98
|
-
'x-gtm-clear': true,
|
|
99
|
-
type: 'object',
|
|
100
|
-
properties: { items: { type: 'array' } },
|
|
101
|
-
},
|
|
102
|
-
user_data: {
|
|
103
|
-
'x-gtm-clear': true,
|
|
104
|
-
type: 'object'
|
|
105
|
-
},
|
|
106
|
-
event: { type: 'string' }
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
// buildExampleFromSchema will not include user_data because it's an empty object
|
|
110
|
-
const example = {
|
|
111
|
-
ecommerce: { items: [{ item_name: 'donuts' }] },
|
|
112
|
-
event: 'purchase'
|
|
113
|
-
};
|
|
114
|
-
buildExampleFromSchema.mockReturnValue(example);
|
|
115
|
-
|
|
116
|
-
const { container } = render(<ExampleDataLayer schema={schema} />);
|
|
117
|
-
|
|
118
|
-
expect(buildExampleFromSchema).toHaveBeenCalledWith(schema);
|
|
119
|
-
|
|
120
|
-
const codeElement = container.querySelector('pre');
|
|
121
|
-
expect(codeElement.textContent).toMatchInlineSnapshot(`
|
|
122
|
-
"window.dataLayer.push({
|
|
123
|
-
"ecommerce": null
|
|
22
|
+
jest.mock('@theme/TabItem', () => {
|
|
23
|
+
return function TabItem({ children, label }) {
|
|
24
|
+
return (
|
|
25
|
+
<div data-testid="tab-item" data-label={label}>
|
|
26
|
+
{children}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
124
30
|
});
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
|
|
31
|
+
|
|
32
|
+
describe('ExampleDataLayer', () => {
|
|
33
|
+
it('should render a single example for a simple schema', () => {
|
|
34
|
+
const schema = {
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
event: { type: 'string', examples: ['test_event'] },
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const { container } = render(<ExampleDataLayer schema={schema} />);
|
|
41
|
+
expect(container).toMatchSnapshot();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should render nothing for an empty schema', () => {
|
|
45
|
+
const { container } = render(<ExampleDataLayer schema={{}} />);
|
|
46
|
+
// An empty schema produces no examples, so the component should render null
|
|
47
|
+
expect(container.firstChild).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should render grouped tabs for a schema with choices', () => {
|
|
51
|
+
const { container, getAllByTestId } = render(
|
|
52
|
+
<ExampleDataLayer schema={choiceEventSchema} />,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// Check for the group headings
|
|
56
|
+
const headings = screen.getAllByRole('heading', { level: 4 });
|
|
57
|
+
expect(headings[0]).toHaveTextContent(/user_id options:/);
|
|
58
|
+
expect(headings[1]).toHaveTextContent(/payment_method options:/);
|
|
59
|
+
|
|
60
|
+
const tabItems = getAllByTestId('tab-item');
|
|
61
|
+
// 2 options for user_id + 2 options for payment_method = 4 tabs total
|
|
62
|
+
expect(tabItems).toHaveLength(4);
|
|
63
|
+
|
|
64
|
+
// Check the labels for one of the groups
|
|
65
|
+
expect(tabItems[0]).toHaveAttribute('data-label', 'User ID as String');
|
|
66
|
+
expect(tabItems[1]).toHaveAttribute('data-label', 'User ID as Integer');
|
|
67
|
+
|
|
68
|
+
// Let snapshot testing verify the complex content of each tab
|
|
69
|
+
expect(container).toMatchSnapshot();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should use the provided dataLayerName', () => {
|
|
73
|
+
const schema = {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
event: { type: 'string', examples: ['test_event'] },
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const { getByText } = render(
|
|
80
|
+
<ExampleDataLayer schema={schema} dataLayerName="customDataLayer" />,
|
|
81
|
+
);
|
|
82
|
+
expect(getByText(/window.customDataLayer.push/)).toBeInTheDocument();
|
|
83
|
+
});
|
|
137
84
|
});
|
|
138
85
|
|
|
139
86
|
describe('findClearableProperties', () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
it('should return an empty array if no properties have "x-gtm-clear": true', () => {
|
|
160
|
-
const schema = {
|
|
161
|
-
properties: {
|
|
162
|
-
prop1: { type: 'string' },
|
|
163
|
-
prop2: { type: 'object' },
|
|
164
|
-
prop3: { 'x-gtm-clear': false, type: 'object' },
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
expect(findClearableProperties(schema)).toEqual([]);
|
|
168
|
-
});
|
|
87
|
+
it('should return an empty array when schema is empty, null, or has no properties', () => {
|
|
88
|
+
expect(findClearableProperties({})).toEqual([]);
|
|
89
|
+
expect(findClearableProperties({ type: 'object' })).toEqual([]);
|
|
90
|
+
expect(findClearableProperties(null)).toEqual([]);
|
|
91
|
+
expect(findClearableProperties(undefined)).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should return properties with "x-gtm-clear": true', () => {
|
|
95
|
+
const schema = {
|
|
96
|
+
properties: {
|
|
97
|
+
prop1: { type: 'string' },
|
|
98
|
+
prop2: { 'x-gtm-clear': true, type: 'object' },
|
|
99
|
+
prop3: { 'x-gtm-clear': false, type: 'object' },
|
|
100
|
+
prop4: { 'x-gtm-clear': true, type: 'array' },
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
expect(findClearableProperties(schema)).toEqual(['prop2', 'prop4']);
|
|
104
|
+
});
|
|
169
105
|
});
|
|
@@ -22,20 +22,12 @@
|
|
|
22
22
|
"value": {
|
|
23
23
|
"type": "number",
|
|
24
24
|
"description": "The monetary value of the event. Set value to the sum of (price * quantity) for all items in items.",
|
|
25
|
-
"examples": [
|
|
26
|
-
30.03,
|
|
27
|
-
99.99,
|
|
28
|
-
45.50
|
|
29
|
-
]
|
|
25
|
+
"examples": [30.03, 99.99, 45.5]
|
|
30
26
|
},
|
|
31
27
|
"currency": {
|
|
32
28
|
"type": "string",
|
|
33
29
|
"description": "The currency of the items in ISO 4217 three-letter format. Required when value is set.",
|
|
34
|
-
"examples": [
|
|
35
|
-
"USD",
|
|
36
|
-
"EUR",
|
|
37
|
-
"GBP"
|
|
38
|
-
]
|
|
30
|
+
"examples": ["USD", "EUR", "GBP"]
|
|
39
31
|
},
|
|
40
32
|
"items": {
|
|
41
33
|
"type": "array",
|
|
@@ -46,10 +38,7 @@
|
|
|
46
38
|
}
|
|
47
39
|
}
|
|
48
40
|
},
|
|
49
|
-
"required": [
|
|
50
|
-
"currency",
|
|
51
|
-
"items"
|
|
52
|
-
]
|
|
41
|
+
"required": ["currency", "items"]
|
|
53
42
|
}
|
|
54
43
|
}
|
|
55
|
-
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://example.com/parent-event-anchor.json",
|
|
3
|
+
"title": "Parent Event Anchor",
|
|
4
|
+
"description": "This is a parent event with oneOf.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"oneOf": [
|
|
7
|
+
{
|
|
8
|
+
"title": "Child Event Anchor",
|
|
9
|
+
"description": "This is a child event with an anchor.",
|
|
10
|
+
"$anchor": "child-event-with-anchor",
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"property_a": {
|
|
14
|
+
"type": "string"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"title": "Child Event Title",
|
|
20
|
+
"description": "This is a child event with only a title.",
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"property_b": {
|
|
24
|
+
"type": "string"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://tracking-docs-demo.buchert.digital/schemas/1.2.0/choice-event.json",
|
|
4
|
+
"title": "Choice Event",
|
|
5
|
+
"description": "An example event that uses oneOf and anyOf.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"event": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"const": "one_of_event"
|
|
11
|
+
},
|
|
12
|
+
"user_id": {
|
|
13
|
+
"description": "The user's ID.",
|
|
14
|
+
"oneOf": [
|
|
15
|
+
{
|
|
16
|
+
"type": "string",
|
|
17
|
+
"title": "User ID as String",
|
|
18
|
+
"description": "The user's ID as a string.",
|
|
19
|
+
"examples": ["user-123"]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "integer",
|
|
23
|
+
"title": "User ID as Integer",
|
|
24
|
+
"description": "The user's ID as an integer.",
|
|
25
|
+
"examples": [123]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"payment_method": {
|
|
30
|
+
"description": "The user's payment method.",
|
|
31
|
+
"type": "object",
|
|
32
|
+
"anyOf": [
|
|
33
|
+
{
|
|
34
|
+
"title": "Credit Card",
|
|
35
|
+
"properties": {
|
|
36
|
+
"payment_type": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": ["credit_card", "debit_card"],
|
|
39
|
+
"examples": ["credit_card"]
|
|
40
|
+
},
|
|
41
|
+
"card_number": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"examples": ["1234-5678-9012-3456"]
|
|
44
|
+
},
|
|
45
|
+
"expiry_date": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"examples": ["12/26"]
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"required": ["card_number", "expiry_date"]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"title": "PayPal",
|
|
54
|
+
"type": "object",
|
|
55
|
+
"properties": {
|
|
56
|
+
"payment_type": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"const": "paypal"
|
|
59
|
+
},
|
|
60
|
+
"email": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"format": "email",
|
|
63
|
+
"examples": ["test@example.com"]
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"required": ["email"]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"required": ["event", "user_id", "payment_method"]
|
|
72
|
+
}
|
|
@@ -1,58 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
"user_data": {
|
|
23
|
-
"type": "object",
|
|
24
|
-
"description": "User related data.",
|
|
25
|
-
"x-gtm-clear": true
|
|
26
|
-
}
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://tracking-docs-demo.buchert.digital/schemas/components/dataLayer.json",
|
|
4
|
+
"title": "dataLayer",
|
|
5
|
+
"description": "Schema for the object structure pushed to the dataLayer.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"allOf": [
|
|
8
|
+
{
|
|
9
|
+
"$ref": "#/$defs/strictObject"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"event": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The name of the event."
|
|
16
|
+
},
|
|
17
|
+
"ecommerce": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"description": "Ecommerce related data.",
|
|
20
|
+
"x-gtm-clear": true
|
|
27
21
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
22
|
+
"user_data": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"description": "User related data.",
|
|
25
|
+
"x-gtm-clear": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": ["event"],
|
|
29
|
+
"$defs": {
|
|
30
|
+
"strictObject": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"propertyNames": {
|
|
33
|
+
"maxLength": 40,
|
|
34
|
+
"pattern": "^[a-z0-9_]+$"
|
|
35
|
+
},
|
|
36
|
+
"additionalProperties": {
|
|
37
|
+
"anyOf": [
|
|
38
|
+
{
|
|
39
|
+
"$ref": "#/$defs/strictObject"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"$ref": "#/$defs/strictObject"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"not": {
|
|
49
|
+
"type": "object"
|
|
55
50
|
}
|
|
56
|
-
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
57
54
|
}
|
|
58
|
-
}
|
|
55
|
+
}
|
|
56
|
+
}
|