zapier-platform-schema 11.0.0 → 11.2.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/LICENSE +1 -2
- package/exported-schema.json +90 -5
- package/lib/functional-constraints/uniqueInputFieldKeys.js +5 -0
- package/lib/schemas/BasicHookOperationSchema.js +5 -0
- package/lib/schemas/BasicHookToPollOperationSchema.js +93 -0
- package/lib/schemas/BasicPollingOperationSchema.js +2 -1
- package/lib/schemas/FieldSchema.js +5 -4
- package/lib/schemas/RefResourceSchema.js +13 -2
- package/lib/schemas/TriggerSchema.js +3 -0
- package/lib/utils/buildDocs.js +14 -3
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
Copyright (c) Zapier, Inc.
|
|
2
2
|
|
|
3
|
-
This repository is part of Zapier Platform, of
|
|
4
|
-
https://zapier.com/platform/tos.
|
|
3
|
+
This repository is part of Zapier Platform. By downloading, installing, accessing, or using any part of the Zapier Platform, including this repository, you agree to the Zapier Platform Agreement, which can be found at: https://zapier.com/platform/tos. If you do not agree to the Zapier Platform Agreement, you may not download, install, access, or use any part of the Zapier Platform, including this repository.
|
package/exported-schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "11.
|
|
2
|
+
"version": "11.2.0",
|
|
3
3
|
"schemas": {
|
|
4
4
|
"AppSchema": {
|
|
5
5
|
"id": "/AppSchema",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"id": "/RefResourceSchema",
|
|
116
116
|
"description": "Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.",
|
|
117
117
|
"type": "string",
|
|
118
|
-
"pattern": "^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*)?$"
|
|
118
|
+
"pattern": "^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_\\s\\[\\]]+(\\.[a-zA-Z0-9_\\s\\[\\]]+(,[a-zA-Z0-9_\\s\\[\\]]+)*)?$"
|
|
119
119
|
},
|
|
120
120
|
"FieldChoicesSchema": {
|
|
121
121
|
"id": "/FieldChoicesSchema",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"maxLength": 1000
|
|
165
165
|
},
|
|
166
166
|
"type": {
|
|
167
|
-
"description": "The type of this value.",
|
|
167
|
+
"description": "The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font.",
|
|
168
168
|
"type": "string",
|
|
169
169
|
"enum": [
|
|
170
170
|
"string",
|
|
@@ -175,7 +175,8 @@
|
|
|
175
175
|
"datetime",
|
|
176
176
|
"file",
|
|
177
177
|
"password",
|
|
178
|
-
"copy"
|
|
178
|
+
"copy",
|
|
179
|
+
"code"
|
|
179
180
|
]
|
|
180
181
|
},
|
|
181
182
|
"required": {
|
|
@@ -732,6 +733,10 @@
|
|
|
732
733
|
}
|
|
733
734
|
}
|
|
734
735
|
},
|
|
736
|
+
"canPaginate": {
|
|
737
|
+
"description": "Does this endpoint support pagination via temporary cursor storage?",
|
|
738
|
+
"type": "boolean"
|
|
739
|
+
},
|
|
735
740
|
"performSubscribe": {
|
|
736
741
|
"description": "Takes a URL and any necessary data from the user and subscribes. Note: this is required for public apps to ensure the best UX for the end-user. For private apps, you can ignore warnings about this property with the `--without-style` flag during `zapier push`.",
|
|
737
742
|
"oneOf": [
|
|
@@ -816,7 +821,7 @@
|
|
|
816
821
|
]
|
|
817
822
|
},
|
|
818
823
|
"canPaginate": {
|
|
819
|
-
"description": "Does this endpoint support
|
|
824
|
+
"description": "Does this endpoint support pagination via temporary cursor storage?",
|
|
820
825
|
"type": "boolean"
|
|
821
826
|
},
|
|
822
827
|
"inputFields": {
|
|
@@ -1059,6 +1064,83 @@
|
|
|
1059
1064
|
},
|
|
1060
1065
|
"additionalProperties": false
|
|
1061
1066
|
},
|
|
1067
|
+
"BasicHookToPollOperationSchema": {
|
|
1068
|
+
"id": "/BasicHookToPollOperationSchema",
|
|
1069
|
+
"description": "Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.",
|
|
1070
|
+
"type": "object",
|
|
1071
|
+
"required": ["performList", "performSubscribe", "performUnsubscribe"],
|
|
1072
|
+
"properties": {
|
|
1073
|
+
"type": {
|
|
1074
|
+
"description": "Must be explicitly set to `\"hook_to_poll\"`.",
|
|
1075
|
+
"type": "string",
|
|
1076
|
+
"enum": ["hook_to_poll"],
|
|
1077
|
+
"required": {
|
|
1078
|
+
"type": "replace",
|
|
1079
|
+
"value": "**yes** (with exceptions, see description)"
|
|
1080
|
+
}
|
|
1081
|
+
},
|
|
1082
|
+
"performList": {
|
|
1083
|
+
"description": "Similar a polling trigger, but checks for new data when a webhook is received, instead of every few minutes",
|
|
1084
|
+
"oneOf": [
|
|
1085
|
+
{
|
|
1086
|
+
"$ref": "/RequestSchema"
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
"$ref": "/FunctionSchema"
|
|
1090
|
+
}
|
|
1091
|
+
]
|
|
1092
|
+
},
|
|
1093
|
+
"canPaginate": {
|
|
1094
|
+
"description": "Does this endpoint support pagination via temporary cursor storage?",
|
|
1095
|
+
"type": "boolean"
|
|
1096
|
+
},
|
|
1097
|
+
"performSubscribe": {
|
|
1098
|
+
"description": "Takes a URL and any necessary data from the user and subscribes. ",
|
|
1099
|
+
"oneOf": [
|
|
1100
|
+
{
|
|
1101
|
+
"$ref": "/RequestSchema"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
"$ref": "/FunctionSchema"
|
|
1105
|
+
}
|
|
1106
|
+
]
|
|
1107
|
+
},
|
|
1108
|
+
"performUnsubscribe": {
|
|
1109
|
+
"description": "Takes a URL and data from a previous subscribe call and unsubscribes. ",
|
|
1110
|
+
"oneOf": [
|
|
1111
|
+
{
|
|
1112
|
+
"$ref": "/RequestSchema"
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
"$ref": "/FunctionSchema"
|
|
1116
|
+
}
|
|
1117
|
+
]
|
|
1118
|
+
},
|
|
1119
|
+
"inputFields": {
|
|
1120
|
+
"description": "What should the form a user sees and configures look like?",
|
|
1121
|
+
"$ref": "/DynamicFieldsSchema"
|
|
1122
|
+
},
|
|
1123
|
+
"outputFields": {
|
|
1124
|
+
"description": "What fields of data will this return? Will use resource outputFields if missing, will also use sample if available.",
|
|
1125
|
+
"$ref": "/DynamicFieldsSchema"
|
|
1126
|
+
},
|
|
1127
|
+
"sample": {
|
|
1128
|
+
"description": "What does a sample of data look like? Will use resource sample if missing. Requirement waived if `display.hidden` is true or if this belongs to a resource that has a top-level sample",
|
|
1129
|
+
"type": "object",
|
|
1130
|
+
"minProperties": 1,
|
|
1131
|
+
"docAnnotation": {
|
|
1132
|
+
"required": {
|
|
1133
|
+
"type": "replace",
|
|
1134
|
+
"value": "**yes** (with exceptions, see description)"
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
},
|
|
1139
|
+
"additionalProperties": false,
|
|
1140
|
+
"docAnnotation": {
|
|
1141
|
+
"hide": true
|
|
1142
|
+
}
|
|
1143
|
+
},
|
|
1062
1144
|
"TriggerSchema": {
|
|
1063
1145
|
"id": "/TriggerSchema",
|
|
1064
1146
|
"description": "How will Zapier get notified of new objects?",
|
|
@@ -1087,6 +1169,9 @@
|
|
|
1087
1169
|
},
|
|
1088
1170
|
{
|
|
1089
1171
|
"$ref": "/BasicHookOperationSchema"
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
"$ref": "/BasicHookToPollOperationSchema"
|
|
1090
1175
|
}
|
|
1091
1176
|
]
|
|
1092
1177
|
}
|
|
@@ -15,6 +15,11 @@ const uniqueInputFieldKeys = (definition) => {
|
|
|
15
15
|
const existingKeys = {}; // map of key to where it already lives
|
|
16
16
|
|
|
17
17
|
inputFields.forEach((inputField, index) => {
|
|
18
|
+
// could be a string or a non-field object (`source` or `require` function obj)
|
|
19
|
+
if (!inputField.key) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
if (existingKeys[inputField.key]) {
|
|
19
24
|
errors.push(
|
|
20
25
|
new jsonschema.ValidationError(
|
|
@@ -51,6 +51,11 @@ BasicHookOperationSchema.properties = {
|
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
+
canPaginate: {
|
|
55
|
+
description:
|
|
56
|
+
'Does this endpoint support pagination via temporary cursor storage?',
|
|
57
|
+
type: 'boolean',
|
|
58
|
+
},
|
|
54
59
|
performSubscribe: {
|
|
55
60
|
description:
|
|
56
61
|
'Takes a URL and any necessary data from the user and subscribes. ' +
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const makeSchema = require('../utils/makeSchema');
|
|
4
|
+
const { SKIP_KEY } = require('../constants');
|
|
5
|
+
|
|
6
|
+
const BasicOperationSchema = require('./BasicOperationSchema');
|
|
7
|
+
const FunctionSchema = require('./FunctionSchema');
|
|
8
|
+
const RequestSchema = require('./RequestSchema');
|
|
9
|
+
|
|
10
|
+
// TODO: would be nice to deep merge these instead
|
|
11
|
+
// or maybe use allOf which is built into json-schema
|
|
12
|
+
const BasicHookToPollOperationSchema = JSON.parse(
|
|
13
|
+
JSON.stringify(BasicOperationSchema.schema)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
BasicHookToPollOperationSchema.id = '/BasicHookToPollOperationSchema';
|
|
17
|
+
|
|
18
|
+
BasicHookToPollOperationSchema.description =
|
|
19
|
+
'Represents the inbound mechanics of hook to poll style triggers. Defers to list for fields.';
|
|
20
|
+
|
|
21
|
+
BasicHookToPollOperationSchema.docAnnotation = {
|
|
22
|
+
hide: true,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
BasicHookToPollOperationSchema.required = [
|
|
26
|
+
'performList',
|
|
27
|
+
'performSubscribe',
|
|
28
|
+
'performUnsubscribe',
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
BasicHookToPollOperationSchema.properties = {
|
|
32
|
+
type: {
|
|
33
|
+
description: 'Must be explicitly set to `"hook_to_poll"`.',
|
|
34
|
+
type: 'string',
|
|
35
|
+
enum: ['hook_to_poll'],
|
|
36
|
+
required: {
|
|
37
|
+
type: 'replace',
|
|
38
|
+
value: '**yes** (with exceptions, see description)',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
performList: {
|
|
42
|
+
description:
|
|
43
|
+
'Similar a polling trigger, but checks for new data when a webhook is received, instead of every few minutes',
|
|
44
|
+
oneOf: [{ $ref: RequestSchema.id }, { $ref: FunctionSchema.id }],
|
|
45
|
+
},
|
|
46
|
+
canPaginate: {
|
|
47
|
+
description:
|
|
48
|
+
'Does this endpoint support pagination via temporary cursor storage?',
|
|
49
|
+
type: 'boolean',
|
|
50
|
+
},
|
|
51
|
+
performSubscribe: {
|
|
52
|
+
description:
|
|
53
|
+
'Takes a URL and any necessary data from the user and subscribes. ',
|
|
54
|
+
oneOf: [{ $ref: RequestSchema.id }, { $ref: FunctionSchema.id }],
|
|
55
|
+
},
|
|
56
|
+
performUnsubscribe: {
|
|
57
|
+
description:
|
|
58
|
+
'Takes a URL and data from a previous subscribe call and unsubscribes. ',
|
|
59
|
+
oneOf: [{ $ref: RequestSchema.id }, { $ref: FunctionSchema.id }],
|
|
60
|
+
},
|
|
61
|
+
inputFields: BasicHookToPollOperationSchema.properties.inputFields,
|
|
62
|
+
outputFields: BasicHookToPollOperationSchema.properties.outputFields,
|
|
63
|
+
sample: BasicHookToPollOperationSchema.properties.sample,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
BasicHookToPollOperationSchema.examples = [
|
|
67
|
+
{
|
|
68
|
+
type: 'hook_to_poll',
|
|
69
|
+
performList: { require: 'some/path/to/file2.js' },
|
|
70
|
+
performSubscribe: { require: 'some/path/to/file3.js' },
|
|
71
|
+
performUnsubscribe: { require: 'some/path/to/file4.js' },
|
|
72
|
+
sample: { id: 42, name: 'Hooli' },
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
BasicHookToPollOperationSchema.antiExamples = [
|
|
77
|
+
{
|
|
78
|
+
[SKIP_KEY]: true, // Cannot validate that sample is only required if display isn't true
|
|
79
|
+
example: {
|
|
80
|
+
type: 'hook_to_poll',
|
|
81
|
+
performList: { require: 'some/path/to/file2.js' },
|
|
82
|
+
performSubscribe: { require: 'some/path/to/file3.js' },
|
|
83
|
+
performUnsubscribe: { require: 'some/path/to/file4.js' },
|
|
84
|
+
},
|
|
85
|
+
reason:
|
|
86
|
+
'Missing required key: sample. Note - This is only invalid if `display` is not explicitly set to true',
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
module.exports = makeSchema(
|
|
91
|
+
BasicHookToPollOperationSchema,
|
|
92
|
+
BasicOperationSchema.dependencies
|
|
93
|
+
);
|
|
@@ -26,7 +26,8 @@ BasicPollingOperationSchema.properties = {
|
|
|
26
26
|
resource: BasicPollingOperationSchema.properties.resource,
|
|
27
27
|
perform: BasicPollingOperationSchema.properties.perform,
|
|
28
28
|
canPaginate: {
|
|
29
|
-
description:
|
|
29
|
+
description:
|
|
30
|
+
'Does this endpoint support pagination via temporary cursor storage?',
|
|
30
31
|
type: 'boolean',
|
|
31
32
|
},
|
|
32
33
|
inputFields: BasicPollingOperationSchema.properties.inputFields,
|
|
@@ -14,9 +14,8 @@ const { INCOMPATIBLE_FIELD_SCHEMA_KEYS } = require('../constants');
|
|
|
14
14
|
// ... etc
|
|
15
15
|
const wrapInBackticks = (s) => `\`${s}\``;
|
|
16
16
|
const formatBullet = (f) => `* ${f.map(wrapInBackticks).join(' & ')}`;
|
|
17
|
-
const incompatibleFieldsList =
|
|
18
|
-
formatBullet
|
|
19
|
-
).join('\n');
|
|
17
|
+
const incompatibleFieldsList =
|
|
18
|
+
INCOMPATIBLE_FIELD_SCHEMA_KEYS.map(formatBullet).join('\n');
|
|
20
19
|
|
|
21
20
|
module.exports = makeSchema(
|
|
22
21
|
{
|
|
@@ -45,7 +44,8 @@ module.exports = makeSchema(
|
|
|
45
44
|
maxLength: 1000,
|
|
46
45
|
},
|
|
47
46
|
type: {
|
|
48
|
-
description:
|
|
47
|
+
description:
|
|
48
|
+
'The type of this value. Use `string` for basic text input, `text` for a large, `<textarea>` style box, and `code` for a `<textarea>` with a fixed-width font.',
|
|
49
49
|
type: 'string',
|
|
50
50
|
// string == unicode
|
|
51
51
|
// text == a long textarea string
|
|
@@ -61,6 +61,7 @@ module.exports = makeSchema(
|
|
|
61
61
|
'file',
|
|
62
62
|
'password',
|
|
63
63
|
'copy',
|
|
64
|
+
'code',
|
|
64
65
|
],
|
|
65
66
|
},
|
|
66
67
|
required: {
|
|
@@ -7,18 +7,29 @@ module.exports = makeSchema({
|
|
|
7
7
|
description:
|
|
8
8
|
'Reference a resource by key and the data it returns. In the format of: `{resource_key}.{foreign_key}(.{human_label_key})`.',
|
|
9
9
|
type: 'string',
|
|
10
|
+
// the human_label_key should match the broad `string` type that FieldSchema.key can be, with commas!
|
|
10
11
|
pattern:
|
|
11
|
-
'^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*)?$',
|
|
12
|
+
'^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_\\s\\[\\]]+(\\.[a-zA-Z0-9_\\s\\[\\]]+(,[a-zA-Z0-9_\\s\\[\\]]+)*)?$',
|
|
12
13
|
examples: [
|
|
13
14
|
'contact.id',
|
|
14
15
|
'contact.id.name',
|
|
15
16
|
'contact.id.firstName,lastName',
|
|
16
17
|
'contact.id.first_name,last_name,email',
|
|
18
|
+
'contact.Contact Id.Full Name',
|
|
19
|
+
'contact.data[]id.data[]First Name,data[]Last Name',
|
|
17
20
|
],
|
|
18
21
|
antiExamples: [
|
|
22
|
+
{
|
|
23
|
+
example: 'Contact List',
|
|
24
|
+
reason: 'Does not match resource_key pattern',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
example: 'Contact.list,find.id',
|
|
28
|
+
reason: 'Does not match foreign_key pattern',
|
|
29
|
+
},
|
|
19
30
|
{
|
|
20
31
|
example: 'Contact.list.id.full_name',
|
|
21
|
-
reason: 'Does not match pattern',
|
|
32
|
+
reason: 'Does not match human_label_key pattern',
|
|
22
33
|
},
|
|
23
34
|
],
|
|
24
35
|
});
|
|
@@ -4,6 +4,7 @@ const makeSchema = require('../utils/makeSchema');
|
|
|
4
4
|
|
|
5
5
|
const BasicDisplaySchema = require('./BasicDisplaySchema');
|
|
6
6
|
const BasicHookOperationSchema = require('./BasicHookOperationSchema');
|
|
7
|
+
const BasicHookToPollOperationSchema = require('./BasicHookToPollOperationSchema');
|
|
7
8
|
const BasicPollingOperationSchema = require('./BasicPollingOperationSchema');
|
|
8
9
|
const KeySchema = require('./KeySchema');
|
|
9
10
|
|
|
@@ -34,6 +35,7 @@ module.exports = makeSchema(
|
|
|
34
35
|
anyOf: [
|
|
35
36
|
{ $ref: BasicPollingOperationSchema.id },
|
|
36
37
|
{ $ref: BasicHookOperationSchema.id },
|
|
38
|
+
{ $ref: BasicHookToPollOperationSchema.id },
|
|
37
39
|
],
|
|
38
40
|
},
|
|
39
41
|
},
|
|
@@ -89,5 +91,6 @@ module.exports = makeSchema(
|
|
|
89
91
|
BasicDisplaySchema,
|
|
90
92
|
BasicPollingOperationSchema,
|
|
91
93
|
BasicHookOperationSchema,
|
|
94
|
+
BasicHookToPollOperationSchema,
|
|
92
95
|
]
|
|
93
96
|
);
|
package/lib/utils/buildDocs.js
CHANGED
|
@@ -11,6 +11,7 @@ const links = require('./links');
|
|
|
11
11
|
const NO_DESCRIPTION = '_No description given._';
|
|
12
12
|
const COMBOS = ['anyOf', 'allOf', 'oneOf'];
|
|
13
13
|
const { SKIP_KEY } = require('../constants');
|
|
14
|
+
const hiddenRefs = [];
|
|
14
15
|
|
|
15
16
|
const walkSchemas = (InitSchema, callback) => {
|
|
16
17
|
const recurse = (Schema, parents) => {
|
|
@@ -27,7 +28,11 @@ const walkSchemas = (InitSchema, callback) => {
|
|
|
27
28
|
const collectSchemas = (InitSchema) => {
|
|
28
29
|
const schemas = {};
|
|
29
30
|
walkSchemas(InitSchema, (Schema) => {
|
|
30
|
-
|
|
31
|
+
if (!_.get(Schema, 'schema.docAnnotation.hide')) {
|
|
32
|
+
schemas[Schema.id] = Schema;
|
|
33
|
+
} else {
|
|
34
|
+
hiddenRefs.push(Schema.id);
|
|
35
|
+
}
|
|
31
36
|
});
|
|
32
37
|
return schemas;
|
|
33
38
|
};
|
|
@@ -64,12 +69,18 @@ const typeOrLink = (schema) => {
|
|
|
64
69
|
return `${quoteOrNa(schema.type)}[${typeOrLink(schema.items)}]`;
|
|
65
70
|
}
|
|
66
71
|
if (schema.$ref) {
|
|
67
|
-
|
|
72
|
+
if (!hiddenRefs.includes(schema.$ref)) {
|
|
73
|
+
return `[${schema.$ref}](${links.anchor(schema.$ref)})`;
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
68
76
|
}
|
|
69
77
|
for (let i = 0; i < COMBOS.length; i++) {
|
|
70
78
|
const key = COMBOS[i];
|
|
71
79
|
if (schema[key] && schema[key].length) {
|
|
72
|
-
return `${key}(${schema[key]
|
|
80
|
+
return `${key}(${schema[key]
|
|
81
|
+
.map(typeOrLink)
|
|
82
|
+
.filter(Boolean)
|
|
83
|
+
.join(', ')})`;
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
if (schema.enum && schema.enum.length) {
|
package/package.json
CHANGED