Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Artsy Open #156

Merged
merged 2 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Artsy CLI is published on npm, so installing is really easy:
$ npm install --global @artsy/cli
```

## [Docs]

- [Artsy Open Docs](docs/open.md)

## Releasing

The release process happens automatically on every PR merge thanks to [auto](https://github.com/intuit/auto). To ensure
Expand Down
55 changes: 55 additions & 0 deletions docs/open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Artsy CLI Open

Open Artsy links with iOS, Android or the browser.

## Usage

**With an alias:**

```
artsy open artwork
```

opens https://www.artsy.net/artwork/banksy-love-rat-signed-16 on iOS

**With a path:**

```
artsy open /artwork/andy-warhol-watercolor-paint-kit-with-brushes-11
```

opens https://www.artsy.net/artwork/andy-warhol-watercolor-paint-kit-with-brushes-11 on iOS

**With a full URL:**

```
artsy open https://www.staging.artsy.net/artwork/andy-warhol-watercolor-paint-kit-with-brushes-11
```

opens https://www.staging.artsy.net/artwork/andy-warhol-watercolor-paint-kit-with-brushes-11 on iOS

**With flags:**

```
artsy open artwork -a -l
```

opens localhost:3000/artwork/banksy-love-rat-signed-16 on Android

**With custom variables:**

```
artsy open artist artistID:andy-warhol
```

opens https://www.artsy.net/artist/andy-warhol on Android

## Config

All aliases and defaults can be found [here](src/lib/open/data/config.json).

The config can be overriden by providing `~/.config/artsy-open.json`. Just copy the config from GitHub and modify it:

```
curl https://www.raw.githubusercontent.com/artsy/cli/master/src/lib/open/data/config.json > ~/.config/artsy-open.json
```
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"apollo-client": "^2.6.10",
"apollo-link-http": "^1.5.17",
"cli-ux": "^5.3.1",
"colon-template": "^1.0.3",
"cross-fetch": "^3.0.6",
"dashify": "^2.0.0",
"dotenv": "^8.0.0",
"graphql": "^15.5.0",
"graphql-tag": "^2.11.0",
Expand All @@ -29,7 +31,8 @@
"node-fetch": "^2.6.0",
"querystring": "^0.2.0",
"rss-parser": "^3.11.0",
"tslib": "^2"
"tslib": "^2",
"uri-scheme": "^1.0.76"
},
"devDependencies": {
"@artsy/auto-config": "^1.0.1",
Expand All @@ -42,6 +45,7 @@
"@oclif/test": "^1",
"@oclif/tslint": "^3",
"@types/chai": "^4",
"@types/dashify": "^1.0.0",
"@types/mocha": "^8",
"@types/node": "^14",
"@types/node-fetch": "^2.5.0",
Expand All @@ -52,6 +56,7 @@
"nock": "^13.0.10",
"nyc": "^13",
"prettier": "^1.18.2",
"sinon": "^10.0.0",
"ts-node": "^9",
"tslint": "^5",
"tslint-config-prettier": "^1.18.0",
Expand Down
81 changes: 81 additions & 0 deletions src/commands/open.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { flags } from "@oclif/command"
import Command from "../base"

import openPage from "../lib/open"
import config from "../lib/open/config"

export default class Open extends Command {
static description =
"Open Artsy links with the iOS/Android emulator or the browser"

static examples = [
`$ artsy open artwork
opens "https://www.artsy.net/artwork/banksy-love-rat-signed-16" on iOS`,
`$ artsy open artwork/andy-warhol-watercolor-paint-kit-with-brushes-11
opens "https://www.artsy.net/artwork/andy-warhol-watercolor-paint-kit-with-brushes-11" on iOS`,
`artsy open artist artistID:andy-warhol
Open "https://www.artsy.net/artist/andy-warhol" on iOS`,
`$ artsy open home -a
opens "https://www.artsy.net/" on Android`,
`$ artsy open about -l
opens "localhost/about" on iOS`,
`\nALL PAGES`,
Object.keys(config.pages).join(", "),
]

static flags = {
...Command.flags,
ios: flags.boolean({ char: "i" }),
android: flags.boolean({ char: "a" }),
web: flags.boolean({ char: "w" }),
production: flags.boolean({ char: "p" }),
staging: flags.boolean({ char: "s" }),
local: flags.boolean({ char: "l" }),
}

static args = [
{ name: "page", required: false, default: "/" },
{ name: "customVariables", required: false },
]

parsePlatform(): string | undefined {
const { flags } = this.parse(Open)

if (flags.ios) return "ios"
if (flags.android) return "android"
if (flags.web) return "web"
}

parseEnvironment(): string | undefined {
const { flags } = this.parse(Open)

if (flags.staging) return "staging"
if (flags.production) return "production"
if (flags.local) return "local"
}

parseCustomVariables(): object {
const {
args: { customVariables },
} = this.parse(Open)

if (!customVariables) return {}

return customVariables.split(",").reduce((acc: any, element: string) => {
const [key, value] = element.split(":")
acc[key] = value
return acc
}, {})
}

async run() {
const { args } = this.parse(Open)

openPage({
page: args.page as string,
platform: this.parsePlatform(),
environment: this.parseEnvironment(),
customVariables: this.parseCustomVariables(),
})
}
}
9 changes: 9 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ export const Config = {
path: (): string => {
return `${os.homedir()}/.config/artsy`
},
readOpenConfig: (): any => {
try {
return JSON.parse(
fs.readFileSync(`${os.homedir()}/.config/artsy-open.json`)
)
} catch {
return {}
}
},
readToken: (): string => {
return fs.readFileSync(Config.path(), { encoding: "utf-8" })
},
Expand Down
13 changes: 13 additions & 0 deletions src/lib/open/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Config } from "../../config"
import { defaults, environments, pages, variables } from "./data/config.json"

const homeConfig = Config.readOpenConfig()

const config = {
environments: { ...environments, ...homeConfig.environments },
pages: { ...pages, ...homeConfig.pages },
variables: { ...variables, ...homeConfig.variables },
defaults: { ...defaults, ...homeConfig.defaults },
}

export default config
103 changes: 103 additions & 0 deletions src/lib/open/data/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"defaults": {
"environment": "production",
"platform": "ios"
},
"environments": {
"local": "localhost:3000",
"production": "https://www.artsy.net",
"staging": "https://www.staging.artsy.net"
},
"pages": {
"about": "/about",
"admin": "/admin",
"admin2": "/admin2",
"artist": "/artist/:artistID",
"artist-articles": "/artist/:artistID/articles",
"artist-series": "/artist-series/:artistSeriesID",
"artwork": "/artwork/:artworkID",
"artwork-attribution-class-faq": "/artwork-classifications",
"artwork-medium": "/artwork/:artworkID/medium",
"auction": "/auction/:auctionID",
"auction-bid-artwork": "/auction/:saleID/bid/:artworkID",
"auction-faq": "/auction-faq",
"auction-info": "/auction/:saleID/info",
"auction-registration": "/auction-registration/:saleID",
"auction-result": "/artist/:artistID/auction-result/:auctionResultInternalID",
"auction2": "/auction/:saleID",
"auctions": "/auctions",
"buy-now-feature-faq": "/buy-now-feature-faq",
"categories": "/categories",
"checkout": "/orders/:orderID",
"city-bmwlist": "/city-bmw-list/:citySlug",
"city-fair-list": "/city-fair/:citySlug",
"city-saved-list": "/city-save/:citySlug",
"city-section-list": "/city/:citySlug/:section",
"collection": "/collection/:collectionID",
"conditions-of-sale": "/conditions-of-sale",
"consignments-submission-form": "/consign/submission",
"conversation": "/user/conversations/:conversationID",
"fair": "/fair/:fairID/exhibitors",
"fair-all-followed-artists": "/fair/:fairID/followedArtists",
"fair-articles": "/fair/:fairID/articles",
"fair-bmwart-activation": "/fair/:fairID/bmw-sponsored-content",
"fair-more-info": "/fair/:fairID/info",
"favorites": "/favorites",
"feature": "/feature/:featureSlug",
"full-artist-series-list": "/artist/:artistID/artist-series",
"full-featured-artist-list": "/collection/:collectionID/artists",
"gene": "/gene/:geneID",
"home": "/",
"identity-verification-faq": "/identity-verification-faq",
"inbox": "/inbox",
"inquiry": "/inquiry/:artworkID",
"local-discovery": "/local-discovery",
"make-offer-modal": "/make-offer/:artworkID",
"my-account": "/my-account",
"my-account-edit-email": "/my-account/edit-email",
"my-account-edit-name": "/my-account/edit-name",
"my-account-edit-password": "/my-account/edit-password",
"my-account-edit-phone": "/my-account/edit-phone",
"my-collection": "/my-collection",
"my-collection-artwork": "/my-collection/artwork/:artworkSlug",
"my-collection-artwork-full-details": "/my-collection/artwork-details/:artworkSlug",
"my-collection-artwork-images": "/my-collection/artwork-images/:artworkSlug",
"my-profile": "/my-profile",
"my-profile-payment": "/my-profile/payment",
"my-profile-payment-new-credit-card": "/my-profile/payment/new-card",
"my-profile-push-notifications": "/my-profile/push-notifications",
"order": "/orders/:orderID",
"partner-locations": "/partner-locations/:partnerID",
"privacy": "/privacy",
"privacy-request": "/privacy-request",
"sales": "/sales",
"sales-not-root-tab-view": "/collections/my-collection/marketing-landing",
"search": "/search",
"show": "/show/:showID",
"show-more-info": "/show/:showID/info",
"terms": "/terms",
"viewing-room": "/viewing-room/:viewing_room_id",
"viewing-room-artwork": "/viewing-room/:viewing_room_id/:artworkID",
"viewing-room-artworks": "/viewing-room/:viewing_room_id/artworks",
"viewing-rooms": "/viewing-rooms",
"works-for-you": "/works-for-you"
},
"variables": {
"artistID": "banksy",
"artistSeriesID": "andy-warhol-watercolor-paint-kit-with-brushes",
"artworkID": "banksy-love-rat-signed-16",
"auctionID": "american-friends-of-museums-in-israel-benefit-auction-2021",
"auctionResultInternalID": "",
"citySlug": "berlin",
"collectionID": "abstract-expressionism-works-on-paper",
"conversationID": "",
"fairID": "one-x-artsy",
"featureSlug": "museum-of-contemporary-art-san-diego-benefit-auction-2020",
"geneID": "design",
"orderID": "",
"partnerID": "menconi-plus-schoelkopf",
"saleID": "american-friends-of-museums-in-israel-benefit-auction-2021",
"showID": "first-floor-gallery-harare-amanda-mushate-nguve-inemuridzi",
"viewing_room_id": "artcn-panacea-of-liu-zhenchen"
}
}
62 changes: 62 additions & 0 deletions src/lib/open/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const { Android, Ios } = require("uri-scheme")
const dashify = require("dashify")
const template = require("colon-template")
const { cli } = require("cli-ux")

import config from "./config"
interface OpenPageProps {
page: string
platform: string | undefined
environment: string | undefined
customVariables: object
}

const openUri = (uri: string, platform: string) => {
switch (platform) {
case "android":
Android.openAsync({ uri })
break
case "ios":
Ios.openAsync({ uri })
break
case "web":
cli.open(uri)
}
}

const removeTrailingSlash = (path: string): string => {
return path.replace(/^\//, "")
}

const getURI = (
input: string,
variables: object,
environment: string
): string => {
if (input.includes("://")) return input

const { pages, environments } = config

const templatePath = removeTrailingSlash(pages[dashify(input)] || input)

const path = template(templatePath, variables)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool! 💯


return `${environments[environment]}/${path}`
}

const openPage = ({
page,
platform,
environment,
customVariables,
}: OpenPageProps) => {
const variables = { ...config.variables, ...customVariables }
const env = environment || config.defaults.environment
const uri = getURI(page, variables, env)

console.log(`Open "${uri}" on ${platform || config.defaults.platform}`)

openUri(uri, platform || config.defaults.platform)
}

export default openPage
Loading