Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apibake

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apibake - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

23

dist/index.js

@@ -45,2 +45,4 @@ #!/usr/bin/env node

separateSchemas: { key: '-separate-schemas', value: false, help: 'When multiple API files parsed, create separate schemas section for each.' },
style: { key: '-style', value: '', help: 'Path to style.json. See -export-style.' },
exportStyle: { key: '-export-style', value: false, help: 'Save default document style into style.json for editing.' },
help: { key: '-h', value: false, help: 'Show this help.' },

@@ -60,8 +62,25 @@ };

}
if (args.help.value || argsParser.rest.length === 0) {
if (args.help.value) {
printUsageHelp();
return;
}
let style;
if (args.style.value) {
try {
style = JSON.parse(fs_1.default.readFileSync(args.style.value, 'utf8'));
}
catch (e) {
(0, logger_1.errorLog)(`Error in ${args.style.value}: ${e}`);
return;
}
}
const outputFile = args.output.value;
const doc = new pdf_writer_1.PdfWriter(outputFile);
const doc = new pdf_writer_1.PdfWriter(outputFile, style);
if (args.exportStyle.value) {
fs_1.default.writeFileSync('style.json', JSON.stringify(doc.style, null, 2));
}
if (argsParser.rest.length === 0) {
(0, logger_1.log)('No .json or .yaml files specified.\n');
return;
}
doc.addTitlePage(args.title.value, args.subtitle.value, (0, moment_1.default)().format('YYYY-MM-DD'));

@@ -68,0 +87,0 @@ const errorMessages = [];

92

dist/pdf-writer.js

@@ -19,3 +19,21 @@ "use strict";

class PdfWriter {
constructor(outputFilePath) {
constructor(outputFilePath, style) {
// configurable PDF style
this.style = {
color: {
main: '#333333',
secondary: '#6B7B8E',
types: '#8A3324',
headers: '#2A4D69',
subHeaders: '#4B86B4',
},
font: {
baseSize: 10,
},
format: {
indentStep: 12,
horizontalMargin: 70,
verticalMargin: 50
}
};
this.currentSectionName = '';

@@ -32,21 +50,17 @@ this.pageNumber = 0;

];
this.colorMain = 'black';
this.colorAccent = 'blue';
this.colorDisabled = 'grey';
this.baseFontSize = 10;
this.paraGap = this.baseFontSize / 3;
this.subHeaderGap = this.baseFontSize / 2;
this.headerGap = this.baseFontSize + 4;
this.indentStep = 12;
this.margins = {
horizontal: 70,
vertical: 50
};
// calculated in applyStyle()
this.paraGap = 0;
this.subHeaderGap = 0;
this.headerGap = 0;
this.baseStyle = {
font: EFont.NORM,
fontSize: this.baseFontSize,
fillColor: this.colorMain,
leftMargin: this.margins.horizontal,
fontSize: this.style.font.baseSize,
fillColor: this.style.color.main,
leftMargin: this.style.format.horizontalMargin,
lineGap: 0,
};
if (style) {
this.style = style; // external style
}
this.applyStyle();
this.doc = new PDFDocument({

@@ -56,6 +70,6 @@ bufferPages: true,

margins: {
left: this.margins.horizontal,
right: this.margins.horizontal,
top: this.margins.vertical,
bottom: this.margins.vertical
left: this.style.format.horizontalMargin,
right: this.style.format.horizontalMargin,
top: this.style.format.verticalMargin,
bottom: this.style.format.verticalMargin
}

@@ -84,3 +98,3 @@ });

if (date) {
this.styledText(date, { font: EFont.NORM, fontSize: 12, fillColor: this.colorDisabled }, { align: 'center' });
this.styledText(date, { font: EFont.NORM, fontSize: 12, fillColor: this.style.color.secondary }, { align: 'center' });
}

@@ -112,3 +126,3 @@ }

const doc = this.doc;
this.styledText(str, { font: EFont.BOLD, fontSize: this.baseFontSize + 4 - level * 2, lineGap: this.headerGap - level * 3 }, { destination: anchor });
this.styledText(str, { fillColor: this.style.color.headers, font: EFont.BOLD, fontSize: this.style.font.baseSize + 4 - level * 2, lineGap: this.headerGap - level * 3 }, { destination: anchor });
let newOutline;

@@ -144,6 +158,6 @@ const outlinesLen = this.docOutlines.length;

subHeader(str) {
this.styledText(str, { font: EFont.BOLD, fontSize: this.baseFontSize, lineGap: this.subHeaderGap });
this.styledText(str, { fillColor: this.style.color.subHeaders, font: EFont.BOLD, fontSize: this.style.font.baseSize, lineGap: this.subHeaderGap });
}
indentStart() {
this.pushStyle({ leftMargin: this.indentStep });
this.pushStyle({ leftMargin: this.style.format.indentStep });
return this;

@@ -164,3 +178,3 @@ }

description(str, options) {
this.styledText(str, { fillColor: this.colorDisabled }, options);
this.styledText(str, { fillColor: this.style.color.secondary }, options);
}

@@ -182,11 +196,11 @@ dataFields(dataFields) {

dataFields.forEach((field) => {
var _a, _b, _c, _d;
var _a, _b, _c, _d, _e;
const fieldName = `${field.name}${((_a = field.required) !== null && _a !== void 0 ? _a : true) ? '' : '?'}`;
const fieldType = (_b = field.type) === null || _b === void 0 ? void 0 : _b.text;
const fieldType = ((_b = field.type) === null || _b === void 0 ? void 0 : _b.text) ? `${(_c = field.type) === null || _c === void 0 ? void 0 : _c.text};` : undefined;
this.text(fieldName, { continued: fieldType ? true : false });
if (fieldType) {
this.text(': ', { continued: true });
this.styledText(`${fieldType};`, { fillColor: this.colorAccent }, {
goTo: (_c = field.type) === null || _c === void 0 ? void 0 : _c.anchor,
underline: ((_d = field.type) === null || _d === void 0 ? void 0 : _d.anchor) ? true : false
this.styledText(fieldType, { fillColor: this.style.color.types }, {
goTo: (_d = field.type) === null || _d === void 0 ? void 0 : _d.anchor,
underline: ((_e = field.type) === null || _e === void 0 ? void 0 : _e.anchor) ? true : false
});

@@ -197,3 +211,6 @@ }

let nameAndType = fieldName + (fieldType ? `: ${fieldType}` : '');
this.styledText(`// ${field.description}`, { fillColor: this.colorDisabled }, { x: origX + 12, indent: this.doc.widthOfString(nameAndType) });
this.styledText(` // ${field.description}`, { fillColor: this.style.color.secondary }, {
x: origX + this.style.format.indentStep,
indent: this.doc.widthOfString(nameAndType) - this.style.format.indentStep
});
}

@@ -210,3 +227,3 @@ this.doc.x = origX;

this.text('Type: ', { continued: true });
this.styledText(typeName, { fillColor: this.colorAccent });
this.styledText(typeName, { fillColor: this.style.color.types });
}

@@ -216,4 +233,4 @@ enumValues(values) {

this.doc.moveUp();
const nextLineIndent = this.doc.x + this.indentStep;
const indent = this.doc.widthOfString('Values: ') - this.indentStep;
const nextLineIndent = this.doc.x + this.style.format.indentStep;
const indent = this.doc.widthOfString('Values: ') - this.style.format.indentStep;
values.forEach((value, index, array) => {

@@ -239,3 +256,3 @@ const str = (index < array.length - 1) ? `${value}, ` : value;

if (i > 0) {
this.withStyle({ font: EFont.NORM, fontSize: 9, fillColor: this.colorDisabled }, () => {
this.withStyle({ font: EFont.NORM, fontSize: 9, fillColor: this.style.color.secondary }, () => {
if (this.pageHeaderNodes[i]) {

@@ -252,2 +269,7 @@ this.text(this.pageHeaderNodes[i], { y: origTop / 2, align: 'right' });

}
applyStyle() {
this.paraGap = this.style.font.baseSize / 3;
this.subHeaderGap = this.style.font.baseSize / 2;
this.headerGap = this.style.font.baseSize + 4;
}
setStyle(style) {

@@ -254,0 +276,0 @@ var _a;

{
"name": "apibake",
"version": "0.1.3",
"version": "0.1.4",
"description": "OpenAPI to PDF generator.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -7,14 +7,36 @@ # ApiBake

npm install -g apibake
```
npm install -g apibake
apibake <openapi.json|.yaml|folder-name> [<file-or-folder2> <file-or-folder3> ...] [<options>]
apibake <openapi.json|.yaml|folder-name> [<file-or-folder2> <file-or-folder3> ...] [<options>]
```
**Options**:
**Options:**
-out <string>: Output file.
-title <string>: Document title.
-subtitle <string>: Document sub title.
-separate-schemas: When multiple API files parsed create separate schemas section for each file.
-h: Show this help.
```
-out <string>: Output PDF file name.
-title <string>: Document title.
-subtitle <string>: Document sub title.
-separate-schemas: When multiple API files parsed, create separate schemas section for each.
-style <string>: Style to use. See -export-style.
-export-style: Save document style into style.json for editing.
-h: Show this help.
```
**Examples:**
Specify title and subtitle for your PDF:
```
apibake openapi.json -title 'REST API Spec' -subtitle 'created by ApiBake'
```
Combine several OpenAPI specs into one PDF:
```
apibake api1.json api2.yaml -title 'REST API Spec'
```
# MIT License

@@ -21,0 +43,0 @@

@@ -19,2 +19,4 @@ #!/usr/bin/env node

separateSchemas: <Arg>{ key: '-separate-schemas', value: false, help: 'When multiple API files parsed, create separate schemas section for each.' },
style: <Arg>{ key: '-style', value: '', help: 'Path to style.json. See -export-style.' },
exportStyle: <Arg>{ key: '-export-style', value: false, help: 'Save default document style into style.json for editing.' },
help: <Arg>{ key: '-h', value: false, help: 'Show this help.' },

@@ -38,3 +40,3 @@ }

if (args.help.value || argsParser.rest.length === 0) {
if (args.help.value) {
printUsageHelp();

@@ -44,4 +46,24 @@ return;

let style;
if (args.style.value) {
try {
style = JSON.parse(fs.readFileSync(args.style.value as string, 'utf8'));
} catch (e) {
errorLog(`Error in ${args.style.value}: ${e}`);
return;
}
}
const outputFile = args.output.value as string;
const doc = new PdfWriter(outputFile);
const doc = new PdfWriter(outputFile, style);
if (args.exportStyle.value) {
fs.writeFileSync('style.json', JSON.stringify(doc.style, null, 2));
}
if (argsParser.rest.length === 0) {
log('No .json or .yaml files specified.\n');
return;
}
doc.addTitlePage(

@@ -48,0 +70,0 @@ args.title.value as string,

@@ -33,2 +33,22 @@ import fs from 'fs';

export class PdfWriter {
// configurable PDF style
style = {
color: {
main: '#333333',
secondary: '#6B7B8E',
types: '#8A3324',
headers: '#2A4D69',
subHeaders: '#4B86B4',
},
font: {
baseSize: 10,
},
format: {
indentStep: 12,
horizontalMargin: 70,
verticalMargin: 50
}
}
private doc;

@@ -51,27 +71,21 @@

private colorMain = 'black';
private colorAccent = 'blue';
private colorDisabled = 'grey';
// calculated in applyStyle()
private paraGap = 0;
private subHeaderGap = 0;
private headerGap = 0;
private baseFontSize = 10;
private paraGap = this.baseFontSize / 3;
private subHeaderGap = this.baseFontSize / 2;
private headerGap = this.baseFontSize + 4;
private indentStep = 12;
private margins = {
horizontal: 70,
vertical: 50
};
private baseStyle: TextStyle = {
font: EFont.NORM,
fontSize: this.baseFontSize,
fillColor: this.colorMain,
leftMargin: this.margins.horizontal,
fontSize: this.style.font.baseSize,
fillColor: this.style.color.main,
leftMargin: this.style.format.horizontalMargin,
lineGap: 0,
};
constructor(outputFilePath: string, style?: any) {
if (style) {
this.style = style; // external style
}
this.applyStyle();
constructor(outputFilePath: string) {
this.doc = new PDFDocument({

@@ -81,6 +95,6 @@ bufferPages: true,

margins: {
left: this.margins.horizontal,
right: this.margins.horizontal,
top: this.margins.vertical,
bottom: this.margins.vertical
left: this.style.format.horizontalMargin,
right: this.style.format.horizontalMargin,
top: this.style.format.verticalMargin,
bottom: this.style.format.verticalMargin
}

@@ -114,3 +128,3 @@ });

if (date) {
this.styledText(date, { font: EFont.NORM, fontSize: 12, fillColor: this.colorDisabled }, { align: 'center' });
this.styledText(date, { font: EFont.NORM, fontSize: 12, fillColor: this.style.color.secondary }, { align: 'center' });
}

@@ -149,3 +163,3 @@ }

this.styledText(str,
{ font: EFont.BOLD, fontSize: this.baseFontSize + 4 - level * 2, lineGap: this.headerGap - level * 3 },
{ fillColor: this.style.color.headers, font: EFont.BOLD, fontSize: this.style.font.baseSize + 4 - level * 2, lineGap: this.headerGap - level * 3 },
{ destination: anchor }

@@ -185,7 +199,7 @@ );

subHeader(str: string) {
this.styledText(str, { font: EFont.BOLD, fontSize: this.baseFontSize, lineGap: this.subHeaderGap });
this.styledText(str, { fillColor: this.style.color.subHeaders, font: EFont.BOLD, fontSize: this.style.font.baseSize, lineGap: this.subHeaderGap });
}
indentStart(): PdfWriter {
this.pushStyle({ leftMargin: this.indentStep });
this.pushStyle({ leftMargin: this.style.format.indentStep });
return this;

@@ -210,3 +224,3 @@ }

description(str: string, options?: TextOptions) {
this.styledText(str, { fillColor: this.colorDisabled }, options);
this.styledText(str, { fillColor: this.style.color.secondary }, options);
}

@@ -233,3 +247,3 @@

const fieldName = `${field.name}${(field.required ?? true) ? '':'?'}`
const fieldType = field.type?.text;
const fieldType = field.type?.text ? `${field.type?.text};` : undefined;
this.text(fieldName, { continued: fieldType ? true : false });

@@ -239,3 +253,3 @@

this.text(': ', { continued: true });
this.styledText(`${fieldType};`, { fillColor: this.colorAccent }, {
this.styledText(fieldType, { fillColor: this.style.color.types }, {
goTo: field.type?.anchor,

@@ -249,3 +263,6 @@ underline: field.type?.anchor ? true : false

let nameAndType = fieldName + (fieldType ? `: ${fieldType}` : '');
this.styledText(`// ${field.description}`, { fillColor: this.colorDisabled }, { x: origX + 12, indent: this.doc.widthOfString(nameAndType) });
this.styledText(` // ${field.description}`, { fillColor: this.style.color.secondary }, {
x: origX + this.style.format.indentStep,
indent: this.doc.widthOfString(nameAndType) - this.style.format.indentStep
});
}

@@ -264,3 +281,3 @@ this.doc.x = origX;

this.text('Type: ', { continued: true });
this.styledText(typeName, { fillColor: this.colorAccent });
this.styledText(typeName, { fillColor: this.style.color.types });
}

@@ -271,4 +288,4 @@

this.doc.moveUp();
const nextLineIndent = this.doc.x + this.indentStep;
const indent = this.doc.widthOfString('Values: ') - this.indentStep;
const nextLineIndent = this.doc.x + this.style.format.indentStep;
const indent = this.doc.widthOfString('Values: ') - this.style.format.indentStep;

@@ -299,3 +316,3 @@ values.forEach((value, index, array) => {

if (i > 0) {
this.withStyle({ font: EFont.NORM, fontSize: 9, fillColor: this.colorDisabled }, () => {
this.withStyle({ font: EFont.NORM, fontSize: 9, fillColor: this.style.color.secondary }, () => {
if (this.pageHeaderNodes[i]) {

@@ -315,2 +332,8 @@ this.text(this.pageHeaderNodes[i], { y: origTop / 2, align: 'right' });

private applyStyle() {
this.paraGap = this.style.font.baseSize / 3;
this.subHeaderGap = this.style.font.baseSize / 2;
this.headerGap = this.style.font.baseSize + 4;
}
private setStyle(style: TextStyle) {

@@ -317,0 +340,0 @@ this.doc.font(this.fonts[style.font ?? 0]).fontSize(style.fontSize).fillColor(style.fillColor);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc