{"id":18698448,"url":"https://github.com/plurid/deon","last_synced_at":"2025-04-12T07:33:08.577Z","repository":{"id":57137322,"uuid":"290121499","full_name":"plurid/deon","owner":"plurid","description":"DeObject Notation Format","archived":false,"fork":false,"pushed_at":"2022-09-30T16:16:25.000Z","size":5675,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-09T03:28:10.667Z","etag":null,"topics":["data","file-format"],"latest_commit_sha":null,"homepage":"https://deon.plurid.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plurid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-25T05:25:20.000Z","updated_at":"2023-02-10T12:00:58.000Z","dependencies_parsed_at":"2022-08-22T20:50:12.733Z","dependency_job_id":null,"html_url":"https://github.com/plurid/deon","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Fdeon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Fdeon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Fdeon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Fdeon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plurid","download_url":"https://codeload.github.com/plurid/deon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223505197,"owners_count":17156485,"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":["data","file-format"],"created_at":"2024-11-07T11:28:22.592Z","updated_at":"2024-11-07T11:28:23.108Z","avatar_url":"https://github.com/plurid.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca target=\"_blank\" href=\"https://deon.plurid.com\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/plurid/deon/master/about/identity/deon-logo.png\" height=\"250px\"\u003e\n    \u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/plurid/deon/blob/master/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-DEL-blue.svg?colorB=1380C3\u0026style=for-the-badge\" alt=\"License: DEL\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\n\n\u003ch1 align=\"center\"\u003e\n    deon\n\u003c/h1\u003e\n\n\n\u003ch3 align=\"center\"\u003e\n    DeObject Notation Format\n\u003c/h3\u003e\n\n\n\n\u003cbr /\u003e\n\n\n\n`deon` is a notation format for structured data.\n\n`deon` is intended to be:\n\n+ light on syntax — friendly for human read/write, should feel more like note-taking than data entry;\n+ moderately fast — with a general use case for configuration-like files, loaded once at build/runtime;\n+ programming-lite — although not a programming language, the in-file imports and the linking (in-file variables) give `deon` a programmatic feel.\n\nThe `deon` filename extension is `.deon`, and the media type is `application/deon`.\n\nWhy `deobject`? More of a play-on-words, although a case can be made considering the [linking](#linking) feature and the possible 'assembling' of the `root`, as if the object has been de-structured. As an afterthought, `deon` could also be rooted into the Ancient Greek word, [δέον](https://en.wiktionary.org/wiki/%CE%B4%CE%AD%CE%BF%CE%BD), that which is binding, such as how data binds functionality into code.\n\n\n### Contents\n\n+ [Example](#example)\n+ [Implementations](#implementations)\n+ [Installs](#installs)\n+ [Service](#service)\n+ [General](#general)\n+ [Values](#values)\n+ [Maps](#maps)\n+ [Lists](#lists)\n+ [Structures](#structures)\n+ [Comments](#comments)\n+ [Linking](#linking)\n+ [Importing](#importing)\n+ [Injecting](#injecting)\n+ [Interpolation](#interpolation)\n+ [Stringifying](#stringifying)\n+ [Parsing](#parsing)\n+ [Literals](#literals)\n+ [Advanced Usage](#advanced-usage)\n+ [In Use](#in-use)\n+ [Usages](#usages)\n+ [Idiomaticity](#idiomaticity)\n+ [Specifics](#specifics)\n+ [Packages](#packages)\n+ [Codeophon](#codeophon)\n\n\n\n## Example\n\nThe following `.deon` file\n\n``` deon\n// deon\n\n{\n    entities [\n        {\n            id 01\n            name One\n            active true\n        }\n        {\n            id 02\n            name Two\n            active false\n        }\n    ]\n    #time\n}\n\ntime 1598439736\n```\n\nwill produce the following data\n\n``` typescript\n// JavaScript/TypeScript\n\nconst data = {\n    entities: [\n        {\n            id: '01',\n            name: 'One',\n            active: 'true',\n        },\n        {\n            id: '02',\n            name: 'Two',\n            active: 'false',\n        },\n    ],\n    time: '1598439736',\n};\n```\n\n``` rust\n// Rust\n\nlet data = deon!({\n    entities [\n        {\n            id 01\n            name One\n            active true\n        }\n        {\n            id 02\n            name Two\n            active false\n        }\n    ]\n    time: 1598439736\n});\n```\n\n``` python\n# Python\n\ndata = {\n    \"entities\": [\n        {\n            \"id\": \"01\",\n            \"name\": \"One\",\n            \"active\": \"true\",\n        },\n        {\n            \"id\": \"02\",\n            \"name\": \"Two\",\n            \"active\": \"false\",\n        },\n    ],\n    \"time\": \"1598439736\",\n}\n```\n\n\n### Comparisons\n\nConsider the following commonly-used formats with an example file from [`performer`](https://github.com/plurid/performer):\n\n\n``` yaml\n# an .yaml file\n\n---\nstages:\n- name: 'Setup NPM Private Access'\n  directory: '/path/to/package'\n  imagene: 'ubuntu'\n  command:\n  - '/bin/bash'\n  - './configurations/.npmrc.sh'\n  secretsEnvironment:\n  - 'NPM_TOKEN'\n\n- name: 'Generate the Imagene'\n  directory: '/path/to/package'\n  imagene: 'docker'\n  command: [\n    'build',\n    '-f',\n    './configurations/docker.development.dockerfile',\n    '-t',\n    'hypod.cloud/package-name:$SHORT_SHA',\n    '.'\n  ]\n\n- name: 'Push Imagene to Registry'\n  directory: '/path/to/package'\n  imagene: 'docker'\n  command: [\n    'push',\n    'hypod.cloud/package-name:$SHORT_SHA'\n  ]\n\ntimeout: 720\n```\n\n``` json\n// a .json file\n\n{\n  \"stages\": [\n    {\n      \"name\": \"Setup NPM Private Access\",\n      \"directory\": \"/path/to/package\",\n      \"imagene\": \"ubuntu\",\n      \"command\": [\n        \"/bin/bash\",\n        \"./configurations/.npmrc.sh\"\n      ],\n      \"secretsEnvironment\": [\n        \"NPM_TOKEN\"\n      ]\n    },\n    {\n      \"name\": \"Generate the Imagene\",\n      \"directory\": \"/path/to/package\",\n      \"imagene\": \"docker\",\n      \"command\": [\n        \"build\",\n        \"-f\",\n        \"./configurations/docker.development.dockerfile\",\n        \"-t\",\n        \"hypod.cloud/package-name:$SHORT_SHA\",\n        \".\"\n      ]\n    },\n    {\n      \"name\": \"Push Imagene to Registry\",\n      \"directory\": \"/path/to/package\",\n      \"imagene\": \"docker\",\n      \"command\": [\n        \"push\",\n        \"hypod.cloud/package-name:$SHORT_SHA\"\n      ]\n    }\n  ],\n  \"timeout\": 720\n}\n```\n\nConsider the `.deon` version:\n\n``` deon\n// a .deon file\n\n{\n    stages [\n        {\n            name Setup NPM Private Access\n            directory /path/to/package\n            imagene ubuntu\n            command [\n                /bin/bash\n                ./configurations/.npmrc.sh\n            ]\n            secretsEnvironment [\n                NPM_TOKEN\n            ]\n        }\n        {\n            name Generate the Imagene\n            directory /path/to/package\n            imagene docker\n            command [\n                build\n                -f\n                ./configurations/docker.development.dockerfile\n                -t\n                hypod.cloud/package-name:$SHORT_SHA\n                .\n            ]\n        }\n        {\n            name Push Imagene to Registry\n            directory /path/to/package\n            imagene docker\n            command [\n                push\n                hypod.cloud/package-name:$SHORT_SHA\n            ]\n        }\n    ]\n    timeout 720\n}\n```\n\n\nor with nested internal linking\n\n\n``` deon\n// a .deon file\n\n// the root\n{\n    stages [\n        #stage1\n        #stage2\n        #stage3\n    ]\n    timeout 720\n}\n\n\n// the leaflinks\nstage1 {\n    name Setup NPM Private Access\n    #directory\n    imagene ubuntu\n    command #commands.stage1\n    #secretsEnvironment\n}\n\nstage2 {\n    name Generate the Imagene\n    #directory\n    imagene docker\n    command #commands.stage2\n}\n\nstage3 {\n    name Push Imagene to Registry\n    #directory\n    imagene docker\n    command #commands.stage3\n}\n\ndirectory /path/to/package\n\ncommands {\n    stage1 [\n        /bin/bash\n        ./configurations/.npmrc.sh\n    ]\n    stage2 [\n        build\n        -f\n        ./configurations/docker.development.dockerfile\n        -t\n        #imageneName\n        .\n    ]\n    stage3 [\n        push\n        #imageneName\n    ]\n}\n\nsecretsEnvironment [\n    NPM_TOKEN\n]\n\nimageneName hypod.cloud/package-name:$SHORT_SHA\n```\n\n\n\n## Implementations\n\n`deon` is implemented for:\n\n+ [`JavaScript/TypeScript`](https://github.com/plurid/deon/tree/master/packages/deon-javascript)\n+ [`Rust`](https://github.com/plurid/deon/tree/master/packages/deon-rust) - in progress\n\nand will be implemented for:\n\n+ [`C`](https://github.com/plurid/deon/tree/master/packages/deon-c)\n+ [`C++`](https://github.com/plurid/deon/tree/master/packages/deon-cpp)\n+ [`denatural`](https://github.com/plurid/deon/tree/master/packages/deon-denatural)\n+ [`Go`](https://github.com/plurid/deon/tree/master/packages/deon-go)\n+ [`Java`](https://github.com/plurid/deon/tree/master/packages/deon-java)\n+ [`PHP`](https://github.com/plurid/deon/tree/master/packages/deon-php)\n+ [`Python`](https://github.com/plurid/deon/tree/master/packages/deon-python)\n+ [`Swift`](https://github.com/plurid/deon/tree/master/packages/deon-swift)\n\nSee [specifics](#specifics) for implementation details.\n\n\n## Installs\n\n`deon` can be installed locally with the appropriate package manager for each implementation language, or can be installed globally as a `Command-Line Interface` tool.\n\nUsing the `NodeJS` runtime, run the command\n\n``` bash\nnpm install -g @plurid/deon\n```\n\nor download the appropriate [binary](https://plurid.link/binaries-deon)\n\n+ [MacOS](https://files.plurid.com/binaries/deon/macos)\n+ [Linux](https://files.plurid.com/binaries/deon/linux)\n+ [Windows](https://files.plurid.com/binaries/deon/windows)\n\n\n### CLI\n\n```\nUsage: deon [options] [command] \u003cfile\u003e\n\nread a \".deon\" file and output the parsed result\n\nOptions:\n    -v, --version                                   output the version number\n    -o, --output \u003cvalue\u003e                            output type: deon, json (default: \"deon\")\n    -t, --typed \u003cvalue\u003e                             typed output (default: \"false\")\n    -f, --filesystem \u003cvalue\u003e                        allow filesystem (default: \"true\")\n    -n, --network \u003cvalue\u003e                           allow network (default: \"true\")\n    -h, --help                                      display help for command\n\nCommands:\n    convert \u003csource\u003e [destination]                  convert a \".json\" file to \".deon\"\n    environment [options] \u003csource\u003e \u003ccommand...\u003e     loads environment variables from a \".deon\" file and spawns a new command\n    confile [options] \u003cfiles...\u003e                    combine files into a single \".deon\" file\n    exfile \u003csource\u003e                                 extract files from a \".deon\" confile\n```\n\n\n\n## Service\n\nThe `deon` data parsing can be explored on [`deon.plurid.com`](https://deon.plurid.com) and `deon.plurid.com/parse` can be used for programmatic `POST` requests.\n\n``` bash\ncurl \\\n    -X POST \\\n    -H 'Content-Type: application/deon' \\\n    -d '{ key value }' \\\n    https://deon.plurid.com/parse\n```\n\nThe response is `deon` by default, but can be specified through the `kind` query parameter (`json`, `yaml`, `toml`, or `xml`).\n\n``` bash\ncurl \\\n    -X POST \\\n    -H 'Content-Type: application/deon' \\\n    -d '{ key value }' \\\n    https://deon.plurid.com/parse?kind=yaml\n```\n\nConversely, `json`, `yaml`, `toml`, or `xml` data can be converted to `deon` through a `deon.plurid.com/convert` `POST` request\n\n``` bash\ncurl \\\n    -X POST \\\n    -H 'Content-Type: application/json' \\\n    -d '{ \"key\": \"value\" }' \\\n    https://deon.plurid.com/convert\n```\n\nThe [`deon.plurid.com`](https://deon.plurid.com) service can also host `.deon` files to be easily `import`ed or `inject`ed into other files from a fixed `URL` allowing control over the private/public status, the file's revision, or access-aware content (the content of the file changes based on who/what token requests it).\n\n\n\n## General\n\nA `deon` is comprised of a required `root` and none or more, optional `leaflink`s.\n\nIn `deon` every endleaf value is a `string`. It is up to the consumer to handle the required type conversions based on the problem domain interface. An [advanced use case](#advanced-usage) couples `deon` with [`datasign`](https://github.com/plurid/datasign) to handle type conversions.\n\n`deon` supports two types of [`value`](#values) groupings, the [`map`](#maps) and the [`list`](#lists).\n\nThe `root` can be `map` or `list`-like.\n\nThe `leaflink`s can be `string`s, `map`s, or `list`s.\n\nThe `map`s and the `list`s can have `string`s, `list`s, and `map`s as values,\n\nThe order of the `root` or of any of the `leaflink`s is not important.\n\nThe per `map` `key` names and the `leaflink`s names are expected to be unique.\n\nWhen parsed or imported, a `.deon` file will allow access only to the `root`. The `leaflink`s are private as data-details at the file level. By convention, a `__leaflinks__` key can be manually added to the `root` to allow access to the `leaflink`s if absolutely needed.\n\n\n\n## Values\n\nAn endleaf `value`, simply called `value`, is a string of characters, with or without spaces:\n\n``` deon\n{\n    key simpleValue\n}\n```\n\n``` deon\n{\n    key value with spaces\n}\n```\n\n\nA `value` can be surrounded by singlequotes `'` in order to support special characters, such as trailing spaces\n\n``` deon\n{\n    key 'value with 4 trailing spaces    '\n}\n```\n\n\nMulti-line `value`s are surrounded by backticks \u003ccode\u003e`\u003c/code\u003e. The multi-line string is stripped of any whitespace or new lines before the first non-space character and after the last non-space character.\n\n\n``` deon\n{\n    key `\na\nmulti\nline\nstring\nvalue\n        `\n}\n```\n\nor linked\n\n``` deon\n{\n    #key\n}\n\nkey `\na\nmulti\nline\nstring\nvalue\n`\n```\n\n\n\n## Maps\n\n``` deon\nmapName {\n    mapKey mapValue\n}\n```\n\nA `map` is comprised of key-value pairs. The `deon` `root` is the single base-level `map` without a `mapName`.\n\nA `mapKey` is an `A-Za-z0-9_-` string of characters. To support special characters (such as space), the `mapKey` must be surrounded by single quotes, such as\n\n``` deon\nmapName {\n    'map Key' mapValue\n}\n```\n\nA `mapValue` starts after the space of the `mapKey` and continues until the end of the line or until a comma.\n\n\n``` deon\nmapName {\n    mapKey1 map Value 1\n    mapKey2 mapValue2\n}\n```\n\nor\n\n``` deon\nmapName {\n    mapKey1 map Value 1, mapKey2 mapValue2\n}\n```\n\nA `mapValue` can be a `string`, a `list`, or a `map`.\n\nA `mapValue` can be an empty `string`:\n\n``` deon\nmapName {\n    mapKey1\n    mapKey2 mapValue2\n}\n```\n\nor\n\n``` deon\nmapName {\n    mapKey1 '', mapKey2 mapValue2\n}\n```\n\n\n\n## Lists\n\n``` deon\nlistName [\n    list Value 1\n    listValue2\n]\n```\n\nA `list` is comprised of a `listName` and the list items. The `deon` `root` is the single base-level `list` without a `listName`.\n\nA `list` item value starts at the first non-space character after the left square bracket `[`, or after the previous list item, and ends at the end of the line or at the comma.\n\nSuch as\n\n``` deon\nlistName [\n    list Value 1, listValue2\n]\n```\n\nor\n\n``` deon\nlistName [list Value 1, listValue2]\n```\n\nEach list item can be a `string`, a `list`, or a `map`.\n\nA list item can be an empty `string`:\n\n``` deon\nlistName [\n    ''\n    listValue2\n]\n```\n\nor\n\n``` deon\nlistName [\n    '', listValue2\n]\n```\n\n\n## Structures\n\nA `structure` is used to specify structured data\n\n```\n{\n    aStructure \u003c\n        // structure signature\n        id, value\n    \u003e [\n        // first data entry\n        one, two\n        // second data entry\n        three, four\n        // third data entry\n        five, six\n    ]\n}\n```\n\n\n## Comments\n\nSingle-line comments use the doubleslash `//`.\n\n``` deon\n// comment outside root\n{\n    // comment inside root\n    key value // comment in-line\n}\n```\n\nMulti-line comments use the slashstar `/*` to start, and the starslash to end `*/`.\n\n``` deon\n/*\n    multi\n    line\n    comment outside root\n*/\n{\n    /*\n        multi\n        line\n        comment inside root\n    */\n    key value\n}\n```\n\n\n\n## Linking\n\n### General\n\nA `leaflink` is designated using the hash sign `#`.\n\nThe `.deon` file\n\n``` deon\n{\n    key value\n}\n```\n\ncan be linked thus\n\n``` deon\n{\n    key #arbitraryName\n}\n\narbitraryName value\n```\n\nor with shortened linking\n\n``` deon\n{\n    #key\n}\n\nkey value\n```\n\nTo support linking with special characters in name, the `leaflink` must be surrounded by singlequotes `'`.\n\n\n``` deon\n{\n    #'key with spaces'\n}\n\n'key with spaces' value\n```\n\n\n### Dot-access\n\nA `leaflink` can be dot-accessed:\n\n``` deon\n{\n    entities [\n        {\n            name #entity1.name\n        }\n    ]\n}\n\n#entity1 {\n    name The Entity\n}\n```\n\nor dot-accessed with shortened link\n\n``` deon\n{\n    entities [\n        {\n            #entity1.name\n        }\n    ]\n}\n\n#entity1 {\n    name The Entity\n}\n```\n\nin which case, the `key` will be the last key of the dot-access string.\n\n\n### Name-access\n\nA `leaflink` can be name-accessed:\n\n``` deon\n{\n    entities [\n        {\n            name #entity1[name]\n        }\n    ]\n}\n\n#entity1 {\n    name The Entity\n}\n```\n\nor from a `list`:\n\n``` deon\n{\n    entities [\n        {\n            name #names[0]\n        }\n    ]\n}\n\n#names [\n    one\n    two\n    three\n]\n```\n\nThe `list` has a zero-based indexation.\n\n\n### Spreading\n\nA `leaflink` can be spreaded by tripledots `...`:\n\n``` deon\n{\n    entities [\n        {\n            ...#entity1\n        }\n    ]\n}\n\n#entity1 {\n    name The Entity\n    timestamp 1598425060\n}\n```\n\nSpreading overwrites the previously defined keys, if any, with the same name as the keys in the spreaded `map`.\n\nA `map` can be spreaded only in another `map`. A `list` can be spreaded only in another `list`. A `string` can be spreaded in a `map` and will result in a `map` where each key equals the index of the character of the `string`, or can be spreaded into a `list` and will result in a `list` where each list item is a character of the `string`.\n\n``` deon\n{\n    entity {\n        ...#spread\n    }\n}\n\nspread abc\n```\n\nwil result in `entity` having the `value`:\n\n``` deon\nentity {\n    0 a\n    1 b\n    2 c\n}\n```\n\nwhereas\n\n``` deon\n{\n    entity [\n        ...#spread\n    ]\n}\n\nspread abc\n```\n\nwil result in `entity` having the `value`:\n\n``` deon\nentity [\n    a\n    b\n    c\n]\n```\n\n\n### Environment variables\n\nA `leaflink` can represent an environment variable using the `#$` syntax. The environment variable will be injected at parse-time:\n\n``` deon\n{\n    one #$SOME_ENV_VARIABLE\n}\n\ntwo #$ANOTHER_ENV_VARIABLE\n```\n\n\n\n## Importing\n\nA `.deon` file can import another `.deon` file using the following syntax\n\n``` deon\nimport \u003cname\u003e from \u003cpath\u003e\n```\n\nWhere the `name` is an arbitrary string, and the `path` is the path of the targeted `.deon` file.\n\nThe `path` does not need to have the `.deon` filename extension specified.\n\nThe `path` can also point to a `.json` file, and `deon` will parse it appropriately.\n\nThe import imports the `root` from the targeted `.deon` file in order to be used as a regular, in-file locally-defined `leaflink`.\n\nThe import statement order in file is not important, although, by convention, they sit at the top of file. Imports will be resolved primarily, before any other action. The import `name` must be unique among all the other imports and among the in-file locally-defined `leaflink`s, given that there is no discernible conceptual difference between them.\n\n\n``` deon\n// file-1.deon\n\n{\n    name The Name\n}\n```\n\n\n``` deon\n// file-2.deon\n\nimport file1 from ./file-1\n\n{\n    name #file1.name\n}\n```\n\nThe `path`s of the imported files can be relative filesystem paths, and they will be automatically searched and imported if found, or absolute filesystem paths, if all the used absolute paths are passed to the parser at parse-time.\n\n``` deon\n// file-2.deon\n\nimport file1 from absolute/path/file-1\n\n{\n    name #file1.name\n}\n```\n\nand parsed giving the absolute paths, specific to a file or general using the `/*` glob-like matcher:\n\n``` typescript\n// TypeScript example\n\nimport Deon from '@plurid/deon';\n\n\nconst deonFilePath = '/absolute/path/to/folder/file-1.deon';\nconst deonFilesPath = '/absolute/path/to/folder/';\n\nconst loadData = async () =\u003e {\n    const absolutePaths = {\n        // specific file\n        'absolute/path/file-1': deonFilePath,\n        // or file lookup at runtime\n        'absolute/path/*': deonFilesPath,\n    };\n\n    const deon = new Deon();\n    const data = await deon.parseFile(\n        '/path/to/file-1.deon',\n        {\n            absolutePaths,\n        },\n    );\n\n    return data;\n}\n\nconst main = async () =\u003e {\n    const data = await loadData();\n\n    // use data\n    console.log(data);\n    // { name: 'The Name' };\n}\n\nmain();\n```\n\n\nA `path` can also be an `URL` such as\n\n``` deon\n// file-url.deon\n\nimport urlFile from https://example.com/url-file.deon\n\n{\n    #urlFile.key\n}\n```\n\nIn order to request `URL` files from protected routes, an `authorization` `map` of authorization `token`s can be passed at parse-time with all the domains required by the imports\n\n``` deon\nauthorization {\n    example.com token\n}\n```\n\nwith the `token` being automatically passed into the `Authorization: Bearer \u003ctoken\u003e` header of the adequate domain at request-time.\n\n``` typescript\n// TypeScript example\n\nimport Deon from '@plurid/deon';\n\n\nconst loadData = async () =\u003e {\n    const authorization = [\n        'example.com': 'token', // provide token securely using environment variables\n    ];\n\n    const deon = new Deon();\n    const data = await deon.parseFile(\n        '/path/to/file-url.deon',\n        {\n            authorization,\n        },\n    );\n\n    return data;\n}\n\nconst main = async () =\u003e {\n    const data = await loadData();\n\n    // use data\n    console.log(data);\n    // { key: 'data from url file' };\n}\n\nmain();\n```\n\nThe token can be passed at import-time in the `.deon` file:\n\n``` deon\nimport urlFile from https://example.com/url-file.deon with secret-token\n\n{\n    #urlFile.key\n}\n```\n\nIn order not to leak secrets, environment variables should be used:\n\n``` deon\nimport urlFile from https://example.com/url-file.deon with #$SECRET_TOKEN\n\n{\n    #urlFile.key\n}\n```\n\n\n\n## Injecting\n\nThe `import` statement will always try to parse the filetext into structured data.\n\nIn order to get only the filetext, the keyword `inject` can be used:\n\n``` deon\ninject leaflinkName from /path/to/file.any\n\n{\n    key #leaflinkName\n}\n```\n\nThe arbitrarily-named `inject` entity can be used as a regular `leaflink` containing a `string`.\n\nSimilar to the `import` statement, the `inject` can target an URL and pass an optional authentication token.\n\n``` deon\ninject file from https://example.com/file\ninject secretFile from https://example.com/secret-file with secret-token\n\n{\n    key1 #file\n    key2 #secretFile\n}\n```\n\nIn order to keep the `.deon` file secret-free, the secrets can be injected from a file outside or ignored by the versioning system.\n\n\n``` deon\ninject secret from file-with-secret.text\ninject secretFile from https://example.com/secret-file with #secret\n\n{\n    key #secretFile\n}\n```\n\n\n\n## Interpolation\n\nA `string` value can be interpolated in another `string` using the `#{}` syntax.\n\n``` deon\n{\n    key value1 #{value2Key} value3\n    list [\n        value1 #{value2Key}\n        value3\n    ]\n}\n\nvalue2Key value2-text\n```\n\nwhich will produce the result\n\n``` deon\n{\n    key value1 value2-text text3\n    list [\n        value1 value2-text\n        value3\n    ]\n}\n```\n\n\nA `deon` entity, `map`, `list`, `string`, can be \"called\" to provision the interpolation values dynamically, on a use-case basis.\n\n``` deon\naKey {\n    subKey value1 #{value2} value3\n}\n\n{\n    key1 #aKey(\n        value2 value2-text\n    )\n    key2 #aKey(\n        value2 value2-different-text\n    )\n}\n```\n\n\n\n## Stringifying\n\nA `stringify` method is implemented in order to convert an in-memory data representation to string. A partial `options` object can be passed.\n\n``` typescript\ninterface DeonStringifyOptions {\n    readable: boolean;\n    indentation: number;\n    leaflinks: boolean;\n    leaflinkLevel: number;\n    leaflinkShortening: boolean;\n    generatedHeader: boolean;\n    generatedComments: boolean;\n}\n```\n\n\n\n## Parsing\n\nThe `parse` method can receive the following partial options:\n\n``` typescript\ninterface DeonParseOptions {\n    absolutePaths: Record\u003cstring, string\u003e,\n    authorization: Record\u003cstring, string\u003e,\n    datasignFiles: string[];\n    datasignMap: Record\u003cstring, string\u003e;\n}\n```\n\n\n\n## Literals\n\nTo handle `deon` data inside the implementation language, a language-specific literal can be used.\n\n\n### `Javascript`/`Typescript`\n\n``` typescript\nimport {\n    deon,\n} from '@plurid/deon';\n\n\nconst main = async () =\u003e {\n    const data = await deon`\n        // handles full-fledged deon data\n        // with imports, injects, leaflinks, etc.\n        {\n            key value\n        }\n    `;\n\n    // { key: 'value' }\n    console.log(data);\n}\n\n\nmain();\n```\n\n\n### Rust\n\n``` rust\nuse deon::{deon}\n\n\nfn main() {\n    let data = deon!(\n        // handles full-fledged deon data\n        // with imports, injects, leaflinks, etc.\n        {\n            key value\n        }\n    );\n\n    // { key: 'value' }\n    println!(\"{}\", data.to_string());\n}\n```\n\n\n\n## Advanced Usage\n\n### Datasign Type Conversion\n\nWhen handling the parsing of `.deon` data, a `.datasign` file can be passed to handle the type conversions.\n\nFor example, given a `JavaScript/TypeScript` use case:\n\n``` datasign\n// ./Entity.datasign\ndata Entity {\n    name: string;\n    age: number;\n}\n```\n\n\n``` deon\n// ./entity.deon\n{\n    entities: [\n        {\n            name Entity One\n            age 1\n        }\n        {\n            name Entity Two\n            age 1.3\n        }\n    ]\n}\n```\n\n\n``` typescript\n// ./index.ts\nimport Deon from '@plurid/deon';\n\n\nconst deonFile = './entity.deon';\nconst datasignFile = './Entity.datasign';\n\nconst data = Deon.parse(\n    deonFile,\n    {\n        // pass an array of all the .datasign files to be considered for type handling\n        datasignFiles: [\n            datasignFile,\n        ],\n        // pass an object of the mappings between the fields from the .deon file\n        // and the expected types from the .datasign file\n        datasignMap: {\n            entities: 'Entity[]',\n        },\n    },\n);\n```\n\n\n\n## In Use\n\n`deon` is used in:\n\n+ [`developer`](https://github.com/plurid/developer) - configuration file\n+ [`delog`](https://github.com/plurid/delog) - configuration file\n+ [`deserve`](https://github.com/plurid/deserve) - configuration file\n+ [`joiner`](https://github.com/plurid/joiner) - configuration file\n+ [`performer`](https://github.com/plurid/performer) - configuration file\n+ [`pluridoc`](https://github.com/plurid/pluridoc) - plurid plane configuration\n\n\n\n## Usages\n\n`deon` can be plugged in into:\n\n+ [`docker`](https://github.com/plurid/deon/tree/master/usages/docker)\n+ [`kubectl`](https://github.com/plurid/deon/tree/master/usages/kubectl)\n\n\n\n## Idiomaticity\n\nIt appears idiomatic to have three sections in a `.deon` file, ordered as:\n\n+ imports;\n+ root;\n+ leaflinks.\n\nThe imports feel well-written when written in one line.\n\nThe root feels well-written when it has only one level of indentation, and every leaf is a `leaflink` (for `map`s or `list`s) or a `string`.\n\nFor example, the following [`joiner`](https://github.com/plurid/joiner) file:\n\n``` deon\nimport otherPackages from ../../path/to/file\n\n\n{\n    #packages\n    #package\n    #commit\n}\n\n\npackages [\n    one\n    two\n    ...#otherPackages\n]\n\npackage {\n    manager yarn\n    publisher npm\n}\n\ncommit {\n    engine git\n    combine true\n    root packages\n    fullFolder true\n    divider ' \u003e '\n    message setup: package\n}\n```\n\n\n\n## Specifics\n\n### `JavaScript` / `TypeScript`\n\n#### Parsing\n\nThe `JavaScript` / `TypeScript` can be used in the `NodeJS` runtime through the `Deon` object, or the `deon` template literal.\n\n``` typescript\nimport Deon, {\n    deon,\n} from '@plurid/deon';\n```\n\nThe parsing of `deon` data can be achieving asynchronously or synchronously\n\n``` typescript\nimport Deon, {\n    deon,\n    deonSynchronous,\n} from '@plurid/deon';\n\nconst main = async () =\u003e {\n    const deonData = `\n        {\n            key value\n        }\n    `;\n\n    const deonObject = new Deon();\n    const parsedObjectAsynchronously = await deonObject.parse(deonData);\n    const parsedObjectSynchronously = deonObject.parseSynchronous(deonData);\n\n    const parsedTemplateAsynchronously = await deon`\n        {\n            key value\n        }\n    `;\n    const parsedTemplateSynchronously = deonSynchronous`\n        {\n            key value\n        }\n    `;\n}\n```\n\nSynchronous parsing is to be used when the `deon` data does not rely on `import` or `inject` features, naturally asynchronous operations. However, when the parsing operation is to be used in a blockable environment (such as the CLI), synchronous parsing can be used for `deon` data with `imports` and `injects` just as well as asynchronous parsing.\n\n`deon` data can also be parsed in the browser, or other sandboxed environments, using the `DeonPure` object, or the `deonPure` template literal.\n\n``` typescript\nimport {\n    DeonPure,\n    deonPure,\n    deonPureSynchronous,\n} from '@plurid/deon';\n\n\nconst main = async () =\u003e {\n    const deonData = `\n        {\n            key value\n        }\n    `;\n\n    const deonObject = new DeonPure();\n    const parsedObjectAsynchronously = await deonObject.parse(deonData);\n    const parsedObjectSynchronously = deonObject.parseSynchronous(deonData);\n\n    const parsedTemplateAsynchronously = await deonPure`\n        {\n            key value\n        }\n    `;\n    const parsedTemplateSynchronously = deonPureSynchronous`\n        {\n            key value\n        }\n    `;\n}\n```\n\nThe `deon` `Pure` implementation does not have access to the file system for `import` and `inject` features.\n\n#### Typing\n\nIn order to handle the typing of the `deon` parsed data the `typer` can be used, which handles the typing in the standard `JavaScript`/`TypeScript` fashion, or the `customTyper` can be used, which requires an aditional, custom `typing` function.\n\n``` typescript\nimport Deon, {\n    customTyper,\n    typer,\n} from '@plurid/deon';\n\n\nconst main = async () =\u003e {\n    const deonData = `\n        {\n            keyBoolean true\n            keyNumber 1\n        }\n    `;\n\n    const deonObject = new Deon();\n    // keyBoolean and keyNumber are typeof 'string'\n    const parsedData = await deonObject.parse(deonData);\n\n    // keyBoolean is typeof 'boolean' and keyNumber is typeof 'number'\n    const defaultTypedData = typer(parsedData);\n\n    // keyBoolean is typeof 'boolean' and keyNumber is typeof 'string'\n    const customTypedData = customTyper(\n        parsedData,\n        (value) =\u003e {\n            if (value === 'true') {\n                return true;\n            }\n\n            return value;\n        },\n    );\n}\n```\n\n#### Environment Loading\n\n`deon` can be used to load environment variables at runtime from a `.deon` file.\n\nRun the function call as soon as possible in the program.\n\n``` deon\n// env-file.deon\n{\n    ONE one\n}\n```\n\n``` typescript\n// index.ts\nimport Deon from '@plurid/deon';\n\n\nconst loadEnvironment = async () =\u003e {\n    const deon = new Deon();\n\n    // optional\n    const options = {\n        overwrite: false,\n    };\n\n    await deon.loadEnvironment(\n        '/path/to/env-file.deon'\n        options,\n    );\n}\n\nconst main = async () =\u003e {\n    await loadEnvironment();\n\n    console.log(process.env.ONE) // one\n}\n\nmain();\n```\n\nThe `.deon` file that will be used for environment variables can use all the features of `deon`, however the `root` must be comprised only of `string`s, or `list` of `string`s, other values will be ignored.\n\n\n### Rust\n\nIn order to parse `deon` data the `Deon` implementation or the `deon!` macro can be used.\n\n``` rust\nuse deon::{\n    Deon,\n    deon!,\n}\n\nfn main() {\n    let deon_data = \"\n        {\n            key value\n        }\n    \";\n\n    let deon_object = Deon::new();\n    let deon_object_parsed = Deon::parse(deon_data);\n\n    let deon_macro_parsed = deon!(\n        {\n            key value\n        }\n    );\n}\n```\n\n\n\n## Packages\n\n\n\u003ca target=\"_blank\" href=\"https://marketplace.visualstudio.com/items?itemName=plurid.deon-grammar\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/vscode-v.0.0.8-1380C3?style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/deon-grammar][deon-grammar] • `Visual Studio Code` syntax highlighting\n\n[deon-grammar]: https://github.com/plurid/deon/tree/master/packages/deon-grammar/vscode\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/deon\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/deon.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"NPM\"\u003e\n\u003c/a\u003e\n\n[@plurid/deon-javascript][deon-javascript] • `JavaScript` / `TypeScript` implementation\n\n[deon-javascript]: https://github.com/plurid/deon/tree/master/packages/deon-javascript\n\n\n\n\u003ca target=\"_blank\" href=\"https://crates.io/crates/deon\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/deon.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"NPM\"\u003e\n\u003c/a\u003e\n\n[@plurid/deon-rust][deon-rust] • `Rust` implementation\n\n[deon-rust]: https://github.com/plurid/deon/tree/master/packages/deon-rust\n\n\n\n## [Codeophon](https://github.com/ly3xqhl8g9/codeophon)\n\n+ licensing: [delicense](https://github.com/ly3xqhl8g9/delicense)\n+ versioning: [αver](https://github.com/ly3xqhl8g9/alpha-versioning)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplurid%2Fdeon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplurid%2Fdeon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplurid%2Fdeon/lists"}