{"id":13735263,"url":"https://github.com/stac-utils/stac-fields","last_synced_at":"2026-04-16T12:01:02.553Z","repository":{"id":42379503,"uuid":"332840055","full_name":"stac-utils/stac-fields","owner":"stac-utils","description":"A minimal STAC library that contains a list of STAC fields with some metadata and helper functions for styling as HTML.","archived":false,"fork":false,"pushed_at":"2026-03-19T11:21:19.000Z","size":173,"stargazers_count":10,"open_issues_count":7,"forks_count":12,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-04-07T22:13:13.143Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stac-utils.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-01-25T18:14:54.000Z","updated_at":"2026-03-09T18:19:17.000Z","dependencies_parsed_at":"2023-12-18T20:13:25.529Z","dependency_job_id":"d4119ea8-3a25-4044-a28b-8b29ebfa4ea7","html_url":"https://github.com/stac-utils/stac-fields","commit_stats":{"total_commits":160,"total_committers":3,"mean_commits":"53.333333333333336","dds":"0.018750000000000044","last_synced_commit":"9c396fc4a5f38b8d009a23b5404464a4859ee0fc"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/stac-utils/stac-fields","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Fstac-fields","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Fstac-fields/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Fstac-fields/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Fstac-fields/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stac-utils","download_url":"https://codeload.github.com/stac-utils/stac-fields/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stac-utils%2Fstac-fields/sbom","scorecard":{"id":845257,"data":{"date":"2025-08-11","repo":{"name":"github.com/stac-utils/stac-fields","commit":"10a07c6548ec4875bc29ea4b37798b52d496e777"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 3 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T21:16:10.065Z","repository_id":42379503,"created_at":"2025-08-23T21:16:10.065Z","updated_at":"2025-08-23T21:16:10.065Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31884929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T11:36:10.202Z","status":"ssl_error","status_checked_at":"2026-04-16T11:36:09.652Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-08-03T03:01:04.835Z","updated_at":"2026-04-16T12:01:02.547Z","avatar_url":"https://github.com/stac-utils.png","language":"JavaScript","funding_links":[],"categories":["`Python` processing of optical imagery (non deep learning)"],"sub_categories":["Cloud Native Geospatial"],"readme":"# stac-fields\n\nA minimal STAC library that contains a list of STAC fields with some metadata (title, unit, prefix) and helper functions for styling as HTML.\n\nVersion: **1.5.8**\n\n## Usage\n\nAdd to your project with `npm install @radiantearth/stac-fields --save`\n\nImport the utilities to format values:\n\n```js\nconst StacFields = require('@radiantearth/stac-fields');\n```\n\nor\n\n```js\nimport StacFields from '@radiantearth/stac-fields';\n```\n\nFormat a value:\n\n```js\nlet stacItem = {\n    stac_version: '1.0.0',\n    id: '...',\n    properties: {\n        datetime: '2020-01-01T13:55:43Z',\n        'radiant:public_access': true,\n        ...\n    },\n    ...\n};\n\n// Add custom extension and field(s)\nStacFields.Registry.addExtension('radiant', 'Radiant Earth');\nStacFields.Registry.addMetadataField('radiant:public_access', {\n    label: \"Data Access\",\n    formatter: (value) =\u003e value ? \"Public\" : \"Private\"\n});\n\n// Option 1: Manually iterate through properties and format them\nfor(let field in stacItem.properties) {\n    let value = stacItem.properties[field];\n    let formatted = StacFields.format(value, field, stacItem);\n    let label = StacFields.label(field);\n    console.log(label, formatted);\n}\n\n// Option 2: Group by extension and format item properties\n// The second parameter is a filter function to skip specific properties or paths, remove to get all properties\nlet groups = StacFields.formatItemProperties(stacItem, (key, path) =\u003e key !== 'eo:bands');\n```\n\nTo filter by path (remove all common_name fields from bands):\n\n```js\nlet groups = StacFields.formatItemProperties(stacItem, (key, path) =\u003e !(path[0] === 'eo:bands' \u0026\u0026 path[2] === 'common_name'));\n```\n\nThis library is written for the latest version of the STAC specification (1.0.0-rc.4).\nIt is recommended to pass your STAC data through a migration tool like\n[`@radiantearth/stac-migrate`](https://www.npmjs.com/package/@radiantearth/stac-migrate)\nbefore so that it complies to the latest STAC version. Otherwise some fields may not be handled correctly.\n\nNon-JavaScript library authors can re-use the `fields.json`. It is available at:\n\u003chttps://cdn.jsdelivr.net/npm/@radiantearth/stac-fields/fields.json\u003e\n\n## fields.json\n\nThis is a file defining useful metadata about extensions and metadata fields.\nIn general, the fields.json only lists fields that are either backed by a released extension or have at least one public catalog implementing it.\n\nThe following options are available in the object:\n\n* `label`: The human-readable title for the value.\n* `format`: The name of the formatter in formatters.js, but without the leading `format`.\n* `formatter`: A formatter function that is compatible to the formatters defined in formatters.js. Use this if no suitable pre-defined formatter is available to be specified in `format`. See also [Custom Formatters](#custom-formatters) for more details.\n* `ext`: Specify the extension key here, if the field belongs to an extension that has no prefix or so.\n* `unit`: A unit to add after the value.\n* `explain`: A long form for an abbreviation that should be shown in a tooltip. Can also be a http or https link, which shows a link instead of an abbreviation.\n* `mapping`: A map with the keys being the original (stringified lower-case) value and the values being the values shown to users.\n* `custom`: A structure that can't easily be rendered with any of the pre-defined formatters and thus needs a custom implementation (see `externalRenderer`).\n* `alias`: If a field has multiple keys, declare the field to use the specification of the other field.\n* `listWithKeys`: Set to `true` to allow the option `items` to specify items in an object of objects (like assets). Defaults to `false`.\n* `items`: If the value is an array of objects (or an object of objects if `listWithKeys` has ben set), a table can be created with the details in this object. It has the same structure as specified here, but in addition `sortable` and `id` are allowed:\n  * `sortable`: Specifies whether the value can be sorted (`true`, e.g. in a table) or not (`false`). Defaults to `false`.\n  * `id`: Specifies whether the value is the unique primary key (`true`) or not (`false`). Defaults to `false`.\n  * `default`: If no value is present, this value will be used instead.\n* `properties`: If the value is an object, specify the properties.\n* `null`: The value that should be given instead of `null`. If a value is null but this property is not given, defaults to \"n/a\".\n* Options related to Collection Summaries:\n  * `summary`: Gives an indication how the field should be summarized:\n    * `false` (boolean): Don't summarize\n    * `r` (string): Summarize as Range Object (minimum and maximum value)\n    * `v` (string): Summarize as array of all values (may require merging arrays)\n    * `s` (string): Summarize as JSON Schema Object (usually for very complex values or very long non-numerical lists of values)\n    * `true` (boolean) or not set: Detect based on the given data type of the values. Use Range Objects for numerical values, use JSON Schema Objects for objects and all other data types provide as array of all values.\n  * `order`: The order of the items in ascending order, e.g. for a table. If not given, the first entry is always the item with `id` set to `true`, all other items are in alphabetic order.\n\nIf only a label is available, it can be passed as string instead of an object.\n\nSome details about the fields included in the fields.json file can be found [here](fields.md).\n\nThere is also a `fields-normalized.json`, which is a normalized version of the fields.json.\nAll non-Javascript users will probably prefer to use the `fields-normalized.json` as it already\nhas the `alias`es resolved and all fields and extensions are defined as objects for easier handling.\n\n## formatters.js\n\nThe most important methods are:\n\n* `format(value: any, field: string, spec: object, context: object = null, parent: object = null, filter: function = null, path: array = []) =\u003e string`: Applies the right formatting depending on the data type of the a single property.\n* `label(key: string, spec: object = null)`: Formats a label according to the rules given in `spec`. By default uses the metadata labels from fields.json.\n* `extension(key: string) =\u003e string`: Formats an extension, similar to `label`.\n* `formatAsset(asset: object, context: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats an asset. Also groups by extension per asset.\n* `formatLink(link: object, context: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats a link. Also groups by extension per link.\n* `formatProvider(provider: object, context: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats a provider. Also groups by extension per provider.\n* `formatCollection(collection: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats a collection. Also groups by extension. *Experimental!*\n* `formatCatalog(catalog: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats a catalog. Also groups by extension. *Experimental!*\n* `formatSummaries(collection: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats the summaries in a collection. Also groups by extension. The filter only works on the top-level!\n* `formatItemProperties(item: object, filter: function = null, coreKey: string = '') =\u003e object`: Formats the properties in an Item. Also groups by extension.\n\n### Pre-defined formatters (`Formatters`)\n\n* Checksum (multihashes, show original hash and hashing algorithm)\n* CommonMark\n   Use the following code to allow rendering HTML in CommonMark:\n\n   ```js\n   import { Formatters } from '@radiantearth/stac-fields';\n   Formatters.allowHtmlInCommonMark = false;\n   ```\n\n* CrsCode (CRS Codes such as `EPSG:1234`)\n* CSV (array to comma-separated values)\n* Date\n* DOI (generate a link for a DOI)\n* Duration (ISO 8601 duration)\n* EPSG (generate a link for an EPSG code - deprecated in favor of CrsCode)\n* Extent (array with two values formatted as range)\n* FileDataType (explains the data types defined in the file extension)\n* FileSize (formats a number of bytes into kB, MB, ...)\n* GridCode (formats the `grid:code` field)\n* HexColor (formats a hex color to a box in this color)\n* License (formats a license as link based on SPDX or the links)\n* MediaType (converts media types into a more human-readable variant) - add `shorten:  true` to the field spec to render a shorter version\n* PROJJSON (formats PROJJSON into a more human-readable variant)\n* Providers (formats an array of providers)\n* Shape (formats an array containing shape/size information, e.g. `proj:shape`)\n* Software (formats the list of software as defined in the processing extension)\n* TemporalExtent (array with two timestamps formatted as temporal range, see Timestamp) - add `shorten:  true` to the field spec to render a shorter version (i.e. date only)\n* TemporalExtents (array containing a temporal extent per element, which is rendered using `TemporalExtent`, see above)\n* Transform (makes 2D numerical arrays, e.g. the `proj:transform` field, better readable)\n* Timestamp (ISO8601 timestamp formatted according to local rules)\n* Url (Formats a STAC Link Object)\n* WKT2 (splits a WKT2 string into nicely formatted chunks for better readability - experimental!)\n* ... (see the source file for more)\n\n### Custom formatters\n\nFormatters are always functions that have the following signature:\n\n`method(value : any, field : string, spec : object, context = null, parent = null) =\u003e string`\n\n* `value` is the value of the field in the STAC JSON.\n* `field` is the key of the field in the STAC JSON.\n* `spec` is the normalized object for the field from the `fields.json`.\n* `context` is the full STAC JSON.\n* `parent` is the parent object, if any.\n\nThe returned value is always expected to be a string.\nIt may contain HTML if the formatter is added to the `htmlFormats` array in `fields.json`.\nIf the return value is allowed to contain HTML, ALL user input must run through the `e()` function (or `parseInt` for integers, for example) to escape malicious HTML tags.\nThis avoids XSS and similar security issues.\n\n### `I18N`\n\nAll properties on the I18N class should only be used in read-only mode.\nYou should use the following functions instead:\n\n* `setTranslator(function fn)`: Set a function with parameters (phrase : string, vars : array|object = null) that can translate phrases.\n* `setLocales(array\u003cstring\u003e locales, object dateFormatterOptions = {}, object dateTimeFormatterOptions = {}, object numberFormatterOptions = {}, object collatorOptions = {})`: Set locales to be used for JS Intl functions.\n\n### `Registry`\n\n* `externalRenderer` (boolean): Set to `true` to not render custom objects, arrays and tables with the renderers from this library. Will return formatted values individually then. Defaults to `false`.\n* `addExtension(prefix : string, spec : object) =\u003e void` - Adds a additional (custom) extension that is compliant to the fields.json, can also be used to replace existing extensions\n* `addMetadataField(field : string, spec : object) =\u003e void` - Adds a additional (custom) metadata field that is compliant to the fields.json, can also be used to replace existing fields\n* `addLinkField(field : string, spec : object) =\u003e void` - Adds a additional (custom) metadata field only for links that is compliant to the fields.json, can also be used to replace existing fields\n* `addAssetField(field : string, spec : object) =\u003e void` - Adds a additional (custom) metadata field only for assets that is compliant to the fields.json, can also be used to replace existing fields\n* `addMetadataFields(specs : object) =\u003e void` - Adds additional (custom) metadata fields that are compliant to the fields.json, can also be used to replace existing fields\n\n### Data Types (`DataTypes`)\n\nThis object has functions to format the native JSON data types as HTML strings:\n\n* array =\u003e `array(arr: array, sort: boolean = false) =\u003e string`\n* object =\u003e `object(obj: object) =\u003e string`\n* null =\u003e `null(label: string = 'n/a') =\u003e string`\n* number =\u003e `number(num: number) =\u003e string`\n* string =\u003e `string(str: string) =\u003e string`\n* boolean =\u003e `boolean(bool: boolean) =\u003e string`\n\nAdditionally, it has a method `format(value: any) =\u003e string`, which applies the right formatting depending on the data type of the value.\n\nAll methods return strings, which may contain HTML. Input is sanitized.\n\n### `Helpers`\n\n* `e(str: string) =\u003e string`: Escapes the values for HTML output.\n* `formatKey(key: string, prefix: boolean = false) =\u003e string`: Formats the property key nicely (e.g. the key `eo:cloud_cover` will be `Cloud Cover`). If `prefix` is set to true, the prefix will not be removed (e.g. the key `eo:cloud_cover` will then be `Eo Cloud Cover`).\n* `groupByExtensions`\n* `isObject`\n* `toLink(url: string, title: string) =\u003e string`: Converts a url and title to a HTML link (`\u003ca href=\"$url\" target=\"_blank\"\u003e$title\u003c/a\u003e`).\n* `toList`\n* `toObject`\n* `hextoUint8`\n* `uint8ToHex`\n* `unit`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstac-utils%2Fstac-fields","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstac-utils%2Fstac-fields","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstac-utils%2Fstac-fields/lists"}