eternity1984/node-red-contrib-friendly-id

View on GitHub
node/friendlyid.html

Summary

Maintainability
Test Coverage
<script type="text/javascript">
    RED.nodes.registerType("friendly-id", {
        category: 'function',
        color: '#C0C0C0',
        icon: "icon.svg",
        inputs: 1,
        outputs: 1,
        defaults: {
            name: {
                value: ""
            },
            mode: {
                value: "GENERATE-NANOID",
                required: true
            },
            charlen: {
                value: 21,
                required: true
            },
            charset: {
                value: "DEFAULT"
            },
            customs: {
                value: "",
                validate: function(v) {
                    var charset = $('#node-input-charset option:selected').val();
                    if (charset === "CUSTOM") {
                        if (v.length == 0) {
                            return false;
                        }
                        var duplicateCount = v.split("")
                            .filter(function(value, index, self) {
                                return self.indexOf(value) !== index;
                            }).length;
                        if (duplicateCount > 0) {
                            return false;
                        }
                        return RED.validators.regex(/[0-9A-Za-z]+/)(v)
                    }
                    return true;
                }
            },
            tostatus: {
                value: false
            },
            statusVal: {
                value: ""
            },
            statusType: {
                value: "auto"
            },
            inputFromVal: {
                value: ""
            },
            inputFromType: {
                value: "auto"
            },
            outputToVal: {
                value: ""
            },
            outputToType: {
                value: "auto"
            }
        },
        label: function() {
            return this.name || "friendly-id";
        },
        labelStyle: function() {
            return this.name ? "node_label_italic" : "";
        },
        oneditprepare: function() {
            var node = this;

            var defaultInOutType = {
                value: "auto",
                label: node._("label.defaultInOutType"),
                hasValue: false
            }
            var inplaceType = {
                value: "inplace",
                label: node._("label.inplaceType"),
                hasValue: false
            }
            var createTypedOutputTypes = function(inplace = true) {
                var dynamicTypes = [defaultInOutType];
                if (inplace) {
                    dynamicTypes.push(inplaceType);
                }
                dynamicTypes.push("msg");
                return dynamicTypes;

            };

            var defaultStatusType = {
                value: "auto",
                label: node._("label.defaultStatusType"),
                hasValue: false
            };
            $("#node-input-typed-status").typedInput({
                default: "auto",
                types: [defaultStatusType, "msg"],
                typeField: $("#node-input-statusType")
            });

            $("#node-input-typed-outputTo").typedInput({
                default: "auto",
                types: createTypedOutputTypes(true),
                typeField: $("#node-input-outputToType")
            })

            $("#node-input-typed-inputFrom").typedInput({
                default: "auto",
                types: [defaultInOutType, "msg"],
                typeField: $("#node-input-inputFromType")
            })
            $("#node-input-typed-inputFrom").typedInput('type', node.inputFromType || node._def.defaults.inputFromType.value);
            $("#node-input-typed-inputFrom").typedInput('value', node.inputFromVal || node._def.defaults.inputFromVal.value);
            $("#node-input-typed-outputTo").typedInput('type', node.outputToType || node._def.defaults.outputToType.value);
            $("#node-input-typed-outputTo").typedInput('value', node.outputToVal || node._def.defaults.outputToVal.value);

            if (node.statusType === undefined) {
                $("#node-input-typed-status").typedInput('type', node._def.defaults.statusType.value);
            }
            if (node.statusVal === undefined) {
                $("#node-input-typed-status").typedInput('value', node._def.defaults.statusVal.value);
            }
            if (node.charlen === undefined) {
                $('#node-input-charlen').val(node._def.defaults.charlen.value);
            }
            if (node.charset === undefined) {
                $('#node-input-charset').val(node._def.defaults.charset.value);
            }

            $("#node-input-tostatus").change(function(e) {
                if ($(this).is(":checked")) {
                    $("#node-input-typed-status").typedInput('type', node.statusType);
                    $("#node-input-typed-status").typedInput('value', node.statusVal);
                    $("#node-tostatus-line").show();
                } else {
                    $("#node-tostatus-line").hide();
                    node.statusType = node._def.defaults.statusType.value;
                    node.statusVal = node._def.defaults.statusVal.value;
                    $("#node-input-typed-status").typedInput('type', node.statusType);
                    $("#node-input-typed-status").typedInput('value', node.statusVal);
                }
            });

            $('#node-input-mode').change(function(e) {
                var inplace = true;
                switch ($('option:selected', this).val()) {
                    case "GENERATE-NANOID":
                        $('#node-nodeid-customs-line').hide();
                        $('#node-nodeid-line').show()
                        inplace = false;
                        break;

                    case "GENERATE-SHORTID":
                    case "GENERATE-UUID4":
                        inplace = false;
                        // break;

                    default:
                        $('#node-nodeid-line').hide()
                        node.charset = node._def.defaults.charset.value;
                        node.charlen = node._def.defaults.charlen.value;
                        $('#node-input-charset').val(node.charset);
                        $('#node-input-charlen').val(node.charlen);
                        break;
                }
                $("#node-input-typed-outputTo").typedInput('types', createTypedOutputTypes(inplace));
                if (inplace) {
                    $('#node-inputs-line').show()
                } else {
                    $('#node-inputs-line').hide()
                    node.inputFromType = node._def.defaults.inputFromType.value;
                    node.inputFromVal = node._def.defaults.inputFromVal.value;
                    $("#node-input-typed-inputFrom").typedInput('type', node.inputFromType);
                    $("#node-input-typed-inputFrom").typedInput('value', node.inputFromVal);
                }
            });
            $('#node-input-charset').change(function(e) {
                if ($('option:selected', this).val() === "CUSTOM") {
                    $("#node-input-customs").val(node.customs || node._def.defaults.customs.value);
                    $('#node-nodeid-customs-line').show();
                } else {
                    $('#node-nodeid-customs-line').hide();
                    node.customs = node._def.defaults.customs.value;
                    $("#node-input-customs").val(node.customs);
                }
            });
        },
        oneditsave: function() {
            $("#node-input-statusVal").val($("#node-input-typed-status").typedInput('value'));
            $("#node-input-inputFromVal").val($("#node-input-typed-inputFrom").typedInput('value'));
            $("#node-input-outputToVal").val($("#node-input-typed-outputTo").typedInput('value'));
        }
    });
