├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── cron.yml │ └── main.yml ├── LICENSE.md ├── README.md └── template ├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── README.md ├── assets └── icon.png ├── package.json ├── src ├── manifest.json ├── my-command.ts └── sketch.d.ts ├── tsconfig.json └── webpack.skpm.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/template" 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/cron.yml: -------------------------------------------------------------------------------- 1 | name: cron 2 | 3 | on: 4 | schedule: 5 | - cron: "0 2 * * *" 6 | 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | 13 | steps: 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 'lts' 17 | 18 | - run: mkdir -p "~/Library/Application Support/com.bohemiancoding.sketch3" 19 | - run: mkdir -p "~/Library/Application Support/com.bohemiancoding.sketch3/Plugins" 20 | - run: /usr/bin/defaults write ~/Library/Preferences/com.bohemiancoding.sketch3.plist AlwaysReloadScript -bool YES 21 | 22 | - run: yarn global add skpm 23 | - run: skpm create sketch-plugin-typescript --template=romansp/skpm-typescript 24 | - run: | 25 | cd sketch-plugin-typescript 26 | yarn install 27 | export NODE_ENV=production 28 | yarn lint 29 | yarn build 30 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: actions/setup-node@v3 20 | with: 21 | node-version: latest 22 | 23 | - name: Build 24 | working-directory: ./template 25 | run: | 26 | yarn install 27 | export NODE_ENV=production 28 | yarn lint 29 | yarn build 30 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Roman Pavlov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeScript skpm template 2 | 3 | [![CI](https://github.com/romansp/skpm-typescript/actions/workflows/main.yml/badge.svg)](https://github.com/romansp/skpm-typescript/actions/workflows/main.yml) 4 | 5 | ⚠️ Currently broken due to: https://github.com/skpm/skpm/issues/304 6 | 7 | ## Documentation 8 | 9 | - This is a template for [skpm](https://github.com/skpm/skpm) with [TypeScript](https://github.com/Microsoft/TypeScript) and [ESLint](https://github.com/eslint/eslint) support. 10 | - [For skpm](https://github.com/skpm/skpm): General information about how to work with skpm, not specific to this template 11 | - [For Sketch plugin](http://developer.sketchapp.com): General information about sketch plugin developement 12 | 13 | ## Usage 14 | 15 | ``` bash 16 | $ npm install -g skpm 17 | $ skpm create my-plugin --template=romansp/skpm-typescript 18 | $ cd my-plugin 19 | $ npm run watch 20 | ``` 21 | -------------------------------------------------------------------------------- /template/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | insert_final_newline = true -------------------------------------------------------------------------------- /template/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@typescript-eslint/eslint-recommended" 4 | ], 5 | "parser": "@typescript-eslint/parser", 6 | "parserOptions": { 7 | "project": "./tsconfig.json" 8 | }, 9 | "plugins": [ 10 | "@typescript-eslint" 11 | ], 12 | "rules": { 13 | "eqeqeq": 0, 14 | "interface-name-prefix": 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | # build artifacts 2 | *.sketchplugin 3 | 4 | # npm 5 | node_modules 6 | .npm 7 | npm-debug.log 8 | 9 | # mac 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # {{ name }} 2 | 3 | _This plugin was created using `skpm`. For a detailed explanation on how things work, checkout the [skpm Readme](https://github.com/skpm/skpm/blob/master/README.md)._ 4 | 5 | ## CLI Commands 6 | 7 | ``` bash 8 | # build with hot reload 9 | npm run watch 10 | 11 | # build for production 12 | npm run build 13 | ``` 14 | 15 | ## Custom Configuration 16 | 17 | ### Babel 18 | 19 | To customize Babel, you have two options: 20 | 21 | * You may create a [`.babelrc`](https://babeljs.io/docs/usage/babelrc) file in your project's root directory. Any settings you define here will overwrite matching config-keys within skpm preset. For example, if you pass a "presets" object, it will replace & reset all Babel presets that skpm defaults to. 22 | 23 | * If you'd like to modify or add to the existing Babel config, you must use a `webpack.skpm.config.js` file. Visit the [Webpack](#webpack) section for more info. 24 | 25 | ### Webpack 26 | 27 | To customize webpack create `webpack.skpm.config.js` file which exports function that will change webpack's config. 28 | 29 | ```js 30 | /** 31 | * Function that mutates original webpack config. 32 | * Supports asynchronous changes when promise is returned. 33 | * 34 | * @param {object} config - original webpack config. 35 | * @param {boolean} isPluginCommand - wether the config is for a plugin command or a resource 36 | **/ 37 | module.exports = function (config, isPluginCommand) { 38 | /** you can change config here **/ 39 | } 40 | ``` 41 | 42 | ## Debugging 43 | 44 | To view the output of your `console.log`, you have a few different options: 45 | * Open `Console.app` and look for the sketch logs 46 | * Use Safari's web inspector to debug your plugin's javascript context 47 | * Look at the `~/Library/Logs/com.bohemiancoding.sketch3/Plugin Output.log` file 48 | 49 | Skpm provides a convenient way to do the latter: 50 | 51 | ```bash 52 | skpm log 53 | ``` 54 | 55 | The `-f` option causes `skpm log` to not stop when the end of logs is reached, but rather to wait for additional data to be appended to the input 56 | 57 | -------------------------------------------------------------------------------- /template/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/romansp/skpm-typescript/73892438d11ceb62fab25bacc85d3b369cebecac/template/assets/icon.png -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foobar", 3 | "version": "0.1.0", 4 | "engines": { 5 | "sketch": ">=3.0" 6 | }, 7 | "skpm": { 8 | "name": "foobar", 9 | "manifest": "src/manifest.json", 10 | "main": "plugin.sketchplugin", 11 | "assets": [ 12 | "assets/**/*" 13 | ] 14 | }, 15 | "scripts": { 16 | "build": "skpm-build", 17 | "watch": "skpm-build --watch", 18 | "start": "skpm-build --watch --run", 19 | "lint": "eslint .", 20 | "postinstall": "npm run build && skpm-link" 21 | }, 22 | "devDependencies": { 23 | "@skpm/builder": "<1", 24 | "@typescript-eslint/eslint-plugin": "^5.2.0", 25 | "@typescript-eslint/parser": "^5.2.0", 26 | "eslint": "^8.1.0", 27 | "terser-webpack-plugin": "^4.2.3", 28 | "ts-loader": "^8.0.0", 29 | "typescript": "^5.0.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /template/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "compatibleVersion": 3, 3 | "bundleVersion": 1, 4 | "commands": [ 5 | { 6 | "name": "my-command", 7 | "identifier": "my-command-identifier", 8 | "script": "./my-command.ts" 9 | } 10 | ], 11 | "menu": { 12 | "title": "foobar", 13 | "items": ["my-command-identifier"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /template/src/my-command.ts: -------------------------------------------------------------------------------- 1 | export default function(context: Sketch.Context) { 2 | context.document.showMessage("It's alive 🙌"); 3 | } 4 | -------------------------------------------------------------------------------- /template/src/sketch.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace Sketch { 2 | interface Context { 3 | document: MSDocument; 4 | } 5 | 6 | interface MSDocument { 7 | showMessage(message: string): void; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src", "**/*.ts", "**/*.js" 4 | ], 5 | "compilerOptions": { 6 | "target": "es5", 7 | "module": "esnext", 8 | "downlevelIteration": true, 9 | "strict": true, 10 | "noUnusedLocals": true, 11 | "noUnusedParameters": true, 12 | "moduleResolution": "node" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /template/webpack.skpm.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | const TerserPlugin = require("terser-webpack-plugin"); 3 | 4 | module.exports = function (config, isPluginCommand) { 5 | const isProduction = process.env.NODE_ENV == "production"; 6 | 7 | config.module.rules.push({ 8 | test: /\.tsx?$/, 9 | exclude: /node_modules/, 10 | loader: 'ts-loader' 11 | }); 12 | 13 | if (!config.resolve) { 14 | config.resolve = { 15 | extensions: [] 16 | }; 17 | } 18 | 19 | config.resolve.extensions = [...config.resolve.extensions, ".ts", ".tsx"]; 20 | 21 | // transformations for production (publish) 22 | if (isProduction) { 23 | config.mode = "production"; 24 | config.plugins.push( 25 | new webpack.LoaderOptionsPlugin({ 26 | minimize: true 27 | }) 28 | ); 29 | config.optimization = { 30 | minimizer: [ 31 | new TerserPlugin({ 32 | test: /\.j|ts($|\?)/i 33 | }) 34 | ] 35 | }; 36 | } 37 | } 38 | --------------------------------------------------------------------------------