├── .gitignore ├── .npmignore ├── tests ├── tsconfig.json └── index.test.ts ├── codecov.yml ├── tslint.json ├── .github └── workflows │ └── ci.yml ├── tsconfig.json ├── LICENSE ├── README.md ├── src └── index.ts └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | coverage 4 | .env 5 | lib 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests 2 | codecov.yml 3 | README.md 4 | .gitignore 5 | coverage 6 | src -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig", 3 | "include": [ 4 | "../src/**/*", 5 | "**/*.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | # Fail the status if coverage drops by >= 3% 6 | threshold: 3 7 | patch: 8 | default: 9 | threshold: 3 10 | 11 | comment: false 12 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint:latest", 4 | "tslint-config-prettier", 5 | "tslint-config-standard" 6 | ], 7 | "rules": { 8 | "interface-name": [ 9 | true, 10 | "never-prefix" 11 | ], 12 | "prefer-object-spread": false, 13 | "no-implicit-dependencies": [ 14 | true, 15 | "dev" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [10.x, 12.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - run: npm ci 25 | - run: npm run build 26 | - run: npm test -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": false, 4 | "lib": [ 5 | "es2015", 6 | "es2017" 7 | ], 8 | "module": "commonjs", 9 | "moduleResolution": "node", 10 | "target": "es5", 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noUnusedLocals": true, 14 | "pretty": true, 15 | "strict": true, 16 | "sourceMap": true, 17 | "outDir": "./lib", 18 | "skipLibCheck": true, 19 | "noImplicitAny": true, 20 | "esModuleInterop": true, 21 | "declaration": true 22 | }, 23 | "include": [ 24 | "src/**/*" 25 | ], 26 | "compileOnSave": false 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jason Etcovitch 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. -------------------------------------------------------------------------------- /tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import nock from 'nock' 2 | import { GistBox } from '../src' 3 | 4 | describe('gist-box', () => { 5 | beforeEach(() => { 6 | nock('https://api.github.com') 7 | .get('/gists/123') 8 | .reply(200, { files: { example: { description: 'pizza' } } }) 9 | }) 10 | 11 | describe('#get', () => { 12 | it('gets the Gist', async () => { 13 | const box = new GistBox({ id: '123', token: '123abc' }) 14 | expect(await box.get()).toEqual( 15 | expect.objectContaining({ 16 | data: { files: { example: { description: 'pizza' } } } 17 | }) 18 | ) 19 | }) 20 | }) 21 | 22 | describe('#update', () => { 23 | it('updates the Gist', async () => { 24 | const scopedNock = nock('https://api.github.com') 25 | .patch('/gists/123') 26 | .reply(200, (_, body) => body) 27 | 28 | const box = new GistBox({ id: '123', token: '123abc' }) 29 | const actual = await box.update({ content: 'pizza' }) 30 | expect(actual.data).toEqual({ files: { example: { content: 'pizza' } } }) 31 | expect(scopedNock.isDone()).toBe(true) 32 | }) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

GistBox

2 |

📌📋 A helper class for updating a single-file Gist

3 |

NPM Build Status Codecov

