All files / app/model plugin.ts

16.66% Statements 3/18
0% Branches 0/10
25% Functions 1/4
16.66% Lines 3/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196117x   127x                                                                                                                                                                                                                                                                         127x                                                                                                                        
import { FormlyFieldConfig } from '@ngx-formly/core';
import { Schema } from 'jtd';
import { DateTime } from 'luxon';
import { toJS } from 'mobx';
import { Observable } from 'rxjs';
import { Ref, RefSort, RefUpdates } from './ref';
import { Config, EmitAction } from './tag';
 
export interface Plugin extends Config {
  config?: Config['config'] & {
    /**
     * Optional flag adding this plugin to the Ref form Add Plugin dropdown.
     */
    add?: boolean,
    /**
     * Optional handlebars template to use as an info UI.
     */
    infoUi?: string,
    /**
     * Add plugin to submit dropdown.
     */
    submit?: string,
    /**
     * Autogenerate URL when submitting.
     */
    genId?: boolean,
    /**
     * This plugin should be used in combination with the internal tag so it
     * does not show up on the home page or search.
     */
    internal?: boolean,
    /**
     * Add a button to the response buttons in the editor for a new response.
     * If there is only one option, no UI will be shown.
     * If there are two or more options a toggle will be shown in the editor.
     */
    responseButton?: string,
    /**
     * Add a DM tab to the submit page to create a DM to this tag.
     */
    submitDm?: boolean,
    /**
     * Add plugin to text dropdown.
     */
    submitText?: boolean,
    /**
     * Nest this plugin within its parent.
     */
    submitChild?: string,
    /**
     * Add to the sort dropdown.
     */
    sorts?: SortConfig[],
    /**
     * Add tab on the inbox page for this plugin using this label.
     */
    inbox?: string,
    /**
     * Add tab on the settings page for this plugin using this label.
     */
    settings?: string,
    /**
     * Disable the editor and use the viewer to edit.
     */
    editingViewer?: boolean;
    /**
     * Provides custom editor.
     */
    editor?: boolean;
    /**
     * This plugin can be exported to a self-contained html file.
     */
    export?: boolean,
    /**
     * Show plugin as signature for existing tag.
     */
    signature?: string,
    /**
     * Copy this plugin into responses.
     */
    inherit?: boolean,
    /**
     * List of file extensions that match this plugin.
     */
    extensions?: string[],
    /**
     * List of url prefixes that match this plugin.
     */
    prefix?: string[],
    /**
     * List of web hosts that match this plugin.
     */
    hosts?: string[],
    /**
     * List of URL schemes that match this plugin.
     */
    schemes?: string[],
    /**
     * Optionally customise the meaning of the published field.
     */
    published?: string;
    /**
     * Has built in defaults available. Should respond to the event `${tag}:defaults`.
     */
    hasDefaults?: boolean;
    /**
     * Require user to confirm resetting defaults with this message.
     */
    defaultsConfirm?: string;
    /**
     * Label for clear cache button. Set this if clear cache method available.
     * Should respond to the event `${tag}:clear-cache`.
     */
    hasClearCache?: string;
    /**
     * Require user to confirm clearing the cache with this message.
     */
    clearCacheConfirm?: string;
    /**
     * Optional formly config for editing a form defined by the schema in bulk tools.
     *
     * Set to true to reuse the existing form.
     */
    bulkForm?: FormlyFieldConfig[] | true,
  };
  // Client-only
  type?: 'plugin';
}
 
export interface SortConfig {
  sort: RefSort;
  label: string;
  title?: string;
}
 
export const pluginSchema: Schema = {
  optionalProperties: {
    tag: { type: 'string' },
    name: { type: 'string' },
    config: {},
    defaults: {},
    schema: {},
  }
};
 
export interface PluginApi {
  comment: (comment: string) => void;
  event: (event: string) => void;
  emit: (a: EmitAction) => void;
  tag: (tag: string) => void;
  respond: (response: string, clear?: string[]) => void;
  watch: (delimiter?: string) => { ref$: Observable<RefUpdates>, comment$: (comment: string) => Observable<string> },
  append: (delimiter?: string) => { updates$: Observable<string>, append$: (value: string) => Observable<string> },
}
 
export function mapPlugin(obj: any): Plugin {
  obj.type = 'plugin';
  obj.origin ||= '';
  obj.modifiedString = obj.modified;
  obj.modified &&= DateTime.fromISO(obj.modified);
  return obj;
}
 
export function maybePlugin(obj: any): Plugin | undefined {
  if (!obj) return undefined;
  return mapPlugin(obj);
}
 
export function writePlugin(plugin: Plugin): Plugin {
  const result = { ...plugin };
  result.modified = result.modifiedString as any;
  delete result.type;
  delete result.upload;
  delete result.exists;
  delete result.outdated;
  delete result.modifiedString;
  delete result.config?._cache;
  return result;
}
 
export interface PluginScope {
  [record: string]: any,
  ref: Ref;
  plugin: Plugin;
}
 
export function getPluginScope(plugin?: Config, ref: Ref = { url: '' }, el?: Element, actions?: PluginApi): PluginScope {
  return {
    el,
    actions,
    ref: toJS(ref),
    plugin: toJS(plugin),
    ...toJS(plugin && ref.plugins?.[plugin.tag || ''] || {}),
  };
}