@enfocussw/switch-scripting-context 25.11.0-beta.14 → 25.11.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/README.md +26 -22
  3. package/dist/init.d.ts +1 -1
  4. package/dist/init.js +18 -7
  5. package/docs/switch-api/{api-connection.md → connection.md} +2 -2
  6. package/docs/switch-api/{api-document-classes.md → document-classes.md} +1 -1
  7. package/docs/switch-api/{api-entry-points.md → entry-points.md} +5 -5
  8. package/docs/switch-api/{api-execution-environment.md → execution-environment.md} +7 -7
  9. package/docs/switch-api/{api-flow-element.md → flow-element.md} +4 -4
  10. package/docs/switch-api/{api-job-patterns.md → job-patterns.md} +8 -8
  11. package/docs/switch-api/{api-job.md → job.md} +4 -4
  12. package/docs/switch-api/{api-logging.md → logging.md} +6 -6
  13. package/docs/switch-api/{api-switch.md → switch.md} +1 -1
  14. package/docs/{switch-api/api-app-guidelines.md → switch-appstore/app-guidelines.md} +41 -33
  15. package/docs/switch-appstore/app-manual.md +75 -0
  16. package/docs/switch-appstore/app-store-listing.md +60 -0
  17. package/docs/switch-appstore/app-store-submission.md +74 -0
  18. package/docs/{switch-api/api-logs-and-dataroot.md → switch-project/logs-and-dataroot.md} +1 -1
  19. package/docs/{switch-api/api-project-planning.md → switch-project/project-planning.md} +13 -13
  20. package/docs/switch-project/property-documentation.md +66 -0
  21. package/docs/{switch-api/api-property-editors.md → switch-project/property-editors.md} +10 -10
  22. package/docs/{switch-api/api-script-declaration.md → switch-project/script-declaration.md} +9 -9
  23. package/docs/{switch-api/api-script-structure.md → switch-project/script-structure.md} +5 -5
  24. package/docs/{switch-api/api-tooling.md → switch-project/tooling.md} +1 -1
  25. package/docs/switch-scripting.md +32 -27
  26. package/package.json +1 -1
  27. /package/docs/switch-api/{api-enums.md → enums.md} +0 -0
  28. /package/docs/switch-api/{api-http.md → http.md} +0 -0
  29. /package/docs/{switch-api/api-debugging.md → switch-project/debugging.md} +0 -0
  30. /package/docs/{switch-api/api-vscode.md → switch-project/vscode.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -3,7 +3,27 @@
3
3
  All notable changes to this package are documented here. Format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
- ## [Unreleased]
6
+ ## [25.11.0-beta.15] - 2026-09-10
7
+
8
+ ### Added
9
+ - `property-documentation.md`, `app-store-listing.md`, `app-manual.md`, and
10
+ `app-store-submission.md`: writing guidance for the four separate places app documentation
11
+ ends up (per-property `Tooltip`/`DetailedInfo`, the declaration's listing fields, the uploaded
12
+ app manual document, and the Appstore website submission forms), including which content is
13
+ reused between them, icon specs, and a shared checklist against generic-sounding text.
14
+
15
+ ### Changed
16
+ - Docs reorganized under `docs/`: the scripting API stays in `docs/switch-api/`; project structure
17
+ and tooling docs moved to `docs/switch-project/`; Appstore publishing guidance moved to
18
+ `docs/switch-appstore/`. Update any bookmarked doc paths after upgrading.
19
+ - Dropped the `api-` prefix from doc filenames, for example `switch-api/job.md`, since each file's
20
+ folder already says what kind of doc it is.
21
+
22
+ ### Fixed
23
+ - `init` now removes the destination docs folder before copying, instead of only adding and
24
+ overwriting. Previously, a doc renamed or moved between versions left the old file behind
25
+ permanently after an upgrade, since the destination folder is gitignored and nothing surfaced
26
+ the stale copy.
7
27
 
8
28
  ## [25.11.0-beta.14] - 2026-09-09
9
29
 
package/README.md CHANGED
@@ -4,7 +4,7 @@ AI coding assistant context for [Enfocus Switch](https://www.enfocus.com/en/swit
4
4
 
5
5
  Installs curated API reference docs and generates config files for 8 AI coding agents (Claude Code, GitHub Copilot, Cursor, Codex CLI/OpenCode, Gemini CLI, Windsurf, Zed, and Cline) so AI assistants understand the Switch scripting API out of the box.
6
6
 
7
- See [CHANGELOG.md](https://cdn.jsdelivr.net/npm/@enfocussw/switch-scripting-context@25.11.0-beta.14/CHANGELOG.md) (also included in this package) for what's changed between versions.
7
+ See [CHANGELOG.md](https://cdn.jsdelivr.net/npm/@enfocussw/switch-scripting-context@25.11.0-beta.15/CHANGELOG.md) (also included in this package) for what's changed between versions.
8
8
 
9
9
  ## Usage
10
10
 
@@ -84,7 +84,7 @@ A few things this gets you without asking for them by name:
84
84
  properties (app path/licence) are off-limits and left to SwitchScripter's GUI instead.
85
85
 
86
86
  Re-run `init` after upgrading this package so the copied docs and generated config files catch up.
87
- See [CHANGELOG.md](https://cdn.jsdelivr.net/npm/@enfocussw/switch-scripting-context@25.11.0-beta.14/CHANGELOG.md) for what changed.
87
+ See [CHANGELOG.md](https://cdn.jsdelivr.net/npm/@enfocussw/switch-scripting-context@25.11.0-beta.15/CHANGELOG.md) for what changed.
88
88
 
89
89
  ## Options
90
90
 
@@ -131,23 +131,27 @@ npm install --save-dev "https://github.com/enfocus-switch/types-switch-scripting
131
131
  The `switch-docs/` folder contains:
132
132
 
133
133
  - `switch-scripting.md`: master index with execution environment rules and "load when" routing table
134
- - `switch-api/api-project-planning.md`: pre-scaffolding checklist covering Script vs App, job-processing approach, target OS, Switch version baseline, concurrency, native/binary npm dependencies, Appstore competition risk
135
- - `switch-api/api-entry-points.md`: all entry point signatures and when each is called
136
- - `switch-api/api-job.md`: `Job` class signatures for routing, file access, child jobs, private data, datasets
137
- - `switch-api/api-flow-element.md`: `FlowElement`: properties, connections, job creation, logging
138
- - `switch-api/api-switch.md`: `Switch` global: global data, webhooks, abort, server utilities
139
- - `switch-api/api-connection.md`: `Connection`: type, properties, file count
140
- - `switch-api/api-http.md`: `HttpRequest` / `HttpResponse` and webhook pattern
141
- - `switch-api/api-enums.md`: all enums with string values (`LogLevel`, `AccessLevel`, `Scope`, etc.)
142
- - `switch-api/api-document-classes.md`: `PdfDocument`, `ImageDocument`, `XmlDocument`, `XmpDocument`
143
- - `switch-api/api-script-declaration.md`: XML declaration reference
144
- - `switch-api/api-script-structure.md`: script folder contents, manifest format, Node.js version per Switch release, Script vs App
145
- - `switch-api/api-tooling.md`: SwitchScriptTool commands, script folder vs package, build and deployment
146
- - `switch-api/api-debugging.md`: enabling debug mode, debuggable entry points, VS Code attach
147
- - `switch-api/api-logging.md`: log levels, when/what to log, `console.log` limitation, common gotchas
148
- - `switch-api/api-logs-and-dataroot.md`: locating the application data root, querying `ServerLogs.db3` directly to diagnose a script
149
- - `switch-api/api-vscode.md`: type declarations, tsconfig for TypeScript 6, ESLint rules
150
- - `switch-api/api-property-editors.md`: property editor types and string return values
151
- - `switch-api/api-job-patterns.md`: `Job` rules and gotchas covering file access semantics, temp cleanup, routing rules, child jobs, executor limits
152
- - `switch-api/api-execution-environment.md`: execution modes, process model, state persistence across jobs, error handling, npm/native module constraints
153
- - `switch-api/api-app-guidelines.md`: pre-publish checklist for Appstore apps covering property naming/tooltips/editors, entry point and sendTo consistency, logging quality, packaging, app-only submission rules
134
+ - `switch-project/project-planning.md`: pre-scaffolding checklist covering Script vs App, job-processing approach, target OS, Switch version baseline, concurrency, native/binary npm dependencies, Appstore competition risk
135
+ - `switch-api/entry-points.md`: all entry point signatures and when each is called
136
+ - `switch-api/job.md`: `Job` class signatures for routing, file access, child jobs, private data, datasets
137
+ - `switch-api/flow-element.md`: `FlowElement`: properties, connections, job creation, logging
138
+ - `switch-api/switch.md`: `Switch` global: global data, webhooks, abort, server utilities
139
+ - `switch-api/connection.md`: `Connection`: type, properties, file count
140
+ - `switch-api/http.md`: `HttpRequest` / `HttpResponse` and webhook pattern
141
+ - `switch-api/enums.md`: all enums with string values (`LogLevel`, `AccessLevel`, `Scope`, etc.)
142
+ - `switch-api/document-classes.md`: `PdfDocument`, `ImageDocument`, `XmlDocument`, `XmpDocument`
143
+ - `switch-project/script-declaration.md`: XML declaration reference
144
+ - `switch-project/script-structure.md`: script folder contents, manifest format, Node.js version per Switch release, Script vs App
145
+ - `switch-project/tooling.md`: SwitchScriptTool commands, script folder vs package, build and deployment
146
+ - `switch-project/debugging.md`: enabling debug mode, debuggable entry points, VS Code attach
147
+ - `switch-api/logging.md`: log levels, when/what to log, `console.log` limitation, common gotchas
148
+ - `switch-project/logs-and-dataroot.md`: locating the application data root, querying `ServerLogs.db3` directly to diagnose a script
149
+ - `switch-project/vscode.md`: type declarations, tsconfig for TypeScript 6, ESLint rules
150
+ - `switch-project/property-editors.md`: property editor types and string return values
151
+ - `switch-api/job-patterns.md`: `Job` rules and gotchas covering file access semantics, temp cleanup, routing rules, child jobs, executor limits
152
+ - `switch-api/execution-environment.md`: execution modes, process model, state persistence across jobs, error handling, npm/native module constraints
153
+ - `switch-appstore/app-guidelines.md`: pre-publish checklist for Appstore apps covering property naming/tooltips/editors, entry point and sendTo consistency, logging quality, packaging, app-only submission rules
154
+ - `switch-project/property-documentation.md`: writing guidance for `Tooltip` and `DetailedInfo` content on properties and connections
155
+ - `switch-appstore/app-store-listing.md`: writing guidance for the Appstore listing fields (`Description`, `Compatibility`, `SupportInfo`, `AppDiscovery`, `Connections`)
156
+ - `switch-appstore/app-manual.md`: writing guidance for the separate app manual document uploaded during Appstore review
157
+ - `switch-appstore/app-store-submission.md`: writing guidance for the Appstore website submission forms (Short Description, What's new, Eula, icon specs)
package/dist/init.d.ts CHANGED
@@ -10,7 +10,7 @@ export interface ToolDefinition {
10
10
  files: ToolFile[];
11
11
  }
12
12
  export interface ApiDoc {
13
- /** Filename within docs/switch-api/, e.g. "api-job.md". */
13
+ /** Path within docs/, e.g. "switch-api/job.md". */
14
14
  file: string;
15
15
  /** The routing table's "Load when" text, verbatim. */
16
16
  loadWhen: string;
package/dist/init.js CHANGED
@@ -64,10 +64,10 @@ function parseRoutingTable(root = packageRoot()) {
64
64
  const hub = fs.readFileSync(path.join(root, 'docs', 'switch-scripting.md'), 'utf8');
65
65
  const docs = [];
66
66
  for (const line of hub.split('\n')) {
67
- // | `switch-api/<file>.md` | <contents> | <load when> |
68
- const m = /^\|\s*`switch-api\/(api-[a-z0-9-]+\.md)`\s*\|(.*)\|(.*)\|\s*$/.exec(line);
67
+ // | `<switch-api|switch-project|switch-appstore>/<file>.md` | <contents> | <load when> |
68
+ const m = /^\|\s*`(switch-api|switch-project|switch-appstore)\/([a-z0-9-]+\.md)`\s*\|(.*)\|(.*)\|\s*$/.exec(line);
69
69
  if (m)
70
- docs.push({ file: m[1], loadWhen: m[3].trim() });
70
+ docs.push({ file: `${m[1]}/${m[2]}`, loadWhen: m[4].trim() });
71
71
  }
72
72
  if (docs.length === 0) {
73
73
  throw new Error('No API docs found in docs/switch-scripting.md — the routing table format changed. ' +
@@ -82,11 +82,11 @@ function apiFiles(root) {
82
82
  const INLINE_CORE_RULES = `## Core rules
83
83
 
84
84
  - Entry point functions are top-level async functions — do NOT use \`export\`, arrow functions, or class methods; declare them with the literal \`function\` keyword.
85
- - Switch finds entry points with a regex, not a parser. Never write a string literal whose content ends with a backslash, a regex literal, or division outside the plain \`word / word\` shape — each silently deletes a span of real code and the entry points inside it, with no error. Read \`api-entry-points.md\` § Entry-point scanner constraints before editing \`main.ts\`/\`main.js\`.
85
+ - Switch finds entry points with a regex, not a parser. Never write a string literal whose content ends with a backslash, a regex literal, or division outside the plain \`word / word\` shape — each silently deletes a span of real code and the entry points inside it, with no error. Read \`entry-points.md\` § Entry-point scanner constraints before editing \`main.ts\`/\`main.js\`.
86
86
  - Every \`jobArrived\` must end with exactly one \`job.sendTo*()\` or \`job.fail()\`.
87
87
  - Use \`AccessLevel.ReadOnly\` for \`job.get()\` unless the file content will be modified.
88
88
  - After \`createJob()\`, \`createChild()\`, or \`createDataset()\` with a file path, delete the source file after routing — Switch does not auto-remove it.
89
- - The XML declaration (\`<ScriptID>.xml\`) can be edited directly — read \`api-script-declaration.md\` first and follow its rules exactly (nothing validates this format, so mistakes fail silently). Never change an existing script's \`Name\`; bump \`Version\` on every declaration edit. Leave \`manifest.xml\` to the user unless explicitly asked.
89
+ - The XML declaration (\`<ScriptID>.xml\`) can be edited directly — read \`script-declaration.md\` first and follow its rules exactly (nothing validates this format, so mistakes fail silently). Never change an existing script's \`Name\`; bump \`Version\` on every declaration edit. Leave \`manifest.xml\` to the user unless explicitly asked.
90
90
  - After editing \`main.ts\`, transpile with \`SwitchScriptTool --transpile <folder>\` — do not use \`tsc\` directly.
91
91
  - Never use a script folder in production — pack with \`SwitchScriptTool --pack\` first; folders are excluded from flow exports.`;
92
92
  // ─── Content generators ──────────────────────────────────────────────────────
@@ -140,7 +140,7 @@ ${MARKER_END}`;
140
140
  // ─── Inline block (for tools without @file import support) ──────────────────
141
141
  function inlineApiFileList(docsDir) {
142
142
  return parseRoutingTable()
143
- .map(d => `- \`${docsDir}/switch-api/${d.file}\` — ${d.loadWhen}`)
143
+ .map(d => `- \`${docsDir}/${d.file}\` — ${d.loadWhen}`)
144
144
  .join('\n');
145
145
  }
146
146
  function generateInlineBlock(docsDir) {
@@ -337,10 +337,21 @@ function applyFileAction(action, dryRun) {
337
337
  const DOCS_EXCLUDE = ['superpowers', 'temp'];
338
338
  function copyDocs(packageRoot, destDir, dryRun) {
339
339
  const src = path.join(packageRoot, 'docs');
340
+ const rel = path.relative(process.cwd(), destDir);
340
341
  if (dryRun) {
341
- console.log(` [dry-run] Copying docs/ → ${path.relative(process.cwd(), destDir)}/`);
342
+ if (fs.existsSync(destDir)) {
343
+ console.log(` [dry-run] ${rel}/ → wiped (removes files from a previous version, e.g. after a doc was renamed or moved)`);
344
+ }
345
+ console.log(` [dry-run] Copying docs/ → ${rel}/`);
342
346
  return;
343
347
  }
348
+ // destDir is entirely owned by this tool (see the .gitignore comment it writes), so wiping
349
+ // it first is safe. Without this, a doc renamed or moved between versions (e.g. a docs/
350
+ // folder restructuring) would leave the old file behind forever: cpSync only adds/overwrites,
351
+ // it never removes, and destDir is gitignored so nothing would surface the staleness.
352
+ if (fs.existsSync(destDir)) {
353
+ fs.rmSync(destDir, { recursive: true, force: true });
354
+ }
344
355
  // The published tarball already omits these, but init may run from a git clone.
345
356
  fs.cpSync(src, destDir, {
346
357
  recursive: true,
@@ -21,12 +21,12 @@ Connection type. One of: `"Move"`, `"Filter"`, `"Traffic-data"`, `"Traffic-log"`
21
21
 
22
22
  ## Connection properties
23
23
 
24
- Connection properties are declared in the script's XML declaration (`ConnectionFields`) and configured per-connection in the canvas. See [api-script-declaration.md](api-script-declaration.md) for how to declare them (via SwitchScripter).
24
+ 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).
25
25
 
26
26
  ```ts
27
27
  connection.getPropertyStringValue(tag: string): Promise<string | string[]>
28
28
  ```
29
- 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 [api-script-declaration.md § Dependency](api-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.
29
+ 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.
30
30
 
31
31
  ```ts
32
32
  connection.getPropertyType(tag: string): PropertyType
@@ -121,7 +121,7 @@ img.getSamplesPerPixel(): number
121
121
  ImageDocument.getSamplesPerPixel(path: string): Promise<number>
122
122
  ```
123
123
 
124
- See [api-enums.md](api-enums.md) for `ImageDocument.ColorMode` and `ImageDocument.ColorSpace` values.
124
+ See [enums.md](enums.md) for `ImageDocument.ColorMode` and `ImageDocument.ColorSpace` values.
125
125
 
126
126
  ---
127
127
 
@@ -47,7 +47,7 @@ or warn about any of this — a script that packs cleanly can still fail to load
47
47
  extraction — if another valid entry point is also present the script packs and loads without
48
48
  error, the misnamed function just never runs.
49
49
 
50
- See [api-tooling.md § Verify entry points before packing](api-tooling.md#verify-entry-points-before-packing)
50
+ See [tooling.md § Verify entry points before packing](../switch-project/tooling.md#verify-entry-points-before-packing)
51
51
  for a script to catch this before it reaches Switch.
52
52
 
53
53
  ## Flow lifecycle
@@ -83,7 +83,7 @@ Called when a job arrives. Must eventually call a `job.sendTo*()` or `job.fail()
83
83
  `jobArrived` and `timerFired` presence must match the declared connections — present when
84
84
  `IncomingConnections="Yes"` (`timerFired` may additionally be present); when
85
85
  `IncomingConnections="No"`, `timerFired` must be present instead. See
86
- [api-script-declaration.md](api-script-declaration.md#built-in-elementfields). Never leave an empty
86
+ [script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields). Never leave an empty
87
87
  `jobArrived` or `timerFired` in the script — remove the function entirely if it does nothing.
88
88
 
89
89
  **Gotcha: a flow restart replays every queued job through `jobArrived` again.** This includes a job
@@ -129,7 +129,7 @@ async function getLibraryForProperty(s: Switch, flowElement: FlowElement, tag: s
129
129
  ```
130
130
  Returns a dynamic list of values for a property's library dropdown. Mandatory if any property uses
131
131
  the `askplugin`/`askplugin2` editor (see
132
- [api-property-editors.md](api-property-editors.md#modal-editors)). Log an error via `flowElement.log()`
132
+ [property-editors.md](../switch-project/property-editors.md#modal-editors)). Log an error via `flowElement.log()`
133
133
  if the list would otherwise come back empty, so the user can see why the dropdown has nothing in it.
134
134
 
135
135
  ```ts
@@ -143,7 +143,7 @@ async function validateProperties(s: Switch, flowElement: FlowElement, tags: str
143
143
  ```
144
144
  Validates one or more property values. Return one result object per tag. Mandatory if any property
145
145
  declares `Validation="Custom"` or `"Standard and custom"` (see
146
- [api-script-declaration.md](api-script-declaration.md#custom-property-elements-elementfields)). Log
146
+ [script-declaration.md](../switch-project/script-declaration.md#custom-property-elements-elementfields)). Log
147
147
  an error via `flowElement.log()` for any tag returned with `valid: false`, so the user sees why.
148
148
 
149
149
  ```ts
@@ -157,4 +157,4 @@ async function findExternalEditorPath(s: Switch, flowElement: FlowElement, tag:
157
157
  ```
158
158
  Resolves the path to an external editor for a property. Required whenever the
159
159
  `external`/`external2`/… editor is used, unless the dependent `Application` property is non-empty —
160
- see [api-property-editors.md § Notes](api-property-editors.md#notes).
160
+ see [property-editors.md § Notes](../switch-project/property-editors.md#notes).
@@ -7,7 +7,7 @@ configures — understanding them avoids subtle bugs around state persistence an
7
7
  ## Execution modes
8
8
 
9
9
  Set in the XML declaration via SwitchScripter, or by editing it directly (see
10
- [api-script-declaration.md](api-script-declaration.md#built-in-elementfields)). Applies to all
10
+ [script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields)). Applies to all
11
11
  instances of the script.
12
12
 
13
13
  **Concurrent** — entry points for the same or different instances may run in parallel. Scripts must
@@ -39,7 +39,7 @@ them:
39
39
  whichever pooled executor is free (or a new one is spawned if none are); executors are reused
40
40
  across many jobs and across different flow elements running the same Node.js version, until
41
41
  recycled (see
42
- [Executor cleanup thresholds](api-job-patterns.md#executor-cleanup-thresholds)).
42
+ [Executor cleanup thresholds](job-patterns.md#executor-cleanup-thresholds)).
43
43
 
44
44
  ## Module-level state persists across jobs on the same executor
45
45
 
@@ -62,15 +62,15 @@ underlying executor process is **not** killed and continues serving subsequent j
62
62
  including for other flow elements pooled onto the same executor. Don't rely on an unhandled
63
63
  rejection to surface as a hard failure of the whole executor; always catch and handle errors
64
64
  explicitly (e.g. via `job.fail()`/`flowElement.failProcess()` — see
65
- [api-logging.md](api-logging.md)) rather than letting a promise reject unhandled.
65
+ [logging.md](logging.md)) rather than letting a promise reject unhandled.
66
66
 
67
67
  ## Third-party npm modules: file-based scripts only
68
68
 
69
69
  A script **expression** (entered inline in a flow element property, not a file-based script/app —
70
- see [Script expression](api-entry-points.md#script-expression)) cannot use third-party npm modules
70
+ see [Script expression](entry-points.md#script-expression)) cannot use third-party npm modules
71
71
  at all; only Node.js built-ins are available via `require`. A file-based script/app can use
72
72
  third-party modules from its own `node_modules` folder (see
73
- [Script folder files](api-script-structure.md#script-folder-files)).
73
+ [Script folder files](../switch-project/script-structure.md#script-folder-files)).
74
74
 
75
75
  ## Native (binary) addons are not supported
76
76
 
@@ -80,7 +80,7 @@ native/binary Node addons (`.node` files). Stick to pure-JavaScript/TypeScript d
80
80
  ## No explicit CPU or memory cap beyond the documented thresholds
81
81
 
82
82
  Beyond the entry-point abort timeout and executor recycling thresholds already documented (see
83
- [Job processing](api-entry-points.md#job-processing) and
84
- [Executor cleanup thresholds](api-job-patterns.md#executor-cleanup-thresholds)), there is no
83
+ [Job processing](entry-points.md#job-processing) and
84
+ [Executor cleanup thresholds](job-patterns.md#executor-cleanup-thresholds)), there is no
85
85
  additional CPU-time or memory limit enforced on a script's own code. A runaway loop or leak is
86
86
  bounded only by those thresholds, not stopped proactively.
@@ -21,7 +21,7 @@ Properties are configured by the user in the Switch canvas and declared in the s
21
21
  ```ts
22
22
  flowElement.getPropertyStringValue(tag: string): Promise<string | string[]>
23
23
  ```
24
- Returns the property value as a string (or array for multi-value properties). For `OAuthToken` properties, returns a valid refreshed token. Throws `"Invalid tag: <tag>"` if the tag is unknown **or if it's a `Dependency` dependent currently hidden by its master's value** — see [api-script-declaration.md § Dependency](api-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. See [api-property-editors.md](api-property-editors.md) for editor types and their return value formats.
24
+ Returns the property value as a string (or array for multi-value properties). For `OAuthToken` properties, returns a valid refreshed token. 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. See [property-editors.md](../switch-project/property-editors.md) for editor types and their return value formats.
25
25
 
26
26
  > **Dynamic values (Switch variables and script expressions) are only resolved when `getPropertyStringValue()` is called from `jobArrived`.** In any other entry point (e.g. `timerFired`) the raw unresolved string is returned.
27
27
  >
@@ -58,7 +58,7 @@ Sets the interval between `timerFired` invocations. Default is 300 s. The actual
58
58
 
59
59
  ## Logging
60
60
 
61
- See [api-logging.md](api-logging.md) for log level semantics and logging practice.
61
+ See [logging.md](logging.md) for log level semantics and logging practice.
62
62
 
63
63
  ```ts
64
64
  flowElement.log(level: LogLevel, message: string, messageParams?: (string | number | boolean)[]): Promise<void>
@@ -75,7 +75,7 @@ Logs a fatal error and puts the element into the "problem process" state. `messa
75
75
  ```ts
76
76
  flowElement.createJob(path: string): Promise<Job>
77
77
  ```
78
- Creates a new job from an existing file/folder path. Valid only in `jobArrived` and `timerFired`. The new job has default properties (no parent). The caller is responsible for cleaning up the source file after routing. See [api-job-patterns.md](api-job-patterns.md#temp-file-cleanup) for temp file cleanup rules and [api-job-patterns.md](api-job-patterns.md#sending-jobs) for routing constraints.
78
+ Creates a new job from an existing file/folder path. Valid only in `jobArrived` and `timerFired`. The new job has default properties (no parent). The caller is responsible for cleaning up the source file after routing. See [job-patterns.md](job-patterns.md#temp-file-cleanup) for temp file cleanup rules and [job-patterns.md](job-patterns.md#sending-jobs) for routing constraints.
79
79
 
80
80
  ```ts
81
81
  flowElement.getJobs(ids: string[]): Promise<Job[]>
@@ -94,7 +94,7 @@ Subscribes to a channel to receive jobs from it. Only one subscriber per channel
94
94
  ```ts
95
95
  flowElement.createPathWithName(name: string, createFolder: boolean): Promise<any>
96
96
  ```
97
- Creates a temporary path (optionally as a folder — `createFolder` is required, not optional). Returns an empty string only if creating the folder throws (e.g. a permissions error); it does not check whether the path already exists first. This is the recommended way to create temp files — see [api-job-patterns.md](api-job-patterns.md#temp-file-cleanup) for cleanup rules, including why this method should be preferred over ad hoc temp-file approaches like the `tmp` npm package.
97
+ Creates a temporary path (optionally as a folder — `createFolder` is required, not optional). Returns an empty string only if creating the folder throws (e.g. a permissions error); it does not check whether the path already exists first. This is the recommended way to create temp files — see [job-patterns.md](job-patterns.md#temp-file-cleanup) for cleanup rules, including why this method should be preferred over ad hoc temp-file approaches like the `tmp` npm package.
98
98
 
99
99
  ```ts
100
100
  flowElement.getFileCount(nested?: boolean): Promise<number>
@@ -73,7 +73,7 @@ await fs.promises.rm(tempPath);
73
73
  - If `OutgoingConnections="Unlimited"` (more than one outgoing connection allowed), never use
74
74
  `job.sendToSingle()` — it only makes sense when exactly one outgoing connection exists.
75
75
  - If no output is produced for a job, call `job.sendToNull()` rather than leaving it unrouted.
76
- - `ConnectionType="Move"` (see [api-script-declaration.md](api-script-declaration.md#connectionfields)):
76
+ - `ConnectionType="Move"` (see [script-declaration.md](../switch-project/script-declaration.md#connectionfields)):
77
77
  never use `job.sendToData()`/`job.sendToLog()` — those are for `TrafficLight` connections only. Use
78
78
  `job.sendTo()`/`job.sendToSingle()`.
79
79
  - `ConnectionType="TrafficLight"`: use only `job.sendToData()`/`job.sendToLog()` — never
@@ -81,9 +81,9 @@ await fs.promises.rm(tempPath);
81
81
  is enabled in the declaration, and `sendToLog` when the corresponding Log connection is enabled.
82
82
  Conversely, don't declare a Success/Warning/Error element the script never routes to — omit it from
83
83
  `ConnectionFields` entirely (see the TrafficLight example in
84
- [api-script-declaration.md](api-script-declaration.md#connectionfields)).
84
+ [script-declaration.md](../switch-project/script-declaration.md#connectionfields)).
85
85
  - Prefer `job.fail()`/`flowElement.failProcess()` for genuine processing errors (see
86
- [api-logging.md](api-logging.md)) over silently routing a failed job to a generic error connection —
86
+ [logging.md](logging.md)) over silently routing a failed job to a generic error connection —
87
87
  reserve an error `TrafficLight` connection for cases the flow author should be able to reroute
88
88
  downstream, not as a substitute for `fail()`.
89
89
 
@@ -93,7 +93,7 @@ await fs.promises.rm(tempPath);
93
93
 
94
94
  **Known issue — pending a server-side fix; remove this section once fixed.** Applies to all current versions.
95
95
 
96
- `job.createChild()` copies the parent's *current* datasets immediately (see [api-job.md](api-job.md#child-jobs)); `job.createDataset()` only registers a pending write, flushed to disk at the next `sendTo*()` call (see [api-job.md](api-job.md#datasets-metadata)). If a child is created *before* a dataset is written, the child inherits the job's existing dataset under that name instead. At flush time, the pending write fans out concurrently to the parent and to every child created so far, all reading from the same source file on disk — targets that already have a dataset by that name get the file **moved** into place, while targets that don't get it **copied**. When a mix of both happens against a single source file, the move wins the race and the copies fail with errors like `Could not place the file with the decoded data '...' into the datasets folder`, deterministically and on every retry (the source file is gone after the first attempt).
96
+ `job.createChild()` copies the parent's *current* datasets immediately (see [job.md](job.md#child-jobs)); `job.createDataset()` only registers a pending write, flushed to disk at the next `sendTo*()` call (see [job.md](job.md#datasets-metadata)). If a child is created *before* a dataset is written, the child inherits the job's existing dataset under that name instead. At flush time, the pending write fans out concurrently to the parent and to every child created so far, all reading from the same source file on disk — targets that already have a dataset by that name get the file **moved** into place, while targets that don't get it **copied**. When a mix of both happens against a single source file, the move wins the race and the copies fail with errors like `Could not place the file with the decoded data '...' into the datasets folder`, deterministically and on every retry (the source file is gone after the first attempt).
97
97
 
98
98
  **Rule:** perform every dataset write on a job before creating any child of it. Where a script's structure naturally interleaves the two, iterate the dataset outputs first, then the child-job outputs, rather than handling each output in one pass.
99
99
 
@@ -131,14 +131,14 @@ The Node.js executor process is recycled when any of the following thresholds is
131
131
 
132
132
  On cleanup, any files/folders created in the temp area are removed. Always close file handles and database connections before the entry point returns.
133
133
 
134
- See [api-execution-environment.md](api-execution-environment.md) for how this process model affects state persistence and error handling across job invocations.
134
+ See [execution-environment.md](execution-environment.md) for how this process model affects state persistence and error handling across job invocations.
135
135
 
136
136
  ## Driving a third-party CLI application
137
137
 
138
138
  `findApplicationPath` and the `ApplicationPath` property are the legacy-scripting mechanism for
139
139
  locating a third-party application; neither is available to Node.js scripts, and `ApplicationPath`
140
140
  is a reserved name Switch silently drops from the declaration (see
141
- [api-script-declaration.md](api-script-declaration.md#built-in-elementfields)). A Node.js script or
141
+ [script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields)). A Node.js script or
142
142
  app that shells out to an external binary resolves the path itself, using the following pattern.
143
143
 
144
144
  1. Declare an ordinary custom property for the path under a name of your own — `cliPath`, not
@@ -147,7 +147,7 @@ app that shells out to an external binary resolves the path itself, using the fo
147
147
  `Default="Automatic"` and `Subtype="automatic"`. The `automatic` literal editor is what lets the
148
148
  user express "find it yourself" without typing a magic string, and `getPropertyStringValue()`
149
149
  returns the literal `"Automatic"` for it — see
150
- [api-property-editors.md § Literal editors](api-property-editors.md#literal-editors).
150
+ [property-editors.md § Literal editors](../switch-project/property-editors.md#literal-editors).
151
151
  3. Resolve the path once per flow start, in `flowStartTriggered`: if the property reads
152
152
  `Automatic`, run whatever discovery the application needs; otherwise take
153
153
  `flowElement.getPropertyStringValue('cliPath')`. Verify the resulting path actually exists, then
@@ -157,7 +157,7 @@ app that shells out to an external binary resolves the path itself, using the fo
157
157
  discovery failed: call `flowElement.failProcess()` so the element goes into an error state,
158
158
  instead of failing every individual job.
159
159
  5. Remove the global data entry in `flowStopTriggered` — global data is never cleaned up
160
- automatically (see [api-switch.md § Global data](api-switch.md#global-data)).
160
+ automatically (see [switch.md § Global data](switch.md#global-data)).
161
161
 
162
162
  Doing discovery once at flow start rather than per job keeps a filesystem search off the job path,
163
163
  and gives the operator a single clear element-level error when the application is missing.
@@ -36,7 +36,7 @@ Returns the local filesystem path to the job. Use `AccessLevel.ReadOnly` to read
36
36
 
37
37
  ## Routing
38
38
 
39
- Every job must be routed exactly once. See [api-job-patterns.md § Sending jobs](api-job-patterns.md#sending-jobs) for which `sendTo*()` method is appropriate for a given `ConnectionType`/`OutgoingConnections` declaration.
39
+ Every job must be routed exactly once. See [job-patterns.md § Sending jobs](job-patterns.md#sending-jobs) for which `sendTo*()` method is appropriate for a given `ConnectionType`/`OutgoingConnections` declaration.
40
40
 
41
41
  ```ts
42
42
  job.sendToNull(): Promise<void>
@@ -75,7 +75,7 @@ Re-queue the job for `jobArrived` after a minimum delay (re-evaluates dynamic pr
75
75
 
76
76
  ## Failure & logging
77
77
 
78
- See [api-logging.md](api-logging.md) for log level semantics and logging practice.
78
+ See [logging.md](logging.md) for log level semantics and logging practice.
79
79
 
80
80
  ```ts
81
81
  job.fail(message: string, messageParams?: (string | number | boolean)[]): void
@@ -92,7 +92,7 @@ Log a message including job context. To log a literal `%`, pass it as a param: `
92
92
  ```ts
93
93
  job.createChild(path: string): Promise<Job>
94
94
  ```
95
- Creates a new job inheriting the processing history, metadata, and private data of the parent. Takes effect immediately: the child's datasets are copied from the parent's *current* server-side state, so any pending `createDataset()` write not yet flushed by a `sendTo*()` call is not reflected in it. See [api-job-patterns.md](api-job-patterns.md#dataset-writes-must-precede-child-job-creation) — creating a child before writing a dataset is a common source of bugs. The caller is responsible for cleaning up the source file after routing (see [api-job-patterns.md](api-job-patterns.md#temp-file-cleanup)).
95
+ Creates a new job inheriting the processing history, metadata, and private data of the parent. Takes effect immediately: the child's datasets are copied from the parent's *current* server-side state, so any pending `createDataset()` write not yet flushed by a `sendTo*()` call is not reflected in it. See [job-patterns.md](job-patterns.md#dataset-writes-must-precede-child-job-creation) — creating a child before writing a dataset is a common source of bugs. The caller is responsible for cleaning up the source file after routing (see [job-patterns.md](job-patterns.md#temp-file-cleanup)).
96
96
 
97
97
  ## Private data
98
98
 
@@ -128,7 +128,7 @@ List all datasets attached to the job. **Immediate**: reads server state at once
128
128
  ```ts
129
129
  job.createDataset(name: string, filePath: string, model: DatasetModel): Promise<void>
130
130
  ```
131
- Attach a new dataset. **Deferred**: registers in-memory only; the file is not uploaded until the next `sendTo*()` call. Caller must clean up the source file after routing — see [api-job-patterns.md](api-job-patterns.md#temp-file-cleanup).
131
+ Attach a new dataset. **Deferred**: registers in-memory only; the file is not uploaded until the next `sendTo*()` call. Caller must clean up the source file after routing — see [job-patterns.md](job-patterns.md#temp-file-cleanup).
132
132
 
133
133
  ```ts
134
134
  job.getDataset(name: string, accessLevel: AccessLevel): Promise<string>
@@ -1,9 +1,9 @@
1
1
  # Logging Practices
2
2
 
3
3
  Guidance for using `job.log()`, `flowElement.log()`, `job.fail()`, and `flowElement.failProcess()`
4
- — see [api-job.md](api-job.md#failure--logging) and
5
- [api-flow-element.md](api-flow-element.md#logging) for their signatures. `LogLevel` values are
6
- listed in [api-enums.md](api-enums.md). Each log call has a small performance overhead, so where
4
+ — see [job.md](job.md#failure--logging) and
5
+ [flow-element.md](flow-element.md#logging) for their signatures. `LogLevel` values are
6
+ listed in [enums.md](enums.md). Each log call has a small performance overhead, so where
7
7
  and how often to log is a deliberate choice, not a default.
8
8
 
9
9
  ## Log levels
@@ -13,7 +13,7 @@ and how often to log is a deliberate choice, not a default.
13
13
  | `Error` | The job/step failed or produced a wrong/unusable result. Often accompanies or precedes a hard stop, but can stand alone if the job continues in a degraded way. |
14
14
  | `Warning` | Something unexpected happened but processing continued successfully (a fallback was used, an optional resource was missing). |
15
15
  | `Info` | Normal, expected checkpoints worth surfacing to a flow operator without them needing debug mode (e.g. "processed 40 records", "output written to X"). |
16
- | `Debug` | Verbose detail for diagnosing execution. Many users leave debug logging enabled in production to self-diagnose issues and to help app developers and Enfocus Support — leave meaningful checkpoints in, but trim noisy or no-longer-useful debug logs before shipping. **`Debug` messages only reach the log database if the Switch preference "Log debug messages" is turned on** (off by default) — see [api-logs-and-dataroot.md](api-logs-and-dataroot.md#retention-and-the-debug-level-gate). |
16
+ | `Debug` | Verbose detail for diagnosing execution. Many users leave debug logging enabled in production to self-diagnose issues and to help app developers and Enfocus Support — leave meaningful checkpoints in, but trim noisy or no-longer-useful debug logs before shipping. **`Debug` messages only reach the log database if the Switch preference "Log debug messages" is turned on** (off by default) — see [logs-and-dataroot.md](../switch-project/logs-and-dataroot.md#retention-and-the-debug-level-gate). |
17
17
 
18
18
  ## Logging in loops
19
19
 
@@ -24,7 +24,7 @@ one call per iteration, e.g. `"Found 12 matching jobs"` instead of one log line
24
24
  ## `console.log` does not work
25
25
 
26
26
  `console.log` only produces output when a debug session is attached (see
27
- [api-debugging.md](api-debugging.md)); in a normal run it is not visible anywhere. Never rely on it
27
+ [debugging.md](../switch-project/debugging.md)); in a normal run it is not visible anywhere. Never rely on it
28
28
  in production scripts — use `job.log()`/`flowElement.log()` for anything that should be visible in
29
29
  the log/message pane.
30
30
 
@@ -75,7 +75,7 @@ job.log(LogLevel.Info, 'Processed file %1 in %2s', [fileName, seconds]);
75
75
  looks unfinished and undermines trust.
76
76
  - Log an `Error` when a custom `validateProperties`/`validateConnectionProperties` check returns
77
77
  `valid: false` for a tag, and when `getLibraryForProperty`/`getLibraryForConnectionProperty` would
78
- otherwise return an empty list — see [api-entry-points.md § Property UI callbacks](api-entry-points.md#property-ui-callbacks).
78
+ otherwise return an empty list — see [entry-points.md § Property UI callbacks](entry-points.md#property-ui-callbacks).
79
79
  Silently returning `false`/`[]` with no log line leaves the user without any explanation.
80
80
 
81
81
  ## Log volume
@@ -120,5 +120,5 @@ const mode = readOnly ? Switch.tr('Read-only') : Switch.tr('Regular');
120
120
  await job.log(LogLevel.Info, Switch.tr('Job ID = %1, Mode = %2'), [job.getId(), mode]);
121
121
  ```
122
122
 
123
- See [api-logging.md § Placeholders instead of concatenation](api-logging.md#placeholders-instead-of-concatenation)
123
+ See [logging.md § Placeholders instead of concatenation](logging.md#placeholders-instead-of-concatenation)
124
124
  for the same rule stated from the logging side.