@enfocussw/switch-scripting-context 25.11.0-beta.8
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 +68 -0
- package/README.md +163 -0
- package/bin/cli.js +8 -0
- package/dist/init.d.ts +19 -0
- package/dist/init.js +616 -0
- package/docs/switch-api/api-connection.md +63 -0
- package/docs/switch-api/api-debugging.md +51 -0
- package/docs/switch-api/api-document-classes.md +167 -0
- package/docs/switch-api/api-entry-points.md +82 -0
- package/docs/switch-api/api-enums.md +153 -0
- package/docs/switch-api/api-execution-environment.md +70 -0
- package/docs/switch-api/api-flow-element.md +112 -0
- package/docs/switch-api/api-http.md +87 -0
- package/docs/switch-api/api-job-patterns.md +79 -0
- package/docs/switch-api/api-job.md +156 -0
- package/docs/switch-api/api-logging.md +53 -0
- package/docs/switch-api/api-logs-and-dataroot.md +71 -0
- package/docs/switch-api/api-property-editors.md +144 -0
- package/docs/switch-api/api-script-declaration.md +351 -0
- package/docs/switch-api/api-script-structure.md +85 -0
- package/docs/switch-api/api-switch.md +75 -0
- package/docs/switch-api/api-tooling.md +61 -0
- package/docs/switch-api/api-vscode.md +62 -0
- package/docs/switch-scripting.md +40 -0
- package/package.json +60 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Script Declaration (XML)
|
|
2
|
+
|
|
3
|
+
The file `<ScriptID>.xml` defines the script's metadata, custom properties, connection properties,
|
|
4
|
+
and execution configuration. It is normally written by **SwitchScripter**, but the format is fully
|
|
5
|
+
documented below — you can edit it directly.
|
|
6
|
+
|
|
7
|
+
## Agent editing policy
|
|
8
|
+
|
|
9
|
+
- Editing this file directly is safe as long as you follow the rules on this page exactly — the
|
|
10
|
+
format has no schema, so Switch will silently misbehave (not error) on a malformed attribute.
|
|
11
|
+
- Preserve every attribute you don't intend to change. Don't reformat, reorder attributes, or drop
|
|
12
|
+
fields you don't understand.
|
|
13
|
+
- `Name` is the script's stable ID — never change it on an existing script (it's used as the flow
|
|
14
|
+
element type and referenced by installed flows). `DisplayName`, tooltips, defaults, adding/removing
|
|
15
|
+
custom properties, and connection topology are all safe to change directly.
|
|
16
|
+
- After editing, `Version` should be bumped (integer, no leading zeros necessary beyond `1`) so
|
|
17
|
+
Switch treats it as an update.
|
|
18
|
+
- Custom property tag names must match `^[A-Za-z][A-Za-z0-9]*$`, must not start with `xml`
|
|
19
|
+
(case-insensitive), and must not collide with a [reserved tag](#reserved-tag-names) below. Switch
|
|
20
|
+
does **not** sanitize or rewrite bad tag names on load — it just fails to work correctly.
|
|
21
|
+
- `manifest.xml` (declares the package's program file(s) and type) rarely needs edits; treat it as
|
|
22
|
+
low-risk to read but confirm with the user before changing `ScriptPackageType`,
|
|
23
|
+
`ScriptDeclarationFile`, or `ScriptProgramFiles`.
|
|
24
|
+
- Never add or edit `ApplicationPath` or `ApplicationLicense` — these are app-only properties that
|
|
25
|
+
point Switch at a third-party application's install location and license. They must be set by the
|
|
26
|
+
user from the Switch Scripter GUI after the script package has been packed; Switch silently drops
|
|
27
|
+
them if written into the declaration file directly.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## XML structure overview
|
|
32
|
+
|
|
33
|
+
```xml
|
|
34
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
35
|
+
<Object>
|
|
36
|
+
<ElementFields> <!-- required: built-in fields + custom property elements -->
|
|
37
|
+
<ConnectionFields> <!-- optional: custom outgoing-connection property elements -->
|
|
38
|
+
<ExtraProperties> <!-- optional: OAuth 2.0 editor config only -->
|
|
39
|
+
</Object>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`ElementFields` is required — Switch rejects the whole declaration without it. `ConnectionFields`
|
|
43
|
+
and `ExtraProperties` may be omitted or left empty.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Built-in ElementFields
|
|
48
|
+
|
|
49
|
+
These configure the flow element (name, topology, execution, pane placement, docs). All carry
|
|
50
|
+
`Editor="hide"` and are never shown to the user directly. Add `Type="..."` to a field only when the
|
|
51
|
+
value is non-string (see the table); an empty string field can omit `Type`.
|
|
52
|
+
|
|
53
|
+
| Element | Values | Notes |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `Name` | string | Stable script ID — **never change on an existing script**. Becomes the flow element `Type`. |
|
|
56
|
+
| `DisplayName` | string | Shown in Switch. Empty falls back to `Name`. A `~` splits "Vendor~Element" — Switch shows the part after `~` as the short name and the whole string (space-joined) as the full name. |
|
|
57
|
+
| `Version` | number | Format `[1-9][0-9]*(\.(0\|[1-9][0-9]*))*`, e.g. `1`, `2.1`. Bump on every declaration change. |
|
|
58
|
+
| `Keywords` | string | Space/comma/semicolon-separated. Elements pane search. |
|
|
59
|
+
| `Tooltip` | string | Elements pane tooltip. |
|
|
60
|
+
| `IncomingConnections` | `Yes` \| `No` | Add `RequireAtLeastOne="Yes"` when `Yes`. |
|
|
61
|
+
| `OutgoingConnections` | `No` \| `One` \| `Unlimited` | Add `RequireAtLeastOne="Yes"` when `One`/`Unlimited`. Always carries `DetailedInfo=""` (or a prose description of the connections, for generated docs). |
|
|
62
|
+
| `ConnectionType` | `Move` \| `Filter` \| `TrafficLight` | Governs which `ConnectionFields` children are legal — see [ConnectionFields](#connectionfields). |
|
|
63
|
+
| `FunctionsNodeJSScript` | `;`-separated names | Entry point function names found in the script. Omit the element entirely if there is no Node.js program. |
|
|
64
|
+
| `ExecutionMode` | `Concurrent` \| `Serialized` | |
|
|
65
|
+
| `NumberOfSlots` | `Default` \| integer | Only meaningful when `Concurrent`. |
|
|
66
|
+
| `ExecutionGroup` | string | Only meaningful when `Serialized`. Empty falls back to `Name`. |
|
|
67
|
+
| `PerformanceTuning` | `Yes` \| `No` | When `Yes`, `IdleAfterJob` (and `NumberOfSlots` if concurrent) become visible/editable in Switch. |
|
|
68
|
+
| `IdleAfterJob` | number (seconds) | |
|
|
69
|
+
| `PositionInElementPane` | `Basics` \| `Tools` \| `Communication` \| `Apps` \| `Configurators` \| `Metadata` \| `Database` | Which section of the Elements pane the script appears under. |
|
|
70
|
+
| `SubcategoryInElementPane` | escaped XML, see [§ escaped payloads](#escaped-valuedescription-payloads) | Apps/Configurators only. |
|
|
71
|
+
| `DispositionInElementPane` | numeric string or empty | Sort position within the category. Empty = alphabetical. |
|
|
72
|
+
| `Description` | string | Long description. |
|
|
73
|
+
| `Compatibility` | string | Configurator only: third-party app compatibility notes. |
|
|
74
|
+
| `SupportInfo` | string | Configurator only: support email/URL. |
|
|
75
|
+
| `AppDiscovery` | string | Configurator only: how the app is located on disk. |
|
|
76
|
+
| `FlowUpgradeWarning` | string | Warning shown during flow upgrade. |
|
|
77
|
+
| `UpgradeMaximumVersion` | number | Previous version up to which the upgrade warning is shown. Optional. |
|
|
78
|
+
| `Connections` | string | Prose description of outgoing connections, for generated docs. |
|
|
79
|
+
| `SwitchModule` | `Configurator` \| `Metadata` \| `Scripting` \| `Database` \| `SwitchClient` \| `SwitchClientSDK` | Licensing module. |
|
|
80
|
+
| `ObsoleteProperties` | `;`/`,`/whitespace-separated tag names | Suppresses "unknown property" warnings when a flow already has properties you removed. Add old tag names here when removing a custom property. |
|
|
81
|
+
| `ObsoleteConnectionProperties` | same | Same, for removed connection properties. |
|
|
82
|
+
|
|
83
|
+
Do **not** add `ApplicationPath` or `ApplicationLicense` as element names — Switch silently drops
|
|
84
|
+
them. These app-only properties must be configured by the user from the Switch Scripter GUI after
|
|
85
|
+
the package is packed, not written into the declaration file.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Custom property elements (ElementFields)
|
|
90
|
+
|
|
91
|
+
Each user-defined property is a child element of `<ElementFields>` with `UserDefined="true"`. The
|
|
92
|
+
element name is the property's **tag** (used as the `tag` argument in `getPropertyStringValue()`)
|
|
93
|
+
and must follow the [tag name rules](#reserved-tag-names).
|
|
94
|
+
|
|
95
|
+
The element must **never be self-closing**. Its text content holds the property's *current value*
|
|
96
|
+
— e.g. `<Count ...>8</Count>`, not `<Count ... Default="8" />`. A self-closing custom property is
|
|
97
|
+
non-editable in Switch Designer.
|
|
98
|
+
|
|
99
|
+
```xml
|
|
100
|
+
<MyProperty UserDefined="true" Type="string" Editor="choosefolder" LocalizedTagName="My Property"
|
|
101
|
+
Tooltip="Select the output folder" DetailedInfo="" Validation="Standard" Default=""
|
|
102
|
+
Subtype="">Default value goes here</MyProperty>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Key attributes:
|
|
106
|
+
|
|
107
|
+
| Attribute | Description |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `UserDefined` | Always `"true"` for custom properties. |
|
|
110
|
+
| `Type` | Value type discriminator — see [Type reference](#type-reference). |
|
|
111
|
+
| `Editor` | `;`-joined chain of editor tokens (inline editor first, then modal editors) — see [api-property-editors.md](api-property-editors.md). |
|
|
112
|
+
| `Subtype` | Which editor in the `Editor` chain is currently active for the stored value. For a single-editor property this equals that editor's token (e.g. `"inline"`); for a bare modal editor with no inline component, leave it `""`. This attribute is read by Switch's validator at runtime, not just bookkeeping — keep it consistent with `Editor`. |
|
|
113
|
+
| `LocalizedTagName` | Display name shown in the Properties pane. |
|
|
114
|
+
| `Tooltip` | Tooltip shown in the Properties pane. |
|
|
115
|
+
| `DetailedInfo` | Long-form description for generated docs. Always include the attribute (empty string `""` is fine) — omitting it makes the property non-editable in Switch Designer. |
|
|
116
|
+
| `Validation` | `None` (skip validation) \| `Standard` (built-in validator) \| `Custom` (needs an `isPropertyValid` entry point) \| `Standard and custom` (both, custom only runs if standard passes). |
|
|
117
|
+
| `Default` | Default value string. Omit only if the value is emitted as CDATA instead. |
|
|
118
|
+
| `Dependency` | Tag of the master property this one depends on. Written flat (not nested) — the dependent element is a sibling of its master, not a child. |
|
|
119
|
+
| `DependencyCondition` | One of: `Not-empty`, `Equals`, `Not-equals`, `Contains`, `Does not contain`, `Matches`, `Does not match`, `Starts with`, `Does not start with`. |
|
|
120
|
+
| `Dependencyvalue` | Value(s) to compare against — `;`-separated for multiple. Note the lowercase `v`. |
|
|
121
|
+
|
|
122
|
+
**Dependency example** — show `OutputFolder` only when `Mode` equals `"Custom"`:
|
|
123
|
+
|
|
124
|
+
```xml
|
|
125
|
+
<Mode UserDefined="true" Type="enum:Default;Custom" Editor="inline" Subtype="inline"
|
|
126
|
+
LocalizedTagName="Mode" Tooltip="" DetailedInfo="" Validation="Standard"
|
|
127
|
+
Default="Default">Default</Mode>
|
|
128
|
+
<OutputFolder UserDefined="true" Type="string" Editor="choosefolder" Subtype=""
|
|
129
|
+
Dependency="Mode" DependencyCondition="Equals" Dependencyvalue="Custom"
|
|
130
|
+
LocalizedTagName="Output folder" Tooltip="" DetailedInfo=""
|
|
131
|
+
Validation="Standard" Default=""></OutputFolder>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Attribute order in the file doesn't matter functionally — SwitchScripter's own output happens to be
|
|
135
|
+
alphabetical (QDom sorts attributes on write), but any order parses correctly.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## ConnectionFields
|
|
140
|
+
|
|
141
|
+
Custom outgoing-connection properties follow the same attribute pattern as element properties, with
|
|
142
|
+
one addition: `AvailableFor="Data"` or `AvailableFor="Log"` restricts which connection kind shows the
|
|
143
|
+
property; omit the attribute for both.
|
|
144
|
+
|
|
145
|
+
```xml
|
|
146
|
+
<ConnectionFields>
|
|
147
|
+
<TargetFolder AvailableFor="Data" UserDefined="true" Type="string" Editor="choosefolder"
|
|
148
|
+
Subtype="" LocalizedTagName="Target folder" Tooltip="" DetailedInfo=""
|
|
149
|
+
Validation="Standard" Default=""></TargetFolder>
|
|
150
|
+
</ConnectionFields>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Connection property values are read at runtime via `connection.getPropertyStringValue(tag)`.
|
|
154
|
+
|
|
155
|
+
**`ConnectionType` gates which built-in connection fields may appear here** — this is the single
|
|
156
|
+
most important thing to get right when hand-editing this section:
|
|
157
|
+
|
|
158
|
+
| `ConnectionType` | Legal built-in children |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `Move` | none — `<ConnectionFields/>` must be empty of built-ins |
|
|
161
|
+
| `Filter` | `IncludeFolderMask`, `ExcludeFolderMask` (both or neither) |
|
|
162
|
+
| `TrafficLight` | `Success`, `Warning`, `Error`, each optionally with `AvailableFor="Data"` or `AvailableFor="Log"` (omit the attribute if available for both; omit the whole element if available for neither) |
|
|
163
|
+
|
|
164
|
+
```xml
|
|
165
|
+
<!-- ConnectionType = TrafficLight -->
|
|
166
|
+
<ConnectionFields>
|
|
167
|
+
<Success AvailableFor="Data" LocalizedTagName="Success out" Type="bool" Editor="inline" Default="Yes">Yes</Success>
|
|
168
|
+
<Error AvailableFor="Data" LocalizedTagName="Error out" Type="bool" Editor="inline" Default="Yes">Yes</Error>
|
|
169
|
+
<!-- no Warning element: not available for Data or Log -->
|
|
170
|
+
</ConnectionFields>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Custom (author-defined) connection properties may be added regardless of `ConnectionType`.
|
|
174
|
+
|
|
175
|
+
**Caution — package-swap connection preservation:** Switch Designer decides whether existing flow
|
|
176
|
+
connections survive a script package replace by comparing the serialised `ConnectionFields` and
|
|
177
|
+
`IncomingConnections` text **byte-for-byte** between old and new declarations, and additionally
|
|
178
|
+
checks whether `ConnectionType`/`OutgoingConnections` changed. Don't make cosmetic whitespace or
|
|
179
|
+
attribute-order changes to those sections without expecting existing flows' outgoing connection
|
|
180
|
+
properties to reset on next package update.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## ExtraProperties
|
|
185
|
+
|
|
186
|
+
Only used for OAuth 2.0 (`Editor` containing `oauth`, see
|
|
187
|
+
[api-property-editors.md](api-property-editors.md)). One child element per OAuth property, named
|
|
188
|
+
identically to the property's tag, in `ElementFields` or `ConnectionFields`:
|
|
189
|
+
|
|
190
|
+
```xml
|
|
191
|
+
<ElementFields>
|
|
192
|
+
<OAuth1 UserDefined="true" Type="string" Editor="oauth" Subtype="" LocalizedTagName="OAuth1"
|
|
193
|
+
Tooltip="" DetailedInfo="" Validation="Standard" Default=""></OAuth1>
|
|
194
|
+
</ElementFields>
|
|
195
|
+
<ExtraProperties>
|
|
196
|
+
<OAuth1 OAuthAuthorizationEndpoint="http://auth-url"
|
|
197
|
+
OAuthClientID="AppID1"
|
|
198
|
+
OAuthClientSecret="Application Password 123"
|
|
199
|
+
OAuthClientSecretEditor="inline"
|
|
200
|
+
OAuthRedirPorts="666"
|
|
201
|
+
OAuthRedirPortsEditor="inline"
|
|
202
|
+
OAuthScope="some-random-scope"
|
|
203
|
+
OAuthScopeEditor="inline"
|
|
204
|
+
OAuthTokenEndpoint="http://token-url"/>
|
|
205
|
+
</ExtraProperties>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Attributes: `OAuthAuthorizationEndpoint`, `OAuthClientID`, `OAuthClientSecret`, `OAuthRedirPorts`,
|
|
209
|
+
`OAuthTokenEndpoint`, `OAuthScope`. A companion `<Attr>Editor` attribute is only needed when that
|
|
210
|
+
attribute has more than one valid input mode; otherwise omit it. If the package is
|
|
211
|
+
password-protected, `OAuthClientSecret` must be stored encrypted — leave OAuth secret edits to the
|
|
212
|
+
user rather than writing a plaintext secret into a password-protected package.
|
|
213
|
+
|
|
214
|
+
If no OAuth property exists on the script, omit `ExtraProperties` entirely or leave it empty
|
|
215
|
+
(`<ExtraProperties/>`).
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Type reference
|
|
220
|
+
|
|
221
|
+
`Type` is a single token, except for enums:
|
|
222
|
+
|
|
223
|
+
| Token | Meaning |
|
|
224
|
+
|---|---|
|
|
225
|
+
| `string` | Text |
|
|
226
|
+
| `number` | Integer |
|
|
227
|
+
| `rational` | Decimal |
|
|
228
|
+
| `password` | Masked text |
|
|
229
|
+
| `bool` | `Yes`/`No` |
|
|
230
|
+
| `date`, `datetime`, `time` | `time` is hours-and-minutes |
|
|
231
|
+
| `path` | Filesystem path |
|
|
232
|
+
| `enum:A;B;C` | Closed choice list, `;`-separated (a trailing `;` is tolerated) |
|
|
233
|
+
| `filefilter`, `folderfilter` | File / folder filter values |
|
|
234
|
+
| `stringlist` | List of strings |
|
|
235
|
+
| `accountlist` | Account list |
|
|
236
|
+
|
|
237
|
+
This is the *authoring* vocabulary written into the XML `Type` attribute. It does not map one-to-one
|
|
238
|
+
onto the runtime `PropertyType` returned by `getPropertyType()` (see
|
|
239
|
+
[api-property-editors.md](api-property-editors.md) and [api-enums.md](api-enums.md)) — e.g. XML
|
|
240
|
+
`bool` becomes runtime `boolean`, XML `path` splits into runtime `filepath`/`folderpath`, and several
|
|
241
|
+
XML types (`rational`, `stringlist`, `accountlist`, `enum:...`, `datetime`, `time`) have no direct
|
|
242
|
+
`PropertyType` counterpart while several runtime values (`filetype`, `folderpattern`, `regex`,
|
|
243
|
+
`oauthtoken`, `literal`) have no direct XML `Type` counterpart. Don't assume the two vocabularies are
|
|
244
|
+
interchangeable.
|
|
245
|
+
|
|
246
|
+
`Type` is not independently authored on properties with a modal editor chain — it follows from
|
|
247
|
+
which editor(s) you choose, per [api-property-editors.md](api-property-editors.md). When combining
|
|
248
|
+
an inline editor with modal editors (e.g. `Editor="inline;sltextwithvar;scriptexp"`), the inline
|
|
249
|
+
editor's type wins: an inline Number editor plus those modal editors still yields `Type="number"`.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Escaped `ValueDescription` payloads
|
|
254
|
+
|
|
255
|
+
`SubcategoryInElementPane` (and a couple of internal-only fields) store a nested XML fragment,
|
|
256
|
+
escaped into the text node:
|
|
257
|
+
|
|
258
|
+
```xml
|
|
259
|
+
<SubcategoryInElementPane Editor="hide"><ValueDescription Type="stringlist">
|
|
260
|
+
<Value>Communication</Value>
|
|
261
|
+
</ValueDescription>
|
|
262
|
+
</SubcategoryInElementPane>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Decodes to:
|
|
266
|
+
|
|
267
|
+
```xml
|
|
268
|
+
<ValueDescription Type="stringlist">
|
|
269
|
+
<Value>Communication</Value>
|
|
270
|
+
</ValueDescription>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
One `Value` child per subcategory string. Escaping only `<` (not also `"`) is fine — both forms
|
|
274
|
+
parse.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Reserved tag names
|
|
279
|
+
|
|
280
|
+
A custom property or connection property tag must not collide with any built-in field name. Do not
|
|
281
|
+
use any of:
|
|
282
|
+
|
|
283
|
+
- Any [built-in `ElementFields` name](#built-in-elementfields) above.
|
|
284
|
+
- Any built-in `ConnectionFields` name: `IncludeFolderMask`, `ExcludeFolderMask`, `Success`,
|
|
285
|
+
`Warning`, `Error`.
|
|
286
|
+
- `Type`, `Category`, `ElementDescription`, `LogDebugMessages`, `SPSDebugMode`, `SPSDebugPort`,
|
|
287
|
+
`SPSDebugEntryPoints`, `AbortTimeoutMinutes`, `ScriptPackagePath`, `Xpos`, `Ypos`, `ElementIcon`,
|
|
288
|
+
`LastModified`, `Path`, `customExecutionMode`, `AdvancedTuningEnabled`, `Hold`, `TrafficType`,
|
|
289
|
+
`CorneringFactor`, `ElementType`.
|
|
290
|
+
- `ApplicationPath`, `ApplicationLicense` (legal as a tag, but Switch silently drops these two from
|
|
291
|
+
the flow element's property set, so don't use them). These are app-only properties, set by the
|
|
292
|
+
user from the Switch Scripter GUI after packing — never modify them directly.
|
|
293
|
+
|
|
294
|
+
Also required: tag matches `^[A-Za-z][A-Za-z0-9]*$` and does not start with `xml` (case-insensitive).
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Annotated example
|
|
299
|
+
|
|
300
|
+
Representative declaration with Move connections, custom properties, and a dependency chain:
|
|
301
|
+
|
|
302
|
+
```xml
|
|
303
|
+
<Object>
|
|
304
|
+
<ElementFields>
|
|
305
|
+
<Name Editor="hide" Type="string">depositJob</Name>
|
|
306
|
+
<DisplayName Editor="hide" Type="string"></DisplayName>
|
|
307
|
+
<Version Editor="hide" Type="number">1</Version>
|
|
308
|
+
<Keywords Editor="hide" Type="string"></Keywords>
|
|
309
|
+
<Tooltip Editor="hide" Type="string"></Tooltip>
|
|
310
|
+
<IncomingConnections RequireAtLeastOne="Yes" Editor="hide">Yes</IncomingConnections>
|
|
311
|
+
<OutgoingConnections RequireAtLeastOne="Yes" DetailedInfo="" Editor="hide">Unlimited</OutgoingConnections>
|
|
312
|
+
<ConnectionType Editor="hide">Move</ConnectionType>
|
|
313
|
+
<FunctionsNodeJSScript Editor="hide">jobArrived</FunctionsNodeJSScript>
|
|
314
|
+
<ExecutionMode Editor="hide">Concurrent</ExecutionMode>
|
|
315
|
+
<NumberOfSlots Editor="hide">Default</NumberOfSlots>
|
|
316
|
+
<ExecutionGroup Editor="hide"></ExecutionGroup>
|
|
317
|
+
<PerformanceTuning Editor="hide">No</PerformanceTuning>
|
|
318
|
+
<IdleAfterJob Editor="hide" Type="number">0</IdleAfterJob>
|
|
319
|
+
<PositionInElementPane Editor="hide">Tools</PositionInElementPane>
|
|
320
|
+
<DispositionInElementPane Editor="hide" Type="number"></DispositionInElementPane>
|
|
321
|
+
<Description Editor="hide" Type="string"></Description>
|
|
322
|
+
<Connections Editor="hide" Type="string"></Connections>
|
|
323
|
+
<SwitchModule Editor="hide" Type="string">Scripting</SwitchModule>
|
|
324
|
+
<ObsoleteProperties Editor="hide" Type="string"></ObsoleteProperties>
|
|
325
|
+
<ObsoleteConnectionProperties Editor="hide" Type="string"></ObsoleteConnectionProperties>
|
|
326
|
+
|
|
327
|
+
<!-- Custom property: folder chooser -->
|
|
328
|
+
<DepositFolder UserDefined="true" Type="string" Editor="choosefolder" Subtype=""
|
|
329
|
+
LocalizedTagName="Deposit folder" Tooltip="" DetailedInfo=""
|
|
330
|
+
Validation="Standard" Default=""></DepositFolder>
|
|
331
|
+
|
|
332
|
+
<!-- Custom property: dropdown enum -->
|
|
333
|
+
<AttachAs UserDefined="true" Type="enum:Job;Dataset" Editor="inline" Subtype="inline"
|
|
334
|
+
LocalizedTagName="Attach as" Tooltip="" DetailedInfo="" Validation="Standard"
|
|
335
|
+
Default="Job">Job</AttachAs>
|
|
336
|
+
|
|
337
|
+
<!-- Custom property: bool, depends on AttachAs = "Dataset" -->
|
|
338
|
+
<IncludeMetadata UserDefined="true" Type="bool" Editor="inline" Subtype="inline"
|
|
339
|
+
Dependency="AttachAs" DependencyCondition="Equals" Dependencyvalue="Dataset"
|
|
340
|
+
LocalizedTagName="Include metadata" Tooltip="" DetailedInfo=""
|
|
341
|
+
Validation="Standard" Default="No">No</IncludeMetadata>
|
|
342
|
+
|
|
343
|
+
<!-- Custom property: literal "Default" editor combined with a modal editor -->
|
|
344
|
+
<FallbackFolder UserDefined="true" Type="string" Editor="default;choosefolder" Subtype=""
|
|
345
|
+
LocalizedTagName="Fallback folder" Tooltip="" DetailedInfo=""
|
|
346
|
+
Validation="Standard" Default="Default">Default</FallbackFolder>
|
|
347
|
+
</ElementFields>
|
|
348
|
+
<ConnectionFields/>
|
|
349
|
+
<ExtraProperties/>
|
|
350
|
+
</Object>
|
|
351
|
+
```
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Script Project Structure
|
|
2
|
+
|
|
3
|
+
A Switch script project lives in a **script folder** during development and is distributed as a `.sscript` package (ZIP).
|
|
4
|
+
|
|
5
|
+
> **Agent editing policy**: Edit TypeScript/JavaScript source files (`main.ts`, `main.js`) and the XML declaration (`<ScriptID>.xml`) freely — see [api-script-declaration.md](api-script-declaration.md) for the declaration's rules. Leave `manifest.xml` to the user unless explicitly asked.
|
|
6
|
+
|
|
7
|
+
## Script folder files
|
|
8
|
+
|
|
9
|
+
| File | Required | Notes |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `manifest.xml` | Yes | Switch internal use only. Do not edit manually. |
|
|
12
|
+
| `<ScriptID>.xml` | Yes | Script declaration (properties, connections, execution config). See [api-script-declaration.md](api-script-declaration.md). |
|
|
13
|
+
| `main.ts` | Yes (TypeScript) | Source file. Edit this. |
|
|
14
|
+
| `main.js` | Yes | Compiled output executed by Switch. Generated by transpiling `main.ts`. |
|
|
15
|
+
| `main.js.map` | No | Source map, generated alongside `main.js`. |
|
|
16
|
+
| `package.json` | Yes (TypeScript) | NPM config for type declarations. |
|
|
17
|
+
| `tsconfig.json` | Yes (TypeScript) | TypeScript transpilation options. |
|
|
18
|
+
| `<IconFileName>.png` | No | 32×32 px, RGB, not interlaced. Extension must be `.png`. |
|
|
19
|
+
| `node_modules/` | No | Local npm packages. |
|
|
20
|
+
| `Resources/` | No | Extra resource files bundled when packing with SwitchScriptTool. |
|
|
21
|
+
| `<LanguageCode>.ts` | No | Translation files (Switch App SDK). |
|
|
22
|
+
| `.vscode/launch.json` | No | Debug config (created by SwitchScriptTool). |
|
|
23
|
+
| `.vscode/switch.code-snippets` | No | Entry point snippets (TypeScript only). |
|
|
24
|
+
|
|
25
|
+
> After editing `main.ts`, transpile with SwitchScriptTool to regenerate `main.js` before testing in Switch.
|
|
26
|
+
|
|
27
|
+
## manifest.xml format
|
|
28
|
+
|
|
29
|
+
```xml
|
|
30
|
+
<Manifest>
|
|
31
|
+
<ScripterInstanceName>myScript</ScripterInstanceName>
|
|
32
|
+
<SwitchVersion>24.0</SwitchVersion>
|
|
33
|
+
<ScriptPackageFormatVersion>1.0</ScriptPackageFormatVersion>
|
|
34
|
+
<ScriptPasswordProtected>No</ScriptPasswordProtected>
|
|
35
|
+
<ScriptPackageType>Script</ScriptPackageType>
|
|
36
|
+
<ScriptDeclarationFile>myScript.xml</ScriptDeclarationFile>
|
|
37
|
+
<ScriptProgramFiles>
|
|
38
|
+
<ScriptProgramFile ScriptLanguage="NodeJSScript">main.ts</ScriptProgramFile>
|
|
39
|
+
</ScriptProgramFiles>
|
|
40
|
+
<ScriptIconFile>myScript_32.png</ScriptIconFile>
|
|
41
|
+
<LocalizationItems/>
|
|
42
|
+
</Manifest>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`ScriptPackageType` is either `Script` (regular) or `App` (scripted plug-in).
|
|
46
|
+
|
|
47
|
+
## Node.js version per Switch version
|
|
48
|
+
|
|
49
|
+
`SwitchVersion` in `manifest.xml` determines which Node.js version executes the script — Switch uses the **latest** Node.js version bundled with the Switch release that created the script.
|
|
50
|
+
|
|
51
|
+
| Switch version | `SwitchVersion` | Node.js used |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Switch 2020 Spring | `20.0` | 12 |
|
|
54
|
+
| Switch 2020 Fall | `20.1` | 12 |
|
|
55
|
+
| Switch 2021 Spring | `21.0` | 14 |
|
|
56
|
+
| Switch 2021 Fall | `21.1` | 16 |
|
|
57
|
+
| Switch 2022 Spring | `22.0` | 16 |
|
|
58
|
+
| Switch 2022 Fall | `22.1` | 16 |
|
|
59
|
+
| Switch 2023 Fall | `23.1` | 18 |
|
|
60
|
+
| Switch 2024 Spring | `24.0` | 18 |
|
|
61
|
+
| Switch 2024 Fall | `24.1` | 20 |
|
|
62
|
+
| Switch 25.11 | `25.11` | 20 |
|
|
63
|
+
|
|
64
|
+
> **Mac (Apple Silicon):** For scripts created in Switch 2021 Fall or later, Switch runs the native ARM build of Node.js on Apple Silicon. Scripts created in earlier versions run under Rosetta using the Intel Node.js build. If a script bundles platform-specific binaries, ship both Intel and ARM variants.
|
|
65
|
+
|
|
66
|
+
## Script vs App
|
|
67
|
+
|
|
68
|
+
| | Script | App |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `ScriptPackageType` | `Script` | `App` |
|
|
71
|
+
| Appears in Elements pane | No (used via Script element) | Yes, as its own element |
|
|
72
|
+
| Distribution | Freely | Enfocus Appstore only |
|
|
73
|
+
| Position in pane | — | Configured via `PositionInElementPane` in XML |
|
|
74
|
+
|
|
75
|
+
## Execution modes
|
|
76
|
+
|
|
77
|
+
Set in the XML declaration via SwitchScripter. Applies to all instances of the script.
|
|
78
|
+
|
|
79
|
+
**Concurrent** — entry points for the same or different instances may run in parallel. Scripts must synchronize access to any shared resources.
|
|
80
|
+
|
|
81
|
+
**Serialized** — entry points within the same **execution group** are never concurrent. Instances in different execution groups may still run in parallel.
|
|
82
|
+
|
|
83
|
+
**Execution group** — only relevant for Serialized mode. Should be a reverse-domain string (e.g. `com.mycompany.myScript`) to avoid collisions. Defaults to the Script ID if left empty.
|
|
84
|
+
|
|
85
|
+
See [api-execution-environment.md](api-execution-environment.md#two-independent-concurrency-tiers) — neither `NumberOfSlots` nor execution group maps to a count of Node.js OS processes; they gate job dispatch on the Switch Server, separate from the pooled executor processes that actually run script code.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Switch Class
|
|
2
|
+
|
|
3
|
+
The `Switch` instance `s` is passed to every entry point. It provides global data storage, webhook subscription, abort handling, and server utilities.
|
|
4
|
+
|
|
5
|
+
## Global data
|
|
6
|
+
|
|
7
|
+
Global data is key/value storage shared across entry point invocations, scoped by `Scope`.
|
|
8
|
+
|
|
9
|
+
| Scope | Shared across |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `Scope.FlowElement` | This script element instance only |
|
|
12
|
+
| `Scope.FlowElements` | All instances of the same script in the same flow |
|
|
13
|
+
| `Scope.Element` | All instances of the same script across all flows |
|
|
14
|
+
| `Scope.Flow` | All elements in the same flow |
|
|
15
|
+
| `Scope.Global` | Any element in any flow — use sparingly; prefix tags with your company name |
|
|
16
|
+
|
|
17
|
+
Dates stored via `setGlobalData` are returned as strings by `getGlobalData` — parse them in your script.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
s.getGlobalData(scope: Scope, tag: string, lock?: boolean): Promise<any>
|
|
21
|
+
s.getGlobalData(scope: Scope, tags: string[], lock?: boolean): Promise<{ tag: string, value: any }[]>
|
|
22
|
+
```
|
|
23
|
+
Read one or multiple values. Returns `''` (empty string) for a tag that doesn't exist, not `undefined`. Optional `lock` (default `false`) prevents concurrent writes until `setGlobalData` is called or the entry point ends.
|
|
24
|
+
|
|
25
|
+
More than 100 global data calls (`getGlobalData`/`setGlobalData` combined) in a single entry point invocation logs a warning — this is an advisory client-side counter, not an enforced server-side limit, but a sign the script should batch reads/writes.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
s.setGlobalData(scope: Scope, tag: string, value: any): Promise<void>
|
|
29
|
+
s.setGlobalData(scope: Scope, globalData: { tag: string, value: any }[]): Promise<void>
|
|
30
|
+
```
|
|
31
|
+
Write one or multiple values. Releases any lock held for the same scope/tag.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
s.removeGlobalData(scope: Scope, tag: string): Promise<void>
|
|
35
|
+
s.removeGlobalData(scope: Scope, tags: string[]): Promise<void>
|
|
36
|
+
```
|
|
37
|
+
Delete one or multiple global data entries.
|
|
38
|
+
|
|
39
|
+
> **Global data is never removed automatically.** Entries persist in Switch's database until explicitly deleted with `removeGlobalData`. Scripts that skip cleanup accumulate entries indefinitely and can fill the database. Always remove global data as soon as it is no longer needed.
|
|
40
|
+
|
|
41
|
+
## Webhooks
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
s.httpRequestSubscribe(method: HttpRequest.Method, path: string, args: any[]): Promise<void>
|
|
45
|
+
```
|
|
46
|
+
Subscribe to incoming HTTP requests. Call inside `flowStartTriggered`. The absolute URL is `https://<host>:51088/scripting/${path}`. `path` must start with `/` (e.g. `/my-path`) or the call throws `"Wrong format of the subscription path."`. The `args` array is forwarded to the `httpRequestTriggeredSync` / `httpRequestTriggeredAsync` entry points.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
s.httpRequestUnsubscribe(method: HttpRequest.Method, path: string): Promise<void>
|
|
50
|
+
```
|
|
51
|
+
Unsubscribe a previously registered webhook.
|
|
52
|
+
|
|
53
|
+
## Abort
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
s.setAbortData(abortData: any): void
|
|
57
|
+
```
|
|
58
|
+
Store a value that will be passed to the `abort` entry point when the configured abort timeout expires.
|
|
59
|
+
|
|
60
|
+
## Server utilities
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
s.getPreferenceSetting(settingKey: string): Promise<any>
|
|
64
|
+
```
|
|
65
|
+
Retrieve a Switch preference setting. `settingKey` format: `"settingGroup"` or `"settingGroup/settingName"`. Returns `''` if the setting/group doesn't exist. Any field whose name contains `password`, `pwd`, or `secret` is redacted in the result. The returned value is JSON-stringified, not a raw object.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
s.getServerVersion(): number
|
|
69
|
+
```
|
|
70
|
+
Returns the Switch server version as `majorVersion + updateNumber/100` (e.g. Switch 25.11 → `25.11`), not a literal version string — don't parse it as one.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
Switch.tr(str: string): string
|
|
74
|
+
```
|
|
75
|
+
Static method. Marks a string literal for translation (used by SwitchScriptTool). Returns the string unchanged at runtime.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Script Folders, Packages & SwitchScriptTool
|
|
2
|
+
|
|
3
|
+
## Script folder vs script package
|
|
4
|
+
|
|
5
|
+
| | Script folder | Script package (`.sscript`) |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| Use for | Development, version control | Production, deployment |
|
|
8
|
+
| Included in flow export | **No** | Yes |
|
|
9
|
+
| TypeScript transpile | Manual — `SwitchScriptTool --transpile` | Automatic in SwitchScripter |
|
|
10
|
+
| Password protection | Not supported | Optional |
|
|
11
|
+
| Can be used as App | No — must pack first | Yes |
|
|
12
|
+
|
|
13
|
+
Script folders are not included in flow exports or backups. Never use a script folder in production — pack it to a `.sscript` package first.
|
|
14
|
+
|
|
15
|
+
## SwitchScriptTool
|
|
16
|
+
|
|
17
|
+
Command-line tool included with Switch. May not be on `PATH` — fall back to the known install
|
|
18
|
+
location for the current OS if the bare command isn't found.
|
|
19
|
+
|
|
20
|
+
**Windows:** `C:\Program Files\Enfocus\Enfocus Switch\SwitchScriptTool\SwitchScriptTool.exe` (add to PATH to avoid typing the full path)
|
|
21
|
+
|
|
22
|
+
**macOS:** symlinked to `/usr/local/bin/SwitchScriptTool` by the installer. If the symlink is missing, the real binary is bundled inside the SwitchScripter app: `/Applications/Enfocus/Enfocus Switch/SwitchScripter.app/Contents/MacOS/SwitchScriptTool/SwitchScriptTool`.
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
| Mode | Command | Purpose |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Create | `SwitchScriptTool --create <ScriptID> <Path> [--JavaScript]` | Scaffold a new script folder with all required files |
|
|
29
|
+
| Transpile | `SwitchScriptTool --transpile <Path>` | Compile `main.ts` → `main.js`. **Must use this, not `tsc` directly** |
|
|
30
|
+
| Pack | `SwitchScriptTool --pack <Folder> <Output> [--password <pwd>] [--verbose]` | Create `.sscript` package for deployment |
|
|
31
|
+
| Unpack | `SwitchScriptTool --unpack <file.sscript> <Folder> [--password <pwd>]` | Extract package to folder |
|
|
32
|
+
| List | `SwitchScriptTool --list <file.sscript>` | List package contents (no password needed) |
|
|
33
|
+
| Generate translations | `SwitchScriptTool --generate-translations <ScriptFolder> <ResultFolder>` | Generate translation files for the script package |
|
|
34
|
+
|
|
35
|
+
**Create** scaffolds: `manifest.xml`, `<ScriptID>.xml`, `<ScriptID>.sscript`, `main.ts` (or `main.js` with `--JavaScript`), `.vscode/launch.json`, `Resources/`, plus `package.json`, `tsconfig.json`, `.vscode/switch.code-snippets`, and type declarations for TypeScript. Creates `<Path>/<ScriptID>/` — it does not write into `<Path>` directly. `ScriptID` may only contain letters, digits, hyphens, and underscores.
|
|
36
|
+
|
|
37
|
+
**Transpile** is required after every edit to `main.ts` before testing a **script folder** directly in Switch. Switch executes `main.js` only — `main.ts` is never run directly. Using SwitchScriptTool (not `tsc`) ensures the same transpile options as SwitchScripter, which is required for consistent behavior. This step is **not** needed before packing — see Pack below.
|
|
38
|
+
|
|
39
|
+
**Pack** transpiles `main.ts` fresh into the package on every run; it never reads or modifies any `main.js` already sitting in the source folder (a stale hand-edited `main.js` there is ignored and left untouched — see the excluded-files note below). It always excludes `package.json` and `.vscode/` from the packed output, printed as an "Info: will not be packed" list even without `--verbose`; `--verbose` additionally prints the full list of what *will* be packed. `node_modules` is packed as-is, so run `npm prune --production` first (see Deployment) — otherwise `devDependencies` (including `@types/*` packages, which the scaffolded `package.json` puts there) get bundled into the package for no runtime benefit. One harmless quirk: the placeholder `<ScriptID>.sscript` file scaffolded by `--create` is not excluded and ends up packed inside the real `.sscript` too.
|
|
40
|
+
|
|
41
|
+
**Unpack** prints package metadata (`Type`, `Protection`, `Status`) before extracting. For a TypeScript-sourced package it extracts only `main.ts` — the compiled `main.js`/`main.js.map` are not written back out, so a pack → unpack round trip returns a clean, editable script folder rather than a compiled snapshot.
|
|
42
|
+
|
|
43
|
+
## Deployment
|
|
44
|
+
|
|
45
|
+
Before packing, remove dev dependencies to reduce package size — this matters because `--pack` bundles `node_modules` as-is, and the scaffolded `package.json` puts type-only packages (`@types/node`, `@types/switch-scripting`, `undici-types`) under `devDependencies`:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
npm prune --production
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then pack:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
SwitchScriptTool --pack <ScriptFolder> <OutputFolder>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Reasons not to use a script folder in production:
|
|
58
|
+
- Not included in flow exports or backups
|
|
59
|
+
- Slower execution than a package
|
|
60
|
+
- Any syntax error saved to `main.js` immediately breaks the running script
|
|
61
|
+
- No password protection available
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# VS Code Setup
|
|
2
|
+
|
|
3
|
+
## Type declarations
|
|
4
|
+
|
|
5
|
+
Enables autocomplete and type checking for `Switch`, `Job`, `FlowElement` and all Switch API globals.
|
|
6
|
+
|
|
7
|
+
**Via npm (preferred):** Add to `devDependencies` in `package.json` and run `npm install`:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
"@types/switch-scripting": "https://github.com/enfocus-switch/types-switch-scripting/archive/refs/tags/v24.1.1-final.tar.gz"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Manual fallback:** Download `index.d.ts` from the types repo and place it at `node_modules/@types/switch-scripting/index.d.ts` inside the script folder.
|
|
14
|
+
|
|
15
|
+
> `SwitchScriptTool --create` sets this up automatically for new TypeScript script folders.
|
|
16
|
+
|
|
17
|
+
## TypeScript 6 / VS Code 1.114+
|
|
18
|
+
|
|
19
|
+
From VS Code 1.114, TypeScript 6 is used. Ambient/global types are no longer auto-included — without explicit configuration, `@types/node` and `@types/switch-scripting` globals (`Switch`, `Job`, etc.) will not be recognised.
|
|
20
|
+
|
|
21
|
+
Add a `types` array to `compilerOptions` in `tsconfig.json`:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"compilerOptions": {
|
|
26
|
+
"types": ["node", "switch-scripting"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## ESLint rules
|
|
32
|
+
|
|
33
|
+
Two rules that catch Switch-specific async bugs before runtime:
|
|
34
|
+
|
|
35
|
+
- **`require-await`** — flags `async` functions that never actually `await`, catching accidentally dropped API call promises
|
|
36
|
+
- **`@typescript-eslint/no-floating-promises`** — errors on any unawaited promise; in Switch scripts these cause silent race conditions that are very difficult to diagnose
|
|
37
|
+
|
|
38
|
+
Example `.eslintrc`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"root": true,
|
|
43
|
+
"parser": "@typescript-eslint/parser",
|
|
44
|
+
"parserOptions": { "project": "./tsconfig.json" },
|
|
45
|
+
"plugins": ["@typescript-eslint", "prettier"],
|
|
46
|
+
"extends": [
|
|
47
|
+
"eslint:recommended",
|
|
48
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
49
|
+
"plugin:@typescript-eslint/recommended",
|
|
50
|
+
"prettier"
|
|
51
|
+
],
|
|
52
|
+
"rules": {
|
|
53
|
+
"require-await": 2,
|
|
54
|
+
"@typescript-eslint/no-floating-promises": 2,
|
|
55
|
+
"prettier/prettier": 2
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Snippets
|
|
61
|
+
|
|
62
|
+
`SwitchScriptTool --create` generates `.vscode/switch.code-snippets` with entry point scaffolding (prefix `switch…`). See the hub doc for details.
|