docusaurus-plugin-generate-schema-docs 1.8.3 → 1.8.5
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 +12 -0
- package/__tests__/__fixtures__/validateSchemas/main-schema-with-not-allof.json +11 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof-multi.json +12 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof.json +30 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-edge-cases.json +24 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-non-object.json +15 -0
- package/__tests__/__snapshots__/generateEventDocs.anchor.test.js.snap +6 -0
- package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +6 -0
- package/__tests__/__snapshots__/generateEventDocs.test.js.snap +15 -0
- package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +6 -0
- package/__tests__/components/PropertiesTable.test.js +66 -0
- package/__tests__/components/PropertyRow.test.js +85 -4
- package/__tests__/components/SchemaJsonViewer.test.js +118 -0
- package/__tests__/generateEventDocs.anchor.test.js +1 -1
- package/__tests__/generateEventDocs.nested.test.js +1 -1
- package/__tests__/generateEventDocs.partials.test.js +1 -1
- package/__tests__/generateEventDocs.test.js +506 -1
- package/__tests__/generateEventDocs.versioned.test.js +1 -1
- package/__tests__/helpers/buildExampleFromSchema.test.js +240 -0
- package/__tests__/helpers/constraintSchemaPaths.test.js +208 -0
- package/__tests__/helpers/continuingLinesStyle.test.js +492 -0
- package/__tests__/helpers/example-helper.test.js +12 -0
- package/__tests__/helpers/exampleModel.test.js +209 -0
- package/__tests__/helpers/file-system.test.js +73 -1
- package/__tests__/helpers/getConstraints.test.js +43 -0
- package/__tests__/helpers/mergeSchema.test.js +94 -0
- package/__tests__/helpers/processSchema.test.js +309 -1
- package/__tests__/helpers/schema-doc-template.test.js +54 -0
- package/__tests__/helpers/schema-processing.test.js +122 -2
- package/__tests__/helpers/schemaToExamples.test.js +1007 -0
- package/__tests__/helpers/schemaToTableData.mutations.test.js +970 -0
- package/__tests__/helpers/schemaToTableData.test.js +157 -0
- package/__tests__/helpers/schemaTraversal.test.js +110 -0
- package/__tests__/helpers/snippetTargets.test.js +432 -0
- package/__tests__/helpers/trackingTargets.test.js +319 -0
- package/__tests__/helpers/validator.test.js +385 -1
- package/__tests__/index.test.js +436 -0
- package/__tests__/syncGtm.test.js +366 -6
- package/__tests__/update-schema-ids.test.js +70 -1
- package/__tests__/validateSchemas-integration.test.js +2 -2
- package/__tests__/validateSchemas.test.js +192 -1
- package/components/PropertiesTable.js +32 -2
- package/components/PropertyRow.js +29 -2
- package/components/SchemaJsonViewer.js +234 -131
- package/components/SchemaRows.css +40 -0
- package/components/SchemaViewer.js +11 -2
- package/generateEventDocs.js +21 -1
- package/helpers/constraintSchemaPaths.js +10 -14
- package/helpers/example-helper.js +2 -2
- package/helpers/getConstraints.js +20 -0
- package/helpers/processSchema.js +32 -1
- package/helpers/schema-doc-template.js +4 -0
- package/helpers/schemaToExamples.js +29 -35
- package/helpers/schemaToTableData.js +538 -492
- package/helpers/schemaTraversal.cjs +148 -0
- package/helpers/trackingTargets.js +26 -3
- package/helpers/validator.js +18 -4
- package/index.js +1 -2
- package/package.json +1 -1
- package/scripts/sync-gtm.js +65 -34
- package/test-data/payloadContracts.js +35 -0
- package/validateSchemas.js +1 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
function visitSchemaNodes(schema, visitor, path = []) {
|
|
2
|
+
if (!schema || typeof schema !== 'object') {
|
|
3
|
+
return;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
visitor(schema, { path });
|
|
7
|
+
|
|
8
|
+
if (schema.properties && typeof schema.properties === 'object') {
|
|
9
|
+
Object.entries(schema.properties).forEach(([key, propertySchema]) => {
|
|
10
|
+
visitSchemaNodes(propertySchema, visitor, [...path, 'properties', key]);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (schema.items && typeof schema.items === 'object') {
|
|
15
|
+
visitSchemaNodes(schema.items, visitor, [...path, 'items']);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (Array.isArray(schema.oneOf)) {
|
|
19
|
+
schema.oneOf.forEach((optionSchema, index) => {
|
|
20
|
+
visitSchemaNodes(optionSchema, visitor, [...path, 'oneOf', index]);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (Array.isArray(schema.anyOf)) {
|
|
25
|
+
schema.anyOf.forEach((optionSchema, index) => {
|
|
26
|
+
visitSchemaNodes(optionSchema, visitor, [...path, 'anyOf', index]);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (schema.if && typeof schema.if === 'object') {
|
|
31
|
+
visitSchemaNodes(schema.if, visitor, [...path, 'if']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (schema.then && typeof schema.then === 'object') {
|
|
35
|
+
visitSchemaNodes(schema.then, visitor, [...path, 'then']);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (schema.else && typeof schema.else === 'object') {
|
|
39
|
+
visitSchemaNodes(schema.else, visitor, [...path, 'else']);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function visitPropertyEntryBranches(
|
|
44
|
+
schema,
|
|
45
|
+
visitor,
|
|
46
|
+
{ prefix = '', path = [], skipArraySubProperties = false } = {},
|
|
47
|
+
) {
|
|
48
|
+
if (!schema || typeof schema !== 'object') {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (Array.isArray(schema.oneOf)) {
|
|
53
|
+
schema.oneOf.forEach((optionSchema, index) => {
|
|
54
|
+
visitSchemaPropertyEntries(optionSchema, visitor, {
|
|
55
|
+
prefix,
|
|
56
|
+
path: [...path, 'oneOf', index],
|
|
57
|
+
skipArraySubProperties,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (Array.isArray(schema.anyOf)) {
|
|
63
|
+
schema.anyOf.forEach((optionSchema, index) => {
|
|
64
|
+
visitSchemaPropertyEntries(optionSchema, visitor, {
|
|
65
|
+
prefix,
|
|
66
|
+
path: [...path, 'anyOf', index],
|
|
67
|
+
skipArraySubProperties,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (schema.then && typeof schema.then === 'object') {
|
|
73
|
+
visitSchemaPropertyEntries(schema.then, visitor, {
|
|
74
|
+
prefix,
|
|
75
|
+
path: [...path, 'then'],
|
|
76
|
+
skipArraySubProperties,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (schema.else && typeof schema.else === 'object') {
|
|
81
|
+
visitSchemaPropertyEntries(schema.else, visitor, {
|
|
82
|
+
prefix,
|
|
83
|
+
path: [...path, 'else'],
|
|
84
|
+
skipArraySubProperties,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function visitSchemaPropertyEntries(
|
|
90
|
+
schema,
|
|
91
|
+
visitor,
|
|
92
|
+
{ prefix = '', path = [], skipArraySubProperties = false } = {},
|
|
93
|
+
) {
|
|
94
|
+
if (!schema || typeof schema !== 'object') {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (schema.properties && typeof schema.properties === 'object') {
|
|
99
|
+
Object.entries(schema.properties).forEach(([key, propertySchema]) => {
|
|
100
|
+
const currentName = prefix ? `${prefix}.${key}` : key;
|
|
101
|
+
const currentPath = [...path, 'properties', key];
|
|
102
|
+
|
|
103
|
+
visitor(propertySchema, {
|
|
104
|
+
key,
|
|
105
|
+
name: currentName,
|
|
106
|
+
path: currentPath,
|
|
107
|
+
parentSchema: schema,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (propertySchema?.type === 'object' && propertySchema.properties) {
|
|
111
|
+
visitSchemaPropertyEntries(propertySchema, visitor, {
|
|
112
|
+
prefix: currentName,
|
|
113
|
+
path: currentPath,
|
|
114
|
+
skipArraySubProperties,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (
|
|
119
|
+
propertySchema?.type === 'array' &&
|
|
120
|
+
propertySchema.items?.properties &&
|
|
121
|
+
!skipArraySubProperties
|
|
122
|
+
) {
|
|
123
|
+
visitSchemaPropertyEntries(propertySchema.items, visitor, {
|
|
124
|
+
prefix: `${currentName}.0`,
|
|
125
|
+
path: [...currentPath, 'items'],
|
|
126
|
+
skipArraySubProperties,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
visitPropertyEntryBranches(propertySchema, visitor, {
|
|
131
|
+
prefix: currentName,
|
|
132
|
+
path: currentPath,
|
|
133
|
+
skipArraySubProperties,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
visitPropertyEntryBranches(schema, visitor, {
|
|
139
|
+
prefix,
|
|
140
|
+
path,
|
|
141
|
+
skipArraySubProperties,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = {
|
|
146
|
+
visitSchemaNodes,
|
|
147
|
+
visitSchemaPropertyEntries,
|
|
148
|
+
};
|
|
@@ -10,6 +10,28 @@ export const SUPPORTED_TRACKING_TARGETS = [
|
|
|
10
10
|
|
|
11
11
|
const TARGET_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+){2,}$/;
|
|
12
12
|
|
|
13
|
+
function isReferenceAggregatorSchema(schema) {
|
|
14
|
+
if (!schema || typeof schema !== 'object') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const hasChoiceAggregation =
|
|
19
|
+
Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf);
|
|
20
|
+
const hasPropertiesKeyword = Object.hasOwn(schema, 'properties');
|
|
21
|
+
const hasValidPropertiesMap =
|
|
22
|
+
hasPropertiesKeyword &&
|
|
23
|
+
schema.properties &&
|
|
24
|
+
typeof schema.properties === 'object' &&
|
|
25
|
+
!Array.isArray(schema.properties);
|
|
26
|
+
const hasOwnProperties =
|
|
27
|
+
hasValidPropertiesMap && Object.keys(schema.properties).length > 0;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
hasChoiceAggregation &&
|
|
31
|
+
(!hasPropertiesKeyword || (hasValidPropertiesMap && !hasOwnProperties))
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
export function resolveTrackingTargets(
|
|
14
36
|
schema,
|
|
15
37
|
{ schemaFile = 'schema', isQuiet = false } = {},
|
|
@@ -17,9 +39,10 @@ export function resolveTrackingTargets(
|
|
|
17
39
|
const configuredTargets = schema?.['x-tracking-targets'];
|
|
18
40
|
|
|
19
41
|
if (configuredTargets == null) {
|
|
20
|
-
const warning =
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
const warning =
|
|
43
|
+
isQuiet || isReferenceAggregatorSchema(schema)
|
|
44
|
+
? null
|
|
45
|
+
: `Schema ${schemaFile} is missing x-tracking-targets. Falling back to "${DEFAULT_TRACKING_TARGET}".`;
|
|
23
46
|
return {
|
|
24
47
|
targets: [DEFAULT_TRACKING_TARGET],
|
|
25
48
|
warning,
|
package/helpers/validator.js
CHANGED
|
@@ -9,14 +9,29 @@ import { promises as fs } from 'fs';
|
|
|
9
9
|
import { URL } from 'url';
|
|
10
10
|
import { resolveConstraintSchemaPath } from './constraintSchemaPaths.js';
|
|
11
11
|
|
|
12
|
+
const schemaFileCache = new Map();
|
|
13
|
+
|
|
14
|
+
export function clearSchemaFileCache() {
|
|
15
|
+
schemaFileCache.clear();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function readSchemaFile(filePath) {
|
|
19
|
+
if (!schemaFileCache.has(filePath)) {
|
|
20
|
+
schemaFileCache.set(
|
|
21
|
+
filePath,
|
|
22
|
+
fs.readFile(filePath, 'utf-8').then(JSON.parse),
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return schemaFileCache.get(filePath);
|
|
26
|
+
}
|
|
27
|
+
|
|
12
28
|
function createAjvInstance(schemas, mainSchema, schemaPath) {
|
|
13
29
|
const schemaVersion = mainSchema?.$schema;
|
|
14
30
|
|
|
15
31
|
const loadSchema = async (uri) => {
|
|
16
32
|
const constraintPath = resolveConstraintSchemaPath(uri);
|
|
17
33
|
if (constraintPath) {
|
|
18
|
-
|
|
19
|
-
return JSON.parse(schemaContent);
|
|
34
|
+
return readSchemaFile(constraintPath);
|
|
20
35
|
}
|
|
21
36
|
|
|
22
37
|
let localPath;
|
|
@@ -29,8 +44,7 @@ function createAjvInstance(schemas, mainSchema, schemaPath) {
|
|
|
29
44
|
} else {
|
|
30
45
|
localPath = path.resolve(schemaPath, uri);
|
|
31
46
|
}
|
|
32
|
-
|
|
33
|
-
return JSON.parse(schemaContent);
|
|
47
|
+
return readSchemaFile(localPath);
|
|
34
48
|
};
|
|
35
49
|
|
|
36
50
|
const options = {
|
package/index.js
CHANGED
|
@@ -7,8 +7,7 @@ import path from 'path';
|
|
|
7
7
|
import { execSync } from 'child_process';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
11
|
|
|
13
12
|
export default async function (context, options) {
|
|
14
13
|
const { siteDir } = context;
|
package/package.json
CHANGED
package/scripts/sync-gtm.js
CHANGED
|
@@ -3,6 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
4
|
const RefParser = require('@apidevtools/json-schema-ref-parser');
|
|
5
5
|
const mergeAllOf = require('json-schema-merge-allof');
|
|
6
|
+
const {
|
|
7
|
+
visitSchemaPropertyEntries,
|
|
8
|
+
} = require('../helpers/schemaTraversal.cjs');
|
|
6
9
|
|
|
7
10
|
const logger = {
|
|
8
11
|
_isQuiet: false,
|
|
@@ -86,48 +89,57 @@ function findJsonFiles(dir) {
|
|
|
86
89
|
return results;
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
function isRootTrackingSchema(schema) {
|
|
93
|
+
return Boolean(schema?.properties?.event || schema?.['x-tracking-targets']);
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
function parseSchema(schema, options, prefix = '') {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
const variables = [];
|
|
98
|
+
|
|
99
|
+
visitSchemaPropertyEntries(
|
|
100
|
+
schema,
|
|
101
|
+
(property, context) => {
|
|
102
|
+
variables.push({
|
|
103
|
+
name: context.name,
|
|
104
|
+
description: property.description,
|
|
105
|
+
type: property.type,
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
prefix,
|
|
110
|
+
skipArraySubProperties: options.skipArraySubProperties,
|
|
111
|
+
},
|
|
112
|
+
);
|
|
93
113
|
|
|
94
|
-
let variables = [];
|
|
95
|
-
for (const key in schema.properties) {
|
|
96
|
-
const property = schema.properties[key];
|
|
97
|
-
const currentPath = prefix ? `${prefix}.${key}` : key;
|
|
98
|
-
variables.push({
|
|
99
|
-
name: currentPath,
|
|
100
|
-
description: property.description,
|
|
101
|
-
type: property.type,
|
|
102
|
-
});
|
|
103
|
-
if (
|
|
104
|
-
property.type === 'array' &&
|
|
105
|
-
property.items &&
|
|
106
|
-
!options.skipArraySubProperties
|
|
107
|
-
) {
|
|
108
|
-
if (property.items.properties) {
|
|
109
|
-
variables.push(
|
|
110
|
-
...parseSchema(property.items, options, `${currentPath}.0`),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
} else if (property.type === 'object' && property.properties) {
|
|
114
|
-
variables.push(...parseSchema(property, options, currentPath));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
114
|
return variables;
|
|
118
115
|
}
|
|
119
116
|
|
|
117
|
+
function shouldIncludeSchemaForGtm(schema) {
|
|
118
|
+
if (!isRootTrackingSchema(schema)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const trackingTargets = schema?.['x-tracking-targets'];
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
Array.isArray(trackingTargets) &&
|
|
126
|
+
trackingTargets.includes('web-datalayer-js')
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
async function getVariablesFromSchemas(
|
|
121
131
|
schemaPath,
|
|
122
132
|
{ skipArraySubProperties = false },
|
|
123
133
|
) {
|
|
124
134
|
const allVariables = new Map();
|
|
125
135
|
const jsonFiles = findJsonFiles(schemaPath);
|
|
126
|
-
const eventFiles = jsonFiles.filter((f) => !f.includes('components'));
|
|
127
136
|
|
|
128
|
-
for (const file of
|
|
137
|
+
for (const file of jsonFiles) {
|
|
129
138
|
try {
|
|
130
139
|
let schema = await RefParser.bundle(file);
|
|
140
|
+
if (!shouldIncludeSchemaForGtm(schema)) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
131
143
|
schema = mergeAllOf(schema);
|
|
132
144
|
const fileVariables = parseSchema(schema, { skipArraySubProperties });
|
|
133
145
|
for (const variable of fileVariables) {
|
|
@@ -205,19 +217,27 @@ function createGtmVariables(variablesToCreate) {
|
|
|
205
217
|
|
|
206
218
|
function deleteGtmVariables(variablesToDelete) {
|
|
207
219
|
logger.log(`Found ${variablesToDelete.length} variables to delete.`);
|
|
220
|
+
const deleted = [];
|
|
221
|
+
const failedDeletes = [];
|
|
208
222
|
for (const v of variablesToDelete) {
|
|
209
223
|
const command = `gtm variables delete --variable-id ${v.variableId} --force --quiet`;
|
|
210
224
|
logger.log(`Executing: ${command}`);
|
|
211
|
-
|
|
225
|
+
try {
|
|
226
|
+
execSync(command, { stdio: 'inherit' });
|
|
227
|
+
deleted.push(v.parameter.find((p) => p.key === 'name').value);
|
|
228
|
+
} catch {
|
|
229
|
+
failedDeletes.push({
|
|
230
|
+
name: v.parameter.find((p) => p.key === 'name').value,
|
|
231
|
+
variableId: v.variableId,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
212
234
|
}
|
|
213
|
-
return
|
|
214
|
-
(v) => v.parameter.find((p) => p.key === 'name').value,
|
|
215
|
-
);
|
|
235
|
+
return { deleted, failedDeletes };
|
|
216
236
|
}
|
|
217
237
|
|
|
218
238
|
async function syncGtmVariables(
|
|
219
239
|
schemaVariables,
|
|
220
|
-
{ skipArraySubProperties = false },
|
|
240
|
+
{ skipArraySubProperties = false } = {},
|
|
221
241
|
) {
|
|
222
242
|
const gtmVariables = getGtmVariables();
|
|
223
243
|
|
|
@@ -235,12 +255,13 @@ async function syncGtmVariables(
|
|
|
235
255
|
);
|
|
236
256
|
|
|
237
257
|
const created = createGtmVariables(toCreate);
|
|
238
|
-
const deleted = deleteGtmVariables(toDelete);
|
|
258
|
+
const { deleted, failedDeletes } = deleteGtmVariables(toDelete);
|
|
239
259
|
|
|
240
260
|
logger.log('GTM variable synchronization complete.');
|
|
241
261
|
return {
|
|
242
262
|
created,
|
|
243
263
|
deleted,
|
|
264
|
+
failedDeletes,
|
|
244
265
|
inSync: inSync.map((v) => v.name),
|
|
245
266
|
};
|
|
246
267
|
}
|
|
@@ -348,6 +369,14 @@ async function main(argv, deps) {
|
|
|
348
369
|
),
|
|
349
370
|
);
|
|
350
371
|
} else {
|
|
372
|
+
if (summary.failedDeletes?.length > 0) {
|
|
373
|
+
log.log(
|
|
374
|
+
`Skipped deleting ${summary.failedDeletes.length} GTM variables (GTM rejected the delete, they may still be referenced):`,
|
|
375
|
+
);
|
|
376
|
+
for (const failed of summary.failedDeletes) {
|
|
377
|
+
log.log(`- ${failed.name} (ID: ${failed.variableId})`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
351
380
|
log.log('Synchronization successful!');
|
|
352
381
|
log.log(
|
|
353
382
|
`All changes applied in GTM workspace: "${workspaceName}" (ID: ${workspaceId})`,
|
|
@@ -385,9 +414,11 @@ module.exports = {
|
|
|
385
414
|
main,
|
|
386
415
|
getVariablesToCreate,
|
|
387
416
|
getVariablesToDelete,
|
|
417
|
+
getGtmVariables,
|
|
388
418
|
createGtmVariables,
|
|
389
419
|
deleteGtmVariables,
|
|
390
420
|
parseSchema,
|
|
421
|
+
shouldIncludeSchemaForGtm,
|
|
391
422
|
findJsonFiles,
|
|
392
423
|
safeJsonParse,
|
|
393
424
|
logger,
|
|
@@ -118,6 +118,41 @@ const PAYLOAD_CONTRACTS = [
|
|
|
118
118
|
},
|
|
119
119
|
},
|
|
120
120
|
},
|
|
121
|
+
{
|
|
122
|
+
id: 'login-with-user-properties',
|
|
123
|
+
class: 'user_properties',
|
|
124
|
+
example: {
|
|
125
|
+
event: 'login',
|
|
126
|
+
method: 'email',
|
|
127
|
+
user_properties: {
|
|
128
|
+
sign_up_method: 'email',
|
|
129
|
+
allow_ad_personalization_signals: 'false',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
expected: {
|
|
133
|
+
web: {
|
|
134
|
+
eventName: 'login',
|
|
135
|
+
payload: {
|
|
136
|
+
event: 'login',
|
|
137
|
+
method: 'email',
|
|
138
|
+
user_properties: {
|
|
139
|
+
sign_up_method: 'email',
|
|
140
|
+
allow_ad_personalization_signals: 'false',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
firebase: {
|
|
145
|
+
eventName: 'login',
|
|
146
|
+
parameters: {
|
|
147
|
+
method: 'email',
|
|
148
|
+
},
|
|
149
|
+
userProperties: {
|
|
150
|
+
sign_up_method: 'email',
|
|
151
|
+
allow_personalized_ads: 'false',
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
121
156
|
{
|
|
122
157
|
id: 'web-fallback-json-serialization',
|
|
123
158
|
class: 'fallback_json_serialization',
|
package/validateSchemas.js
CHANGED
|
@@ -43,7 +43,7 @@ const validateSingleSchema = async (filePath, schemaPath) => {
|
|
|
43
43
|
fileHasAnyExample = true;
|
|
44
44
|
const { example, title } = option;
|
|
45
45
|
|
|
46
|
-
if (
|
|
46
|
+
if (typeof example === 'undefined') {
|
|
47
47
|
errors.push(
|
|
48
48
|
`x Schema ${file} (option: ${title}) does not produce a valid example.`,
|
|
49
49
|
);
|