From af54b80d7e8ecbdc9bfad50f9246b5b691c7ca8c Mon Sep 17 00:00:00 2001 From: Troy Goode Date: Tue, 8 Aug 2023 18:38:34 -0700 Subject: [PATCH] add support for users:get/set --- README.md | 5 ++++ package.json | 2 +- source/commands/Config.tsx | 17 +++++++++---- source/commands/UsersGet.tsx | 36 ++++++++++++++++++++++++++ source/commands/UsersSet.tsx | 48 +++++++++++++++++++++++++++++++++++ source/components/Request.tsx | 7 ++--- source/components/Router.tsx | 39 +++++++++++++++------------- source/mappings.tsx | 39 +++++++++++++++++++++++++--- 8 files changed, 164 insertions(+), 29 deletions(-) create mode 100644 source/commands/UsersGet.tsx create mode 100644 source/commands/UsersSet.tsx diff --git a/README.md b/README.md index 5f705e4..1e07af0 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ You can find your Courier API key in your [Courier Settings](https://app.courier - `courier whoami` – Display the currently authenticated workspace - `courier send` - Send a notification to a user, list, or audience - `courier track` - Send a track event to trigger a Courier Automations +- `courier users:get` - Fetch the data for a given user ID +- `courier users:set` - Overwrite a user's profile with the provided data - `courier digests:flush` – Flush any currently queued events for a given user + digest - `courier translations:upload` - Upload .PO files to your Courier workspace - `courier translations:download` - Download .PO files from your Courier workspace @@ -60,6 +62,9 @@ $ courier send --user user123 --elemental my-template.json --foo bar $ courier track my-event user123 --foo bar +$ courier users:get user123 +$ courier users:set user123 --email user@example.com --tel 555-867-5309 + $ courier digests:flush user123 my-digest-id $ courier translations:upload en-US ./translations/en-US.po diff --git a/package.json b/package.json index 62e70c5..5f92867 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@trycourier/cli", - "version": "1.4.1", + "version": "1.5.0", "license": "MIT", "bin": { "courier": "dist/cli.js" diff --git a/source/commands/Config.tsx b/source/commands/Config.tsx index 92319f0..5be5076 100644 --- a/source/commands/Config.tsx +++ b/source/commands/Config.tsx @@ -9,21 +9,28 @@ type Params = { }; export default ({params}: {params: Params}) => { - const FILE_PATH = `${process.cwd()}/.courier`; + const FILE_PATH = `${process.cwd()}/.courier`; if (!params?.apikey) { - return ; + return ( + + ); } if (fs.existsSync(FILE_PATH) && !params.overwrite) { - return ; + return ( + + ); } - + fs.writeFileSync(FILE_PATH, `COURIER_API_KEY=${params.apikey}\n`); return ( - Your API key has been saved to {FILE_PATH}. Run "courier whoami" to verify API credentials. + Your API key has been saved to {FILE_PATH}. Run "courier whoami" to verify + API credentials. ); }; diff --git a/source/commands/UsersGet.tsx b/source/commands/UsersGet.tsx new file mode 100644 index 0000000..a3adf64 --- /dev/null +++ b/source/commands/UsersGet.tsx @@ -0,0 +1,36 @@ +import React, {useEffect, useState} from 'react'; +import UhOh from '../components/UhOh.js'; +import Request from '../components/Request.js'; +import Response from '../components/Response.js'; +import api from '../lib/api.js'; + +interface IResponse { + res: Response; + json?: any; + err?: Error; +} + +export default ({params}: {params: any}) => { + const [resp, setResp] = useState(); + + const userId = params?._?.[0]; + if (!userId) { + return ; + } + + const request = { + method: 'GET', + url: `/profiles/${userId}`, + }; + + useEffect(() => { + api(request).then(res => setResp(res)); + }, []); + + return ( + <> + + + + ); +}; diff --git a/source/commands/UsersSet.tsx b/source/commands/UsersSet.tsx new file mode 100644 index 0000000..7ce0a42 --- /dev/null +++ b/source/commands/UsersSet.tsx @@ -0,0 +1,48 @@ +import React, {useEffect, useState} from 'react'; +import UhOh from '../components/UhOh.js'; +import Request from '../components/Request.js'; +import Response from '../components/Response.js'; +import api from '../lib/api.js'; + +interface IResponse { + res: Response; + json?: any; + err?: Error; +} + +export default ({params}: {params: any}) => { + const [resp, setResp] = useState(); + + const userId = params?._?.[0]; + if (!userId) { + return ; + } + + const {_, ...properties} = params; + + if (properties.tel) { + properties.phone_number = properties.tel; + delete properties.tel; + } + + const request = { + method: 'PUT', + url: `/profiles/${userId}`, + body: { + profile: { + ...properties, + }, + }, + }; + + useEffect(() => { + api(request).then(res => setResp(res)); + }, []); + + return ( + <> + + + + ); +}; diff --git a/source/components/Request.tsx b/source/components/Request.tsx index aa65705..2abf8e0 100644 --- a/source/components/Request.tsx +++ b/source/components/Request.tsx @@ -29,14 +29,15 @@ type Props = { }; export default (props: Props) => { - const url = `${process.env['COURIER_DOMAIN'] || 'https://api.courier.com'}${props.request.url}`; + const url = `${process.env['COURIER_DOMAIN'] || 'https://api.courier.com'}${ + props.request.url + }`; return ( {' '} - {props.request.method}{' '} - {url} + {props.request.method} {url} {props.request.body ? ( diff --git a/source/components/Router.tsx b/source/components/Router.tsx index 0f069d4..262fcba 100644 --- a/source/components/Router.tsx +++ b/source/components/Router.tsx @@ -27,23 +27,28 @@ export default ({args, mappings}: Props) => { if ((apiKey && apiKey.length) || mapping.noApiKeyRequired) { return mapping.component(parsedParams); } else { - return <> - - No COURIER_API_KEY specified, please set via one of these options: - - - • running "courier config --apikey <your-api-key>" - - - • setting COURIER_API_KEY in your shell via "export COURIER_API_KEY=<your-api-key>" - - - • setting COURIER_API_KEY in a ".courier" file in your current working directory - - - • setting COURIER_API_KEY in a ".courier" file in your user's home directory - - + return ( + <> + + No COURIER_API_KEY specified, please set via one of these options: + + + • running "courier config --apikey <your-api-key>" + + + • setting COURIER_API_KEY in your shell via "export + COURIER_API_KEY=<your-api-key>" + + + • setting COURIER_API_KEY in a ".courier" file in your current + working directory + + + • setting COURIER_API_KEY in a ".courier" file in your user's home + directory + + + ); } } else { return ; diff --git a/source/mappings.tsx b/source/mappings.tsx index 089d14a..fd0f900 100644 --- a/source/mappings.tsx +++ b/source/mappings.tsx @@ -3,6 +3,8 @@ import Help from './commands/Help.js'; import Config from './commands/Config.js'; import WhoAmI from './commands/WhoAmI.js'; import Track from './commands/Track.js'; +import UsersGet from './commands/UsersGet.js'; +import UsersSet from './commands/UsersSet.js'; import Send from './commands/Send.js'; import DigestFlush from './commands/DigestFlush.js'; import TranslationsDownload from './commands/TranslationsDownload.js'; @@ -27,10 +29,11 @@ mappings.set('help', { component: () => { return ; }, - noApiKeyRequired: true + noApiKeyRequired: true, }); mappings.set('config', { - instructions: 'Persist your Courier API key into a .courier file in your current working directory', + instructions: + 'Persist your Courier API key into a .courier file in your current working directory', component: params => { return ; }, @@ -45,7 +48,7 @@ mappings.set('config', { }, ], example: `courier config --apikey MY_API_KEY`, - noApiKeyRequired: true + noApiKeyRequired: true, }); mappings.set('whoami', { instructions: 'Display the currently authenticated workspace', @@ -132,6 +135,36 @@ mappings.set('track', { return ; }, }); +mappings.set('users:get', { + params: '', + instructions: 'Fetch the data for a given user ID', + example: `courier users:get user123`, + component: params => { + return ; + }, +}); +mappings.set('users:set', { + params: '', + instructions: "Overwrite a user's profile with the provided data", + options: [ + { + option: '--email ', + value: '', + }, + { + option: '--tel ', + value: '', + }, + { + option: '-- ', + value: 'arbitrary key/value properties for your user', + }, + ], + example: `courier users:set user123 --email user@example.com`, + component: params => { + return ; + }, +}); mappings.set('digests:flush', { params: ' ', instructions: 'Flush any currently queued events for a given user + digest',