-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #854 from Thenlie/develop
v2.0.2
- Loading branch information
Showing
22 changed files
with
40,602 additions
and
5,394 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env node | ||
|
||
import yargs from 'yargs'; | ||
import { hideBin } from 'yargs/helpers'; | ||
import { Props, main } from '.'; | ||
|
||
const yargsInstance = yargs(hideBin(process.argv)); | ||
|
||
yargsInstance | ||
.options({ | ||
o: { | ||
alias: 'outputFile', | ||
default: 'stdio', | ||
describe: 'Filename to write response to', | ||
type: 'string', | ||
}, | ||
i: { | ||
alias: 'inputFile', | ||
default: 'data/tmdb_openapi.json', | ||
describe: 'Filename to read open api spec from', | ||
type: 'string', | ||
}, | ||
p: { | ||
alias: 'inputPath', | ||
describe: 'TMDB endpoint to be requested', | ||
type: 'string', | ||
}, | ||
d: { | ||
alias: 'useDefaults', | ||
describe: 'If the request should use default values and bypass param entry', | ||
type: 'boolean', | ||
}, | ||
}) | ||
.command( | ||
'run', | ||
'run the CLI tool', | ||
() => {}, | ||
(argv) => { | ||
const { outputFile, inputFile, inputPath, useDefaults } = argv as unknown as Props; | ||
main({ outputFile, inputFile, inputPath, useDefaults }); | ||
} | ||
) | ||
.wrap(yargsInstance.terminalWidth()) | ||
.demandCommand(1) | ||
.parse(); |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import fs, { WriteFileOptions } from 'fs'; | ||
import path from 'path'; | ||
import { fileURLToPath } from 'url'; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = path.dirname(__filename); | ||
|
||
interface MakeRequestProps { | ||
path: string; | ||
params: Array<{ | ||
param: string; | ||
value: string; | ||
path: boolean; | ||
}>; | ||
outputFile: string | undefined; | ||
} | ||
|
||
/** | ||
* Helper function to make fetch request to TMDB and handle output | ||
*/ | ||
const makeRequest = async ({ path, params, outputFile }: MakeRequestProps) => { | ||
// Make fetch request and print output | ||
const data = JSON.stringify(await fetchTMDB(path, params), null, 4); | ||
if (outputFile && outputFile !== 'stdio') { | ||
try { | ||
const writeOptions: WriteFileOptions = { | ||
encoding: 'utf8', | ||
// the value 0o666 sets the file to be readable and writable by everyone but not executable | ||
mode: 0o666, | ||
flag: 'w', | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
fs.writeFileSync(`${__dirname}/${outputFile}`, data, writeOptions); | ||
// eslint-disable-next-line no-console | ||
console.log('File written successfully!'); | ||
} catch (err) { | ||
// eslint-disable-next-line no-console | ||
console.error('Failed to write file!', err); | ||
} | ||
} else { | ||
// eslint-disable-next-line no-console | ||
console.log(data); | ||
} | ||
}; | ||
|
||
/** | ||
* Make a GET request to The Movie DB API with a given endpoint | ||
* @todo make this method generic and move BASE_PATH and API_KEY to a config file | ||
* @param {string} path | ||
* @param {Array<{ param: string, value: string, path: boolean }>} params | ||
* @returns {Promise<object>} | ||
*/ | ||
const fetchTMDB = async ( | ||
path: string, | ||
params: Array<{ param: string; value: string; path: boolean }> | ||
): Promise<object> => { | ||
const BASE_PATH = 'https://api.themoviedb.org'; | ||
// eslint-disable-next-line no-undef | ||
const API_KEY = '?api_key=' + process.env.VITE_MOVIEDB_KEY; | ||
let PARAMS = ''; | ||
if (params.length > 0) { | ||
for (let i = 0; i < params.length; i++) { | ||
if (!params[i].path) { | ||
PARAMS += `&${params[i].param}=${params[i].value}`; | ||
} else { | ||
path = path.replace(`{${params[i].param}}`, params[i].value); | ||
} | ||
} | ||
} | ||
const url = new URL(BASE_PATH + path + API_KEY + PARAMS); | ||
const res = await fetch(url); | ||
if (!res.ok) { | ||
throw new Error(`Failed to fetch: ${String(url)}. Status: ${res.statusText}`); | ||
} | ||
const json = await res.json(); | ||
return json; | ||
}; | ||
|
||
export { makeRequest, fetchTMDB }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import 'dotenv/config'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { fileURLToPath } from 'url'; | ||
import { filterPathsByReqType, getPathParams, validatePath } from './utils.js'; | ||
import searchSelect from './searchSelect.js'; | ||
import { checkbox, input } from '@inquirer/prompts'; | ||
import { makeRequest } from './fetch.js'; | ||
import { DEFAULT_PARAMS } from './lib/params.js'; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = path.dirname(__filename); | ||
|
||
export interface Props { | ||
outputFile: string | undefined; | ||
inputFile: string; | ||
inputPath: string | undefined; | ||
useDefaults: boolean; | ||
} | ||
|
||
export const main = async ({ outputFile, inputFile, inputPath, useDefaults }: Props) => { | ||
// Parse The Movie DB's Open API schema | ||
const json = JSON.parse(fs.readFileSync(`${__dirname}/${inputFile}`, 'utf8')); | ||
|
||
// Create path choices | ||
const getReqPaths = filterPathsByReqType(Object.entries(json.paths), 'get'); | ||
|
||
// Get user selected path | ||
let selectedPath: string; | ||
if (inputPath) { | ||
const isValid = validatePath(inputPath, getReqPaths.map((path) => path[0]) as string[]); | ||
if (!isValid) throw new Error(`Invalid path ${inputPath}!`); | ||
selectedPath = inputPath; | ||
} else { | ||
const pathChoices = getReqPaths.map((path: object) => { | ||
return { | ||
name: path[0], | ||
value: path[0], | ||
description: path[1]['get'].description, | ||
}; | ||
}); | ||
selectedPath = await searchSelect({ | ||
message: 'Select a Movie DB API request', | ||
choices: pathChoices, | ||
}); | ||
} | ||
|
||
// Create list of user selected OR default query parameters | ||
const selectedParams: Array<{ | ||
param: string; | ||
value: string; | ||
path: boolean; | ||
}> = []; | ||
const pathParams = getPathParams(selectedPath); | ||
if (!useDefaults) { | ||
// Get list of all params for selected path | ||
const params = json.paths[selectedPath].get.parameters.map((param) => { | ||
const req = param.required ? ' (required)' : ''; | ||
return { | ||
name: param.name + req, | ||
value: param.name, | ||
checked: !!req, | ||
}; | ||
}); | ||
|
||
// Get user selected params | ||
const selectedParamList: string[] = await checkbox({ | ||
message: 'Select params to add', | ||
choices: params, | ||
loop: true, | ||
}); | ||
|
||
// Prompt user for each selected param | ||
for (let i = 0; i < selectedParamList.length; i++) { | ||
const answer = await input({ message: selectedParamList[i] }); | ||
const isInPath = pathParams.includes(selectedParamList[i]); | ||
selectedParams.push({ param: selectedParamList[i], value: answer, path: isInPath }); | ||
} | ||
} else { | ||
// Get default path params | ||
for (let i = 0; i < pathParams.length; i++) { | ||
const defaultParam = DEFAULT_PARAMS.find((param) => param.name === pathParams[i]); | ||
if (defaultParam) { | ||
selectedParams.push({ | ||
param: pathParams[i], | ||
value: defaultParam.values[Math.round(Math.random())], | ||
path: true, | ||
}); | ||
} | ||
} | ||
} | ||
|
||
await makeRequest({ path: selectedPath, params: selectedParams, outputFile }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* A list of all TMDB path parameters with default values. | ||
* | ||
* @todo Add non-path params | ||
* | ||
* Given a list of paths, you can filter out unique params using the command: | ||
* `grep -Eo '\{\w+\}' <filename> | sort | uniq` | ||
*/ | ||
const DEFAULT_PARAMS = [ | ||
{ name: 'account_id', values: ['', ''] }, | ||
{ name: 'collection_id', values: ['', ''] }, | ||
{ name: 'company_id', values: ['3166', '521'] }, | ||
{ name: 'credit_id', values: ['52fe4311c3a36847f8037ee9', '52fe4311c3a36847f8037ec7'] }, | ||
{ name: 'episode_id', values: ['385571', '62085'] }, | ||
{ name: 'episode_number', values: ['1', '2'] }, | ||
{ name: 'external_id', values: ['', ''] }, | ||
{ name: 'guest_session_id', values: ['', ''] }, | ||
{ name: 'keyword_id', values: ['', ''] }, | ||
{ name: 'list_id', values: ['', ''] }, | ||
{ name: 'movie_id', values: ['1726', '4232'] }, | ||
{ name: 'network_id', values: ['174', '6'] }, | ||
{ name: 'person_id', values: ['17419', '70851'] }, | ||
{ name: 'review_id', values: ['59cc634fc3a3682aa30065a3', '6313ce428c7b0f0082be0687'] }, | ||
{ name: 'season_id', values: ['7240', '3572'] }, | ||
{ name: 'season_number', values: ['1', '2'] }, | ||
{ name: 'series_id', values: ['2316', '1396'] }, | ||
{ name: 'time_window', values: ['day', 'week'] }, | ||
{ name: 'tv_episode_group_id', values: ['', ''] }, | ||
]; | ||
|
||
export { DEFAULT_PARAMS }; |
Oops, something went wrong.