4 | 5 | ## Usage 6 | 7 | ### Installation 8 | 9 | ```sh 10 | $ npm install gist-box 11 | ``` 12 | 13 | ```js 14 | const { GistBox } = require('gist-box') 15 | ``` 16 | 17 | ### API 18 | 19 | ```js 20 | const box = new GistBox({ id, token }) 21 | await box.update({ 22 | filename: 'example.md', 23 | description: 'A new description', 24 | content: 'The new content' 25 | }) 26 | ``` 27 | 28 | You can also import some boundary numbers to use when dealing with pinned Gists: 29 | 30 | ```js 31 | const { 32 | MAX_LENGTH, // The number of characters rendered in one line 33 | MAX_LINES, // The number of lines it will render 34 | MAX_HEIGHT, // The height of the box, in pixels 35 | MAX_WIDTH // The width of the box, in pixels 36 | } = require('gist-box') 37 | ``` 38 | 39 | --- 40 | 41 | Shoutout to [@matchai](https://github.com/matchai) for starting this trend with [bird-box](https://github.com/matchai/bird-box)! 42 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@octokit/request' 2 | 3 | export interface GistBoxOptions { 4 | /** 5 | * The ID of the Gist 6 | */ 7 | id: string 8 | /** 9 | * A GitHub API token to authenticate with 10 | */ 11 | token: string 12 | } 13 | 14 | export interface Updates { 15 | filename?: string 16 | content?: string 17 | description?: string 18 | } 19 | 20 | /** 21 | * The maximum number of characters in a pinned Gist line 22 | */ 23 | export const MAX_LENGTH = 63 24 | /** 25 | * The maximum number of lines in a pinned Gist 26 | */ 27 | export const MAX_LINES = 5 28 | /** 29 | * The maximum width of a pinned Gist image 30 | */ 31 | export const MAX_WIDTH = 325 32 | /** 33 | * The maximum height of a pinned Gist image 34 | */ 35 | export const MAX_HEIGHT = 100 36 | 37 | export class GistBox { 38 | public id: string 39 | private token: string 40 | 41 | constructor ({ id, token }: GistBoxOptions) { 42 | this.id = id 43 | this.token = token 44 | } 45 | 46 | /** 47 | * Get the Gist 48 | */ 49 | public async get () { 50 | return request('GET /gists/:gist_id', { 51 | gist_id: this.id, 52 | headers: { 53 | authorization: `token ${this.token}` 54 | } 55 | }) 56 | } 57 | 58 | /** 59 | * Update the Gist 60 | */ 61 | public async update (updates: Updates) { 62 | const gist = await this.get() 63 | const filename = Object.keys(gist.data.files)[0] 64 | return request('PATCH /gists/:gist_id', { 65 | files: { [filename]: updates }, 66 | gist_id: this.id, 67 | headers: { 68 | authorization: `token ${this.token}` 69 | } 70 | }) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gist-box", 3 | "version": "0.3.1", 4 | "description": "A helper class for updating a single-file Gist", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "build": "rimraf lib && tsc -p tsconfig.json", 8 | "lint": "tslint --project tests", 9 | "test": "tsc --noEmit -p tests && jest --coverage && npm run lint", 10 | "test:update": "tsc --noEmit -p tests && jest --coverage -u && npm run lint", 11 | "prepare": "npm test && npm run build" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/JasonEtco/gist-box.git" 16 | }, 17 | "keywords": [ 18 | "github", 19 | "github api" 20 | ], 21 | "author": "Jason Etcovitch ", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/JasonEtco/gist-box/issues" 25 | }, 26 | "homepage": "https://github.com/JasonEtco/gist-box#readme", 27 | "dependencies": { 28 | "@octokit/request": "^5.3.4" 29 | }, 30 | "devDependencies": { 31 | "@types/jest": "^25.2.1", 32 | "@types/node": "^13.11.0", 33 | "jest": "^25.2.7", 34 | "nock": "^12.0.3", 35 | "standard": "^14.3.3", 36 | "ts-jest": "^25.3.1", 37 | "tslint": "^6.1.1", 38 | "tslint-config-prettier": "^1.18.0", 39 | "tslint-config-standard": "^9.0.0", 40 | "typescript": "^3.8.3" 41 | }, 42 | "standard": { 43 | "env": [ 44 | "jest" 45 | ] 46 | }, 47 | "jest": { 48 | "testEnvironment": "node", 49 | "coveragePathIgnorePatterns": [ 50 | "/lib/" 51 | ], 52 | "moduleFileExtensions": [ 53 | "ts", 54 | "js", 55 | "json" 56 | ], 57 | "transform": { 58 | ".+\\.tsx?$": "ts-jest" 59 | }, 60 | "testMatch": [ 61 | "/tests/**/*.test.(ts|js)" 62 | ], 63 | "globals": { 64 | "ts-jest": { 65 | "babelConfig": false 66 | } 67 | } 68 | } 69 | } 70 | --------------------------------------------------------------------------------