</script>

<script type="text/x-red" data-template-name="friendly-id">
    <div class="form-row">
        <label for="node-input-mode"><i class="fa fa-tasks"></i> <span data-i18n="label.mode.title"></span></label>
        <select type="text" id="node-input-mode" style="width:70%">
            <option value="ENCODE" data-i18n="label.mode._encode"></option>
            <option value="DECODE" data-i18n="label.mode._decode"></option>
            <option value="GENERATE-UUID4" data-i18n="label.mode._uuid"></option>
            <option value="GENERATE-SHORTID" data-i18n="label.mode._shortid"></option>
            <option value="GENERATE-NANOID" data-i18n="label.mode._nanoid"></option>
        </select>
    </div>

    <div id="node-nodeid-line">
        <div class="form-row">
            <label for="node-input-charset"><i class="fa fa-keyboard-o"></i> <span data-i18n="label.charset.title"></span></label>
            <select type="text" id="node-input-charset" style="width:70%">
                <option value="DEFAULT" data-i18n="label.charset._default"></option>
                <option value="NUMERIC" data-i18n="label.charset._numbers" data-restricted="0123456789"></option>
                <option value="LOWERCASE" data-i18n="label.charset._lowercase" data-restricted="abcdefghijklmnopqrstuvwxyz"></option>
                <option value="UPPERCASE" data-i18n="label.charset._uppercase" data-restricted="ABCDEFGHIJKLMNOPQRSTUVWXYZ"></option>
                <option value="ALPHANUMERIC" data-i18n="label.charset._alphanumeric" data-restricted="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"></option>
                <option value="NO-LOOKALIKES" data-i18n="label.charset._nolookalikes" data-restricted="346789ABCDEFGHJKLMNPQRTUVWXYabcdefghijkmnpqrtwxyz"></option>
                <option value="NO-LOOKALIKES-SAFE" data-i18n="label.charset._nolookalikessafe" data-restricted="6789BCDFGHJKLMNPQRTWbcdfghjkmnpqrtwz"></option>
                <option value="CUSTOM" data-i18n="label.charset._custom"></option>
            </select>
        </div>
        <div class="form-row" id="node-nodeid-customs-line">
            <label for="node-input-customs"></label>
            <input type="text" id="node-input-customs" data-i18n="[placeholder]label.charset.unique">
        </div>

        <div class="form-row">
            <label for="node-input-charlen"><i class="fa fa-puzzle-piece"></i> <span data-i18n="label.charlen.title"></span></label>
            <input type="number" min="2" max="32" id="node-input-charlen" style="text-align:end; width:70px !important" oninput="this.value = Math.min(this.max, Math.max(this.min, this.value))">
        </div>
    </div>

    <hr>

    <div class="form-row" id="node-inputs-line">
        <label for="node-input-typed-inputFrom"><i class="fa fa-sign-in"></i> <span data-i18n="label.inputFrom"></span></label>
        <input id="node-input-typed-inputFrom" type="text" style="width: 70%">
        <input id="node-input-inputFromVal" type="hidden">
        <input id="node-input-inputFromType" type="hidden">
    </div>

    <div class="form-row" id="node-outputs-line">
        <label for="node-input-typed-outputTo"><i class="fa fa-sign-out"></i> <span data-i18n="label.outputTo"></span></label>
        <input id="node-input-typed-outputTo" type="text" style="width: 70%">
        <input id="node-input-outputToVal" type="hidden">
        <input id="node-input-outputToType" type="hidden">
    </div>

    <hr>

    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
    </div>

    <div class="form-row">
        <label for="node-input-tostatus">&nbsp;</label>
        <label for="node-input-tostatus" style="width: 70%;">
            <input type="checkbox" id="node-input-tostatus" style="display: inline-block; width: auto; vertical-align: top;"> <span data-i18n="label.tostatus"></span>
        </label>
    </div>

    <div class="form-row" id="node-tostatus-line">
        <label for="node-input-typed-status">&nbsp;</label>
        <input id="node-input-typed-status" type="text" style="width: 70%">
        <input id="node-input-statusVal" type="hidden">
        <input id="node-input-statusType" type="hidden">
    </div>
</script>