From 9d135a954983fb6fdf259f28e8fb969c6cfe01c2 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 09:30:37 +0100 Subject: [PATCH 1/7] meta: Tidy deps and md content Signed-off-by: Charlie Egan --- Makefile | 10 +- package-lock.json | 572 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 + style-guide.md | 62 ++++- 4 files changed, 637 insertions(+), 12 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/Makefile b/Makefile index fa6665e..ce8c0cc 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,4 @@ -PHONY: deps -deps: - hash markdown-toc || echo "please install markdown-toc: npm install -g markdown-toc" - PHONY: toc -toc: deps - markdown-toc -i style-guide.md --bullets="*" --maxdepth=3 - +toc: + npm install # installs the markdown-toc at the expected version from package.json + npx markdown-toc -i style-guide.md --bullets="*" --maxdepth=3 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cc2c24c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,572 @@ +{ + "name": "rego-style-guide", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "markdown-toc": "^1.2.0" + } + }, + "node_modules/ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/autolinker": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz", + "integrity": "sha512-zQAFO1Dlsn69eXaO6+7YZc+v84aquQKbwpzCE3L0stj56ERn9hutFxPopViLjo9G+rWwjozRhgS5KJ25Xy19cQ==", + "dependencies": { + "gulp-header": "^1.7.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/diacritics-map": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/diacritics-map/-/diacritics-map-0.1.0.tgz", + "integrity": "sha512-3omnDTYrGigU0i4cJjvaKwD52B8aoqyX/NEIkukFFkogBemsIbhSa1O414fpTp5nuszJG6lvQ5vBvDVNCbSsaQ==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==", + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gray-matter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", + "integrity": "sha512-vbmvP1Fe/fxuT2QuLVcqb2BfK7upGhhbLIt9/owWEvPYrZZEkelLcq2HqzxosV+PQ67dUFLaAeNpH7C4hhICAA==", + "dependencies": { + "ansi-red": "^0.1.1", + "coffee-script": "^1.12.4", + "extend-shallow": "^2.0.1", + "js-yaml": "^3.8.1", + "toml": "^2.3.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-header": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", + "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", + "deprecated": "Removed event-stream from gulp-header", + "dependencies": { + "concat-with-sourcemaps": "*", + "lodash.template": "^4.4.0", + "through2": "^2.0.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==", + "dependencies": { + "set-getter": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/list-item": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/list-item/-/list-item-1.1.1.tgz", + "integrity": "sha512-S3D0WZ4J6hyM8o5SNKWaMYB1ALSacPZ2nHGEuCjmHZ+dc03gFeNZoNDcqfcnO4vDhTZmNrqrpYZCdXsRh22bzw==", + "dependencies": { + "expand-range": "^1.8.1", + "extend-shallow": "^2.0.1", + "is-number": "^2.1.0", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/markdown-link": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", + "integrity": "sha512-TurLymbyLyo+kAUUAV9ggR9EPcDjP/ctlv9QAFiqUH7c+t6FlsbivPo9OKTU8xdOx9oNd2drW/Fi5RRElQbUqA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-toc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", + "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", + "dependencies": { + "concat-stream": "^1.5.2", + "diacritics-map": "^0.1.0", + "gray-matter": "^2.1.0", + "lazy-cache": "^2.0.2", + "list-item": "^1.1.1", + "markdown-link": "^0.1.1", + "minimist": "^1.2.0", + "mixin-deep": "^1.1.3", + "object.pick": "^1.2.0", + "remarkable": "^1.7.1", + "repeat-string": "^1.6.1", + "strip-color": "^0.1.0" + }, + "bin": { + "markdown-toc": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomatic/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/remarkable": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz", + "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==", + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "~0.28.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/set-getter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", + "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", + "dependencies": { + "to-object-path": "^0.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/strip-color": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", + "integrity": "sha512-p9LsUieSjWNNAxVCXLeilaDlmuUOrDS5/dF9znM1nZc7EGX5+zEFC0bEevsNIaldjlks+2jns5Siz6F9iK6jwA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toml": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", + "integrity": "sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==" + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..70202ab --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "markdown-toc": "^1.2.0" + } +} diff --git a/style-guide.md b/style-guide.md index 2149491..e8c537b 100644 --- a/style-guide.md +++ b/style-guide.md @@ -69,11 +69,12 @@ Rego is a declarative language, which in the best case means you express **what* should be retrieved. When authoring policy, do not try to be "smart" about assumed performance characteristics or optimizations. That's what OPA should worry about! -Optimize for **readability** and **obviousness**. Optimize for performance *only* if you've identified performance +Optimize for **readability** and **obviousness**. Optimize for performance _only_ if you've identified performance issues in your policy, and even if you do — making your policy more compact or "clever" almost never helps at addressing the problem at hand. #### Related Resources + - [Policy Performance](https://www.openpolicyagent.org/docs/latest/policy-performance/) ### Use `opa fmt` @@ -126,6 +127,7 @@ Annotations are also a good way to de-duplicate information such as documentatio and error codes where explanations are returned as part of the result. **Avoid** + ```rego # Example package with documentation package example @@ -144,6 +146,7 @@ deny contains { ``` **Prefer** + ```rego # METADATA # title: Example @@ -179,6 +182,7 @@ deny contains { Use regular comments inside of rule bodies, or for packages and rules you consider "internal". #### Related Resources + - [Annotations](https://www.openpolicyagent.org/docs/latest/policy-language/#metadata) ### Get to know the built-in functions @@ -200,11 +204,13 @@ developer experience as well as the quality of your policies. The built-in functions use `snake_case` for naming — follow that convention for your own rules, functions, and variables. **Avoid** + ```rego userIsAdmin if "admin" in input.user.roles ``` **Prefer** + ```rego user_is_admin if "admin" in input.user.roles ``` @@ -255,11 +261,13 @@ adding references to these rules and functions from other packages. Long lines are tedious to read. Keep line length at 120 characters or below. **Avoid** + ```rego frontend_admin_users := [username | some user in input.users; "frontend" in user.domains; "admin" in user.roles; username := user.username] ``` **Prefer** + ```rego frontend_admin_users := [username | some user in input.users @@ -282,6 +290,7 @@ Helper rules makes policies more readable, and for repeated conditions more perf more than a few simple expressions, consider splitting it into multiple rules with good names. **Avoid** + ```rego allow if { "developer" in input.user.roles @@ -333,6 +342,7 @@ rules that build [sets](https://www.openpolicyagent.org/docs/latest/policy-langu Consider for example this simple rule: **Avoid** + ```rego authorized := count(deny) == 0 @@ -353,6 +363,7 @@ This is nice in that we'll get an even more granular message returned to the cal working with a large set of input data. To deal with this, a helper rule using _negation_ may be used. **Prefer** + ```rego authorized := count(deny) == 0 @@ -366,6 +377,7 @@ but equal to "anonymous". Since we negate the result of the helper rule in the ` cases covered. #### Related Resources + - [OPA AWS CloudFormation Hook Tutorial](https://www.openpolicyagent.org/docs/latest/aws-cloudformation-hooks/) ### Consider partial helper rules over comprehensions in rule bodies @@ -376,6 +388,7 @@ Having many smaller, composable rules, is often key to quickly identifying where queried individually. **Avoid** + ```rego allow if { input.request.method in {"GET", "HEAD"} @@ -394,6 +407,7 @@ allow if { ``` **Prefer** + ```rego allow if { input.request.method in {"GET", "HEAD"} @@ -426,6 +440,7 @@ Since Rego evaluation is generally free of side effects, any rule or function is single value (i.e. a complete rule) or a collection (a partial rule). **Avoid** + ```rego get_first_name(user) := split(user.name, " ")[0] @@ -437,6 +452,7 @@ list_developers contains user if { ``` **Prefer** + ```rego # "get" is implied first_name(user) := split(user.name, " ")[0] @@ -464,6 +480,7 @@ Rules that return values unconditionally should place the assignment directly in in the rule body adds unnecessary noise. **Avoid** + ```rego full_name := name { name := concat(", ", [input.first_name, input.last_name]) @@ -473,7 +490,9 @@ divide_by_ten(x) := y { y := x / 10 } ``` + **Prefer** + ```rego full_name := concat(", ", [input.first_name, input.last_name]) @@ -493,6 +512,7 @@ Using `in` for membership checks clearly communicates intent, and is less prone checking if something is _not_ part of a collection. **Avoid** + ```rego # "Old" way of checking for membership - iteration + comparison allow { @@ -501,11 +521,13 @@ allow { ``` **Prefer** + ```rego allow if "admin" in input.user.roles ``` **Avoid** + ```rego deny contains "Only admin allowed" if not user_is_admin @@ -515,6 +537,7 @@ user_is_admin if { ``` **Prefer** + ```rego deny contains "Only admin allowed" if not "admin" in input.user.roles ``` @@ -530,6 +553,7 @@ Using the `some` .. `in` construct for iteration removes ambiguity around iterat generally more pleasant to read. **Avoid** + ```rego my_rule if { # Are we iterating users over a partial "other_rule" here, @@ -542,6 +566,7 @@ While this could be alleviated by declaring `some user` before the iteration, we granted when reading code from someone else. **Avoid** + ```rego # Iterating over array internal_hosts contains hostname if { @@ -559,6 +584,7 @@ public_endpoints contains endpoint if { ``` **Prefer** + ```rego internal_hosts contains hostname if { some host in data.network.hosts @@ -604,6 +630,7 @@ helper rules, or comparing counts of items in the original collection against a comprehension. **Avoid** + ```rego # Negate result of _any_ match allow if not any_old_registry @@ -615,6 +642,7 @@ any_old_registry if { ``` **Prefer** + ```rego allow if { every container in input.request.object.spec.containers { @@ -624,6 +652,7 @@ allow if { ``` **Avoid** + ```rego words := ["always", "arbitrary", "air", "brand", "asphalt"] @@ -637,6 +666,7 @@ all_starts_with_a if { ``` **Prefer** + ```rego words := ["always", "arbitrary", "air", "brand", "asphalt"] @@ -661,6 +691,7 @@ preferable. Separating assignment from comparison clearly demonstrates intent, a associated with unification. **Avoid** + ```rego # Top level assignment using unification operator roles = input.user.roles @@ -686,6 +717,7 @@ allow if { ``` **Prefer** + ```rego # Top level assignment using assignment operator roles := input.user.roles @@ -739,6 +771,7 @@ router { ``` #### Related Resources + - [Strict-mode to phase-out the "single =" operator](https://github.com/open-policy-agent/opa/issues/4688) - [OPA fmt 2.0](https://github.com/open-policy-agent/opa/issues/4508) @@ -753,6 +786,7 @@ Using undeclared variables (i.e. not declared using `some` or `:=`) makes it har in a rule, and introduces ambiguities around scope. **Avoid** + ```rego messages contains message if { message := input.topics[topic].body @@ -760,6 +794,7 @@ messages contains message if { ``` **Prefer** + ```rego messages contains message if { some topic @@ -786,18 +821,19 @@ Regal rule. Get started with [Regal, the Rego linter](https://docs.styra.com/reg ### Prefer sets over arrays (where applicable) -For any *unordered* sequence of *unique* values, prefer to use +For any _unordered_ sequence of _unique_ values, prefer to use [sets](https://www.openpolicyagent.org/docs/latest/policy-reference/#sets) over [arrays](https://www.openpolicyagent.org/docs/latest/policy-reference/#arrays). This is almost always the case for common policy data like **roles** and **permissions**. For any applicable sequence of values, sets have the following benefits over arrays: -* Clearly communicate uniqueness and non-ordered characteristics -* Performance: set lookups are O(1) while array lookups are O(n) -* Powerful [set operations](https://www.openpolicyagent.org/docs/latest/policy-reference/#sets-2) available +- Clearly communicate uniqueness and non-ordered characteristics +- Performance: set lookups are O(1) while array lookups are O(n) +- Powerful [set operations](https://www.openpolicyagent.org/docs/latest/policy-reference/#sets-2) available **Avoid** + ```rego required_roles := ["accountant", "reports-writer"] provided_roles := [role | some role in input.user.roles] @@ -810,6 +846,7 @@ allow if { ``` **Prefer** + ```rego required_roles := {"accountant", "reports-writer"} provided_roles := {role | some role in input.user.roles} @@ -822,6 +859,7 @@ allow if { ``` **Prefer** + ```rego # Alternatively, use set intersection allow if { @@ -830,6 +868,7 @@ allow if { ``` #### Related Resources + - [Five things you didn't know about OPA](https://blog.styra.com/blog/five-things-you-didnt-know-about-opa). ## Functions @@ -842,6 +881,7 @@ checking the function signature, and it makes it harder to reuse that function i functions that only depend on their arguments are easier to test standalone. **Avoid** + ```rego # Depends on both `input` and `data` is_preferred_login_method(method) if { @@ -854,6 +894,7 @@ is_preferred_login_method(method) if { ``` **Prefer** + ```rego # Depends only on function arguments is_preferred_login_method(method, user, all_login_methods) if { @@ -874,6 +915,7 @@ either using assignment (i.e. `:=`) or by appending a variable name to the argum expressions are thus equivalent: **Avoid** + ```rego first_a := i if { indexof("answer", "a", i) @@ -881,6 +923,7 @@ first_a := i if { ``` **Prefer** + ```rego first_a := i if { i := indexof("answer", "a") @@ -903,6 +946,7 @@ Regal rule. Get started with [Regal, the Rego linter](https://docs.styra.com/reg you to avoid having to escape special characters like `\` in your regex patterns. **Avoid** + ```rego all_digits if { regex.match("[\\d]+", "12345") @@ -910,6 +954,7 @@ all_digits if { ``` **Prefer** + ```rego all_digits if { regex.match(`[\d]+`, "12345") @@ -929,6 +974,7 @@ Importing packages rather than specific rules and functions allows you to refere obvious where the rule or function was declared. Additionally, well-named packages help provide context to assertions. **Avoid** + ```rego import data.user.is_admin @@ -936,6 +982,7 @@ allow if is_admin ``` **Prefer** + ```rego import data.user @@ -954,6 +1001,7 @@ of the attribute(s) less apparent. Clearly differentiating `input` and `data` fr defined inside of the same package helps in making things _obvious_, and few things beat obviousness! **Avoid** + ```rego import input.request.context.user @@ -966,6 +1014,7 @@ fin_dept if { ``` **Prefer** + ```rego fin_dept if { contains(input.request.context.user.department, "finance") @@ -973,6 +1022,7 @@ fin_dept if { ``` **Prefer** + ```rego fin_dept if { # Alternatively, assign an intermediate variable close to where it's referenced @@ -1017,6 +1067,7 @@ import all of the future keywords, this construct risks breaking your policies w their names happen to collide with names you've used for variables or rules. **Avoid** + ```rego import future.keywords @@ -1027,6 +1078,7 @@ severe_violations contains violation if { ``` **Prefer** + ```rego import future.keywords.contains import future.keywords.if From 4c7c854ee2fec16b793e52df7e44f7cfd73838a7 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 09:35:39 +0100 Subject: [PATCH 2/7] docs: Add package name dir matching Signed-off-by: Charlie Egan --- style-guide.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/style-guide.md b/style-guide.md index e8c537b..de9ccf6 100644 --- a/style-guide.md +++ b/style-guide.md @@ -51,6 +51,8 @@ Rego policies. If you enjoy this style guide, make sure to check it out! * [Avoid using the last argument for the return value](#avoid-using-the-last-argument-for-the-return-value) * [Regex](#regex) * [Use raw strings for regex patterns](#use-raw-strings-for-regex-patterns) +* [Packages](#packages) + * [Package name should make file location](#package-name-should-make-file-location) * [Imports](#imports) * [Prefer importing packages over rules and functions](#prefer-importing-packages-over-rules-and-functions) * [Avoid importing `input`](#avoid-importing-input) @@ -966,6 +968,32 @@ You can lint for this recommendation using the [`non-raw-regex-pattern`](https:/ Regal rule. Get started with [Regal, the Rego linter](https://docs.styra.com/regal). ::: +## Packages + +### Package name should make file location + +When naming packages, the package name should reflect the file's location. This +makes the package implementation easier to find when looking up from elsewhere +in a project as well. + +**Avoid** + +```rego +# foo/bar.rego +package bar.foo + +# ... +``` + +**Prefer** + +```rego +# foo/bar.rego +package foo.bar + +# ... +``` + ## Imports ### Prefer importing packages over rules and functions From fbf4539e1b8fa5a2e930ff3945aae083d8db84c3 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 09:43:58 +0100 Subject: [PATCH 3/7] Use mdtoc from package.json --- .github/workflows/ci.yaml | 29 ++++++++++++++--------------- .gitignore | 3 ++- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4c7c6dc..4cf8b36 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,18 +6,17 @@ jobs: ci: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - run: npm install -g markdown-toc - - run: sudo apt-get update && sudo apt-get -y install make git - - run: make toc - - run: git diff - - run: | - if [ -z "$(git status --porcelain)" ]; then - echo "No changes" - else - echo "Please update the table of contents with make toc" - exit 1 - fi + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm install + - run: make toc + - run: git diff + - run: | + if [ -z "$(git status --porcelain)" ]; then + echo "No changes" + else + echo "Please update the table of contents with make toc" + exit 1 + fi diff --git a/.gitignore b/.gitignore index 62c8935..1fe1b00 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.idea/ \ No newline at end of file +.idea/ +node_modules/ From da6d6a5eae0b26d4d264b0b091c7c649dd69d2c9 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 10:41:59 +0100 Subject: [PATCH 4/7] Update linting config --- .github/workflows/ci.yaml | 9 + .markdownlint.yaml | 44 ++++ Makefile | 10 +- package-lock.json | 416 +++++++++++++++++++++++++++++++++++++- package.json | 3 +- 5 files changed, 478 insertions(+), 4 deletions(-) create mode 100644 .markdownlint.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4cf8b36..107648e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,3 +20,12 @@ jobs: echo "Please update the table of contents with make toc" exit 1 fi + - run: make markdownlint + - run: git diff + - run: | + if [ -z "$(git status --porcelain)" ]; then + echo "No changes" + else + echo "Please fix the markdownlint errors" + exit 1 + fi diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..d420777 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,44 @@ +default: true + +# MD013/line-length +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md013.md +MD013: + line_length: 120 + heading_line_length: 80 + code_blocks: false + tables: false + headings: true + +# MD024/no-duplicate-heading +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md024.md +MD024: + siblings_only: true + +# MD026/no-trailing-punctuation +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md026.md +MD026: + # Punctuation characters + punctuation: ".,;:,;:!" + +# MD031/blanks-around-fences +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md031.md +MD031: false + +# MD033/no-inline-html +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md033.md +MD033: + allowed_elements: + - br + - details + - img + - strong + - summary + +# MD036/no-emphasis-as-heading +# https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md036.md +MD036: false + +MD004: + style: dash + +MD010: false diff --git a/Makefile b/Makefile index ce8c0cc..867f390 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,10 @@ +PHONY: deps +deps: + npm install + PHONY: toc -toc: - npm install # installs the markdown-toc at the expected version from package.json +toc: deps npx markdown-toc -i style-guide.md --bullets="*" --maxdepth=3 + +markdownlint: deps + npx markdownlint-cli2 style-guide.md --config=.markdownlint.yaml diff --git a/package-lock.json b/package-lock.json index cc2c24c..6a27e39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,51 @@ "packages": { "": { "dependencies": { - "markdown-toc": "^1.2.0" + "markdown-toc": "^1.2.0", + "markdownlint-cli2": "^0.13.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-red": { @@ -43,6 +87,28 @@ "gulp-header": "^1.7.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/braces/node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -96,6 +162,17 @@ "node": ">=0.8.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -130,6 +207,29 @@ "node": ">=0.10.0" } }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", @@ -153,6 +253,36 @@ "node": ">=0.10.0" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gray-matter": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", @@ -179,6 +309,14 @@ "through2": "^2.0.0" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -197,6 +335,25 @@ "node": ">=0.10.0" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -255,6 +412,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==" + }, "node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -277,6 +439,14 @@ "node": ">=0.10.0" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/list-item": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/list-item/-/list-item-1.1.1.tgz", @@ -313,6 +483,27 @@ "lodash._reinterpolate": "^3.0.0" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/markdown-link": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/markdown-link/-/markdown-link-0.1.1.tgz", @@ -346,11 +537,108 @@ "node": ">=0.10.0" } }, + "node_modules/markdownlint": { + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", + "dependencies": { + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.13.0.tgz", + "integrity": "sha512-Pg4nF7HlopU97ZXtrcVISWp3bdsuc5M0zXyLp2/sJv2zEMlInrau0ZKK482fQURzVezJzWBpNmu4u6vGAhij+g==", + "dependencies": { + "globby": "14.0.1", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.1", + "markdownlint": "0.34.0", + "markdownlint-cli2-formatter-default": "0.0.4", + "micromatch": "4.0.5" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.4.tgz", + "integrity": "sha512-xm2rM0E+sWgjpPn1EesPXx5hIyrN2ddUnUwnbCsD/ONxYtw3PX6LydvdH6dciWAoFDpwzbHM1TO7uHfcMd6IYg==", + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdownlint-cli2/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, "node_modules/math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -401,11 +689,60 @@ "node": ">=0.10.0" } }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/randomatic": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", @@ -480,6 +817,37 @@ "node": ">=0.10" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -496,6 +864,17 @@ "node": ">=0.10.0" } }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -545,6 +924,25 @@ "node": ">=0.10.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/toml": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.6.tgz", @@ -555,6 +953,22 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 70202ab..4a9c4e1 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { - "markdown-toc": "^1.2.0" + "markdown-toc": "^1.2.0", + "markdownlint-cli2": "^0.13.0" } } From 9b7f0f584baaa1de9263480c53016eeb5ac45b38 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 10:44:32 +0100 Subject: [PATCH 5/7] Update desc for package dir struct --- style-guide.md | 55 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/style-guide.md b/style-guide.md index de9ccf6..aff0ccd 100644 --- a/style-guide.md +++ b/style-guide.md @@ -10,7 +10,7 @@ With new features, language constructs, and other improvements continuously find this style guide a reflection of what we consider current best practices. Make sure to check back every once in a while, and see the changelog for updates since your last visit. -### Regal +## Regal Inspired by this style guide, [Regal](https://github.com/StyraInc/regal) is a new linter for Rego that allows you to enforce many of the recommendations in this guide, as well as identifying issues, bugs and potential problems in your @@ -18,6 +18,8 @@ Rego policies. If you enjoy this style guide, make sure to check it out! ## Contents + + @@ -51,8 +53,7 @@ Rego policies. If you enjoy this style guide, make sure to check it out! * [Avoid using the last argument for the return value](#avoid-using-the-last-argument-for-the-return-value) * [Regex](#regex) * [Use raw strings for regex patterns](#use-raw-strings-for-regex-patterns) -* [Packages](#packages) - * [Package name should make file location](#package-name-should-make-file-location) + * [Package name should match file location](#package-name-should-match-file-location) * [Imports](#imports) * [Prefer importing packages over rules and functions](#prefer-importing-packages-over-rules-and-functions) * [Avoid importing `input`](#avoid-importing-input) @@ -63,6 +64,9 @@ Rego policies. If you enjoy this style guide, make sure to check it out! + + + ## General Advice ### Optimize for readability, not performance @@ -968,14 +972,27 @@ You can lint for this recommendation using the [`non-raw-regex-pattern`](https:/ Regal rule. Get started with [Regal, the Rego linter](https://docs.styra.com/regal). ::: -## Packages - -### Package name should make file location +### Package name should match file location -When naming packages, the package name should reflect the file's location. This +When naming packages, the package name should reflect the file location. This makes the package implementation easier to find when looking up from elsewhere in a project as well. +When choosing to follow this recommendation, there are two options: + +- **Matching the directory and filename** + - Pros: Reduced nesting for simple policies. + - Cons: Large packages can become unwieldy in long files. +- **Matching the directory only** + - Pros: Large packages can be broken into many files. + - Cons: Exception needed to co-locate test files (i.e. `pacakge foo_test` + should still be in `foo/`). + +Either is acceptable, just remember to use the same convention throughout +your project. + +#### Matching the directory and filename + **Avoid** ```rego @@ -994,6 +1011,26 @@ package foo.bar # ... ``` +#### Matching the directory only + +**Avoid** + +```rego +# foo/bar.rego +package baz + +# ... +``` + +**Prefer** + +```rego +# foo/bar.rego +package foo + +# ... +``` + ## Imports ### Prefer importing packages over rules and functions @@ -1138,4 +1175,6 @@ If you'd like to add or remove items for your own company, team or project, fork ## Community -For questions, discussions and announcements related to Styra products, services and open source projects, please join the Styra community on [Slack](https://communityinviter.com/apps/styracommunity/signup)! +For questions, discussions and announcements related to +Styra products, services and open source projects, please join +the Styra community on [Slack](https://communityinviter.com/apps/styracommunity/signup)! From a620cb3bce97f072308c411252af7c7d6b216403 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 10:44:43 +0100 Subject: [PATCH 6/7] Revert spacing --- style-guide.md | 51 -------------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/style-guide.md b/style-guide.md index aff0ccd..20c0128 100644 --- a/style-guide.md +++ b/style-guide.md @@ -133,7 +133,6 @@ Annotations are also a good way to de-duplicate information such as documentatio and error codes where explanations are returned as part of the result. **Avoid** - ```rego # Example package with documentation package example @@ -152,7 +151,6 @@ deny contains { ``` **Prefer** - ```rego # METADATA # title: Example @@ -210,13 +208,11 @@ developer experience as well as the quality of your policies. The built-in functions use `snake_case` for naming — follow that convention for your own rules, functions, and variables. **Avoid** - ```rego userIsAdmin if "admin" in input.user.roles ``` **Prefer** - ```rego user_is_admin if "admin" in input.user.roles ``` @@ -267,13 +263,11 @@ adding references to these rules and functions from other packages. Long lines are tedious to read. Keep line length at 120 characters or below. **Avoid** - ```rego frontend_admin_users := [username | some user in input.users; "frontend" in user.domains; "admin" in user.roles; username := user.username] ``` **Prefer** - ```rego frontend_admin_users := [username | some user in input.users @@ -296,7 +290,6 @@ Helper rules makes policies more readable, and for repeated conditions more perf more than a few simple expressions, consider splitting it into multiple rules with good names. **Avoid** - ```rego allow if { "developer" in input.user.roles @@ -312,7 +305,6 @@ allow if { ``` **Prefer** - ```rego allow if { is_developer @@ -348,7 +340,6 @@ rules that build [sets](https://www.openpolicyagent.org/docs/latest/policy-langu Consider for example this simple rule: **Avoid** - ```rego authorized := count(deny) == 0 @@ -369,7 +360,6 @@ This is nice in that we'll get an even more granular message returned to the cal working with a large set of input data. To deal with this, a helper rule using _negation_ may be used. **Prefer** - ```rego authorized := count(deny) == 0 @@ -394,7 +384,6 @@ Having many smaller, composable rules, is often key to quickly identifying where queried individually. **Avoid** - ```rego allow if { input.request.method in {"GET", "HEAD"} @@ -413,7 +402,6 @@ allow if { ``` **Prefer** - ```rego allow if { input.request.method in {"GET", "HEAD"} @@ -446,7 +434,6 @@ Since Rego evaluation is generally free of side effects, any rule or function is single value (i.e. a complete rule) or a collection (a partial rule). **Avoid** - ```rego get_first_name(user) := split(user.name, " ")[0] @@ -458,7 +445,6 @@ list_developers contains user if { ``` **Prefer** - ```rego # "get" is implied first_name(user) := split(user.name, " ")[0] @@ -486,7 +472,6 @@ Rules that return values unconditionally should place the assignment directly in in the rule body adds unnecessary noise. **Avoid** - ```rego full_name := name { name := concat(", ", [input.first_name, input.last_name]) @@ -498,7 +483,6 @@ divide_by_ten(x) := y { ``` **Prefer** - ```rego full_name := concat(", ", [input.first_name, input.last_name]) @@ -518,7 +502,6 @@ Using `in` for membership checks clearly communicates intent, and is less prone checking if something is _not_ part of a collection. **Avoid** - ```rego # "Old" way of checking for membership - iteration + comparison allow { @@ -527,13 +510,11 @@ allow { ``` **Prefer** - ```rego allow if "admin" in input.user.roles ``` **Avoid** - ```rego deny contains "Only admin allowed" if not user_is_admin @@ -543,7 +524,6 @@ user_is_admin if { ``` **Prefer** - ```rego deny contains "Only admin allowed" if not "admin" in input.user.roles ``` @@ -559,7 +539,6 @@ Using the `some` .. `in` construct for iteration removes ambiguity around iterat generally more pleasant to read. **Avoid** - ```rego my_rule if { # Are we iterating users over a partial "other_rule" here, @@ -572,7 +551,6 @@ While this could be alleviated by declaring `some user` before the iteration, we granted when reading code from someone else. **Avoid** - ```rego # Iterating over array internal_hosts contains hostname if { @@ -590,7 +568,6 @@ public_endpoints contains endpoint if { ``` **Prefer** - ```rego internal_hosts contains hostname if { some host in data.network.hosts @@ -636,7 +613,6 @@ helper rules, or comparing counts of items in the original collection against a comprehension. **Avoid** - ```rego # Negate result of _any_ match allow if not any_old_registry @@ -648,7 +624,6 @@ any_old_registry if { ``` **Prefer** - ```rego allow if { every container in input.request.object.spec.containers { @@ -658,7 +633,6 @@ allow if { ``` **Avoid** - ```rego words := ["always", "arbitrary", "air", "brand", "asphalt"] @@ -672,7 +646,6 @@ all_starts_with_a if { ``` **Prefer** - ```rego words := ["always", "arbitrary", "air", "brand", "asphalt"] @@ -697,7 +670,6 @@ preferable. Separating assignment from comparison clearly demonstrates intent, a associated with unification. **Avoid** - ```rego # Top level assignment using unification operator roles = input.user.roles @@ -723,7 +695,6 @@ allow if { ``` **Prefer** - ```rego # Top level assignment using assignment operator roles := input.user.roles @@ -792,7 +763,6 @@ Using undeclared variables (i.e. not declared using `some` or `:=`) makes it har in a rule, and introduces ambiguities around scope. **Avoid** - ```rego messages contains message if { message := input.topics[topic].body @@ -800,7 +770,6 @@ messages contains message if { ``` **Prefer** - ```rego messages contains message if { some topic @@ -839,7 +808,6 @@ For any applicable sequence of values, sets have the following benefits over arr - Powerful [set operations](https://www.openpolicyagent.org/docs/latest/policy-reference/#sets-2) available **Avoid** - ```rego required_roles := ["accountant", "reports-writer"] provided_roles := [role | some role in input.user.roles] @@ -852,7 +820,6 @@ allow if { ``` **Prefer** - ```rego required_roles := {"accountant", "reports-writer"} provided_roles := {role | some role in input.user.roles} @@ -865,7 +832,6 @@ allow if { ``` **Prefer** - ```rego # Alternatively, use set intersection allow if { @@ -887,7 +853,6 @@ checking the function signature, and it makes it harder to reuse that function i functions that only depend on their arguments are easier to test standalone. **Avoid** - ```rego # Depends on both `input` and `data` is_preferred_login_method(method) if { @@ -900,7 +865,6 @@ is_preferred_login_method(method) if { ``` **Prefer** - ```rego # Depends only on function arguments is_preferred_login_method(method, user, all_login_methods) if { @@ -921,7 +885,6 @@ either using assignment (i.e. `:=`) or by appending a variable name to the argum expressions are thus equivalent: **Avoid** - ```rego first_a := i if { indexof("answer", "a", i) @@ -929,7 +892,6 @@ first_a := i if { ``` **Prefer** - ```rego first_a := i if { i := indexof("answer", "a") @@ -952,7 +914,6 @@ Regal rule. Get started with [Regal, the Rego linter](https://docs.styra.com/reg you to avoid having to escape special characters like `\` in your regex patterns. **Avoid** - ```rego all_digits if { regex.match("[\\d]+", "12345") @@ -960,7 +921,6 @@ all_digits if { ``` **Prefer** - ```rego all_digits if { regex.match(`[\d]+`, "12345") @@ -994,7 +954,6 @@ your project. #### Matching the directory and filename **Avoid** - ```rego # foo/bar.rego package bar.foo @@ -1003,7 +962,6 @@ package bar.foo ``` **Prefer** - ```rego # foo/bar.rego package foo.bar @@ -1014,7 +972,6 @@ package foo.bar #### Matching the directory only **Avoid** - ```rego # foo/bar.rego package baz @@ -1023,7 +980,6 @@ package baz ``` **Prefer** - ```rego # foo/bar.rego package foo @@ -1039,7 +995,6 @@ Importing packages rather than specific rules and functions allows you to refere obvious where the rule or function was declared. Additionally, well-named packages help provide context to assertions. **Avoid** - ```rego import data.user.is_admin @@ -1047,7 +1002,6 @@ allow if is_admin ``` **Prefer** - ```rego import data.user @@ -1066,7 +1020,6 @@ of the attribute(s) less apparent. Clearly differentiating `input` and `data` fr defined inside of the same package helps in making things _obvious_, and few things beat obviousness! **Avoid** - ```rego import input.request.context.user @@ -1079,7 +1032,6 @@ fin_dept if { ``` **Prefer** - ```rego fin_dept if { contains(input.request.context.user.department, "finance") @@ -1087,7 +1039,6 @@ fin_dept if { ``` **Prefer** - ```rego fin_dept if { # Alternatively, assign an intermediate variable close to where it's referenced @@ -1132,7 +1083,6 @@ import all of the future keywords, this construct risks breaking your policies w their names happen to collide with names you've used for variables or rules. **Avoid** - ```rego import future.keywords @@ -1143,7 +1093,6 @@ severe_violations contains violation if { ``` **Prefer** - ```rego import future.keywords.contains import future.keywords.if From a7fadd9bb87cfa80131ed3bb76c213089255fc31 Mon Sep 17 00:00:00 2001 From: Charlie Egan Date: Tue, 27 Aug 2024 10:46:55 +0100 Subject: [PATCH 7/7] typo --- style-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/style-guide.md b/style-guide.md index 20c0128..afff00a 100644 --- a/style-guide.md +++ b/style-guide.md @@ -945,7 +945,7 @@ When choosing to follow this recommendation, there are two options: - Cons: Large packages can become unwieldy in long files. - **Matching the directory only** - Pros: Large packages can be broken into many files. - - Cons: Exception needed to co-locate test files (i.e. `pacakge foo_test` + - Cons: Exception needed to co-locate test files (i.e. `package foo_test` should still be in `foo/`). Either is acceptable, just remember to use the same convention throughout