@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,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: app-store-submission
|
|
3
|
+
category: switch-appstore
|
|
4
|
+
order: 24
|
|
5
|
+
summary: "Writing guidance for the Create Appstore App / Create Appstore App Version web forms: Short Description, What's new, Eula, icon specs, and which fields reuse content already written elsewhere"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Preparing content for the Appstore website submission forms"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Writing the Appstore Submission Forms
|
|
11
|
+
|
|
12
|
+
Guidance for the two web forms on the Enfocus Appstore site: **Create Appstore App** (once per
|
|
13
|
+
app) and **Create Appstore App Version** (once per release). These are separate from the
|
|
14
|
+
[listing fields](app-store-listing.md) in the declaration and from the
|
|
15
|
+
[app manual](app-manual.md) — a human fills these forms in directly on the Enfocus website, so
|
|
16
|
+
the agent's job is to prepare the content, not submit it. `Package Password`, `Binary`, and
|
|
17
|
+
`Signed Binary` are manual/security-sensitive steps on the App Version form; leave those to the
|
|
18
|
+
user entirely.
|
|
19
|
+
|
|
20
|
+
**Delivery:** write the content below to `./README.md` at the project root, labeled by field name,
|
|
21
|
+
for the user to copy into the two forms. If the project already has a `README.md` for other
|
|
22
|
+
purposes, add a clearly separated section rather than overwriting it.
|
|
23
|
+
|
|
24
|
+
Same writing-quality bar as [property-documentation.md § Writing quality](../switch-project/property-documentation.md#writing-quality).
|
|
25
|
+
|
|
26
|
+
## Fields that reuse content you've already written
|
|
27
|
+
|
|
28
|
+
Point the user at the source instead of rewriting these:
|
|
29
|
+
|
|
30
|
+
| Form field | Source |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Display Name | Declaration `DisplayName` |
|
|
33
|
+
| Internal Identifier | Declaration `Name` |
|
|
34
|
+
| Long Description | [Listing `Description`](app-store-listing.md#description) |
|
|
35
|
+
| Keywords | Declaration `Keywords` — the form must match it exactly, it's checked against the script source |
|
|
36
|
+
| Categories | Declaration `PositionInElementPane`/`SubcategoryInElementPane` — see [app-guidelines.md](app-guidelines.md#top-level-declaration-properties) |
|
|
37
|
+
| Support Website / Support Phone / Support Email | [Listing `SupportInfo`](app-store-listing.md#supportinfo), split across the three fields the form actually has |
|
|
38
|
+
| Third-party Compatibility | [Listing `Compatibility`](app-store-listing.md#compatibility) |
|
|
39
|
+
| Switch Version | The minimum Switch version, same content as [the app manual's Compatibility section](app-manual.md#compatibility) |
|
|
40
|
+
|
|
41
|
+
## New content
|
|
42
|
+
|
|
43
|
+
Nothing above covers these — the form is the only place they're written.
|
|
44
|
+
|
|
45
|
+
### Short Description
|
|
46
|
+
|
|
47
|
+
Max 500 characters. Distinct from Long Description: this is the search-result and marketing-email
|
|
48
|
+
summary, not a shorter copy of the full description. One or two sentences stating what the app
|
|
49
|
+
does and the third-party dependency, without repeating Display Name.
|
|
50
|
+
|
|
51
|
+
### What's new
|
|
52
|
+
|
|
53
|
+
Per-version release notes: what changed in *this* version, for someone deciding whether to update.
|
|
54
|
+
Lead with the effect on the user (new capability, fixed behavior), not the implementation. Skip
|
|
55
|
+
internal refactors with no user-visible effect.
|
|
56
|
+
|
|
57
|
+
### Eula
|
|
58
|
+
|
|
59
|
+
**Don't draft this from scratch.** A EULA is a binding legal document — write it only from the app
|
|
60
|
+
creator's existing legal-reviewed template, or leave it for them to supply. If neither exists, tell
|
|
61
|
+
the user this needs their own legal review rather than generating terms.
|
|
62
|
+
|
|
63
|
+
## Icons
|
|
64
|
+
|
|
65
|
+
Two separate image assets, both uploaded on the Create Appstore App form:
|
|
66
|
+
|
|
67
|
+
| Field | Spec | Notes |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| Switch Icon | 32×32 px recommended (larger is resized down); PNG/GIF/JPG | Must match the `Icon` property already in the script source — use the same file you packaged with the app, don't create a second one |
|
|
70
|
+
| Appstore Icon | At least 200×200 px, square (a non-square image gets transparent padding added); PNG/GIF/JPG, under 100 MB | Used across the whole Appstore site: overview, detail page, search results |
|
|
71
|
+
|
|
72
|
+
Creating the actual artwork is a design task, not something to improvise without source material —
|
|
73
|
+
if the app creator hasn't supplied a logo or icon source image, say so rather than generating
|
|
74
|
+
placeholder art. Given a source image, verify and derive the two required files with a CLI image
|
|
75
|
+
tool (`sips` on macOS, or ImageMagick):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Verify dimensions and that the file is actually PNG
|
|
79
|
+
sips -g pixelWidth -g pixelHeight -g format icon-source.png
|
|
80
|
+
|
|
81
|
+
# Resize down to the 32x32 Switch icon (never upscale a smaller source)
|
|
82
|
+
sips -z 32 32 icon-source.png --out switch-icon.png
|
|
83
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: debugging
|
|
3
|
+
category: switch-project
|
|
4
|
+
order: 12
|
|
5
|
+
summary: "Enabling debug mode in Switch Designer, debuggable entry points, VS Code attach"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Debugging a script"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Debugging Scripts
|
|
11
|
+
|
|
12
|
+
Debugging requires configuring the Script element in Switch Designer — the agent cannot do this directly but can guide the user through the steps.
|
|
13
|
+
|
|
14
|
+
## Constraints
|
|
15
|
+
|
|
16
|
+
- Only works with script folders and non-password-protected packages (see [tooling.md § Script folder vs script package](tooling.md#script-folder-vs-script-package))
|
|
17
|
+
- Only one script can be in debug mode at a time
|
|
18
|
+
- Execution mode is forced to Serialized while debug is enabled (see [execution-environment.md § Execution modes](../switch-api/execution-environment.md#execution-modes))
|
|
19
|
+
- Only these four entry points can be debugged: `jobArrived`, `timerFired`, `httpRequestTriggeredAsync`, `findExternalEditorPath` (signatures in [entry-points.md](../switch-api/entry-points.md))
|
|
20
|
+
- `console.log` output only appears while a debug session is attached (see [logging.md](../switch-api/logging.md))
|
|
21
|
+
|
|
22
|
+
## Enabling debug mode in Switch Designer
|
|
23
|
+
|
|
24
|
+
In the Script element properties, once a script folder or package is selected, three extra properties appear:
|
|
25
|
+
|
|
26
|
+
| Property | Value |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Enable debug mode | Yes |
|
|
29
|
+
| Port | 9229 (default) |
|
|
30
|
+
| Debug entry points | Select from the supported entry points above |
|
|
31
|
+
|
|
32
|
+
## Attaching VS Code
|
|
33
|
+
|
|
34
|
+
**Script folder:** Open the script folder in VS Code and press F5. The `.vscode/launch.json` created by `SwitchScriptTool --create` (see [tooling.md § Commands](tooling.md#commands)) is pre-configured for attach mode.
|
|
35
|
+
|
|
36
|
+
**Package (no `launch.json`):** Create `launch.json` manually:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"version": "0.2.0",
|
|
41
|
+
"configurations": [
|
|
42
|
+
{
|
|
43
|
+
"type": "node",
|
|
44
|
+
"request": "attach",
|
|
45
|
+
"name": "Attach",
|
|
46
|
+
"port": 9229,
|
|
47
|
+
"skipFiles": ["<node_internals>/**"]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use the port number set in the Script element properties.
|
|
54
|
+
|
|
55
|
+
After attaching, VS Code stops in internal Switch code first — press F5 once more to reach the script entry point. Set breakpoints anywhere in the entry point being debugged.
|
|
56
|
+
|
|
57
|
+
## Critical warning
|
|
58
|
+
|
|
59
|
+
**Disable debug mode in Switch Designer when the debug session is finished.**
|
|
60
|
+
|
|
61
|
+
If left enabled, the flow hangs silently — `jobArrived` leaves jobs stuck in the input folder, other entry points hang with no visible error or indication.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: logs-and-dataroot
|
|
3
|
+
category: switch-project
|
|
4
|
+
order: 19
|
|
5
|
+
summary: "Locating the Application Data Root, querying `ServerLogs.db3` directly"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Diagnosing or validating a script from its actual log output rather than by reading the code"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Locating and Querying Switch's Log Database
|
|
11
|
+
|
|
12
|
+
For diagnosing or validating a script from the outside — reading what the user themselves would see
|
|
13
|
+
in Switch's Message pane — rather than instrumenting the script itself. See
|
|
14
|
+
[logging.md](../switch-api/logging.md) for how a script produces these messages in the first place.
|
|
15
|
+
|
|
16
|
+
## Finding the Application Data Root
|
|
17
|
+
|
|
18
|
+
Switch's application data (including logs) lives under a per-installation "Application Data Root"
|
|
19
|
+
folder, which is configurable and does not always sit at its default location. Resolve it in order:
|
|
20
|
+
|
|
21
|
+
1. Read the `SettingsFolder` value for this Switch Server installation:
|
|
22
|
+
- **macOS:** `defaults read "com.enfocus.Switch Server" SettingsFolder`, or read the plist directly
|
|
23
|
+
at `~/Library/Preferences/com.enfocus.Switch Server.plist`.
|
|
24
|
+
- **Windows:** registry key `HKEY_CURRENT_USER\Software\Enfocus\Switch Server`, value
|
|
25
|
+
`SettingsFolder`.
|
|
26
|
+
2. That value is a folder path. Inside it, open `settingsNew.xml`.
|
|
27
|
+
3. In `settingsNew.xml`, find the `<UserPreference QSettingsKey="ApplicationData/ApplicationDataRoot">`
|
|
28
|
+
element — its text content is the actual configured data root path.
|
|
29
|
+
|
|
30
|
+
Default data root if never changed:
|
|
31
|
+
- **macOS:** `~/Library/Application Support/Enfocus/Switch Server`
|
|
32
|
+
- **Windows:** `%APPDATA%\Enfocus\Switch Server`
|
|
33
|
+
|
|
34
|
+
Don't assume the default — always resolve it via `SettingsFolder` → `settingsNew.xml`, since it can
|
|
35
|
+
be moved to an arbitrary location (via the Application Data Root Tool).
|
|
36
|
+
|
|
37
|
+
## The log database
|
|
38
|
+
|
|
39
|
+
`<data root>/logs/ServerLogs.db3` is a SQLite database and is not itself independently configurable
|
|
40
|
+
— it's always at this fixed path under the data root. It can be queried directly and read-only with
|
|
41
|
+
any SQLite client (e.g. `sqlite3 ServerLogs.db3 "SELECT ..."`) while Switch is running.
|
|
42
|
+
|
|
43
|
+
Relevant columns on the `logmessages` table:
|
|
44
|
+
|
|
45
|
+
| Column | Meaning |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `itemtime` | ISO-8601 timestamp of the log entry |
|
|
48
|
+
| `type` | Log level: `debug`, `info`, `warning`, `error`, `assert` |
|
|
49
|
+
| `module` | The flow element's type/display name |
|
|
50
|
+
| `flow` | The flow name |
|
|
51
|
+
| `element` | The flow element instance's name in that flow |
|
|
52
|
+
| `operation` | The message template, with unresolved `%1`–`%9` placeholders |
|
|
53
|
+
| `arg1`–`arg9` | Substitution values for the placeholders in `operation` |
|
|
54
|
+
| `ticket`, `file` | Job identifier / filename, when the message relates to a specific job |
|
|
55
|
+
|
|
56
|
+
The message text is stored **unresolved** — reconstruct the human-readable message yourself by
|
|
57
|
+
replacing each `%N` in `operation` with the corresponding `argN`. To find a specific script's log
|
|
58
|
+
output, filter on `flow` and `element` (matching the script's flow element name in the canvas) and
|
|
59
|
+
order by `itemtime`.
|
|
60
|
+
|
|
61
|
+
Example: find recent messages for a specific flow element, most recent first —
|
|
62
|
+
|
|
63
|
+
```sql
|
|
64
|
+
SELECT itemtime, type, operation, arg1, arg2, arg3
|
|
65
|
+
FROM logmessages
|
|
66
|
+
WHERE flow = 'MyFlow' AND element = 'MyScriptElement'
|
|
67
|
+
ORDER BY itemtime DESC
|
|
68
|
+
LIMIT 50;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Retention and the debug-level gate
|
|
72
|
+
|
|
73
|
+
- Log messages are pruned after `Logging/KeepLogMessagesForHours` (12 hours by default,
|
|
74
|
+
`settingsNew.xml`) — don't expect old entries to still be present.
|
|
75
|
+
- `LogLevel.Debug` messages from `job.log()`/`flowElement.log()` only reach `ServerLogs.db3` at all
|
|
76
|
+
if the Switch preference `Logging/LogDebugMessages` ("Log debug messages") is enabled — it is
|
|
77
|
+
**off by default** in a typical install and is meant to be turned on when actively debugging. A
|
|
78
|
+
script's `Debug`-level output can be completely absent from the log database even though the
|
|
79
|
+
script correctly calls `job.log(LogLevel.Debug, ...)`; check this preference before concluding a
|
|
80
|
+
script isn't logging.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: node-versions
|
|
3
|
+
category: switch-project
|
|
4
|
+
order: 26
|
|
5
|
+
summary: "How `SwitchVersion` in `manifest.xml` selects the Node.js version, the version table per Switch release, which tools overwrite `SwitchVersion`, values missing from the table, other effects of `SwitchVersion`"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Working out which Node.js version a script or app will run on, or what `SwitchVersion` in manifest.xml does"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Node.js version per Switch version
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
The Switch Server running the script picks its Node.js version by looking up `SwitchVersion` from
|
|
14
|
+
`manifest.xml` in a fixed table that ships with each Switch release:
|
|
15
|
+
|
|
16
|
+
| Switch version | `SwitchVersion` | Node.js used |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| Switch 2020 Spring | `20.0` | 12 |
|
|
19
|
+
| Switch 2020 Fall | `20.1` | 12 |
|
|
20
|
+
| Switch 2021 Spring | `21.0` | 14 |
|
|
21
|
+
| Switch 2021 Fall | `21.1` | 16 |
|
|
22
|
+
| Switch 2022 Spring | `22.0` | 16 |
|
|
23
|
+
| Switch 2022 Fall | `22.1` | 16 |
|
|
24
|
+
| Switch 2023 Fall | `23.1` | 18 |
|
|
25
|
+
| Switch 2024 Spring | `24.0` | 18 |
|
|
26
|
+
| Switch 2024 Fall | `24.1` | 20 |
|
|
27
|
+
| Switch 25.11 | `25.11` | 20 |
|
|
28
|
+
| Switch 26.11 | `26.11` | 24 |
|
|
29
|
+
|
|
30
|
+
Switch 26.11 bundles Node.js 12.22.12, 14.21.3, 16.20.2, 18.20.8, 20.20.0, and 24.13.0.
|
|
31
|
+
|
|
32
|
+
`SwitchVersion` controls the Node.js version only. Which scripting API methods exist depends on the
|
|
33
|
+
Switch version the script runs on, see [api-versions.md](../switch-api/api-versions.md).
|
|
34
|
+
|
|
35
|
+
## What writes `SwitchVersion`
|
|
36
|
+
|
|
37
|
+
`SwitchVersion` is the version of whichever tool last wrote the manifest. It is not a setting the
|
|
38
|
+
author picks:
|
|
39
|
+
|
|
40
|
+
- `SwitchScriptTool --create` writes the tool's own version into the new script folder.
|
|
41
|
+
- `SwitchScriptTool --pack` writes the tool's own version into the packed `.sscript`, whatever the
|
|
42
|
+
script folder's manifest says. The script folder's manifest itself is left unchanged. With
|
|
43
|
+
SwitchScriptTool 26.11, a folder whose manifest says `21.0` packs to a `.sscript` whose manifest
|
|
44
|
+
says `26.11`, which moves the script from Node.js 14 to Node.js 24. This was verified with a
|
|
45
|
+
pre-release SwitchScriptTool build.
|
|
46
|
+
- SwitchScripter writes its own version on every save. Opening a script with a different
|
|
47
|
+
`SwitchVersion` shows a warning that saving updates the script to the current Node.js version.
|
|
48
|
+
|
|
49
|
+
**Gotcha:** a script folder tested directly in Switch and the `.sscript` packed from it can run on
|
|
50
|
+
different Node.js versions. A folder created with an older SwitchScriptTool keeps that tool's
|
|
51
|
+
version, but packing it with a newer SwitchScriptTool stamps the newer one. Test the packed
|
|
52
|
+
`.sscript`, not only the folder, before shipping it.
|
|
53
|
+
|
|
54
|
+
To target an older Node.js version, pack the script with the SwitchScriptTool of a Switch release
|
|
55
|
+
whose row in the table gives that version. For example, a script packed with SwitchScriptTool 25.11
|
|
56
|
+
gets `SwitchVersion` `25.11` and runs on Node.js 20, in Switch 26.11 too. Apps work the same way
|
|
57
|
+
with SwitchScripter, except that there is no SwitchScripter for Switch 25.11. An app that
|
|
58
|
+
needs Node.js 20 is built with the Switch 2024 Fall SwitchScripter (`SwitchVersion` `24.1`), see
|
|
59
|
+
[script-structure.md § SwitchScripter and Switch version compatibility](script-structure.md#switchscripter-and-switch-version-compatibility).
|
|
60
|
+
Editing `SwitchVersion` by hand doesn't last, because `--pack` and SwitchScripter overwrite it.
|
|
61
|
+
|
|
62
|
+
## Values missing from the table
|
|
63
|
+
|
|
64
|
+
Behavior of the Switch 26.11 Server:
|
|
65
|
+
|
|
66
|
+
- No `SwitchVersion` element: treated as `20.1`, so Node.js 12.
|
|
67
|
+
- Lower than the first entry: Node.js 12.
|
|
68
|
+
- Higher than the last entry, for example a package built by a newer tool than the Switch it runs
|
|
69
|
+
on: the newest Node.js that Switch bundles. The Server logs a debug message that the script
|
|
70
|
+
"might not be compatible with the current Switch version" and runs it anyway.
|
|
71
|
+
- **Known issue:** a value that isn't an exact entry but falls numerically between the first and
|
|
72
|
+
last entries matches no Node.js version, for example `25.1` instead of `25.11`, `24.10` instead of
|
|
73
|
+
`24.1`, or `23.0`. The Server then fails to build the path to a Node.js binary, so no executor
|
|
74
|
+
process starts for the script. This was confirmed by running the Switch 26.11 lookup code with
|
|
75
|
+
these values, not by running such a script in Switch, so the exact symptom in Switch hasn't been
|
|
76
|
+
checked. A value such as `26.3` works today only because it's higher than the last entry, and it
|
|
77
|
+
will break once a later release adds an entry above it. Never hand-edit `SwitchVersion`. If you
|
|
78
|
+
must, copy a value exactly as the table above spells it.
|
|
79
|
+
|
|
80
|
+
## Other effects of `SwitchVersion`
|
|
81
|
+
|
|
82
|
+
- npm dependencies that are ES modules are bundled with esbuild before execution only when
|
|
83
|
+
`SwitchVersion` is `24.0` or higher.
|
|
84
|
+
- A script expression has no manifest. It always runs on the newest Node.js the running Switch
|
|
85
|
+
bundles.
|
|
86
|
+
|
|
87
|
+
> **Mac (Apple Silicon):** For scripts whose `SwitchVersion` is `21.1` (Switch 2021 Fall) or later, Switch runs the native ARM build of Node.js on Apple Silicon. Scripts with an earlier `SwitchVersion` run under Rosetta, because the bundled Node.js 12 and 14 are Intel-only builds. If a script bundles platform-specific binaries, ship both Intel and ARM variants.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: project-planning
|
|
3
|
+
category: switch-project
|
|
4
|
+
order: 1
|
|
5
|
+
summary: "Planning checklist, run before scaffolding or on a project that is already scaffolded: Script vs App, job-processing approach, one script folder or several, target OS, Switch version baseline, concurrency, native/binary npm dependencies, Appstore competition risk"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Starting a new script or app, before scaffolding any files, or working in a script folder that is already scaffolded where Script vs App has not been settled"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Project Planning
|
|
11
|
+
|
|
12
|
+
A planning checklist for a new script or app. Work through this with the user before
|
|
13
|
+
creating any files.
|
|
14
|
+
|
|
15
|
+
A script folder that already exists (scaffolded by the user, SwitchScripter, or `SwitchScriptTool
|
|
16
|
+
--create`) does not skip the checklist. The manifest's `ScriptPackageType` is always `Script` in a
|
|
17
|
+
scaffolded folder, so it does not answer item 1. Ask Script or App anyway, and run the other
|
|
18
|
+
checks against the code that exists. The goal is to make a few decisions deliberately up front, because retrofitting
|
|
19
|
+
them after code exists is expensive: password protection and localization for an app, path handling
|
|
20
|
+
for a second target OS, synchronizing shared-resource access for concurrency, or restructuring entry
|
|
21
|
+
points around a job-processing approach chosen too casually.
|
|
22
|
+
|
|
23
|
+
Two items below are direct questions for the user. The rest are not questions to ask upfront; they
|
|
24
|
+
are checks the agent runs against what's actually being built, raised only when they become
|
|
25
|
+
relevant.
|
|
26
|
+
|
|
27
|
+
<!-- docs-index:contents begin -->
|
|
28
|
+
## Contents
|
|
29
|
+
|
|
30
|
+
- Ask the user directly
|
|
31
|
+
- 1. Script or App?
|
|
32
|
+
- 2. What should job processing look like in their flow?
|
|
33
|
+
- Evaluate and flag, don't ask upfront
|
|
34
|
+
- One script folder or several
|
|
35
|
+
- Target OS
|
|
36
|
+
- Switch version baseline (apps only)
|
|
37
|
+
- Concurrency
|
|
38
|
+
- Native or binary npm dependencies
|
|
39
|
+
- Appstore competition risk (apps only)
|
|
40
|
+
<!-- docs-index:contents end -->
|
|
41
|
+
|
|
42
|
+
## Ask the user directly
|
|
43
|
+
|
|
44
|
+
### 1. Script or App?
|
|
45
|
+
|
|
46
|
+
Ask whether this is for private or internal use (a plain `Script`, distributed freely) or intended
|
|
47
|
+
for the Enfocus Appstore (an `App`). See
|
|
48
|
+
[script-structure.md § Script vs App](script-structure.md#script-vs-app) for what differs.
|
|
49
|
+
|
|
50
|
+
This answer gates several items below:
|
|
51
|
+
|
|
52
|
+
- **App**: localization, password protection, `Name`-never-changes discipline, `Concurrent`-by-default
|
|
53
|
+
expectation, icon/keywords, and the version-baseline and Appstore-competition checks further down
|
|
54
|
+
all apply. See [app-guidelines.md](../switch-appstore/app-guidelines.md) for the full pre-publish checklist,
|
|
55
|
+
most of which is worth designing toward from the start rather than retrofitting later.
|
|
56
|
+
- **Script**: none of the app-only items apply. Keep it simple and don't raise app concerns for a
|
|
57
|
+
plain script.
|
|
58
|
+
|
|
59
|
+
If App, also ask which languages it must support. English is required; more than one language is
|
|
60
|
+
preferable, see [app-guidelines.md § Localization](../switch-appstore/app-guidelines.md#localization).
|
|
61
|
+
|
|
62
|
+
### 2. What should job processing look like in their flow?
|
|
63
|
+
|
|
64
|
+
Ask about job handling at a functional level: what should happen when a job arrives, does anything
|
|
65
|
+
need to wait on an external process or resource, could more than one job at a time contend for a
|
|
66
|
+
shared resource. Don't ask the user to pick entry points or connection types directly. Translate the
|
|
67
|
+
answer into a concrete proposal (which entry points, which `sendTo*()` methods, whether `jobArrived`
|
|
68
|
+
alone is enough or work must be deferred to `timerFired`) using
|
|
69
|
+
[entry-points.md](../switch-api/entry-points.md) and
|
|
70
|
+
[job-patterns.md § Sending jobs](../switch-api/job-patterns.md#sending-jobs), and be upfront about
|
|
71
|
+
limitations and tradeoffs so the user can make an informed choice, rather than silently picking an
|
|
72
|
+
approach.
|
|
73
|
+
|
|
74
|
+
If the design defers job processing to `timerFired` via global data, say explicitly that a flow
|
|
75
|
+
restart replays every queued job through `jobArrived` again, and the script must recognize and skip
|
|
76
|
+
an already-registered job quickly, or a large backlog is slow to clear, see
|
|
77
|
+
[entry-points.md § Job processing](../switch-api/entry-points.md#job-processing).
|
|
78
|
+
|
|
79
|
+
## Evaluate and flag, don't ask upfront
|
|
80
|
+
|
|
81
|
+
### One script folder or several
|
|
82
|
+
|
|
83
|
+
One script folder produces one flow element. Once the job-processing design from question 2 is
|
|
84
|
+
clear, check whether it needs more than one flow element: distinct steps a flow builder should
|
|
85
|
+
place and configure as separate elements, or several related apps meant to ship as an app bundle.
|
|
86
|
+
Most designs need one, so don't ask about this upfront.
|
|
87
|
+
|
|
88
|
+
If the design needs several, propose the split before creating any files: the Script ID and
|
|
89
|
+
purpose of each script folder and, for apps, whether they form an app bundle. Wait for the user to
|
|
90
|
+
confirm. Then lay them out and create them as described in
|
|
91
|
+
[script-structure.md § Several script folders side by side](script-structure.md#several-script-folders-side-by-side).
|
|
92
|
+
|
|
93
|
+
### Target OS
|
|
94
|
+
|
|
95
|
+
Switch Server runs on Windows and macOS. Default to writing platform-independent code (the `path`
|
|
96
|
+
module, no hardcoded separators, see
|
|
97
|
+
[job-patterns.md § Platform-independent paths](../switch-api/job-patterns.md#platform-independent-paths))
|
|
98
|
+
without asking. Only raise target OS as an explicit question once the script needs OS-specific code,
|
|
99
|
+
bundles a native binary, or ships a platform-specific package build, since only then does the answer
|
|
100
|
+
change anything.
|
|
101
|
+
|
|
102
|
+
### Switch version baseline (apps only)
|
|
103
|
+
|
|
104
|
+
Once Script vs App is answered as App, ask or infer the oldest Switch version the app must support.
|
|
105
|
+
This sets two separate limits:
|
|
106
|
+
|
|
107
|
+
- Which SwitchScripter build is needed to produce a compatible `.enfpack`, and so which Node.js
|
|
108
|
+
version the app runs on (see
|
|
109
|
+
[node-versions.md](node-versions.md)).
|
|
110
|
+
Write code for that Node.js version.
|
|
111
|
+
- Which scripting API methods the code may call. Methods follow the Switch version the app runs on,
|
|
112
|
+
so check every call against [api-versions.md](../switch-api/api-versions.md) for the oldest
|
|
113
|
+
supported version.
|
|
114
|
+
|
|
115
|
+
Don't ask this for a plain script. Assume it runs on the Switch version whose SwitchScriptTool packs
|
|
116
|
+
it (`SwitchScriptTool --version`), unless the user mentions an older Switch Server.
|
|
117
|
+
|
|
118
|
+
### Concurrency
|
|
119
|
+
|
|
120
|
+
Default to `Concurrent` execution; it's the preferred choice for apps per
|
|
121
|
+
[app-guidelines.md § Top-level declaration properties](../switch-appstore/app-guidelines.md#top-level-declaration-properties).
|
|
122
|
+
Don't ask the user to choose upfront. Only raise `Serialized`, and explain why, when the design has
|
|
123
|
+
an actual reason to need it: a third-party application or shared resource that can't tolerate
|
|
124
|
+
concurrent access, or an API the script drives that isn't safe to call in parallel. See
|
|
125
|
+
[execution-environment.md § Execution modes](../switch-api/execution-environment.md#execution-modes).
|
|
126
|
+
|
|
127
|
+
### Native or binary npm dependencies
|
|
128
|
+
|
|
129
|
+
A file-based script or app that ends up on the ESM bundling path cannot use native (binary) Node
|
|
130
|
+
addons at all, see
|
|
131
|
+
[execution-environment.md § Native (binary) addons are not supported](../switch-api/execution-environment.md#native-binary-addons-are-not-supported).
|
|
132
|
+
If a planned dependency needs one, for example `sharp` or native `sqlite3` bindings, say so before
|
|
133
|
+
the user commits to that library, and suggest a pure JavaScript alternative or a workaround, such as
|
|
134
|
+
shelling out to an external binary, see
|
|
135
|
+
[job-patterns.md § Driving a third-party CLI application](../switch-api/job-patterns.md#driving-a-third-party-cli-application),
|
|
136
|
+
where one exists.
|
|
137
|
+
|
|
138
|
+
### Appstore competition risk (apps only)
|
|
139
|
+
|
|
140
|
+
An app whose core functionality duplicates an existing Switch module without requiring that module
|
|
141
|
+
risks Appstore rejection. For example, an app that performs database CRUD operations without
|
|
142
|
+
requiring the Database Module competes directly with it. If the planned app looks like it falls into
|
|
143
|
+
this category, say so before significant effort is spent, and suggest either gating the app behind
|
|
144
|
+
the relevant module license or contacting Enfocus to check before proceeding.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
This checklist stops at planning. Once these are answered, move to
|
|
149
|
+
[script-structure.md](script-structure.md) to scaffold the project.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: property-documentation
|
|
3
|
+
category: switch-project
|
|
4
|
+
order: 21
|
|
5
|
+
summary: "Writing guidance for `Tooltip` and `DetailedInfo` content on properties/connections"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Writing or reviewing the text in a property's or connection's `Tooltip`/`DetailedInfo`"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Writing Property and Connection Documentation
|
|
11
|
+
|
|
12
|
+
Guidance for the *content* of `Tooltip` and `DetailedInfo` on properties and connections — see
|
|
13
|
+
[script-declaration.md](script-declaration.md#custom-property-elements-elementfields) for
|
|
14
|
+
the attribute mechanics (when each is required, what breaks if omitted). This page covers what to
|
|
15
|
+
actually write in them.
|
|
16
|
+
|
|
17
|
+
Both attributes are read only inside Switch Designer, by someone who has already added the flow
|
|
18
|
+
element to a flow. Compare with [app-store-listing.md](../switch-appstore/app-store-listing.md), read by
|
|
19
|
+
someone deciding whether to install the app at all, and [app-manual.md](../switch-appstore/app-manual.md), a
|
|
20
|
+
separate uploaded document.
|
|
21
|
+
|
|
22
|
+
**Delivery:** write this content directly into the `Tooltip`/`DetailedInfo` attributes in
|
|
23
|
+
`<ScriptID>.xml` — there is no separate file. See
|
|
24
|
+
[script-declaration.md § Agent editing policy](script-declaration.md#agent-editing-policy)
|
|
25
|
+
for how to edit the declaration safely.
|
|
26
|
+
|
|
27
|
+
## Tooltip
|
|
28
|
+
|
|
29
|
+
The one-line hint shown in the Properties pane. This is the field that matters most here — it's
|
|
30
|
+
always visible to whoever is configuring the property, connection, or the app's own icon, with no
|
|
31
|
+
extra click required.
|
|
32
|
+
|
|
33
|
+
- Add information the property name doesn't already give: units, valid range, format, or an
|
|
34
|
+
example value. A tooltip that just restates the label ("Output folder: the output folder to
|
|
35
|
+
use") wastes the one line a user reliably reads.
|
|
36
|
+
- If no sensible default is possible, put an example value in the tooltip — see the `Default`
|
|
37
|
+
guideline in [script-declaration.md](script-declaration.md#custom-property-elements-elementfields).
|
|
38
|
+
- Sentence-style capitalization, no trailing period, one line. Match the style already used in
|
|
39
|
+
declarations: `Tooltip="Select the output folder"`.
|
|
40
|
+
- Skip it only when the property is genuinely self-explanatory from its name alone, with no
|
|
41
|
+
constraints worth stating (e.g. "Number of copies" with no min/max).
|
|
42
|
+
|
|
43
|
+
## DetailedInfo
|
|
44
|
+
|
|
45
|
+
Feeds the HTML documentation Switch Designer can export for a whole *flow* — not something
|
|
46
|
+
specific to this app, it's compiled from every element the flow builder happens to have placed in
|
|
47
|
+
that flow. Real, but low priority in practice: it's an opt-in export most flow builders never
|
|
48
|
+
generate, and plenty of shipped apps leave it blank. Don't treat an empty `DetailedInfo` as a
|
|
49
|
+
defect to pad out.
|
|
50
|
+
|
|
51
|
+
Fill it in when the tooltip's one line genuinely isn't enough — an interaction with another
|
|
52
|
+
property, an edge case worth flagging, or why a setting matters, not a restatement of the tooltip
|
|
53
|
+
in longer sentences. A trivial property with `DetailedInfo=""` is expected and fine.
|
|
54
|
+
|
|
55
|
+
If you do write `DetailedInfo`, don't rely on it being the only place that content exists — the
|
|
56
|
+
property's fuller description belongs in [app-manual.md](../switch-appstore/app-manual.md#properties-detailed-info)
|
|
57
|
+
regardless, since that document is far more likely to actually be read.
|
|
58
|
+
|
|
59
|
+
## Writing quality
|
|
60
|
+
|
|
61
|
+
Applies to both fields, and is the same bar [app-store-listing.md](../switch-appstore/app-store-listing.md)
|
|
62
|
+
and [app-manual.md](../switch-appstore/app-manual.md) hold their content to:
|
|
63
|
+
|
|
64
|
+
- **Don't restate the field name.** A tooltip on "Output folder" that says "The output folder"
|
|
65
|
+
adds nothing a user didn't already know.
|
|
66
|
+
- **No generic AI/marketing vocabulary** — powerful, seamless, robust, intuitive, and similar
|
|
67
|
+
words that could describe any property in any app. Say the specific thing this one does.
|
|
68
|
+
- **No meta-commentary about the implementation.** Write what the user sees or does, not how the
|
|
69
|
+
script is coded internally ("this property is passed to the internal handler").
|
|
70
|
+
- **No vague filler.** "Set this to an appropriate value" tells a user nothing; a concrete unit,
|
|
71
|
+
range, or example does.
|
|
72
|
+
- **No copy-pasted boilerplate across properties.** Identical tooltip text reused on unrelated
|
|
73
|
+
properties signals nobody thought about the individual property.
|
|
74
|
+
- **Keep it translatable.** Idioms and culture-specific references don't translate cleanly into
|
|
75
|
+
the six Switch languages — see [switch.md § Translation extraction rules](../switch-api/switch.md#translation-extraction-rules).
|