Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

jprevo/mapstronaut

Open more actions menu

Repository files navigation

Mapstronaut Banner

Mapstronaut is a lightweight and flexible JavaScript/TypeScript library for transforming objects. It simplifies complex object manipulation by defining mapping rules, letting you focus on the data, not the boilerplate code.

npm version MIT License Tests 302/302 Coverage 99%

Why Mapstronaut?

  • Declarative Approach: Define your mapping structure as an array of rules. It's easy to read, understand, and maintain.
  • Advanced Data Selection: Uses JSONPath to precisely select source properties, even from complex nested objects and arrays. Uses dot-prop to select target properties.
  • Automapping: Can automatically map properties with matching names and types, saving you from defining obvious mappings.
  • High-Performance Async: Supports parallel asynchronous mapping, offering a significant performance boost for I/O-heavy transformations.

Developer's note: I used Typescript for a long time before having to switch to Java a few years ago. I love using the popular object mapper Mapstruct and was inspired by it for Mapstronaut.

Installation

npm i mapstronaut

Usage

All examples will use the following space mission data:

const spaceMissionData = {
  mission: {
    id: "artemis-3",
    name: "Artemis III",
    status: "planned",
    launch: {
      date: "2027-07-15T14:30:00Z",
      site: "Kennedy Space Center",
    },
  },
  crew: [
    { id: "cmdr-001", name: "Sarah Chen", role: "commander", experience: 2840 },
    {
      id: "plt-002",
      name: "Marcus Rodriguez",
      role: "pilot",
      experience: 1650,
    },
  ],
  spacecraft: {
    name: "Orion",
    modules: ["crew", "service"],
    fuel: { type: "liquid", amount: 95.5 },
  },
};

Basic Mapping

import { mapObject } from "mapstronaut";

const structure = [
  ["mission.name", "missionTitle"],
  ["mission.launch.date", "scheduledDate"],
  ["crew[0].name", "commander"],
  ["spacecraft.fuel.amount", "spacecraft.fuelLevel"],
];

const result = mapObject(structure, spaceMissionData);

// Result:
// {
//   missionTitle: "Artemis III",
//   scheduledDate: "2027-07-15T14:30:00Z",
//   commander: "Sarah Chen"
//   spacecraft: {
//     fuelLevel: 95.5
//   }
// }

Transforming and Filtering

Apply transformations and conditional logic during mapping:

import { mapObject } from "mapstronaut";

const structure = [
  {
    source: "mission.launch.date",
    target: "launchYear",
    transform: (date) => new Date(date).getFullYear(),
  },
  {
    source: "crew",
    target: "activeCrew",
    filter: (crew, source) => source.mission.status === "in-progress",
  },
  {
    source: "spacecraft.fuel.amount",
    target: "fuelStatus",
    transform: (amount) => (amount > 90 ? "ready" : "needs-refuel"),
  },
];

const result = mapObject(structure, spaceMissionData);

// Result:
// {
//   launchYear: 2027,
//   fuelStatus: "ready"
// }
// // activeCrew is filtered out

Asynchronous Mapping

import { mapObjectAsync } from "mapstronaut";

// Simulate external API calls
const fetchWeatherData = (site) =>
  new Promise((resolve) =>
    setTimeout(() => resolve({ temp: 22, conditions: "clear" }), 100),
  );

const fetchCrewCertification = (crewId) =>
  new Promise((resolve) =>
    setTimeout(() => resolve({ certified: true, expires: "2027-01-01" }), 150),
  );

const structure = [
  ["mission.name", "title"],
  {
    source: "mission.launch.site",
    target: "weather",
    transform: async (site) => await fetchWeatherData(site),
  },
  {
    source: "crew[0].id",
    target: "commanderStatus",
    transform: async (id) => await fetchCrewCertification(id),
  },
];

const result = await mapObjectAsync(structure, spaceMissionData, undefined, {
  parallelRun: true,
});

// Result:
// {
//   title: "Artemis III",
//   weather: { temp: 22, conditions: 'clear' },
//   commanderStatus: { certified: true, expires: '2027-01-01' }
// }

Documentation

What's New in Version 2.0.0?

  • Using dot-prop for better target properties selection
  • Improved automapping with deep merging of object and arrays
  • Added maximum number of parallel jobs option in async mapping
  • Improved and tested documentation to help you get the most out of the library

Contributions

Contributions are welcome! If you have a feature request, bug report, or want to improve the code, please feel free to open an issue or submit a pull request.

Licence

This project is licensed under the MIT License.

Built by Jonathan Prevost.

Releases

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.