Skip to content

Code Editor

The Code Editor is used to modify code for Scripts and Local Database Queries.

Code Editor

Editor Buttons

There are several buttons that may appear alongside the code editor.

Setting Description
Fullscreen Whether the editor should expand to fill the entire screen. This setting is not remembered.
Help Opens the gsApi Scripting Documentation in the side panel.
Upload File Allows the user to upload a file from their local machine to the code editor. The editor's contents will be completely overwritten by the selected file.
Import from URL Allows the user to enter a URL to import the contents of a script. The editor's contents will be completely overwritten by the entered URL.
Font Size Whether to use a larger or smaller font. This setting is saved per user and will persist across devices.
Theme Which theme to use. The available options are dark, light, or system. The default is system.

The code editor overlay with the buttons highlighted

Shortcuts

The GS code editor has a few useful shortcuts.

Keycode Description
ctrl+space Opens the autocomplete menu
F2 Rename a variable or function
F12 Jump to variable or function definition
shift+F12 Show references to variable or function
shift+alt+f Format code in the current editor

Type Hints and Autocomplete

Although Javascript is a Dynamically Typed Language, it is possible to provide documentation and type hints to the GS code editor. This allows the editor to show autocomplete and to catch some types of errors without needing to run the script.

These hints can be provided using JSDoc comments.

The code editor overlay showing the autocomplete functionality.

Variables

Variables may be documented by including a block-style comment.

Any text which is not decorated with a JSDoc tag will be used as the description of the variable.

The variable type may be annotated by using the @type tag followed by the type in brackets. For example:

/**
 * The maximum number of defects which is allowed for this process.  When the maximum number of defects has been exceeded, this variable will be set to a string containing an explaining the reason for the defects.
 * @type {string|number}
 */
let maxAllowedDefects;

Note that the custom types provided by GS may be used. For example:

/**
 * @type {SPCTestApi}
 */
const spcTestApi = gsApi.inspection.subInspection('subi 1').spc('spc-test-1');

Functions

Functions may be annotated in the same way as variables. The most common tags are:

  • @param - Provides a definition for a parameter in the form of @param {type} parameterName
  • @returns - Provides the definition of the return type in the form of @returns {type}

An example function may look like:

/**
 * Calculate the CPK based on the value, returning null if the threshold is not met.
 * @param {SPCDataDetail} data - The data to perform the calculation on.
 * @param {number} threshold - The threshold to check the CPK against.
 * @returns {number|undefined} The resulting CPK, or undefined if the threshold is not met.
 */
function customCalculation(data, threshold) {
    ...
}

Type Inference

The GS code editor is capable of determining the type of a variable in some instances. In these cases, the type does not need to be manually applied. For example:

const cpk = customCalculation(data, threshold);

Because the customCalculation function returns a number, as documented above, the cpk variable must be a number. Hovering over a variable with the mouse will reveal what type the GS code editor believes the variable to be.

Casting

If there are multiple possible values which can be assigned to a variable, attempting to access a property on that variable will result in an error.

The code editor showing that attempting to access string properties on the value of a Traceability Test without any type narrowing results in an error.

There are times when the author of a script is aware of context which is not available to the GS code editor. In these cases, it may be desirable to cast the variable in order to prevent the code editor from showing a warning or error. In order to cast a variable, use the @type tag inline. For example, if the author of a script knows that custom options have been set on a traceability test, they may cast the options to the correct type.

Without casting:

const properties = await gsApi.inspection.subInspection('subi 1').traceability('trace 1').getProperties();
properties.options.map(option => option * 2); // This is an error, because options may undefined or a string[]

With casting:

const properties = await gsApi.inspection.subInspection('subi 1').traceability('trace 1').getProperties();
(/**@type {number[]} **/(properties.options)).map(option => option * 2); // No error

Narrowing

If the underlying type of the variable is unknown by the author of the script, it is better to check the underlying type using type narrowing. Checking the type of a variable allows the code editor to determine the type of the variable.

The code editor showing that attempting to access string properties on the value of a Traceability Test does not result in an error if it was properly narrowed.

This can be done with the typeof property on primitive types:

/**
 * @type {string|number}
 */
const stringOrNumber = getStringOrNumber();
if (typeof stringOrNumber === 'string') {
    // The code editor now knows that stringOrNumber is a string
}

This can also be used to narrow between overlapping object types:

/**
 * @typedef {Object} FirstObjectType
 * @property {'first'} type
 * @property {number} firstObjectProperty
 */

/**
 * @typedef {Object} SecondObjectType
 * @property {'second'} type
 * @property {string} secondObjectProperty
 */

/**
 * @type {FirstObjectType|SecondObjectType}
 */
const firstOrSecond = getFirstOrSecond();

if (firstOrSecond.type === 'first') {
    // The code editor now knows that firstOrSecond is the FirstObjectType.  Can now access firstOrSecond.firstObjectProperty
}

Custom Types

There are times where it is convenient to reuse a type definition in multiple places. This can be accomplised with the @typedef tag. This can be used to limit a variable to a subset of strings:

/**
 * @typedef {'firstValue' | 'secondValue' | 'thirdValue'} ValueList
 */

/**
 * @type {ValueList}
 */
const myValue = 'firstValue'; // Must be 'firstValue', 'secondValue' or 'thirdValue'

It can also be used to construct a complex object type:

/**
 * @typedef {Object} CustomObject
 * @property {number} firstValue
 * @property {number} secondValue
 * @property {number} thirdValue
 */

/**
 * @type {CustomObject}
 */
const customObject = {
    firstValue: 2,
    secondValue: 20,
    thirdValue: 200
};

See Also