@trayio/cdk-dsl 1.14.0 → 1.16.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.
Files changed (2) hide show
  1. package/README.md +239 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -38,6 +38,245 @@ A connector will have one folder per operation under the `src` folder, this fold
38
38
  - `handler.ts` which is where the logic of the operation is
39
39
  - `handler.test.ts` which contains the test cases for testing the operation's behaviour defined in the handler
40
40
 
41
+ ## Input & Output
42
+
43
+ Each operation has an `input.ts` and `output.ts` that defines the input and output parameters for the operation. It should export this as a type named `<OperationName>Input` or `<OperationName>Output`.
44
+
45
+ During the deployment of a connector these input/output types are converted to JSON schema which powers how the Tray builder UI renders the input fields. This conversion also happens locally when you run the `tray-cdk build` command should you wish to inspect the generated JSON schema.
46
+
47
+ ### Additional Input configuration
48
+
49
+ The following sections outline the number of different ways to render your input fields in Tray's builder UI by adding JSdoc annotations to the properties in your `input.ts`.
50
+
51
+ #### Data types
52
+
53
+ - string: represents string values
54
+ - number: represents a number, e.g. 42. If you want to limit an input field to a whole number you can use the JSdoc annotation `@TJS-type integer` above the number.
55
+ - boolean: is for the two values true and false
56
+ - array: represented by `[]`, e.g. number[]
57
+ - object: represented by object that contains different fields
58
+
59
+ Here is an example use of the different data types:
60
+
61
+ ```typescript
62
+ export type ExampleOperationInput = {
63
+ str: string;
64
+ num: number;
65
+ /**
66
+ * @TJS-type integer
67
+ */
68
+ int: number;
69
+ bool: boolean;
70
+ obj: object;
71
+ arr: object[];
72
+ };
73
+ ```
74
+
75
+ #### Enums (Static dropdown lists)
76
+ Enums are rendered in the Tray builder UI as dropdowns. The user will see the enum display names and the enum values are what will be passed into the handler. By default, user friendly enum display names are generated. e.g. an enum of value `my-enum-value` will be rendered in the UI with the display name `My enum value`.
77
+
78
+ ```typescript
79
+ export type ExampleOperationInput = {
80
+ type: ActionType;
81
+ };
82
+
83
+ enum ActionType {
84
+ first-option = 'first-option', // User will see an auto generated display name: First option
85
+ second-option = 'second-option', // User will see an auto generated display name: Second option
86
+ third-option = 'third-option', // User will see an auto generated display name: Third option
87
+ }
88
+ ```
89
+ You may want to provide custom enum display names instead, to do so use the JSdoc annotation `@enumLabels` followed by a comma separated list of strings that matches the order you have defined your enums in.
90
+
91
+ ```typescript
92
+ export type ExampleOperationInput = {
93
+ type: ActionType;
94
+ };
95
+
96
+ /**
97
+ * @enumLabels The First Option, The Second Option, The Third Option
98
+ */
99
+ enum ActionType {
100
+ first-option = 'first-option',
101
+ second-option = 'second-option',
102
+ third-option = 'third-option',
103
+ }
104
+ ```
105
+
106
+
107
+ #### DDL (Dynamic dropdown lists)
108
+ Sometimes you want to provide the user a dropdown list, but you don't know the items to display in the list because they come from another API. For example you may want to display a list of user names in a dropdown and based on the selection send the user ID. DDL's solve this problem. Once you have created an operation for your DDL (see more on this in the Composite Implementation section) you can use this DDL in the input of many other operations.
109
+
110
+ The JSdoc annotation `@lookupOperation` specifies what operation to invoke when the user expands the dropdown. `@lookupInput` is used to describe the JSON payload to send to that DDL operation. Any inputs defined in input.ts can be passed to the DDL operation using tripple braces. In this example we send the workspaceId field value by doing `{{{workspaceId}}}`. If your DDL operation calls an authenticated endpoint you can pass along the token used in the current operation by setting `@lookupAuthRequired true`.
111
+ ```typescript
112
+ export type ExampleOperationInput = {
113
+ workspaceId: string;
114
+ /**
115
+ * @title user
116
+ * @lookupOperation list_users_ddl
117
+ * @lookupInput {"includePrivateChannels": false,"workspaceId": "{{{workspaceId}}}"}
118
+ * @lookupAuthRequired true
119
+ */
120
+ userId: string;
121
+ };
122
+ ```
123
+
124
+ #### Reusing types across multiple operations
125
+ You can reuse types by importing them and reuse sections of a schema by using TypeScript intersections.
126
+
127
+ ```typescript
128
+ // input.ts
129
+ import { ReusableField } from './ReusableField';
130
+ import { ReusableSchema } from './ReusableSchema';
131
+
132
+ export type ExampleOperationInput = SpecificSchema & ReusableSchema;
133
+
134
+ type SpecificSchema = {
135
+ specificField: string;
136
+ reusableFields: ReusableField;
137
+ };
138
+ ```
139
+
140
+ ```typescript
141
+ // ReusableField.ts
142
+ export type ReusableField = {
143
+ reusableFieldA: number;
144
+ reusableFieldB: string;
145
+ };
146
+ ```
147
+
148
+ ```typescript
149
+ // ReusableSchema.ts
150
+ export type ReusableSchema = {
151
+ reusableSchemaA: number;
152
+ reusableSchemaB: string;
153
+ };
154
+ ```
155
+ Once the imports and intersection are resolved the above example would look like this
156
+ ```typescript
157
+ export type Input = {
158
+ specificField: string;
159
+ reusableFields: {
160
+ reusableFieldA: number;
161
+ reusableFieldB: string;
162
+ };
163
+ reusableSchemaA: number;
164
+ reusableSchemaB: string;
165
+ }
166
+ ```
167
+
168
+ #### Union types (Supporting multiple types)
169
+ If you want to support two or more different object types in your schema you can achieve this using TypeScript unions.
170
+
171
+ In the example below our input accepts an array of elements. Each element of this array can be either of type image or text. When the user adds an item to the array they will see a dropdown where they can select if this element will be an image or text. The JSdoc annotation `@title` on the image and text types will be displayed in the dropdown the user sees.
172
+
173
+ ```typescript
174
+
175
+ export type ExampleOperationInput = {
176
+ elements: ImageOrText[];
177
+ };
178
+
179
+ type ImageOrText = Image | Text;
180
+
181
+ /**
182
+ * @title Image
183
+ */
184
+ type Image = {
185
+ name: string;
186
+ src: string;
187
+ };
188
+
189
+ /**
190
+ * @title Text
191
+ */
192
+ type Text = {
193
+ text: string;
194
+ };
195
+ ```
196
+
197
+ #### Required/Optional fields
198
+ By default all input fields are mandatory, you can set any to optional with a `?` in your TypeScript type. Mandatory fields get a red * in the Tray builder UI and will warn the user that they must be filled in before attempting to run a workflow.
199
+
200
+ ```typescript
201
+ export type ExampleOperationInput = {
202
+ mandatoryField: string;
203
+ optionalField?: string;
204
+ };
205
+
206
+ ```
207
+
208
+ #### Formatting fields
209
+ By default properties on your input type render as simple input fields. You can select a more user friendly way to render the field based on your needs by using the JSdoc annotation `@format`.
210
+
211
+ The format options available are:
212
+ - datetime - renders a date and time picker
213
+ - code - renders a button which on click opens a modal with a simple code editor
214
+ - text - for longer text inputs, expands when you enter new lines
215
+
216
+ ```typescript
217
+ export type ExampleOperationInput = {
218
+ /**
219
+ * @format datetime
220
+ */
221
+ timestamp: string;
222
+ /**
223
+ * @format code
224
+ */
225
+ html: string;
226
+ /**
227
+ * @format text
228
+ */
229
+ longNotes: string;
230
+ };
231
+ ```
232
+
233
+ #### Default values
234
+ If you want to provide a default initial value for a field you can use the JSdoc annotation `@default`.
235
+ ```typescript
236
+ export type ExampleOperationInput = {
237
+ /**
238
+ * @default string default
239
+ */
240
+ str: string;
241
+ /**
242
+ * @default 0.1
243
+ */
244
+ num: number;
245
+ /**
246
+ * @TJS-type integer
247
+ * @default 1
248
+ */
249
+ int: number;
250
+ /**
251
+ * @default true
252
+ */
253
+ bool: boolean;
254
+ /**
255
+ * @default { "default": true }
256
+ */
257
+ obj: object;
258
+ /**
259
+ * @default ["default"]
260
+ */
261
+ arr: object[];
262
+ };
263
+ ```
264
+
265
+ #### Advanced fields
266
+ If you have optional fields that are for more advanced use cases you can obscure these into the Tray builder UI's advanced fields section. This can provide a cleaner interface for your operation, but can still be accessed by the user by expanding the advanced fields section. You can add fields here by using the JSdoc annotation `@advanced true`.
267
+
268
+ ```typescript
269
+ export type ExampleOperationInput = {
270
+ normalField: string;
271
+ /**
272
+ * @advanced true
273
+ */
274
+ advancedField?: string;
275
+ };
276
+ ```
277
+
278
+
279
+
41
280
  ## Handler
42
281
 
43
282
  A handler at its core, describes a function, that takes an `ctx` value with an `auth` property described by the authentication type (which is the same for all operations) and it takes an `input` value described by the input type of the operation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trayio/cdk-dsl",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "A DSL for connector development",
5
5
  "exports": {
6
6
  "./*": "./dist/*.js"
@@ -14,7 +14,7 @@
14
14
  "access": "public"
15
15
  },
16
16
  "dependencies": {
17
- "@trayio/commons": "1.14.0"
17
+ "@trayio/commons": "1.16.0"
18
18
  },
19
19
  "typesVersions": {
20
20
  "*": {