@fourier-labs/harbour-contracts 0.74.0 → 0.77.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 +4 -4
- package/contract-release.json +26 -26
- package/dist/gen-ts/app-integrations-declaration.d.ts +15 -1
- package/dist/gen-ts/contract-release.d.ts +6 -6
- package/dist/gen-ts/contract-release.js +6 -6
- package/dist/gen-ts/data-grant-v2.d.ts +5 -5
- package/dist/gen-ts/deploy-request.d.ts +3 -3
- package/dist/gen-ts/deployment-source.d.ts +4 -4
- package/dist/gen-ts/integration-execute-input-rules.d.ts +214 -0
- package/dist/gen-ts/integration-execute-input-rules.js +85 -0
- package/dist/gen-ts/integration-execute-request.d.ts +53 -6
- package/dist/gen-ts/integration-execute-result.d.ts +161 -1
- package/dist/gen-ts/integration-operations.d.ts +77 -0
- package/dist/gen-ts/integration-operations.js +99 -0
- package/dist/gen-ts/saas-connection.d.ts +22 -8
- package/gen-ts/app-integrations-declaration.ts +15 -1
- package/gen-ts/contract-release.ts +6 -6
- package/gen-ts/data-grant-v2.ts +15 -4
- package/gen-ts/deploy-request.ts +3 -3
- package/gen-ts/deployment-source.ts +4 -4
- package/gen-ts/integration-execute-input-rules.ts +86 -1
- package/gen-ts/integration-execute-request.ts +63 -5
- package/gen-ts/integration-execute-result.ts +161 -1
- package/gen-ts/integration-operations.ts +99 -0
- package/gen-ts/saas-connection.ts +32 -7
- package/package.json +1 -1
- package/schema/app-integrations-declaration.schema.json +233 -2
- package/schema/data-grant-v2.schema.json +4 -4
- package/schema/deploy-request.schema.json +4 -4
- package/schema/deployment-source.schema.json +9 -5
- package/schema/integration-execute-request.schema.json +529 -4
- package/schema/integration-execute-result.schema.json +542 -1
- package/schema/saas-connection.schema.json +35 -7
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://schemas.harbour.dev/integration-execute-request.schema.json",
|
|
4
4
|
"title": "IntegrationExecuteRequest",
|
|
5
|
-
"description": "Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is fixed by the operation for every operation but the declared-mode Slack operations (slack.channel.history, slack.message.post, slack.message.update, slack.message.delete; 0.71.0 widened history), and always enforced from an approved grant; any identity/userId/scope field is rejected by additionalProperties. A declared-mode operation runs as the app (for a post: the IT-approved per-app name from the grant, plus a \"Posted by <app> on Isomorph\" footer) or as the signed-in person (no name, no footer) \u2014 the same input either way \u2014 and since 0.55.0 the call names which of the app's approved modes it runs under (`mode`): required when IT approved both modes for the app (MODE_REQUIRED otherwise), optional when it approved one (that one is used), and a named mode without an approved grant is refused (MODE_NOT_GRANTED) rather than served under the other, so approval order never decides what a call does. Per-operation input bounds (0.71.0, ADR 0018): slack.channel.history {limit? 1..100, default 15, cursor?, oldest?, latest?}; slack.message.post {text 1..4000 chars, threadId?, format? plain|mrkdwn} and a required idempotencyKey retained across retries of one explicit Send; slack.message.update {messageId, text, format?}; slack.message.delete {messageId}; slack.dm.send {to 1..8 addresses, text, format?} (app mode only) with a required idempotencyKey; slack.user.lookup {email}; gmail.thread.list {limit? 1..50, default 15, q?, labelIds? default [INBOX], pageToken?}; gmail.thread.read {threadId}; gmail.message.read {messageId}; gmail.attachment.read {messageId, attachmentId}; gmail.message.send {to 1..50 addresses (to+cc+bcc <= 50 in total), cc?, bcc?, subject 1..256 chars, text 1..4000 chars, html? <= 64 KiB, attachments? 1..5 of <= 2 MiB each as base64, replyToMessageId?} and a required idempotencyKey like slack.message.post; warehouse.view.read {columns? 1..32, where? 1..16 filters, groupBy? 1..8 columns, aggregates? 1..16, orderBy? 1..8, limit? 1..1000, default 100} (0.70.0: a plain read names columns, an aggregate read names aggregates and optionally groupBy; the cross-field rules \u2014 exactly one of columns or aggregates, groupBy needs aggregates, a filter value that fits its op, orderBy naming a returned column, every named column approved \u2014 are enforced by governance, not expressible here; ADR 0017). Each operation's then-block is the one statement of its input rules: propertyNames.enum names the fields it accepts, required the ones it needs, and per-field overrides (maximum, default) narrow the shared property. Codegen derives IntegrationExecuteInputRules and validateIntegrationExecuteInput (gen-ts/integration-execute-input-rules.ts, gen-go/integration_execute_input_rules.go) from exactly these blocks, so the governance execute route, the app SDK and the kit's local check refuse the same request with the same message. Transport limits (not expressible here): request <= 16 KiB except a gmail.message.send carrying attachments (governance sizes that route for the attachment bound), total deadline 10 s.",
|
|
5
|
+
"description": "Body of POST /_harbour/integrations/execute (app SDK), forwarded unchanged to the governance development and runtime execute routes. Exactly one declared operation against one declared resource. The identity mode is fixed by the operation for every operation but the declared-mode Slack operations (slack.channel.history, slack.message.post, slack.message.update, slack.message.delete; 0.71.0 widened history), and always enforced from an approved grant; any identity/userId/scope field is rejected by additionalProperties. A declared-mode operation runs as the app (for a post: the IT-approved per-app name from the grant, plus a \"Posted by <app> on Isomorph\" footer) or as the signed-in person (no name, no footer) \u2014 the same input either way \u2014 and since 0.55.0 the call names which of the app's approved modes it runs under (`mode`): required when IT approved both modes for the app (MODE_REQUIRED otherwise), optional when it approved one (that one is used), and a named mode without an approved grant is refused (MODE_NOT_GRANTED) rather than served under the other, so approval order never decides what a call does. Per-operation input bounds (0.71.0, ADR 0018): slack.channel.history {limit? 1..100, default 15, cursor?, oldest?, latest?}; slack.message.post {text 1..4000 chars, threadId?, format? plain|mrkdwn} and a required idempotencyKey retained across retries of one explicit Send; slack.message.update {messageId, text, format?}; slack.message.delete {messageId}; slack.dm.send {to 1..8 addresses, text, format?} (app mode only) with a required idempotencyKey; slack.user.lookup {email}; gmail.thread.list {limit? 1..50, default 15, q?, labelIds? default [INBOX], pageToken?}; gmail.thread.read {threadId}; gmail.message.read {messageId}; gmail.attachment.read {messageId, attachmentId}; gmail.message.send {to 1..50 addresses (to+cc+bcc <= 50 in total), cc?, bcc?, subject 1..256 chars, text 1..4000 chars, html? <= 64 KiB, attachments? 1..5 of <= 2 MiB each as base64, replyToMessageId?} and a required idempotencyKey like slack.message.post; warehouse.view.read {columns? 1..32, where? 1..16 filters, groupBy? 1..8 columns, aggregates? 1..16, orderBy? 1..8, limit? 1..1000, default 100} (0.70.0: a plain read names columns, an aggregate read names aggregates and optionally groupBy; the cross-field rules \u2014 exactly one of columns or aggregates, groupBy needs aggregates, a filter value that fits its op, orderBy naming a returned column, every named column approved \u2014 are enforced by governance, not expressible here; ADR 0017). Basecamp (0.76.0, ADR 0022; every id a string of 1..20 digits, every operation user mode): basecamp.project.list {pageToken?, projectStatus? active|archived} on the fixed `account` alias; on a project alias basecamp.todolist.list {pageToken?}; basecamp.todo.list {todolistId, completed?, pageToken?}; basecamp.todo.create {todolistId, content 1..1000 (the to-do title), description? <= 16384, contentFormat? plain|html, dueOn? YYYY-MM-DD, assigneeIds? 1..20, notify?} with a required idempotencyKey; basecamp.todo.complete {todoId} (idempotent at Basecamp, so no key); basecamp.message.list {pageToken?}; basecamp.message.post {subject 1..256, content 1..65536, contentFormat?} with a required idempotencyKey; basecamp.comment.list {recordingId, pageToken?}; basecamp.comment.post {recordingId, content 1..16384, contentFormat?} with a required idempotencyKey; basecamp.campfire.post {content 1..4000, contentFormat?} with a required idempotencyKey; basecamp.people.list {pageToken?}. `pageToken` is the previous page's `nextPageToken` (a Basecamp page number as digits). Each operation's then-block is the one statement of its input rules: propertyNames.enum names the fields it accepts, required the ones it needs, and per-field overrides (maximum, default) narrow the shared property. Codegen derives IntegrationExecuteInputRules and validateIntegrationExecuteInput (gen-ts/integration-execute-input-rules.ts, gen-go/integration_execute_input_rules.go) from exactly these blocks, so the governance execute route, the app SDK and the kit's local check refuse the same request with the same message. Transport limits (not expressible here): request <= 16 KiB except a gmail.message.send carrying attachments (governance sizes that route for the attachment bound) and a basecamp.message.post (its 64 KiB body; governance allows 80 KiB there), total deadline 10 s.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": [
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"type": "string",
|
|
100
100
|
"minLength": 1,
|
|
101
101
|
"maxLength": 256,
|
|
102
|
-
"description": "gmail.thread.list (0.71.0): the `nextPageToken` of the previous page; absent reads the first page."
|
|
102
|
+
"description": "gmail.thread.list (0.71.0) and every basecamp.*.list operation (0.76.0): the `nextPageToken` of the previous page; absent reads the first page."
|
|
103
103
|
},
|
|
104
104
|
"email": {
|
|
105
105
|
"$ref": "#/definitions/EmailAddress",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"type": "string",
|
|
122
122
|
"minLength": 1,
|
|
123
123
|
"maxLength": 256,
|
|
124
|
-
"description": "gmail.message.send: one-line subject (no line breaks)."
|
|
124
|
+
"description": "gmail.message.send: one-line subject (no line breaks). basecamp.message.post (0.76.0): the message's title."
|
|
125
125
|
},
|
|
126
126
|
"replyToMessageId": {
|
|
127
127
|
"type": "string",
|
|
@@ -143,6 +143,61 @@
|
|
|
143
143
|
},
|
|
144
144
|
"description": "gmail.message.send (0.71.0): files to attach, 1..5, each at most 2 MiB (2,796,203 base64 characters)."
|
|
145
145
|
},
|
|
146
|
+
"todolistId": {
|
|
147
|
+
"$ref": "app-integrations-declaration.schema.json#/definitions/BasecampId",
|
|
148
|
+
"description": "basecamp.todo.list / basecamp.todo.create (0.76.0): the to-do list, as a basecamp.todolist.list result named it."
|
|
149
|
+
},
|
|
150
|
+
"todoId": {
|
|
151
|
+
"$ref": "app-integrations-declaration.schema.json#/definitions/BasecampId",
|
|
152
|
+
"description": "basecamp.todo.complete (0.76.0): the to-do, as a basecamp.todo.list or basecamp.todo.create result named it."
|
|
153
|
+
},
|
|
154
|
+
"recordingId": {
|
|
155
|
+
"$ref": "app-integrations-declaration.schema.json#/definitions/BasecampId",
|
|
156
|
+
"description": "basecamp.comment.list / basecamp.comment.post (0.76.0): the Basecamp recording commented on — a message, a to-do or any other id a basecamp.* result named."
|
|
157
|
+
},
|
|
158
|
+
"content": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"minLength": 1,
|
|
161
|
+
"maxLength": 65536,
|
|
162
|
+
"description": "basecamp.todo.create (0.76.0): the to-do's title, 1..1000 characters. basecamp.message.post: the body, at most 64 KiB; basecamp.comment.post: at most 16 KiB; basecamp.campfire.post: at most 4000 characters. Plain text unless `contentFormat` is html."
|
|
163
|
+
},
|
|
164
|
+
"contentFormat": {
|
|
165
|
+
"$ref": "#/definitions/BasecampContentFormat",
|
|
166
|
+
"description": "basecamp.todo.create / basecamp.message.post / basecamp.comment.post / basecamp.campfire.post (0.76.0): how `content` (and a to-do's `description`) is read; plain when absent."
|
|
167
|
+
},
|
|
168
|
+
"description": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"minLength": 1,
|
|
171
|
+
"maxLength": 16384,
|
|
172
|
+
"description": "basecamp.todo.create (0.76.0): the to-do's notes, at most 16 KiB, read the way `contentFormat` says."
|
|
173
|
+
},
|
|
174
|
+
"dueOn": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
177
|
+
"description": "basecamp.todo.create (0.76.0): the due date as YYYY-MM-DD; absent leaves the to-do undated."
|
|
178
|
+
},
|
|
179
|
+
"assigneeIds": {
|
|
180
|
+
"type": "array",
|
|
181
|
+
"minItems": 1,
|
|
182
|
+
"maxItems": 20,
|
|
183
|
+
"uniqueItems": true,
|
|
184
|
+
"items": {
|
|
185
|
+
"$ref": "app-integrations-declaration.schema.json#/definitions/BasecampId"
|
|
186
|
+
},
|
|
187
|
+
"description": "basecamp.todo.create (0.76.0): the people assigned, 1..20, by the ids a basecamp.people.list result named."
|
|
188
|
+
},
|
|
189
|
+
"notify": {
|
|
190
|
+
"type": "boolean",
|
|
191
|
+
"description": "basecamp.todo.create (0.76.0): whether Basecamp notifies the assignees; false when absent."
|
|
192
|
+
},
|
|
193
|
+
"completed": {
|
|
194
|
+
"type": "boolean",
|
|
195
|
+
"description": "basecamp.todo.list (0.76.0): true lists the completed to-dos instead of the open ones; absent lists the open ones."
|
|
196
|
+
},
|
|
197
|
+
"projectStatus": {
|
|
198
|
+
"$ref": "#/definitions/BasecampProjectStatus",
|
|
199
|
+
"description": "basecamp.project.list (0.76.0): which projects to list; active when absent."
|
|
200
|
+
},
|
|
146
201
|
"columns": {
|
|
147
202
|
"type": "array",
|
|
148
203
|
"minItems": 1,
|
|
@@ -239,7 +294,7 @@
|
|
|
239
294
|
"idempotencyKey": {
|
|
240
295
|
"type": "string",
|
|
241
296
|
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
|
|
242
|
-
"description": "UUID of one explicit Send action; required for slack.message.post
|
|
297
|
+
"description": "UUID of one explicit Send action; required for the sends (slack.message.post, slack.dm.send, gmail.message.send) and the receipted Basecamp writes (basecamp.todo.create, basecamp.message.post, basecamp.comment.post, basecamp.campfire.post; 0.76.0), refused everywhere else. The same key with the same payload and subject returns the recorded outcome for seven days."
|
|
243
298
|
},
|
|
244
299
|
"mode": {
|
|
245
300
|
"$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationIdentityMode",
|
|
@@ -654,6 +709,360 @@
|
|
|
654
709
|
}
|
|
655
710
|
}
|
|
656
711
|
},
|
|
712
|
+
{
|
|
713
|
+
"if": {
|
|
714
|
+
"properties": {
|
|
715
|
+
"operation": {
|
|
716
|
+
"const": "basecamp.project.list"
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
"then": {
|
|
721
|
+
"x-read-only": true,
|
|
722
|
+
"x-primary-identity": "user",
|
|
723
|
+
"not": {
|
|
724
|
+
"required": [
|
|
725
|
+
"idempotencyKey"
|
|
726
|
+
]
|
|
727
|
+
},
|
|
728
|
+
"properties": {
|
|
729
|
+
"mode": false,
|
|
730
|
+
"input": {
|
|
731
|
+
"propertyNames": {
|
|
732
|
+
"enum": [
|
|
733
|
+
"pageToken",
|
|
734
|
+
"projectStatus"
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
"if": {
|
|
743
|
+
"properties": {
|
|
744
|
+
"operation": {
|
|
745
|
+
"const": "basecamp.todolist.list"
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
"then": {
|
|
750
|
+
"x-read-only": true,
|
|
751
|
+
"x-primary-identity": "user",
|
|
752
|
+
"not": {
|
|
753
|
+
"required": [
|
|
754
|
+
"idempotencyKey"
|
|
755
|
+
]
|
|
756
|
+
},
|
|
757
|
+
"properties": {
|
|
758
|
+
"mode": false,
|
|
759
|
+
"input": {
|
|
760
|
+
"propertyNames": {
|
|
761
|
+
"enum": [
|
|
762
|
+
"pageToken"
|
|
763
|
+
]
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
"if": {
|
|
771
|
+
"properties": {
|
|
772
|
+
"operation": {
|
|
773
|
+
"const": "basecamp.todo.list"
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
"then": {
|
|
778
|
+
"x-read-only": true,
|
|
779
|
+
"x-primary-identity": "user",
|
|
780
|
+
"not": {
|
|
781
|
+
"required": [
|
|
782
|
+
"idempotencyKey"
|
|
783
|
+
]
|
|
784
|
+
},
|
|
785
|
+
"properties": {
|
|
786
|
+
"mode": false,
|
|
787
|
+
"input": {
|
|
788
|
+
"propertyNames": {
|
|
789
|
+
"enum": [
|
|
790
|
+
"todolistId",
|
|
791
|
+
"completed",
|
|
792
|
+
"pageToken"
|
|
793
|
+
]
|
|
794
|
+
},
|
|
795
|
+
"required": [
|
|
796
|
+
"todolistId"
|
|
797
|
+
]
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"if": {
|
|
804
|
+
"properties": {
|
|
805
|
+
"operation": {
|
|
806
|
+
"const": "basecamp.todo.create"
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
"then": {
|
|
811
|
+
"x-read-only": false,
|
|
812
|
+
"x-primary-identity": "user",
|
|
813
|
+
"required": [
|
|
814
|
+
"idempotencyKey"
|
|
815
|
+
],
|
|
816
|
+
"properties": {
|
|
817
|
+
"mode": false,
|
|
818
|
+
"input": {
|
|
819
|
+
"propertyNames": {
|
|
820
|
+
"enum": [
|
|
821
|
+
"todolistId",
|
|
822
|
+
"content",
|
|
823
|
+
"description",
|
|
824
|
+
"contentFormat",
|
|
825
|
+
"dueOn",
|
|
826
|
+
"assigneeIds",
|
|
827
|
+
"notify"
|
|
828
|
+
]
|
|
829
|
+
},
|
|
830
|
+
"required": [
|
|
831
|
+
"todolistId",
|
|
832
|
+
"content"
|
|
833
|
+
],
|
|
834
|
+
"properties": {
|
|
835
|
+
"content": {
|
|
836
|
+
"maxLength": 1000
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
"if": {
|
|
845
|
+
"properties": {
|
|
846
|
+
"operation": {
|
|
847
|
+
"const": "basecamp.todo.complete"
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
},
|
|
851
|
+
"then": {
|
|
852
|
+
"x-read-only": false,
|
|
853
|
+
"x-primary-identity": "user",
|
|
854
|
+
"not": {
|
|
855
|
+
"required": [
|
|
856
|
+
"idempotencyKey"
|
|
857
|
+
]
|
|
858
|
+
},
|
|
859
|
+
"properties": {
|
|
860
|
+
"mode": false,
|
|
861
|
+
"input": {
|
|
862
|
+
"propertyNames": {
|
|
863
|
+
"enum": [
|
|
864
|
+
"todoId"
|
|
865
|
+
]
|
|
866
|
+
},
|
|
867
|
+
"required": [
|
|
868
|
+
"todoId"
|
|
869
|
+
]
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
"if": {
|
|
876
|
+
"properties": {
|
|
877
|
+
"operation": {
|
|
878
|
+
"const": "basecamp.message.list"
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
"then": {
|
|
883
|
+
"x-read-only": true,
|
|
884
|
+
"x-primary-identity": "user",
|
|
885
|
+
"not": {
|
|
886
|
+
"required": [
|
|
887
|
+
"idempotencyKey"
|
|
888
|
+
]
|
|
889
|
+
},
|
|
890
|
+
"properties": {
|
|
891
|
+
"mode": false,
|
|
892
|
+
"input": {
|
|
893
|
+
"propertyNames": {
|
|
894
|
+
"enum": [
|
|
895
|
+
"pageToken"
|
|
896
|
+
]
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
"if": {
|
|
904
|
+
"properties": {
|
|
905
|
+
"operation": {
|
|
906
|
+
"const": "basecamp.message.post"
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
"then": {
|
|
911
|
+
"x-read-only": false,
|
|
912
|
+
"x-primary-identity": "user",
|
|
913
|
+
"required": [
|
|
914
|
+
"idempotencyKey"
|
|
915
|
+
],
|
|
916
|
+
"properties": {
|
|
917
|
+
"mode": false,
|
|
918
|
+
"input": {
|
|
919
|
+
"propertyNames": {
|
|
920
|
+
"enum": [
|
|
921
|
+
"subject",
|
|
922
|
+
"content",
|
|
923
|
+
"contentFormat"
|
|
924
|
+
]
|
|
925
|
+
},
|
|
926
|
+
"required": [
|
|
927
|
+
"subject",
|
|
928
|
+
"content"
|
|
929
|
+
]
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
"if": {
|
|
936
|
+
"properties": {
|
|
937
|
+
"operation": {
|
|
938
|
+
"const": "basecamp.comment.list"
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
"then": {
|
|
943
|
+
"x-read-only": true,
|
|
944
|
+
"x-primary-identity": "user",
|
|
945
|
+
"not": {
|
|
946
|
+
"required": [
|
|
947
|
+
"idempotencyKey"
|
|
948
|
+
]
|
|
949
|
+
},
|
|
950
|
+
"properties": {
|
|
951
|
+
"mode": false,
|
|
952
|
+
"input": {
|
|
953
|
+
"propertyNames": {
|
|
954
|
+
"enum": [
|
|
955
|
+
"recordingId",
|
|
956
|
+
"pageToken"
|
|
957
|
+
]
|
|
958
|
+
},
|
|
959
|
+
"required": [
|
|
960
|
+
"recordingId"
|
|
961
|
+
]
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
"if": {
|
|
968
|
+
"properties": {
|
|
969
|
+
"operation": {
|
|
970
|
+
"const": "basecamp.comment.post"
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
},
|
|
974
|
+
"then": {
|
|
975
|
+
"x-read-only": false,
|
|
976
|
+
"x-primary-identity": "user",
|
|
977
|
+
"required": [
|
|
978
|
+
"idempotencyKey"
|
|
979
|
+
],
|
|
980
|
+
"properties": {
|
|
981
|
+
"mode": false,
|
|
982
|
+
"input": {
|
|
983
|
+
"propertyNames": {
|
|
984
|
+
"enum": [
|
|
985
|
+
"recordingId",
|
|
986
|
+
"content",
|
|
987
|
+
"contentFormat"
|
|
988
|
+
]
|
|
989
|
+
},
|
|
990
|
+
"required": [
|
|
991
|
+
"recordingId",
|
|
992
|
+
"content"
|
|
993
|
+
],
|
|
994
|
+
"properties": {
|
|
995
|
+
"content": {
|
|
996
|
+
"maxLength": 16384
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
"if": {
|
|
1005
|
+
"properties": {
|
|
1006
|
+
"operation": {
|
|
1007
|
+
"const": "basecamp.campfire.post"
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
"then": {
|
|
1012
|
+
"x-read-only": false,
|
|
1013
|
+
"x-primary-identity": "user",
|
|
1014
|
+
"required": [
|
|
1015
|
+
"idempotencyKey"
|
|
1016
|
+
],
|
|
1017
|
+
"properties": {
|
|
1018
|
+
"mode": false,
|
|
1019
|
+
"input": {
|
|
1020
|
+
"propertyNames": {
|
|
1021
|
+
"enum": [
|
|
1022
|
+
"content",
|
|
1023
|
+
"contentFormat"
|
|
1024
|
+
]
|
|
1025
|
+
},
|
|
1026
|
+
"required": [
|
|
1027
|
+
"content"
|
|
1028
|
+
],
|
|
1029
|
+
"properties": {
|
|
1030
|
+
"content": {
|
|
1031
|
+
"maxLength": 4000
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
"if": {
|
|
1040
|
+
"properties": {
|
|
1041
|
+
"operation": {
|
|
1042
|
+
"const": "basecamp.people.list"
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
},
|
|
1046
|
+
"then": {
|
|
1047
|
+
"x-read-only": true,
|
|
1048
|
+
"x-primary-identity": "user",
|
|
1049
|
+
"not": {
|
|
1050
|
+
"required": [
|
|
1051
|
+
"idempotencyKey"
|
|
1052
|
+
]
|
|
1053
|
+
},
|
|
1054
|
+
"properties": {
|
|
1055
|
+
"mode": false,
|
|
1056
|
+
"input": {
|
|
1057
|
+
"propertyNames": {
|
|
1058
|
+
"enum": [
|
|
1059
|
+
"pageToken"
|
|
1060
|
+
]
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
657
1066
|
{
|
|
658
1067
|
"if": {
|
|
659
1068
|
"properties": {
|
|
@@ -723,6 +1132,23 @@
|
|
|
723
1132
|
"default": "plain",
|
|
724
1133
|
"description": "How Slack renders a message body (0.71.0): plain posts the text verbatim; mrkdwn lets Slack interpret its markup (*bold*, links, lists)."
|
|
725
1134
|
},
|
|
1135
|
+
"BasecampContentFormat": {
|
|
1136
|
+
"type": "string",
|
|
1137
|
+
"enum": [
|
|
1138
|
+
"plain",
|
|
1139
|
+
"html"
|
|
1140
|
+
],
|
|
1141
|
+
"default": "plain",
|
|
1142
|
+
"description": "How Basecamp reads a body (0.76.0): plain is HTML-escaped by governance with newlines as <br>; html is passed to Basecamp's rich text as written."
|
|
1143
|
+
},
|
|
1144
|
+
"BasecampProjectStatus": {
|
|
1145
|
+
"type": "string",
|
|
1146
|
+
"enum": [
|
|
1147
|
+
"active",
|
|
1148
|
+
"archived"
|
|
1149
|
+
],
|
|
1150
|
+
"description": "Which projects basecamp.project.list returns (0.76.0): the active ones (the default) or the archived ones."
|
|
1151
|
+
},
|
|
726
1152
|
"EmailAttachment": {
|
|
727
1153
|
"type": "object",
|
|
728
1154
|
"additionalProperties": false,
|
|
@@ -1178,6 +1604,105 @@
|
|
|
1178
1604
|
"total": null
|
|
1179
1605
|
}
|
|
1180
1606
|
]
|
|
1607
|
+
},
|
|
1608
|
+
{
|
|
1609
|
+
"connection": "company-basecamp",
|
|
1610
|
+
"operation": "basecamp.project.list",
|
|
1611
|
+
"resource": "account",
|
|
1612
|
+
"input": {
|
|
1613
|
+
"projectStatus": "active"
|
|
1614
|
+
}
|
|
1615
|
+
},
|
|
1616
|
+
{
|
|
1617
|
+
"connection": "company-basecamp",
|
|
1618
|
+
"operation": "basecamp.todolist.list",
|
|
1619
|
+
"resource": "launch",
|
|
1620
|
+
"input": {}
|
|
1621
|
+
},
|
|
1622
|
+
{
|
|
1623
|
+
"connection": "company-basecamp",
|
|
1624
|
+
"operation": "basecamp.todo.list",
|
|
1625
|
+
"resource": "launch",
|
|
1626
|
+
"input": {
|
|
1627
|
+
"todolistId": "1069479520",
|
|
1628
|
+
"completed": false
|
|
1629
|
+
}
|
|
1630
|
+
},
|
|
1631
|
+
{
|
|
1632
|
+
"connection": "company-basecamp",
|
|
1633
|
+
"operation": "basecamp.todo.create",
|
|
1634
|
+
"resource": "launch",
|
|
1635
|
+
"input": {
|
|
1636
|
+
"todolistId": "1069479520",
|
|
1637
|
+
"content": "Ship the weekly report",
|
|
1638
|
+
"description": "Attach the PDF to the message board post.",
|
|
1639
|
+
"dueOn": "2026-10-17",
|
|
1640
|
+
"assigneeIds": [
|
|
1641
|
+
"1049715914"
|
|
1642
|
+
],
|
|
1643
|
+
"notify": true
|
|
1644
|
+
},
|
|
1645
|
+
"idempotencyKey": "6f1c2c1e-3a1c-4c3e-9f0e-2b6f7d8a9c16"
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
"connection": "company-basecamp",
|
|
1649
|
+
"operation": "basecamp.todo.complete",
|
|
1650
|
+
"resource": "launch",
|
|
1651
|
+
"input": {
|
|
1652
|
+
"todoId": "1069479526"
|
|
1653
|
+
}
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
"connection": "company-basecamp",
|
|
1657
|
+
"operation": "basecamp.message.list",
|
|
1658
|
+
"resource": "launch",
|
|
1659
|
+
"input": {
|
|
1660
|
+
"pageToken": "2"
|
|
1661
|
+
}
|
|
1662
|
+
},
|
|
1663
|
+
{
|
|
1664
|
+
"connection": "company-basecamp",
|
|
1665
|
+
"operation": "basecamp.message.post",
|
|
1666
|
+
"resource": "launch",
|
|
1667
|
+
"input": {
|
|
1668
|
+
"subject": "Weekly report",
|
|
1669
|
+
"content": "<p>The weekly report is <b>attached</b>.</p>",
|
|
1670
|
+
"contentFormat": "html"
|
|
1671
|
+
},
|
|
1672
|
+
"idempotencyKey": "6f1c2c1e-3a1c-4c3e-9f0e-2b6f7d8a9c17"
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
"connection": "company-basecamp",
|
|
1676
|
+
"operation": "basecamp.comment.list",
|
|
1677
|
+
"resource": "launch",
|
|
1678
|
+
"input": {
|
|
1679
|
+
"recordingId": "1069479530"
|
|
1680
|
+
}
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
"connection": "company-basecamp",
|
|
1684
|
+
"operation": "basecamp.comment.post",
|
|
1685
|
+
"resource": "launch",
|
|
1686
|
+
"input": {
|
|
1687
|
+
"recordingId": "1069479530",
|
|
1688
|
+
"content": "Shipped, thanks."
|
|
1689
|
+
},
|
|
1690
|
+
"idempotencyKey": "6f1c2c1e-3a1c-4c3e-9f0e-2b6f7d8a9c18"
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
"connection": "company-basecamp",
|
|
1694
|
+
"operation": "basecamp.campfire.post",
|
|
1695
|
+
"resource": "launch",
|
|
1696
|
+
"input": {
|
|
1697
|
+
"content": "Weekly report is up on the message board."
|
|
1698
|
+
},
|
|
1699
|
+
"idempotencyKey": "6f1c2c1e-3a1c-4c3e-9f0e-2b6f7d8a9c19"
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
"connection": "company-basecamp",
|
|
1703
|
+
"operation": "basecamp.people.list",
|
|
1704
|
+
"resource": "launch",
|
|
1705
|
+
"input": {}
|
|
1181
1706
|
}
|
|
1182
1707
|
]
|
|
1183
1708
|
}
|