Quick Links: Security Relevance | Installation | API Documentation
How to view artifacts: Source code for each utility function in root directory; unit tests in /test/ folder.
Result snapshot: Published npm package with 20+ utility functions, comprehensive test coverage, and modular architecture.
Quick review:
- Security focus: Input validation, type checking, safe array/object comparison, test-driven development
- Key files:
index.js(exports),eqObjects.js(deep equality),test/(unit tests) - Start with: Review test files to see edge case handling and validation patterns
Lotide is a mini-clone of the Lodash library, created to understand how utility libraries work under the hood. This project demonstrates fundamental JavaScript programming, test-driven development, algorithm implementation, and npm package publishing. It showcases secure coding practices through input validation, type safety, and comprehensive edge case testing.
Developed during: Lighthouse Labs Web Development Bootcamp (February - March 2021)
Published to npm: @VioletFigueroa/lotide
- Type checking prevents unexpected behavior from incorrect input types
- Edge case handling (empty arrays, null values, undefined) prevents runtime errors
- Defensive programming validates assumptions before processing
- Boundary condition testing ensures functions handle extremes safely
- Demonstrates understanding that unexpected input is a security concern
- Unit tests for every function validate expected behavior
- Edge case coverage tests null, undefined, empty, and boundary values
- Regression testing ensures fixes don't break existing functionality
- Assertion libraries provide consistent validation patterns
- Test coverage makes security regressions visible
- Array equality comparison handles nested arrays safely
- Object equality comparison prevents prototype pollution vulnerabilities
- Deep comparison logic avoids infinite recursion on circular references
- Safe iteration patterns using for...in and Array methods
- Immutability patterns - functions don't mutate original data structures
- Modular design - each function in separate file facilitates review
- Clear naming conventions make code intent explicit
- DRY principles reduce attack surface through code reuse
- Export patterns control public API surface
- Documentation aids in security code review
- Version control enables tracking of changes and security fixes
- Dependency management (minimal external dependencies reduces supply chain risk)
- Package.json security defines entry points and exposed functionality
- Gitignore prevents accidental exposure of sensitive files
- Published package demonstrates understanding of software distribution
- Implement common utility functions from scratch
- Practice test-driven development methodology
- Understand JavaScript data structures and algorithms
- Publish package to npm registry
- Write clean, maintainable, well-documented code
- JavaScript ES6+ for modern language features
- Test-Driven Development with assertion functions
- Mocha & Chai for professional-grade testing
- Modular architecture with single-responsibility functions
- npm for package management and publishing
- Array Utilities: head, tail, middle, map, takeUntil, without
- Object Utilities: eqObjects, findKey, findKeyByValue
- String Utilities: countLetters, letterPositions
- Assertion Utilities: assertEqual, assertArraysEqual, assertObjectsEqual
- Comparison Utilities: eqArrays, eqObjects with deep equality
- Iteration Utilities: countOnly, map with callback support
- JavaScript ES6+: Arrow functions, destructuring, template literals
- Node.js: Module system (require/exports)
- Mocha: Test framework for organized test suites
- Chai: Assertion library for expressive tests
- npm: Package manager and registry
- Utility functions are attack surface: Even simple helpers can have security implications
- Type coercion can be dangerous: JavaScript's loose typing requires explicit validation
- Deep comparison is hard: Object/array equality needs careful handling to avoid vulnerabilities
- Test coverage matters: Untested edge cases are where bugs (and vulnerabilities) hide
- Dependencies are risk: Even a utility library has supply chain security considerations
- API design impacts security: What you expose publicly increases attack surface
- Documentation prevents misuse: Clear docs help developers use functions safely
The following functions are currently implemented:
head(arr)- Returns the first element of an arraytail(arr)- Returns all elements except the firstmiddle(array)- Returns the middle element(s) of an arraymap(array, callback)- Applies callback to each element, returns new arraytakeUntil(array, callback)- Returns elements until callback returns truthywithout(source, itemsToRemove)- Returns array without specified elements
eqObjects(object1, object2)- Deep equality comparison for objectsfindKey(object, callback)- Returns first key where callback returns truthyfindKeyByValue(object, value)- Returns key for a given valueassertObjectsEqual(actual, expected)- Assertion for object equality
countLetters(sentence)- Returns object with letter countsletterPositions(sentence)- Returns object with array of indices for each letter
eqArrays(array1, array2)- Deep equality comparison for arraysassertEqual(actual, expected)- Assertion for primitive equalityassertArraysEqual(array1, array2)- Assertion for array equality
countOnly(allItems, itemsToCount)- Counts specified items in arraymiddleIndex(array)- Returns middle index of array (rounded down)
Install it:
npm install @VioletFigueroa/lotideRequire it:
const _ = require('@VioletFigueroa/lotide');Call it:
const results = _.tail([1, 2, 3]); // => [2, 3]
const middle = _.middle([1, 2, 3, 4, 5]); // => [3]
const isEqual = _.eqObjects({a: 1}, {a: 1}); // => true// Safe object comparison with array handling
const eqObjects = (object1, object2) => {
// Type and length validation
if (Object.keys(object1).length !== Object.keys(object2).length)
return false;
// Handle nested arrays safely
for (let key in object1) {
if (Array.isArray(object1[key]) && Array.isArray(object2[key])) {
if (!eqArrays(object1[key], object2[key])) return false;
} else if (object1[key] !== object2[key]) return false;
}
return true;
};// Safe middle element extraction with edge case handling
const middle = (array) => {
if (!Array.isArray(array) || array.length < 3) {
return []; // Safe default for invalid input
}
const midIndex = Math.floor(array.length / 2);
return array.length % 2 === 0
? [array[midIndex - 1], array[midIndex]]
: [array[midIndex]];
};# Run all tests
npm test
# Run specific test file
npm test test/headTest.js// Comprehensive edge case testing
describe('#head', () => {
it('returns first element of array', () => {
assert.strictEqual(head([1, 2, 3]), 1);
});
it('returns undefined for empty array', () => {
assert.strictEqual(head([]), undefined);
});
it('returns only element for single-element array', () => {
assert.strictEqual(head([42]), 42);
});
it('does not modify original array', () => {
const arr = [1, 2, 3];
head(arr);
assert.deepEqual(arr, [1, 2, 3]);
});
});This project demonstrates foundational AppSec skills:
- Secure Coding Practices: Input validation, type checking, and defensive programming
- Test-Driven Development: Security testing integrated from the start
- Code Review Skills: Clean, readable code facilitates security review
- Supply Chain Security: Understanding npm packages and dependency management
- API Design: Minimizing attack surface through careful API exposure
Software engineering fundamentals essential for AppSec:
- Code Review: Reading and understanding utility library code (common in security reviews)
- Testing Methodology: Writing security tests and validating edge cases
- Algorithm Analysis: Understanding time/space complexity and potential DoS vectors
- Dependency Management: Evaluating third-party library security
- Secure Development: Implementing defensive programming patterns
- Documentation: Clear communication about function behavior and limitations
This project demonstrates that good security starts with good engineering - clean code, comprehensive tests, and careful design are the foundation of secure software.
Author: Violet Figueroa
Contact: GitHub Profile
npm Package: @VioletFigueroa/lotide
Career Focus: Application Security | Secure Software Development | Software Engineering
BEWARE: This library was published for learning purposes. It is not intended for use in production-grade software.