{"id":15608424,"url":"https://github.com/hypercubed/milton","last_synced_at":"2025-04-28T11:46:12.724Z","repository":{"id":38078385,"uuid":"237346000","full_name":"Hypercubed/milton","owner":"Hypercubed","description":"Now Milton, don't be greedy; let's pass it along and make sure everyone gets a piece","archived":false,"fork":false,"pushed_at":"2023-03-31T02:10:05.000Z","size":462,"stargazers_count":2,"open_issues_count":25,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T09:21:42.741Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hypercubed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-31T02:26:39.000Z","updated_at":"2022-06-06T20:17:49.000Z","dependencies_parsed_at":"2024-10-03T05:20:53.872Z","dependency_job_id":"7e6bd5e2-635d-4473-ad2f-151cd8c25465","html_url":"https://github.com/Hypercubed/milton","commit_stats":{"total_commits":45,"total_committers":3,"mean_commits":15.0,"dds":0.4666666666666667,"last_synced_commit":"5a531fcf63cc84dbea5ebb2965cd5fd8ca317a46"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hypercubed%2Fmilton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hypercubed%2Fmilton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hypercubed%2Fmilton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hypercubed%2Fmilton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hypercubed","download_url":"https://codeload.github.com/Hypercubed/milton/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251309089,"owners_count":21568744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T05:20:46.658Z","updated_at":"2025-04-28T11:46:12.707Z","avatar_url":"https://github.com/Hypercubed.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Milton\n\n*Now Milton, don't be greedy; let's pass it along and make sure everyone gets a piece*\n\n![](https://i.imgflip.com/3no9mr.jpg)\n\n## Goals\n\nMilton is JavaScript object stringifier powered by plugins.  Co-worker of [Smykowski](https://github.com/Hypercubed/smykowski).\n\n## Features\n\n- Extendable\n- Types (`undefined`, `±Infinity`, `NaN`, `-0`)\n- Objects (`RegExp`, `Date`, `Map` and `Set`)\n- Classes and class instances\n- ANSI colorized output\n\n## Install\n\n```bash\nnpm i @hypercubed/milton\n```\n\n## Usage\n\n```js\nimport { Milton, pretty, ansiColors } from '@hypercubed/milton';\n\nconst milton = new Milton();\nmilton.use(pretty);\n\nconst obj = {\n  null: null,\n  numbers: [\n    3.14159,\n    NaN,\n    Infinity,\n    -Infinity,\n    -0,\n    -10000000000000006n\n  ],\n  strings: {\n    empty: '',\n    string: 'foo',\n    multiline: `\n    This\n    is\n    multiline\n    `\n  },\n  arrays: {\n    empty: [],\n    array: [ 'one', 'two', 'three' ]\n  },\n  nested: { hello: 'hapi' },\n  false: false,\n  true: true,\n  undef: undefined,\n  error: new Error('bad'),\n  regexp: /.*\\n/g,\n  symbol: Symbol('Waddams'),\n  function: function Yes() { /* noop */ },\n  map: new Map([['key1', 'value1'], ['key2', 'value2']]),\n  set: new Set([1, 2, 3]),\n  date: new Date('1995-12-17T03:24:00'),\n  objects: {\n    class: Milton,\n    instance: milton\n  }\n};\n\nconst stringified = milton.stringify(obj);\nconsole.log(stringified);\n```\n\nprints:\n\n```\n{\n  null: null,\n  numbers: [ 3.14159, NaN, Infinity, -Infinity, -0, -10000000000000006n ],\n  strings: {\n    empty: '',\n    string: 'foo',\n    multiline: '\\n    This\\n    is\\n    multiline\\n    '\n  },\n  arrays: { empty: [ ], array: [ 'one', 'two', 'three' ] },\n  nested: { hello: 'hapi' },\n  false: false,\n  true: true,\n  undef: undefined,\n  error: Error: bad,\n  regexp: /.*\\n/g,\n  symbol: Symbol(Waddams),\n  function: [ƒ Yes],\n  map: Map(2) { key1 =\u003e 'value1', key2 =\u003e 'value2' },\n  set: Set(3) { 1, 2, 3 },\n  date: Sun Dec 17 1995 03:24:00 GMT-0700 (Mountain Standard Time),\n  objects: { class: [class: Milton], instance: Milton { } }\n}\n```\n\nadd the `ansiColors` plugin:\n\n```js\nmilton.add(ansiColors);\n\nconst colorized = milton.stringify(obj);\nconsole.log(colorized);\n```\n\nwill print:\n\n![](./output.png)\n\n## Description\n\n`Milton` is an interface for processing JS objects.  In `Milton` we have a concept of plugins and presets. Plugins are functions that define a \"replacer\" functions.  Replacer functions accept each value and returns a stringified result.  The value returned by the replacer function replaces the original value in the stringified result. If it returns `undefined` the property will be removed. If it returns the existing value it will be unchanged.  Values returned from one replacer are passed down to the next.  Plugins are added using the `.add` method on a `Milton` instance.  The order of the plugins does matter.  Plugins that stringify values should come first, followed by plugins that format the results.\n\nPresets are ordered sets of plugins.  You may use a preset using the `.use` method on a milton instance. \n\n```ascii\n| ........................ stringify ........................... |\n        | .................... preset ................... |\n        | ... plugin ... |\n\n           +----------+     +----------+     +----------+\nInput  --\u003e | Replacer | --\u003e | Replacer | --\u003e | Replacer | --\u003e Output\n           +----------+     +----------+     +----------+\n\n```\n\nPresets and plugins may be used together:\n\n```ts\nmilton.add(reference);\nmiltion.use(json);\nmilton.add(ansiColors);\n```\n\n## Presets\n\n- `json` - Produces valid JSON; reproducing, as much as possible, the built-in `JSON.stringify`.\n- `js` - Produces valid JS with support for additional types, printed as JS compatible code (for example `new Date(\"1995-12-17T10:24:00.000Z\")`)\n- `pretty` - Pretty prints objects and values, similar to the browser's console output or node's `util.inspect`.  Output is neither valid JSON nor valid JS.\n\n(see [presets.ts](https://github.com/Hypercubed/milton/blob/master/src/lib/presets.ts) for implementation details)\n\n## Plugins\n\n- `reference` - Prints repeated objects as reference pointers\n- `ansiColors` - Colorizes output based on types.\n\n(see [plugins.ts](https://github.com/Hypercubed/milton/blob/master/src/lib/plugins.ts) for more)\n\n## Writing Plugins and Presets\n\nA plugin is a function that accepts an options object, the root value (the first value passed to the `Miltion#stringify` method), and a \"get\" function used for recursion.  The plugin should return a replacer function that is called (recursively) on each value in the object.\n\nFor example here is very simple plugin that will handle a hypothetical `Decimal` class:\n\n```ts\nconst decimalPlugin = () =\u003e (s: any) =\u003e {\n  if (s instanceof Decimal) {\n    return s.toFloat();\n  }\n  return s;\n};\n```\n\nIt is importrant that the replacer function return the input value if it is unaltered.\n\n(see [plugins.ts](https://github.com/Hypercubed/milton/blob/master/src/lib/plugins.ts) for more)\n\nPresets are functions that add plugins to a `Milton` instance in a desiered order.  For example:\n\n```ts\nfunction myPrettyPrint(_: Milton) {\n  _.add(reference);\n\n  _.add(arrayDecender);\n  _.add(objectDecender, { quoteKeys: false, compact: true });\n\n  _.add(decimalPlugin);\n  _.add(jsValues);\n  _.add(jsonValues, { quote: `'` });\n\n  _.add(maxDepth);\n  _.add(indent);\n  return _;\n}\n```\n\n## API\n\n### Class `Milton`\n\n`new Milton()`\n\n#### Method `milton.add(plugin[, options])`\n\n```ts\nadd(plugin: Plugin, options?: any) =\u003e this\n```\n\n* `plugin` - A function that initializes returns a replacer\n* `options` (optional, default = null) — Configuration for plugin\n\n#### Method `milton.use(preset)`\n\n```ts\nuse(preset: Preset, options: any) =\u003e this\n```\n\n* `preset` - A adds plugins to a milton instance in the desired order\n\n#### Method `milton.stringify(value)`\n\n```ts\nstringify(value: any) =\u003e string\n```\n\n* `value` - any JS value supported by the plugins\n\nPass the value throuhgt the added replacers.\n\n### `Replacer`\n\n```ts\ntype Replacer = (s: any, p: Path, value: any) =\u003e any ;\n```\n\n### `Plugin`\n\n```ts\ntype Plugin = (options: any, root: any, get: StringifyFunction) =\u003e Replacer;\n```\n\n### `Preset`\n\n```ts\ntype Preset = (milton: Milton) =\u003e Milton;\n```\n\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypercubed%2Fmilton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhypercubed%2Fmilton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypercubed%2Fmilton/lists"}