Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 1x 5x 5x 5x | let fs = require("fs");
let path = require("path");
let mkdirp = require("mkdirp");
import * as _ from "lodash";
import { IArgdownRequest, IArgdownResponse, IHtmlRequest, IArgdownLogger, ArgdownPluginError } from "@argdown/core";
import { IAsyncArgdownPlugin, IAsyncRequestHandler } from "../IAsyncArgdownPlugin";
import { IFileRequest } from "../IFileRequest";
export interface IFileNameProvider {
(settings: ISaveAsSettings, request: IArgdownRequest, response: IArgdownResponse): string;
}
export interface ISaveAsSettings {
dataKey?: string;
extension?: string;
outputDir?: string;
isRequestData?: boolean;
fileName?: string | IFileNameProvider;
}
export interface ISaveAsRequest extends IFileRequest, IHtmlRequest {
saveAs?: ISaveAsSettings;
}
export class SaveAsFilePlugin implements IAsyncArgdownPlugin {
name = "SaveAsFilePlugin";
defaults: ISaveAsSettings;
constructor(config: ISaveAsSettings) {
this.defaults = _.defaultsDeep({}, config, {
dataKey: "test",
extension: ".txt",
outputDir: "./output"
});
}
// there can be several instances of this plugin in the same ArgdownApplication
// Because of this, we can not add the instance default settings to the request object as in other plugins
// Instead we have to add it each time the getSettings method is called to avoid keeping request specific state
getSettings(request: IArgdownRequest): ISaveAsSettings {
const r = <ISaveAsRequest>request;
let settings = r.saveAs || {};
settings = _.defaultsDeep({}, settings, this.defaults);
return settings;
}
runAsync: IAsyncRequestHandler = async (request, response, logger) => {
const saveAsRequest = <ISaveAsRequest>request;
const settings = this.getSettings(request);
if (!settings.dataKey) {
throw new ArgdownPluginError(this.name, "No data key.");
}
let fileContent: string | undefined = !settings.isRequestData
? (<any>response)[settings.dataKey!]
: (<any>request)[settings.dataKey!];
if (fileContent === undefined) {
throw new ArgdownPluginError(this.name, "No content to save.");
}
if (!_.isString(fileContent)) {
throw new ArgdownPluginError(this.name, "Content is not a string.");
}
if (_.isEmpty(fileContent)) {
throw new ArgdownPluginError(this.name, "Data field is empty string.");
}
const dataSettings = !settings.isRequestData && settings.dataKey ? (<any>request)[settings.dataKey] : null;
let fileName = "default";
let outputDir = settings.outputDir;
if (saveAsRequest.outputDir) {
fileName = this.getFileName(saveAsRequest.outputDir);
outputDir = path.dirname(saveAsRequest.outputDir);
} else if (dataSettings && dataSettings.outputDir) {
fileName = this.getFileName(dataSettings.outputDir);
outputDir = path.dirname(dataSettings.outputDir);
} else if (_.isFunction(settings.fileName)) {
fileName = settings.fileName.call(settings, request, response);
} else if (_.isString(settings.fileName)) {
fileName = settings.fileName;
} else if (saveAsRequest.inputPath) {
fileName = this.getFileName(saveAsRequest.inputPath);
}
if (dataSettings && dataSettings.outputDir) {
outputDir = dataSettings.outputDir;
}
if (outputDir && settings.extension) {
await this.saveAsFile(fileContent, outputDir, fileName, settings.extension, logger);
}
};
getFileName(file: string): string {
let extension = path.extname(file);
return path.basename(file, extension);
}
async saveAsFile(data: string, outputDir: string, fileName: string, extension: string, logger: IArgdownLogger) {
let absoluteOutputDir = path.resolve(process.cwd(), outputDir);
await new Promise((resolve, reject) => {
mkdirp(absoluteOutputDir, function(err: Error) {
if (err) {
reject(err);
}
resolve();
});
});
await new Promise((resolve, reject) => {
fs.writeFile(absoluteOutputDir + "/" + fileName + extension, data, function(err: Error) {
if (err) {
reject(err);
}
logger.log("verbose", "Saved " + absoluteOutputDir + "/" + fileName + extension);
resolve();
});
});
}
}
|