1+ // Libraries used
2+ const fs = require ( 'fs' ) ;
3+ const path = require ( 'path' ) ;
4+ const axios = require ( 'axios' ) ;
5+ const mammoth = require ( 'mammoth' ) ;
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 <docx_file> and <book_slug> arguments need to be provided' ) ;
22+ return ;
23+ }
24+
25+ // Get arguments passed via command
26+ const [ _exec , _script , docxFile , bookSlug ] = process . argv ;
27+
28+ // Check the docx file exists
29+ if ( ! fs . existsSync ( docxFile ) ) {
30+ console . error ( `Provided docx file "${ docxFile } " could not be found` ) ;
31+ return ;
32+ }
33+
34+ // Create an axios instance for our API
35+ const api = axios . create ( {
36+ baseURL : bookStackConfig . base_url . replace ( / \/ $ / , '' ) + '/api/' ,
37+ timeout : 5000 ,
38+ headers : { 'Authorization' : `Token ${ bookStackConfig . token_id } :${ bookStackConfig . token_secret } ` } ,
39+ } ) ;
40+
41+ // Wrap the rest of our code in an async function so we can await within.
42+ ( async function ( ) {
43+
44+ // Fetch the related book to ensure it exists
45+ const { data : bookSearch } = await api . get ( `/books?filter[slug]=${ encodeURIComponent ( bookSlug ) } ` ) ;
46+ if ( bookSearch . data . length === 0 ) {
47+ console . error ( `Book with a slug of "${ bookSlug } " could not be found` ) ;
48+ return ;
49+ }
50+ const book = bookSearch . data [ 0 ] ;
51+
52+ // Convert our document
53+ const { value : html , messages} = await mammoth . convertToHtml ( { path : docxFile } ) ;
54+
55+ // Create a name from our document file name
56+ let { name} = path . parse ( docxFile ) ;
57+ name = name . replace ( / [ - _ ] / g, ' ' ) ;
58+
59+ // Upload our page
60+ const { data : page } = await api . post ( '/pages' , {
61+ book_id : book . id ,
62+ name,
63+ html,
64+ } ) ;
65+
66+ // Output the results
67+ console . info ( `File converted and created as a page.` ) ;
68+ console . info ( ` - Page ID: ${ page . id } ` ) ;
69+ console . info ( ` - Page Name: ${ page . name } ` ) ;
70+ console . info ( `====================================` ) ;
71+ console . info ( `Conversion occurred with ${ messages . length } message(s):` ) ;
72+ for ( const message of messages ) {
73+ console . warn ( `[${ message . type } ] ${ message . message } ` ) ;
74+ }
75+
76+ } ) ( ) . catch ( err => {
77+ // Handle API errors
78+ if ( err . response ) {
79+ console . error ( `Request failed with status ${ err . response . status } [${ err . response . statusText } ]` ) ;
80+ return ;
81+ }
82+ // Output all other errors
83+ console . error ( err )
84+ } ) ;
0 commit comments