UNPKG

4.02 kBJavaScriptView Raw
1/*!
2Kettle File DataSource
3
4Copyright 2012-2013 OCAD University
5Copyright 2016 OCAD University
6
7Licensed under the New BSD license. You may not use this file except in
8compliance with this License.
9
10You may obtain a copy of the License at
11https://github.com/fluid-project/kettle/blob/master/LICENSE.txt
12*/
13
14"use strict";
15
16var fluid = fluid || require("infusion"),
17 kettle = fluid.registerNamespace("kettle"),
18 fs = require("fs");
19
20fluid.require("querystring", require, "node.querystring");
21
22fluid.registerNamespace("kettle.dataSource");
23
24/**** FILE DATASOURCE SUPPORT ****/
25
26fluid.defaults("kettle.dataSource.file", {
27 gradeNames: ["kettle.dataSource"],
28 readOnlyGrade: "kettle.dataSource.file",
29 invokers: {
30 getImpl: {
31 funcName: "kettle.dataSource.file.handle",
32 args: ["{that}", "{arguments}.0", "{arguments}.1"] // options, directModel
33 }
34 }
35});
36
37fluid.defaults("kettle.dataSource.file.writable", {
38 gradeNames: ["kettle.dataSource.writable"],
39 invokers: {
40 setImpl: {
41 funcName: "kettle.dataSource.file.handle",
42 args: ["{that}", "{arguments}.0", "{arguments}.1", "{arguments}.2"] // options, directModel, model
43 }
44 }
45});
46
47/** Central strategy point for all file-system backed DataSource operations (both read and write).
48 * Accumulates options to be sent to the underlying node.js `readFile` or `writeFile` primitives, collects and interprets the
49 * results back into promise resolutions.
50 * @param that {Component} The DataSource itself
51 * @param requestOptions {Object} A merged form of the options sent to the top-level `dataSource.get` method together with relevant
52 * static options configured on the component
53 * @param directModel {Object} The `directModel` argument sent to top-level `dataSource.get/set`
54 * @param model {String} The `model` argument sent to top-level `dataSource.get/set` after it has been pushed through the transform chain
55 */
56
57kettle.dataSource.file.handle = function (that, requestOptions, directModel, model) {
58 if (!that.options.path) {
59 fluid.fail("Cannot operate file dataSource ", that, " without an option named \"path\"");
60 }
61 var fileName = kettle.dataSource.URL.resolveUrl(that.options.path, that.options.termMap, directModel, true);
62 var promise = fluid.promise(),
63 method = "readFile",
64 operation = requestOptions.operation,
65 fsCallback = function (error, readData) {
66 /* istanbul ignore if - don't know how to reliably and portably trigger file error that is not "not found" */
67 if (error) {
68 promise.reject({
69 message: error.message
70 });
71 } else {
72 promise.resolve(requestOptions.operation === "set" ? undefined : readData);
73 }
74 },
75 args = [fileName, that.options.charEncoding];
76 promise.accumulateRejectionReason = function (originError) {
77 return kettle.upgradeError(originError, " while " + (operation === "set" ? "writing" : "reading") + " file " + fileName);
78 };
79 if (operation === "set") {
80 method = "writeFile";
81 args.splice(1, 0, model);
82 } else {
83 if (!fs.existsSync(fileName)) {
84 if (requestOptions.notFoundIsEmpty) {
85 promise.resolve(undefined);
86 } else {
87 promise.reject({
88 isError: true,
89 message: "File " + fileName + " was not found",
90 statusCode: 404
91 });
92 }
93 return promise;
94 }
95 }
96 args.push(kettle.wrapCallback(fsCallback));
97 fs[method].apply(null, args);
98 return promise;
99};
100
101/** A mixin grade for `kettle.dataSource.file` which automatically expands any %terms corresponding to module names registered in Infusion's module database */
102
103fluid.defaults("kettle.dataSource.file.moduleTerms", {
104 gradeNames: "kettle.dataSource.file",
105 termMap: "@expand:fluid.module.terms()"
106});