UNPKG

@nodescript/core

Version:

Visual programming language for Browser and Node

169 lines 5.26 kB
import { clone } from '../util/clone.js'; import { evaluateEscapes } from '../util/escape.js'; export class PropLineView { constructor(node, propKey, propLine) { this.node = node; this.propKey = propKey; this.propLine = propLine; const paramSpec = this.node.getModuleSpec().params[this.propKey] ?? { schema: { type: 'any' }, }; let schema = paramSpec.schema; if (['@system/Output', '@system/Result'].includes(this.node.ref)) { schema = this.graph.moduleSpec.result.schema; } this._paramSpec = { ...paramSpec, schema, }; } toJSON() { return clone(this.propLine); } get graph() { return this.node.graph; } get value() { return this.propLine.value; } get linkId() { return this.propLine.linkId; } get linkKey() { return this.propLine.linkKey; } getParamSpec() { return this._paramSpec; } getStaticValue() { return evaluateEscapes(this.value); } isUsingDefaultValue() { return this.getStaticValue() === ''; } /** * Returns the node identified by its linkId. */ getLinkNode() { const { linkId } = this.propLine; return linkId ? this.graph.getNodeById(linkId) : null; } isLinked() { const { linkId } = this.propLine; return !!linkId && this.graph.isNodeExists(linkId); } canExpand() { return true; } isExpanded() { return this.canExpand() && this.propLine.expand && this.isLinked(); } isDeferred() { return this.getParamSpec().deferred && this.isLinked() && !this.propLine.expand; } } export class PropView extends PropLineView { constructor(node, propKey, propSpec) { super(node, propKey, propSpec); this.propSpec = propSpec; } get lineUid() { return this.node.nodeUid + ':' + this.propKey; } getSchema() { return this.getParamSpec().schema; } getEntries() { return [ ...this.getManagedEntries(), ...this.getCustomEntries(), ]; } /** * Managed entries appear for each property defined in parent prop's schema. * * They are special in a couple ways: * * - users can't delete them or change their key * - the order of managed entries is predefined * - they have stable ids so that they are consistently persisted */ getManagedEntries() { const schema = this.getSchema(); if (schema.type !== 'object') { return []; } const existingEntries = (this.propSpec.entries ?? []).filter(_ => _.managed); const entries = []; for (const key of Object.keys(schema.properties ?? {})) { const id = key.replace(/[^0-9a-z]/i, '_'); const entrySpec = existingEntries.find(_ => _.id === id) ?? { id, key, value: '', managed: true, expand: false }; entries.push(new PropEntryView(this, entrySpec)); } return entries; } getCustomEntries() { const entrySpecs = (this.propSpec.entries ?? []).filter(_ => !_.managed); return entrySpecs.map(_ => new PropEntryView(this, _)); } isSupportsEntries() { const schema = this.getSchema(); const { hideEntries } = this.getParamSpec(); return !hideEntries && (schema.type === 'object' || schema.type === 'array'); } isUsesEntries() { return this.isSupportsEntries() && this.isListed() && !this.isLinked(); } hasEntries() { return (this.propSpec.entries?.length ?? 0) > 0; } isAdvanced() { return !!this.getParamSpec().advanced; } isListed() { if (!this.isAdvanced()) { return true; } // Advanced props are rendered when either: // - value is specified and non-default // - prop is linked // - prop key is explicitly added to node metadata // - prop has entries return !!this.node.metadata.listedProps[this.propKey] || !this.isUsingDefaultValue() || this.isLinked() || this.hasEntries(); } } export class PropEntryView extends PropLineView { constructor(parentProp, propEntrySpec) { super(parentProp.node, parentProp.propKey, propEntrySpec); this.parentProp = parentProp; this.propEntrySpec = propEntrySpec; } get id() { return this.propEntrySpec.id; } get key() { return this.propEntrySpec.key; } get lineUid() { return this.parentProp.lineUid + ':' + this.propEntrySpec.id; } isManaged() { return this.propEntrySpec.managed; } getSchema() { const baseSchema = this.parentProp.getSchema(); switch (baseSchema.type) { case 'array': return baseSchema.items ?? { type: 'any' }; case 'object': return baseSchema.properties?.[this.key] ?? baseSchema.additionalProperties ?? { type: 'any' }; default: return { type: 'any' }; } } } //# sourceMappingURL=PropView.js.map