zapier-platform-schema 11.1.1
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/CHANGELOG.md +3 -0
- package/LICENSE +4 -0
- package/README.md +21 -0
- package/exported-schema.json +1418 -0
- package/lib/constants.js +21 -0
- package/lib/functional-constraints/deepNestedFields.js +68 -0
- package/lib/functional-constraints/index.js +35 -0
- package/lib/functional-constraints/labelWhenVisible.js +31 -0
- package/lib/functional-constraints/matchingKeys.js +35 -0
- package/lib/functional-constraints/mutuallyExclusiveFields.js +70 -0
- package/lib/functional-constraints/requiredSamples.js +56 -0
- package/lib/functional-constraints/searchOrCreateKeys.js +67 -0
- package/lib/functional-constraints/uniqueInputFieldKeys.js +67 -0
- package/lib/schemas/AppFlagsSchema.js +22 -0
- package/lib/schemas/AppSchema.js +148 -0
- package/lib/schemas/AuthenticationBasicConfigSchema.js +14 -0
- package/lib/schemas/AuthenticationCustomConfigSchema.js +14 -0
- package/lib/schemas/AuthenticationDigestConfigSchema.js +14 -0
- package/lib/schemas/AuthenticationOAuth1ConfigSchema.js +53 -0
- package/lib/schemas/AuthenticationOAuth2ConfigSchema.js +73 -0
- package/lib/schemas/AuthenticationSchema.js +118 -0
- package/lib/schemas/AuthenticationSessionConfigSchema.js +31 -0
- package/lib/schemas/BasicActionOperationSchema.js +59 -0
- package/lib/schemas/BasicCreateActionOperationSchema.js +26 -0
- package/lib/schemas/BasicDisplaySchema.js +92 -0
- package/lib/schemas/BasicHookOperationSchema.js +117 -0
- package/lib/schemas/BasicOperationSchema.js +73 -0
- package/lib/schemas/BasicPollingOperationSchema.js +41 -0
- package/lib/schemas/BulkReadSchema.js +72 -0
- package/lib/schemas/BulkReadsSchema.js +69 -0
- package/lib/schemas/BundleSchema.js +17 -0
- package/lib/schemas/CreateSchema.js +108 -0
- package/lib/schemas/CreatesSchema.js +78 -0
- package/lib/schemas/DynamicFieldsSchema.js +36 -0
- package/lib/schemas/FieldChoiceWithLabelSchema.js +37 -0
- package/lib/schemas/FieldChoicesSchema.js +40 -0
- package/lib/schemas/FieldOrFunctionSchema.js +40 -0
- package/lib/schemas/FieldSchema.js +183 -0
- package/lib/schemas/FieldsSchema.js +17 -0
- package/lib/schemas/FlatObjectSchema.js +45 -0
- package/lib/schemas/FunctionRequireSchema.js +28 -0
- package/lib/schemas/FunctionSchema.js +42 -0
- package/lib/schemas/FunctionSourceSchema.js +37 -0
- package/lib/schemas/HydratorsSchema.js +29 -0
- package/lib/schemas/KeySchema.js +30 -0
- package/lib/schemas/MiddlewaresSchema.js +35 -0
- package/lib/schemas/RedirectRequestSchema.js +41 -0
- package/lib/schemas/RefResourceSchema.js +24 -0
- package/lib/schemas/RequestSchema.js +109 -0
- package/lib/schemas/ResourceMethodCreateSchema.js +67 -0
- package/lib/schemas/ResourceMethodGetSchema.js +74 -0
- package/lib/schemas/ResourceMethodHookSchema.js +72 -0
- package/lib/schemas/ResourceMethodListSchema.js +76 -0
- package/lib/schemas/ResourceMethodSearchSchema.js +67 -0
- package/lib/schemas/ResourceSchema.js +168 -0
- package/lib/schemas/ResourcesMethodGetSchema.js +57 -0
- package/lib/schemas/ResourcesSchema.js +95 -0
- package/lib/schemas/ResultsSchema.js +25 -0
- package/lib/schemas/SearchOrCreateSchema.js +84 -0
- package/lib/schemas/SearchOrCreatesSchema.js +60 -0
- package/lib/schemas/SearchSchema.js +84 -0
- package/lib/schemas/SearchesSchema.js +54 -0
- package/lib/schemas/TriggerSchema.js +93 -0
- package/lib/schemas/TriggersSchema.js +61 -0
- package/lib/schemas/VersionSchema.js +18 -0
- package/lib/utils/buildDocs.js +213 -0
- package/lib/utils/exportSchema.js +23 -0
- package/lib/utils/links.js +27 -0
- package/lib/utils/makeSchema.js +27 -0
- package/lib/utils/makeValidator.js +150 -0
- package/package.json +40 -0
- package/schema.js +13 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
|
|
5
|
+
const BasicDisplaySchema = require('./BasicDisplaySchema');
|
|
6
|
+
const BasicActionOperationSchema = require('./BasicActionOperationSchema');
|
|
7
|
+
const KeySchema = require('./KeySchema');
|
|
8
|
+
|
|
9
|
+
module.exports = makeSchema(
|
|
10
|
+
{
|
|
11
|
+
id: '/SearchSchema',
|
|
12
|
+
description: 'How will Zapier search for existing objects?',
|
|
13
|
+
type: 'object',
|
|
14
|
+
required: ['key', 'noun', 'display', 'operation'],
|
|
15
|
+
properties: {
|
|
16
|
+
key: {
|
|
17
|
+
description: 'A key to uniquely identify this search.',
|
|
18
|
+
$ref: KeySchema.id,
|
|
19
|
+
},
|
|
20
|
+
noun: {
|
|
21
|
+
description:
|
|
22
|
+
'A noun for this search that completes the sentence "finds a specific XXX".',
|
|
23
|
+
type: 'string',
|
|
24
|
+
minLength: 2,
|
|
25
|
+
maxLength: 255,
|
|
26
|
+
},
|
|
27
|
+
display: {
|
|
28
|
+
description: 'Configures the UI for this search.',
|
|
29
|
+
$ref: BasicDisplaySchema.id,
|
|
30
|
+
},
|
|
31
|
+
operation: {
|
|
32
|
+
description: 'Powers the functionality for this search.',
|
|
33
|
+
$ref: BasicActionOperationSchema.id,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
examples: [
|
|
38
|
+
{
|
|
39
|
+
key: 'recipe',
|
|
40
|
+
noun: 'Recipe',
|
|
41
|
+
display: {
|
|
42
|
+
label: 'Find a Recipe',
|
|
43
|
+
description: 'Search for recipe by cuisine style.',
|
|
44
|
+
},
|
|
45
|
+
operation: {
|
|
46
|
+
perform: '$func$2$f$',
|
|
47
|
+
sample: { id: 1 },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'recipe',
|
|
52
|
+
noun: 'Recipe',
|
|
53
|
+
display: {
|
|
54
|
+
label: 'Find a Recipe',
|
|
55
|
+
description: 'Search for recipe by cuisine style.',
|
|
56
|
+
hidden: true,
|
|
57
|
+
},
|
|
58
|
+
operation: { perform: '$func$2$f$' },
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
antiExamples: [
|
|
62
|
+
{
|
|
63
|
+
example: 'abc',
|
|
64
|
+
reason: 'Must be an object',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
example: {
|
|
68
|
+
key: 'recipe',
|
|
69
|
+
noun: 'Recipe',
|
|
70
|
+
display: {
|
|
71
|
+
label: 'Find a Recipe',
|
|
72
|
+
description: 'Search for recipe by cuisine style.',
|
|
73
|
+
},
|
|
74
|
+
operation: {
|
|
75
|
+
perform: '$func$2$f$',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
reason:
|
|
79
|
+
'Missing required key in operation: sample. Note - this is valid if the associated resource has defined a sample.',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
[BasicDisplaySchema, BasicActionOperationSchema, KeySchema]
|
|
84
|
+
);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
const { SKIP_KEY } = require('../constants');
|
|
5
|
+
|
|
6
|
+
const SearchSchema = require('./SearchSchema');
|
|
7
|
+
|
|
8
|
+
module.exports = makeSchema(
|
|
9
|
+
{
|
|
10
|
+
id: '/SearchesSchema',
|
|
11
|
+
description: 'Enumerates the searches your app has available for users.',
|
|
12
|
+
type: 'object',
|
|
13
|
+
patternProperties: {
|
|
14
|
+
'^[a-zA-Z]+[a-zA-Z0-9_]*$': {
|
|
15
|
+
description:
|
|
16
|
+
'Any unique key can be used and its values will be validated against the SearchSchema.',
|
|
17
|
+
$ref: SearchSchema.id,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
examples: [
|
|
21
|
+
{
|
|
22
|
+
recipe: {
|
|
23
|
+
key: 'recipe',
|
|
24
|
+
noun: 'Recipe',
|
|
25
|
+
display: {
|
|
26
|
+
label: 'Find a Recipe',
|
|
27
|
+
description: 'Search for recipe by cuisine style.',
|
|
28
|
+
hidden: true,
|
|
29
|
+
},
|
|
30
|
+
operation: { perform: '$func$2$f$' },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
antiExamples: [
|
|
35
|
+
{
|
|
36
|
+
[SKIP_KEY]: true, // Cannot validate that keys match
|
|
37
|
+
example: {
|
|
38
|
+
searchRecipe: {
|
|
39
|
+
key: 'recipe',
|
|
40
|
+
noun: 'Recipe',
|
|
41
|
+
display: {
|
|
42
|
+
label: 'Find a Recipe',
|
|
43
|
+
description: 'Search for recipe by cuisine style.',
|
|
44
|
+
hidden: true,
|
|
45
|
+
},
|
|
46
|
+
operation: { perform: '$func$2$f$' },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
reason: 'Key must match the key of the associated /SearchSchema',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
[SearchSchema]
|
|
54
|
+
);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
|
|
5
|
+
const BasicDisplaySchema = require('./BasicDisplaySchema');
|
|
6
|
+
const BasicHookOperationSchema = require('./BasicHookOperationSchema');
|
|
7
|
+
const BasicPollingOperationSchema = require('./BasicPollingOperationSchema');
|
|
8
|
+
const KeySchema = require('./KeySchema');
|
|
9
|
+
|
|
10
|
+
module.exports = makeSchema(
|
|
11
|
+
{
|
|
12
|
+
id: '/TriggerSchema',
|
|
13
|
+
description: 'How will Zapier get notified of new objects?',
|
|
14
|
+
type: 'object',
|
|
15
|
+
required: ['key', 'noun', 'display', 'operation'],
|
|
16
|
+
properties: {
|
|
17
|
+
key: {
|
|
18
|
+
description: 'A key to uniquely identify this trigger.',
|
|
19
|
+
$ref: KeySchema.id,
|
|
20
|
+
},
|
|
21
|
+
noun: {
|
|
22
|
+
description:
|
|
23
|
+
'A noun for this trigger that completes the sentence "triggers on a new XXX".',
|
|
24
|
+
type: 'string',
|
|
25
|
+
minLength: 2,
|
|
26
|
+
maxLength: 255,
|
|
27
|
+
},
|
|
28
|
+
display: {
|
|
29
|
+
description: 'Configures the UI for this trigger.',
|
|
30
|
+
$ref: BasicDisplaySchema.id,
|
|
31
|
+
},
|
|
32
|
+
operation: {
|
|
33
|
+
description: 'Powers the functionality for this trigger.',
|
|
34
|
+
anyOf: [
|
|
35
|
+
{ $ref: BasicPollingOperationSchema.id },
|
|
36
|
+
{ $ref: BasicHookOperationSchema.id },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
examples: [
|
|
42
|
+
{
|
|
43
|
+
key: 'new_recipe',
|
|
44
|
+
noun: 'Recipe',
|
|
45
|
+
display: {
|
|
46
|
+
label: 'New Recipe',
|
|
47
|
+
description: 'Triggers when a new recipe is added.',
|
|
48
|
+
},
|
|
49
|
+
operation: {
|
|
50
|
+
type: 'polling',
|
|
51
|
+
perform: '$func$0$f$',
|
|
52
|
+
sample: { id: 1 },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: 'new_recipe',
|
|
57
|
+
noun: 'Recipe',
|
|
58
|
+
display: {
|
|
59
|
+
label: 'New Recipe',
|
|
60
|
+
description: 'Triggers when a new recipe is added.',
|
|
61
|
+
hidden: true,
|
|
62
|
+
},
|
|
63
|
+
operation: {
|
|
64
|
+
type: 'polling',
|
|
65
|
+
perform: '$func$0$f$',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
antiExamples: [
|
|
70
|
+
{
|
|
71
|
+
example: {
|
|
72
|
+
key: 'new_recipe',
|
|
73
|
+
noun: 'Recipe',
|
|
74
|
+
display: {
|
|
75
|
+
label: 'New Recipe',
|
|
76
|
+
description: 'Triggers when a new recipe is added.',
|
|
77
|
+
},
|
|
78
|
+
operation: {
|
|
79
|
+
perform: '$func$0$f$',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
reason:
|
|
83
|
+
'Missing required key from operation: sample. Note - this is valid if the Recipe resource has defined a sample.',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
[
|
|
88
|
+
KeySchema,
|
|
89
|
+
BasicDisplaySchema,
|
|
90
|
+
BasicPollingOperationSchema,
|
|
91
|
+
BasicHookOperationSchema,
|
|
92
|
+
]
|
|
93
|
+
);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
const { SKIP_KEY } = require('../constants');
|
|
5
|
+
|
|
6
|
+
const TriggerSchema = require('./TriggerSchema');
|
|
7
|
+
|
|
8
|
+
module.exports = makeSchema(
|
|
9
|
+
{
|
|
10
|
+
id: '/TriggersSchema',
|
|
11
|
+
description: 'Enumerates the triggers your app has available for users.',
|
|
12
|
+
type: 'object',
|
|
13
|
+
patternProperties: {
|
|
14
|
+
'^[a-zA-Z]+[a-zA-Z0-9_]*$': {
|
|
15
|
+
description:
|
|
16
|
+
'Any unique key can be used and its values will be validated against the TriggerSchema.',
|
|
17
|
+
$ref: TriggerSchema.id,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
examples: [
|
|
22
|
+
{
|
|
23
|
+
newRecipe: {
|
|
24
|
+
key: 'newRecipe',
|
|
25
|
+
noun: 'Recipe',
|
|
26
|
+
display: {
|
|
27
|
+
label: 'New Recipe',
|
|
28
|
+
description: 'Triggers when a new recipe is added.',
|
|
29
|
+
},
|
|
30
|
+
operation: {
|
|
31
|
+
type: 'polling',
|
|
32
|
+
perform: '$func$0$f$',
|
|
33
|
+
sample: { id: 1 },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
antiExamples: [
|
|
39
|
+
{
|
|
40
|
+
example: {
|
|
41
|
+
[SKIP_KEY]: true, // Cannot validate that keys don't match
|
|
42
|
+
newRecipe: {
|
|
43
|
+
key: 'new_recipe',
|
|
44
|
+
noun: 'Recipe',
|
|
45
|
+
display: {
|
|
46
|
+
label: 'New Recipe',
|
|
47
|
+
description: 'Triggers when a new recipe is added.',
|
|
48
|
+
},
|
|
49
|
+
operation: {
|
|
50
|
+
type: 'polling',
|
|
51
|
+
perform: '$func$0$f$',
|
|
52
|
+
sample: { id: 1 },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
reason: 'Key must match the key on the associated /TriggerSchema',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
[TriggerSchema]
|
|
61
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
|
|
5
|
+
module.exports = makeSchema({
|
|
6
|
+
id: '/VersionSchema',
|
|
7
|
+
description:
|
|
8
|
+
'Represents a simplified semver string, from `0.0.0` to `999.999.999`.',
|
|
9
|
+
type: 'string',
|
|
10
|
+
pattern: '^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$',
|
|
11
|
+
examples: ['1.0.0', '2.11.3', '999.999.999'],
|
|
12
|
+
antiExamples: [
|
|
13
|
+
{ example: '1.0.0.0', reason: 'Must have only 2 periods' },
|
|
14
|
+
{ example: '1000.0.0', reason: 'Each number can be a maximum of 3 digits' },
|
|
15
|
+
{ example: 'v1.0.0', reason: 'No letters allowed' },
|
|
16
|
+
{ example: '1.0.0-beta', reson: 'No letters allowed' },
|
|
17
|
+
],
|
|
18
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const util = require('util');
|
|
4
|
+
|
|
5
|
+
const _ = require('lodash');
|
|
6
|
+
const toc = require('markdown-toc');
|
|
7
|
+
|
|
8
|
+
const packageJson = require('../../package.json');
|
|
9
|
+
const links = require('./links');
|
|
10
|
+
|
|
11
|
+
const NO_DESCRIPTION = '_No description given._';
|
|
12
|
+
const COMBOS = ['anyOf', 'allOf', 'oneOf'];
|
|
13
|
+
const { SKIP_KEY } = require('../constants');
|
|
14
|
+
|
|
15
|
+
const walkSchemas = (InitSchema, callback) => {
|
|
16
|
+
const recurse = (Schema, parents) => {
|
|
17
|
+
parents = parents || [];
|
|
18
|
+
callback(Schema, parents);
|
|
19
|
+
Schema.dependencies.forEach((childSchema) => {
|
|
20
|
+
const newParents = parents.concat([InitSchema]);
|
|
21
|
+
recurse(childSchema, newParents);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
recurse(InitSchema);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const collectSchemas = (InitSchema) => {
|
|
28
|
+
const schemas = {};
|
|
29
|
+
walkSchemas(InitSchema, (Schema) => {
|
|
30
|
+
schemas[Schema.id] = Schema;
|
|
31
|
+
});
|
|
32
|
+
return schemas;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const BREAK_LENGTH = 96;
|
|
36
|
+
const prepQuote = (val) => val.replace('`', '');
|
|
37
|
+
const quote = (val, triple, indent = '') =>
|
|
38
|
+
// either ``` with optional indentation or `
|
|
39
|
+
triple && val.length > BREAK_LENGTH
|
|
40
|
+
? '```\n' +
|
|
41
|
+
val
|
|
42
|
+
.match(/[^\r\n]+/g)
|
|
43
|
+
.map((line) => indent + line)
|
|
44
|
+
.join('\n') +
|
|
45
|
+
'\n' +
|
|
46
|
+
indent +
|
|
47
|
+
'```'
|
|
48
|
+
: `\`${prepQuote(val)}\``;
|
|
49
|
+
const quoteOrNa = (val, triple = false, indent = '') =>
|
|
50
|
+
val ? quote(val, triple, indent) : '_n/a_';
|
|
51
|
+
|
|
52
|
+
const formatExample = (example) => {
|
|
53
|
+
const ex = _.isPlainObject(example) ? _.omit(example, SKIP_KEY) : example;
|
|
54
|
+
return `* ${quoteOrNa(
|
|
55
|
+
util.inspect(ex, { depth: null, breakLength: BREAK_LENGTH }),
|
|
56
|
+
true,
|
|
57
|
+
' '
|
|
58
|
+
)}`.replace(/\s+\n/gm, '\n');
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Generate a display of the type (or link to a $ref).
|
|
62
|
+
const typeOrLink = (schema) => {
|
|
63
|
+
if (schema.type === 'array' && schema.items) {
|
|
64
|
+
return `${quoteOrNa(schema.type)}[${typeOrLink(schema.items)}]`;
|
|
65
|
+
}
|
|
66
|
+
if (schema.$ref) {
|
|
67
|
+
return `[${schema.$ref}](${links.anchor(schema.$ref)})`;
|
|
68
|
+
}
|
|
69
|
+
for (let i = 0; i < COMBOS.length; i++) {
|
|
70
|
+
const key = COMBOS[i];
|
|
71
|
+
if (schema[key] && schema[key].length) {
|
|
72
|
+
return `${key}(${schema[key].map(typeOrLink).join(', ')})`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (schema.enum && schema.enum.length) {
|
|
76
|
+
return `${quoteOrNa(schema.type)} in (${schema.enum
|
|
77
|
+
.map(util.inspect)
|
|
78
|
+
.map(quoteOrNa)
|
|
79
|
+
.join(', ')})`;
|
|
80
|
+
}
|
|
81
|
+
return quoteOrNa(schema.type);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Properly quote and display examples.
|
|
85
|
+
const makeExampleSection = (Schema) => {
|
|
86
|
+
const examples = Schema.schema.examples || [];
|
|
87
|
+
if (!examples.length) {
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
return `\
|
|
91
|
+
#### Examples
|
|
92
|
+
|
|
93
|
+
${examples.map(formatExample).join('\n')}
|
|
94
|
+
`;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Properly quote and display anti-examples.
|
|
98
|
+
const makeAntiExampleSection = (Schema) => {
|
|
99
|
+
const antiExamples = Schema.schema.antiExamples || [];
|
|
100
|
+
if (!antiExamples.length) {
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
return `\
|
|
104
|
+
#### Anti-Examples
|
|
105
|
+
|
|
106
|
+
${antiExamples
|
|
107
|
+
.map(({ example, reason }) => {
|
|
108
|
+
const formattedAntiExample = formatExample(example);
|
|
109
|
+
// If block quote, newline and indent the reason.
|
|
110
|
+
// Otherwise, show the reason inline w/ the anti-example and separated by a dash.
|
|
111
|
+
return formattedAntiExample.endsWith('```')
|
|
112
|
+
? `${formattedAntiExample}\n _${reason}_`
|
|
113
|
+
: `${formattedAntiExample} - _${reason}_`;
|
|
114
|
+
})
|
|
115
|
+
.join('\n')}
|
|
116
|
+
`;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const processProperty = (key, property, propIsRequired) => {
|
|
120
|
+
let isRequired = propIsRequired ? '**yes**' : 'no';
|
|
121
|
+
if (_.get(property, 'docAnnotation.hide')) {
|
|
122
|
+
return '';
|
|
123
|
+
} else if (_.get(property, 'docAnnotation.required')) {
|
|
124
|
+
// can also support keys besides "required"
|
|
125
|
+
const annotation = property.docAnnotation.required;
|
|
126
|
+
if (annotation.type === 'replace') {
|
|
127
|
+
isRequired = annotation.value;
|
|
128
|
+
} else if (annotation.type === 'append') {
|
|
129
|
+
isRequired += annotation.value;
|
|
130
|
+
} else {
|
|
131
|
+
throw new Error(`unrecognized docAnnotation type: ${annotation.type}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return `${quoteOrNa(key)} | ${isRequired} | ${typeOrLink(property)} | ${
|
|
135
|
+
property.description || NO_DESCRIPTION
|
|
136
|
+
}`;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Enumerate the properties as a table.
|
|
140
|
+
const makePropertiesSection = (Schema) => {
|
|
141
|
+
const properties =
|
|
142
|
+
Schema.schema.properties || Schema.schema.patternProperties || {};
|
|
143
|
+
if (!Object.keys(properties).length) {
|
|
144
|
+
return '';
|
|
145
|
+
}
|
|
146
|
+
const required = Schema.schema.required || [];
|
|
147
|
+
return `\
|
|
148
|
+
#### Properties
|
|
149
|
+
|
|
150
|
+
Key | Required | Type | Description
|
|
151
|
+
--- | -------- | ---- | -----------
|
|
152
|
+
${Object.keys(properties)
|
|
153
|
+
.map((key) => {
|
|
154
|
+
const property = properties[key];
|
|
155
|
+
return processProperty(key, property, required.includes(key));
|
|
156
|
+
})
|
|
157
|
+
.join('\n')}
|
|
158
|
+
`;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Given a "root" schema, create some markdown.
|
|
162
|
+
const makeMarkdownSection = (Schema) => {
|
|
163
|
+
return `\
|
|
164
|
+
## ${Schema.id}
|
|
165
|
+
|
|
166
|
+
${Schema.schema.description || NO_DESCRIPTION}
|
|
167
|
+
|
|
168
|
+
#### Details
|
|
169
|
+
|
|
170
|
+
* **Type** - ${typeOrLink(Schema.schema)}${
|
|
171
|
+
Schema.schema.pattern
|
|
172
|
+
? `
|
|
173
|
+
* **Pattern** - ${quoteOrNa(Schema.schema.pattern)}`
|
|
174
|
+
: ''
|
|
175
|
+
}
|
|
176
|
+
* [**Source Code**](${links.makeCodeLink(Schema.id)})
|
|
177
|
+
|
|
178
|
+
${makePropertiesSection(Schema)}
|
|
179
|
+
${makeExampleSection(Schema)}
|
|
180
|
+
${makeAntiExampleSection(Schema)}
|
|
181
|
+
`.trim();
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Generate the final markdown.
|
|
185
|
+
const buildDocs = (InitSchema) => {
|
|
186
|
+
const schemas = collectSchemas(InitSchema);
|
|
187
|
+
const markdownSections = _.chain(schemas)
|
|
188
|
+
.values()
|
|
189
|
+
.sortBy('id')
|
|
190
|
+
.map(makeMarkdownSection)
|
|
191
|
+
.join('\n\n-----\n\n');
|
|
192
|
+
const docs = `\
|
|
193
|
+
<!-- {% raw %} -->
|
|
194
|
+
# \`zapier-platform-schema\` Generated Documentation
|
|
195
|
+
|
|
196
|
+
This is automatically generated by the \`npm run docs\` command in \`zapier-platform-schema\` version ${quoteOrNa(
|
|
197
|
+
packageJson.version
|
|
198
|
+
)}.
|
|
199
|
+
|
|
200
|
+
-----
|
|
201
|
+
|
|
202
|
+
## Index
|
|
203
|
+
<!-- toc -->
|
|
204
|
+
|
|
205
|
+
-----
|
|
206
|
+
|
|
207
|
+
${markdownSections}
|
|
208
|
+
<!-- {% endraw %} -->
|
|
209
|
+
`.trim();
|
|
210
|
+
return toc.insert(docs, { maxdepth: 2, bullets: '*' });
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
module.exports = buildDocs;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const packageJson = require('../../package.json');
|
|
5
|
+
|
|
6
|
+
const exportSchema = (InitSchema) => {
|
|
7
|
+
const exportedSchema = {
|
|
8
|
+
version: packageJson.version,
|
|
9
|
+
schemas: {},
|
|
10
|
+
};
|
|
11
|
+
const addAndRecurse = (Schema) => {
|
|
12
|
+
exportedSchema.schemas[Schema.id.replace('/', '')] = _.omit(
|
|
13
|
+
Schema.schema,
|
|
14
|
+
'examples',
|
|
15
|
+
'antiExamples'
|
|
16
|
+
);
|
|
17
|
+
Schema.dependencies.map(addAndRecurse);
|
|
18
|
+
};
|
|
19
|
+
addAndRecurse(InitSchema);
|
|
20
|
+
return exportedSchema;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
module.exports = exportSchema;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
3
|
+
const packageJson = require('../../package.json');
|
|
4
|
+
const constants = require('../constants.js');
|
|
5
|
+
|
|
6
|
+
// From '</SomeSchema>' to 'SomeSchema'.
|
|
7
|
+
const filename = (val) => _.trim(String(val), '/<>');
|
|
8
|
+
|
|
9
|
+
// From '/SomeSchema' to '#someschema'.
|
|
10
|
+
const anchor = (val) => '#' + filename(val.toLowerCase());
|
|
11
|
+
|
|
12
|
+
const makeCodeLink = (id) =>
|
|
13
|
+
`${constants.ROOT_GITHUB}/blob/zapier-platform-schema@${
|
|
14
|
+
packageJson.version
|
|
15
|
+
}/packages/schema/lib/schemas/${filename(id)}.js`;
|
|
16
|
+
const makeDocLink = (id) =>
|
|
17
|
+
_.template(constants.DOC_URL_TEMPLATE)({
|
|
18
|
+
version: packageJson.version,
|
|
19
|
+
anchor: anchor(id),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
filename: filename,
|
|
24
|
+
anchor: anchor,
|
|
25
|
+
makeCodeLink: makeCodeLink,
|
|
26
|
+
makeDocLink: makeDocLink,
|
|
27
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
|
|
5
|
+
const makeValidator = require('./makeValidator');
|
|
6
|
+
|
|
7
|
+
const getRawSchema = (schema) => schema.schema;
|
|
8
|
+
|
|
9
|
+
const getDependencies = (schema) => schema.dependencies;
|
|
10
|
+
|
|
11
|
+
const flattenDependencies = (schemas) => {
|
|
12
|
+
schemas = schemas || [];
|
|
13
|
+
return _.flatten(schemas.map(getDependencies).concat(schemas));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const makeSchema = (schemaDefinition, schemaDependencies) => {
|
|
17
|
+
const dependencies = flattenDependencies(schemaDependencies);
|
|
18
|
+
const validatorDependencies = dependencies.map(getRawSchema);
|
|
19
|
+
return {
|
|
20
|
+
dependencies,
|
|
21
|
+
id: schemaDefinition.id,
|
|
22
|
+
schema: schemaDefinition,
|
|
23
|
+
validate: makeValidator(schemaDefinition, validatorDependencies).validate,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
module.exports = makeSchema;
|