Commit ebcf2efe authored by Panagiotis Skarvelis's avatar Panagiotis Skarvelis
Browse files

make it hybrid esm/commonjs

parent 6b8d30ad
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateAuditRecord = void 0;
const protocol_1 = __importDefault(require("./lib/protocol"));
const sequence_1 = __importDefault(require("./lib/sequence"));
const db_1 = __importDefault(require("./lib/db"));
const FileEngine_1 = __importDefault(require("./lib/FileEngine"));
/**
* @description Use this on your app to generate and log the audit record
* @coment This is the main function of the application
* @comment The audit record is stored in the database,
* @comment you can provide a custom audit record, or use the generated one
* @param auditInit - The audit record to be stored, if is empty a new one will be generated
* @param storagePath - The path where the audit record will be stored, default is the tmp directory
* @env env.HOSTIP - useful to pass the IP address of the end user automatically on docker enviroments
* @returns AuditRecord | null - The audit record generated or the one provided
*/
const generateAuditRecord = (auditInit, storagePath = "/tmp") => {
const auditUnit = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditUnit) || "gov.gr";
const auditTransactionId = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditTransactionId) || "" + (0, sequence_1.default)(storagePath + "/sequence", storagePath + "/sequence");
const auditProtocol = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditProtocol) || (0, protocol_1.default)(storagePath);
const auditTransactionDate = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditTransactionDate) || new Date().toISOString().split('.')[0] + "Z";
const auditUserIp = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditUserIp) || process.env.HOSTIP || "127.0.0.1";
const auditUserId = (auditInit === null || auditInit === void 0 ? void 0 : auditInit.auditUserId) || "system";
const auditRecord = {
auditUnit,
auditTransactionId,
auditProtocol,
auditTransactionDate,
auditUserIp,
auditUserId
};
const dbEngine = new db_1.default(new FileEngine_1.default(storagePath));
try {
return dbEngine.put(auditRecord);
}
catch (error) {
const err = error;
console.log(err.code, err.message);
return null;
}
};
exports.generateAuditRecord = generateAuditRecord;
exports.default = exports.generateAuditRecord;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _FileEngine_path;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileEngine = void 0;
//Use File System as DB storage
const fs_1 = __importDefault(require("fs"));
/**
* @description AuditEngine implementation
* @note This class is used to implement the methods that must be implemented by the AuditEngine
* @class FileEngine
* @implements AuditEngine
* @param {string} path - path to store the records
*/
class FileEngine {
constructor(path) {
_FileEngine_path.set(this, void 0);
__classPrivateFieldSet(this, _FileEngine_path, path, "f");
}
/**
* @description Store a record in the database
* @param {AuditRecord} record - record to be stored
* @returns {AuditRecord} - the record stored
* @memberof FileEngine
* @method put
*/
put(record) {
const data = JSON.stringify(record, null, 2);
try {
fs_1.default.writeFileSync(__classPrivateFieldGet(this, _FileEngine_path, "f") + '/record-' + record.auditTransactionId + '.json', data);
return record;
}
catch (error) {
throw error;
}
}
/**
* @description Get a record from the database
* @param auditTransactionId
* @returns {AuditRecord}
* @memberof FileEngine
* @method get
*/
get(auditTransactionId) {
try {
const data = fs_1.default.readFileSync(__classPrivateFieldGet(this, _FileEngine_path, "f") + '/record-' + auditTransactionId + '.json', 'utf8');
return JSON.parse(data);
}
catch (error) {
throw error;
}
}
}
exports.FileEngine = FileEngine;
_FileEngine_path = new WeakMap();
exports.default = FileEngine;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.db = void 0;
/**
* @description AuditEngine implementation
* @note This class uses AuditEngine implemetations, look at FileEngine.ts for an example
* @class db
* @param {AuditEngine} engine - AuditEngine implementation
*/
class db {
constructor(engine) {
this.engine = engine;
}
/**
* @description Store a record in the database
* @param record
* @returns AuditRecord
* @memberof db
* @method put
*/
put(record) {
if (!record.auditTransactionId)
throw new Error("record.auditTransactionId is required");
return this.engine.put(record);
}
/**
* @description Get a record from the database
* @param auditTransactionId
* @returns AuditRecord
* @memberof db
* @method get
*/
get(auditTransactionId) {
if (!auditTransactionId)
throw new Error("auditTransactionId is required");
return this.engine.get(auditTransactionId);
}
}
exports.db = db;
exports.default = db;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sequence_1 = __importDefault(require("./sequence"));
/**
* Generate a new protocol number
* in the format sequence/date
* each day a new sequence is generated
* @param protocol_path
* @returns string
*/
const protocol = (protocol_path) => {
const protocol_date = new Date().toISOString().split('T')[0];
const path = `${protocol_path}/${protocol_date}.protocol.sequence`;
const protocol_sequence = (0, sequence_1.default)(path, path); //Protocol starts from 1 each day.
let pn = protocol_sequence + "/" + protocol_date;
return pn;
};
exports.default = protocol;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const LOCK_FILE_PATH = "/tmp/sequence";
const SEQUENCE_FILE = "/tmp/sequence";
/**
* timeout for lock file, we will try to delete it after timeout, in case was not deleted on previous run
* you can increase this value if you have a lot of processes running on the same machine
* @type {number}
* @env TIMEOUT_LOCK_FILE
*/
const TIMEOUT_LOCK_FILE = (process.env.TIMEOUT_LOCK_FILE ? ~~process.env.TIMEOUT_LOCK_FILE : undefined) || 10000;
/**
* set delay in ms
* @param ms
* @returns Promise<void>
*/
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
/**
* create a lock file
* @param path
* @param timeout
* @returns Promise<number>
*/
const lockFile = (path, timeout = 0) => __awaiter(void 0, void 0, void 0, function* () {
//TODO if the file exists for long time have to delete it
// because probably something is broken on previous run
// this works but may be not the best solution
if (timeout++ > TIMEOUT_LOCK_FILE) {
console.log(timeout, " times loop, try to unlock");
yield delay(1000);
unlockFile(path);
}
;
const lockPath = `${path}.lock`;
try {
return fs_1.default.openSync(lockPath, fs_1.default.constants.O_CREAT | fs_1.default.constants.O_EXCL | fs_1.default.constants.O_RDWR);
}
catch (error) {
const err = error;
if (err.code !== "EEXIST")
console.log(err.message);
return lockFile(path, timeout);
}
});
/**
* unlink the lock file
* @param path
* @param timeout
* @returns Promise<void>
*/
const unlockFile = (path, timeout = 0) => __awaiter(void 0, void 0, void 0, function* () {
const lockPath = `${path}.lock`;
if (timeout++ > TIMEOUT_LOCK_FILE) {
console.log(timeout, " times loop, unlock exit");
return;
}
;
try {
return fs_1.default.unlinkSync(lockPath);
}
catch (error) {
const err = error;
if (err.code === "ENOENT") {
return;
}
else {
console.log(err.message);
yield delay(500);
return unlockFile(path, timeout++);
}
}
});
/**
* update the sequence number on giveb sequence file
* @param seqfile
* @param lockfile
* @returns number
*/
const sequence = (seqfile = "", lockfile = "") => {
let SEQF = SEQUENCE_FILE;
let LFP = LOCK_FILE_PATH;
if (seqfile !== "")
SEQF = seqfile;
if (lockfile !== "")
LFP = lockfile;
if (!fs_1.default.existsSync(SEQF)) {
fs_1.default.writeFileSync(SEQF, "0");
}
const abla = lockFile(LFP);
let seq = ~~fs_1.default.readFileSync(SEQF); //Read as integer ~~ is synonimus for parseInt
fs_1.default.writeFileSync(SEQF, "" + ++seq);
const oubla = unlockFile(LFP);
return seq;
};
exports.default = sequence;
{
"type": "commonjs"
}
import { AuditRecord } from './interfaces/index';
/**
* @description Use this on your app to generate and log the audit record
* @coment This is the main function of the application
* @comment The audit record is stored in the database,
* @comment you can provide a custom audit record, or use the generated one
* @param auditInit - The audit record to be stored, if is empty a new one will be generated
* @param storagePath - The path where the audit record will be stored, default is the tmp directory
* @env env.HOSTIP - useful to pass the IP address of the end user automatically on docker enviroments
* @returns AuditRecord | null - The audit record generated or the one provided
*/
export declare const generateAuditRecord: (auditInit: AuditRecord | undefined, storagePath?: string) => AuditRecord | null;
export default generateAuditRecord;
export { AuditRecord };
/**
* @description Record to be stored in the database
* @note Must be fullfiled completely, even if it is empty
*/
export declare type AuditRecord = {
auditUnit?: string;
auditTransactionId?: string;
auditProtocol?: string;
auditTransactionDate?: string;
auditUserIp?: string;
auditUserId?: string;
};
/**
* @description AuditEngine interface
* @note This interface is used to define the methods that must be implemented by the AuditEngine look at FileEngine.ts for an example
* @interface AuditEngine
*/
export interface AuditEngine {
put: (record: AuditRecord) => AuditRecord;
get: (auditTransactionId: string) => AuditRecord;
}
/**
* @description FileSystem errors
*/
export declare type FS_ERROR = {
code: string;
message: string;
};
import { AuditRecord, AuditEngine } from '../interfaces/index';
/**
* @description AuditEngine implementation
* @note This class is used to implement the methods that must be implemented by the AuditEngine
* @class FileEngine
* @implements AuditEngine
* @param {string} path - path to store the records
*/
export declare class FileEngine implements AuditEngine {
#private;
constructor(path: string);
/**
* @description Store a record in the database
* @param {AuditRecord} record - record to be stored
* @returns {AuditRecord} - the record stored
* @memberof FileEngine
* @method put
*/
put(record: AuditRecord): AuditRecord;
/**
* @description Get a record from the database
* @param auditTransactionId
* @returns {AuditRecord}
* @memberof FileEngine
* @method get
*/
get(auditTransactionId: string): AuditRecord;
}
export default FileEngine;
import { AuditRecord, AuditEngine } from '../interfaces/index';
/**
* @description AuditEngine implementation
* @note This class uses AuditEngine implemetations, look at FileEngine.ts for an example
* @class db
* @param {AuditEngine} engine - AuditEngine implementation
*/
export declare class db {
engine: AuditEngine;
constructor(engine: AuditEngine);
/**
* @description Store a record in the database
* @param record
* @returns AuditRecord
* @memberof db
* @method put
*/
put(record: AuditRecord): AuditRecord;
/**
* @description Get a record from the database
* @param auditTransactionId
* @returns AuditRecord
* @memberof db
* @method get
*/
get(auditTransactionId: string): AuditRecord;
}
export default db;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment