feat(stardust): generate typescript definitions (#752)

This commit is contained in:
Thomas Bengtsson
2022-02-08 12:18:57 +01:00
committed by GitHub
parent b756b6b6b6
commit 016b6bd5c7
9 changed files with 747 additions and 9 deletions

View File

@@ -1 +1,2 @@
dist/
**/index.d.ts

View File

@@ -27,3 +27,18 @@ orion.render({
fields: ['Product', 'Region', 'Sales']
});
```
## Typescript
Stardust comes with typescript definitions. It references the Qlik's Engine definitions published at @types/qlik-engineapi.
When installing Stardust it also installs the package @types/qlik-engineapi. Use [overrides](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides) in your package.json if the installed version deviates from the Qlik Engine you are using:
```json
{
"overrides": {
"@types/qlik-engineapi": "<your-engine-version>"
},
...
}
```

View File

@@ -42,4 +42,13 @@ module.exports = {
},
},
},
toDts: {
spec: './api-spec/spec.json',
output: {
file: './types/index.d.ts',
},
dependencies: {
references: ['qlik-engineapi'],
},
},
};

View File

@@ -1782,7 +1782,6 @@
"params": [
{
"name": "field",
"description": "TODO validate param name",
"type": "T"
},
{
@@ -1801,7 +1800,6 @@
"params": [
{
"name": "field",
"description": "TODO validate param name",
"type": "T"
},
{
@@ -1810,7 +1808,6 @@
},
{
"name": "index",
"description": "TODO validate param name",
"type": "number"
}
]

View File

@@ -22,17 +22,23 @@
"main": "index.js",
"jsdelivr": "dist/stardust.js",
"unpkg": "dist/stardust.js",
"types": "types/index.d.ts",
"files": [
"LICENSE",
"core",
"dist"
"dist",
"types/index.d.ts"
],
"scripts": {
"build": "cross-env NODE_ENV=production rollup --config ../../rollup.config.js",
"build:dev": "rollup --config ../../rollup.config.js",
"build:watch": "rollup --config ../../rollup.config.js -w",
"prepublishOnly": "rm -rf dist && yarn run build",
"spec": "sy from-jsdoc -c ./api-spec/spec.conf.js"
"spec": "sy from-jsdoc -c ./api-spec/spec.conf.js",
"ts": "sy to-dts -c ./api-spec/spec.conf.js"
},
"dependencies": {
"@types/qlik-engineapi": "12.67.11"
},
"devDependencies": {
"@material-ui/core": "4.12.3",
@@ -46,6 +52,7 @@
"@nebula.js/ui": "^2.3.1",
"@scriptappy/cli": "0.0.1",
"@scriptappy/from-jsdoc": "0.7.0",
"@scriptappy/to-dts": "1.0.0-beta.4",
"extend": "3.0.2",
"node-event-emitter": "0.0.1",
"react": "17.0.2",

689
apis/stardust/types/index.d.ts vendored Normal file
View File

@@ -0,0 +1,689 @@
// File generated automatically by "@scriptappy/to-dts"; DO NOT EDIT.
/// <reference types="qlik-engineapi" />
/**
* Initiates a new `Embed` instance using the specified enigma `app`.
* @param app
* @param instanceConfig
*/
export function embed(app: EngineAPI.IApp, instanceConfig?: stardust.Configuration): stardust.Embed;
export namespace embed {
/**
* Creates a new `embed` scope bound to the specified `configuration`.
*
* The configuration is merged with all previous scopes.
* @param configuration The configuration object
*/
function createConfiguration(configuration: stardust.Configuration): typeof embed;
}
/**
* Creates a stateful value.
* @param initialState The initial state.
*/
export function useState<S>(initialState: S | (()=>S)): [S, stardust.SetStateFn<S>];
/**
* Triggers a callback function when a dependent value changes.
* @param effect The callback.
* @param deps The dependencies that should trigger the callback.
*/
export function useEffect(effect: stardust.EffectCallback, deps?: any[]): void;
/**
* Creates a stateful value when a dependent changes.
* @param factory The factory function.
* @param deps The dependencies.
*/
export function useMemo<T>(factory: ()=>T, deps: any[]): T;
/**
* Runs a callback function when a dependent changes.
* @param factory The factory function that calls the promise.
* @param deps The dependencies.
*/
export function usePromise<P>(factory: ()=>Promise<P>, deps?: any[]): [P, Error];
/**
* Gets the HTMLElement this visualization is rendered into.
*/
export function useElement(): HTMLElement;
/**
* Gets the size of the HTMLElement the visualization is rendered into.
*/
export function useRect(): stardust.Rect;
/**
* Gets the layout of the generic object associated with this visualization.
*/
export function useLayout(): EngineAPI.IGenericObjectLayout;
/**
* Gets the layout of the generic object associated with this visualization.
*
* Unlike the regular layout, a _stale_ layout is not changed when a generic object enters
* the modal state. This is mostly notable in that `qSelectionInfo.qInSelections` in the layout is
* always `false`.
* The returned value from `useStaleLayout()` and `useLayout()` are identical when the object
* is not in a modal state.
*/
export function useStaleLayout(): EngineAPI.IGenericObjectLayout;
/**
* Gets the layout of the app associated with this visualization.
*/
export function useAppLayout(): EngineAPI.INxAppLayout;
/**
* Gets the generic object API of the generic object connected to this visualization.
*/
export function useModel(): EngineAPI.IGenericObject | undefined;
/**
* Gets the doc API.
*/
export function useApp(): EngineAPI.IApp | undefined;
/**
* Gets the global API.
*/
export function useGlobal(): EngineAPI.IGlobal | undefined;
/**
* Gets the object selections.
*/
export function useSelections(): stardust.ObjectSelections;
/**
* Gets the theme.
*/
export function useTheme(): stardust.Theme;
/**
* Gets the embed instance used.
*/
export function useEmbed(): stardust.Embed;
/**
* Gets the translator.
*/
export function useTranslator(): stardust.Translator;
/**
* Gets the device type. ('touch' or 'desktop')
*/
export function useDeviceType(): string;
/**
* Gets the array of plugins provided when rendering the visualization.
*/
export function usePlugins(): stardust.Plugin[];
/**
* Registers a custom action.
* @param factory
* @param deps
*/
export function useAction<A>(factory: ()=>stardust.ActionDefinition<A>, deps?: any[]): A;
/**
* Gets the desired constraints that should be applied when rendering the visualization.
*
* The constraints are set on the embed configuration before the visualization is rendered
* and should respected by you when implementing the visualization.
*/
export function useConstraints(): stardust.Constraints;
/**
* Gets the options object provided when rendering the visualization.
*
* This is an empty object by default but enables customization of the visualization through this object.
* Options are different from setting properties on the generic object in that options
* are only temporary settings applied to the visualization when rendered.
*
* You have the responsibility to provide documentation of the options you support, if any.
*/
export function useOptions(): object;
/**
* Registers a callback that is called when a snapshot is taken.
* @param snapshotCallback
*/
export function onTakeSnapshot(snapshotCallback: ($: EngineAPI.IGenericObjectLayout)=>Promise<EngineAPI.IGenericObjectLayout>): void;
/**
* Gets render state instance.
*
* Used to update properties and get a new layout without triggering onInitialRender.
*/
export function useRenderState(): stardust.RenderState;
/**
* Gets the desired keyboard settings and status to applied when rendering the visualization.
* A visualization should in general only have tab stops if either `keyboard.enabled` is false or if active is true.
* This means that either Nebula isn't configured to handle keyboard input or the chart is currently focused.
* Enabling or disabling keyboardNavigation are set on the embed configuration and
* should be respected by the visualization.
*/
export function useKeyboard(): stardust.Keyboard;
declare namespace stardust {
interface Context {
keyboardNavigation?: boolean;
constraints?: {
active?: boolean;
passive?: boolean;
select?: boolean;
};
theme?: string;
language?: string;
deviceType?: string;
}
interface Configuration {
context?: stardust.Context;
types?: stardust.TypeInfo[];
themes?: stardust.ThemeInfo[];
anything?: object;
}
interface Galaxy {
translator: stardust.Translator;
flags: stardust.Flags;
deviceType: string;
anything: object;
}
class Embed {
constructor();
/**
* Renders a visualization into an HTMLElement.
* @param cfg The render configuration.
*/
render(cfg: stardust.CreateConfig | stardust.GetConfig): Promise<stardust.Viz>;
/**
* Updates the current context of this embed instance.
* Use this when you want to change some part of the current context, like theme.
* @param ctx The context to update.
*/
context(ctx: stardust.Context): Promise<undefined>;
/**
* Gets the app selections of this instance.
*/
selections(): Promise<stardust.AppSelections>;
/**
* Gets the listbox instance of the specified field
* @param fieldIdentifier Fieldname as a string or a Library dimension
*/
field(fieldIdentifier: string | stardust.LibraryField): Promise<stardust.FieldInstance>;
/**
* Gets a list of registered visualization types and versions
*/
getRegisteredTypes(): Object[];
}
/**
* A callback function which receives another function as input.
*/
type ReceiverFunction = ($: ()=>void)=>void;
class FieldInstance {
constructor();
/**
* Mounts the field as a listbox into the provided HTMLElement.
* @param element
* @param options Settings for the embedded listbox
*/
static mount(element: HTMLElement, options?: {
title?: string;
direction?: string;
listLayout?: string;
search?: boolean;
toolbar?: boolean;
stateName?: boolean;
properties?: object;
sessionModel?: object;
selectionsApi?: object;
update?: stardust.ReceiverFunction;
}): void;
/**
* Unmounts the field listbox from the DOM.
*/
static unmount(): void;
}
type ThemeJSON = any;
interface ThemeInfo {
id: string;
/**
* A function that should return a Promise that resolves to a raw JSON theme.
*/
load(): Promise<stardust.ThemeJSON>;
}
/**
* A controller to further modify a visualization after it has been rendered.
*/
class Viz {
constructor();
id: string;
/**
* Destroys the visualization and removes it from the the DOM.
*/
destroy(): void;
/**
* Converts the visualization to a different registered type
* @param newType Which registered type to convert to.
* @param forceUpdate Whether to run setProperties or not, defaults to true.
*/
convertTo(newType: string, forceUpdate?: boolean): Promise<object>;
}
interface Flags {
/**
* Checks whether the specified flag is enabled.
* @param flag The value flag to check.
*/
isEnabled(flag: string): boolean;
}
class AppSelections {
constructor();
/**
* Mounts the app selection UI into the provided HTMLElement.
* @param element
*/
mount(element: HTMLElement): void;
/**
* Unmounts the app selection UI from the DOM.
*/
unmount(): void;
}
class ObjectSelections {
constructor();
/**
* @param paths
*/
begin(paths: string[]): Promise<undefined>;
clear(): Promise<undefined>;
confirm(): Promise<undefined>;
cancel(): Promise<undefined>;
/**
* @param s
*/
select(s: {
method: string;
params: any[];
}): Promise<boolean>;
canClear(): boolean;
canConfirm(): boolean;
canCancel(): boolean;
isActive(): boolean;
isModal(): boolean;
/**
* @param paths
*/
goModal(paths: string[]): Promise<undefined>;
/**
* @param accept
*/
noModal(accept?: boolean): Promise<undefined>;
}
type Field = string | EngineAPI.INxDimension | EngineAPI.INxMeasure | stardust.LibraryField;
/**
* Rendering configuration for creating and rendering a new object
*/
interface CreateConfig extends stardust.BaseConfig{
type: string;
version: string;
fields?: stardust.Field[];
properties?: EngineAPI.IGenericObjectProperties;
}
/**
* Basic rendering configuration for rendering an object
*/
interface BaseConfig {
element: HTMLElement;
options?: object;
plugins?: stardust.Plugin[];
}
/**
* Rendering configuration for rendering an existing object
*/
interface GetConfig extends stardust.BaseConfig{
id: string;
}
interface LibraryField {
qLibraryId: string;
type: "dimension" | "measure";
}
/**
* An object literal containing meta information about the plugin and a function containing the plugin implementation.
*/
interface Plugin {
info: {
name: string;
};
fn: ()=>void;
}
interface LoadType {
(type: {
name: string;
version: string;
}): Promise<stardust.Visualization>;
}
interface TypeInfo {
name: string;
version: string;
load: stardust.LoadType;
meta?: object;
}
interface ActionToolbarElement extends HTMLElement{
className: "njs-action-toolbar-popover";
}
interface ActionElement extends HTMLElement{
className: "njs-cell-action";
}
interface CellElement extends HTMLElement{
className: "njs-cell";
}
interface CellFooter extends HTMLElement{
className: "njs-cell-footer";
}
interface CellTitle extends HTMLElement{
className: "njs-cell-title";
}
interface CellSubTitle extends HTMLElement{
className: "njs-cell-sub-title";
}
interface VizElementAttributes extends NamedNodeMap{
"data-render-count": string;
}
interface VizElement extends HTMLElement{
attributes: stardust.VizElementAttributes;
className: "njs-viz";
}
/**
* The entry point for defining a visualization.
*/
interface Visualization {
(galaxy: stardust.Galaxy): stardust.VisualizationDefinition;
}
interface VisualizationDefinition {
qae: stardust.QAEDefinition;
component(): void;
}
interface SetStateFn<S> {
(newState: S | (($: S)=>S)): void;
}
type EffectCallback = ()=>void | (()=>void);
interface Rect {
top: number;
left: number;
width: number;
height: number;
}
interface ActionDefinition<A> {
action: A;
hidden?: boolean;
disabled?: boolean;
icon?: {
viewBox?: string;
shapes: {
}[];
};
}
interface Constraints {
passive?: boolean;
active?: boolean;
select?: boolean;
}
interface RenderState {
pending: any;
restore: any;
}
interface Keyboard {
enabled: boolean;
active: boolean;
/**
* Function used by the visualization to tell Nebula to it wants to relinquish focus
*/
blur?(): void;
/**
* Function used by the visualization to tell Nebula to it wants focus
*/
focus?(): void;
/**
* Function used by the visualization to tell Nebula to focus the selection toolbar
*/
focusSelection?(): void;
}
/**
* Imports properties for a chart with a hypercube.
*/
type importProperties = (args: {
exportFormat: stardust.ExportFormat;
initialProperties?: Object;
dataDefinition?: Object;
defaultPropertyValues?: Object;
hypercubePath: string;
})=>Object;
/**
* Exports properties for a chart with a hypercube.
*/
type exportProperties = (args: {
propertyTree: Object;
hypercubePath: string;
})=>stardust.ExportFormat;
interface QAEDefinition {
properties?: EngineAPI.IGenericObjectProperties;
data?: {
targets: stardust.DataTarget[];
};
importProperties?: stardust.importProperties;
exportProperties?: stardust.exportProperties;
}
interface DataTarget {
path: string;
dimensions?: stardust.FieldTarget<EngineAPI.INxDimension>;
measures?: stardust.FieldTarget<EngineAPI.INxMeasure>;
}
type fieldTargetAddedCallback<T> = (field: T, properties: EngineAPI.IGenericObjectProperties)=>void;
type fieldTargetRemovedCallback<T> = (field: T, properties: EngineAPI.IGenericObjectProperties, index: number)=>void;
interface FieldTarget<T> {
min?(): number;
max?(): number;
added?: stardust.fieldTargetAddedCallback<T>;
removed?: stardust.fieldTargetRemovedCallback<T>;
}
class Translator {
constructor();
/**
* Registers a string in multiple locales
* @param item
*/
add(item: {
id: string;
locale: object;
}): void;
/**
* Translates a string for current locale.
* @param str ID of the registered string.
* @param args Values passed down for string interpolation.
*/
get(str: string, args?: string[]): string;
}
class Theme {
constructor();
getDataColorScales(): stardust.Theme.ScalePalette[];
getDataColorPalettes(): stardust.Theme.DataPalette[];
getDataColorPickerPalettes(): stardust.Theme.ColorPickerPalette[];
getDataColorSpecials(): stardust.Theme.DataColorSpecials;
/**
* Resolve a color object using the color picker palette from the provided JSON theme.
* @param c
*/
getColorPickerColor(c: {
index?: number;
color?: string;
}): string;
/**
* Get the best contrasting color against the specified `color`.
* This is typically used to find a suitable text color for a label placed on an arbitrarily colored background.
*
* The returned colors are derived from the theme.
* @param color A color to measure the contrast against
*/
getContrastingColorTo(color: string): string;
/**
* Get the value of a style attribute in the theme by searching in the theme's JSON structure.
* The search starts at the specified base path and continues upwards until the value is found.
* If possible it will get the attribute's value using the given path.
* @param basePath Base path in the theme's JSON structure to start the search in (specified as a name path separated by dots).
* @param path Expected path for the attribute (specified as a name path separated by dots).
* @param attribute Name of the style attribute.
*/
getStyle(basePath: string, path: string, attribute: string): string;
}
namespace Theme {
interface ScalePalette {
key: string;
type: "gradient" | "class-pyramid";
colors: string[] | (string[])[];
}
interface DataPalette {
key: string;
type: "pyramid" | "row";
colors: string[] | (string[])[];
}
interface ColorPickerPalette {
key: string;
colors: string[];
}
interface DataColorSpecials {
primary: string;
nil: string;
others: string;
}
}
/**
* Used for exporting and importing properties between backend models. An object that exports to
* ExportFormat should put dimensions and measures inside one data group. If an object has two hypercubes,
* each of the cubes should export dimensions and measures in two separate data groups.
* An object that imports from this structure is responsible for putting the existing properties where they should be
* in the new model.
*/
interface ExportFormat {
data?: stardust.ExportDataDef[];
properties?: object;
}
interface ExportDataDef {
dimensions: EngineAPI.INxDimension[];
measures: EngineAPI.INxMeasure[];
excludedDimensions: EngineAPI.INxDimension[];
excludedMeasures: EngineAPI.INxMeasure[];
interColumnSortOrder: number[];
}
interface ConversionType {
importProperties: stardust.importProperties;
exportProperties: stardust.exportProperties;
}
/**
* Provides conversion functionality to extensions.
*/
interface Conversion {
hypercube: stardust.hyperCubeConversion;
}
interface hyperCubeConversion {
}
}

View File

@@ -42,16 +42,16 @@ const noop = () => {};
/**
* @callback fieldTargetAddedCallback
* @template T
* @param {T} field TODO validate param name
* @param {T} field
* @param {EngineAPI.IGenericObjectProperties} properties
*/
/**
* @callback fieldTargetRemovedCallback
* @template T
* @param {T} field TODO validate param name
* @param {T} field
* @param {EngineAPI.IGenericObjectProperties} properties
* @param {number} index TODO validate param name
* @param {number} index
*/
/**

View File

@@ -72,13 +72,15 @@ const GLOBALS = {
const watch = process.argv.indexOf('-w') > 2;
const TYPES_SCOPE_RX = /^@types\//;
const config = ({ format = 'umd', debug = false, file, targetPkg }) => {
const umdName = targetName
.replace(/-([a-z])/g, (m, p1) => p1.toUpperCase())
.split('.js')
.join('');
if (Object.keys(targetPkg.dependencies || {}).length) {
if (Object.keys(targetPkg.dependencies || {}).filter((dep) => !TYPES_SCOPE_RX.test(dep)).length) {
throw new Error('Dependencies for a web javascript library makes no sense');
}

View File

@@ -5374,6 +5374,14 @@
resolved "https://registry.yarnpkg.com/@scriptappy/schema/-/schema-1.1.0.tgz#ad3ddffb81ed0e3ffdbfb9e86ef575f3feb0429e"
integrity sha512-HiiW0niupVqK3qbIyWyMLIQoyjCjAzl2DqwSdWap6Cm97xN3XqW2wDKMIzsGCeSYCjaMY+dGaRK2ENSMW2mdlA==
"@scriptappy/to-dts@1.0.0-beta.4":
version "1.0.0-beta.4"
resolved "https://registry.yarnpkg.com/@scriptappy/to-dts/-/to-dts-1.0.0-beta.4.tgz#0b366a62022f87a17b1abde1964656df8a121a56"
integrity sha512-YbaoUzQrwxePOFCqVtlbrdsmrP4u5haBp5seHEw5WdrZx/jEALeEenw63xLkLQmUfTPLZ+R8rRSZFyvFb7z8SQ==
dependencies:
dts-dom "^3.1.0"
extend "3.0.2"
"@sinonjs/commons@^1", "@sinonjs/commons@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.4.0.tgz#7b3ec2d96af481d7a0321252e7b1c94724ec5a78"
@@ -6378,6 +6386,11 @@
version "15.7.1"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
"@types/qlik-engineapi@12.67.11":
version "12.67.11"
resolved "https://registry.yarnpkg.com/@types/qlik-engineapi/-/qlik-engineapi-12.67.11.tgz#279da931e9cbd2a2d4d9d17220f3f12a482027eb"
integrity sha512-zMzI2+TibE4XHImPvBA2iQi2RE0XYhe5MdXaT1ViPfjbT7qgIfWoy58idOsOPbPtGupvE+gCw4TtFx069ClAdQ==
"@types/qs@^6.9.5":
version "6.9.6"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1"
@@ -10150,6 +10163,11 @@ downshift@^6.0.15:
prop-types "^15.7.2"
react-is "^17.0.2"
dts-dom@^3.1.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/dts-dom/-/dts-dom-3.6.0.tgz#0e8beaf6240e699d623bf4d7dcf0e6216222459a"
integrity sha512-on5jxTgt+A6r0Zyyz6ZRHXaAO7J1VPnOd6+AmvI1vH440AlAZZNc5rUHzgPuTjGlrVr1rOWQYNl7ZJK6rDohbw==
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"