1+ // Libraries used
2+ const fs = require ( 'fs' ) ;
3+ const path = require ( 'path' ) ;
4+ const axios = require ( 'axios' ) ;
5+ const FormData = require ( 'form-data' ) ;
6+
7+ // BookStack API variables
8+ // Uses values on the environment unless hardcoded
9+ // To hardcode, add values to the empty strings in the below.
10+ const bookStackConfig = {
11+ base_url : '' || process . env . BS_URL ,
12+ token_id : '' || process . env . BS_TOKEN_ID ,
13+ token_secret : '' || process . env . BS_TOKEN_SECRET ,
14+ } ;
15+
16+ // Script Logic
17+ ////////////////
18+
19+ // Check arguments provided
20+ if ( process . argv . length < 4 ) {
21+ console . error ( 'Both <page_id> and <file_path> arguments need to be provided' ) ;
22+ return ;
23+ }
24+
25+ // Get arguments passed via command
26+ const [ _exec , _script , pageId , filePath ] = process . argv ;
27+
28+ // Check the given file exists
29+ if ( ! fs . existsSync ( filePath ) ) {
30+ console . error ( `File at "${ filePath } " could not be found` ) ;
31+ return ;
32+ }
33+
34+ // Get the file name and create a read stream from the given file
35+ const fileStream = fs . createReadStream ( filePath ) ;
36+ const fileName = path . basename ( filePath ) ;
37+
38+ // Gather our form data with all the required bits
39+ const formPostData = new FormData ( ) ;
40+ formPostData . append ( 'file' , fileStream ) ;
41+ formPostData . append ( 'name' , fileName ) ;
42+ formPostData . append ( 'uploaded_to' , pageId ) ;
43+
44+ // Create an axios instance for our API
45+ const api = axios . create ( {
46+ baseURL : bookStackConfig . base_url . replace ( / \/ $ / , '' ) + '/api/' ,
47+ timeout : 30000 ,
48+ headers : { 'Authorization' : `Token ${ bookStackConfig . token_id } :${ bookStackConfig . token_secret } ` } ,
49+ } ) ;
50+
51+ // Wrap the rest of our code in an async function, so we can await within.
52+ ( async function ( ) {
53+
54+ // Upload the file using the gathered data
55+ // Sends it with a "Content-Type: multipart/form-data" with the post
56+ // body formatted as multipart/form-data content, with the "FormData" object
57+ // from the "form-data" library does for us.
58+ const { data : attachment } = await api . post ( '/attachments' , formPostData , {
59+ headers : formPostData . getHeaders ( ) ,
60+ } ) ;
61+
62+ // Output the results
63+ console . info ( `File successfully uploaded to page ${ pageId } .` ) ;
64+ console . info ( ` - Attachment ID: ${ attachment . id } ` ) ;
65+ console . info ( ` - Attachment Name: ${ attachment . name } ` ) ;
66+
67+ } ) ( ) . catch ( err => {
68+ // Handle API errors
69+ if ( err . response ) {
70+ console . error ( `Request failed with status ${ err . response . status } [${ err . response . statusText } ]` ) ;
71+ console . error ( JSON . stringify ( err . response . data ) ) ;
72+ return ;
73+ }
74+ // Output all other errors
75+ console . error ( err )
76+ } ) ;
0 commit comments