├── .nvmrc ├── src ├── interfaces │ ├── WF │ │ ├── WFAppIdentifier.ts │ │ ├── WFItemType.ts │ │ ├── WFEncodeMode.ts │ │ ├── FaceTimeType.ts │ │ ├── WFWiFiDetail.ts │ │ ├── WFWorkflowImportQuestion.ts │ │ ├── WFMapsApps.ts │ │ ├── WFHTTPBodyType.ts │ │ ├── WFDateActionMode.ts │ │ ├── WFHashType.ts │ │ ├── WFIPAddressTypeOption.ts │ │ ├── WFInputType.ts │ │ ├── WFCondition.ts │ │ ├── WFFlashlightSetting.ts │ │ ├── WFSkipBackBehavior.ts │ │ ├── WFIPAddressSourceOption.ts │ │ ├── WFNetworkDetailsNetwork.ts │ │ ├── WFWorkflowType.ts │ │ ├── WFTimeUntilReferenceDate.ts │ │ ├── AssertionType.ts │ │ ├── WFMathOperation.ts │ │ ├── WFHTTPMethod.ts │ │ ├── WFRelativeDateFormatStyle.ts │ │ ├── WFWorkflowIcon.ts │ │ ├── WFAskActionDateGranularity.ts │ │ ├── WFCountType.ts │ │ ├── WFGetDictionaryValueType.ts │ │ ├── WFBase64LineBreakMode.ts │ │ ├── Type.ts │ │ ├── WFCellularDetail.ts │ │ ├── WFFrequency.ts │ │ ├── WFArchiveFormat.ts │ │ ├── WFTimeUntilUnit.ts │ │ ├── WFCaseType.ts │ │ ├── WFStatisticsOperation.ts │ │ ├── WFDeviceDetail.ts │ │ ├── WFSerializationType.ts │ │ ├── WFTimeFormatStyle.ts │ │ ├── AggrandizementType.ts │ │ ├── WFDateFormatStyle.ts │ │ ├── Attachment.ts │ │ ├── WFDictionaryFieldValueItem.ts │ │ ├── WFScientificMathOperation.ts │ │ ├── WFWorkflowAction.ts │ │ ├── WFWorkflowInputContentItemClass.ts │ │ ├── WFWorkflow.ts │ │ ├── AggrandizementCoercionItemClass.ts │ │ ├── WFSerialization.ts │ │ └── Aggrandizement.ts │ ├── BuildShortcutOptions.ts │ └── Value.ts ├── meta │ ├── index.ts │ └── colors.ts ├── actions │ ├── pythonista │ │ ├── index.ts │ │ ├── editScript.ts │ │ └── runScript.ts │ ├── share.ts │ ├── openURLs.ts │ ├── call.ts │ ├── pauseMusic.ts │ ├── clearUpNext.ts │ ├── tweet.ts │ ├── skipForward.ts │ ├── vibrateDevice.ts │ ├── trimMedia.ts │ ├── getClipboard.ts │ ├── print.ts │ ├── showDefinition.ts │ ├── addToReadingList.ts │ ├── correctSpelling.ts │ ├── getLastImport.ts │ ├── getCurrentSong.ts │ ├── playSound.ts │ ├── airDrop.ts │ ├── getDatesFromInput.ts │ ├── markup.ts │ ├── createNote.ts │ ├── getCurrentLocation.ts │ ├── openInBooks.ts │ ├── getContactsFromInput.ts │ ├── getFramesFromImage.ts │ ├── quickLook.ts │ ├── removeReminders.ts │ ├── continueShortcutInApp.ts │ ├── exitShortcut.ts │ ├── getAddressesFromInput.ts │ ├── nothing.ts │ ├── postOnFacebook.ts │ ├── getNameOfEmoji.ts │ ├── openURLsInChrome.ts │ ├── postToTumblr.ts │ ├── shareWithExtensions.ts │ ├── deletePhotos.ts │ ├── getLinkToFile.ts │ ├── getURLsFromInput.ts │ ├── makeRichTextFromHTML.ts │ ├── viewContentGraph.ts │ ├── postToWordPress.ts │ ├── getBatteryLevel.ts │ ├── getType.ts │ ├── showInCalendar.ts │ ├── getHeadersOfURL.ts │ ├── scanQROrBarcode.ts │ ├── expandURL.ts │ ├── extractArchive.ts │ ├── getMapsURL.ts │ ├── URL.ts │ ├── getContentsOfWebPage.ts │ ├── getImagesFromInput.ts │ ├── makeMarkdownFromRichText.ts │ ├── makeRichTextFromMarkdown.ts │ ├── showInITunesStore.ts │ ├── waitToReturn.ts │ ├── detectLanguageWithMicrosoft.ts │ ├── openApp.ts │ ├── selectEmailAddress.ts │ ├── selectPhoneNumber.ts │ ├── setWiFi.ts │ ├── getName.ts │ ├── getPhoneNumbersFromInput.ts │ ├── getTextFromInput.ts │ ├── getEmailAddressesFromInput.ts │ ├── getMyShortcuts.ts │ ├── setVolume.ts │ ├── wait.ts │ ├── setBluetooth.ts │ ├── setAirplaneMode.ts │ ├── setCellularData.ts │ ├── setLowPowerMode.ts │ ├── getDiffbotArticleFromWebPage.ts │ ├── setBrightness.ts │ ├── number.ts │ ├── getDictionaryFromInput.ts │ ├── comment.ts │ ├── postOnInstagram.ts │ ├── showResult.ts │ ├── getVariable.ts │ ├── getLatestVideos.ts │ ├── setTorch.ts │ ├── setVariable.ts │ ├── getLatestBursts.ts │ ├── text.ts │ ├── getLatestScreenshots.ts │ ├── getLatestLivePhotos.ts │ ├── list.ts │ ├── count.ts │ ├── skipBack.ts │ ├── generateHash.ts │ ├── showInMaps.ts │ ├── runShortcut.ts │ ├── facetime.ts │ ├── URLEncode.ts │ ├── setDictionaryValue.ts │ ├── changeCase.ts │ ├── addToVariable.ts │ ├── getDeviceDetails.ts │ ├── setName.ts │ ├── getDictionaryValue.ts │ └── calculateStatistics.ts ├── index.ts ├── utils │ ├── flatten.ts │ ├── encodeShortcut.ts │ ├── variable.ts │ ├── actionOutput.ts │ ├── index.ts │ ├── withActionOutput.ts │ └── withVariables.ts └── variables.ts ├── docs ├── src │ ├── index.js │ ├── components │ │ ├── App │ │ │ ├── index.js │ │ │ ├── styles.module.scss │ │ │ └── component.jsx │ │ ├── Docs │ │ │ ├── index.js │ │ │ ├── Markdown │ │ │ │ └── index.js │ │ │ ├── Metadata │ │ │ │ ├── content.md │ │ │ │ ├── index.js │ │ │ │ ├── styles.module.scss │ │ │ │ ├── ShortcutIcon │ │ │ │ │ ├── index.js │ │ │ │ │ └── content.md │ │ │ │ └── component.jsx │ │ │ ├── NotFound │ │ │ │ ├── content.md │ │ │ │ ├── index.js │ │ │ │ ├── styles.module.scss │ │ │ │ └── component.jsx │ │ │ ├── Screenshot │ │ │ │ ├── index.js │ │ │ │ ├── frame-xs-max.png │ │ │ │ ├── styles.module.scss │ │ │ │ └── component.jsx │ │ │ ├── Variables │ │ │ │ ├── index.js │ │ │ │ ├── screenshot00.png │ │ │ │ ├── screenshot01.png │ │ │ │ ├── screenshot02.png │ │ │ │ ├── styles.module.scss │ │ │ │ └── component.jsx │ │ │ ├── GettingStarted │ │ │ │ ├── index.js │ │ │ │ ├── styles.module.scss │ │ │ │ ├── component.jsx │ │ │ │ └── content.md │ │ │ ├── Contributing │ │ │ │ └── ActionIcons │ │ │ │ │ ├── index.js │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ ├── content.md │ │ │ │ │ └── component.jsx │ │ │ └── Actions │ │ │ │ ├── index.js │ │ │ │ └── icons@2x.png │ │ └── Home │ │ │ ├── index.js │ │ │ ├── Button │ │ │ └── index.js │ │ │ ├── Footer │ │ │ ├── index.js │ │ │ └── styles.module.scss │ │ │ ├── CodeEditor │ │ │ ├── index.js │ │ │ └── styles.module.scss │ │ │ ├── Contributors │ │ │ └── index.js │ │ │ ├── ExternalLinks │ │ │ ├── index.js │ │ │ └── atp-artwork.jpg │ │ │ ├── Jumbotron │ │ │ └── index.js │ │ │ ├── AboutTheAuthor │ │ │ ├── index.js │ │ │ └── headshot.jpg │ │ │ └── ShortcutCreator │ │ │ ├── index.js │ │ │ └── styles.module.scss │ ├── contributors.json │ ├── styles │ │ └── variables.scss │ └── index.jsx ├── .env ├── public │ ├── favicon.ico │ └── manifest.json └── .eslintrc.js ├── meta.js ├── actions.js ├── assets ├── logo.png ├── demo-shortcut.jpeg └── battery-checker-shortcut.jpeg ├── variables.js ├── tsconfig.release.json ├── __tests__ ├── meta │ ├── colors.spec.ts │ ├── glyphs.spec.ts │ └── index.spec.ts ├── actions │ ├── call.spec.ts │ ├── share.spec.ts │ ├── print.spec.ts │ ├── tweet.spec.ts │ ├── openURLs.spec.ts │ ├── nothing.spec.ts │ ├── markup.spec.ts │ ├── playSound.spec.ts │ ├── airDrop.spec.ts │ ├── expandURL.spec.ts │ ├── getName.spec.ts │ ├── getType.spec.ts │ ├── pauseMusic.spec.ts │ ├── trimMedia.spec.ts │ ├── clearUpNext.spec.ts │ ├── deletePhotos.spec.ts │ ├── getClipboard.spec.ts │ ├── getMapsURL.spec.ts │ ├── openInBooks.spec.ts │ ├── quickLook.spec.ts │ ├── skipForward.spec.ts │ ├── exitShortcut.spec.ts │ ├── extractArchive.spec.ts │ ├── createNote.spec.ts │ ├── getLinkToFile.spec.ts │ ├── getCurrentSong.spec.ts │ ├── getLastImport.spec.ts │ ├── postToTumblr.spec.ts │ ├── showDefinition.spec.ts │ ├── correctSpelling.spec.ts │ ├── getNameOfEmoji.spec.ts │ ├── removeReminders.spec.ts │ ├── scanQROrBarcode.spec.ts │ ├── showInCalendar.spec.ts │ ├── addToReadingList.spec.ts │ ├── getHeadersOfURL.spec.ts │ ├── openURLsInChrome.spec.ts │ ├── getDatesFromInput.spec.ts │ ├── getMyShortcuts.spec.ts │ ├── getTextFromInput.spec.ts │ ├── getURLsFromInput.spec.ts │ ├── postOnFacebook.spec.ts │ ├── showInITunesStore.spec.ts │ ├── postToWordPress.spec.ts │ ├── selectPhoneNumber.spec.ts │ ├── viewContentGraph.spec.ts │ ├── getImagesFromInput.spec.ts │ ├── selectEmailAddress.spec.ts │ ├── vibrateDevice.spec.ts │ ├── waitToReturn.spec.ts │ ├── getCurrentLocation.spec.ts │ ├── getFramesFromImage.spec.ts │ ├── shareWithExtensions.spec.ts │ ├── getAddressesFromInput.spec.ts │ ├── getContactsFromInput.spec.ts │ ├── continueShortcutInApp.spec.ts │ ├── getBatteryLevel.spec.ts │ ├── getContentsOfWebPage.spec.ts │ ├── makeRichTextFromHTML.spec.ts │ ├── getDictionaryFromInput.spec.ts │ ├── getDiffbotArticleFromWebPage.spec.ts │ ├── getPhoneNumbersFromInput.spec.ts │ ├── makeMarkdownFromRichText.spec.ts │ ├── makeRichTextFromMarkdown.spec.ts │ ├── detectLanguageWithMicrosoft.spec.ts │ ├── getEmailAddressesFromInput.spec.ts │ ├── setVariable.spec.ts │ ├── addToVariable.spec.ts │ ├── URL.spec.ts │ ├── wait.spec.ts │ ├── setWiFi.spec.ts │ ├── count.spec.ts │ ├── URLEncode.spec.ts │ ├── comment.spec.ts │ ├── openApp.spec.ts │ ├── number.spec.ts │ ├── list.spec.ts │ ├── setBluetooth.spec.ts │ ├── setTorch.spec.ts │ ├── pythonista │ │ ├── runScript.spec.ts │ │ └── editScript.spec.ts │ ├── runScriptOverSSH.spec.ts │ ├── setBrightness.spec.ts │ ├── setVolume.spec.ts │ ├── setAirplaneMode.spec.ts │ ├── setCellularData.spec.ts │ ├── setLowPowerMode.spec.ts │ ├── getLatestVideos.spec.ts │ ├── getDeviceDetails.spec.ts │ └── postOnInstagram.spec.ts ├── utils │ ├── encodeShortcut.spec.ts │ ├── variable.spec.ts │ └── flatten.spec.ts └── _helpers │ └── compareObjectsWithGroupingIdentifier.ts ├── .travis.yml ├── tslint.json ├── .gitignore ├── .npmignore ├── jest.config.js ├── tsconfig.json └── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE └── request-new-actions.md /.nvmrc: -------------------------------------------------------------------------------- 1 | 10 -------------------------------------------------------------------------------- /src/interfaces/WF/WFAppIdentifier.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.jsx'; 2 | -------------------------------------------------------------------------------- /docs/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | 3 | -------------------------------------------------------------------------------- /meta.js: -------------------------------------------------------------------------------- 1 | const meta = require('./build/meta'); 2 | 3 | module.exports = meta; 4 | -------------------------------------------------------------------------------- /actions.js: -------------------------------------------------------------------------------- 1 | const actions = require('./build/actions'); 2 | 3 | module.exports = actions; 4 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/assets/logo.png -------------------------------------------------------------------------------- /variables.js: -------------------------------------------------------------------------------- 1 | const variables = require('./build/variables'); 2 | 3 | module.exports = variables; 4 | -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/src/components/App/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /assets/demo-shortcut.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/assets/demo-shortcut.jpeg -------------------------------------------------------------------------------- /docs/src/components/Docs/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Markdown/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/content.md: -------------------------------------------------------------------------------- 1 | ## Metadata 2 | 3 | [WIP] 4 | 5 | ### Build Options 6 | 7 | [WIP] 8 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Docs/NotFound/content.md: -------------------------------------------------------------------------------- 1 | ## 404 Page Not Found 2 | 3 | This page is missing. 4 | 5 | [WIP] 6 | -------------------------------------------------------------------------------- /docs/src/components/Docs/NotFound/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/Button/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/Footer/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Screenshot/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/CodeEditor/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/Contributors/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/ExternalLinks/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/Jumbotron/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFItemType.ts: -------------------------------------------------------------------------------- 1 | type WFItemType = ( 2 | 0 | 1 | 2 | 3 | 4 3 | ); 4 | 5 | export default WFItemType; 6 | -------------------------------------------------------------------------------- /docs/src/components/Docs/GettingStarted/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/AboutTheAuthor/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /docs/src/components/Home/ShortcutCreator/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /assets/battery-checker-shortcut.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/assets/battery-checker-shortcut.jpeg -------------------------------------------------------------------------------- /docs/src/components/Docs/Contributing/ActionIcons/index.js: -------------------------------------------------------------------------------- 1 | import Component from './component'; 2 | 3 | export default Component; 4 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFEncodeMode.ts: -------------------------------------------------------------------------------- 1 | type WFEncodeMode = ( 2 | 'Encode' 3 | | 'Decode' 4 | ); 5 | 6 | export default WFEncodeMode; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/FaceTimeType.ts: -------------------------------------------------------------------------------- 1 | type FaceTimeType = ( 2 | 'Audio' 3 | | 'Video' 4 | ); 5 | 6 | export default FaceTimeType; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWiFiDetail.ts: -------------------------------------------------------------------------------- 1 | type WFWiFiDetail = ( 2 | 'Network Name' 3 | | 'BSSID' 4 | ); 5 | 6 | export default WFWiFiDetail; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflowImportQuestion.ts: -------------------------------------------------------------------------------- 1 | interface WFWorkflowImportQuestion { 2 | } 3 | 4 | export default WFWorkflowImportQuestion; 5 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Actions/index.js: -------------------------------------------------------------------------------- 1 | import Component, { Icon } from './component'; 2 | 3 | export default Component; 4 | export { Icon }; 5 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFMapsApps.ts: -------------------------------------------------------------------------------- 1 | type WFMapsApps = ( 2 | 'Maps' 3 | | 'Google Maps' 4 | | 'Waze' 5 | ); 6 | 7 | export default WFMapsApps; 8 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Actions/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Docs/Actions/icons@2x.png -------------------------------------------------------------------------------- /src/interfaces/WF/WFHTTPBodyType.ts: -------------------------------------------------------------------------------- 1 | type WFHTTPBodyType = ( 2 | 'JSON' 3 | | 'Form' 4 | | 'File' 5 | ); 6 | 7 | export default WFHTTPBodyType; 8 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/styles.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 1.7rem; 3 | max-width: 100%; 4 | width: var(--max-content-width); 5 | } 6 | -------------------------------------------------------------------------------- /docs/src/components/Docs/NotFound/styles.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 1.7rem; 3 | max-width: 100%; 4 | width: var(--max-content-width); 5 | } 6 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/screenshot00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Docs/Variables/screenshot00.png -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/screenshot01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Docs/Variables/screenshot01.png -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/screenshot02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Docs/Variables/screenshot02.png -------------------------------------------------------------------------------- /src/interfaces/WF/WFDateActionMode.ts: -------------------------------------------------------------------------------- 1 | type WFDateActionMode = ( 2 | 'Current Date' 3 | | 'Specified Date' 4 | ); 5 | 6 | export default WFDateActionMode; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFHashType.ts: -------------------------------------------------------------------------------- 1 | type WFHashType = ( 2 | 'MD5' 3 | | 'SHA1' 4 | | 'SHA256' 5 | | 'SHA512' 6 | ); 7 | 8 | export default WFHashType; 9 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFIPAddressTypeOption.ts: -------------------------------------------------------------------------------- 1 | type WFIPAddressTypeOption = ( 2 | 'IPv4' 3 | | 'IPv6' 4 | ); 5 | 6 | export default WFIPAddressTypeOption; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFInputType.ts: -------------------------------------------------------------------------------- 1 | type WFInputType = ( 2 | 'Text' 3 | | 'Number' 4 | | 'URL' 5 | | 'Date' 6 | ); 7 | 8 | export default WFInputType; 9 | -------------------------------------------------------------------------------- /src/meta/index.ts: -------------------------------------------------------------------------------- 1 | import { COLORS } from './colors'; 2 | import { GLYPHS } from './glyphs'; 3 | 4 | export const ICON = { 5 | COLORS, 6 | GLYPHS, 7 | }; 8 | -------------------------------------------------------------------------------- /docs/src/components/Docs/GettingStarted/styles.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 1.7rem; 3 | max-width: 100%; 4 | width: var(--max-content-width); 5 | } 6 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/ShortcutIcon/index.js: -------------------------------------------------------------------------------- 1 | import Component, { Glyph } from './component'; 2 | 3 | export default Component; 4 | export { Glyph }; 5 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Screenshot/frame-xs-max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Docs/Screenshot/frame-xs-max.png -------------------------------------------------------------------------------- /docs/src/components/Home/AboutTheAuthor/headshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Home/AboutTheAuthor/headshot.jpg -------------------------------------------------------------------------------- /docs/src/components/Home/ExternalLinks/atp-artwork.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshfarrant/shortcuts-js/HEAD/docs/src/components/Home/ExternalLinks/atp-artwork.jpg -------------------------------------------------------------------------------- /src/interfaces/WF/WFCondition.ts: -------------------------------------------------------------------------------- 1 | type WFCondition = ( 2 | 'Equals' 3 | | 'Is Greater Than' 4 | | 'Is Less Than' 5 | ); 6 | 7 | export default WFCondition; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFFlashlightSetting.ts: -------------------------------------------------------------------------------- 1 | type WFFlashlightSetting = ( 2 | 'On' 3 | | 'Off' 4 | | 'Toggle' 5 | ); 6 | 7 | export default WFFlashlightSetting; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFSkipBackBehavior.ts: -------------------------------------------------------------------------------- 1 | type WFSkipBackBehavior = ( 2 | 'Beginning' 3 | | 'Previous Song' 4 | ); 5 | 6 | export default WFSkipBackBehavior; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFIPAddressSourceOption.ts: -------------------------------------------------------------------------------- 1 | type WFIPAddressSourceOption = ( 2 | 'External' 3 | | 'Local' 4 | ); 5 | 6 | export default WFIPAddressSourceOption; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFNetworkDetailsNetwork.ts: -------------------------------------------------------------------------------- 1 | type WFNetworkDetailsNetwork = ( 2 | 'Wi-Fi' 3 | | 'Cellular' 4 | ); 5 | 6 | export default WFNetworkDetailsNetwork; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflowType.ts: -------------------------------------------------------------------------------- 1 | type WFWorkflowType = ( 2 | 'ActionExtension' 3 | | 'NCWidget' 4 | | 'WatchKit' 5 | ); 6 | 7 | export default WFWorkflowType; 8 | -------------------------------------------------------------------------------- /src/actions/pythonista/index.ts: -------------------------------------------------------------------------------- 1 | import editScript from './editScript'; 2 | import runScript from './runScript'; 3 | 4 | export { 5 | editScript, 6 | runScript, 7 | }; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFTimeUntilReferenceDate.ts: -------------------------------------------------------------------------------- 1 | type WFTimeUntilReferenceDate = ( 2 | 'Right Now' 3 | | 'Other' 4 | ); 5 | 6 | export default WFTimeUntilReferenceDate; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/AssertionType.ts: -------------------------------------------------------------------------------- 1 | type AssertionType = ( 2 | 'Turned Off' 3 | | 'Time' 4 | | 'I Leave' 5 | | 'Event Ends' 6 | ); 7 | 8 | export default AssertionType; 9 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFMathOperation.ts: -------------------------------------------------------------------------------- 1 | type WFMathOperation = ( 2 | '+' 3 | | '-' 4 | | '×' 5 | | '÷' 6 | | '…' 7 | ); 8 | 9 | export default WFMathOperation; 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFHTTPMethod.ts: -------------------------------------------------------------------------------- 1 | type WFHTTPMethod = ( 2 | 'GET' 3 | | 'POST' 4 | | 'PUT' 5 | | 'DELETE' 6 | | 'PATCH' 7 | ); 8 | 9 | export default WFHTTPMethod; 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFRelativeDateFormatStyle.ts: -------------------------------------------------------------------------------- 1 | type WFRelativeDateFormatStyle = ( 2 | 'Short' 3 | | 'Medium' 4 | | 'Long' 5 | ); 6 | 7 | export default WFRelativeDateFormatStyle; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflowIcon.ts: -------------------------------------------------------------------------------- 1 | interface WFWorkflowIcon { 2 | WFWorkflowIconStartColor: number; 3 | WFWorkflowIconGlyphNumber: number; 4 | } 5 | 6 | export default WFWorkflowIcon; 7 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFAskActionDateGranularity.ts: -------------------------------------------------------------------------------- 1 | type WFAskActionDateGranularity = ( 2 | 'Date' 3 | | 'Time' 4 | | 'Date and Time' 5 | ); 6 | 7 | export default WFAskActionDateGranularity; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFCountType.ts: -------------------------------------------------------------------------------- 1 | type WFCountType = ( 2 | 'Items' 3 | | 'Characters' 4 | | 'Words' 5 | | 'Sentences' 6 | | 'Lines' 7 | ); 8 | 9 | export default WFCountType; 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFGetDictionaryValueType.ts: -------------------------------------------------------------------------------- 1 | type WFGetDictionaryValueType = ( 2 | 'Value' 3 | | 'All Keys' 4 | | 'All Values' 5 | ); 6 | 7 | export default WFGetDictionaryValueType; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFBase64LineBreakMode.ts: -------------------------------------------------------------------------------- 1 | type WFBase64LineBreakMode = ( 2 | 'None' 3 | | 'Every 64 Characters' 4 | | 'Every 76 Characters' 5 | ); 6 | 7 | export default WFBase64LineBreakMode; 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/Type.ts: -------------------------------------------------------------------------------- 1 | type Type = ( 2 | 'ActionOutput' 3 | | 'Ask' 4 | | 'Clipboard' 5 | | 'CurrentDate' 6 | | 'ExtensionInput' 7 | | 'Variable' 8 | ); 9 | 10 | export default Type; 11 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/styles.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 1.7rem; 3 | max-width: 100%; 4 | width: var(--max-content-width); 5 | } 6 | 7 | .center { 8 | text-align: center; 9 | } 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFCellularDetail.ts: -------------------------------------------------------------------------------- 1 | type WFCellularDetail = ( 2 | 'Carrier Name' 3 | | 'Radio Technology' 4 | | 'Country Code' 5 | | 'WFTextTokenAttachment' 6 | ); 7 | 8 | export default WFCellularDetail; 9 | -------------------------------------------------------------------------------- /src/interfaces/BuildShortcutOptions.ts: -------------------------------------------------------------------------------- 1 | interface BuildShortcutOptions { 2 | icon: { 3 | color: number; 4 | glyph: number; 5 | }; 6 | showInWidget: boolean; 7 | } 8 | 9 | export default BuildShortcutOptions; 10 | -------------------------------------------------------------------------------- /src/interfaces/Value.ts: -------------------------------------------------------------------------------- 1 | export type Value = string | number | boolean | ValueObject | ValueArray; 2 | 3 | export interface ValueObject { 4 | [x: string]: Value; 5 | } 6 | 7 | export interface ValueArray extends Array {} 8 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFFrequency.ts: -------------------------------------------------------------------------------- 1 | type WFFrequency = ( 2 | 'Sunday' 3 | | 'Monday' 4 | | 'Tuesday' 5 | | 'Wednesday' 6 | | 'Thursday' 7 | | 'Friday' 8 | | 'Saturday' 9 | ); 10 | 11 | export default WFFrequency; 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | actionOutput, 3 | buildShortcut, 4 | variable, 5 | withVariables, 6 | } from './utils'; 7 | 8 | export { 9 | actionOutput, 10 | buildShortcut, 11 | variable, 12 | withVariables, 13 | }; 14 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFArchiveFormat.ts: -------------------------------------------------------------------------------- 1 | type WFArchiveFormat = ( 2 | 'zip' 3 | | 'tar.gz' 4 | | 'tar.bz2' 5 | | 'tar.xz' 6 | | 'tar' 7 | | 'gz' 8 | | 'cpio' 9 | | 'iso' 10 | ); 11 | 12 | export default WFArchiveFormat; 13 | -------------------------------------------------------------------------------- /tsconfig.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src", 5 | "outDir": "build", 6 | "removeComments": false, 7 | }, 8 | "include": [ 9 | "src/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /docs/src/contributors.json: -------------------------------------------------------------------------------- 1 | [ 2 | "pietropizzi", 3 | "Archez", 4 | "DanielRuf", 5 | "xAlien95", 6 | "gcordalis", 7 | "JB1905", 8 | "bachya", 9 | "ikaikastine", 10 | "regaw-leinad", 11 | "jakebathman", 12 | "jtokash" 13 | ] 14 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFTimeUntilUnit.ts: -------------------------------------------------------------------------------- 1 | type WFTimeUntilUnit = ( 2 | 'Total Time' 3 | | 'Seconds' 4 | | 'Minutes' 5 | | 'Hours' 6 | | 'Days' 7 | | 'Weeks' 8 | | 'Months' 9 | | 'Years' 10 | ); 11 | 12 | export default WFTimeUntilUnit; 13 | -------------------------------------------------------------------------------- /src/utils/flatten.ts: -------------------------------------------------------------------------------- 1 | /** @ignore */ 2 | export const flatten = (arr: T[]): T[] => ( 3 | arr.reduce( 4 | (acc: T[], val: T) => ( 5 | Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val) 6 | ), 7 | [], 8 | ) 9 | ); 10 | -------------------------------------------------------------------------------- /docs/src/components/App/styles.module.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | position: absolute; 3 | width: 100%; 4 | height: 100%; 5 | overflow-y: scroll; 6 | } 7 | 8 | @media (pointer: coarse) { 9 | .container { 10 | position: initial; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFCaseType.ts: -------------------------------------------------------------------------------- 1 | type WFCaseType = ( 2 | 'lowercase' 3 | | 'Capitalize Every Word' 4 | | 'Capitalize with Title Case' 5 | | 'Capitalize with sentence case.' 6 | | 'cApItAlIzE wItH aLtErNaTiNg CaSe.' 7 | ); 8 | 9 | export default WFCaseType; 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFStatisticsOperation.ts: -------------------------------------------------------------------------------- 1 | type WFStatisticsOperation = ( 2 | 'Average' 3 | | 'Minimum' 4 | | 'Maximum' 5 | | 'Sum' 6 | | 'Median' 7 | | 'Mode' 8 | | 'Range' 9 | | 'Standard Deviation' 10 | ); 11 | 12 | export default WFStatisticsOperation; 13 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFDeviceDetail.ts: -------------------------------------------------------------------------------- 1 | type WFDeviceDetail = ( 2 | 'Device Name' 3 | | 'Device Model' 4 | | 'System Version' 5 | | 'Screen Width' 6 | | 'Screen Height' 7 | | 'Current Volume' 8 | | 'Current Brightness' 9 | ); 10 | 11 | export default WFDeviceDetail; 12 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFSerializationType.ts: -------------------------------------------------------------------------------- 1 | type WFSerializationType = ( 2 | 'WFArrayParameterState' 3 | | 'WFDictionaryFieldValue' 4 | | 'WFNumberSubstitutableState' 5 | | 'WFTextTokenAttachment' 6 | | 'WFTextTokenString' 7 | ); 8 | 9 | export default WFSerializationType; 10 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFTimeFormatStyle.ts: -------------------------------------------------------------------------------- 1 | type WFTimeFormatStyle = ( 2 | 'None' 3 | | 'Short' 4 | | 'Medium' 5 | | 'Long' 6 | | 'Relative' // only in Format Date action 7 | | 'ISO 8601 Time' // only in as Date aggrandizement 8 | ); 9 | 10 | export default WFTimeFormatStyle; 11 | -------------------------------------------------------------------------------- /src/interfaces/WF/AggrandizementType.ts: -------------------------------------------------------------------------------- 1 | type AggrandizementType = ( 2 | 'WFCoercionVariableAggrandizement' 3 | | 'WFDateFormatVariableAggrandizement' 4 | | 'WFDictionaryValueVariableAggrandizement' 5 | | 'WFPropertyVariableAggrandizement' 6 | ); 7 | 8 | export default AggrandizementType; 9 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFDateFormatStyle.ts: -------------------------------------------------------------------------------- 1 | type WFDateFormatStyle = ( 2 | 'None' 3 | | 'Short' 4 | | 'Medium' 5 | | 'Long' 6 | | 'Relative' 7 | | 'RFC 2822' 8 | | 'ISO 8601' 9 | | 'Custom' 10 | | 'How Long Ago/Until' // only in as Date aggrandizement 11 | ); 12 | 13 | export default WFDateFormatStyle; 14 | -------------------------------------------------------------------------------- /src/utils/encodeShortcut.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflow from '../interfaces/WF/WFWorkflow'; 2 | 3 | /** @ignore */ 4 | const createBplist: (obj: {}) => string = require('bplist-creator'); 5 | 6 | /** @ignore */ 7 | export const encodeShortcut = ( 8 | data: WFWorkflow, 9 | ): string => ( 10 | createBplist(data) 11 | ); 12 | -------------------------------------------------------------------------------- /src/interfaces/WF/Attachment.ts: -------------------------------------------------------------------------------- 1 | import Aggrandizement from './Aggrandizement'; 2 | import Type from './Type'; 3 | 4 | interface Attachment { 5 | Aggrandizements?: Aggrandizement[]; 6 | OutputName?: string; 7 | OutputUUID?: string; 8 | Type: Type; 9 | VariableName?: string; 10 | } 11 | 12 | export default Attachment; 13 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFDictionaryFieldValueItem.ts: -------------------------------------------------------------------------------- 1 | import WFItemType from './WFItemType'; 2 | import WFSerialization from './WFSerialization'; 3 | 4 | interface WFDictionaryFieldValueItem { 5 | WFKey?: WFSerialization; 6 | WFItemType: WFItemType; 7 | WFValue: WFSerialization; 8 | } 9 | 10 | export default WFDictionaryFieldValueItem; 11 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Contributing/ActionIcons/styles.module.scss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding: 1.7rem; 3 | max-width: 100%; 4 | width: var(--max-content-width); 5 | } 6 | 7 | .iconList { 8 | column-width: 200px; 9 | 10 | .item { 11 | margin-bottom: 4px; 12 | 13 | code { 14 | font-size: 14px; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /__tests__/meta/colors.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ICON, 3 | } from '../../src/meta'; 4 | 5 | const { COLORS } = ICON; 6 | 7 | describe('COLORS object', () => { 8 | 9 | it('is an object', () => { 10 | const isObject = !Array.isArray(COLORS) && Object(COLORS) === COLORS; 11 | 12 | expect(isObject).toBeTruthy(); 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /__tests__/meta/glyphs.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ICON, 3 | } from '../../src/meta'; 4 | 5 | const { GLYPHS } = ICON; 6 | 7 | describe('GLYPHS object', () => { 8 | 9 | it('is an object', () => { 10 | const isObject = !Array.isArray(GLYPHS) && Object(GLYPHS) === GLYPHS; 11 | 12 | expect(isObject).toBeTruthy(); 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" 4 | - node 5 | 6 | script: 7 | - echo "Running tests against $(node -v)..." 8 | - npm test 9 | 10 | install: npm install 11 | 12 | jobs: 13 | include: 14 | - stage: Produce Coverage 15 | node_js: node 16 | script: jest --coverage --coverageReporters=text-lcov | coveralls 17 | -------------------------------------------------------------------------------- /docs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: 'babel-eslint', 3 | extends: [ 4 | 'airbnb', 5 | ], 6 | rules: { 7 | strict: 0, 8 | 'react/destructuring-assignment': 0 9 | }, 10 | parserOptions: { 11 | ecmaFeatures: { 12 | jsx: true, 13 | }, 14 | }, 15 | globals: { 16 | document: true, 17 | window: true, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFScientificMathOperation.ts: -------------------------------------------------------------------------------- 1 | type WFScientificMathOperation = ( 2 | 'Modulus' 3 | | 'x^2' 4 | | 'x^3' 5 | | 'x^y' 6 | | 'e^x' 7 | | '10^x' 8 | | 'ln(x)' 9 | | 'log(x)' 10 | | '√x' 11 | | '∛x' 12 | | 'x!' 13 | | 'sin(x)' 14 | | 'cos(x)' 15 | | 'tan(x)' 16 | | 'abs(x)' 17 | ); 18 | 19 | export default WFScientificMathOperation; 20 | -------------------------------------------------------------------------------- /src/utils/variable.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | 3 | /** 4 | * Creates a Variable. 5 | * 6 | * ```js 7 | * const myVar = variable('My Variable'); 8 | * ``` 9 | */ 10 | export const variable = ( 11 | /** The name of the Variable */ 12 | name: string, 13 | ): Variable => new Variable({ 14 | VariableName: name, 15 | Type: 'Variable', 16 | }); 17 | -------------------------------------------------------------------------------- /docs/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Shortcuts JS", 3 | "name": "Shortcuts JS", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflowAction.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowActionIdentifier from './WFWorkflowActionIdentifier'; 2 | import WFWorkflowActionParameters from './WFWorkflowActionParameters'; 3 | 4 | interface WFWorkflowAction { 5 | WFWorkflowActionIdentifier: WFWorkflowActionIdentifier; 6 | WFWorkflowActionParameters: WFWorkflowActionParameters; 7 | } 8 | 9 | export default WFWorkflowAction; 10 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Raw from 'raw.macro'; 3 | 4 | import Markdown from '../Markdown'; 5 | 6 | import styles from './styles.module.scss'; 7 | 8 | const content = Raw('./content.md'); 9 | 10 | export default () => ( 11 |
12 | 16 |
17 | ); 18 | -------------------------------------------------------------------------------- /docs/src/components/Docs/NotFound/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Raw from 'raw.macro'; 3 | 4 | import Markdown from '../Markdown'; 5 | 6 | import styles from './styles.module.scss'; 7 | 8 | const content = Raw('./content.md'); 9 | 10 | export default () => ( 11 |
12 | 16 |
17 | ); 18 | -------------------------------------------------------------------------------- /docs/src/components/Docs/GettingStarted/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Raw from 'raw.macro'; 3 | 4 | import Markdown from '../Markdown'; 5 | 6 | import styles from './styles.module.scss'; 7 | 8 | const content = Raw('./content.md'); 9 | 10 | export default () => ( 11 |
12 | 16 |
17 | ); 18 | -------------------------------------------------------------------------------- /docs/src/components/Home/CodeEditor/styles.module.scss: -------------------------------------------------------------------------------- 1 | $height: 510px; 2 | $padding: 8px; 3 | 4 | .container { 5 | position: relative; 6 | height: $height + 2 * $padding; 7 | margin-bottom: 1.7rem; 8 | 9 | :global .CodeMirror { 10 | height: $height + 2 * $padding; 11 | border-radius: 5px; 12 | padding: $padding; 13 | } 14 | } 15 | 16 | .editor { 17 | position: absolute; 18 | top: 0; 19 | right: 0; 20 | bottom: 0; 21 | left: 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/meta/colors.ts: -------------------------------------------------------------------------------- 1 | /** @ignore */ 2 | export const COLORS = { 3 | RED: 0xFF4351FF, 4 | DARK_ORANGE: 0xFD6631FF, 5 | ORANGE: 0xFE9949FF, 6 | YELLOW: 0xFEC418FF, 7 | GREEN: 0xFFD426FF, 8 | TEAL: 0x19BD03FF, 9 | LIGHT_BLUE: 0x55DAE1FF, 10 | BLUE: 0x1B9AF7FF, 11 | DARK_BLUE: 0x3871DEFF, 12 | DARK_PURPLE: 0x7B72E9FF, 13 | LIGHT_PURPLE: 0xDB49D8FF, 14 | PINK: 0xED4694FF, 15 | DARK_GRAY: 0x000000FF, 16 | GRAY: 0xB4B2A9FF, 17 | BLUE_GRAY: 0xA9A9A9FF, 18 | }; 19 | -------------------------------------------------------------------------------- /src/actions/share.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Share 5 | * @section Content Types > Sharing > System 6 | * @icon Sharing 7 | * 8 | * Prompts to share the input. 9 | * 10 | * ```js 11 | * share(); 12 | * ``` 13 | */ 14 | 15 | const share = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.share', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default share; 21 | -------------------------------------------------------------------------------- /__tests__/actions/call.spec.ts: -------------------------------------------------------------------------------- 1 | import { call } from '../../src/actions'; 2 | 3 | describe('call function', () => { 4 | it('is a function', () => { 5 | expect(typeof call).toBe('function'); 6 | }); 7 | 8 | it('builds a call action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'com.apple.mobilephone.call', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = call(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/share.spec.ts: -------------------------------------------------------------------------------- 1 | import { share } from '../../src/actions'; 2 | 3 | describe('share function', () => { 4 | it('is a function', () => { 5 | expect(typeof share).toBe('function'); 6 | }); 7 | 8 | it('builds an share action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.share', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = share(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /docs/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --white-color: #ffffff; 3 | --lightest-gray-color: #f3f3f5; 4 | --lighter-gray-color: #d9d9dc; 5 | --light-gray-color: #c0c0c0; 6 | --gray-color: #808080; 7 | --dark-gray-color: #505050; 8 | --darker-gray-color: #272a2e; 9 | --darkest-gray-color: #202020; 10 | --purple-color: #9d62f3; 11 | --pink-color: #fc00ff; 12 | --yellow-color: #fbc630; 13 | --aqua-color: #00dbde; 14 | --blue-color: #7688ed; 15 | --shadow-color: rgba(0, 0, 0, .3); 16 | } 17 | -------------------------------------------------------------------------------- /src/actions/openURLs.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Open URLs 5 | * @section Content Types > Web > Safari 6 | * @icon Safari 7 | * 8 | * Opens URLs passed into the action in Safari. 9 | * 10 | * ```js 11 | * openURLs(); 12 | * ``` 13 | */ 14 | 15 | const openURLs = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.openurl', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default openURLs; 21 | -------------------------------------------------------------------------------- /__tests__/actions/print.spec.ts: -------------------------------------------------------------------------------- 1 | import { print } from '../../src/actions'; 2 | 3 | describe('print function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof print).toBe('function'); 7 | }); 8 | 9 | it('builds a print action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.print', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = print({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/tweet.spec.ts: -------------------------------------------------------------------------------- 1 | import { tweet } from '../../src/actions'; 2 | 3 | describe('tweet function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof tweet).toBe('function'); 7 | }); 8 | 9 | it('builds a tweet action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.tweet', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = tweet({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/openURLs.spec.ts: -------------------------------------------------------------------------------- 1 | import { openURLs } from '../../src/actions'; 2 | 3 | describe('openURLs function', () => { 4 | it('is a function', () => { 5 | expect(typeof openURLs).toBe('function'); 6 | }); 7 | 8 | it('builds a openURLs action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.openurl', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = openURLs(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/call.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Call 5 | * @section Content Types > Contacts > Phone 6 | * @icon PhoneNumber 7 | * 8 | * Call the contact, the text, place or phone number given as input. 9 | * 10 | * ```js 11 | * call(); 12 | * ``` 13 | */ 14 | 15 | const call = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'com.apple.mobilephone.call', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default call; 21 | -------------------------------------------------------------------------------- /src/actions/pauseMusic.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Pause Music 5 | * @section Content Types > Music > Playback 6 | * @icon Pause 7 | * 8 | * Pauses the currently playing music. 9 | * 10 | * ```js 11 | * pauseMusic(); 12 | * ``` 13 | */ 14 | 15 | const pauseMusic = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.pausemusic', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default pauseMusic; 21 | -------------------------------------------------------------------------------- /__tests__/actions/nothing.spec.ts: -------------------------------------------------------------------------------- 1 | import { nothing } from '../../src/actions'; 2 | 3 | describe('nothing function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof nothing).toBe('function'); 7 | }); 8 | 9 | it('builds a nothing action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.nothing', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = nothing(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/markup.spec.ts: -------------------------------------------------------------------------------- 1 | import { markup } from '../../src/actions'; 2 | 3 | describe('markup function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof markup).toBe('function'); 7 | }); 8 | 9 | it('builds a markup action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.avairyeditphoto', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = markup({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/playSound.spec.ts: -------------------------------------------------------------------------------- 1 | import { playSound } from '../../src/actions'; 2 | 3 | describe('playSound function', () => { 4 | it('is a function', () => { 5 | expect(typeof playSound).toBe('function'); 6 | }); 7 | 8 | it('builds a play sound action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.playsound', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = playSound(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/clearUpNext.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Clear Up Next 5 | * @section Content Types > Music > Music 6 | * @icon Music 7 | * 8 | * Clears all the music in your Up Next queue. 9 | * 10 | * ```js 11 | * clearUpNext(); 12 | * ``` 13 | */ 14 | 15 | const clearUpNext = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.clearupnext', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default clearUpNext; 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint-config-airbnb" 4 | ], 5 | "rules": { 6 | "import-name": false, 7 | "max-line-length": [ 8 | true, 9 | { 10 | "limit": 100, 11 | "ignore-pattern": "^\\s\\*" 12 | } 13 | ], 14 | "no-any": true, 15 | "ordered-imports": true, 16 | "variable-name": [true, "allow-pascal-case"], 17 | "typedef": [ 18 | true, 19 | "call-signature", 20 | "parameter", 21 | "property-declaration" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Dependencies 7 | node_modules/ 8 | 9 | # Coverage 10 | coverage 11 | 12 | # Transpiled files 13 | build/ 14 | 15 | # Documentation 16 | docs/api/data.json 17 | docs/static/ 18 | 19 | # VS Code 20 | .vscode 21 | !.vscode/tasks.js 22 | 23 | # JetBrains IDEs 24 | .idea/ 25 | 26 | # Optional npm cache directory 27 | .npm 28 | 29 | # Optional eslint cache 30 | .eslintcache 31 | 32 | # Misc 33 | .DS_Store 34 | 35 | shortcuts/ 36 | playground.js 37 | playground/ 38 | 39 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | npm-debug.log* 3 | 4 | # Dependency directories 5 | node_modules 6 | 7 | # npm package lock 8 | package-lock.json 9 | yarn.lock 10 | 11 | # project files 12 | __tests__ 13 | assets 14 | coverage 15 | docs 16 | documentation 17 | playground 18 | scripts 19 | shortcuts 20 | src 21 | .github 22 | .gitignore 23 | .nvmrc 24 | jest.config.js 25 | tsconfig.json 26 | tsconfig.release.json 27 | tslint.json 28 | webpack.config.js 29 | CONTRIBUTING.md 30 | CODE_OF_CONDUCT.md 31 | PULL_REQUEST_TEMPLATE.md 32 | playground.js 33 | -------------------------------------------------------------------------------- /__tests__/actions/airDrop.spec.ts: -------------------------------------------------------------------------------- 1 | import { airDrop } from '../../src/actions'; 2 | 3 | describe('airDrop function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof airDrop).toBe('function'); 7 | }); 8 | 9 | it('builds a airDrop action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.airdropdocument', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = airDrop({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/expandURL.spec.ts: -------------------------------------------------------------------------------- 1 | import { expandURL } from '../../src/actions'; 2 | 3 | describe('expandURL function', () => { 4 | it('is a function', () => { 5 | expect(typeof expandURL).toBe('function'); 6 | }); 7 | 8 | it('builds an expand url action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.url.expand', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = expandURL({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getName.spec.ts: -------------------------------------------------------------------------------- 1 | import { getName } from '../../src/actions'; 2 | 3 | describe('getName function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getName).toBe('function'); 7 | }); 8 | 9 | it('builds a getName action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getitemname', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = getName({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/getType.spec.ts: -------------------------------------------------------------------------------- 1 | import { getType } from '../../src/actions'; 2 | 3 | describe('getType function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getType).toBe('function'); 7 | }); 8 | 9 | it('builds a getType action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getitemtype', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = getType({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/pauseMusic.spec.ts: -------------------------------------------------------------------------------- 1 | import { pauseMusic } from '../../src/actions'; 2 | 3 | describe('pauseMusic function', () => { 4 | it('is a function', () => { 5 | expect(typeof pauseMusic).toBe('function'); 6 | }); 7 | 8 | it('builds a pause music action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.pausemusic', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = pauseMusic(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/trimMedia.spec.ts: -------------------------------------------------------------------------------- 1 | import { trimMedia } from '../../src/actions'; 2 | 3 | describe('trimMedia function', () => { 4 | it('is a function', () => { 5 | expect(typeof trimMedia).toBe('function'); 6 | }); 7 | 8 | it('builds a get last import action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.trimvideo', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = trimMedia(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/utils/actionOutput.ts: -------------------------------------------------------------------------------- 1 | import * as uuidv4 from 'uuid/v4'; 2 | 3 | import Variable from '../interfaces/Variable'; 4 | 5 | /** 6 | * Creates a Magic Variable to be used as action output. 7 | * 8 | * ```js 9 | * const magic = actionOutput('My Magic Variable'); 10 | * ``` 11 | */ 12 | export const actionOutput = ( 13 | /** The custom name of the Magic Variable */ 14 | name?: string, 15 | ): Variable => new Variable({ 16 | ...(name && { OutputName: name }), 17 | OutputUUID: uuidv4(), 18 | Type: 'ActionOutput', 19 | }); 20 | -------------------------------------------------------------------------------- /docs/src/components/App/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route } from 'react-router'; 3 | 4 | import Docs from '../Docs'; 5 | // import Home from '../Home'; 6 | 7 | import styles from './styles.module.scss'; 8 | 9 | export default class Component extends React.Component { 10 | render() { 11 | return ( 12 |
13 | 14 | {/* */} 15 | 16 | 17 |
18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/actions/tweet.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Tweet 7 | * @section Content Types > Sharing > Twitter 8 | * @icon Twitter 9 | * 10 | * Tweets the input. 11 | * 12 | * ```js 13 | * tweet(); 14 | * ``` 15 | */ 16 | const tweet = (): WFWorkflowAction => ({ 17 | WFWorkflowActionIdentifier: 'is.workflow.actions.tweet', 18 | WFWorkflowActionParameters: {}, 19 | }); 20 | 21 | export default withActionOutput(tweet); 22 | -------------------------------------------------------------------------------- /__tests__/actions/clearUpNext.spec.ts: -------------------------------------------------------------------------------- 1 | import { clearUpNext } from '../../src/actions'; 2 | 3 | describe('clearUpNext function', () => { 4 | it('is a function', () => { 5 | expect(typeof clearUpNext).toBe('function'); 6 | }); 7 | 8 | it('builds a clear up next action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.clearupnext', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = clearUpNext(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/skipForward.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Skip Forward 5 | * @section Content Types > Music > Playback 6 | * @icon FastForward 7 | * 8 | * Skips to the next song in the current music queue. 9 | * 10 | * ```js 11 | * skipForward(); 12 | * ``` 13 | */ 14 | 15 | const skipForward = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.skipforward', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default skipForward; 21 | -------------------------------------------------------------------------------- /__tests__/actions/deletePhotos.spec.ts: -------------------------------------------------------------------------------- 1 | import { deletePhotos } from '../../src/actions'; 2 | 3 | describe('deletePhotos function', () => { 4 | it('is a function', () => { 5 | expect(typeof deletePhotos).toBe('function'); 6 | }); 7 | 8 | it('builds a delete photos action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.deletephotos', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = deletePhotos(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getClipboard.spec.ts: -------------------------------------------------------------------------------- 1 | import { getClipboard } from '../../src/actions'; 2 | 3 | describe('getClipboard function', () => { 4 | it('is a function', () => { 5 | expect(typeof getClipboard).toBe('function'); 6 | }); 7 | 8 | it('builds a get clipboard action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getclipboard', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getClipboard(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getMapsURL.spec.ts: -------------------------------------------------------------------------------- 1 | import { getMapsURL } from '../../src/actions'; 2 | 3 | describe('getMapsURL function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getMapsURL).toBe('function'); 7 | }); 8 | 9 | it('builds a getMapsURL action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmapslink', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = getMapsURL({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/openInBooks.spec.ts: -------------------------------------------------------------------------------- 1 | import { openInBooks } from '../../src/actions'; 2 | 3 | describe('openInBooks function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof openInBooks).toBe('function'); 7 | }); 8 | 9 | it('builds a openInBooks action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'com.apple.iBooks.openin', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = openInBooks({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/quickLook.spec.ts: -------------------------------------------------------------------------------- 1 | import { quickLook } from '../../src/actions'; 2 | 3 | describe('quickLook function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof quickLook).toBe('function'); 7 | }); 8 | 9 | it('builds a quickLook action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.previewdocument', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = quickLook({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/skipForward.spec.ts: -------------------------------------------------------------------------------- 1 | import { skipForward } from '../../src/actions'; 2 | 3 | describe('skipForward function', () => { 4 | it('is a function', () => { 5 | expect(typeof skipForward).toBe('function'); 6 | }); 7 | 8 | it('builds a skip forward action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.skipforward', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | 14 | const actual = skipForward(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/actions/vibrateDevice.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Vibrate Device 5 | * @section Actions > Scripting > Notification 6 | * @icon Notification 7 | * 8 | * Vibrates the device for a short amount of time. 9 | * 10 | * ```js 11 | * vibrateDevice(); 12 | * ``` 13 | */ 14 | 15 | const vibrateDevice = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.vibrate', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default vibrateDevice; 21 | -------------------------------------------------------------------------------- /__tests__/actions/exitShortcut.spec.ts: -------------------------------------------------------------------------------- 1 | import { exitShortcut } from '../../src/actions'; 2 | 3 | describe('exitShortcut function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof exitShortcut).toBe('function'); 7 | }); 8 | 9 | it('builds an exitShortcut action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.exit', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = exitShortcut(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/extractArchive.spec.ts: -------------------------------------------------------------------------------- 1 | import { extractArchive } from '../../src/actions'; 2 | 3 | describe('extractArchive function', () => { 4 | it('is a function', () => { 5 | expect(typeof extractArchive).toBe('function'); 6 | }); 7 | 8 | it('builds a extract archive action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.unzip', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = extractArchive(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /docs/src/components/Docs/GettingStarted/content.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | Shortcuts JS lets you build Shortcuts more efficiently by allowing you to leverage all of the features of JavaScript to generate a Shortcut, allowing you to create complex Shortcuts more quickly and more easily than ever before. 4 | 5 | ### Installation 6 | 7 | Shortcuts JS is a [Node.js package](https://www.npmjs.com/package/@joshfarrant/shortcuts-js). To install it, type: 8 | 9 | ```sh 10 | npm install @joshfarrant/shortcuts-js 11 | ``` 12 | 13 | ### Usage 14 | 15 | [WIP] 16 | -------------------------------------------------------------------------------- /src/actions/trimMedia.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Trim Media 5 | * @section Content Types > Photos & Video > Video 6 | * @icon QuickTime 7 | * 8 | * Presents a view allowing you to trim the media passed into the action. 9 | * 10 | * ```js 11 | * trimMedia(); 12 | * ``` 13 | */ 14 | 15 | const trimMedia = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.trimvideo', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default trimMedia; 21 | -------------------------------------------------------------------------------- /__tests__/actions/createNote.spec.ts: -------------------------------------------------------------------------------- 1 | import { createNote } from '../../src/actions'; 2 | 3 | describe('createNote function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof createNote).toBe('function'); 7 | }); 8 | 9 | it('builds a createNote action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'com.apple.mobilenotes.SharingExtension', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = createNote({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/getLinkToFile.spec.ts: -------------------------------------------------------------------------------- 1 | import { getLinkToFile } from '../../src/actions'; 2 | 3 | describe('getLinkToFile function', () => { 4 | it('is a function', () => { 5 | expect(typeof getLinkToFile).toBe('function'); 6 | }); 7 | 8 | it('builds a get link to file action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.file.getlink', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getLinkToFile({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/getClipboard.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Clipboard 5 | * @section Content Types > Sharing > Clipboard 6 | * @icon Clipboard 7 | * 8 | * Passes the contents of the clipboard to the next action. 9 | * 10 | * ```js 11 | * getClipboard(); 12 | * ``` 13 | */ 14 | 15 | const getClipboard = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getclipboard', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getClipboard; 21 | -------------------------------------------------------------------------------- /src/actions/print.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Print 7 | * @section Content Types > Documents > Printing 8 | * @icon Print 9 | * 10 | * Prints the input using AirPrint. 11 | * 12 | * ```js 13 | * print(); 14 | * ``` 15 | */ 16 | 17 | const print = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.print', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(print); 23 | -------------------------------------------------------------------------------- /src/actions/showDefinition.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Show Definition 5 | * @section Content Types > Text > 6 | * @icon Dictionary 7 | * 8 | * Shows the definition of the word passed into the action. 9 | * 10 | * ```js 11 | * showDefinition(); 12 | * ``` 13 | */ 14 | 15 | const showDefinition = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.showdefinition', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default showDefinition; 21 | -------------------------------------------------------------------------------- /__tests__/actions/getCurrentSong.spec.ts: -------------------------------------------------------------------------------- 1 | import { getCurrentSong } from '../../src/actions'; 2 | 3 | describe('getCurrentSong function', () => { 4 | it('is a function', () => { 5 | expect(typeof getCurrentSong).toBe('function'); 6 | }); 7 | 8 | it('builds a get current song action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getcurrentsong', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getCurrentSong(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getLastImport.spec.ts: -------------------------------------------------------------------------------- 1 | import { getLastImport } from '../../src/actions'; 2 | 3 | describe('getLastImport function', () => { 4 | it('is a function', () => { 5 | expect(typeof getLastImport).toBe('function'); 6 | }); 7 | 8 | it('builds a get last import action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlatestphotoimport', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getLastImport(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/postToTumblr.spec.ts: -------------------------------------------------------------------------------- 1 | import { postToTumblr } from '../../src/actions'; 2 | 3 | describe('postToTumblr function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof postToTumblr).toBe('function'); 7 | }); 8 | 9 | it('builds a postToTumblr action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.tumblr.post', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = postToTumblr({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/showDefinition.spec.ts: -------------------------------------------------------------------------------- 1 | import { showDefinition } from '../../src/actions'; 2 | 3 | describe('showDefinition function', () => { 4 | it('is a function', () => { 5 | expect(typeof showDefinition).toBe('function'); 6 | }); 7 | 8 | it('builds a show definition action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.showdefinition', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = showDefinition(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /docs/src/components/Home/ShortcutCreator/styles.module.scss: -------------------------------------------------------------------------------- 1 | .buttonContainer { 2 | display: flex; 3 | align-items: flex-start; 4 | justify-content: center; 5 | width: 100%; 6 | 7 | & > button { 8 | margin: 0; 9 | } 10 | } 11 | 12 | .error { 13 | display: inline; 14 | margin: 0 0 1.7rem; 15 | padding: 0; 16 | border: none; 17 | outline: none; 18 | color: var(--purple-color); 19 | text-align: left; 20 | font-weight: 700; 21 | cursor: pointer; 22 | 23 | &:hover, 24 | &:focus { 25 | text-decoration: underline; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/actions/addToReadingList.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Add to Reading List 5 | * @section Content Types > Web > Safari 6 | * @icon Safari 7 | * 8 | * Adds URLs passed into the action to your reading list. 9 | * 10 | * ```js 11 | * addToReadingList(); 12 | * ``` 13 | */ 14 | 15 | const addToReadingList = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.readinglist', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default addToReadingList; 21 | -------------------------------------------------------------------------------- /__tests__/actions/correctSpelling.spec.ts: -------------------------------------------------------------------------------- 1 | import { correctSpelling } from '../../src/actions'; 2 | 3 | describe('correctSpelling function', () => { 4 | it('is a function', () => { 5 | expect(typeof correctSpelling).toBe('function'); 6 | }); 7 | 8 | it('builds a correct spelling action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.correctspelling', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = correctSpelling(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getNameOfEmoji.spec.ts: -------------------------------------------------------------------------------- 1 | import { getNameOfEmoji } from '../../src/actions'; 2 | 3 | describe('getNameOfEmoji function', () => { 4 | it('is a function', () => { 5 | expect(typeof getNameOfEmoji).toBe('function'); 6 | }); 7 | 8 | it('builds a get name of emoji action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getnameofemoji', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getNameOfEmoji({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/removeReminders.spec.ts: -------------------------------------------------------------------------------- 1 | import { removeReminders } from '../../src/actions'; 2 | 3 | describe('removeReminders function', () => { 4 | it('is a function', () => { 5 | expect(typeof removeReminders).toBe('function'); 6 | }); 7 | 8 | it('builds a remove reminders action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.removereminders', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = removeReminders(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/scanQROrBarcode.spec.ts: -------------------------------------------------------------------------------- 1 | import { scanQROrBarcode } from '../../src/actions'; 2 | 3 | describe('scanQROrBarcode function', () => { 4 | it('is a function', () => { 5 | expect(typeof scanQROrBarcode).toBe('function'); 6 | }); 7 | 8 | it('builds a scan qr/barcode action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.scanbarcode', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = scanQROrBarcode({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/showInCalendar.spec.ts: -------------------------------------------------------------------------------- 1 | import { showInCalendar } from '../../src/actions'; 2 | 3 | describe('showInCalendar function', () => { 4 | it('is a function', () => { 5 | expect(typeof showInCalendar).toBe('function'); 6 | }); 7 | 8 | it('builds a show in calendar action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.showincalendar', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = showInCalendar({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/correctSpelling.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Correct Spelling 5 | * @section Content Types > Text > Text Editing 6 | * @icon Text 7 | * 8 | * Autocorrects the spelling of text passed into the action. 9 | * 10 | * ```js 11 | * correctSpelling(); 12 | * ``` 13 | */ 14 | 15 | const correctSpelling = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.correctspelling', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default correctSpelling; 21 | -------------------------------------------------------------------------------- /src/actions/getLastImport.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Last Import 5 | * @section Content Types > Photos & Video > Photos 6 | * @icon Photos 7 | * 8 | * Gets the most recent photo import from the Photos app. 9 | * 10 | * ```js 11 | * getLastImport(); 12 | * ``` 13 | */ 14 | 15 | const getLastImport = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlatestphotoimport', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getLastImport; 21 | -------------------------------------------------------------------------------- /__tests__/actions/addToReadingList.spec.ts: -------------------------------------------------------------------------------- 1 | import { addToReadingList } from '../../src/actions'; 2 | 3 | describe('addToReadingList function', () => { 4 | it('is a function', () => { 5 | expect(typeof addToReadingList).toBe('function'); 6 | }); 7 | 8 | it('builds a add to reading list action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.readinglist', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = addToReadingList(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getHeadersOfURL.spec.ts: -------------------------------------------------------------------------------- 1 | import { getHeadersOfURL } from '../../src/actions'; 2 | 3 | describe('getHeadersOfURL function', () => { 4 | it('is a function', () => { 5 | expect(typeof getHeadersOfURL).toBe('function'); 6 | }); 7 | 8 | it('builds a get headers of url action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.url.getheaders', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getHeadersOfURL({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/openURLsInChrome.spec.ts: -------------------------------------------------------------------------------- 1 | import { openURLsInChrome } from '../../src/actions'; 2 | 3 | describe('openURLsInChrome function', () => { 4 | it('is a function', () => { 5 | expect(typeof openURLsInChrome).toBe('function'); 6 | }); 7 | 8 | it('builds a openURLsInChrome action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'com.google.chrome.ios.openurl', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = openURLsInChrome({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/getCurrentSong.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Current Song 5 | * @section Content Types > Music > Music 6 | * @icon Music 7 | * 8 | * Returns the song that is currently playing in the Music app, if any. 9 | * 10 | * ```js 11 | * getCurrentSong(); 12 | * ``` 13 | */ 14 | 15 | const getCurrentSong = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getcurrentsong', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getCurrentSong; 21 | -------------------------------------------------------------------------------- /src/actions/playSound.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Play Sound 5 | * @section Actions > Scripting > Notification 6 | * @icon Sound 7 | * 8 | * Plays the audio file passed as input, or a default notification sound if no audio file was passed. 9 | * 10 | * ```js 11 | * playSound(); 12 | * ``` 13 | */ 14 | 15 | const playSound = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.playsound', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default playSound; 21 | -------------------------------------------------------------------------------- /__tests__/actions/getDatesFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getDatesFromInput } from '../../src/actions'; 2 | 3 | describe('getDatesFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getDatesFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get dates from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.date', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getDatesFromInput(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getMyShortcuts.spec.ts: -------------------------------------------------------------------------------- 1 | import { getMyShortcuts } from '../../src/actions'; 2 | 3 | describe('getMyShortcuts function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getMyShortcuts).toBe('function'); 7 | }); 8 | 9 | it('builds a getMyShortcuts action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmyworkflows', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = getMyShortcuts({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/getTextFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getTextFromInput } from '../../src/actions'; 2 | 3 | describe('getTextFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getTextFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get text from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.text', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getTextFromInput({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getURLsFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getURLsFromInput } from '../../src/actions'; 2 | 3 | describe('getURLsFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getURLsFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get urls from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.link', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getURLsFromInput({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/postOnFacebook.spec.ts: -------------------------------------------------------------------------------- 1 | import { postOnFacebook } from '../../src/actions'; 2 | 3 | describe('postOnFacebook function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof postOnFacebook).toBe('function'); 7 | }); 8 | 9 | it('builds a postOnFacebook action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.postonfacebook', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = postOnFacebook({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/showInITunesStore.spec.ts: -------------------------------------------------------------------------------- 1 | import { showInITunesStore } from '../../src/actions'; 2 | 3 | describe('showInITunesStore function', () => { 4 | it('is a function', () => { 5 | expect(typeof showInITunesStore).toBe('function'); 6 | }); 7 | 8 | it('builds a show in itunes store action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.showinstore', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = showInITunesStore(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/postToWordPress.spec.ts: -------------------------------------------------------------------------------- 1 | import { postToWordPress } from '../../src/actions'; 2 | 3 | describe('postToWordPress function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof postToWordPress).toBe('function'); 7 | }); 8 | 9 | it('builds a postToWordPress action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.wordpress.post', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = postToWordPress({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/selectPhoneNumber.spec.ts: -------------------------------------------------------------------------------- 1 | import { selectPhoneNumber } from '../../src/actions'; 2 | 3 | describe('selectPhoneNumber function', () => { 4 | it('is a function', () => { 5 | expect(typeof selectPhoneNumber).toBe('function'); 6 | }); 7 | 8 | it('builds a select phone number action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.selectphone', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = selectPhoneNumber({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/viewContentGraph.spec.ts: -------------------------------------------------------------------------------- 1 | import { viewContentGraph } from '../../src/actions'; 2 | 3 | describe('viewContentGraph function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof viewContentGraph).toBe('function'); 7 | }); 8 | 9 | it('builds a viewContentGraph action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.viewresult', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = viewContentGraph({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /src/actions/airDrop.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action AirDrop 7 | * @section Content Types > Sharing > System 8 | * @icon AirDrop 9 | * 10 | * Prompts to share the input via AirDrop. 11 | * 12 | * ```js 13 | * airDrop(); 14 | * ``` 15 | */ 16 | 17 | const airDrop = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.airdropdocument', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(airDrop); 23 | -------------------------------------------------------------------------------- /src/actions/getDatesFromInput.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Dates from Input 5 | * @section Content Types > Calendar > Dates 6 | * @icon Date 7 | * 8 | * Returns any dates found in the output from the previous action. 9 | * 10 | * ```js 11 | * getDatesFromInput(); 12 | * ``` 13 | */ 14 | 15 | const getDatesFromInput = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.date', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getDatesFromInput; 21 | -------------------------------------------------------------------------------- /src/actions/markup.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Markup 7 | * @section Content Types > Photos & Video > Editing 8 | * @icon Markup 9 | * 10 | * Edits an image or PDF with Markup. 11 | * 12 | * ```js 13 | * markup(); 14 | * ``` 15 | */ 16 | 17 | const markup = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.avairyeditphoto', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(markup); 23 | -------------------------------------------------------------------------------- /__tests__/actions/getImagesFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getImagesFromInput } from '../../src/actions'; 2 | 3 | describe('getImagesFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getImagesFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get images from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.images', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getImagesFromInput(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/selectEmailAddress.spec.ts: -------------------------------------------------------------------------------- 1 | import { selectEmailAddress } from '../../src/actions'; 2 | 3 | describe('selectEmailAddress function', () => { 4 | it('is a function', () => { 5 | expect(typeof selectEmailAddress).toBe('function'); 6 | }); 7 | 8 | it('builds a select email address action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.selectemail', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = selectEmailAddress({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/vibrateDevice.spec.ts: -------------------------------------------------------------------------------- 1 | import { vibrateDevice } from '../../src/actions'; 2 | 3 | describe('vibrateDevice function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof vibrateDevice).toBe('function'); 7 | }); 8 | 9 | it('builds a vibrateDevice action when no options are passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.vibrate', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = vibrateDevice(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/waitToReturn.spec.ts: -------------------------------------------------------------------------------- 1 | import { waitToReturn } from '../../src/actions'; 2 | 3 | describe('waitToReturn function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof waitToReturn).toBe('function'); 7 | }); 8 | 9 | it('builds a waitToReturn action when no options are passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.waittoreturn', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = waitToReturn(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /src/actions/createNote.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Create Note 7 | * @section Content Types > Sharing > Notes 8 | * @icon Notes 9 | * 10 | * Shares the input with Notes. 11 | * 12 | * ```js 13 | * createNote(); 14 | * ``` 15 | */ 16 | 17 | const createNote = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'com.apple.mobilenotes.SharingExtension', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(createNote); 23 | -------------------------------------------------------------------------------- /src/actions/getCurrentLocation.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Current Location 5 | * @section Content Types > Location > Get Current Location 6 | * @icon Location 7 | * 8 | * Gets the current location of the device. 9 | * 10 | * ```js 11 | * getCurrentLocation(); 12 | * ``` 13 | */ 14 | 15 | const getCurrentLocation = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getcurrentlocation', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getCurrentLocation; 21 | -------------------------------------------------------------------------------- /src/actions/openInBooks.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Open in Books 7 | * @section Content Types > Documents > Books 8 | * @icon Books 9 | * 10 | * Opens the input as a PDF in Books. 11 | * 12 | * ```js 13 | * openInBooks(); 14 | * ``` 15 | */ 16 | 17 | const openInBooks = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'com.apple.iBooks.openin', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(openInBooks); 23 | -------------------------------------------------------------------------------- /__tests__/actions/getCurrentLocation.spec.ts: -------------------------------------------------------------------------------- 1 | import { getCurrentLocation } from '../../src/actions'; 2 | 3 | describe('getCurrentLocation function', () => { 4 | it('is a function', () => { 5 | expect(typeof getCurrentLocation).toBe('function'); 6 | }); 7 | 8 | it('builds a get current location action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getcurrentlocation', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getCurrentLocation(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getFramesFromImage.spec.ts: -------------------------------------------------------------------------------- 1 | import { getFramesFromImage } from '../../src/actions'; 2 | 3 | describe('getFramesFromImage function', () => { 4 | it('is a function', () => { 5 | expect(typeof getFramesFromImage).toBe('function'); 6 | }); 7 | 8 | it('builds a get frames from image action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getframesfromimage', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getFramesFromImage(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/shareWithExtensions.spec.ts: -------------------------------------------------------------------------------- 1 | import { shareWithExtensions } from '../../src/actions'; 2 | 3 | describe('shareWithExtensions function', () => { 4 | it('is a function', () => { 5 | expect(typeof shareWithExtensions).toBe('function'); 6 | }); 7 | 8 | it('builds an share with extensions action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.runextension', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = shareWithExtensions(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getAddressesFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getAddressesFromInput } from '../../src/actions'; 2 | 3 | describe('getAddressesFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getAddressesFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a extract archive action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.address', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getAddressesFromInput(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/getContactsFromInput.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Contacts from Input 5 | * @section Content Types > Contacts > Contacts 6 | * @icon Contacts 7 | * 8 | * Gets contacts from the result of the previous action. 9 | * 10 | * ```js 11 | * getContactsFromInput(); 12 | * ``` 13 | */ 14 | 15 | const getContactsFromInput = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.contacts', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getContactsFromInput; 21 | -------------------------------------------------------------------------------- /src/actions/getFramesFromImage.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Frames from Image 5 | * @section Content Types > Photos & Video > GIFs 6 | * @icon GIF 7 | * 8 | * Splits an animated GIF or a photo burst into individual frames. 9 | * 10 | * ```js 11 | * getFramesFromImage(); 12 | * ``` 13 | */ 14 | 15 | const getFramesFromImage = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getframesfromimage', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getFramesFromImage; 21 | -------------------------------------------------------------------------------- /src/actions/quickLook.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Quick Look 7 | * @section Content Types > Documents > Previewing 8 | * @icon QuickLook 9 | * 10 | * Displays a preview of the input. 11 | * 12 | * ```js 13 | * quickLook(); 14 | * ``` 15 | */ 16 | 17 | const quickLook = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.previewdocument', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(quickLook); 23 | -------------------------------------------------------------------------------- /__tests__/actions/getContactsFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getContactsFromInput } from '../../src/actions'; 2 | 3 | describe('getContactsFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getContactsFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get conacts from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.contacts', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getContactsFromInput(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/removeReminders.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Remove Reminders 5 | * @section Content Types > Calendar > Reminders 6 | * @icon Reminders 7 | * 8 | * Removes all reminders passed into the action from the lists they are contained in. 9 | * 10 | * ```js 11 | * removeReminders(); 12 | * ``` 13 | */ 14 | 15 | const removeReminders = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.removereminders', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default removeReminders; 21 | -------------------------------------------------------------------------------- /__tests__/actions/continueShortcutInApp.spec.ts: -------------------------------------------------------------------------------- 1 | import { continueShortcutInApp } from '../../src/actions'; 2 | 3 | describe('continueShortcutInApp function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof continueShortcutInApp).toBe('function'); 7 | }); 8 | 9 | it('builds a continueShortcutInApp action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.handoff', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = continueShortcutInApp(); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/getBatteryLevel.spec.ts: -------------------------------------------------------------------------------- 1 | import { getBatteryLevel } from '../../src/actions'; 2 | 3 | describe('getBatteryLevel function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getBatteryLevel).toBe('function'); 7 | }); 8 | 9 | it('builds a get battery level action when no text is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getbatterylevel', 12 | WFWorkflowActionParameters: {}, 13 | }; 14 | const actual = getBatteryLevel({}); 15 | 16 | expect(actual).toEqual(expected); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/actions/getContentsOfWebPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { getContentsOfWebPage } from '../../src/actions'; 2 | 3 | describe('getContentsOfWebPage function', () => { 4 | it('is a function', () => { 5 | expect(typeof getContentsOfWebPage).toBe('function'); 6 | }); 7 | 8 | it('builds a get contents of web page action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getwebpagecontents', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getContentsOfWebPage({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/makeRichTextFromHTML.spec.ts: -------------------------------------------------------------------------------- 1 | import { makeRichTextFromHTML } from '../../src/actions'; 2 | 3 | describe('makeRichTextFromHTML function', () => { 4 | it('is a function', () => { 5 | expect(typeof makeRichTextFromHTML).toBe('function'); 6 | }); 7 | 8 | it('builds a get rich text from html action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getrichtextfromhtml', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = makeRichTextFromHTML(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/continueShortcutInApp.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Continue Shortcut in App 5 | * @section Actions > Scripting > Control Flow 6 | * @icon HandoffAction 7 | * 8 | * Switches into the Shortcuts app and continues to the next action. 9 | * 10 | * ```js 11 | * continueShortcutInApp(); 12 | * ``` 13 | */ 14 | 15 | const continueShortcutInApp = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.handoff', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default continueShortcutInApp; 21 | -------------------------------------------------------------------------------- /src/actions/exitShortcut.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Exit Shortcut 5 | * @section Actions > Scripting > Control Flow 6 | * @icon Scripting 7 | * 8 | * Stops execution of the current shortcut and dismisses the shortcut on screen. No more actions will be run after this action. 9 | * 10 | * ```js 11 | * exitShortcut(); 12 | * ``` 13 | */ 14 | 15 | const exitShortcut = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.exit', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default exitShortcut; 21 | -------------------------------------------------------------------------------- /src/actions/getAddressesFromInput.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Addresses from Input 5 | * @section Content Types > Location > Maps 6 | * @icon Maps 7 | * 8 | * Returns any street addresses found in the output from the previous action. 9 | * 10 | * ```js 11 | * getAddressesFromInput(); 12 | * ``` 13 | */ 14 | 15 | const getAddressesFromInput = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.address', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getAddressesFromInput; 21 | -------------------------------------------------------------------------------- /src/actions/nothing.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Nothing 5 | * @section Actions > Scripting > Content 6 | * @icon Scripting 7 | * 8 | * This action does nothing and produces no output. It is useful to separate blocks of actions, or to ensure that no input is passed to the next action. 9 | * 10 | * ```js 11 | * nothing(); 12 | * ``` 13 | */ 14 | 15 | const nothing = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.nothing', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default nothing; 21 | -------------------------------------------------------------------------------- /src/actions/postOnFacebook.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Post on Facebook 7 | * @section Content Types > Sharing > Facebook 8 | * @icon Facebook 9 | * 10 | * Shares the input on Facebook. 11 | * 12 | * ```js 13 | * postOnFacebook(); 14 | * ``` 15 | */ 16 | 17 | const postOnFacebook = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.postonfacebook', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(postOnFacebook); 23 | -------------------------------------------------------------------------------- /__tests__/actions/getDictionaryFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getDictionaryFromInput } from '../../src/actions'; 2 | 3 | describe('getDictionaryFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getDictionaryFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get dictionary from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.dictionary', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getDictionaryFromInput({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/getNameOfEmoji.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Name of Emoji 7 | * @section Content Types > Text > 8 | * @icon Smiley 9 | * 10 | * Gets the names of emoji passed into the action. 11 | * 12 | * ```js 13 | * getNameOfEmoji(); 14 | * ``` 15 | */ 16 | 17 | const getNameOfEmoji = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getnameofemoji', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getNameOfEmoji); 23 | -------------------------------------------------------------------------------- /src/actions/openURLsInChrome.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Open URLs in Chrome 7 | * @section Content Types > Web > Chrome 8 | * @icon Chrome 9 | * 10 | * Opens the inputted URLs in Google Chrome. 11 | * 12 | * ```js 13 | * openURLsInChrome(); 14 | * ``` 15 | */ 16 | const openURLsInChrome = (): WFWorkflowAction => ({ 17 | WFWorkflowActionIdentifier: 'com.google.chrome.ios.openurl', 18 | WFWorkflowActionParameters: {}, 19 | }); 20 | 21 | export default withActionOutput(openURLsInChrome); 22 | -------------------------------------------------------------------------------- /src/actions/postToTumblr.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Post to Tumblr 7 | * @section Content Types > Sharing > Tumblr 8 | * @icon Tumblr 9 | * 10 | * Posts the content passed into the action to Tumblr. 11 | * 12 | * ```js 13 | * postToTumblr(); 14 | * ``` 15 | */ 16 | 17 | const postToTumblr = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.tumblr.post', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(postToTumblr); 23 | -------------------------------------------------------------------------------- /src/actions/shareWithExtensions.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Share with Extensions 5 | * @section Content Types > Sharing > System 6 | * @icon Apps 7 | * 8 | * Prompts to share the input using action extensions and sharing extensions provided by other apps. 9 | * 10 | * ```js 11 | * shareWithExtensions(); 12 | * ``` 13 | */ 14 | 15 | const shareWithExtensions = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.runextension', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default shareWithExtensions; 21 | -------------------------------------------------------------------------------- /__tests__/actions/getDiffbotArticleFromWebPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { getDiffbotArticleFromWebPage } from '../../src/actions'; 2 | 3 | describe('getDiffbotArticleFromWebPage function', () => { 4 | it('is a function', () => { 5 | expect(typeof getDiffbotArticleFromWebPage).toBe('function'); 6 | }); 7 | 8 | it('builds a get article action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getarticle', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getDiffbotArticleFromWebPage({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest" 5 | }, 6 | moduleFileExtensions: [ 7 | "ts", 8 | "tsx", 9 | "js", 10 | "jsx", 11 | "json", 12 | "node", 13 | ], 14 | testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(ts|js)x?$', 15 | testPathIgnorePatterns: [ 16 | '/node_modules/', 17 | '/shortcuts/', 18 | '/__tests__/_fixtures/', 19 | '/__tests__/_helpers/', 20 | ], 21 | coverageDirectory: 'coverage', 22 | collectCoverageFrom: [ 23 | 'src/**/*.{ts,tsx,js,jsx}', 24 | '!src/**/*.d.ts', 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /__tests__/actions/getPhoneNumbersFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getPhoneNumbersFromInput } from '../../src/actions'; 2 | 3 | describe('getPhoneNumbersFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getPhoneNumbersFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get phone numbers from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.phonenumber', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getPhoneNumbersFromInput({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/makeMarkdownFromRichText.spec.ts: -------------------------------------------------------------------------------- 1 | import { makeMarkdownFromRichText } from '../../src/actions'; 2 | 3 | describe('makeMarkdownFromRichText function', () => { 4 | it('is a function', () => { 5 | expect(typeof makeMarkdownFromRichText).toBe('function'); 6 | }); 7 | 8 | it('builds a get markdown from rich text action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmarkdownfromrichtext', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = makeMarkdownFromRichText(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/makeRichTextFromMarkdown.spec.ts: -------------------------------------------------------------------------------- 1 | import { makeRichTextFromMarkdown } from '../../src/actions'; 2 | 3 | describe('makeRichTextFromMarkdown function', () => { 4 | it('is a function', () => { 5 | expect(typeof makeRichTextFromMarkdown).toBe('function'); 6 | }); 7 | 8 | it('builds a get rich text from markdown action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.getrichtextfrommarkdown', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = makeRichTextFromMarkdown(); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/deletePhotos.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Delete Photos 5 | * @section Content Types > Photos & Video > Photos 6 | * @icon Photos 7 | * 8 | * Deletes the photos passed as input from the device's photo library. This action asks for confirmation before performing the deletion. 9 | * 10 | * ```js 11 | * deletePhotos(); 12 | * ``` 13 | */ 14 | 15 | const deletePhotos = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.deletephotos', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default deletePhotos; 21 | -------------------------------------------------------------------------------- /src/actions/getLinkToFile.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Link to File 7 | * @section Content Types > Documents > File Storage 8 | * @icon Documents 9 | * 10 | * Gets a public link to the file passed into the action. 11 | * 12 | * ```js 13 | * getLinkToFile(); 14 | * ``` 15 | */ 16 | 17 | const getLinkToFile = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.file.getlink', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getLinkToFile); 23 | -------------------------------------------------------------------------------- /__tests__/actions/detectLanguageWithMicrosoft.spec.ts: -------------------------------------------------------------------------------- 1 | import { detectLanguageWithMicrosoft } from '../../src/actions'; 2 | 3 | describe('detectLanguageWithMicrosoft function', () => { 4 | it('is a function', () => { 5 | expect(typeof detectLanguageWithMicrosoft).toBe('function'); 6 | }); 7 | 8 | it('builds a detect language with microsoft action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detectlanguage', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = detectLanguageWithMicrosoft({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /__tests__/actions/getEmailAddressesFromInput.spec.ts: -------------------------------------------------------------------------------- 1 | import { getEmailAddressesFromInput } from '../../src/actions'; 2 | 3 | describe('getEmailAddressesFromInput function', () => { 4 | it('is a function', () => { 5 | expect(typeof getEmailAddressesFromInput).toBe('function'); 6 | }); 7 | 8 | it('builds a get email addresses from input action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.emailaddress', 11 | WFWorkflowActionParameters: {}, 12 | }; 13 | const actual = getEmailAddressesFromInput({}); 14 | 15 | expect(actual).toEqual(expected); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/actions/getURLsFromInput.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get URLs from Input 7 | * @section Content Types > Web > URLs 8 | * @icon URL 9 | * 10 | * Returns any links found in the output from the previous action. 11 | * 12 | * ```js 13 | * getURLsFromInput(); 14 | * ``` 15 | */ 16 | 17 | const getURLsFromInput = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.link', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getURLsFromInput); 23 | -------------------------------------------------------------------------------- /src/actions/makeRichTextFromHTML.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Make Rich Text from HTML 5 | * @section Content Types > Text > Rich Text 6 | * @icon RichText 7 | * 8 | * Takes the inputted HTML and turns it into rich text, which can then be converted to other formats. 9 | * 10 | * ```js 11 | * makeRichTextFromHTML(); 12 | * ``` 13 | */ 14 | 15 | const makeRichTextFromHTML = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getrichtextfromhtml', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default makeRichTextFromHTML; 21 | -------------------------------------------------------------------------------- /src/actions/viewContentGraph.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action View Content Graph 7 | * @section Actions > Scripting > Content 8 | * @icon Graph 9 | * 10 | * Shows the results of the previous action in the Content Graph. 11 | * 12 | * ```js 13 | * viewContentGraph(); 14 | * ``` 15 | */ 16 | 17 | const viewContentGraph = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.viewresult', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(viewContentGraph); 23 | -------------------------------------------------------------------------------- /__tests__/utils/encodeShortcut.spec.ts: -------------------------------------------------------------------------------- 1 | import { encodeShortcut } from '../../src/utils'; 2 | 3 | import { testShortcutNoActions } from '../_fixtures/actions'; 4 | 5 | const createBplist: (obj: {}) => string = require('bplist-creator'); 6 | 7 | describe('encodeShortcut function', () => { 8 | 9 | it('is a function', () => { 10 | expect(typeof encodeShortcut).toBe('function'); 11 | }); 12 | 13 | it('converts the shortcut to a bplist', () => { 14 | const expected = createBplist(testShortcutNoActions); 15 | const actual = encodeShortcut(testShortcutNoActions); 16 | 17 | expect(actual).toEqual(expected); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/actions/postToWordPress.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Post to WordPress 7 | * @section Content Types > Sharing > WordPress 8 | * @icon WordPress 9 | * 10 | * Posts the input to a WordPress blog as a new post or page. 11 | * 12 | * ```js 13 | * postToWordPress(); 14 | * ``` 15 | */ 16 | 17 | const postToWordPress = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.wordpress.post', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(postToWordPress); 23 | -------------------------------------------------------------------------------- /docs/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { BrowserRouter } from 'react-router-dom'; 4 | 5 | import './styles/base.scss'; 6 | import App from './components/App'; 7 | import * as serviceWorker from './serviceWorker'; 8 | 9 | ReactDOM.render(( 10 | 11 | 12 | 13 | ), document.getElementById('root')); 14 | 15 | // If you want your app to work offline and load faster, you can change 16 | // unregister() to register() below. Note this comes with some pitfalls. 17 | // Learn more about service workers: http://bit.ly/CRA-PWA 18 | serviceWorker.unregister(); 19 | -------------------------------------------------------------------------------- /src/actions/getBatteryLevel.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | import { withActionOutput } from '../utils'; 4 | 5 | /** 6 | * @action Get Battery Level 7 | * @section Actions > Scripting > Device 8 | * @icon Battery 9 | * 10 | * Outputs the percentage of battery remaining as a number from 0 to 100. 11 | * 12 | * ```js 13 | * getBatteryLevel(); 14 | * ``` 15 | */ 16 | 17 | const getBatteryLevel = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getbatterylevel', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getBatteryLevel); 23 | -------------------------------------------------------------------------------- /src/actions/getType.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Type 7 | * @section Actions > Scripting > Content 8 | * @icon Scripting 9 | * 10 | * Returns the type of every item passed as input. For example, if a URL is passed, this action will return “URL”. 11 | * 12 | * ```js 13 | * getType(); 14 | * ``` 15 | */ 16 | 17 | const getType = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getitemtype', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getType); 23 | -------------------------------------------------------------------------------- /src/actions/showInCalendar.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Show in Calendar 7 | * @section Content Types > Calendar > Calendar 8 | * @icon Calendar 9 | * 10 | * Shows the date or calendar event passed as input in the Calendar app. 11 | * 12 | * ```js 13 | * showInCalendar(); 14 | * ``` 15 | */ 16 | 17 | const showInCalendar = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.showincalendar', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(showInCalendar); 23 | -------------------------------------------------------------------------------- /src/actions/getHeadersOfURL.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Headers of URL 7 | * @section Content Types > Web > URLs 8 | * @icon Downloads 9 | * 10 | * Retrieves the HTTP headers of the URL passed as input using a HEAD request. 11 | * 12 | * ```js 13 | * getHeadersOfURL(); 14 | * ``` 15 | */ 16 | 17 | const getHeadersOfURL = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.url.getheaders', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getHeadersOfURL); 23 | -------------------------------------------------------------------------------- /src/actions/scanQROrBarcode.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Scan QR/BarCode 7 | * @section Content Types > Text > 8 | * @icon QRCode 9 | * 10 | * Scans a QR code or bar code using the camera, and returns the text/URL that is found. 11 | * 12 | * ```js 13 | * scanQROrBarcode(); 14 | * ``` 15 | */ 16 | 17 | const scanQROrBarcode = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.scanbarcode', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(scanQROrBarcode); 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["es2017"], 4 | "target": "es6", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "importHelpers": true, 9 | "jsx": "react", 10 | "alwaysStrict": true, 11 | "sourceMap": true, 12 | "declaration": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "noImplicitReturns": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "strict": true 19 | }, 20 | "include": [ 21 | "src/**/*", 22 | "__tests__/**/*" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /src/actions/expandURL.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Expand URL 7 | * @section Content Types > Web > URLs 8 | * @icon URL 9 | * 10 | * This action expands and cleans up URLs which have been shortened using a URL shortening service like TinyURL or Bit.ly. 11 | * 12 | * ```js 13 | * expandURL(); 14 | * ``` 15 | */ 16 | 17 | const expandURL = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.url.expand', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(expandURL); 23 | -------------------------------------------------------------------------------- /src/actions/extractArchive.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Extract Archive 5 | * @section Content Types > Documents > Archives 6 | * @icon Documents 7 | * 8 | * Extracts files from the archive passed as input. Many archive formats are supported, including zip, rar, tar.gz, tar.bz2, tar, gzip, cpio, cab, and iso archives. 9 | * 10 | * ```js 11 | * extractArchive(); 12 | * ``` 13 | */ 14 | 15 | const extractArchive = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.unzip', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default extractArchive; 21 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Contributing/ActionIcons/content.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | ### Action Icons 4 | 5 | [WIP: you can set an action icon via the `@icon` tag...] 6 | 7 | ```ts 8 | /** 9 | * @action Add to Reading List 10 | * @section Content Types > Web > Safari 11 | * @icon Safari 12 | * 13 | * Adds URLs passed into the action to your reading list. 14 | * 15 | * ```js 16 | * addToReadingList(); 17 | * ``` 18 | */ 19 | const addToReadingList = (): WFWorkflowAction => ({ 20 | WFWorkflowActionIdentifier: 'is.workflow.actions.readinglist', 21 | WFWorkflowActionParameters: {}, 22 | }); 23 | ``` 24 | 25 | [WIP: here are the available action icons...] 26 | -------------------------------------------------------------------------------- /src/actions/getMapsURL.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Maps URL 7 | * @section Content Types > Location > Maps 8 | * @icon Maps 9 | * 10 | * Creates a URL to search for the location, place, or text that was passed into the action in a separate maps app. 11 | * 12 | * ```js 13 | * getMapsURL(); 14 | * ``` 15 | */ 16 | 17 | const getMapsURL = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmapslink', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getMapsURL); 23 | -------------------------------------------------------------------------------- /src/actions/URL.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action URL 5 | * @section Content Types > Web > URLs 6 | * @icon URL 7 | * 8 | * Passes the specified URL to the next action. 9 | * 10 | * ```js 11 | * URL({ 12 | * url: 'https://shortcuts.fun', 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const URL = ( 18 | { 19 | url = '', 20 | }: { 21 | /** The URL to set */ 22 | url?: string, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.url', 26 | WFWorkflowActionParameters: { 27 | WFURLActionURL: url, 28 | }, 29 | }); 30 | 31 | export default URL; 32 | -------------------------------------------------------------------------------- /src/actions/getContentsOfWebPage.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Contents of Web Page 7 | * @section Content Types > Web > Safari 8 | * @icon Safari 9 | * 10 | * Extracts the contents of the web pages passed into the action. 11 | * 12 | * ```js 13 | * getContentsOfWebPage(); 14 | * ``` 15 | */ 16 | 17 | const getContentsOfWebPage = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getwebpagecontents', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getContentsOfWebPage); 23 | -------------------------------------------------------------------------------- /src/actions/getImagesFromInput.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Get Images from Input 5 | * @section Content Types > Photos & Video > Images 6 | * @icon Image 7 | * 8 | * Gets images from the result of the previous action. For example, this action can get the album art of a song, or all the images on a web page. 9 | * 10 | * ```js 11 | * getImagesFromInput(); 12 | * ``` 13 | */ 14 | 15 | const getImagesFromInput = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.images', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default getImagesFromInput; 21 | -------------------------------------------------------------------------------- /src/actions/makeMarkdownFromRichText.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Make Markdown from Rich Text 5 | * @section Content Types > Text > Rich Text 6 | * @icon RichText 7 | * 8 | * Converts the rich text passed as input to Markdown text (comparable to Aaron Swartz's html2text script). 9 | * 10 | * ```js 11 | * makeMarkdownFromRichText(); 12 | * ``` 13 | */ 14 | 15 | const makeMarkdownFromRichText = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmarkdownfromrichtext', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default makeMarkdownFromRichText; 21 | -------------------------------------------------------------------------------- /src/actions/makeRichTextFromMarkdown.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Make Rich Text from Markdown 5 | * @section Content Types > Text > Rich Text 6 | * @icon RichText 7 | * 8 | * Takes the inputted Markdown and turns it into rich text, which can then be converted to other formats. 9 | * 10 | * ```js 11 | * makeRichTextFromMarkdown(); 12 | * ``` 13 | */ 14 | 15 | const makeRichTextFromMarkdown = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.getrichtextfrommarkdown', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default makeRichTextFromMarkdown; 21 | -------------------------------------------------------------------------------- /src/actions/showInITunesStore.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Show in iTunes Store 5 | * @section Content Types > Music > iTunes Store 6 | * @icon iTunes 7 | * 8 | * Shows the iTunes products or App Store apps passed as input in a store sheet. This is useful with the Search iTunes Store and Search App Store actions. 9 | * 10 | * ```js 11 | * showInITunesStore(); 12 | * ``` 13 | */ 14 | 15 | const showInITunesStore = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.showinstore', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default showInITunesStore; 21 | -------------------------------------------------------------------------------- /src/actions/waitToReturn.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Wait to Return 5 | * @section Actions > Scripting > Control Flow 6 | * @icon Scripting 7 | * 8 | * Pauses execution until you leave the Shortcuts app and return to it. This action might be useful after an action that switches apps, to pause execution until you return to the Shortcuts app. 9 | * 10 | * ```js 11 | * waitToReturn(); 12 | * ``` 13 | */ 14 | 15 | const waitToReturn = (): WFWorkflowAction => ({ 16 | WFWorkflowActionIdentifier: 'is.workflow.actions.waittoreturn', 17 | WFWorkflowActionParameters: {}, 18 | }); 19 | 20 | export default waitToReturn; 21 | -------------------------------------------------------------------------------- /src/actions/detectLanguageWithMicrosoft.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Detect Language with Microsoft 7 | * @section Content Types > Text > 8 | * @icon Translate 9 | * 10 | * Detects the language of the text provided as input. 11 | * 12 | * ```js 13 | * detectLanguageWithMicrosoft(); 14 | * ``` 15 | */ 16 | 17 | const detectLanguageWithMicrosoft = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detectlanguage', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(detectLanguageWithMicrosoft); 23 | -------------------------------------------------------------------------------- /src/actions/openApp.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Open App 5 | * @section Content Types > Apps > 6 | * @icon Apps 7 | * 8 | * Opens the specified app. 9 | * 10 | * ```js 11 | * openApp({ 12 | * appId: 'com.christianselig.Apollo' 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const openApp = ( 18 | { 19 | appId = '', 20 | }: { 21 | /** The App identifier */ 22 | appId?: string; 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.openapp', 26 | WFWorkflowActionParameters: { 27 | WFAppIdentifier: appId, 28 | }, 29 | }); 30 | 31 | export default openApp; 32 | -------------------------------------------------------------------------------- /src/actions/selectEmailAddress.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Select Email Address 7 | * @section Content Types > Contacts > Mail 8 | * @icon Mail 9 | * 10 | * Prompts to pick an email address from your contacts and passes the selection to the next action. 11 | * 12 | * ```js 13 | * selectEmailAddress(); 14 | * ``` 15 | */ 16 | 17 | const selectEmailAddress = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.selectemail', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(selectEmailAddress); 23 | -------------------------------------------------------------------------------- /src/actions/selectPhoneNumber.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Select Phone Number 7 | * @section Content Types > Contacts > Phone 8 | * @icon PhoneNumber 9 | * 10 | * Prompts to pick a phone number from your contacts and passes the selection to the next action. 11 | * 12 | * ```js 13 | * selectPhoneNumber(); 14 | * ``` 15 | */ 16 | 17 | const selectPhoneNumber = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.selectphone', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(selectPhoneNumber); 23 | -------------------------------------------------------------------------------- /src/actions/setWiFi.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Wi-Fi 5 | * @section Actions > Scripting > Device 6 | * @icon Wi-Fi 7 | * 8 | * Sets the device’s Wi-Fi to on or off. 9 | * 10 | * ```js 11 | * setWiFi({ 12 | * value: true, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setWiFi = ( 18 | { 19 | value = true, 20 | }: { 21 | /** Enable or disable Wi-Fi */ 22 | value?: boolean, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.wifi.set', 26 | WFWorkflowActionParameters: { 27 | OnValue: value, 28 | }, 29 | }); 30 | 31 | export default setWiFi; 32 | -------------------------------------------------------------------------------- /__tests__/utils/variable.spec.ts: -------------------------------------------------------------------------------- 1 | import WFSerialization from '../../src/interfaces/WF/WFSerialization'; 2 | import { variable } from '../../src/utils'; 3 | 4 | describe('variable function', () => { 5 | 6 | it('is a function', () => { 7 | expect(typeof variable).toBe('function'); 8 | }); 9 | 10 | it('returns a variable when passed a string', () => { 11 | const actual = variable('My Variable'); 12 | const expected: WFSerialization = { 13 | Value: { 14 | VariableName: 'My Variable', 15 | Type: 'Variable', 16 | }, 17 | WFSerializationType: 'WFTextTokenAttachment', 18 | }; 19 | 20 | expect(actual).toEqual(expected); 21 | }); 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /src/actions/getName.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Name 7 | * @section Actions > Scripting > Content 8 | * @icon Scripting 9 | * 10 | * Returns the name of every item passed as input. Depending on the input, this could be a file name, the title of a website, the title of a calendar event, etc. 11 | * 12 | * ```js 13 | * getName(); 14 | * ``` 15 | */ 16 | 17 | const getName = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getitemname', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getName); 23 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflowInputContentItemClass.ts: -------------------------------------------------------------------------------- 1 | type WFWorkflowInputContentItemClass = ( 2 | 'WFAppStoreAppContentItem' 3 | | 'WFArticleContentItem' 4 | | 'WFContactContentItem' 5 | | 'WFDateContentItem' 6 | | 'WFEmailAddressContentItem' 7 | | 'WFGenericFileContentItem' 8 | | 'WFImageContentItem' 9 | | 'WFiTunesProductContentItem' 10 | | 'WFLocationContentItem' 11 | | 'WFDCMapsLinkContentItem' 12 | | 'WFAVAssetContentItem' 13 | | 'WFPDFContentItem' 14 | | 'WFPhoneNumberContentItem' 15 | | 'WFRichTextContentItem' 16 | | 'WFSafariWebPageContentItem' 17 | | 'WFStringContentItem' 18 | | 'WFURLContentItem' 19 | ); 20 | 21 | export default WFWorkflowInputContentItemClass; 22 | -------------------------------------------------------------------------------- /src/actions/getPhoneNumbersFromInput.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Phone Numbers from Input 7 | * @section Content Types > Contacts > Phone 8 | * @icon PhoneNumber 9 | * 10 | * Returns any phone numbers found in the output from the previous action. 11 | * 12 | * ```js 13 | * getPhoneNumbersFromInput(); 14 | * ``` 15 | */ 16 | 17 | const getPhoneNumbersFromInput = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.phonenumber', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getPhoneNumbersFromInput); 23 | -------------------------------------------------------------------------------- /src/actions/getTextFromInput.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Text from Input 7 | * @section Content Types > Text > 8 | * @icon Text 9 | * 10 | * Returns text from the previous action's output. For example, this action can get the name of a photo or song, or the text of a web page. 11 | * 12 | * ```js 13 | * getTextFromInput(); 14 | * ``` 15 | */ 16 | 17 | const getTextFromInput = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.text', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getTextFromInput); 23 | -------------------------------------------------------------------------------- /src/actions/getEmailAddressesFromInput.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Email Addresses from Input 7 | * @section Content Types > Contacts > Mail 8 | * @icon Mail 9 | * 10 | * Returns any email addresses found in the output from the previous action. 11 | * 12 | * ```js 13 | * getEmailAddressesFromInput(); 14 | * ``` 15 | */ 16 | 17 | const getEmailAddressesFromInput = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.emailaddress', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getEmailAddressesFromInput); 23 | -------------------------------------------------------------------------------- /src/actions/getMyShortcuts.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get My Shortcuts 7 | * @section Actions > Scripting > Shortcuts 8 | * @icon Shortcuts 9 | * 10 | * Gets the shortcuts stored on this device. For example, you could use this action with the Make Archive action to zip up your shortcuts. 11 | * 12 | * ```js 13 | * getMyShortcuts(); 14 | * ``` 15 | */ 16 | 17 | const getMyShortcuts = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getmyworkflows', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getMyShortcuts); 23 | -------------------------------------------------------------------------------- /src/actions/setVolume.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Volume 5 | * @section Content Types > Music > Playback 6 | * @icon Sound 7 | * 8 | * Sets the system volume. 9 | * 10 | * ```js 11 | * setVolume({ 12 | * volume: 50, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setVolume = ( 18 | { 19 | volume = 50, 20 | }: { 21 | /** Number between 0 & 100 to set the volume to */ 22 | volume ?: number, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvolume', 26 | WFWorkflowActionParameters: { 27 | WFVolume: volume / 100, 28 | }, 29 | }); 30 | 31 | export default setVolume; 32 | -------------------------------------------------------------------------------- /docs/src/components/Home/Footer/styles.module.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | width: 100%; 3 | margin-top: 64px; 4 | padding-top: 6px; 5 | 6 | background: var(--pink-color); 7 | background: -webkit-linear-gradient(to right, var(--pink-color), var(--aqua-color)); 8 | background: linear-gradient(to right, var(--pink-color), var(--aqua-color)); 9 | color: var(--white-color); 10 | } 11 | 12 | .textContainer { 13 | display: flex; 14 | flex-flow: column nowrap; 15 | align-items: center; 16 | justify-content: center; 17 | 18 | width: 100%; 19 | height: 100%; 20 | padding: 16px; 21 | background: var(--shadow-color); 22 | text-align: center; 23 | } 24 | 25 | .link { 26 | color: var(--white-color); 27 | } 28 | -------------------------------------------------------------------------------- /src/actions/wait.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Wait 5 | * @section Actions > Scripting > Control Flow 6 | * @icon Scripting 7 | * 8 | * Waits for the specified number of seconds before continuing with the next action. 9 | * 10 | * ```js 11 | * wait({ 12 | * time: 19, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const wait = ( 18 | { 19 | time = 1, 20 | }: { 21 | /** The number of seconds to wait */ 22 | time?: number, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.delay', 26 | WFWorkflowActionParameters: { 27 | WFDelayTime: time, 28 | }, 29 | }); 30 | 31 | export default wait; 32 | -------------------------------------------------------------------------------- /src/actions/setBluetooth.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Bluetooth 5 | * @section Actions > Scripting > Device 6 | * @icon Bluetooth 7 | * 8 | * Sets the device’s Bluetooth to on or off. 9 | * 10 | * ```js 11 | * setBluetooth({ 12 | * value: true, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setBluetooth = ( 18 | { 19 | value = true, 20 | }: { 21 | /** Enable or disable Bluetooth */ 22 | value?: boolean, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.bluetooth.set', 26 | WFWorkflowActionParameters: { 27 | OnValue: value, 28 | }, 29 | }); 30 | 31 | export default setBluetooth; 32 | -------------------------------------------------------------------------------- /src/variables.ts: -------------------------------------------------------------------------------- 1 | import Variable from './interfaces/Variable'; 2 | 3 | const askWhenRun: Variable = new Variable({ 4 | Type: 'Ask', 5 | }); 6 | 7 | const clipboard: Variable = new Variable({ 8 | Type: 'Clipboard', 9 | }); 10 | 11 | const currentDate: Variable = new Variable({ 12 | Type: 'CurrentDate', 13 | }); 14 | 15 | const shortcutInput: Variable = new Variable({ 16 | Type: 'ExtensionInput', 17 | }); 18 | 19 | const repeatIndex = ( 20 | level?: number, 21 | ): Variable => new Variable({ 22 | VariableName: level && level !== 1 ? `Repeat Index ${level}` : 'Repeat Index', 23 | Type: 'Variable', 24 | }); 25 | 26 | export { 27 | askWhenRun, 28 | clipboard, 29 | currentDate, 30 | repeatIndex, 31 | shortcutInput, 32 | }; 33 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFWorkflow.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from './WFWorkflowAction'; 2 | import WFWorkflowIcon from './WFWorkflowIcon'; 3 | import WFWorkflowImportQuestion from './WFWorkflowImportQuestion'; 4 | import WFWorkflowInputContentItemClass from './WFWorkflowInputContentItemClass'; 5 | import WFWorkflowType from './WFWorkflowType'; 6 | 7 | interface WFWorkflow { 8 | WFWorkflowClientVersion: string; 9 | WFWorkflowClientRelease: string; 10 | WFWorkflowIcon: WFWorkflowIcon; 11 | WFWorkflowImportQuestions: WFWorkflowImportQuestion[]; 12 | WFWorkflowTypes: WFWorkflowType[]; 13 | WFWorkflowInputContentItemClasses: WFWorkflowInputContentItemClass[]; 14 | WFWorkflowActions: WFWorkflowAction[]; 15 | } 16 | 17 | export default WFWorkflow; 18 | -------------------------------------------------------------------------------- /src/actions/setAirplaneMode.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Airplane Mode 5 | * @section Actions > Scripting > Device 6 | * @icon AirplaneMode 7 | * 8 | * Sets the device’s Airplane Mode to on or off. 9 | * 10 | * ```js 11 | * setAirplaneMode({ 12 | * value: true, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setAirplaneMode = ( 18 | { 19 | value = true, 20 | }: { 21 | /** Enable or disable airplane mode */ 22 | value?: boolean, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.airplanemode.set', 26 | WFWorkflowActionParameters: { 27 | OnValue: value, 28 | }, 29 | }); 30 | 31 | export default setAirplaneMode; 32 | -------------------------------------------------------------------------------- /src/actions/setCellularData.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Cellular Data 5 | * @section Actions > Scripting > Device 6 | * @icon CellularData 7 | * 8 | * Sets the device’s Cellular Data to on or off. 9 | * 10 | * ```js 11 | * setCellularData({ 12 | * value: true, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setCellularData = ( 18 | { 19 | value = true, 20 | }: { 21 | /** Enable or disable cellular data */ 22 | value?: boolean, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.cellulardata.set', 26 | WFWorkflowActionParameters: { 27 | OnValue: value, 28 | }, 29 | }); 30 | 31 | export default setCellularData; 32 | -------------------------------------------------------------------------------- /src/actions/setLowPowerMode.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Low Power Mode 5 | * @section Actions > Scripting > Device 6 | * @icon Battery 7 | * 8 | * Sets the device’s Low Power Mode to on or off. 9 | * 10 | * ```js 11 | * setLowPowerMode({ 12 | * value: false, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setLowPowerMode = ( 18 | { 19 | value = true, 20 | }: { 21 | /** Enable or disable low power mode */ 22 | value?: boolean, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.lowpowermode.set', 26 | WFWorkflowActionParameters: { 27 | OnValue: value, 28 | }, 29 | }); 30 | 31 | export default setLowPowerMode; 32 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Screenshot/styles.module.scss: -------------------------------------------------------------------------------- 1 | .screenshot { 2 | $width: 300px; 3 | $padding: $width / 397px * 24px; 4 | 5 | display: inline-block; 6 | padding: $padding; 7 | margin: 0 20px 1.7rem; 8 | box-sizing: border-box; 9 | background-image: url(./frame-xs-max.png); 10 | background-repeat: no-repeat; 11 | background-size: 100%; 12 | overflow: hidden; 13 | width: $width; 14 | font-size: 0; 15 | 16 | &.top { 17 | padding-bottom: 0; 18 | border-bottom: 1px solid #e6e6e6; 19 | } 20 | 21 | &.bottom { 22 | padding-top: 0; 23 | border-top: 1px solid #e6e6e6; 24 | background-position: bottom; 25 | } 26 | 27 | img { 28 | position: relative; 29 | width: 100%; 30 | z-index: -1; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/actions/getDiffbotArticleFromWebPage.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Diffbot Article from Web Page 7 | * @section Content Types > Web > Articles 8 | * @icon DownloadArticle 9 | * 10 | * Gets article details, including body text, author, publish date, and more, from every URL passed into the action. 11 | * 12 | * ```js 13 | * getDiffbotArticleFromWebPage(); 14 | * ``` 15 | */ 16 | 17 | const getDiffbotArticleFromWebPage = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.getarticle', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getDiffbotArticleFromWebPage); 23 | -------------------------------------------------------------------------------- /src/actions/setBrightness.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Set Brightness 5 | * @section Actions > Scripting > Device 6 | * @icon Brightness 7 | * 8 | * Sets the device brightness. 9 | * 10 | * ```js 11 | * setBrightness({ 12 | * brightness: 75, 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const setBrightness = ( 18 | { 19 | brightness = 100, 20 | }: { 21 | /** The brightness percentage value from 0 to 100 */ 22 | brightness?: number, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.setbrightness', 26 | WFWorkflowActionParameters: { 27 | WFBrightness: brightness / 100, 28 | }, 29 | }); 30 | 31 | export default setBrightness; 32 | -------------------------------------------------------------------------------- /src/actions/number.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Number 7 | * @section Actions > Scripting > Maths 8 | * @icon Calculator 9 | * 10 | * Passes a number to the next action. 11 | * 12 | * ```js 13 | * number({ 14 | * number: 7, 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const numberAction = ( 20 | { 21 | number = 0, 22 | }: { 23 | /** The number to set */ 24 | number?: number; 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.number', 28 | WFWorkflowActionParameters: { 29 | WFNumberActionNumber: number, 30 | }, 31 | }); 32 | 33 | export default withActionOutput(numberAction); 34 | -------------------------------------------------------------------------------- /src/actions/getDictionaryFromInput.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Dictionary from Input 7 | * @section Actions > Scripting > Dictionaries 8 | * @icon Scripting 9 | * 10 | * Makes a dictionary from the text passed as input. JSON (like {"foo": "bar"}), key-value pairs (like foo=bar&baz=biz), and XML-based plist are supported. 11 | * 12 | * ```js 13 | * getDictionaryFromInput(); 14 | * ``` 15 | */ 16 | 17 | const getDictionaryFromInput = (): WFWorkflowAction => ({ 18 | WFWorkflowActionIdentifier: 'is.workflow.actions.detect.dictionary', 19 | WFWorkflowActionParameters: {}, 20 | }); 21 | 22 | export default withActionOutput(getDictionaryFromInput); 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | _Please delete all sections in italics before submitting this PR._ 2 | 3 | **Checks** 4 | 5 | - [ ] I've checked there are no linting errors. 6 | - [ ] I've checked the code is still at 100% test coverage. 7 | 8 | 9 | **Added Actions (if relevant)** 10 | 11 | - _List added actions here..._ 12 | 13 | 14 | **Are you happy to be listed as a contributor on [Shortcuts.fun](https://shortcuts.fun)?** 15 | 16 | _Yes_ / _No_ 17 | 18 | 19 | **Any other information / comments** 20 | 21 | _If this is your first time contributing, I'd love to hear what you thought about the process. Was it easy/hard to find the information you were looking for? Did the Contributing Guide make sense? What were your stumbling blocks? Basically, any and all feedback is encouraged!_ 22 | -------------------------------------------------------------------------------- /__tests__/actions/setVariable.spec.ts: -------------------------------------------------------------------------------- 1 | import { setVariable } from '../../src/actions'; 2 | import { variable } from '../../src/utils'; 3 | 4 | describe('setVariable function', () => { 5 | 6 | it('is a function', () => { 7 | expect(typeof setVariable).toBe('function'); 8 | }); 9 | 10 | it('builds a setVariable action when a variable is passed', () => { 11 | const name = variable('Test Variable'); 12 | 13 | const expected = { 14 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvariable', 15 | WFWorkflowActionParameters: { 16 | WFVariableName: name.Value.VariableName, 17 | }, 18 | }; 19 | 20 | const actual = setVariable({ 21 | variable: name, 22 | }); 23 | 24 | expect(actual).toEqual(expected); 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /src/actions/comment.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Comment 5 | * @section Actions > Scripting > 6 | * @icon Text 7 | * 8 | * This action lets you explain how part of a shortcut works. When run, this action does nothing. 9 | * 10 | * ```js 11 | * // Create a comment 12 | * comment({ 13 | * text: 'A very important comment', 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const comment = ( 19 | { 20 | text = '', 21 | }: { 22 | /** The body of the comment */ 23 | text?: string, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'is.workflow.actions.comment', 27 | WFWorkflowActionParameters: { 28 | WFCommentActionText: text, 29 | }, 30 | }); 31 | 32 | export default comment; 33 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { actionOutput } from './actionOutput'; 2 | import { buildSerialization } from './buildSerialization'; 3 | import { buildShortcut } from './buildShortcut'; 4 | import { buildShortcutTemplate } from './buildShortcutTemplate'; 5 | import { encodeShortcut } from './encodeShortcut'; 6 | import { flatten } from './flatten'; 7 | import { getItemType } from './getItemType'; 8 | import { variable } from './variable'; 9 | import { withActionOutput } from './withActionOutput'; 10 | import { withVariables } from './withVariables'; 11 | 12 | export { 13 | actionOutput, 14 | buildSerialization, 15 | buildShortcut, 16 | buildShortcutTemplate, 17 | encodeShortcut, 18 | flatten, 19 | getItemType, 20 | variable, 21 | withActionOutput, 22 | withVariables, 23 | }; 24 | -------------------------------------------------------------------------------- /__tests__/actions/addToVariable.spec.ts: -------------------------------------------------------------------------------- 1 | import { addToVariable } from '../../src/actions'; 2 | import { variable } from '../../src/utils'; 3 | 4 | describe('addToVariable function', () => { 5 | 6 | it('is a function', () => { 7 | expect(typeof addToVariable).toBe('function'); 8 | }); 9 | 10 | it('builds a addToVariable action when a variable is passed', () => { 11 | const name = variable('Test Variable'); 12 | 13 | const expected = { 14 | WFWorkflowActionIdentifier: 'is.workflow.actions.appendvariable', 15 | WFWorkflowActionParameters: { 16 | WFVariableName: name.Value.VariableName, 17 | }, 18 | }; 19 | 20 | const actual = addToVariable({ 21 | variable: name, 22 | }); 23 | 24 | expect(actual).toEqual(expected); 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /src/actions/postOnInstagram.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | /** 4 | * @action Post on Instagram 5 | * @section Content Types > Sharing > Instagram 6 | * @icon Instagram 7 | * 8 | * Opens the photo passed into this action in the Instagram app and copies the caption to the clipboard. 9 | * 10 | * ```js 11 | * postOnInstagram({ 12 | * caption: 'My caption', 13 | * }); 14 | * ``` 15 | */ 16 | 17 | const postOnInstagram = ( 18 | { 19 | caption = '', 20 | }: { 21 | /** Photo caption */ 22 | caption?: string, 23 | }, 24 | ): WFWorkflowAction => ({ 25 | WFWorkflowActionIdentifier: 'com.burbn.instagram.openin', 26 | WFWorkflowActionParameters: { 27 | InstagramCaption: caption, 28 | }, 29 | }); 30 | 31 | export default postOnInstagram; 32 | -------------------------------------------------------------------------------- /src/actions/showResult.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 2 | 3 | import WFSerialization from '../interfaces/WF/WFSerialization'; 4 | 5 | /** 6 | * @action Show Result 7 | * @section Actions > Scripting > 8 | * @icon Scripting 9 | * 10 | * Shows the specified text in Siri or in an alert. 11 | * 12 | * ```js 13 | * showResult({ 14 | * text: 'Hello, world!', 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const showResult = ( 20 | { 21 | text = '', 22 | }: { 23 | /** The text to show in the dialogue */ 24 | text?: WFSerialization | string, 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.showresult', 28 | WFWorkflowActionParameters: { 29 | Text: text, 30 | }, 31 | }); 32 | 33 | export default showResult; 34 | -------------------------------------------------------------------------------- /src/actions/getVariable.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Get Variable 6 | * @section Actions > Scripting > Variables 7 | * @icon Variable 8 | * 9 | * Gets the value of the specified variable and passes it to the next action. 10 | * 11 | * ```js 12 | * getVariable({ 13 | * variable: variable('My Variable'), 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const getVariable = ( 19 | { 20 | variable, 21 | }: { 22 | /** The variable to get */ 23 | variable: Variable; 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'is.workflow.actions.getvariable', 27 | WFWorkflowActionParameters: { 28 | WFVariable: variable, 29 | }, 30 | }); 31 | 32 | export default getVariable; 33 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Metadata/ShortcutIcon/content.md: -------------------------------------------------------------------------------- 1 | ## Metadata 2 | 3 | ### Shortcut Icon 4 | 5 | In `buildShortcut()`, the `icon` option let you specify what icon the Shortcut will have. A total of 15 color shades and 256 glyphs (with the addition of 2 unreleased ones) can be used within Shortcuts JS. 6 | 7 | ```js 8 | const { 9 | buildShortcut, 10 | } = require('@joshfarrant/shortcuts-js'); 11 | const { 12 | COLORS, 13 | GLYPHS, 14 | } = require('@joshfarrant/shortcuts-js/meta'); 15 | 16 | const actions = []; 17 | 18 | const shortcut = buildShortcut(actions, { 19 | icon: { 20 | color: COLORS.ORANGE, 21 | glyph: GLYPHS.ROCKET, 22 | }, 23 | }); 24 | ``` 25 | 26 | Default icon color and glyph are `.YELLOW` and `.KEYBOARD` respectively. 27 | Click on one of the following icons to get the corresponding codename. 28 | -------------------------------------------------------------------------------- /src/actions/getLatestVideos.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Latest Videos 7 | * @section Content Types > Photos & Video > Photos 8 | * @icon Photos 9 | * 10 | * Gets the most recent videos from the camera roll. 11 | * 12 | * ```js 13 | * getLatestVideos({ 14 | * count: 1, 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const getLatestVideos = ( 20 | { 21 | count = 1, 22 | }: { 23 | /** The number of videos to get */ 24 | count?: number, 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlastvideo', 28 | WFWorkflowActionParameters: { 29 | WFGetLatestPhotoCount: count, 30 | }, 31 | }); 32 | 33 | export default withActionOutput(getLatestVideos); 34 | -------------------------------------------------------------------------------- /src/actions/setTorch.ts: -------------------------------------------------------------------------------- 1 | import WFFlashlightSetting from '../interfaces/WF/WFFlashlightSetting'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Set Flashlight 6 | * @section Actions > Scripting > Device 7 | * @icon Flashlight 8 | * 9 | * Turns on or off the flashlight near the device's camera. 10 | * 11 | * ```js 12 | * setTorch({ 13 | * setting: 'Off', 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const setTorch = ( 19 | { 20 | setting = 'On', 21 | }: { 22 | /** The state to set for the torch */ 23 | setting?: WFFlashlightSetting, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'is.workflow.actions.flashlight', 27 | WFWorkflowActionParameters: { 28 | WFFlashlightSetting: setting, 29 | }, 30 | }); 31 | 32 | export default setTorch; 33 | -------------------------------------------------------------------------------- /__tests__/_helpers/compareObjectsWithGroupingIdentifier.ts: -------------------------------------------------------------------------------- 1 | import WFWorkflowAction from '../../src/interfaces/WF/WFWorkflowAction'; 2 | 3 | export const compareObjectsWithGroupingIdentifier = ( 4 | actual: WFWorkflowAction | WFWorkflowAction[], 5 | expected: WFWorkflowAction[], 6 | ) => { 7 | const actualArr = Array.isArray(actual) ? actual : [actual]; 8 | 9 | expect.assertions(expected.length); 10 | 11 | expected.forEach((obj, idx) => { 12 | const actualObj = actualArr[idx]; 13 | const expectedObj = { 14 | ...obj, 15 | }; 16 | 17 | const { GroupingIdentifier } = actualObj.WFWorkflowActionParameters; 18 | if (GroupingIdentifier) { 19 | expectedObj.WFWorkflowActionParameters.GroupingIdentifier = GroupingIdentifier; 20 | } 21 | 22 | expect(actualArr[idx]).toEqual(expectedObj); 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /src/actions/setVariable.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Set Variable 6 | * @section Actions > Scripting > Variables 7 | * @icon Variable 8 | * 9 | * Sets the value of the specified variable to the input of this action. 10 | * 11 | * ```js 12 | * setVariable({ 13 | * variable: variable('My Variable'), 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const setVariable = ( 19 | { 20 | variable, 21 | }: { 22 | /** The variable to set */ 23 | variable: Variable, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvariable', 27 | WFWorkflowActionParameters: { 28 | WFVariableName: variable.Value.VariableName, 29 | }, 30 | }); 31 | 32 | export default setVariable; 33 | -------------------------------------------------------------------------------- /src/actions/getLatestBursts.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Latest Bursts 7 | * @section Content Types > Photos & Video > Photos 8 | * @icon Bursts 9 | * 10 | * Gets the most recent burst photos from the camera roll. 11 | * 12 | * ```js 13 | * getLatestBursts({ 14 | * count: 20, 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const getLatestBursts = ( 20 | { 21 | count = 1, 22 | }: { 23 | /** The number of burst photos to get */ 24 | count?: number, 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlatestbursts', 28 | WFWorkflowActionParameters: { 29 | WFGetLatestPhotoCount: count, 30 | }, 31 | }); 32 | 33 | export default withActionOutput(getLatestBursts); 34 | -------------------------------------------------------------------------------- /src/actions/text.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFSerialization from '../interfaces/WF/WFSerialization'; 4 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 5 | 6 | /** 7 | * @action Text 8 | * @section Content Types > Text > 9 | * @icon Text 10 | * 11 | * Passes the specified text to the next action. 12 | * 13 | * ```js 14 | * text({ 15 | * text: 'Some lovely text!', 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const textAction = ( 21 | { 22 | text = '', 23 | }: { 24 | /** The text to set */ 25 | text?: WFSerialization | string, 26 | }, 27 | ): WFWorkflowAction => ({ 28 | WFWorkflowActionIdentifier: 'is.workflow.actions.gettext', 29 | WFWorkflowActionParameters: { 30 | WFTextActionText: text, 31 | }, 32 | }); 33 | 34 | export default withActionOutput(textAction); 35 | -------------------------------------------------------------------------------- /src/actions/pythonista/editScript.ts: -------------------------------------------------------------------------------- 1 | import WFSerialization from '../../interfaces/WF/WFSerialization'; 2 | import WFWorkflowAction from '../../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Edit Script 6 | * @section Actions > Scripting > Pythonista 7 | * @icon Pythonista 8 | * 9 | * Opens the specified script in Pythonista for editing. 10 | * 11 | * ```js 12 | * editScript({ 13 | * script: 'MyScript.py', 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const editScript = ( 19 | { 20 | script = '', 21 | }: { 22 | /** The name of the script to edit */ 23 | script?: WFSerialization | string, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.editscript', 27 | WFWorkflowActionParameters: { 28 | PythonistaScript: script, 29 | }, 30 | }); 31 | 32 | export default editScript; 33 | -------------------------------------------------------------------------------- /src/actions/getLatestScreenshots.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Latest Screenshots 7 | * @section Content Types > Photos & Video > Photos 8 | * @icon Photos 9 | * 10 | * Gets the most recent screenshots from the camera roll. 11 | * 12 | * ```js 13 | * getLatestScreenshots({ 14 | * count: 1, 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const getLatestScreenshots = ( 20 | { 21 | count = 1, 22 | }: { 23 | /** The number of screenshots to get */ 24 | count?: number, 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlastscreenshot', 28 | WFWorkflowActionParameters: { 29 | WFGetLatestPhotoCount: count, 30 | }, 31 | }); 32 | 33 | export default withActionOutput(getLatestScreenshots); 34 | -------------------------------------------------------------------------------- /src/actions/getLatestLivePhotos.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Get Latest Live Photos 7 | * @section Content Types > Photos & Video > Photos 8 | * @icon LivePhotos 9 | * 10 | * Gets the most recent Live Photos from the camera roll. 11 | * 12 | * ```js 13 | * getLatestLivePhotos({ 14 | * count: 1, 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const getLatestLivePhotos = ( 20 | { 21 | count = 1, 22 | }: { 23 | /** The number of live photos to get */ 24 | count?: number, 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlatestlivephotos', 28 | WFWorkflowActionParameters: { 29 | WFGetLatestPhotoCount: count, 30 | }, 31 | }); 32 | 33 | export default withActionOutput(getLatestLivePhotos); 34 | -------------------------------------------------------------------------------- /src/actions/list.ts: -------------------------------------------------------------------------------- 1 | import { 2 | withActionOutput, 3 | } from '../utils'; 4 | 5 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 6 | 7 | /** 8 | * @action List 9 | * @section Actions > Scripting > Lists 10 | * @icon Scripting 11 | * 12 | * Allows you to specify a list of items to be passed to the next action. 13 | * 14 | * ```js 15 | * // Create a list 16 | * list({ 17 | * value: [ 18 | * 'a', 19 | * 'b', 20 | * 'c', 21 | * '123', 22 | * ], 23 | * }); 24 | * ``` 25 | */ 26 | 27 | const list = ( 28 | { 29 | value = [], 30 | }: { 31 | /** The list array */ 32 | value?: string[], 33 | }, 34 | ): WFWorkflowAction => ({ 35 | WFWorkflowActionIdentifier: 'is.workflow.actions.list', 36 | WFWorkflowActionParameters: { 37 | WFItems: [...value], 38 | }, 39 | }); 40 | 41 | export default withActionOutput(list); 42 | -------------------------------------------------------------------------------- /src/utils/withActionOutput.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** @ignore */ 5 | export const withActionOutput = ( 6 | actionBuilder: (options: OptionsType) => WFWorkflowAction | WFWorkflowAction[], 7 | ) => ( 8 | ( 9 | options: OptionsType, 10 | output?: Variable, 11 | ): WFWorkflowAction | WFWorkflowAction[] => { 12 | const action = actionBuilder(options); 13 | 14 | if (output) { 15 | const actionToModify = Array.isArray(action) ? action[action.length - 1] : action; 16 | 17 | actionToModify.WFWorkflowActionParameters.UUID = output.Value.OutputUUID; 18 | if (output.Value.OutputName) { 19 | actionToModify.WFWorkflowActionParameters.CustomOutputName = output.Value.OutputName; 20 | } 21 | } 22 | return action; 23 | } 24 | ); 25 | -------------------------------------------------------------------------------- /src/actions/count.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFCountType from '../interfaces/WF/WFCountType'; 4 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 5 | 6 | /** 7 | * @action Count 8 | * @section Actions > Scripting > Content 9 | * @icon Calculator 10 | * 11 | * Counts the number of items, characters, words, sentences, or lines passed as input. 12 | * 13 | * ```js 14 | * count({ 15 | * // Count the number of lines in the input 16 | * type: 'Lines', 17 | * }); 18 | * ``` 19 | */ 20 | 21 | const count = ( 22 | { 23 | type = 'Items', 24 | }: { 25 | /** The thing to count */ 26 | type?: WFCountType; 27 | }, 28 | ): WFWorkflowAction => ({ 29 | WFWorkflowActionIdentifier: 'is.workflow.actions.count', 30 | WFWorkflowActionParameters: { 31 | WFCountType: type, 32 | }, 33 | }); 34 | 35 | export default withActionOutput(count); 36 | -------------------------------------------------------------------------------- /src/actions/skipBack.ts: -------------------------------------------------------------------------------- 1 | import WFSkipBackBehavior from '../interfaces/WF/WFSkipBackBehavior'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Skip Back 6 | * @section Content Types > Music > Playback 7 | * @icon Rewind 8 | * 9 | * Skips to the previous song in the current music queue. 10 | * 11 | * ```js 12 | * skipBack({ 13 | * skipBackBehavior: 'Beginning', 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const skipBack = ( 19 | { 20 | skipBackBehavior = 'Beginning', 21 | }: { 22 | /** The skip back behavior option to get (Beginning or Previous Song) */ 23 | skipBackBehavior ?: WFSkipBackBehavior, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'is.workflow.actions.skipback', 27 | WFWorkflowActionParameters: { 28 | WFSkipBackBehavior: skipBackBehavior, 29 | }, 30 | }); 31 | 32 | export default skipBack; 33 | -------------------------------------------------------------------------------- /src/actions/pythonista/runScript.ts: -------------------------------------------------------------------------------- 1 | import WFSerialization from '../../interfaces/WF/WFSerialization'; 2 | import WFWorkflowAction from '../../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Run Script 6 | * @section Actions > Scripting > Pythonista 7 | * @icon Pythonista 8 | * 9 | * Runs the specified script in Pythonista and waits to continue the shortcut until you return to the Shortcuts app. 10 | * 11 | * ```js 12 | * runScript({ 13 | * script: 'MyScript.py', 14 | * }); 15 | * ``` 16 | */ 17 | 18 | const runScript = ( 19 | { 20 | script = '', 21 | }: { 22 | /** The name of the script to run */ 23 | script?: WFSerialization | string, 24 | }, 25 | ): WFWorkflowAction => ({ 26 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.runscript', 27 | WFWorkflowActionParameters: { 28 | PythonistaScript: script, 29 | }, 30 | }); 31 | 32 | export default runScript; 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request-new-actions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Request new actions 3 | about: Suggest an app's actions to be added to the library 4 | labels: 5 | 6 | --- 7 | 8 | - [ ] These actions aren't already listed in the 'All Actions to be implemented' issue [here](https://github.com/joshfarrant/shortcuts-js/issues/6). 9 | - [ ] These actions haven't already been requested in another issue. 10 | - [ ] Fill out the information below, deleting the examples in italics. 11 | 12 | **What is the name of the app these actions are a part of?** 13 | _Bear_ 14 | 15 | **Is this a free or paid app?** 16 | _Free_ 17 | 18 | **Please list all of the actions this app exposes.** 19 | - _Search in Bear_ 20 | - _Create Bear Note_ 21 | - _...etc_ 22 | 23 | **Provide a link to download a .shortcut file containing as many of these actions as possible.** 24 | _[iCloud](https://www.icloud.com/shortcuts/94bde3696d104b5db47ee192d3ea8b02)_ 25 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Screenshot/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styles from './styles.module.scss'; 5 | 6 | const classList = (classNames) => Object 7 | .entries(classNames) 8 | .map(([className, condition]) => condition && className) 9 | .filter(el => el) 10 | .join(' '); 11 | 12 | const Component = ({ align, alt, src, ...props }) => ( 13 |
17 | {alt} 22 |
23 | ); 24 | 25 | Component.propTypes = { 26 | align: PropTypes.oneOf(['', 'top', 'bottom']), 27 | alt: PropTypes.string, 28 | src: PropTypes.string.isRequired, 29 | }; 30 | 31 | Component.defaultProps = { 32 | align: '', 33 | alt: 'Screenshot', 34 | }; 35 | 36 | export default Component; 37 | -------------------------------------------------------------------------------- /__tests__/meta/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ICON, 3 | } from '../../src/meta'; 4 | 5 | import { 6 | COLORS as COLORS_DIRECT, 7 | } from '../../src/meta/colors'; 8 | import { 9 | GLYPHS as GLYPHS_DIRECT, 10 | } from '../../src/meta/glyphs'; 11 | 12 | describe('meta index.ts file', () => { 13 | 14 | it('exports an ICON object', () => { 15 | 16 | const isObject = !Array.isArray(ICON) && Object(ICON) === ICON; 17 | 18 | expect(isObject).toBeTruthy(); 19 | }); 20 | 21 | it('exports ICON.COLORS as an object', () => { 22 | 23 | const actual = ICON.COLORS.toString(); 24 | const expected = COLORS_DIRECT.toString(); 25 | 26 | expect(actual).toEqual(expected); 27 | }); 28 | 29 | it('exports ICON.GLYPHS as an object', () => { 30 | 31 | const actual = ICON.GLYPHS.toString(); 32 | const expected = GLYPHS_DIRECT.toString(); 33 | 34 | expect(actual).toEqual(expected); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /src/actions/generateHash.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFHashType from '../interfaces/WF/WFHashType'; 4 | import WFSerialization from '../interfaces/WF/WFSerialization'; 5 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 6 | 7 | /** 8 | * @action Generate Hash 9 | * @section Actions > Scripting > Files 10 | * @icon Scripting 11 | * 12 | * Generates a MD5/SHA1 hash from the input. 13 | * 14 | * ```js 15 | * generateHash({ 16 | * type: 'MD5', 17 | * }); 18 | * ``` 19 | */ 20 | 21 | const generateHash = ( 22 | { 23 | type = 'MD5', 24 | }: { 25 | /** The type of hash to use */ 26 | type?: WFSerialization | WFHashType, 27 | }, 28 | ): WFWorkflowAction => ({ 29 | WFWorkflowActionIdentifier: 'is.workflow.actions.hash', 30 | WFWorkflowActionParameters: { 31 | WFHashType: type, 32 | }, 33 | }); 34 | 35 | export default withActionOutput(generateHash); 36 | -------------------------------------------------------------------------------- /src/actions/showInMaps.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFMapsApps from '../interfaces/WF/WFMapsApps'; 4 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 5 | 6 | /** 7 | * @action Show in Maps 8 | * @section Content Types > Location > Maps 9 | * @icon Maps 10 | * 11 | * Opens your choice of Maps, Google Maps, or Waze and searches for the location, place, or text that was passed into the action. 12 | * 13 | * ```js 14 | * showInMaps({ 15 | * app: 'Google Maps', 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const showInMaps = ( 21 | { 22 | app = 'Maps', 23 | }: { 24 | /** The maps app to use */ 25 | app?: WFMapsApps, 26 | }, 27 | ): WFWorkflowAction => ({ 28 | WFWorkflowActionIdentifier: 'is.workflow.actions.searchmaps', 29 | WFWorkflowActionParameters: { 30 | WFSearchMapsActionApp: app, 31 | }, 32 | }); 33 | 34 | export default withActionOutput(showInMaps); 35 | -------------------------------------------------------------------------------- /src/interfaces/WF/AggrandizementCoercionItemClass.ts: -------------------------------------------------------------------------------- 1 | type AggrandizementCoercionItemClass = ( 2 | 'WFEmailAddressContentItem' 3 | | 'WFAppStoreAppContentItem' 4 | | 'WFArticleContentItem' 5 | | 'WFAVAssetContentItem' 6 | | 'WFBooleanContentItem' 7 | | 'WFContactContentItem' 8 | | 'WFContentItem' 9 | | 'WFDateContentItem' 10 | | 'WFDCMapsLinkContentItem' 11 | | 'WFDictionaryContentItem' 12 | | 'WFGenericFileContentItem' 13 | | 'WFImageContentItem' 14 | | 'WFiTunesProductContentItem' 15 | | 'WFLocationContentItem' 16 | | 'WFMKMapItemContentItem' 17 | | 'WFMPMediaContentItem' 18 | | 'WFNumberContentItem' 19 | | 'WFPDFContentItem' 20 | | 'WFPhoneNumberContentItem' 21 | | 'WFPhotoMediaContentItem' 22 | | 'WFRichTextContentItem' 23 | | 'WFSafariWebPageContentItem' 24 | | 'WFStringContentItem' 25 | | 'WFURLContentItem' 26 | | 'WFVCardContentItem' 27 | ); 28 | 29 | export default AggrandizementCoercionItemClass; 30 | -------------------------------------------------------------------------------- /__tests__/actions/URL.spec.ts: -------------------------------------------------------------------------------- 1 | import { URL } from '../../src/actions'; 2 | 3 | describe('URL function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof URL).toBe('function'); 7 | }); 8 | 9 | it('builds a URL action when no URL is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.url', 12 | WFWorkflowActionParameters: { 13 | WFURLActionURL: '', 14 | }, 15 | }; 16 | const actual = URL({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a URL action with given URL', () => { 22 | const testUrl = ''; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.url', 25 | WFWorkflowActionParameters: { 26 | WFURLActionURL: testUrl, 27 | }, 28 | }; 29 | const actual = URL({ url: testUrl }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/wait.spec.ts: -------------------------------------------------------------------------------- 1 | import { wait } from '../../src/actions'; 2 | 3 | describe('wait function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof wait).toBe('function'); 7 | }); 8 | 9 | it('builds a wait action when no time is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.delay', 12 | WFWorkflowActionParameters: { 13 | WFDelayTime: 1, 14 | }, 15 | }; 16 | const actual = wait({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a wait action when a time is passed', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'is.workflow.actions.delay', 24 | WFWorkflowActionParameters: { 25 | WFDelayTime: 200, 26 | }, 27 | }; 28 | const actual = wait({ 29 | time: 200, 30 | }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /src/actions/runShortcut.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Run Shortcut 7 | * @section Actions > Scripting > Shortcuts 8 | * @icon Shortcuts 9 | * 10 | * Run a shortcut from your shortcut. 11 | * 12 | * ```js 13 | * runShortcut({ 14 | * name: 'My Great Shortcut', 15 | * show: true, 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const runShortcut = ( 21 | { 22 | name, 23 | show = false, 24 | }: { 25 | /** The name of the shortcut to run */ 26 | name: string, 27 | /** Whether to show the shortcut while it runs */ 28 | show?: boolean, 29 | }, 30 | ): WFWorkflowAction => ({ 31 | WFWorkflowActionIdentifier: 'is.workflow.actions.runworkflow', 32 | WFWorkflowActionParameters: { 33 | WFWorkflowName: name, 34 | WFShowWorkflow: show, 35 | }, 36 | }); 37 | 38 | export default withActionOutput(runShortcut); 39 | -------------------------------------------------------------------------------- /src/actions/facetime.ts: -------------------------------------------------------------------------------- 1 | import FaceTimeType from '../interfaces/WF/FaceTimeType'; 2 | import WFSerialization from '../interfaces/WF/WFSerialization'; 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action FaceTime 7 | * @section Content Types > Contacts > Phone 8 | * @icon FaceTime 9 | * 10 | * Facetime the contact, the text, place or phone number given as input. 11 | * 12 | * ```js 13 | * facetime({}); // Default type is Video 14 | * facetime({ type: askWhenRun }); // type could be 'Audio' or 'Video' 15 | * ``` 16 | */ 17 | 18 | const facetime = ({ 19 | type = 'Video', 20 | }: { 21 | /** Define the type to use for the FaceTime. Default to 'Video' */ 22 | type?: WFSerialization | FaceTimeType, 23 | }): WFWorkflowAction => ({ 24 | WFWorkflowActionIdentifier: 'com.apple.facetime.facetime', 25 | WFWorkflowActionParameters: { 26 | WFFaceTimeType: type, 27 | }, 28 | }); 29 | 30 | export default facetime; 31 | -------------------------------------------------------------------------------- /src/actions/URLEncode.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFEncodeMode from '../interfaces/WF/WFEncodeMode'; 4 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 5 | 6 | /** 7 | * @action URL Encode 8 | * @section Actions > Scripting > X-Callback 9 | * @icon URL 10 | * 11 | * Encodes or decodes text passed into the action to be suitable for inclusion in a URL by adding or removing percent escapes when appropriate. 12 | * 13 | * ```js 14 | * URLEncode({ 15 | * encodeMode: 'Encode', 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const URLEncode = ( 21 | { 22 | encodeMode = 'Encode', 23 | }: { 24 | /** The encoding mode to use */ 25 | encodeMode?: WFEncodeMode, 26 | }, 27 | ): WFWorkflowAction => ({ 28 | WFWorkflowActionIdentifier: 'is.workflow.actions.urlencode', 29 | WFWorkflowActionParameters: { 30 | WFEncodeMode: encodeMode, 31 | }, 32 | }); 33 | 34 | export default withActionOutput(URLEncode); 35 | -------------------------------------------------------------------------------- /__tests__/actions/setWiFi.spec.ts: -------------------------------------------------------------------------------- 1 | import { setWiFi } from '../../src/actions'; 2 | 3 | describe('setWiFi function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setWiFi).toBe('function'); 7 | }); 8 | 9 | it('builds a setWiFi action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.wifi.set', 12 | WFWorkflowActionParameters: { 13 | OnValue: true, 14 | }, 15 | }; 16 | const actual = setWiFi({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setWiFi action with given value', () => { 22 | const value = false; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.wifi.set', 25 | WFWorkflowActionParameters: { 26 | OnValue: value, 27 | }, 28 | }; 29 | const actual = setWiFi({ value }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /src/actions/setDictionaryValue.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Set Dictionary Value 7 | * @section Actions > Scripting > Dictionaries 8 | * @icon Scripting 9 | * 10 | * Sets a value in the dictionary passed into the action. 11 | * 12 | * ```js 13 | * setDictionaryValue({ 14 | * key: 'testKey', 15 | * value: 'testValue', 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const setDictionaryValue = ( 21 | { 22 | key = '', 23 | value = '', 24 | }: { 25 | /** The key to set */ 26 | key?: string, 27 | /** The value to set */ 28 | value?: string, 29 | }, 30 | ): WFWorkflowAction => ({ 31 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvalueforkey', 32 | WFWorkflowActionParameters: { 33 | WFDictionaryKey: key, 34 | WFDictionaryValue: value, 35 | }, 36 | }); 37 | 38 | export default withActionOutput(setDictionaryValue); 39 | -------------------------------------------------------------------------------- /__tests__/actions/count.spec.ts: -------------------------------------------------------------------------------- 1 | import { count } from '../../src/actions'; 2 | 3 | describe('count function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof count).toBe('function'); 7 | }); 8 | 9 | it('builds a count action when no type is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.count', 12 | WFWorkflowActionParameters: { 13 | WFCountType: 'Items', 14 | }, 15 | }; 16 | const actual = count({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a count action when name and show are passed', () => { 22 | const type = 'Sentences'; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.count', 25 | WFWorkflowActionParameters: { 26 | WFCountType: type, 27 | }, 28 | }; 29 | const actual = count({ type }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /src/actions/changeCase.ts: -------------------------------------------------------------------------------- 1 | import WFCaseType from '../interfaces/WF/WFCaseType'; 2 | import WFSerialization from '../interfaces/WF/WFSerialization'; 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Change Case 7 | * @section Content Types > Text > Change Case 8 | * @icon Text 9 | * 10 | * Changes the case of the text passed into the action to UPPERCASE, lowercase or Title Case. 11 | * 12 | * ```js 13 | * changeCase({}); 14 | * ``` 15 | */ 16 | 17 | const changeCase = ( 18 | { 19 | caseType, 20 | }: { 21 | /** The particular casing format. */ 22 | caseType?: WFCaseType | WFSerialization; 23 | }, 24 | ): WFWorkflowAction => { 25 | const parameters = caseType ? 26 | { 27 | WFCaseType: caseType, 28 | } : {}; 29 | 30 | return { 31 | WFWorkflowActionIdentifier: 'is.workflow.actions.text.changecase', 32 | WFWorkflowActionParameters: parameters, 33 | }; 34 | }; 35 | 36 | export default changeCase; 37 | -------------------------------------------------------------------------------- /__tests__/utils/flatten.spec.ts: -------------------------------------------------------------------------------- 1 | import { flatten } from '../../src/utils'; 2 | 3 | describe('flatten function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof flatten).toBe('function'); 7 | }); 8 | 9 | it('doesn\'t modify a 1 level deep array', () => { 10 | const input = [1, 2, 3, 4, 5]; 11 | const expected = input; 12 | const actual = flatten(input); 13 | 14 | expect(actual).toEqual(expected); 15 | }); 16 | 17 | it('flattens a 2 level deep array', () => { 18 | const input = [1, [2, 3], 4, [5, 6, 7], 8, 9]; 19 | const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 20 | const actual = flatten(input); 21 | 22 | expect(actual).toEqual(expected); 23 | }); 24 | 25 | it('flattens a 4 level deep array', () => { 26 | const input = [1, [2, [3, 4, [5, 6, 7], 8]], 9]; 27 | const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 28 | const actual = flatten(input); 29 | 30 | expect(actual).toEqual(expected); 31 | }); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /src/actions/addToVariable.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Add to Variable 6 | * @section Actions > Scripting > Variables 7 | * @icon Variable 8 | * 9 | * Appends this action's input to the specified variable, creating the variable if it does not exist. This allows you to make a variable hold multiple items. 10 | * 11 | * ```js 12 | * // Append the input to the variable named 'My Var' 13 | * addToVariable({ 14 | * variable: variable('My Var'), 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const addToVariable = ( 20 | { 21 | variable, 22 | }: { 23 | /** The variable to add to */ 24 | variable: Variable; 25 | }, 26 | ): WFWorkflowAction => ({ 27 | WFWorkflowActionIdentifier: 'is.workflow.actions.appendvariable', 28 | WFWorkflowActionParameters: { 29 | WFVariableName: variable.Value.VariableName, 30 | }, 31 | }); 32 | 33 | export default addToVariable; 34 | -------------------------------------------------------------------------------- /src/interfaces/WF/WFSerialization.ts: -------------------------------------------------------------------------------- 1 | import Aggrandizement from './Aggrandizement'; 2 | import Attachment from './Attachment'; 3 | import Type from './Type'; 4 | import WFDictionaryFieldValueItem from './WFDictionaryFieldValueItem'; 5 | import WFSerializationType from './WFSerializationType'; 6 | 7 | interface SerializationValue { 8 | Aggrandizements?: Aggrandizement[]; 9 | attachmentsByRange?: { 10 | [key: string]: Attachment; 11 | }; 12 | OutputUUID?: string; 13 | OutputName?: string; 14 | string?: string; 15 | Type?: Type; 16 | Value?: WFSerialization | boolean; 17 | VariableName?: string; 18 | WFDictionaryFieldValueItems?: WFDictionaryFieldValueItem[]; 19 | } 20 | 21 | interface WFSerialization { 22 | Value: ( 23 | SerializationValue 24 | | WFSerialization 25 | | WFDictionaryFieldValueItem[] 26 | | string 27 | | number 28 | | boolean 29 | ); 30 | WFSerializationType: WFSerializationType; 31 | } 32 | 33 | export default WFSerialization; 34 | -------------------------------------------------------------------------------- /__tests__/actions/URLEncode.spec.ts: -------------------------------------------------------------------------------- 1 | import { URLEncode } from '../../src/actions'; 2 | 3 | describe('URLEncode function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof URLEncode).toBe('function'); 7 | }); 8 | 9 | it('builds a URLEncode action (encode)', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.urlencode', 12 | WFWorkflowActionParameters: { 13 | WFEncodeMode: 'Encode', 14 | }, 15 | }; 16 | const actual = URLEncode({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a URLEncode action (decode)', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'is.workflow.actions.urlencode', 24 | WFWorkflowActionParameters: { 25 | WFEncodeMode: 'Decode', 26 | }, 27 | }; 28 | const actual = URLEncode({ 29 | encodeMode: 'Decode', 30 | }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/actions/comment.spec.ts: -------------------------------------------------------------------------------- 1 | import { comment } from '../../src/actions'; 2 | 3 | describe('comment function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof comment).toBe('function'); 7 | }); 8 | 9 | it('builds a comment action when no text is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.comment', 12 | WFWorkflowActionParameters: { 13 | WFCommentActionText: '', 14 | }, 15 | }; 16 | const actual = comment({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a comment action with given text', () => { 22 | const text = 'Hello, world!'; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.comment', 25 | WFWorkflowActionParameters: { 26 | WFCommentActionText: text, 27 | }, 28 | }; 29 | const actual = comment({ text }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/openApp.spec.ts: -------------------------------------------------------------------------------- 1 | import { openApp } from '../../src/actions'; 2 | 3 | describe('openApp function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof openApp).toBe('function'); 7 | }); 8 | 9 | it('builds an openApp action when no text is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.openapp', 12 | WFWorkflowActionParameters: { 13 | WFAppIdentifier: '', 14 | }, 15 | }; 16 | const actual = openApp({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds an openApp action with given appId', () => { 22 | const appId = 'Hello, world!'; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.openapp', 25 | WFWorkflowActionParameters: { 26 | WFAppIdentifier: appId, 27 | }, 28 | }; 29 | const actual = openApp({ appId }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/number.spec.ts: -------------------------------------------------------------------------------- 1 | import { number } from '../../src/actions'; 2 | 3 | describe('number function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof number).toBe('function'); 7 | }); 8 | 9 | it('builds a number action when no text is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.number', 12 | WFWorkflowActionParameters: { 13 | WFNumberActionNumber: 0, 14 | }, 15 | }; 16 | const actual = number({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a number action with given text', () => { 22 | const testNumber = 42; 23 | 24 | const expected = { 25 | WFWorkflowActionIdentifier: 'is.workflow.actions.number', 26 | WFWorkflowActionParameters: { 27 | WFNumberActionNumber: testNumber, 28 | }, 29 | }; 30 | const actual = number({ number: testNumber }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/actions/list.spec.ts: -------------------------------------------------------------------------------- 1 | import { list } from '../../src/actions'; 2 | 3 | describe('list function', () => { 4 | it('is a function', () => { 5 | expect(typeof list).toBe('function'); 6 | }); 7 | 8 | it('builds a list action', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.list', 11 | WFWorkflowActionParameters: { 12 | WFItems: [], 13 | }, 14 | }; 15 | const actual = list({}); 16 | 17 | expect(actual).toEqual(expected); 18 | }); 19 | 20 | it('builds a list action when passed a value', () => { 21 | const value = [ 22 | 'a', 23 | 'b', 24 | 'c', 25 | '123', 26 | ]; 27 | 28 | const expected = { 29 | WFWorkflowActionIdentifier: 'is.workflow.actions.list', 30 | WFWorkflowActionParameters: { 31 | WFItems: [...value], 32 | }, 33 | }; 34 | const actual = list({ 35 | value, 36 | }); 37 | 38 | expect(actual).toEqual(expected); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /src/actions/getDeviceDetails.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFDeviceDetail from '../interfaces/WF/WFDeviceDetail'; 4 | import WFSerialization from '../interfaces/WF/WFSerialization'; 5 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 6 | 7 | /** 8 | * @action Get Device Details 9 | * @section Actions > Scripting > Device 10 | * @icon Scripting 11 | * 12 | * Gets information about the current device. 13 | * 14 | * ```js 15 | * getDeviceDetails({ 16 | * detail: 'Device Name', 17 | * }); 18 | * ``` 19 | */ 20 | 21 | const getDeviceDetails = ( 22 | { 23 | detail = 'Device Name', 24 | }: { 25 | /** The particular detail to retrieve */ 26 | detail?: WFSerialization | WFDeviceDetail, 27 | }, 28 | ): WFWorkflowAction => ({ 29 | WFWorkflowActionIdentifier: 'is.workflow.actions.getdevicedetails', 30 | WFWorkflowActionParameters: { 31 | WFDeviceDetail: detail, 32 | }, 33 | }); 34 | 35 | export default withActionOutput(getDeviceDetails); 36 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Variables/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Raw from 'raw.macro'; 3 | 4 | import Markdown from '../Markdown'; 5 | import Screenshot from '../Screenshot'; 6 | 7 | import styles from './styles.module.scss'; 8 | 9 | import screenshot00 from './screenshot00.png'; 10 | import screenshot01 from './screenshot01.png'; 11 | import screenshot02 from './screenshot02.png'; 12 | 13 | const content = Raw('./content.md'); 14 | 15 | export default () => ( 16 |
17 | 21 |
22 | 23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 | 31 | 32 |
33 | 34 |
35 | 36 |
37 | ); 38 | -------------------------------------------------------------------------------- /__tests__/actions/setBluetooth.spec.ts: -------------------------------------------------------------------------------- 1 | import { setBluetooth } from '../../src/actions'; 2 | 3 | describe('setBluetooth function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setBluetooth).toBe('function'); 7 | }); 8 | 9 | it('builds a setBluetooth action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.bluetooth.set', 12 | WFWorkflowActionParameters: { 13 | OnValue: true, 14 | }, 15 | }; 16 | const actual = setBluetooth({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setBluetooth action with given value', () => { 22 | const value = false; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.bluetooth.set', 25 | WFWorkflowActionParameters: { 26 | OnValue: value, 27 | }, 28 | }; 29 | const actual = setBluetooth({ value }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/setTorch.spec.ts: -------------------------------------------------------------------------------- 1 | import { setTorch } from '../../src/actions'; 2 | 3 | describe('setTorch function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setTorch).toBe('function'); 7 | }); 8 | 9 | it('builds a setTorch action when no setting is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.flashlight', 12 | WFWorkflowActionParameters: { 13 | WFFlashlightSetting: 'On', 14 | }, 15 | }; 16 | const actual = setTorch({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setTorch action when setting is passed', () => { 22 | const setting = 'Toggle'; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.flashlight', 25 | WFWorkflowActionParameters: { 26 | WFFlashlightSetting: setting, 27 | }, 28 | }; 29 | const actual = setTorch({ setting }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /src/actions/setName.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 4 | 5 | /** 6 | * @action Set Name 7 | * @section Actions > Scripting > Content 8 | * @icon Scripting 9 | * 10 | * Sets the name of the item passed as input. 11 | * 12 | * ```js 13 | * setName({ 14 | * name: 'Test', 15 | * dontIncludeFileExtension: true, 16 | * }); 17 | * ``` 18 | */ 19 | 20 | const setName = ( 21 | { 22 | name, 23 | dontIncludeFileExtension = false, 24 | }: { 25 | /** The name to set */ 26 | name: string, 27 | /** Whether to include file extension */ 28 | dontIncludeFileExtension?: boolean, 29 | }, 30 | ): WFWorkflowAction => ({ 31 | WFWorkflowActionIdentifier: 'is.workflow.actions.setitemname', 32 | WFWorkflowActionParameters: { 33 | WFName: name, 34 | WFDontIncludeFileExtension: dontIncludeFileExtension, 35 | Advanced: dontIncludeFileExtension, 36 | }, 37 | }); 38 | 39 | export default withActionOutput(setName); 40 | -------------------------------------------------------------------------------- /__tests__/actions/pythonista/runScript.spec.ts: -------------------------------------------------------------------------------- 1 | import { runScript } from '../../../src/actions/pythonista'; 2 | 3 | describe('runScript function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof runScript).toBe('function'); 7 | }); 8 | 9 | it('builds a runScript action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.runscript', 12 | WFWorkflowActionParameters: { 13 | PythonistaScript: '', 14 | }, 15 | }; 16 | const actual = runScript({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a runScript action with a script name', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.runscript', 24 | WFWorkflowActionParameters: { 25 | PythonistaScript: 'test.py', 26 | }, 27 | }; 28 | const actual = runScript({ 29 | script: 'test.py', 30 | }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/actions/runScriptOverSSH.spec.ts: -------------------------------------------------------------------------------- 1 | import { runScriptOverSSH } from '../../src/actions'; 2 | 3 | describe('runScriptOverSSH function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof runScriptOverSSH).toBe('function'); 7 | }); 8 | 9 | it('builds a runScriptOverSSH action when options are passed', () => { 10 | const host = '192.168.1.1'; 11 | const password = 'root'; 12 | const port = '22'; 13 | const script = 'uptime'; 14 | const user = 'root'; 15 | 16 | const expected = { 17 | WFWorkflowActionIdentifier: 'is.workflow.actions.runsshscript', 18 | WFWorkflowActionParameters: { 19 | WFSSHHost: host, 20 | WFSSHPassword: password, 21 | WFSSHPort: port, 22 | WFSSHScript: script, 23 | WFSSHUser: user, 24 | }, 25 | }; 26 | const actual = runScriptOverSSH({ 27 | host, 28 | password, 29 | port, 30 | script, 31 | user, 32 | }); 33 | 34 | expect(actual).toEqual(expected); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /docs/src/components/Docs/Contributing/ActionIcons/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Raw from 'raw.macro'; 3 | 4 | import Markdown from '../../Markdown'; 5 | 6 | import { Icon } from '../../Actions'; 7 | import icons from '../../Actions/icons.js'; 8 | 9 | import styles from './styles.module.scss'; 10 | 11 | const content = Raw('./content.md'); 12 | 13 | export default () => ( 14 |
15 | 19 | 20 |
21 | {icons 22 | .concat(['Calendar']) 23 | .sort((a,b) => a.localeCompare(b)) 24 | .map((icon) => ( 25 |
29 | 33 | {icon} 34 |
35 | ) 36 | )} 37 |
38 |
39 | ); 40 | -------------------------------------------------------------------------------- /src/interfaces/WF/Aggrandizement.ts: -------------------------------------------------------------------------------- 1 | import AggrandizementCoercionItemClass from './AggrandizementCoercionItemClass'; 2 | import AggrandizementPropertyName from './AggrandizementPropertyName'; 3 | import AggrandizementPropertyUserInfo from './AggrandizementPropertyUserInfo'; 4 | import AggrandizementType from './AggrandizementType'; 5 | import WFDateFormatStyle from './WFDateFormatStyle'; 6 | import WFRelativeDateFormatStyle from './WFRelativeDateFormatStyle'; 7 | import WFTimeFormatStyle from './WFTimeFormatStyle'; 8 | 9 | interface Aggrandizement { 10 | CoercionItemClass?: AggrandizementCoercionItemClass; 11 | DictionaryKey?: string; 12 | PropertyName?: AggrandizementPropertyName; 13 | PropertyUserInfo?: AggrandizementPropertyUserInfo; 14 | Type: AggrandizementType; 15 | WFDateFormat?: string; 16 | WFDateFormatStyle?: WFDateFormatStyle; 17 | WFTimeFormatStyle?: WFTimeFormatStyle; 18 | WFISO8601IncludeTime?: boolean; 19 | WFRelativeDateFormatStyle?: WFRelativeDateFormatStyle; 20 | } 21 | 22 | export default Aggrandizement; 23 | -------------------------------------------------------------------------------- /__tests__/actions/setBrightness.spec.ts: -------------------------------------------------------------------------------- 1 | import { setBrightness } from '../../src/actions'; 2 | 3 | describe('setBrightness function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setBrightness).toBe('function'); 7 | }); 8 | 9 | it('builds a set brightness action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.setbrightness', 12 | WFWorkflowActionParameters: { 13 | WFBrightness: 1, 14 | }, 15 | }; 16 | const actual = setBrightness({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a set brightness action when a value is passed', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'is.workflow.actions.setbrightness', 24 | WFWorkflowActionParameters: { 25 | WFBrightness: 0.5, 26 | }, 27 | }; 28 | const actual = setBrightness({ 29 | brightness: 50, 30 | }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/actions/pythonista/editScript.spec.ts: -------------------------------------------------------------------------------- 1 | import { editScript } from '../../../src/actions/pythonista'; 2 | 3 | describe('editScript function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof editScript).toBe('function'); 7 | }); 8 | 9 | it('builds an editScript action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.editscript', 12 | WFWorkflowActionParameters: { 13 | PythonistaScript: '', 14 | }, 15 | }; 16 | const actual = editScript({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds an editScript action with a script name', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'com.omz-software.Pythonista.editscript', 24 | WFWorkflowActionParameters: { 25 | PythonistaScript: 'test.py', 26 | }, 27 | }; 28 | const actual = editScript({ 29 | script: 'test.py', 30 | }); 31 | 32 | expect(actual).toEqual(expected); 33 | }); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /__tests__/actions/setVolume.spec.ts: -------------------------------------------------------------------------------- 1 | import { setVolume } from '../../src/actions'; 2 | 3 | describe('setVolume function', () => { 4 | it('is a function', () => { 5 | expect(typeof setVolume).toBe('function'); 6 | }); 7 | 8 | it('builds a setVolume action when no options are passed', () => { 9 | const expected = { 10 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvolume', 11 | WFWorkflowActionParameters: { 12 | WFVolume: 0.5, 13 | }, 14 | }; 15 | 16 | const actual = setVolume({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setVolume action when a volume options is specified', () => { 22 | const volumeLevel = 30; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.setvolume', 25 | WFWorkflowActionParameters: { 26 | WFVolume: 0.3, 27 | }, 28 | }; 29 | 30 | const actual = setVolume({ 31 | volume: volumeLevel, 32 | }); 33 | 34 | expect(actual).toEqual(expected); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /src/actions/getDictionaryValue.ts: -------------------------------------------------------------------------------- 1 | import WFGetDictionaryValueType from '../interfaces/WF/WFGetDictionaryValueType'; 2 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 3 | 4 | /** 5 | * @action Get Dictionary Value 6 | * @section Actions > Scripting > Dictionaries 7 | * @icon Scripting 8 | * 9 | * Gets the value for the specified key in the dictionary passed into the action. 10 | * 11 | * ```js 12 | * getDictionaryValue({ 13 | * get: 'Value', 14 | * key: 'My Key', 15 | * }); 16 | * ``` 17 | */ 18 | 19 | const getDictionaryValue = ( 20 | { 21 | key = '', 22 | get = 'Value', 23 | }: { 24 | /** The key of the dictionary to get */ 25 | key?: string, 26 | /** The thing to get */ 27 | get?: WFGetDictionaryValueType, 28 | }, 29 | ): WFWorkflowAction => ({ 30 | WFWorkflowActionIdentifier: 'is.workflow.actions.getvalueforkey', 31 | WFWorkflowActionParameters: { 32 | WFDictionaryKey: key, 33 | WFGetDictionaryValueType: get, 34 | }, 35 | }); 36 | 37 | export default getDictionaryValue; 38 | -------------------------------------------------------------------------------- /__tests__/actions/setAirplaneMode.spec.ts: -------------------------------------------------------------------------------- 1 | import { setAirplaneMode } from '../../src/actions'; 2 | 3 | describe('setAirplaneMode function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setAirplaneMode).toBe('function'); 7 | }); 8 | 9 | it('builds a setAirplaneMode action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.airplanemode.set', 12 | WFWorkflowActionParameters: { 13 | OnValue: true, 14 | }, 15 | }; 16 | const actual = setAirplaneMode({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setAirplaneMode action with given value', () => { 22 | const value = false; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.airplanemode.set', 25 | WFWorkflowActionParameters: { 26 | OnValue: value, 27 | }, 28 | }; 29 | const actual = setAirplaneMode({ value }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/setCellularData.spec.ts: -------------------------------------------------------------------------------- 1 | import { setCellularData } from '../../src/actions'; 2 | 3 | describe('setCellularData function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setCellularData).toBe('function'); 7 | }); 8 | 9 | it('builds a setCellularData action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.cellulardata.set', 12 | WFWorkflowActionParameters: { 13 | OnValue: true, 14 | }, 15 | }; 16 | const actual = setCellularData({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setCellularData action with given value', () => { 22 | const value = false; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.cellulardata.set', 25 | WFWorkflowActionParameters: { 26 | OnValue: value, 27 | }, 28 | }; 29 | const actual = setCellularData({ value }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /__tests__/actions/setLowPowerMode.spec.ts: -------------------------------------------------------------------------------- 1 | import { setLowPowerMode } from '../../src/actions'; 2 | 3 | describe('setLowPowerMode function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof setLowPowerMode).toBe('function'); 7 | }); 8 | 9 | it('builds a setLowPowerMode action when no value is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.lowpowermode.set', 12 | WFWorkflowActionParameters: { 13 | OnValue: true, 14 | }, 15 | }; 16 | const actual = setLowPowerMode({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a setLowPowerMode action with given value', () => { 22 | const value = true; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.lowpowermode.set', 25 | WFWorkflowActionParameters: { 26 | OnValue: value, 27 | }, 28 | }; 29 | const actual = setLowPowerMode({ value }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /src/utils/withVariables.ts: -------------------------------------------------------------------------------- 1 | import Variable from '../interfaces/Variable'; 2 | import WFSerialization from '../interfaces/WF/WFSerialization'; 3 | 4 | /** @ignore */ 5 | export const withVariables = ( 6 | strings: TemplateStringsArray, 7 | ...vars: Variable[] 8 | ): WFSerialization => ({ 9 | WFSerializationType: 'WFTextTokenString', 10 | Value: { 11 | string: strings.join('\ufffc'), // Join strings with object replacement character 12 | attachmentsByRange: strings.reduce( 13 | (a, _, i, s) => { 14 | // If we've got no vars for this string, skip 15 | if (!vars[i]) return a; 16 | 17 | // Calculate the length of the string so far, including the replacement character 18 | const lengthSoFar = s.reduce( 19 | (a2, c2, i2) => ( 20 | (i2 <= i) ? (a2 + c2.length + 1) : a2 21 | ), 22 | -1, 23 | ); 24 | 25 | return { 26 | ...a, 27 | [`{${lengthSoFar}, 1}`]: vars[i].Value, 28 | }; 29 | }, 30 | {}, 31 | ), 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /__tests__/actions/getLatestVideos.spec.ts: -------------------------------------------------------------------------------- 1 | import { getLatestVideos } from '../../src/actions'; 2 | 3 | describe('getLatestVideos function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getLatestVideos).toBe('function'); 7 | }); 8 | 9 | it('builds a getLatestVideos action when no count is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlastvideo', 12 | WFWorkflowActionParameters: { 13 | WFGetLatestPhotoCount: 1, 14 | }, 15 | }; 16 | const actual = getLatestVideos({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a getLatestVideos action with a given count', () => { 22 | const count = 2; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'is.workflow.actions.getlastvideo', 25 | WFWorkflowActionParameters: { 26 | WFGetLatestPhotoCount: 2, 27 | }, 28 | }; 29 | const actual = getLatestVideos({ count }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /src/actions/calculateStatistics.ts: -------------------------------------------------------------------------------- 1 | import { withActionOutput } from '../utils'; 2 | 3 | import WFSerialization from '../interfaces/WF/WFSerialization'; 4 | import WFStatisticsOperation from '../interfaces/WF/WFStatisticsOperation'; 5 | import WFWorkflowAction from '../interfaces/WF/WFWorkflowAction'; 6 | 7 | /** 8 | * @action Calculate Statistics 9 | * @section Actions > Scripting > Maths 10 | * @icon Calculator 11 | * 12 | * Calculates statistics on the numbers that are provided as input. 13 | * 14 | * ```js 15 | * calculateStatistics({ 16 | * operation: 'Average', 17 | * }); 18 | * ``` 19 | */ 20 | 21 | const calculateStatistics = ( 22 | { 23 | operation = 'Average', 24 | }: { 25 | /** The operation to perform */ 26 | operation?: WFSerialization | WFStatisticsOperation, 27 | }, 28 | ): WFWorkflowAction => ({ 29 | WFWorkflowActionIdentifier: 'is.workflow.actions.statistics', 30 | WFWorkflowActionParameters: { 31 | WFStatisticsOperation: operation, 32 | }, 33 | }); 34 | 35 | export default withActionOutput(calculateStatistics); 36 | -------------------------------------------------------------------------------- /__tests__/actions/getDeviceDetails.spec.ts: -------------------------------------------------------------------------------- 1 | import { getDeviceDetails } from '../../src/actions'; 2 | 3 | describe('getDeviceDetails function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof getDeviceDetails).toBe('function'); 7 | }); 8 | 9 | it('builds a getDeviceDetails action', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'is.workflow.actions.getdevicedetails', 12 | WFWorkflowActionParameters: { 13 | WFDeviceDetail: 'Device Name', 14 | }, 15 | }; 16 | const actual = getDeviceDetails({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a getDeviceDetails action when a detail is passed', () => { 22 | const expected = { 23 | WFWorkflowActionIdentifier: 'is.workflow.actions.getdevicedetails', 24 | WFWorkflowActionParameters: { 25 | WFDeviceDetail: 'System Version', 26 | }, 27 | }; 28 | const actual = getDeviceDetails({ detail: 'System Version' }); 29 | 30 | expect(actual).toEqual(expected); 31 | }); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /__tests__/actions/postOnInstagram.spec.ts: -------------------------------------------------------------------------------- 1 | import { postOnInstagram } from '../../src/actions'; 2 | 3 | describe('postOnInstagram function', () => { 4 | 5 | it('is a function', () => { 6 | expect(typeof postOnInstagram).toBe('function'); 7 | }); 8 | 9 | it('builds a postOnInstagram action when no caption is passed', () => { 10 | const expected = { 11 | WFWorkflowActionIdentifier: 'com.burbn.instagram.openin', 12 | WFWorkflowActionParameters: { 13 | InstagramCaption: '', 14 | }, 15 | }; 16 | const actual = postOnInstagram({}); 17 | 18 | expect(actual).toEqual(expected); 19 | }); 20 | 21 | it('builds a postOnInstagram action with given caption', () => { 22 | const caption = 'Hello, world!'; 23 | const expected = { 24 | WFWorkflowActionIdentifier: 'com.burbn.instagram.openin', 25 | WFWorkflowActionParameters: { 26 | InstagramCaption: caption, 27 | }, 28 | }; 29 | const actual = postOnInstagram({ caption }); 30 | 31 | expect(actual).toEqual(expected); 32 | }); 33 | 34 | }); 35 | --------------------------------------------------------------------------------