New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

enonic-wizardry

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

enonic-wizardry - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

bin/xml-to-ts.d.ts

145

bin/xml-to-ts.js
"use strict";
exports.__esModule = true;
var change_case_1 = require("change-case");
Object.defineProperty(exports, "__esModule", { value: true });
var commander = require("commander");

@@ -8,41 +7,77 @@ var fs = require("fs");

var xmltools = require("./src/xmltools");
var STDOUT_FILENO = 1; // standard output file descriptor
function generateInterface(filename) {
var interfaceName = path.basename(change_case_1.pascalCase(filename.substring(0, filename.lastIndexOf("."))));
var xml = fs.readFileSync(filename, "utf-8");
return xmltools.createInterface(interfaceName, xml);
var generator = xmltools.NewInterfaceGenerator();
function generateInterface(xmlFilename, tsFilename) {
var interfaceName = xmltools.generateInterfaceName(tsFilename);
var xml = fs.readFileSync(xmlFilename, "utf-8");
return generator.createInterface(interfaceName, xml);
}
exports.generateInterface = generateInterface;
function openTsFile(filename, flags) {
filename = filename.substring(0, filename.lastIndexOf(".")) + ".ts";
return fs.openSync(filename, flags);
// map<directory, suffix>
var directorySuffix = {
parts: "-part-config",
pages: "-page-config",
site: "-config"
};
// tries to avoid conflicting filenames
function getTsFilename(filename) {
var dirname = path.dirname(filename);
var basename = path.basename(filename, path.extname(filename));
var closestDir = path
.dirname(filename)
.split(path.sep)
.reverse()
.slice(0, 2)
.find(function (p) { return directorySuffix[p]; });
var suffix = closestDir ? directorySuffix[closestDir] : "";
return dirname + "/" + basename + suffix + ".ts";
}
function replaceFileExtension(newExtension) {
return function (filename) {
return filename.substring(0, filename.length - path.extname(filename).length) +
newExtension;
};
}
// XML-files in these directories will generate TypeScript interfaces when
// using the --enonic-xml flag.
var directories = [
"./src/main/resources/site/site.xml",
"./src/main/resources/site/content-types",
"./src/main/resources/site/parts",
"./src/main/resources/site/pages"
"src/main/resources/site/site.xml",
"src/main/resources/site/content-types",
"src/main/resources/site/parts",
"src/main/resources/site/pages"
];
function getEnonicXmlFiles() {
var files = [];
var _loop_1 = function (dir) {
dir = path.resolve(dir);
if (!fs.existsSync(dir)) {
return "continue";
}
var mixinDir = "src/main/resources/site/mixins";
function getEnonicXmlFiles(projectRootDir) {
return directories
.map(function (dir) { return path.join(projectRootDir, dir); })
.map(function (dir) { return path.resolve(dir); })
.filter(function (dir) { return fs.existsSync(dir); })
.reduce(function (result, dir) {
var stat = fs.statSync(dir);
if (stat.isFile()) {
files.push(dir);
}
else if (stat.isDirectory()) {
files.push.apply(files, fs.readdirSync(dir).map(function (filename) { return dir + filename; }));
}
return result
.concat(stat.isFile() ? [dir] : [])
.concat(stat.isDirectory() ? listXmlFiles(dir) : []);
}, []);
}
function listXmlFiles(dir) {
return listFiles(dir).filter(function (file) { return path.extname(file) === ".xml"; });
}
function listFiles(dir) {
return fs
.readdirSync(dir)
.map(function (file) { return path.join(dir, file); })
.reduce(function (result, dir) {
var stat = fs.statSync(dir);
return result
.concat(stat.isFile() ? [dir] : [])
.concat(stat.isDirectory() ? listFiles(dir) : []);
}, []);
}
function consoleWriter(_) {
return console.log;
}
function fileWriter(filename) {
return function (output) {
var fd = fs.openSync(filename, "w+");
fs.writeSync(fd, Buffer.from(output, "utf8"));
fs.closeSync(fd);
};
for (var _i = 0, directories_1 = directories; _i < directories_1.length; _i++) {
var dir = directories_1[_i];
_loop_1(dir);
}
return files;
}

@@ -53,33 +88,45 @@ function exit(message) {

}
function collect(next, prev) {
return prev.concat([next]);
}
function command(argv) {
var cmd = new commander.Command();
cmd
.option("--enonic-xml", "Use the default Enonic XML-files")
.option("--write-to-file", "Write to .ts files instead of to stdout")
.option("--project <dir>", "generate all xml files for the specified Enonic project")
.option("--write-to-file", "write to .ts files instead of stdout")
.option("-v, --verbose")
.option("--mixin <file>", "add a file as a mixin", collect, [])
.command("<cmd> [options] [files...]");
cmd.parse(argv);
var writeToFile = cmd.writeToFile === true;
var files = cmd.enonicXml ? getEnonicXmlFiles() : cmd.args;
var projectMixins = cmd.project ? listXmlFiles(path.join(cmd.project, mixinDir)) : [];
var mixinFiles = cmd.mixin.concat(projectMixins);
for (var _i = 0, mixinFiles_1 = mixinFiles; _i < mixinFiles_1.length; _i++) {
var filename = mixinFiles_1[_i];
var xml = fs.readFileSync(filename, "utf8");
generator.addMixin(filename, xml);
}
var rename = cmd.project ? getTsFilename : replaceFileExtension(".ts");
var write = cmd.writeToFile ? fileWriter : consoleWriter;
var files = cmd.project ? getEnonicXmlFiles(cmd.project) : cmd.args;
if (files.length === 0) {
exit("No files");
}
var notFiles = files.filter(function (f) { return !fs.existsSync(f); });
var notFiles = files.filter(function (file) { return !fs.existsSync(file); });
if (notFiles.length > 0) {
var fileList = notFiles.map(function (f) { return " - " + f; }).join("\n");
var fileList = notFiles.map(function (file) { return " - " + file; }).join("\n");
exit("Files do not exist: \n" + fileList);
}
for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
var filename = files_1[_i];
for (var _a = 0, files_1 = files; _a < files_1.length; _a++) {
var xmlFilename = files_1[_a];
if (cmd.verbose) {
console.error(xmlFilename);
}
try {
var ts = generateInterface(filename);
var buf = Buffer.from(ts, "utf8");
var output = !writeToFile ? STDOUT_FILENO : openTsFile(filename, "w+");
fs.writeSync(output, buf);
if (writeToFile) {
fs.closeSync(output);
}
var tsFilename = rename(xmlFilename);
var tsInterface = generateInterface(xmlFilename, tsFilename);
write(tsFilename)(tsInterface);
}
catch (err) {
if (err === xmltools.MissingFieldNameError) {
exit(filename + ": " + err);
exit(xmlFilename + ": " + err);
}

@@ -86,0 +133,0 @@ throw err;

@@ -1,2 +0,1 @@

import { pascalCase } from "change-case";
import * as commander from "commander";

@@ -7,44 +6,92 @@ import * as fs from "fs";

const STDOUT_FILENO = 1; // standard output file descriptor
const generator = xmltools.NewInterfaceGenerator();
export function generateInterface(filename: string): string {
const interfaceName = path.basename(
pascalCase(filename.substring(0, filename.lastIndexOf(".")))
);
const xml = fs.readFileSync(filename, "utf-8");
return xmltools.createInterface(interfaceName, xml);
function generateInterface(xmlFilename: string, tsFilename: string) {
const interfaceName = xmltools.generateInterfaceName(tsFilename);
const xml = fs.readFileSync(xmlFilename, "utf-8");
return generator.createInterface(interfaceName, xml);
}
function openTsFile(filename: string, flags: string): number {
filename = filename.substring(0, filename.lastIndexOf(".")) + ".ts";
return fs.openSync(filename, flags);
// map<directory, suffix>
const directorySuffix: { [key: string]: string } = {
parts: "-part-config",
pages: "-page-config",
site: "-config"
};
// tries to avoid conflicting filenames
function getTsFilename(filename: string): string {
const dirname = path.dirname(filename);
const basename = path.basename(filename, path.extname(filename));
const closestDir = path
.dirname(filename)
.split(path.sep)
.reverse()
.slice(0, 2)
.find(p => directorySuffix[p]);
const suffix = closestDir ? directorySuffix[closestDir] : "";
return `${dirname}/${basename}${suffix}.ts`;
}
function replaceFileExtension(
newExtension: string
): (filename: string) => string {
return filename =>
filename.substring(0, filename.length - path.extname(filename).length) +
newExtension;
}
// XML-files in these directories will generate TypeScript interfaces when
// using the --enonic-xml flag.
const directories = [
"./src/main/resources/site/site.xml",
"./src/main/resources/site/content-types",
"./src/main/resources/site/parts",
"./src/main/resources/site/pages"
"src/main/resources/site/site.xml",
"src/main/resources/site/content-types",
"src/main/resources/site/parts",
"src/main/resources/site/pages"
];
const mixinDir = "src/main/resources/site/mixins";
function getEnonicXmlFiles() {
const files = [];
for (let dir of directories) {
dir = path.resolve(dir);
if (!fs.existsSync(dir)) {
continue;
}
function getEnonicXmlFiles(projectRootDir: string): Array<string> {
return directories
.map(dir => path.join(projectRootDir, dir))
.map(dir => path.resolve(dir))
.filter(dir => fs.existsSync(dir))
.reduce((result: Array<string>, dir: string) => {
const stat = fs.statSync(dir);
return result
.concat(stat.isFile() ? [dir] : [])
.concat(stat.isDirectory() ? listXmlFiles(dir) : []);
}, []);
}
const stat = fs.statSync(dir);
if (stat.isFile()) {
files.push(dir);
} else if (stat.isDirectory()) {
files.push(...fs.readdirSync(dir).map(filename => dir + filename));
}
}
return files;
function listXmlFiles(dir: string): Array<string> {
return listFiles(dir).filter(file => path.extname(file) === ".xml");
}
function listFiles(dir: string): Array<string> {
return fs
.readdirSync(dir)
.map(file => path.join(dir, file))
.reduce((result: Array<string>, dir) => {
const stat = fs.statSync(dir);
return result
.concat(stat.isFile() ? [dir] : [])
.concat(stat.isDirectory() ? listFiles(dir) : []);
}, []);
}
function consoleWriter(_: string): (output: string) => void {
return console.log;
}
function fileWriter(filename: string): (output: string) => void {
return (output: string) => {
const fd = fs.openSync(filename, "w+");
fs.writeSync(fd, Buffer.from(output, "utf8"));
fs.closeSync(fd);
};
}
function exit(message: string) {

@@ -55,8 +102,17 @@ console.error(message);

function command(argv: string[]) {
function collect<T>(next: T, prev: Array<T>) {
return prev.concat([next]);
}
function command(argv: Array<string>) {
const cmd = new commander.Command();
cmd
.option("--enonic-xml", "Use the default Enonic XML-files")
.option("--write-to-file", "Write to .ts files instead of to stdout")
.option(
"--project <dir>",
"generate all xml files for the specified Enonic project"
)
.option("--write-to-file", "write to .ts files instead of stdout")
.option("-v, --verbose")
.option("--mixin <file>", "add a file as a mixin", collect, [])
.command("<cmd> [options] [files...]");

@@ -66,5 +122,14 @@

const writeToFile = cmd.writeToFile === true;
const projectMixins = cmd.project ? listXmlFiles(path.join(cmd.project, mixinDir)) : [];
const mixinFiles = cmd.mixin.concat(projectMixins);
const files = cmd.enonicXml ? getEnonicXmlFiles() : cmd.args;
for (const filename of mixinFiles) {
const xml = fs.readFileSync(filename, "utf8");
generator.addMixin(filename, xml);
}
const rename = cmd.project ? getTsFilename : replaceFileExtension(".ts");
const write = cmd.writeToFile ? fileWriter : consoleWriter;
const files = cmd.project ? getEnonicXmlFiles(cmd.project) : cmd.args;
if (files.length === 0) {

@@ -74,21 +139,19 @@ exit("No files");

const notFiles = files.filter(f => !fs.existsSync(f));
const notFiles = files.filter(file => !fs.existsSync(file));
if (notFiles.length > 0) {
const fileList = notFiles.map(f => ` - ${f}`).join("\n");
const fileList = notFiles.map(file => ` - ${file}`).join("\n");
exit(`Files do not exist: \n${fileList}`);
}
for (const filename of files) {
for (const xmlFilename of files) {
if (cmd.verbose) {
console.error(xmlFilename);
}
try {
const ts = generateInterface(filename);
const buf = Buffer.from(ts, "utf8");
const output = !writeToFile ? STDOUT_FILENO : openTsFile(filename, "w+");
fs.writeSync(output, buf);
if (writeToFile) {
fs.closeSync(output);
}
const tsFilename = rename(xmlFilename);
const tsInterface = generateInterface(xmlFilename, tsFilename);
write(tsFilename)(tsInterface);
} catch (err) {
if (err === xmltools.MissingFieldNameError) {
exit(`${filename}: ${err}`);
exit(`${xmlFilename}: ${err}`);
}

@@ -95,0 +158,0 @@ throw err;

{
"name": "enonic-wizardry",
"version": "0.0.6",
"version": "0.0.7",
"description": "Functional utility library for Enonic XP",

@@ -9,5 +9,5 @@ "main": "lib/index.js",

"scripts": {
"clean": "rimraf lib/* es6/*",
"clean": "rimraf lib/* es6/* bin/*",
"build": "npm run clean && tsc && tsc -p tsconfig.es6.json && npm run build:cli",
"build:cli": "tsc -outDir bin cli/xml-to-ts.ts",
"build:cli": "tsc -p tsconfig.cli.json",
"test": "jest",

@@ -31,3 +31,2 @@ "watch:test": "jest --watch"

"dependencies": {
"@types/xmldom": "^0.1.29",
"change-case": "^3.1.0",

@@ -41,2 +40,3 @@ "commander": "^3.0.1",

"devDependencies": {
"@types/xmldom": "^0.1.29",
"@types/jest": "^24.0.18",

@@ -43,0 +43,0 @@ "@types/node": "^12.7.4",

@@ -6,1 +6,36 @@ # Enonic Wizardry

Functional utility library for Enonic XP
## CLI
`xml-to-ts.js` is a command line utility that can generate TypeScript interfaces
for Sites, ContentTypes, Parts, and Pages from XML-files.
- Build it: `npm run build` or `npm run build:cli`
- Run it from the command line: `node bin/xml-to-ts.js my-xml-file.xml`
### Gradle
`xml-to-ts.js` can be run automatically as part of the`enonic project deploy`
process. First, add the dependency with `npm install enonic-wizardry`, and then
add a task to `build.gradle`, for example:
```groovy
task generateTypeScriptInterfaces( type: NodeTask, dependsOn: npmInstall ) {
description = 'Generate TypeScript interfaces'
environment = [ 'NODE_ENV': nodeEnvironment() ]
args = [ '--project', '.', '--write-to-file' ]
script = file( 'node_modules/enonic-wizardry/bin/xml-to-ts.js' )
}
```
To run the task as part of the deploy process, add it to the `jar` block:
```
jar {
// ... other dependencies
generateTypeScriptInterfaces
// ...
}
```
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