@enfocussw/switch-scripting-context 0.1.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/CHANGELOG.md +504 -0
- package/README.md +192 -0
- package/bin/cli.js +8 -0
- package/dist/init.d.ts +78 -0
- package/dist/init.js +894 -0
- package/docs/switch-api/api-versions.md +127 -0
- package/docs/switch-api/connection.md +82 -0
- package/docs/switch-api/document-classes.md +189 -0
- package/docs/switch-api/entry-points.md +185 -0
- package/docs/switch-api/enums.md +181 -0
- package/docs/switch-api/execution-environment.md +143 -0
- package/docs/switch-api/flow-element.md +143 -0
- package/docs/switch-api/http.md +96 -0
- package/docs/switch-api/job-patterns.md +238 -0
- package/docs/switch-api/job.md +187 -0
- package/docs/switch-api/logging.md +117 -0
- package/docs/switch-api/switch.md +210 -0
- package/docs/switch-appstore/app-guidelines.md +281 -0
- package/docs/switch-appstore/app-manual.md +84 -0
- package/docs/switch-appstore/app-store-listing.md +69 -0
- package/docs/switch-appstore/app-store-submission.md +83 -0
- package/docs/switch-project/debugging.md +61 -0
- package/docs/switch-project/logs-and-dataroot.md +80 -0
- package/docs/switch-project/node-versions.md +87 -0
- package/docs/switch-project/project-planning.md +149 -0
- package/docs/switch-project/property-documentation.md +75 -0
- package/docs/switch-project/property-editors.md +249 -0
- package/docs/switch-project/script-declaration.md +407 -0
- package/docs/switch-project/script-structure.md +157 -0
- package/docs/switch-project/tooling.md +165 -0
- package/docs/switch-project/vscode.md +90 -0
- package/docs/switch-scripting.md +70 -0
- package/package.json +65 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: api-versions
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 25
|
|
5
|
+
summary: "Which Switch release added each scripting API class, method, and enum value; API availability follows the running Switch, not `manifest.xml`"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Writing or reviewing code for a script or app that must run on a Switch version older than the latest, or when the user names a minimum Switch version"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# API availability by Switch version
|
|
11
|
+
|
|
12
|
+
<!-- docs-index:contents begin -->
|
|
13
|
+
## Contents
|
|
14
|
+
|
|
15
|
+
- The running Switch decides which methods exist
|
|
16
|
+
- Checking at runtime
|
|
17
|
+
- Release names
|
|
18
|
+
- Source and limits of this list
|
|
19
|
+
- Baseline (every Switch version with Node.js scripting)
|
|
20
|
+
- Added per release
|
|
21
|
+
- Declaration changes to existing methods
|
|
22
|
+
<!-- docs-index:contents end -->
|
|
23
|
+
|
|
24
|
+
## The running Switch decides which methods exist
|
|
25
|
+
|
|
26
|
+
Each Switch installation ships one copy of the scripting module, and every bundled Node.js version
|
|
27
|
+
uses that same copy. So which API methods a script can call depends on the Switch Server the script
|
|
28
|
+
runs on, not on anything in the script package. A script whose `manifest.xml` says `20.1` runs on
|
|
29
|
+
Node.js 12 in Switch 26.11, and it still gets the full 26.11 API.
|
|
30
|
+
|
|
31
|
+
The two versions are independent:
|
|
32
|
+
|
|
33
|
+
| Depends on | Decided by |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Node.js version (language features, Node built-ins) | `SwitchVersion` in `manifest.xml`, looked up by the running Switch. See [node-versions.md](../switch-project/node-versions.md) |
|
|
36
|
+
| Scripting API (classes, methods, enum values below) | The version of the Switch Server the script runs on |
|
|
37
|
+
|
|
38
|
+
When code must run on an older Switch, check every API call against the tables below for the
|
|
39
|
+
**oldest** Switch version the script or app must support. For an app, that is the version baseline
|
|
40
|
+
from [project-planning.md § Switch version baseline](../switch-project/project-planning.md#switch-version-baseline-apps-only).
|
|
41
|
+
|
|
42
|
+
### Checking at runtime
|
|
43
|
+
|
|
44
|
+
`s.getServerVersion()` (Switch 24.0+) returns the running Switch version as a number, e.g. `25.11`.
|
|
45
|
+
It doesn't exist on older Switch versions, so it can't detect those. To use a newer method when
|
|
46
|
+
available and fall back otherwise, test for the method itself:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
if (typeof job.getVariableAsString === 'function') {
|
|
50
|
+
// Switch 24.0+
|
|
51
|
+
} else {
|
|
52
|
+
// fallback for older Switch versions
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Release names
|
|
57
|
+
|
|
58
|
+
| `SwitchVersion` | Release |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `20.0` | Switch 2020 Spring |
|
|
61
|
+
| `20.1` | Switch 2020 Fall |
|
|
62
|
+
| `21.0` | Switch 2021 Spring |
|
|
63
|
+
| `21.1` | Switch 2021 Fall |
|
|
64
|
+
| `22.0` | Switch 2022 Spring |
|
|
65
|
+
| `22.1` | Switch 2022 Fall |
|
|
66
|
+
| `23.1` | Switch 2023 Fall |
|
|
67
|
+
| `24.0` | Switch 2024 Spring |
|
|
68
|
+
| `24.1` | Switch 2024 Fall |
|
|
69
|
+
| `25.11` | Switch 25.11 |
|
|
70
|
+
| `26.11` | Switch 26.11 |
|
|
71
|
+
|
|
72
|
+
## Source and limits of this list
|
|
73
|
+
|
|
74
|
+
The list comes from Enfocus's published type declarations
|
|
75
|
+
(`github.com/enfocus-switch/types-switch-scripting`), diffed from one release's tags to the next.
|
|
76
|
+
Several tags for one release (for example 22.1.0 and 22.1.1) are corrections to the declarations
|
|
77
|
+
for that release, not API changes, so they count as one release. A release with no tag added
|
|
78
|
+
nothing.
|
|
79
|
+
|
|
80
|
+
- The first tags (1.0.0 and 1.0.1, October 2020) are the baseline. The declarations don't separate
|
|
81
|
+
Switch 2020 Spring from 2020 Fall, so treat the baseline as available in every Switch version
|
|
82
|
+
that runs Node.js scripts.
|
|
83
|
+
- Tag 1.1.0 (May 2021) is Switch 2021 Spring. The later tags carry the release number (21.1.x,
|
|
84
|
+
22.0.x, 22.1.x, 24.0.x, 24.1.x).
|
|
85
|
+
- The declarations end at v24.1.1-final (Switch 2024 Fall). SwitchScriptTool 26.11 still scaffolds
|
|
86
|
+
that version. A check of the scripting module in a pre-release Switch build found no public class,
|
|
87
|
+
method, or enum value that v24.1.1 lacks, and 26.11 adds no scripting API. So nothing was added in
|
|
88
|
+
23.1, 25.11, or 26.11.
|
|
89
|
+
- Entry points aren't part of the type declarations, so this list doesn't record when each entry
|
|
90
|
+
point appeared. The webhook entry points (`httpRequestTriggeredSync`/`Async`) need
|
|
91
|
+
`s.httpRequestSubscribe()`, so they can't be used before Switch 21.1 either.
|
|
92
|
+
|
|
93
|
+
## Baseline (every Switch version with Node.js scripting)
|
|
94
|
+
|
|
95
|
+
| Class | Members |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `Switch` | `getGlobalData`, `setGlobalData`, `removeGlobalData` (including the `lock` parameter) |
|
|
98
|
+
| `FlowElement` | `getPropertyStringValue`, `getPropertyType`, `getPropertyDisplayName`, `hasProperty`, `getOutConnections`, `setTimerInterval`, `log`, `failProcess`, `createJob`, `getPluginResourcesPath` |
|
|
99
|
+
| `Job` | `getName`, `getId`, `isFile`, `isFolder`, `get`, `sendToNull`, `sendToSingle`, `sendTo`, `sendToData`, `sendToLog`, `fail`, `log`, `createChild`, `getPrivateData`, `setPrivateData`, `removePrivateData`, `listDatasets`, `createDataset`, `getDataset`, `removeDataset` |
|
|
100
|
+
| `Connection` | `getId`, `getName`, `getPropertyStringValue`, `getPropertyType`, `getPropertyDisplayName`, `hasProperty` |
|
|
101
|
+
| Enums | `AccessLevel` (all), `Connection.Level` (all), `PropertyType` (all), `LogLevel.Info`/`Warning`/`Error`, `DatasetModel.Opaque`/`XML`/`XMP`/`JDF`, `Scope.Element`/`FlowElement`/`Global` |
|
|
102
|
+
|
|
103
|
+
## Added per release
|
|
104
|
+
|
|
105
|
+
| Release | Added |
|
|
106
|
+
|---|---|
|
|
107
|
+
| 21.0 | `flowElement.getJobs()`; `PdfDocument` and `PdfPage` (whole classes); `EnfocusSwitchPrivateDataTag` with `hierarchy`, `emailAddresses`, `emailBody`, `userName`, `userFullName`, `userEmail`, `origin`; `LogLevel.Debug` |
|
|
108
|
+
| 21.1 | `flowElement.getName()`; `HttpRequest` and `HttpResponse` (whole classes, including `HttpRequest.Method`); `s.httpRequestSubscribe()`, `s.httpRequestUnsubscribe()`; `ImageDocument` (whole class, including `ImageDocument.ColorMode` and `ImageDocument.ColorSpace`); `EnfocusSwitchPrivateDataTag.initiated`, `.submittedTo` |
|
|
109
|
+
| 22.0 | `flowElement.getFlowName()`; `Switch.tr()`; `XmlDocument` (whole class); `Scope.Flow`, `Scope.FlowElements`; `DatasetModel.JSON` |
|
|
110
|
+
| 22.1 | `job.getPriority()`, `job.setPriority()`, `Priority` enum; `job.sendToChannel()`, `flowElement.subscribeToChannel()`; `job.processLater()`; `s.setAbortData()`; `XmpDocument` (whole class), `pdfDocument.getXMP()`; `EnfocusSwitchPrivateDataTag.state` |
|
|
111
|
+
| 23.1 | Nothing |
|
|
112
|
+
| 24.0 | `flowElement.getScriptDataPath()`, `flowElement.createPathWithName()`; `job.getVariableAsString()`, `job.getxmlData()`, `job.getxmpData()`, `job.getJdfData()`, `job.getJSONData()`; `s.getPreferenceSetting()`, `s.getServerVersion()`; `NoYesListPropertyStringValue` |
|
|
113
|
+
| 24.1 | `connection.getType()`, `connection.getFileCount()`, `flowElement.getFileCount()` |
|
|
114
|
+
| 25.11, 26.11 | Nothing |
|
|
115
|
+
|
|
116
|
+
## Declaration changes to existing methods
|
|
117
|
+
|
|
118
|
+
These signatures changed between releases in the declarations. The declarations don't say whether
|
|
119
|
+
older runtimes enforced the older signature, so when targeting a release before the change, write
|
|
120
|
+
code that satisfies both.
|
|
121
|
+
|
|
122
|
+
- Before 21.0, private data and global data values were declared as `string`; from 21.0 they are
|
|
123
|
+
`any`. On 20.x, store strings (for example `JSON.stringify` the value) and parse them on read.
|
|
124
|
+
- Before 21.0, `job.fail()` declared `messageParams` as required. On 20.x, pass an array, even an
|
|
125
|
+
empty one.
|
|
126
|
+
- Before 22.1, `flowElement.failProcess()` declared `messageParam` as a required `string`. On an
|
|
127
|
+
older Switch, pass a string.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connection
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 6
|
|
5
|
+
summary: "`Connection`: type, properties, file count"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Routing to specific connections or reading connection properties"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Connection Class
|
|
11
|
+
|
|
12
|
+
A `Connection` represents an outgoing connection from the flow element. Obtain instances via `flowElement.getOutConnections()`.
|
|
13
|
+
|
|
14
|
+
## Identity
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
connection.getId(): string
|
|
18
|
+
```
|
|
19
|
+
Unique ID for the connection. Stable across deactivate/reactivate, Switch restarts, holding/releasing connections, and renaming the flow itself. Changes on export/re-import, a flow upgrade, or renaming the flow *element* (not the flow).
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
connection.getName(): string
|
|
23
|
+
```
|
|
24
|
+
Display name as shown on the canvas. May be an empty string.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
// Switch 24.1+
|
|
28
|
+
connection.getType(): string
|
|
29
|
+
```
|
|
30
|
+
Connection type. One of: `"Move"`, `"Filter"`, `"Traffic-data"`, `"Traffic-log"`, `"Traffic-datawithlog"`.
|
|
31
|
+
|
|
32
|
+
## Connection properties
|
|
33
|
+
|
|
34
|
+
Connection properties are declared in the script's XML declaration (`ConnectionFields`) and configured per-connection in the canvas. See [script-declaration.md](../switch-project/script-declaration.md) for how to declare them (via SwitchScripter).
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
connection.getPropertyStringValue(tag: string): Promise<string | string[]>
|
|
38
|
+
```
|
|
39
|
+
Returns the connection property value as a string. Throws `"Invalid tag: <tag>"` if the tag is unknown **or if it's a `Dependency` dependent currently hidden by its master's value** — see [script-declaration.md § Dependency](../switch-project/script-declaration.md#custom-property-elements-elementfields). Before fetching a dependent property, confirm its condition holds (from the already-read master value, or via `hasProperty(tag)` below) rather than fetching it unconditionally.
|
|
40
|
+
|
|
41
|
+
This is **not** how to check which traffic light level(s) a connection accepts before calling `job.sendToData()` — `"Success"`/`"Warning"`/`"Error"` are not property tags, so passing one throws the same invalid-tag error. There is no supported way to check in advance; see [Connection.Level enum](#connectionlevel-enum) below.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
connection.getPropertyType(tag: string): PropertyType
|
|
45
|
+
```
|
|
46
|
+
Returns the `PropertyType` of the property.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
connection.getPropertyDisplayName(tag: string): string
|
|
50
|
+
```
|
|
51
|
+
Returns the English display name of the property (for use in log messages).
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
connection.hasProperty(tag: string): boolean
|
|
55
|
+
```
|
|
56
|
+
Returns `true` if the property exists and is visible for the current configuration. Use this to guard `getPropertyStringValue(tag)` calls on `Dependency` dependents — see the note above.
|
|
57
|
+
|
|
58
|
+
## File count
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// Switch 24.1+
|
|
62
|
+
connection.getFileCount(nested?: boolean): Promise<number>
|
|
63
|
+
```
|
|
64
|
+
Returns the number of files in the folder at the other end of this connection. If `nested` is `false`, counts only direct children; if `true` (the default, so it can be omitted), counts recursively (subfolders themselves are not counted).
|
|
65
|
+
|
|
66
|
+
## Connection.Level enum
|
|
67
|
+
|
|
68
|
+
Used with `job.sendToData()` and `job.sendToLog()` to select which traffic light connection a job routes to.
|
|
69
|
+
|
|
70
|
+
| Value | String |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `Connection.Level.Success` | `"success"` |
|
|
73
|
+
| `Connection.Level.Warning` | `"warning"` |
|
|
74
|
+
| `Connection.Level.Error` | `"error"` |
|
|
75
|
+
|
|
76
|
+
Available as `EnfocusSwitch.Connection.Level.*` outside `main.ts`.
|
|
77
|
+
|
|
78
|
+
**Traffic light levels are not a readable connection property.** `flowElement.getOutConnections()`
|
|
79
|
+
returns the outgoing `Connection` objects, but the supported API has no way to determine which
|
|
80
|
+
level(s) a given connection accepts. Don't call `connection.getPropertyStringValue("Success")`, `"Warning"`, or `"Error"` expecting to
|
|
81
|
+
read this back; those are not valid property tags for a traffic light connection. To route
|
|
82
|
+
optionally, see [job-patterns.md § Sending jobs](job-patterns.md#sending-jobs).
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: document-classes
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 9
|
|
5
|
+
summary: "`PdfDocument`, `PdfPage`, `ImageDocument`, `XmlDocument`, `XmpDocument`: read-only file introspection"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Inspecting PDF, image, XML, or XMP file contents"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Document Classes
|
|
11
|
+
|
|
12
|
+
Read-only document introspection utilities. All methods may throw — wrap in `try/catch`. Load this file when working with PDF, image, XML, or XMP documents.
|
|
13
|
+
|
|
14
|
+
Each class needs a minimum Switch version: `PdfDocument` and `PdfPage` 21.0+, `ImageDocument` 21.1+, `XmlDocument` 22.0+, `XmpDocument` and `doc.getXMP()` 22.1+.
|
|
15
|
+
|
|
16
|
+
<!-- docs-index:contents begin -->
|
|
17
|
+
## Contents
|
|
18
|
+
|
|
19
|
+
- PdfDocument
|
|
20
|
+
- Static page dimension methods
|
|
21
|
+
- PdfPage
|
|
22
|
+
- ImageDocument
|
|
23
|
+
- XmlDocument
|
|
24
|
+
- XmpDocument
|
|
25
|
+
<!-- docs-index:contents end -->
|
|
26
|
+
|
|
27
|
+
## PdfDocument
|
|
28
|
+
|
|
29
|
+
Open a PDF to inspect metadata and page geometry.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
PdfDocument.open(path: string): PdfDocument
|
|
33
|
+
```
|
|
34
|
+
Opens the PDF. Call `close()` when done.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
doc.close(): void
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
doc.getNumberOfPages(): number
|
|
42
|
+
PdfDocument.getNumberOfPages(path: string): number
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
doc.getPDFVersion(): string // e.g. "1.6"
|
|
47
|
+
PdfDocument.getPDFVersion(path: string): string
|
|
48
|
+
|
|
49
|
+
doc.getPDFXVersion(): string // empty string if not PDF/X
|
|
50
|
+
PdfDocument.getPDFXVersion(path: string): string
|
|
51
|
+
|
|
52
|
+
doc.getSecurityMethod(): string
|
|
53
|
+
PdfDocument.getSecurityMethod(path: string): string
|
|
54
|
+
|
|
55
|
+
doc.getPage(pageNumber?: number): PdfPage // 1-based; defaults to page 1
|
|
56
|
+
doc.getXMP(): XmpDocument // Switch 22.1+
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Static page dimension methods
|
|
60
|
+
|
|
61
|
+
All take `(path: string, pageNumber?: number, effective?: boolean)` — page numbers are 1-based, `effective` defaults to `true` (applies rotation and scaling). All return `number` in points.
|
|
62
|
+
|
|
63
|
+
| Method | Description |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `PdfDocument.getPageHeight` | Alias for media box height |
|
|
66
|
+
| `PdfDocument.getPageWidth` | Alias for media box width |
|
|
67
|
+
| `PdfDocument.getPageMediaBoxHeight` / `Width` | Media box |
|
|
68
|
+
| `PdfDocument.getPageCropBoxHeight` / `Width` | Crop box |
|
|
69
|
+
| `PdfDocument.getPageBleedBoxHeight` / `Width` | Bleed box |
|
|
70
|
+
| `PdfDocument.getPageTrimBoxHeight` / `Width` | Trim box |
|
|
71
|
+
| `PdfDocument.getPageArtBoxHeight` / `Width` | Art box — **known issue:** currently returns the crop box value instead (not expected to be fixed soon) |
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
PdfDocument.getPageRotation(path: string, pageNumber?: number): number // degrees
|
|
75
|
+
PdfDocument.getPageScaling(path: string, pageNumber?: number): number
|
|
76
|
+
PdfDocument.getPageLabel(path: string, pageNumber?: number): string // empty if none
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## PdfPage
|
|
82
|
+
|
|
83
|
+
Obtained via `PdfDocument.getPage()`. Instance-level page geometry. All dimensions in points.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
page.getHeight(effective?: boolean): number // alias for getMediaBoxHeight
|
|
87
|
+
page.getWidth(effective?: boolean): number // alias for getMediaBoxWidth
|
|
88
|
+
|
|
89
|
+
page.getMediaBoxHeight(effective?: boolean): number
|
|
90
|
+
page.getMediaBoxWidth(effective?: boolean): number
|
|
91
|
+
page.getCropBoxHeight(effective?: boolean): number
|
|
92
|
+
page.getCropBoxWidth(effective?: boolean): number
|
|
93
|
+
page.getBleedBoxHeight(effective?: boolean): number
|
|
94
|
+
page.getBleedBoxWidth(effective?: boolean): number
|
|
95
|
+
page.getTrimBoxHeight(effective?: boolean): number
|
|
96
|
+
page.getTrimBoxWidth(effective?: boolean): number
|
|
97
|
+
page.getArtBoxHeight(effective?: boolean): number // known issue: currently returns the crop box value
|
|
98
|
+
page.getArtBoxWidth(effective?: boolean): number // known issue: currently returns the crop box value
|
|
99
|
+
|
|
100
|
+
page.getRotation(): number // degrees
|
|
101
|
+
page.getScaling(): number
|
|
102
|
+
page.getPageLabel(): string // empty if none
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`effective` defaults to `true` — applies rotation and scaling.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## ImageDocument
|
|
110
|
+
|
|
111
|
+
Supported formats: JPEG, TIFF, PNG. Reads values from EXIF and XMP.
|
|
112
|
+
|
|
113
|
+
**`open` is async** — use `await`:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const img = await ImageDocument.open(path);
|
|
117
|
+
// ...
|
|
118
|
+
img.close();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
All static methods also return `Promise<T>`.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
ImageDocument.open(path: string): Promise<ImageDocument>
|
|
125
|
+
img.close(): void
|
|
126
|
+
|
|
127
|
+
img.getWidth(): number
|
|
128
|
+
ImageDocument.getWidth(path: string): Promise<number>
|
|
129
|
+
|
|
130
|
+
img.getHeight(): number
|
|
131
|
+
ImageDocument.getHeight(path: string): Promise<number>
|
|
132
|
+
|
|
133
|
+
img.getColorMode(): ImageDocument.ColorMode
|
|
134
|
+
ImageDocument.getColorMode(path: string): Promise<ImageDocument.ColorMode>
|
|
135
|
+
|
|
136
|
+
img.getColorSpace(): ImageDocument.ColorSpace
|
|
137
|
+
ImageDocument.getColorSpace(path: string): Promise<ImageDocument.ColorSpace>
|
|
138
|
+
|
|
139
|
+
img.getICCProfile(): string // Photoshop, falling back to the EXIF ProfileDescription if absent
|
|
140
|
+
ImageDocument.getICCProfile(path: string): Promise<string>
|
|
141
|
+
|
|
142
|
+
img.getSamplesPerPixel(): number
|
|
143
|
+
ImageDocument.getSamplesPerPixel(path: string): Promise<number>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
See [enums.md](enums.md) for `ImageDocument.ColorMode` and `ImageDocument.ColorSpace` values.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## XmlDocument
|
|
151
|
+
|
|
152
|
+
XPath 1.0 queries against XML files or strings.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
XmlDocument.open(path: string): XmlDocument
|
|
156
|
+
XmlDocument.parse(xmlString: string): XmlDocument
|
|
157
|
+
|
|
158
|
+
doc.evaluate(xpath: string, prefixMap?: { [prefix: string]: string }): boolean | number | string | object | undefined
|
|
159
|
+
doc.getDefaultNSMap(): { [prefix: string]: string }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
XPath does not support default namespaces — always use a prefix. `getDefaultNSMap()` returns all namespace mappings occurring in the document; the default namespace (if any) is accessible via the special prefixes `default_switch_ns`, `dn`, and `jdf`. `evaluate()` can also return an `object` (e.g. a node-set result), not just the primitive types.
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
const doc = XmlDocument.open(path);
|
|
166
|
+
const map = doc.getDefaultNSMap();
|
|
167
|
+
const result = doc.evaluate('/dn:root/dn:item/@id', map);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## XmpDocument
|
|
173
|
+
|
|
174
|
+
Evaluate XMP location paths (not XPath) against XMP-only files. Obtained from `PdfDocument.getXMP()` or opened directly.
|
|
175
|
+
|
|
176
|
+
> **Note**: `open()` requires an XMP-only file — do not pass a PDF or image path.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
XmpDocument.open(path: string): XmpDocument
|
|
180
|
+
|
|
181
|
+
doc.evaluate(
|
|
182
|
+
xmpLocationPath: string,
|
|
183
|
+
additionalPrefixMap?: { [prefix: string]: string }
|
|
184
|
+
): boolean | number | string | undefined
|
|
185
|
+
|
|
186
|
+
doc.save(path: string): void
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
If `additionalPrefixMap` is omitted, the default prefix map (all standard XMP namespaces plus any extras in the file) is used.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: entry-points
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 2
|
|
5
|
+
summary: "All entry point signatures, constraints, and when each is called"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Scaffolding a script, adding/editing an entry point, or making any edit to main.ts/main.js"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Switch Script Entry Points
|
|
11
|
+
|
|
12
|
+
Entry points are top-level `async` functions with specific names. They are **not exported**. Switch calls them automatically based on flow events.
|
|
13
|
+
|
|
14
|
+
<!-- docs-index:contents begin -->
|
|
15
|
+
## Contents
|
|
16
|
+
|
|
17
|
+
- Entry-point scanner constraints
|
|
18
|
+
- Flow lifecycle
|
|
19
|
+
- Timer
|
|
20
|
+
- Job processing
|
|
21
|
+
- Webhooks
|
|
22
|
+
- Script expression
|
|
23
|
+
- Property UI callbacks
|
|
24
|
+
<!-- docs-index:contents end -->
|
|
25
|
+
|
|
26
|
+
## Entry-point scanner constraints
|
|
27
|
+
|
|
28
|
+
Switch discovers a script's entry points by regex, not by parsing. Before matching
|
|
29
|
+
`function\s+(name)\s*\(` it strips comments and literals with a regex that doesn't understand JS
|
|
30
|
+
escaping. Certain source shapes make that strip regex delete large spans of real code — and every
|
|
31
|
+
`function` declaration inside the deleted span becomes invisible to Switch, whether or not that
|
|
32
|
+
function is itself well-formed.
|
|
33
|
+
|
|
34
|
+
This applies to **every** entry point on this page, not only the four checked below — a swallowed
|
|
35
|
+
`validateProperties` or `getLibraryForProperty` fails silently (the callback just never runs, no
|
|
36
|
+
error anywhere), which is worse than the loud failure the four below produce. The one exception is
|
|
37
|
+
`calculateScriptExpression`: it's invoked directly at runtime rather than through this scanner, so
|
|
38
|
+
it isn't at risk.
|
|
39
|
+
|
|
40
|
+
If none of `jobArrived`, `timerFired`, `flowStopTriggered`, `httpRequestTriggeredAsync` survives,
|
|
41
|
+
Switch fails with `Cannot open script '<name>': no entry points found` — `httpRequestTriggeredSync`
|
|
42
|
+
alone does not satisfy this check. Both the packed `.sscript` (the entry-point list is baked in at
|
|
43
|
+
pack time) and the unpacked script folder (`main.js` is rescanned by this same scanner every time
|
|
44
|
+
Switch loads it, e.g. running or debugging from Designer) are affected. Packing does not validate
|
|
45
|
+
or warn about any of this — a script that packs cleanly can still fail to load.
|
|
46
|
+
|
|
47
|
+
**Rules for writing entry points in `main.ts`/`main.js`:**
|
|
48
|
+
|
|
49
|
+
1. Never write a string literal whose content ends with a backslash: `"\\"`, `'\\'`, `` `\\` ``,
|
|
50
|
+
`"C:\\Temp\\"`. This is the highest-frequency trigger — the strip regex hunts for the next
|
|
51
|
+
matching quote character anywhere later in the file to close the literal (a backslash right
|
|
52
|
+
before the real closing quote makes it skip past that quote), and deletes everything in between.
|
|
53
|
+
Use `"\x5c"`, `"\u005C"`, `String.fromCharCode(92)`, or restructure (e.g.
|
|
54
|
+
`JSON.stringify(v).slice(1, -1)` for backslash/quote escaping) instead. A backslash elsewhere in
|
|
55
|
+
the literal is fine: `"\\n is newline"`, `"a\\b"`.
|
|
56
|
+
2. Avoid regex literals — including ones that look properly closed, like `/[^/]+/` (a character
|
|
57
|
+
class containing an unescaped `/`). The strip regex doesn't understand character classes, so it
|
|
58
|
+
closes the "literal" early at the inner `/` and leaves a dangling `/` that swallows forward to
|
|
59
|
+
the next `/` anywhere later in the file. Use `new RegExp("...")` instead.
|
|
60
|
+
3. Avoid division that isn't in the plain `word / word` shape. `a / b` is recognised and stripped
|
|
61
|
+
safely; `) / 2`, `] / 2`, and `/=` are not, and the leftover `/` swallows forward exactly like an
|
|
62
|
+
unclosed regex literal. Rewrite as `Math.floor(x / y)` with plain identifiers, or hoist to a
|
|
63
|
+
named variable first.
|
|
64
|
+
4. Declare every entry point with the literal `function` keyword at top level:
|
|
65
|
+
`function jobArrived(...)` or `async function jobArrived(...)`. Arrow functions,
|
|
66
|
+
`exports.jobArrived = function (...)`, and class methods are invisible to the scanner.
|
|
67
|
+
5. Entry-point names are matched case-sensitively. `JobArrived` is silently dropped during
|
|
68
|
+
extraction — if another valid entry point is also present the script packs and loads without
|
|
69
|
+
error, the misnamed function just never runs.
|
|
70
|
+
|
|
71
|
+
See [tooling.md § Verify entry points before packing](../switch-project/tooling.md#verify-entry-points-before-packing)
|
|
72
|
+
for a script to catch this before it reaches Switch.
|
|
73
|
+
|
|
74
|
+
## Flow lifecycle
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
async function flowStartTriggered(s: Switch, flowElement: FlowElement): Promise<void>
|
|
78
|
+
```
|
|
79
|
+
Called when the flow starts. Use to subscribe to webhooks (`s.httpRequestSubscribe`) or channels (`flowElement.subscribeToChannel`). Cannot coexist with `timerFired` or `jobArrived` as the sole entry point. May execute in parallel for concurrent elements. Not available for debugging.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
async function flowStopTriggered(s: Switch, flowElement: FlowElement): Promise<void>
|
|
83
|
+
```
|
|
84
|
+
Called when the flow stops. May execute in parallel for concurrent elements. Not available for debugging.
|
|
85
|
+
|
|
86
|
+
## Timer
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
async function timerFired(s: Switch, flowElement: FlowElement): Promise<void>
|
|
90
|
+
```
|
|
91
|
+
Called on a recurring timer. First fires after `flowStartTriggered`. Set the interval via `flowElement.setTimerInterval(seconds)`, called from inside `timerFired`; calling it from any other entry point has no effect (see [flow-element.md § Timer](flow-element.md#timer)). Cannot coexist with `flowStartTriggered` as the sole entry point.
|
|
92
|
+
|
|
93
|
+
Required when `IncomingConnections="No"`; optional (alongside `jobArrived`) when
|
|
94
|
+
`IncomingConnections="Yes"`. Never leave it present but empty — remove it entirely if it does
|
|
95
|
+
nothing.
|
|
96
|
+
|
|
97
|
+
## Job processing
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
async function jobArrived(s: Switch, flowElement: FlowElement, job: Job): Promise<void>
|
|
101
|
+
```
|
|
102
|
+
Called when a job arrives. Must eventually call a `job.sendTo*()` or `job.fail()`. Can run concurrently if configured in the script XML declaration.
|
|
103
|
+
|
|
104
|
+
`jobArrived` and `timerFired` presence must match the declared connections — present when
|
|
105
|
+
`IncomingConnections="Yes"` (`timerFired` may additionally be present); when
|
|
106
|
+
`IncomingConnections="No"`, `timerFired` must be present instead. See
|
|
107
|
+
[script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields). Never leave an empty
|
|
108
|
+
`jobArrived` or `timerFired` in the script — remove the function entirely if it does nothing.
|
|
109
|
+
|
|
110
|
+
**Gotcha: a flow restart replays every queued job through `jobArrived` again.** This includes a job
|
|
111
|
+
whose real processing was deferred elsewhere, such as a job registered in global data and actually
|
|
112
|
+
handled later in `timerFired`. `jobArrived` does not skip a job just because it was already
|
|
113
|
+
registered on a previous run; if the element still has a large backlog queued when the flow
|
|
114
|
+
restarts, every one of those jobs fires `jobArrived` again, and working through a long backlog this
|
|
115
|
+
way can take a long time even when each invocation only needs to recognize the job as already
|
|
116
|
+
registered and return. A script that defers processing this way must check global data at the top
|
|
117
|
+
of `jobArrived` and return immediately for a job already registered there, rather than assuming
|
|
118
|
+
`jobArrived` fires exactly once per job.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
async function abort(s: Switch, flowElement: FlowElement, job: Job, abortData: any): Promise<void>
|
|
122
|
+
```
|
|
123
|
+
Called when an entry point exceeds its configured timeout. The `abortData` value was set beforehand via `s.setAbortData()` (Switch 22.1+). Applies to: `jobArrived`, `timerFired`, `httpRequestTriggeredSync`, `httpRequestTriggeredAsync`, `flowStartTriggered`, `flowStopTriggered`.
|
|
124
|
+
|
|
125
|
+
**The timeout for `jobArrived` and `timerFired` is the flow element's "Abort after (minutes)" property (`AbortTimeoutMinutes`), not 60 seconds.** Left at `Default`, it takes the Switch preference Error handling > "Abort processes after (minutes)". While the element is in debug mode, Switch never aborts it. The 60-second figure applies only to `abort` itself: it gets at most 60 seconds, after which the script executor is killed.
|
|
126
|
+
|
|
127
|
+
## Webhooks
|
|
128
|
+
|
|
129
|
+
Both webhook entry points need Switch 21.1+, the first release with `s.httpRequestSubscribe()`.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
async function httpRequestTriggeredSync(request: HttpRequest, args: any[], response: HttpResponse, s: Switch): Promise<void>
|
|
133
|
+
```
|
|
134
|
+
Synchronous webhook handler. A response **must** be sent before the function returns. Registered via `s.httpRequestSubscribe()` in `flowStartTriggered`. Executes in concurrent mode. Request body limit: 1 MB (HTTP 413). Queue limit: 10,000 pending requests (HTTP 429). Execution timeout: 1 minute (HTTP 524). Default response if none set: HTTP 200 with `{"status": true}`.
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
async function httpRequestTriggeredAsync(request: HttpRequest, args: any[], s: Switch, flowElement: FlowElement): Promise<void>
|
|
138
|
+
```
|
|
139
|
+
Asynchronous webhook handler. No response is required. Registered via `s.httpRequestSubscribe()` in `flowStartTriggered`. Only invoked if `httpRequestTriggeredSync` is not defined, or if the sync handler returned a 2xx status.
|
|
140
|
+
|
|
141
|
+
## Script expression
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
async function calculateScriptExpression(s: Switch, flowElement: FlowElement, job: Job): Promise<string | number | boolean>
|
|
145
|
+
```
|
|
146
|
+
Called to evaluate a script expression for the flow element. The return value is used as the expression result.
|
|
147
|
+
|
|
148
|
+
## Property UI callbacks
|
|
149
|
+
|
|
150
|
+
Not available for debugging.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
async function getLibraryForProperty(s: Switch, flowElement: FlowElement, tag: string): Promise<string[]>
|
|
154
|
+
```
|
|
155
|
+
Returns a dynamic list of values for a property's library dropdown. Mandatory if any property uses
|
|
156
|
+
the `askplugin`/`askplugin2` editor (see
|
|
157
|
+
[property-editors.md](../switch-project/property-editors.md#modal-editors)). Log an error via `flowElement.log()`
|
|
158
|
+
if the list would otherwise come back empty, so the user can see why the dropdown has nothing in it.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
async function getLibraryForConnectionProperty(s: Switch, flowElement: FlowElement, c: Connection, tag: string): Promise<string[]>
|
|
162
|
+
```
|
|
163
|
+
Returns a dynamic list of values for a connection property's library dropdown. Same guidance as
|
|
164
|
+
`getLibraryForProperty` above, for connection fields using `askplugin`/`askplugin2`.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
async function validateProperties(s: Switch, flowElement: FlowElement, tags: string[]): Promise<{ tag: string, valid: boolean }[]>
|
|
168
|
+
```
|
|
169
|
+
Validates one or more property values. Return one result object per tag. Mandatory if any property
|
|
170
|
+
declares `Validation="Custom"` or `"Standard and custom"` (see
|
|
171
|
+
[script-declaration.md](../switch-project/script-declaration.md#custom-property-elements-elementfields)). Log
|
|
172
|
+
an error via `flowElement.log()` for any tag returned with `valid: false`, so the user sees why.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
async function validateConnectionProperties(s: Switch, flowElement: FlowElement, c: Connection, tags: string[]): Promise<{ tag: string, valid: boolean }[]>
|
|
176
|
+
```
|
|
177
|
+
Validates one or more connection property values. Same guidance as `validateProperties` above, for
|
|
178
|
+
connection fields declaring `Validation="Custom"`/`"Standard and custom"`.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
async function findExternalEditorPath(s: Switch, flowElement: FlowElement, tag: string): Promise<string>
|
|
182
|
+
```
|
|
183
|
+
Resolves the path to an external editor for a property. Required whenever the
|
|
184
|
+
`external`/`external2`/… editor is used, unless the dependent `Application` property is non-empty —
|
|
185
|
+
see [property-editors.md § Notes](../switch-project/property-editors.md#notes).
|