{
  "version": 1,
  "workflows": [
    {
      "id": "5F604A89-7AC2-45D9-B48C-BB540B60CA67",
      "defaultIntroducedVersion": 1,
      "name": "Convert Case",
      "nameLocalizationKey": "convert_identifier_case",
      "summary": "camelCase · PascalCase · snake_case",
      "symbolName": "textformat",
      "isEnabled": true,
      "requiresTrustConfirmation": false,
      "sortOrder": -1,
      "mode": "scriptFilter",
      "supportedTypes": [
        "text"
      ],
      "script": {
        "source": "inline",
        "code": "ObjC.import(\"Foundation\");\n\nfunction readJSON() {\n    var data = $.NSFileHandle.fileHandleWithStandardInput.readDataToEndOfFile;\n    var text = $.NSString.alloc.initWithDataEncoding(data, $.NSUTF8StringEncoding).js;\n    return JSON.parse(text);\n}\n\nfunction writeJSON(value) {\n    var text = JSON.stringify(value);\n    var data = $(text).dataUsingEncoding($.NSUTF8StringEncoding);\n    $.NSFileHandle.fileHandleWithStandardOutput.writeData(data);\n}\n\nfunction wordsFrom(input) {\n    return input.match(/([A-Z]?[a-z]+|[A-Z]+(?![a-z])|\\d+)/g) || [];\n}\n\nfunction isValidInput(input) {\n    if (input.length === 0 || /[^A-Za-z0-9_.\\- ]/.test(input)) {\n        return false;\n    }\n    if (input.indexOf(\"  \") >= 0 || /[_\\-.]$/.test(input)) {\n        return false;\n    }\n    return wordsFrom(input).length > 0;\n}\n\nfunction capitalize(value) {\n    return value.slice(0, 1).toUpperCase() + value.slice(1);\n}\n\nfunction transform(style, input) {\n    var words = wordsFrom(input);\n    if (words.length === 0) {\n        return \"\";\n    }\n\n    switch (style) {\n    case \"camel\":\n        return words[0].toLowerCase() + words.slice(1).map(capitalize).join(\"\");\n    case \"pascal\":\n        return words.map(capitalize).join(\"\");\n    case \"snake\":\n        return words.map(function (word) { return word.toLowerCase(); }).join(\"_\");\n    case \"screamingSnake\":\n        return words.map(function (word) { return word.toUpperCase(); }).join(\"_\");\n    case \"kebab\":\n        return words.map(function (word) { return word.toLowerCase(); }).join(\"-\");\n    case \"train\":\n        return words.map(function (word) {\n            return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase();\n        }).join(\"-\");\n    case \"dot\":\n        return words.map(function (word) { return word.toLowerCase(); }).join(\".\");\n    default:\n        throw new Error(\"Unknown case style: \" + style);\n    }\n}\n\nfunction preferredStyles(input, wordCount) {\n    if (input.indexOf(\"_\") >= 0) {\n        return [\"camel\", \"pascal\", \"kebab\", \"snake\", \"screamingSnake\", \"train\", \"dot\"];\n    }\n    if (input.indexOf(\"-\") >= 0 || input.indexOf(\".\") >= 0) {\n        return [\"camel\", \"pascal\", \"snake\", \"kebab\", \"train\", \"screamingSnake\", \"dot\"];\n    }\n    if (wordCount > 1 && /[A-Z]/.test(input)) {\n        return [\"snake\", \"kebab\", \"screamingSnake\", \"camel\", \"pascal\", \"train\", \"dot\"];\n    }\n    return [\"pascal\", \"screamingSnake\", \"camel\", \"snake\", \"kebab\", \"train\", \"dot\"];\n}\n\nfunction filterActions(input) {\n    if (!isValidInput(input)) {\n        return [];\n    }\n    var words = wordsFrom(input);\n    var definitions = [\n        { id: \"camel\", title: \"camelCase\", multiple: false },\n        { id: \"pascal\", title: \"PascalCase\", multiple: false },\n        { id: \"snake\", title: \"snake_case\", multiple: true },\n        { id: \"screamingSnake\", title: \"SCREAMING_SNAKE_CASE\", multiple: false },\n        { id: \"kebab\", title: \"kebab-case\", multiple: true },\n        { id: \"train\", title: \"Train-Case\", multiple: true },\n        { id: \"dot\", title: \"dot.case\", multiple: true }\n    ];\n    var priority = preferredStyles(input, words.length);\n\n    return definitions.map(function (definition) {\n        return {\n            definition: definition,\n            value: transform(definition.id, input)\n        };\n    }).filter(function (item) {\n        if (item.definition.multiple && words.length < 2) {\n            return false;\n        }\n        return item.value.length > 0 && item.value !== input;\n    }).sort(function (left, right) {\n        return priority.indexOf(left.definition.id) - priority.indexOf(right.definition.id);\n    }).map(function (item) {\n        return {\n            id: item.definition.id,\n            title: item.definition.title,\n            subtitle: item.value,\n            icon: \"textformat\",\n            argument: { style: item.definition.id }\n        };\n    });\n}\n\nfunction main() {\n    var payload = readJSON();\n    var input = ((payload.paste && payload.paste.text) || \"\").trim();\n\n    if (payload.phase === \"filter\") {\n        writeJSON({\n            version: 1,\n            actions: filterActions(input)\n        });\n        return;\n    }\n\n    if (payload.phase === \"execute\") {\n        if (!isValidInput(input)) {\n            throw new Error(\"Invalid identifier input\");\n        }\n        var argument = payload.argument || {};\n        var style = argument.style || payload.actionID;\n        writeJSON({\n            version: 1,\n            result: {\n                type: \"text\",\n                value: transform(style, input)\n            }\n        });\n        return;\n    }\n\n    throw new Error(\"Unsupported phase: \" + payload.phase);\n}\n\nmain();\n",
        "scriptPath": "",
        "interpreterPath": "/usr/bin/osascript",
        "arguments": [
          "-l",
          "JavaScript"
        ],
        "workingDirectory": "",
        "filterTimeout": 5,
        "executeTimeout": 5
      },
      "workflowVersion": 1
    }
  ]
}
