
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
ojx is an extension to OJET (Oracle JET) - MVVM
npm i ojx
or
yarn add ojx
Add the following block in project's src/js/path_mapping.json after "ojs" block.
"ojx": {
"cwd": "node_modules/ojx",
"debug": {
"src": ["dist/**"],
"path": "libs/ojx",
"pathSuffix": "/dist'"
},
"release": {
"src": ["dist/**"],
"path": "libs/ojx",
"pathSuffix": "/dist'"
}
},
Import ojx AMD modules in src/js/appController.js or src/js/root.js or any viewModel.js
define(['knockout', 'jquery',
..., ..., ..., ...,
'ojx/bundle', // load all modules
'ojx/elements', // for all ojx-elements: <ojx-bind-html>, <ojx-module>, ...
'ojx/bind-html', // for <ojx-bind-html> only
'ojx/module', // for <ojx-module> only
'ojx/utils', // for ojet util functions
'ojx/dom', // for DOM util functions
'ojx/object', // for object util functions
'ojx/type', // for type util functions
'ojx/data-time', // for date-time util functions
'ojx/storage', // for multi-user sessionStorage and localStorage
'ojx/file-system', // for file system util functions
'ojx/libs', // to export ko, jquery($) to global
], function (ko, $, ...) {
});
ojx/elementsNOTE: you need to import 'ojx/elements' or 'ojx/bind-html', 'ojx/module' in viewModel.js. Refer import guide in Usage section above.
In views/*.html
... ... ...
<!-- <ojx-bind-html> for <oj-bind-dom> -->
<ojx-bind-html value="<strong>HTML</strong> text"></ojx-bind-html>
<ojx-bind-html value="[[sectionTitle]]"></ojx-bind-html>
<!-- optionally use voidxss attribute to void XSS content in value -->
<ojx-bind-html value="[[sectionTitle]]" voidxss></ojx-bind-html>
... ... ...
<!-- <ojx-module> simplified wrapper for <oj-module> -->
<ojx-module
path="customers/view-customer"
data="[[customerRecord]]"
render="[[toggleModuleRender]]"></ojx-module>
... ... ...
ojx/utils
// for view.html: <oj-bind-dom config="[[ titleConfig ]]"></oj-bind-dom>
// in viewModel.js
this.titleConfig = ojx.domConfig( '<strong>HTML</strong> Text' );
// ... ... ... ... ... ... ... ... ... ... ...
// for view.html: <oj-module config="[[ editCustViewConfig ]]"></oj-module>
// in viewModel.js
let moduleName = 'customers/edit-view';
let params = {
user: {
firstName: 'Donal',
lastName: 'Duck',
email: 'donald.duck@disney.com'
}
};
this.editCustViewConfig = ojx.moduleConfig( moduleName, params );
returns oj ArrayDataProvider (ojs/ojarraydataprovider) for a given source array
/**
* returns oj ArrayDataProvider (ojs/ojarraydataprovider) for a given source array
* @param {Array} srcArray - The source array
* @param {string} keyAttribute - The key attribute (e.g., 'id', 'userId', 'departmentId', 'lastUpdated')
* @param {string} sortOrder - for ascending : 'asc' | 'ascending'
* for descending: any value other than ['asc', 'ascending'] (ex., 'desc', 'descending')
* @param {string} sortBy - The key to sort by if ohter than keyAttribute (e.g., 'departmentId', 'StartDate')
* @param {string} isDateTime - is sortBy field of type Date/Time?
*/
let ojTableDataProvider1 = ojx.arrayDataProvider( srcArray, keyAttributes, sortOrder, sortBy, isDateTime );
// auto-detect key field in source array for unique-key
let ojTableDataProvider2 = ojx.arrayDataProvider( srcArray );
// use 'DepartmentId' field as key, and only indicate sort as desc - but does not sort the source array
let ojTableDataProvider3 = ojx.arrayDataProvider( srcArray, 'DepartmentId', 'desc' );
// use 'DepartmentId' field as unique key, and re-sort the source array by DepartmentId (descending)
let ojTableDataProvider4 = ojx.arrayDataProvider( srcArray, 'DepartmentId', 'desc*' );
// use 'id' field as unique key, and re-sort the source array by 'firstName' (ascending)
let ojTableDataProvider5 = ojx.arrayDataProvider( srcArray, 'id', 'asc', 'firstName' );
// use 'id' field as unique key, and re-sort the source array by 'lastUpdatedOn' (descending) + auto-detects date/time field by its fieldname
let ojTableDataProvider6 = ojx.arrayDataProvider( srcArray, 'id', 'desc', 'lastUpdatedOn' );
// use 'id' field as unique key, and re-sort the source array by 'lastUpdatedOn' (descending) and consider 'lastUpdatedOn' as date-time field.
let ojTableDataProvider7 = ojx.arrayDataProvider( srcArray, 'id', 'desc', 'lastUpdatedOn', true );
ojx/dom// instead of document.querySelector( '#pgHeader' );
let secHeaderA = _$( '#sectionHeader' );
// OR
let secHeaderB = ojx.$( '#pgHeader' );
// instead of document.querySelectorAll( '.menu-items' );
let menuItemsA = _$$( '.menu-items' );
// OR
let menuItemsB = ojx.$$( '.menu-items' );
sanitizeXSS( '<script>alert("Hi")</script>' ); // '<xss-script>alert("Hi")</xss-script>'
sanitizeXSS( '<button onclick="doSomething()">Click Me</button>' ); // '<button xss-onclick="doSomething()">Click Me</button>'
sanitizeXSS( { note: '<button onclick="doSomething()">Click Me</button>' } ); // { note: '<button xss-onclick="doSomething()">Click Me</button>' }
// OR
ojx.sanitizeXSS( '<script>alert("Hi")</script>' ); // '<xss-script>alert("Hi")</xss-script>'
ojx/objectTo get keys
let testObjA = {
name: 'Javascript',
altName: 'ECMA Script',
active: true
};
console.log( testObjA.__keys() ); // ['name', 'altName', 'active']
// OR
console.log( ojx.keysOf(testObjA) ); // ['name', 'altName', 'active']
// ----------------------------------------------------------------
const testObjB = {
company: "TechCorp",
employees: [
{ name: "Tom", role: "Dev" },
{ name: "Jerry", role: "Design" }
]
};
testObjB.__keys( true ); // ["company", "employees", "employees[0].name", "employees[0].role"]
// OR
ojx.keysOf(testObjB, true ); // ["company", "employees", "employees[0].name", "employees[0].role"]
High-performance JSON-object merge.
const user = { profile: { name: 'JavaScript' } };
const update1 = { profile: { age: 30 }, settings: { dark: true } };
const update2 = { profile: { location: 'everywhere' } };
user.__merge(update1, update2);
// OR
ojx.merge(user, update1, update2)
// Result:
// user = {
// profile: { name: 'JavaScript', age: 30, location: 'everywhere' },
// settings: { dark: true }
// }
To find the object's Class
// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
// <h1 id="sectionTitle">Section Title</h1>
document.getElementById('sectionTitle').__ofClass(); // 'HTMLHeadingElement'
document.querySelector('h1').__ofClass(); // 'HTMLHeadingElement'
/* HTML
<ul>
<li class="menu-items">menu item 01</li>
<li class="menu-items">menu item 02</li>
<li class="menu-items">menu item 03</li>
<li class="menu-items">menu item 04</li>
<li class="menu-items">menu item 05</li>
</ul>
*/
document.getElementsByClassName('menu-item').__ofClass(); // 'HTMLCollection'
document.querySelectorAll('.menu-item').__ofClass(); // 'NodeList'
Sorts an array of objects based on a specific field and order.
/**
* Sorts an array of objects based on a specific field and order.
* @param {Array} srcArray - The source array
* @param {string} sortByField - The keyField to sort by (e.g., 'id', 'userId', 'lastUpdated', 'address.shipping.zip')
* @param {string} orderBy - for ascending : 'asc' | 'ascending'
* for descending: any value other than ['asc', 'ascending'] (ex., 'desc', 'descending')
* @param {string} isDateTime - is sortByField of type Date/Time?
*/
ojx.sortBy(srcArray, sortByField, orderBy, isDateTime);
let sortedArray1 = ojx.sortBy( [...srcArray], sortByField, orderBy, isDateTime );
let sortedArray2 = ojx.sortBy( [...srcArray], 'lastUpdatedOn', 'desc', true );
let sortedArray3 = ojx.sortBy( [...srcArray], 'itemPrice', 'desc' );
let sortedArray4 = ojx.sortBy( [...srcArray], 'firstName' );
// also you can
let sortedArray5 = [ ...srcArray ];
sortedArray5.__sortBy('firstName');
console.log( sortedArray5 );
Deeply retrieves a value from an object/array using a string path.
/**
* Deeply retrieves a value from an object/array using a string path.
* Supports: "address.city", "tags[0]", "orders.0.id"
*/
// ojx.valueOfPath(obj, path);
//-------------------------------------------------------------
const testDataX = {
name: 'Unknown',
age: 10,
address: {
billing: {
address: 'billing address line',
city: 'billing city',
state: 'billing state',
zip: '111111'
},
shipping: {
address: 'shipping address line',
city: 'shipping city',
state: 'shipping state',
zip: '222222'
}
}
};
ojx.valueOfPath(testDataX, 'address.shipping.zip'); // 222222
// OR
testDataX.__valueOfPath('address.shipping.zip'); // 222222
//-------------------------------------------------------------
const testDataY = [
{ id: 2, info: { name: "Beta", date: "2023-01-01" } },
{ id: 1, info: { name: "Alpha 10", date: "2021-01-01" } },
{ id: 3, info: { name: "Alpha 2", date: "2022-01-01" } },
{ id: 4, info: null }
];
ojx.valueOfPath(testDataY, '[0].id'); // 2
ojx.valueOfPath(testDataY, '1.info.name'); // "Alpha 10"
ojx.valueOfPath(testDataY, '[2].info.date'); // "2022-01-01"
ojx.valueOfPath(testDataY, 'info.name'); // undefined
ojx.valueOfPath(testDataY, '[3].info'); // null
//-------------------------------------------------------------
const testDataZ = [{ x: { y: [ { z: "found" } ] } }];
ojx.valueOfPath(testDataZ, "0.x.y[0].z"); // "found"
ojx.valueOfPath(testDataZ, "0.x.y.0.z"); // "found"
ojx/typeofType | ojx.ofType
// instead of typeof xyz === 'type'
// use ofType which returns / checks exact variable type; particularly for array and null.
let testNull = null;
let testArray = [];
let testString = '';
let testObject = {};
ofType( testNull ); // returns 'null'
ofType( testArray ); // returns 'array'
ofType( testArray, 'array' ); // returns true : alternate to Array.isArray(testArray)
ofType( document.getElementsByClassName('menu-item') ); // returns 'array-like'
function fx () {
console.log(typeof arguments, ofType(arguments), ofClass(arguments) ); // object array-like Arguments
};
ofClass | ojx.ofClass
ofClass( document.querySelectorAll('h1') ); // 'NodeList'
ofClass( document.getElementsByTagName('h1') ); // 'HTMLCollection'
ofClass( document.querySelector('h1') ); // 'HTMLHeadingElement'
isEmpty
let testArrayX = [];
let testStringX = '';
let testObjectX = {};
isEmpty( testArrayX ); //returns true
isEmpty( testStringX ); //returns true
isEmpty( testObjectX ); //returns true
ojx/data-timedateYYYYMMDD | ojx.dateYYYYMMDD
now(); // returns current timestamp
dateYYYYMMDD(); // returns current date in YYYYMMDD - ex: 20031206
dateYYYYMMDD( '-' ); // returns current date in YYYY-MM-DD - ex: 2003-12-06
dateYYYYMMDD( '/' ); // returns current date in YYYY/MM/DD - ex: 2003/12/06
dateYYYYMMDD( '/', dateObj ); // returns given date in YYYY/MM/DD
timeHHMMSS | ojx.timeHHMMSS
timeHHMMSS(); // returns current time in HHMMSS - ex: 141030
timeHHMMSS( ':' ); // returns current time in HH:MM:SS - ex: 14:10:30
timeHHMMSS( ':', dateObj ); // returns given time in HH:MM:SS
ojx/storage for sessionStorage and localStorage utils
let storage = sessionStorage; // or localStorage
storage.user(); // get current userStoreToken
storage.user( 'userID' ); // set current userStoreToken
storage.getUserItemStr( 'key' ); // get raw value as string
storage.getUserItem( 'key' ); // get parsed value
storage.setUserItemStr( 'key', value ); // store value as raw string
storage.setUserItem( 'key', value ); // store value as JSON String;
storage.removeUserItem( 'key' ); // remove user key-value
storage.entries(); // return all entries (value:string)
storage.entries( true ); // return all entries (parsed=true) as js object
storage.userEntries(); // return only current user entries (value:string)
storage.userEntries( true ); // return current user entries (parsed=true) as js object
ojx/file-systemfs.readFileContent | ojx.readFileContent
function callbackFnOnSuccess ( fileContent ) {
// ... ... ...
}
function callbackFnOnError ( error ) {
// ... ... ...
}
fs.readFileContent( callbackFnOnSuccess );
fs.readFileContent( callbackFnOnSuccess, callbackFnOnError );
fs.readFileContent( callbackFnOnSuccess, callbackFnOnError, fileTypes );
fs.readFileContent( callbackFnOnSuccess, fileTypes );
// fileTypes: any text file extensions - Ex: '.txt,.html,.css,.js,.json,.yaml,.yml,.csv'
fs.saveToDisk | ojx.saveToDisk// ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
fs.saveToDisk(fileContent, fileName);
ojx/libsExport ko and jQuery($) to window, so you don't have to require in every modules with ['knockout', 'jquery'].
Write less, done fast 🚀
Happy coding until your company replaces you with AI Agents!
FAQs
OJET custom components and utilities
We found that ojx demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.