All files Chenv.js

100% Statements 24/24
60% Branches 3/5
100% Functions 9/9
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                          2x                         2x 3x 2x 2x     2x 1x 1x 1x                           5x 4x 4x 4x 4x       4x   4x       1x 1x             1x 1x               1x 1x               1x 1x                                    
// @flow
import dtz from 'dtz'
import Zip from 'jszip'
import { asserts } from './util'
import { getAccessToken } from './api.token'
import {
  insertItem,
  updateItem,
  publishItem,
  checkItem,
  type ItemResource,
} from './api.item'
 
const manifestMap = {
  ['remove']: {
    manifest_version: 2,
    name: '(removed)',
    version: '0',
  },
  ['create']: {
    manifest_version: 2,
    name: '',
    version: '0.0.0',
  },
}
 
const zipApp = async (src) => {
  asserts(src, `[chenv] src is ${src}`)
  const zip = await dtz(src)
  return zip.generateNodeStream()
}
 
const zipEmpty = (manifestJson) => {
  const zip = new Zip()
  zip.file('manifest.json', JSON.stringify(manifestJson))
  return zip.generateNodeStream()
}
 
type Credentials = {
  client_id: string,
  client_secret: string,
  refresh_token: string
}
 
export class Chenv {
  token: string
  credentials: Credentials
 
  constructor({ client_id, client_secret, refresh_token }: Credentials = {}) {
    asserts(client_id, `client_id is required`)
    asserts(client_secret, `client_secret is required`)
    asserts(refresh_token, `refresh_token is required`)
    this.token = ''
    this.credentials = { client_id, client_secret, refresh_token }
  }
 
  setToken() {
    return this.token
    ? false
    : getAccessToken(this.credentials).then(token => this.token = token)
  }
 
  async insertItem(src: string): Promise<ItemResource> {
    await this.setToken()
    return insertItem({
      token: this.token,
      body: await zipApp(src)
    })
  }
 
  async updateItem(id: string, src: string): Promise<ItemResource> {
    await this.setToken()
    return updateItem({
      token: this.token,
      body: await zipApp(src),
      id
    })
  }
 
  async publishItem(id: string, trustedTesters?: boolean): Promise<ItemResource> {
    await this.setToken()
    return publishItem({
      token: this.token,
      target: trustedTesters ? 'trustedTesters' : 'default',
      id,
    })
  }
 
  async removeItem(id: string): Promise<ItemResource> {
    await this.setToken()
    return updateItem({
      token: this.token,
      body: zipEmpty(manifestMap['remove']),
      id
    })
  }
 
  /*
  ref: https://developer.chrome.com/webstore/webstore_api/items/get
  async checkItem(id: string, projection: string): Promise<ItemResource> {
    await this.setToken()
    return checkItem({
      token: this.token,
      projection,
      id
    })
  }
  */
}