From e8a2d5be0d3b06e50bbe6f379e850d0c03f299da Mon Sep 17 00:00:00 2001 From: David Thor Date: Fri, 1 Dec 2023 16:50:26 -0500 Subject: [PATCH 1/3] Added support for static buckets --- deno.lock | 106 +- examples/datacenters/local/datacenter.arc | 86 + src/@resources/bucket/README.md | 2 + src/@resources/bucket/inputs.schema.json | 10 + src/@resources/bucket/inputs.ts | 3 + src/@resources/bucket/outputs.schema.json | 46 + src/@resources/bucket/outputs.ts | 32 + src/@resources/ingress/inputs.schema.json | 233 +- src/@resources/ingress/inputs.ts | 22 +- src/@resources/task/inputs.schema.json | 141 + src/@resources/task/inputs.ts | 79 + src/@resources/task/outputs.schema.json | 10 + src/@resources/task/outputs.ts | 3 + src/@resources/types.ts | 15 +- src/@resources/volume/inputs.schema.json | 10 - src/@resources/volume/inputs.ts | 6 - src/@resources/volume/outputs.schema.json | 14 +- src/@resources/volume/outputs.ts | 9 +- src/commands/build/component.ts | 65 - src/commands/tag.ts | 2 +- src/components/__tests__/version-helper.ts | 1 - src/components/component-schema.ts | 6215 +++++++++-------- src/components/component.schema.json | 255 +- src/components/component.ts | 16 +- src/components/schema.ts | 3 +- src/components/v1/__tests__/index.test.ts | 2 - src/components/v1/index.ts | 74 +- src/components/v2/__tests__/index.test.ts | 2 - src/components/v2/bucket.ts | 41 + src/components/v2/container.ts | 75 + src/components/v2/deployment.ts | 77 +- src/components/v2/index.ts | 426 +- src/components/v2/schema.json | 255 +- src/datacenters/datacenter-schema.ts | 3205 +++++---- src/datacenters/datacenter.schema.json | 328 +- src/datacenters/schema.ts | 10 +- .../v1/__tests__/datacenter.test.ts | 4 - src/datacenters/v1/schema.json | 328 +- src/environments/environment-schema.ts | 334 +- src/environments/schema.ts | 12 +- 40 files changed, 7468 insertions(+), 5089 deletions(-) create mode 100644 src/@resources/bucket/README.md create mode 100644 src/@resources/bucket/inputs.schema.json create mode 100644 src/@resources/bucket/inputs.ts create mode 100644 src/@resources/bucket/outputs.schema.json create mode 100644 src/@resources/bucket/outputs.ts create mode 100644 src/@resources/task/inputs.schema.json create mode 100644 src/@resources/task/inputs.ts create mode 100644 src/@resources/task/outputs.schema.json create mode 100644 src/@resources/task/outputs.ts create mode 100644 src/components/v2/bucket.ts create mode 100644 src/components/v2/container.ts diff --git a/deno.lock b/deno.lock index 4bc4d607b..eb945a51d 100644 --- a/deno.lock +++ b/deno.lock @@ -2,6 +2,8 @@ "version": "3", "packages": { "specifiers": { + "npm:@types/node": "npm:@types/node@18.16.19", + "npm:@types/pg@^8.6.5": "npm:@types/pg@8.10.9", "npm:mustache": "npm:mustache@4.2.0", "npm:pg@8.8.0": "npm:pg@8.8.0", "npm:ts-json-schema-generator": "npm:ts-json-schema-generator@1.2.0" @@ -11,6 +13,18 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dependencies": {} }, + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "@types/pg@8.10.9": { + "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "dependencies": { + "@types/node": "@types/node@18.16.19", + "pg-protocol": "pg-protocol@1.6.0", + "pg-types": "pg-types@4.0.1" + } + }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dependencies": {} @@ -72,6 +86,10 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dependencies": {} }, + "obuf@1.1.2": { + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dependencies": {} + }, "once@1.4.0": { "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { @@ -90,6 +108,10 @@ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "dependencies": {} }, + "pg-numeric@1.0.2": { + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dependencies": {} + }, "pg-pool@3.6.1_pg@8.8.0": { "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", "dependencies": { @@ -110,6 +132,18 @@ "postgres-interval": "postgres-interval@1.2.0" } }, + "pg-types@4.0.1": { + "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dependencies": { + "pg-int8": "pg-int8@1.0.1", + "pg-numeric": "pg-numeric@1.0.2", + "postgres-array": "postgres-array@3.0.2", + "postgres-bytea": "postgres-bytea@3.0.0", + "postgres-date": "postgres-date@2.0.1", + "postgres-interval": "postgres-interval@3.0.0", + "postgres-range": "postgres-range@1.1.3" + } + }, "pg@8.8.0": { "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", "dependencies": { @@ -132,20 +166,42 @@ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "dependencies": {} }, + "postgres-array@3.0.2": { + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dependencies": {} + }, "postgres-bytea@1.0.0": { "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", "dependencies": {} }, + "postgres-bytea@3.0.0": { + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dependencies": { + "obuf": "obuf@1.1.2" + } + }, "postgres-date@1.0.7": { "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", "dependencies": {} }, + "postgres-date@2.0.1": { + "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dependencies": {} + }, "postgres-interval@1.2.0": { "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "dependencies": { "xtend": "xtend@4.0.2" } }, + "postgres-interval@3.0.0": { + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dependencies": {} + }, + "postgres-range@1.1.3": { + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", + "dependencies": {} + }, "safe-stable-stringify@2.4.3": { "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", "dependencies": {} @@ -180,6 +236,13 @@ } } }, + "redirects": { + "https://esm.sh/v124/@types/escodegen@latest/index.d.ts": "https://esm.sh/v124/@types/escodegen@0.0.9/index.d.ts", + "https://esm.sh/v124/@types/estraverse@^5/index.d.ts": "https://esm.sh/v124/@types/estraverse@5.1.4/index.d.ts", + "https://esm.sh/v124/@types/events@~1.1/index.d.ts": "https://esm.sh/v124/@types/events@1.1.0/index.d.ts", + "https://esm.sh/v124/@types/js-yaml@^4/index.d.ts": "https://esm.sh/v124/@types/js-yaml@4.0.5/index.d.ts", + "https://esm.sh/v124/@types/tar@^6/index.d.ts": "https://esm.sh/v124/@types/tar@6.1.6/index.d.ts" + }, "remote": { "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", @@ -478,6 +541,18 @@ "https://deno.land/std@0.177.0/node/string_decoder.ts": "1a17e3572037c512cc5fc4b29076613e90f225474362d18da908cb7e5ccb7e88", "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", "https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.181.0/bytes/bytes_list.ts": "b4cbdfd2c263a13e8a904b12d082f6177ea97d9297274a4be134e989450dfa6a", + "https://deno.land/std@0.181.0/bytes/concat.ts": "d26d6f3d7922e6d663dacfcd357563b7bf4a380ce5b9c2bbe0c8586662f25ce2", + "https://deno.land/std@0.181.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", + "https://deno.land/std@0.181.0/bytes/ends_with.ts": "4228811ebc71615d27f065c54b5e815ec1972538772b0f413c0efe05245b472e", + "https://deno.land/std@0.181.0/bytes/equals.ts": "b87494ce5442dc786db46f91378100028c402f83a14a2f7bbff6bda7810aefe3", + "https://deno.land/std@0.181.0/bytes/includes_needle.ts": "76a8163126fb2f8bf86fd7f22192c3bb04bf6a20b987a095127c2ca08adf3ba6", + "https://deno.land/std@0.181.0/bytes/index_of_needle.ts": "65c939607df609374c4415598fa4dad04a2f14c4d98cd15775216f0aaf597f24", + "https://deno.land/std@0.181.0/bytes/last_index_of_needle.ts": "7181072883cb4908c6ce8f7a5bb1d96787eef2c2ab3aa94fe4268ab326a53cbf", + "https://deno.land/std@0.181.0/bytes/mod.ts": "e869bba1e7a2e3a9cc6c2d55471888429a544e70a840c087672e656e7ba21815", + "https://deno.land/std@0.181.0/bytes/repeat.ts": "6f5e490d8d72bcbf8d84a6bb04690b9b3eb5822c5a11687bca73a2318a842294", + "https://deno.land/std@0.181.0/bytes/starts_with.ts": "3e607a70c9c09f5140b7a7f17a695221abcc7244d20af3eb47ccbb63f5885135", + "https://deno.land/std@0.181.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", "https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", "https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", "https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", @@ -491,6 +566,9 @@ "https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", "https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", "https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.181.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.181.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.181.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", "https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", "https://deno.land/std@0.182.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", "https://deno.land/std@0.182.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", @@ -512,6 +590,7 @@ "https://deno.land/std@0.192.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", "https://deno.land/std@0.192.0/collections/_utils.ts": "5114abc026ddef71207a79609b984614e66a63a4bda17d819d56b0e72c51527e", "https://deno.land/std@0.192.0/collections/deep_merge.ts": "5a8ed29030f4471a5272785c57c3455fa79697b9a8f306013a8feae12bafc99a", + "https://deno.land/std@0.192.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", "https://deno.land/std@0.192.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", "https://deno.land/std@0.192.0/fs/copy.ts": "14214efd94fc3aa6db1e4af2b4b9578e50f7362b7f3725d5a14ad259a5df26c8", "https://deno.land/std@0.192.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", @@ -526,6 +605,12 @@ "https://deno.land/std@0.192.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", "https://deno.land/std@0.192.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", "https://deno.land/std@0.192.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.192.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.192.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.192.0/testing/_test_suite.ts": "30f018feeb3835f12ab198d8a518f9089b1bcb2e8c838a8b615ab10d5005465c", + "https://deno.land/std@0.192.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/std@0.192.0/testing/bdd.ts": "59f7f7503066d66a12e50ace81bfffae5b735b6be1208f5684b630ae6b4de1d0", + "https://deno.land/std@0.192.0/testing/mock.ts": "220ed9b8151cb2cac141043d4cfea7c47673fab5d18d1c1f0943297c8afb5d13", "https://deno.land/std@0.195.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", "https://deno.land/std@0.195.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", "https://deno.land/std@0.195.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", @@ -548,6 +633,7 @@ "https://deno.land/std@0.50.0/path/posix.ts": "b742fe902d5d6821c39c02319eb32fc5a92b4d4424b533c47f1a50610afbf381", "https://deno.land/x/cliffy@v0.25.7/_utils/distance.ts": "02af166952c7c358ac83beae397aa2fbca4ad630aecfcd38d92edb1ea429f004", "https://deno.land/x/cliffy@v0.25.7/ansi/ansi_escapes.ts": "885f61f343223f27b8ec69cc138a54bea30542924eacd0f290cd84edcf691387", + "https://deno.land/x/cliffy@v0.25.7/ansi/chain.ts": "31fb9fcbf72fed9f3eb9b9487270d2042ccd46a612d07dd5271b1a80ae2140a0", "https://deno.land/x/cliffy@v0.25.7/ansi/colors.ts": "5f71993af5bd1aa0a795b15f41692d556d7c89584a601fed75997df844b832c9", "https://deno.land/x/cliffy@v0.25.7/ansi/cursor_position.ts": "d537491e31d9c254b208277448eff92ff7f55978c4928dea363df92c0df0813f", "https://deno.land/x/cliffy@v0.25.7/ansi/deps.ts": "0f35cb7e91868ce81561f6a77426ea8bc55dc15e13f84c7352f211023af79053", @@ -597,6 +683,7 @@ "https://deno.land/x/cliffy@v0.25.7/flags/types/string.ts": "e89b6a5ce322f65a894edecdc48b44956ec246a1d881f03e97bbda90dd8638c5", "https://deno.land/x/cliffy@v0.25.7/keycode/key_code.ts": "c4ab0ffd102c2534962b765ded6d8d254631821bf568143d9352c1cdcf7a24be", "https://deno.land/x/cliffy@v0.25.7/keycode/key_codes.ts": "917f0a2da0dbace08cf29bcfdaaa2257da9fe7e705fff8867d86ed69dfb08cfe", + "https://deno.land/x/cliffy@v0.25.7/keycode/mod.ts": "292d2f295316c6e0da6955042a7b31ab2968ff09f2300541d00f05ed6c2aa2d4", "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_input.ts": "737cff2de02c8ce35250f5dd79c67b5fc176423191a2abd1f471a90dd725659e", "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_list.ts": "79b301bf09eb19f0d070d897f613f78d4e9f93100d7e9a26349ef0bfaa7408d2", "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_prompt.ts": "8630ce89a66d83e695922df41721cada52900b515385d86def597dea35971bb2", @@ -650,13 +737,16 @@ "https://deno.land/x/dnt@0.36.0/lib/utils.ts": "878b7ac7003a10c16e6061aa49dbef9b42bd43174853ebffc9b67ea47eeb11d8", "https://deno.land/x/dnt@0.36.0/mod.ts": "670f1820f2115e6b6aa4f79999bc796e30cc0d0b45096b84a4e1db9f62b82984", "https://deno.land/x/dnt@0.36.0/transform.ts": "1b127c5f22699c8ab2545b98aeca38c4e5c21405b0f5342ea17e9c46280ed277", + "https://deno.land/x/mock_file@v1.1.2/mod.ts": "57b111ba84b5611c09ed82ef300dd063eb278ef68bd286d5149e5b018eb8948d", + "https://deno.land/x/mock_file@v1.1.2/src/memory_file.ts": "24817e782c819cdfb48b9459dc8ad568e8fb2cd2934cd5b775688147e6dc4cbd", + "https://deno.land/x/mock_file@v1.1.2/src/polyfill.ts": "f10f05ec2493cb1e029b30cd211a21803b7683d811813d519696aa2939529b35", "https://deno.land/x/ts_morph@18.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9", "https://deno.land/x/ts_morph@18.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06", "https://deno.land/x/ts_morph@18.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d", "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed", "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700", "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59", - "https://esm.sh/ansi-escapes@6.2.0": "9cd33a5845aed0e739ee1ca89bead377a01e5eefee017e1cef38d244c2d4357a", + "https://esm.sh/ansi-escapes@6.2.0": "508d1d1d8f44b52c45e9c701cd5a78c56d7764a14d005d5328f0cff72b0291b4", "https://esm.sh/mustache@4.2.0": "da4f1d45c3fec1e78a516e6ce01ab4582ffc5b868ace8a244cc640fc25282c60", "https://esm.sh/v124/*acorn-loose@8.4.0": "5255c5344625c52612c421cb99b66d401af8772342a5de8bac38d1d78d0f94b4", "https://esm.sh/v124/*log-update@5.0.1": "49199324effae77a660f21ea75937847315fdb5f67a86881496717314bb95b2a", @@ -805,6 +895,7 @@ "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/required.js": "945988a3e33e21322f240fa5304a3dbbb4a80b2cf8c56032bfd27df9294c9793", "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/uniqueItems.js": "77bf5a6f1bdd56129e0a217865e9d2beb2fd6623a6b288cc4b5af93c49cad69b", "https://esm.sh/v124/ajv@8.11.0/dist/2019.js": "646df403ae1a0d94045d530fe3b7ca65e4bd4a1163e6041d34bc9d321bb7334f", + "https://esm.sh/v124/ajv@8.11.0/dist/core": "7af19c4e1b07edc97c97d9a4e1b2859154d626fc9d10b618c8fda3b178ce26c0", "https://esm.sh/v124/ajv@8.12.0": "7621f26ca63271c26d3c0d3812be6a826809bb56036db0bf3ffb3e82bb7482d1", "https://esm.sh/v124/ajv@8.12.0/denonext/ajv.mjs": "dd2ce45ec01492d9d6bf91bc6bf0e2608fc8977d70cc4bbc0d2d7c1453d514b9", "https://esm.sh/v124/ajv@8.12.0/denonext/dist/2019.js": "26aae2b10cb7a43fe6527beae125ade89406357ddb58019e63d3414ca7c6a3f2", @@ -813,7 +904,10 @@ "https://esm.sh/v124/ansi-styles@6.2.1/denonext/ansi-styles.mjs": "d40ccc0e5be3eced4c723f48dbdb5249efa00b7f8561a90999b7487db3ee5c09", "https://esm.sh/v124/async@3.2.4/denonext/forEach.js": "c265bae8dbe1a8b9bbc26bf012f89f0c37fbb5864df1232af585596f13896ace", "https://esm.sh/v124/async@3.2.4/denonext/series.js": "a555746f7a024becc7b63f37ed3cf00aaa32302855e0c07cdfc0b3aa9abee3c2", + "https://esm.sh/v124/base64-js@1.5.1/denonext/base64-js.mjs": "fc961905a7e7a9a1c753f006903a610306d299569a0b3af9c48318a28ac48b84", "https://esm.sh/v124/bowser@2.11.0/denonext/bowser.mjs": "9876a6f4cb94547829dc82a448b1b7a02b590a819aeb0a29f7e6416fca3a446a", + "https://esm.sh/v124/buffer@4.9.2": "97db8c9b70e6b09f4a09440a62cb9a8a577c1a28787ece11dcaaed918d790840", + "https://esm.sh/v124/buffer@4.9.2/denonext/buffer.mjs": "b41fd0012d60aea2ec448dddefa54c90b4d9dd2a3a1bdb224679c8861a9cb28f", "https://esm.sh/v124/chownr@2.0.0/denonext/chownr.mjs": "230f6e23902418045f5057ff9a7cee6a7a28a21655eeb98f5671395d32839a1a", "https://esm.sh/v124/cli-cursor@4.0.0": "2ed1740a92df113d48f30ac950b174042c2f904556219b3165f04d4e50392cac", "https://esm.sh/v124/cli-cursor@4.0.0/denonext/cli-cursor.mjs": "0904486398e7456058b337418d8af5338924f07682b96f1b3016a01b94009ecc", @@ -826,6 +920,8 @@ "https://esm.sh/v124/estraverse@5.3.0": "a172212d2f4a87f930430cb7e0462cb507891b9f390e17025533f572d895092c", "https://esm.sh/v124/estraverse@5.3.0/denonext/estraverse.mjs": "3e3574b932e1b7c1476f467e6103559d7b978df412e50b6b97299679d4556004", "https://esm.sh/v124/esutils@2.0.3/denonext/esutils.mjs": "56b9038ae71de0a374c86435a347793030afc96deb151466a5009cb5384a85d0", + "https://esm.sh/v124/events@1.1.1": "aa42c257bbfdbd6e635628110bc65ef7d66d7110ffcdcdf894e3afc722e0c87b", + "https://esm.sh/v124/events@1.1.1/denonext/events.mjs": "cafdffd6a39d45b8282efe4b29a0b902ce76e3fd426840fb54eb3e6cec208fab", "https://esm.sh/v124/fast-deep-equal@3.1.3/denonext/fast-deep-equal.mjs": "6313b3e05436550e1c0aeb2a282206b9b8d9213b4c6f247964dd7bb4835fb9e5", "https://esm.sh/v124/fast-xml-parser@4.2.5/denonext/fast-xml-parser.mjs": "0132711d650c1ba44721b4bcf6e0636cd0e0f81894694e8e5b36242434eceb9c", "https://esm.sh/v124/fecha@4.2.3/denonext/fecha.mjs": "d87efb3f6dd068229dcaaf6ce19072720634695668c49da74e6d7289fc67ee48", @@ -833,9 +929,11 @@ "https://esm.sh/v124/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "e3ee6d0df9871f490d05b070b47cd6495f8f33ae4eed90167242cd9819c82cca", "https://esm.sh/v124/hcl2-json-parser@1.0.1": "c50574c485772ae59ed44a3b8f679b85e6ff61788b76f9849e3da1065c249823", "https://esm.sh/v124/hcl2-json-parser@1.0.1/denonext/hcl2-json-parser.mjs": "a51581a1181c31284bfb1ff0907f79a34b248e3fcb1b333c986b8273781fb39f", + "https://esm.sh/v124/ieee754@1.2.1/denonext/ieee754.mjs": "9ec2806065f50afcd4cf3f3f2f38d93e777a92a5954dda00d219f57d4b24832f", "https://esm.sh/v124/inherits@2.0.4/denonext/inherits.mjs": "8095f3d6aea060c904fb24ae50f2882779c0acbe5d56814514c8b5153f3b4b3b", "https://esm.sh/v124/is-fullwidth-code-point@4.0.0/denonext/is-fullwidth-code-point.mjs": "e9801323732e385027651be9a815a58a6f340484316c9f6ed27a0eec6c48c161", "https://esm.sh/v124/is-stream@2.0.1/denonext/is-stream.mjs": "456bc690361378c52fac24a7f362044f036942b1298e812799a67882d6c1febf", + "https://esm.sh/v124/isarray@1.0.0/denonext/isarray.mjs": "6368a41cf02c83843453ac571deb4c393c14e6f5e1d9ca6bbe43a4623f3856c8", "https://esm.sh/v124/isexe@2.0.0/denonext/isexe.mjs": "733c6d04662ec8e40a169a321fcdfaaafb5fce27a3113408c09f17becbd1acd8", "https://esm.sh/v124/js-yaml@4.1.0": "546cd3718747e8cc7d431a079df570c6c62417b338387f6e0a059b4c102d3847", "https://esm.sh/v124/js-yaml@4.1.0/denonext/js-yaml.mjs": "b4e4f1b1cadcc873d4079f242cdc811b1a36fdd0eb01b9b54ca2ae6e2ff2a92f", @@ -852,6 +950,8 @@ "https://esm.sh/v124/ms@2.1.3/denonext/ms.mjs": "0f06597e493998793b8f52232868976128fca326eec3bcd56f10e66e6efd1839", "https://esm.sh/v124/one-time@1.0.0/denonext/one-time.mjs": "b3a4b3d5de194c6f2bf7a9556607a622f9ac27b08a35ac6e87d9f9e7580afcc4", "https://esm.sh/v124/onetime@5.1.2/denonext/onetime.mjs": "dcdb53bfa68b0d43d301c1fd4bb131150a6e58ba843db9b61e6dcd282c9434da", + "https://esm.sh/v124/querystring@0.2.0": "c426159c0d0a6c8732e9e3e976230edb77cb7b225ae7f5b4fc1c131563bf9537", + "https://esm.sh/v124/querystring@0.2.0/denonext/querystring.mjs": "0cc5ad58cddf88b56ccd9bbb47ecdb8707f037c9a25ad47cf38a7fdc4189ae1b", "https://esm.sh/v124/readable-stream@3.6.2/denonext/lib/_stream_writable.js": "fcd380d7da84d0708692263c1e46b1a673d7ab64da9f654b73abfad0219a7560", "https://esm.sh/v124/readable-stream@3.6.2/denonext/readable-stream.mjs": "061037c060d88267d4cbbd57688f0bf2ed6cceda918e17d407f83248a6aad672", "https://esm.sh/v124/restore-cursor@4.0.0/denonext/restore-cursor.mjs": "9c2be16e5018dcfeed7503897c1113d9427016b1b907013ee36cb1aa27173fb9", @@ -878,6 +978,8 @@ "https://esm.sh/v124/unique-names-generator@4.7.1": "6d61270c703d91c6fb27bd9b68a06f241659c3f01df03f76f4e8b540acf45c44", "https://esm.sh/v124/unique-names-generator@4.7.1/denonext/unique-names-generator.mjs": "b40a40ff6a8533a2f35c6a4b6883a5e5737d75287f2d635a863176247bcb7f19", "https://esm.sh/v124/uri-js@4.4.1/denonext/uri-js.mjs": "4b46d46cd678979debedbf2d05fa39b50ec17656e3960a9ec3418e7763aa7c34", + "https://esm.sh/v124/url@0.10.3": "07386e574238e0e64451b25c1d699146b6bace90f58e1e751dae337d003fe44c", + "https://esm.sh/v124/url@0.10.3/denonext/url.mjs": "ba58c05c534164ab58a98e7e9f9ba67400750a2d71031658c4580d7112ac4144", "https://esm.sh/v124/util-deprecate@1.0.2/denonext/util-deprecate.mjs": "e7f4e3a1ec5eb3f2e04dbfaf90e4874f535ca298a7c91512f1d083e1ba765c37", "https://esm.sh/v124/uuid@8.3.2/denonext/uuid.mjs": "c0da38266b24ac79d62b02290f17caba7e75d078f6771bbe8fb61bdef60f837c", "https://esm.sh/v124/which@3.0.1": "f27ee01cac772029a95d37fad83158ebe6a6cc4222ee9396f5f54bfe4903da6c", @@ -890,6 +992,6 @@ "https://esm.sh/v124/wrap-ansi@8.1.0/denonext/wrap-ansi.mjs": "1804d60795c6034323e4b8dc92425aa9ab28385b87bb700772e16cb92bb0d8f8", "https://esm.sh/v124/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", "https://esm.sh/v128/mustache@4.2.0/denonext/mustache.mjs": "8c046aa4755b9beb2f203e01fdab7d36e4c75dd1bc22021be44ac31723ead9f0", - "https://esm.sh/v133/ansi-escapes@6.2.0/denonext/ansi-escapes.mjs": "e82f350a4e3ef3113cd99b6d99513de1821bb9ae50bb4ed1dbbd6b9789af560d" + "https://esm.sh/v129/ansi-escapes@6.2.0/denonext/ansi-escapes.mjs": "e82f350a4e3ef3113cd99b6d99513de1821bb9ae50bb4ed1dbbd6b9789af560d" } } diff --git a/examples/datacenters/local/datacenter.arc b/examples/datacenters/local/datacenter.arc index 4f730ffd6..21496e8b0 100644 --- a/examples/datacenters/local/datacenter.arc +++ b/examples/datacenters/local/datacenter.arc @@ -68,6 +68,30 @@ environment { } } + module "staticWebServer" { + when = contains(environment.nodes.*.type, "bucket") + build = "./deployment" + + volume { + host_path = "/var/run/docker.sock" + mount_path = "/var/run/docker.sock" + } + + volume { + host_path = "${var.secretsDir}/${environment.name}/buckets/" + mount_path = "/usr/share/nginx/html" + } + + environment = { + DOCKER_HOST = "unix:///var/run/docker.sock" + } + + inputs = { + name = "${environment.name}-static-web-server" + image = "nginx" + } + } + database { when = node.inputs.databaseType == "postgres" @@ -203,4 +227,66 @@ environment { image = module.build.image } } + + bucket { + module "dynamicBucket" { + when = node.inputs.deploy + build = "./deployment" + + environment = { + DOCKER_HOST = "unix:///var/run/docker.sock" + } + + volume { + host_path = "/var/run/docker.sock" + mount_path = "/var/run/docker.sock" + } + + # This volume is shared with the nginx webserver + volume { + host_path = "${var.secretsDir}/${environment.name}/buckets/" + mount_path = "/data" + } + + inputs = merge(node.inputs.deploy, { + volume_mounts = [{ + host_path = "/data" + mount_path = node.inputs.deploy.publish + }] + }) + } + + module "staticBucket" { + when = node.inputs.directory + build = "./deployment" + + environment = { + DOCKER_HOST = "unix:///var/run/docker.sock" + } + + volume { + host_path = "/var/run/docker.sock" + mount_path = "/var/run/docker.sock" + } + + # This volume is shared with the nginx webserver + volume { + host_path = "${var.secretsDir}/${environment.name}/buckets/" + mount_path = "/data" + } + + inputs = { + image = "alpine" + command = [ + "sh", + "-c", + "cp -r ${node.inputs.directory} /data" + ] + volume_mounts = [{ + host_path = "/data" + mount_path = "/data" + }] + } + } + } } \ No newline at end of file diff --git a/src/@resources/bucket/README.md b/src/@resources/bucket/README.md new file mode 100644 index 000000000..5cff8ce21 --- /dev/null +++ b/src/@resources/bucket/README.md @@ -0,0 +1,2 @@ +# The `bucket` resource + diff --git a/src/@resources/bucket/inputs.schema.json b/src/@resources/bucket/inputs.schema.json new file mode 100644 index 000000000..be9991879 --- /dev/null +++ b/src/@resources/bucket/inputs.schema.json @@ -0,0 +1,10 @@ +{ + "$ref": "#/definitions/BucketInputs", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "BucketInputs": { + "additionalProperties": {}, + "type": "object" + } + } +} \ No newline at end of file diff --git a/src/@resources/bucket/inputs.ts b/src/@resources/bucket/inputs.ts new file mode 100644 index 000000000..5fa0374b3 --- /dev/null +++ b/src/@resources/bucket/inputs.ts @@ -0,0 +1,3 @@ +export type BucketInputs = Record; + +export default BucketInputs; diff --git a/src/@resources/bucket/outputs.schema.json b/src/@resources/bucket/outputs.schema.json new file mode 100644 index 000000000..66d466a18 --- /dev/null +++ b/src/@resources/bucket/outputs.schema.json @@ -0,0 +1,46 @@ +{ + "$ref": "#/definitions/BucketOutputs", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "BucketOutputs": { + "additionalProperties": false, + "properties": { + "access_key_id": { + "description": "Access key ID used to authenticate with the bucket", + "type": "string" + }, + "endpoint": { + "description": "Endpoint that hosts the bucket", + "examples": [ + "https://nyc3.digitaloceanspaces.com", + "https://bucket.s3.region.amazonaws.com" + ], + "type": "string" + }, + "id": { + "description": "Unique ID of the bucket that was created", + "examples": [ + "abc123" + ], + "type": "string" + }, + "region": { + "description": "Region the bucket was created in", + "type": "string" + }, + "secret_access_key": { + "description": "Secret access key used to authenticate with the bucket", + "type": "string" + } + }, + "required": [ + "id", + "endpoint", + "region", + "access_key_id", + "secret_access_key" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/src/@resources/bucket/outputs.ts b/src/@resources/bucket/outputs.ts new file mode 100644 index 000000000..e95275859 --- /dev/null +++ b/src/@resources/bucket/outputs.ts @@ -0,0 +1,32 @@ +export type BucketOutputs = { + /** + * Unique ID of the bucket that was created + * @example "abc123" + */ + id: string; + + /** + * Endpoint that hosts the bucket + * + * @example "https://nyc3.digitaloceanspaces.com" + * @example "https://bucket.s3.region.amazonaws.com" + */ + endpoint: string; + + /** + * Region the bucket was created in + */ + region: string; + + /** + * Access key ID used to authenticate with the bucket + */ + access_key_id: string; + + /** + * Secret access key used to authenticate with the bucket + */ + secret_access_key: string; +}; + +export default BucketOutputs; diff --git a/src/@resources/ingress/inputs.schema.json b/src/@resources/ingress/inputs.schema.json index 7bb1a907c..b46e9eeb7 100644 --- a/src/@resources/ingress/inputs.schema.json +++ b/src/@resources/ingress/inputs.schema.json @@ -3,116 +3,183 @@ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "IngressRuleInputs": { - "additionalProperties": false, - "properties": { - "headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Headers to include in responses", - "examples": [ - { - "X-Frame-Options": "DENY" + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Headers to include in responses", + "examples": [ + { + "X-Frame-Options": "DENY" + } + ], + "type": "object" + }, + "internal": { + "default": false, + "description": "Whether or not this should be fulfilled by an internal load balancer (e.g. no public IP)", + "type": "boolean" + }, + "password": { + "description": "Basic auth password", + "examples": [ + "password" + ], + "type": "string" + }, + "path": { + "default": "/", + "description": "The path the ingress rule listens on", + "type": "string" + }, + "protocol": { + "default": "http", + "description": "The protocol the ingress rule listens for traffic on", + "type": "string" + }, + "service": { + "additionalProperties": false, + "description": "The configuration details of the target service", + "properties": { + "host": { + "description": "The hostname the service is listening on", + "examples": [ + "my-service" + ], + "type": "string" + }, + "name": { + "description": "Name of the service the ingress points to", + "examples": [ + "my-service" + ], + "type": "string" + }, + "port": { + "description": "The port the service deployment is listening on", + "examples": [ + 80 + ], + "type": "string" + }, + "protocol": { + "description": "The protocol the service is listening on", + "examples": [ + "http" + ], + "type": "string" + } + }, + "required": [ + "name", + "host", + "port", + "protocol" + ], + "type": "object" + }, + "subdomain": { + "description": "The subdomain the ingress rule listens on", + "examples": [ + "api" + ], + "type": "string" + }, + "username": { + "description": "Basic auth username", + "examples": [ + "admin" + ], + "type": "string" } + }, + "required": [ + "internal", + "path", + "protocol", + "service" ], "type": "object" }, - "internal": { - "default": false, - "description": "Whether or not this should be fulfilled by an internal load balancer (e.g. no public IP)", - "type": "boolean" - }, - "password": { - "description": "Basic auth password", - "examples": [ - "password" - ], - "type": "string" - }, - "path": { - "default": "/", - "description": "The path the ingress rule listens on", - "type": "string" - }, - "port": { - "description": "Port that the ingress rule listens for traffic on", - "examples": [ - 80 - ], - "type": [ - "string", - "number" - ] - }, - "protocol": { - "default": "http", - "description": "The protocol the ingress rule listens for traffic on", - "type": "string" - }, - "service": { + { "additionalProperties": false, - "description": "The configuration details of the target service", "properties": { - "host": { - "description": "The hostname the service is listening on", + "bucket": { + "additionalProperties": false, + "description": "Configuration details for a target bucket to route requests to", + "properties": { + "id": { + "description": "Unique ID of the bucket the ingress rule should route to", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Headers to include in responses", "examples": [ - "my-service" + { + "X-Frame-Options": "DENY" + } ], - "type": "string" + "type": "object" + }, + "internal": { + "default": false, + "description": "Whether or not this should be fulfilled by an internal load balancer (e.g. no public IP)", + "type": "boolean" }, - "name": { - "description": "Name of the service the ingress points to", + "password": { + "description": "Basic auth password", "examples": [ - "my-service" + "password" ], "type": "string" }, - "port": { - "description": "The port the service deployment is listening on", + "path": { + "default": "/", + "description": "The path the ingress rule listens on", + "type": "string" + }, + "protocol": { + "default": "http", + "description": "The protocol the ingress rule listens for traffic on", + "type": "string" + }, + "subdomain": { + "description": "The subdomain the ingress rule listens on", "examples": [ - 80 + "api" ], "type": "string" }, - "protocol": { - "description": "The protocol the service is listening on", + "username": { + "description": "Basic auth username", "examples": [ - "http" + "admin" ], "type": "string" } }, "required": [ - "name", - "host", - "port", + "bucket", + "internal", + "path", "protocol" ], "type": "object" - }, - "subdomain": { - "description": "The subdomain the ingress rule listens on", - "examples": [ - "api" - ], - "type": "string" - }, - "username": { - "description": "Basic auth username", - "examples": [ - "admin" - ], - "type": "string" } - }, - "required": [ - "port", - "service", - "protocol", - "path", - "internal" - ], - "type": "object" + ] } } } \ No newline at end of file diff --git a/src/@resources/ingress/inputs.ts b/src/@resources/ingress/inputs.ts index a8d106674..92bee5c3a 100644 --- a/src/@resources/ingress/inputs.ts +++ b/src/@resources/ingress/inputs.ts @@ -1,10 +1,4 @@ -export type IngressRuleInputs = { - /** - * Port that the ingress rule listens for traffic on - * @example 80 - */ - port: string | number; - +type ServiceIngressInputs = { /** * The configuration details of the target service */ @@ -33,7 +27,21 @@ export type IngressRuleInputs = { */ protocol: string; }; +}; + +type BucketIngressInputs = { + /** + * Configuration details for a target bucket to route requests to + */ + bucket: { + /** + * Unique ID of the bucket the ingress rule should route to + */ + id: string; + }; +}; +export type IngressRuleInputs = (ServiceIngressInputs | BucketIngressInputs) & { /** * The protocol the ingress rule listens for traffic on * @default http diff --git a/src/@resources/task/inputs.schema.json b/src/@resources/task/inputs.schema.json new file mode 100644 index 000000000..78aa6fc9f --- /dev/null +++ b/src/@resources/task/inputs.schema.json @@ -0,0 +1,141 @@ +{ + "$ref": "#/definitions/TaskInputs", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "TaskInputs": { + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Command to execute in the container", + "examples": [ + [ + "node", + "index.js" + ] + ] + }, + "cpu": { + "description": "Number of CPUs to allocate to the container", + "minimum": 0.1, + "type": "number" + }, + "entrypoint": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "" + ], + "description": "Entrypoint of the container" + }, + "environment": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "not": {} + } + ] + }, + "description": "Environment variables to pass to the container", + "examples": [ + { + "NODE_ENV": "production" + } + ], + "type": "object" + }, + "image": { + "description": "Image the container runs from", + "examples": [ + "registry.architect.io/my-image:latest" + ], + "type": "string" + }, + "memory": { + "description": "Amount of memory to allocate to the container", + "examples": [ + "512Mi", + "1Gi" + ], + "type": "string" + }, + "platform": { + "description": "Target platform the deployment will run on", + "examples": [ + "linux/amd64" + ], + "type": "string" + }, + "volume_mounts": { + "description": "A set of volumes to mount to the container", + "items": { + "additionalProperties": false, + "properties": { + "mount_path": { + "description": "Path in the container to mount the volume to", + "examples": [ + "/var/lib/my-volume" + ], + "type": "string" + }, + "readonly": { + "default": false, + "description": "Whether or not the volume should be mounted as read-only", + "type": "boolean" + }, + "volume": { + "description": "Name of the volume to mount", + "examples": [ + "my-volume" + ], + "type": "string" + } + }, + "required": [ + "volume", + "mount_path", + "readonly" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "image" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/src/@resources/task/inputs.ts b/src/@resources/task/inputs.ts new file mode 100644 index 000000000..405b82573 --- /dev/null +++ b/src/@resources/task/inputs.ts @@ -0,0 +1,79 @@ +export type TaskInputs = { + /** + * Image the container runs from + * + * @example "registry.architect.io/my-image:latest" + */ + image: string; + + /** + * Command to execute in the container + * + * @example ["node", "index.js"] + */ + command?: string | string[]; + + /** + * Entrypoint of the container + * + * @default [""] + */ + entrypoint?: string | string[]; + + /** + * Target platform the deployment will run on + * + * @example "linux/amd64" + */ + platform?: string; + + /** + * Environment variables to pass to the container + * + * @example + * { + * "NODE_ENV": "production" + * } + */ + environment?: Record; + + /** + * Number of CPUs to allocate to the container + * @minimum 0.1 + */ + cpu?: number; + + /** + * Amount of memory to allocate to the container + * + * @example "512Mi" + * @example "1Gi" + */ + memory?: string; + + /** + * A set of volumes to mount to the container + */ + volume_mounts?: Array<{ + /** + * Name of the volume to mount + * @example "my-volume" + */ + volume: string; + + /** + * Path in the container to mount the volume to + * + * @example "/var/lib/my-volume" + */ + mount_path: string; + + /** + * Whether or not the volume should be mounted as read-only + * @default false + */ + readonly: boolean; + }>; +}; + +export default TaskInputs; diff --git a/src/@resources/task/outputs.schema.json b/src/@resources/task/outputs.schema.json new file mode 100644 index 000000000..2cab15f55 --- /dev/null +++ b/src/@resources/task/outputs.schema.json @@ -0,0 +1,10 @@ +{ + "$ref": "#/definitions/TaskOutputs", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "TaskOutputs": { + "additionalProperties": false, + "type": "object" + } + } +} \ No newline at end of file diff --git a/src/@resources/task/outputs.ts b/src/@resources/task/outputs.ts new file mode 100644 index 000000000..bf18a2da7 --- /dev/null +++ b/src/@resources/task/outputs.ts @@ -0,0 +1,3 @@ +export type TaskOutputs = {}; + +export default TaskOutputs; diff --git a/src/@resources/types.ts b/src/@resources/types.ts index 94ea31d62..8a82f957d 100644 --- a/src/@resources/types.ts +++ b/src/@resources/types.ts @@ -1,3 +1,5 @@ +import type bucketInputs from './bucket/inputs.ts'; +import type bucketOutputs from './bucket/outputs.ts'; import type cronjobInputs from './cronjob/inputs.ts'; import type cronjobOutputs from './cronjob/outputs.ts'; import type databaseInputs from './database/inputs.ts'; @@ -14,10 +16,13 @@ import type secretInputs from './secret/inputs.ts'; import type secretOutputs from './secret/outputs.ts'; import type serviceInputs from './service/inputs.ts'; import type serviceOutputs from './service/outputs.ts'; +import type taskInputs from './task/inputs.ts'; +import type taskOutputs from './task/outputs.ts'; import type volumeInputs from './volume/inputs.ts'; import type volumeOutputs from './volume/outputs.ts'; export type ResourceType = + | 'bucket' | 'cronjob' | 'database' | 'databaseUser' @@ -26,9 +31,12 @@ export type ResourceType = | 'ingress' | 'secret' | 'service' - | 'volume'; + | 'task' + | 'volume' +; export const ResourceTypeList: ResourceType[] = [ + 'bucket', 'cronjob', 'database', 'databaseUser', @@ -37,10 +45,12 @@ export const ResourceTypeList: ResourceType[] = [ 'ingress', 'secret', 'service', + 'task', 'volume', ]; export type ResourceInputs = { + 'bucket': bucketInputs; 'cronjob': cronjobInputs; 'database': databaseInputs; 'databaseUser': databaseUserInputs; @@ -49,10 +59,12 @@ export type ResourceInputs = { 'ingress': ingressInputs; 'secret': secretInputs; 'service': serviceInputs; + 'task': taskInputs; 'volume': volumeInputs; }; export type ResourceOutputs = { + 'bucket': bucketOutputs; 'cronjob': cronjobOutputs; 'database': databaseOutputs; 'databaseUser': databaseUserOutputs; @@ -61,6 +73,7 @@ export type ResourceOutputs = { 'ingress': ingressOutputs; 'secret': secretOutputs; 'service': serviceOutputs; + 'task': taskOutputs; 'volume': volumeOutputs; }; diff --git a/src/@resources/volume/inputs.schema.json b/src/@resources/volume/inputs.schema.json index da0dea9ef..c750f9224 100644 --- a/src/@resources/volume/inputs.schema.json +++ b/src/@resources/volume/inputs.schema.json @@ -11,18 +11,8 @@ "/Users/batman/my-volume" ], "type": "string" - }, - "name": { - "description": "Name to give to the volume resource", - "examples": [ - "my-volume" - ], - "type": "string" } }, - "required": [ - "name" - ], "type": "object" } } diff --git a/src/@resources/volume/inputs.ts b/src/@resources/volume/inputs.ts index cfdd66c8d..5e984a71e 100644 --- a/src/@resources/volume/inputs.ts +++ b/src/@resources/volume/inputs.ts @@ -1,10 +1,4 @@ export type VolumeInputs = { - /** - * Name to give to the volume resource - * @example "my-volume" - */ - name: string; - /** * Path on the host machine to mount the volume to * @example "/Users/batman/my-volume" diff --git a/src/@resources/volume/outputs.schema.json b/src/@resources/volume/outputs.schema.json index 78c98434e..b6cb43fd4 100644 --- a/src/@resources/volume/outputs.schema.json +++ b/src/@resources/volume/outputs.schema.json @@ -3,7 +3,19 @@ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "VolumeOutputs": { - "additionalProperties": {}, + "additionalProperties": false, + "properties": { + "id": { + "description": "The unique ID of the volume", + "examples": [ + "my-volume" + ], + "type": "string" + } + }, + "required": [ + "id" + ], "type": "object" } } diff --git a/src/@resources/volume/outputs.ts b/src/@resources/volume/outputs.ts index abaa05786..90c94d810 100644 --- a/src/@resources/volume/outputs.ts +++ b/src/@resources/volume/outputs.ts @@ -1,3 +1,10 @@ -export type VolumeOutputs = Record; +export type VolumeOutputs = { + /** + * The unique ID of the volume + * + * @example "my-volume" + */ + id: string; +}; export default VolumeOutputs; diff --git a/src/commands/build/component.ts b/src/commands/build/component.ts index a64bdc460..f30a2e45f 100644 --- a/src/commands/build/component.ts +++ b/src/commands/build/component.ts @@ -1,4 +1,3 @@ -import * as mod from 'https://deno.land/std@0.195.0/fs/copy.ts'; import * as path from 'std/path/mod.ts'; import { Component, parseComponent } from '../../components/index.ts'; import { verifyDocker } from '../../docker/helper.ts'; @@ -107,36 +106,6 @@ const ComponentBuildCommand = BaseCommand() build_args.push(build_context); await getDigest(build_args, options.verbose); return imageRepository.toString(); - }, async (build_options) => { - imageRepository.tag = imageRepository.tag + '-' + build_options.deployment_name + '-volumes-' + - build_options.volume_name; - console.log( - 'Building image for volume', - build_options.deployment_name + '.volumes.' + build_options.volume_name, - ); - - // Create the directory for the new volume container - const tmpDir = await Deno.makeTempDir(); - await mod.copy(build_options.host_path, path.join(tmpDir, 'contents')); - Deno.writeTextFileSync( - path.join(tmpDir, 'Dockerfile'), - ` - FROM alpine:latest - WORKDIR /app - COPY ./contents . - CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] - `, - ); - - // Publish the volume container - const buildArgs = ['build', '--push', '--tag', imageRepository.toString()]; - if (options.verbose) { - buildArgs.push('--quiet'); - } - buildArgs.push(tmpDir); - - await getDigest(buildArgs, options.verbose); - return imageRepository.toString(); }); // Tag and push the component itself @@ -175,33 +144,6 @@ const ComponentBuildCommand = BaseCommand() buildArgs.push(path.join(Deno.cwd(), context, build_options.context)); } - return getDigest(buildArgs, options.verbose); - }, async (build_options) => { - console.log( - 'Building image for volume', - build_options.deployment_name + '.volumes.' + build_options.volume_name, - ); - - // Create the directory for the new volume container - const tmpDir = await Deno.makeTempDir(); - await mod.copy(build_options.host_path, path.join(tmpDir, 'contents')); - Deno.writeTextFileSync( - path.join(tmpDir, 'Dockerfile'), - ` - FROM alpine:latest - WORKDIR /app - COPY ./contents . - CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] - `, - ); - - // Publish the volume container - const buildArgs = ['build']; - if (options.verbose) { - buildArgs.push('--quiet'); - } - buildArgs.push(tmpDir); - return getDigest(buildArgs, options.verbose); }); @@ -215,13 +157,6 @@ const ComponentBuildCommand = BaseCommand() await exec('docker', { args: ['tag', sourceRef, targetRef] }); console.log(`Deployment Tagged: ${targetRef}`); return targetRef; - }, async (digest: string, deploymentName: string, volumeName: string) => { - const imageRepository = new ImageRepository(tag); - const targetRef = imageRepository.toString() + '-deployments-' + deploymentName + '-volumes-' + volumeName; - - await exec('docker', { args: ['tag', digest, targetRef] }); - console.log(`Volume Tagged: ${targetRef}`); - return targetRef; }); const component_digest = await command_helper.componentStore.add(component); diff --git a/src/commands/tag.ts b/src/commands/tag.ts index d518d6155..eef8b115a 100644 --- a/src/commands/tag.ts +++ b/src/commands/tag.ts @@ -18,7 +18,7 @@ async function tag_action(options: GlobalOptions, source: string, target: string component.tag(async (sourceRef: string, targetName: string) => { const imageRepository = new ImageRepository(target); - const targetRef = imageRepository.toString() + '-deployments-' + targetName; + const targetRef = imageRepository.toString() + '-' + targetName; await exec('docker', { args: ['tag', sourceRef, targetRef] }); console.log(`Deployment Tagged: ${targetRef}`); return targetRef; diff --git a/src/components/__tests__/version-helper.ts b/src/components/__tests__/version-helper.ts index 7ee0f1c59..39fa76b2f 100644 --- a/src/components/__tests__/version-helper.ts +++ b/src/components/__tests__/version-helper.ts @@ -274,7 +274,6 @@ export const testIngressGeneration = ( component: 'component', inputs: { password: `\${{ component/service/${options.service_name}.password }}`, - port: `\${{ component/service/${options.service_name}.port }}`, protocol: `\${{ component/service/${options.service_name}.protocol }}`, service: { name: `\${{ component/service/${options.service_name}.name }}`, diff --git a/src/components/component-schema.ts b/src/components/component-schema.ts index 4aa442ca0..957050a0c 100644 --- a/src/components/component-schema.ts +++ b/src/components/component-schema.ts @@ -1,3897 +1,4054 @@ export default { - 'oneOf': [ + "oneOf": [ { - 'additionalProperties': false, - 'properties': { - 'databases': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'description': 'A human-readable description of the database and its purpose', - 'type': 'string', - }, - 'type': { - 'description': 'Type of database and version required by the application', - 'type': 'string', + "additionalProperties": false, + "properties": { + "databases": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "description": "A human-readable description of the database and its purpose", + "type": "string" }, + "type": { + "description": "Type of database and version required by the application", + "type": "string" + } }, - 'required': [ - 'type', + "required": [ + "type" ], - 'type': 'object', + "type": "object" }, - 'description': 'A set of databases required by the component', - 'type': 'object', + "description": "A set of databases required by the component", + "type": "object" }, - 'dependencies': { - 'additionalProperties': { - 'anyOf': [ + "dependencies": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'component': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "component": { + "type": "string" }, - 'inputs': { - 'additionalProperties': { - 'items': { - 'type': 'string', + "inputs": { + "additionalProperties": { + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'component', + "required": [ + "component" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': 'A set of components and associated versions that this component depends on.', - 'type': 'object', + "description": "A set of components and associated versions that this component depends on.", + "type": "object" }, - 'description': { - 'description': 'A human-readable description of the component and what it should be used for', - 'type': 'string', + "description": { + "description": "A human-readable description of the component and what it should be used for", + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'description': { - 'description': 'A human-readable description of the interface and how it should be used.', - 'type': 'string', - }, - 'ingress': { - 'additionalProperties': false, - 'description': 'Ingress configuration to allow the interface to be exposed publicly', - 'properties': { - 'internal': { - 'default': false, - 'description': - 'Indicates whether the ingress rule should be attached to a public or private load balancer', - 'type': 'boolean', - }, - 'path': { - 'description': 'Path that the interface should be exposed under', - 'type': 'string', - }, - 'subdomain': { - 'description': 'Subdomain the interface should be accessed on', - 'type': 'string', - }, + "additionalProperties": false, + "properties": { + "description": { + "description": "A human-readable description of the interface and how it should be used.", + "type": "string" + }, + "ingress": { + "additionalProperties": false, + "description": "Ingress configuration to allow the interface to be exposed publicly", + "properties": { + "internal": { + "default": false, + "description": "Indicates whether the ingress rule should be attached to a public or private load balancer", + "type": "boolean" + }, + "path": { + "description": "Path that the interface should be exposed under", + "type": "string" + }, + "subdomain": { + "description": "Subdomain the interface should be accessed on", + "type": "string" + } }, - 'type': 'object', - }, - 'url': { - 'description': - 'The url of the downstream interfaces that should be exposed. This will usually be a reference to one of your services interfaces.', - 'type': 'string', + "type": "object" }, + "url": { + "description": "The url of the downstream interfaces that should be exposed. This will usually be a reference to one of your services interfaces.", + "type": "string" + } }, - 'required': [ - 'url', + "required": [ + "url" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': - 'A dictionary of named interfaces that the component makes available to upstreams, including other components via dependencies or environments via interface mapping.\n\nInterfaces can either be an object describing the interface, or a string shorthand that directly applies to the `url` value.', - 'type': 'object', + "description": "A dictionary of named interfaces that the component makes available to upstreams, including other components via dependencies or environments via interface mapping.\n\nInterfaces can either be an object describing the interface, or a string shorthand that directly applies to the `url` value.", + "type": "object" }, - 'keywords': { - 'description': - 'An array of keywords that can be used to index the component and make it discoverable for others', - 'items': { - 'type': 'string', + "keywords": { + "description": "An array of keywords that can be used to index the component and make it discoverable for others", + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'name': { - 'description': 'Unique name of the component. Must be of the format, /', - 'type': 'string', + "name": { + "description": "Unique name of the component. Must be of the format, /", + "type": "string" }, - 'parameters': { - 'additionalProperties': { - 'anyOf': [ + "parameters": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'default': { - 'description': - 'The default value to apply to the parameter when one wasn\'t provided by the operator', - 'type': [ - 'string', - 'number', - ], - }, - 'description': { - 'description': - 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', - 'type': 'string', - }, - 'merge': { - 'default': false, - 'description': 'Whether or not to merge results from multiple sources into a single array', - 'type': 'boolean', - }, - 'required': { - 'default': false, - 'description': 'A boolean indicating whether or not an operator is required ot provide a value', - 'type': 'boolean', - }, + "additionalProperties": false, + "properties": { + "default": { + "description": "The default value to apply to the parameter when one wasn't provided by the operator", + "type": [ + "string", + "number" + ] + }, + "description": { + "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", + "type": "string" + }, + "merge": { + "default": false, + "description": "Whether or not to merge results from multiple sources into a single array", + "type": "boolean" + }, + "required": { + "default": false, + "description": "A boolean indicating whether or not an operator is required ot provide a value", + "type": "boolean" + } }, - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': - 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.', - 'type': 'object', + "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.", + "type": "object" }, - 'secrets': { - 'additionalProperties': { - 'anyOf': [ + "secrets": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'default': { - 'description': - 'The default value to apply to the parameter when one wasn\'t provided by the operator', - 'type': [ - 'string', - 'number', - ], - }, - 'description': { - 'description': - 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', - 'type': 'string', - }, - 'merge': { - 'default': false, - 'description': 'Whether or not to merge results from multiple sources into a single array', - 'type': 'boolean', - }, - 'required': { - 'default': false, - 'description': 'A boolean indicating whether or not an operator is required ot provide a value', - 'type': 'boolean', - }, + "additionalProperties": false, + "properties": { + "default": { + "description": "The default value to apply to the parameter when one wasn't provided by the operator", + "type": [ + "string", + "number" + ] + }, + "description": { + "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", + "type": "string" + }, + "merge": { + "default": false, + "description": "Whether or not to merge results from multiple sources into a single array", + "type": "boolean" + }, + "required": { + "default": false, + "description": "A boolean indicating whether or not an operator is required ot provide a value", + "type": "boolean" + } }, - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': - 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.', - 'type': 'object', + "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.", + "type": "object" }, - 'services': { - 'additionalProperties': { - 'anyOf': [ + "services": { + "additionalProperties": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'command': { - 'anyOf': [ + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', - }, - 'context': { - 'type': 'string', + "type": "object" }, - 'dockerfile': { - 'type': 'string', + "context": { + "type": "string" }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'depends_on': { - 'items': { - 'type': 'string', + "depends_on": { + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'path': { - 'type': 'string', - }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', - }, - 'password': { - 'type': 'string', + "type": "object" }, - 'port': { - 'type': [ - 'number', - 'string', - ], + "password": { + "type": "string" }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'liveness_probe': { - 'additionalProperties': false, - 'properties': { - 'command': { - 'anyOf': [ + "liveness_probe": { + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'failure_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'initial_delay': { - 'type': 'string', - }, - 'interval': { - 'type': 'string', - }, - 'path': { - 'type': 'string', - }, - 'port': { - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'timeout': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', + "type": "string" + } + ] + }, + "failure_threshold": { + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "path": { + "type": "string" + }, + "port": { + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "type": [ + "number", + "string" + ] + }, + "timeout": { + "type": "string" + } + }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] }, + "memory": { + "type": "string" + } }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], + "type": "object" }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'depends_on': { - 'description': 'Specify other services that you want to wait for before starting this one', - 'items': { - 'type': 'string', + "depends_on": { + "description": "Specify other services that you want to wait for before starting this one", + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'type': 'number', + "type": "number" }, { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', - }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'path': { - 'type': 'string', - }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', - }, - 'password': { - 'type': 'string', + "type": "object" }, - 'port': { - 'type': [ - 'number', - 'string', - ], + "password": { + "type": "string" }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'required': [ - 'port', + "required": [ + "port" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', - }, - 'language': { - 'deprecated': true, - 'type': 'string', - }, - 'liveness_probe': { - 'additionalProperties': false, - 'description': 'Task run continuously to determine if each service replica is healthy', - 'properties': { - 'command': { - 'anyOf': [ + "type": "object" + }, + "language": { + "deprecated": true, + "type": "string" + }, + "liveness_probe": { + "additionalProperties": false, + "description": "Task run continuously to determine if each service replica is healthy", + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], - 'description': - 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', - }, - 'failure_threshold': { - 'default': 3, - 'description': - 'The number of times to retry a failed health check before the container is considered unhealthy', - 'type': [ - 'number', - 'string', - ], - }, - 'initial_delay': { - 'default': '0s', - 'description': 'Delays the check from running for the specified amount of time', - 'type': 'string', - }, - 'interval': { - 'default': '30s', - 'description': - 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', - 'type': 'string', - }, - 'path': { - 'deprecated': true, - 'type': 'string', - }, - 'port': { - 'deprecated': true, - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'default': 1, - 'description': - 'The number of times to retry a health check before the container is considered healthy', - 'type': [ - 'number', - 'string', + "type": "array" + } ], - }, - 'timeout': { - 'default': '5s', - 'description': - 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', - 'type': 'string', - }, + "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." + }, + "failure_threshold": { + "default": 3, + "description": "The number of times to retry a failed health check before the container is considered unhealthy", + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "default": "0s", + "description": "Delays the check from running for the specified amount of time", + "type": "string" + }, + "interval": { + "default": "30s", + "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", + "type": "string" + }, + "path": { + "deprecated": true, + "type": "string" + }, + "port": { + "deprecated": true, + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "default": 1, + "description": "The number of times to retry a health check before the container is considered healthy", + "type": [ + "number", + "string" + ] + }, + "timeout": { + "default": "5s", + "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", + "type": "string" + } }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'description': 'Number of replicas of the deployment to run', - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'description': 'Autoscaling rules for the deployment', - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'description': 'Metrics to be used to trigger autoscaling', - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], - }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "description": "Number of replicas of the deployment to run", + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "description": "Autoscaling rules for the deployment", + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "description": "Metrics to be used to trigger autoscaling", + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] + }, + "memory": { + "type": "string" + } + }, + "type": "object" + }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'required': [ - 'min_replicas', - 'max_replicas', - 'metrics', + "required": [ + "min_replicas", + "max_replicas", + "metrics" ], - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', - }, - 'type': 'object', - }, - 'context': { - 'type': 'string', - }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', - }, + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "context": { + "type": "string" + }, + "dockerfile": { + "type": "string" + }, + "target": { + "type": "string" + } }, - 'required': [ - 'context', + "required": [ + "context" ], - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'context': { - 'type': 'string', + "context": { + "type": "string" }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'depends_on': { - 'items': { - 'type': 'string', + "depends_on": { + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', - }, - 'path': { - 'type': 'string', + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'password': { - 'type': 'string', + "password": { + "type": "string" }, - 'port': { - 'type': [ - 'number', - 'string', - ], - }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'liveness_probe': { - 'additionalProperties': false, - 'properties': { - 'command': { - 'anyOf': [ + "liveness_probe": { + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'failure_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'initial_delay': { - 'type': 'string', - }, - 'interval': { - 'type': 'string', - }, - 'path': { - 'type': 'string', - }, - 'port': { - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'timeout': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', + "type": "string" + } + ] + }, + "failure_threshold": { + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "path": { + "type": "string" + }, + "port": { + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "type": [ + "number", + "string" + ] + }, + "timeout": { + "type": "string" + } + }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] }, + "memory": { + "type": "string" + } }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], + "type": "object" }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'depends_on': { - 'description': 'Specify other services that you want to wait for before starting this one', - 'items': { - 'type': 'string', + "depends_on": { + "description": "Specify other services that you want to wait for before starting this one", + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'type': 'number', + "type": "number" }, { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', - }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', - }, - 'path': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'password': { - 'type': 'string', - }, - 'port': { - 'type': [ - 'number', - 'string', - ], + "password": { + "type": "string" }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'required': [ - 'port', + "required": [ + "port" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', - }, - 'language': { - 'deprecated': true, - 'type': 'string', - }, - 'liveness_probe': { - 'additionalProperties': false, - 'description': 'Task run continuously to determine if each service replica is healthy', - 'properties': { - 'command': { - 'anyOf': [ + "type": "object" + }, + "language": { + "deprecated": true, + "type": "string" + }, + "liveness_probe": { + "additionalProperties": false, + "description": "Task run continuously to determine if each service replica is healthy", + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], - 'description': - 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', - }, - 'failure_threshold': { - 'default': 3, - 'description': - 'The number of times to retry a failed health check before the container is considered unhealthy', - 'type': [ - 'number', - 'string', + "type": "array" + } ], - }, - 'initial_delay': { - 'default': '0s', - 'description': 'Delays the check from running for the specified amount of time', - 'type': 'string', - }, - 'interval': { - 'default': '30s', - 'description': - 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', - 'type': 'string', - }, - 'path': { - 'deprecated': true, - 'type': 'string', - }, - 'port': { - 'deprecated': true, - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'default': 1, - 'description': - 'The number of times to retry a health check before the container is considered healthy', - 'type': [ - 'number', - 'string', - ], - }, - 'timeout': { - 'default': '5s', - 'description': - 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', - 'type': 'string', - }, + "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." + }, + "failure_threshold": { + "default": 3, + "description": "The number of times to retry a failed health check before the container is considered unhealthy", + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "default": "0s", + "description": "Delays the check from running for the specified amount of time", + "type": "string" + }, + "interval": { + "default": "30s", + "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", + "type": "string" + }, + "path": { + "deprecated": true, + "type": "string" + }, + "port": { + "deprecated": true, + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "default": 1, + "description": "The number of times to retry a health check before the container is considered healthy", + "type": [ + "number", + "string" + ] + }, + "timeout": { + "default": "5s", + "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", + "type": "string" + } }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'description': 'Number of replicas of the deployment to run', - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'description': 'Autoscaling rules for the deployment', - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'description': 'Metrics to be used to trigger autoscaling', - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], - }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "description": "Number of replicas of the deployment to run", + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "description": "Autoscaling rules for the deployment", + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "description": "Metrics to be used to trigger autoscaling", + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] + }, + "memory": { + "type": "string" + } + }, + "type": "object" + }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'required': [ - 'min_replicas', - 'max_replicas', - 'metrics', + "required": [ + "min_replicas", + "max_replicas", + "metrics" ], - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'host_path': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'mount_path': { - 'type': 'string', - }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'build', + "required": [ + "build" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', - }, - 'type': 'object', - }, - 'context': { - 'type': 'string', - }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', - }, + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "context": { + "type": "string" + }, + "dockerfile": { + "type": "string" + }, + "target": { + "type": "string" + } }, - 'required': [ - 'context', + "required": [ + "context" ], - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'context': { - 'type': 'string', + "context": { + "type": "string" }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'depends_on': { - 'items': { - 'type': 'string', + "depends_on": { + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', - }, - 'path': { - 'type': 'string', + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'password': { - 'type': 'string', + "password": { + "type": "string" }, - 'port': { - 'type': [ - 'number', - 'string', - ], - }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'liveness_probe': { - 'additionalProperties': false, - 'properties': { - 'command': { - 'anyOf': [ + "liveness_probe": { + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'failure_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'initial_delay': { - 'type': 'string', - }, - 'interval': { - 'type': 'string', - }, - 'path': { - 'type': 'string', - }, - 'port': { - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'type': [ - 'number', - 'string', - ], - }, - 'timeout': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', + "type": "string" + } + ] + }, + "failure_threshold": { + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "path": { + "type": "string" + }, + "port": { + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "type": [ + "number", + "string" + ] + }, + "timeout": { + "type": "string" + } + }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] }, + "memory": { + "type": "string" + } }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], + "type": "object" }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'depends_on': { - 'description': 'Specify other services that you want to wait for before starting this one', - 'items': { - 'type': 'string', + "depends_on": { + "description": "Specify other services that you want to wait for before starting this one", + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'interfaces': { - 'additionalProperties': { - 'anyOf': [ + "interfaces": { + "additionalProperties": { + "anyOf": [ { - 'type': 'number', + "type": "number" }, { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'host': { - 'type': 'string', - }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', - }, - 'path': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'password': { - 'type': 'string', - }, - 'port': { - 'type': [ - 'number', - 'string', - ], + "password": { + "type": "string" }, - 'protocol': { - 'type': 'string', + "port": { + "type": [ + "number", + "string" + ] }, - 'url': { - 'type': 'string', + "protocol": { + "type": "string" }, - 'username': { - 'type': 'string', + "url": { + "type": "string" }, + "username": { + "type": "string" + } }, - 'required': [ - 'port', + "required": [ + "port" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', - }, - 'language': { - 'deprecated': true, - 'type': 'string', - }, - 'liveness_probe': { - 'additionalProperties': false, - 'description': 'Task run continuously to determine if each service replica is healthy', - 'properties': { - 'command': { - 'anyOf': [ + "type": "object" + }, + "language": { + "deprecated": true, + "type": "string" + }, + "liveness_probe": { + "additionalProperties": false, + "description": "Task run continuously to determine if each service replica is healthy", + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], - 'description': - 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', - }, - 'failure_threshold': { - 'default': 3, - 'description': - 'The number of times to retry a failed health check before the container is considered unhealthy', - 'type': [ - 'number', - 'string', - ], - }, - 'initial_delay': { - 'default': '0s', - 'description': 'Delays the check from running for the specified amount of time', - 'type': 'string', - }, - 'interval': { - 'default': '30s', - 'description': - 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', - 'type': 'string', - }, - 'path': { - 'deprecated': true, - 'type': 'string', - }, - 'port': { - 'deprecated': true, - 'type': [ - 'number', - 'string', - ], - }, - 'success_threshold': { - 'default': 1, - 'description': - 'The number of times to retry a health check before the container is considered healthy', - 'type': [ - 'number', - 'string', + "type": "array" + } ], - }, - 'timeout': { - 'default': '5s', - 'description': - 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', - 'type': 'string', - }, + "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." + }, + "failure_threshold": { + "default": 3, + "description": "The number of times to retry a failed health check before the container is considered unhealthy", + "type": [ + "number", + "string" + ] + }, + "initial_delay": { + "default": "0s", + "description": "Delays the check from running for the specified amount of time", + "type": "string" + }, + "interval": { + "default": "30s", + "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", + "type": "string" + }, + "path": { + "deprecated": true, + "type": "string" + }, + "port": { + "deprecated": true, + "type": [ + "number", + "string" + ] + }, + "success_threshold": { + "default": 1, + "description": "The number of times to retry a health check before the container is considered healthy", + "type": [ + "number", + "string" + ] + }, + "timeout": { + "default": "5s", + "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", + "type": "string" + } }, - 'type': 'object', - }, - 'memory': { - 'type': 'string', - }, - 'platform': { - 'type': 'string', - }, - 'replicas': { - 'description': 'Number of replicas of the deployment to run', - 'type': [ - 'number', - 'string', - ], - }, - 'scaling': { - 'additionalProperties': false, - 'description': 'Autoscaling rules for the deployment', - 'properties': { - 'max_replicas': { - 'type': [ - 'number', - 'string', - ], - }, - 'metrics': { - 'additionalProperties': false, - 'description': 'Metrics to be used to trigger autoscaling', - 'properties': { - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'type': 'string', - }, - }, - 'type': 'object', - }, - 'min_replicas': { - 'type': [ - 'number', - 'string', - ], - }, + "type": "object" + }, + "memory": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "replicas": { + "description": "Number of replicas of the deployment to run", + "type": [ + "number", + "string" + ] + }, + "scaling": { + "additionalProperties": false, + "description": "Autoscaling rules for the deployment", + "properties": { + "max_replicas": { + "type": [ + "number", + "string" + ] + }, + "metrics": { + "additionalProperties": false, + "description": "Metrics to be used to trigger autoscaling", + "properties": { + "cpu": { + "type": [ + "number", + "string" + ] + }, + "memory": { + "type": "string" + } + }, + "type": "object" + }, + "min_replicas": { + "type": [ + "number", + "string" + ] + } }, - 'required': [ - 'min_replicas', - 'max_replicas', - 'metrics', + "required": [ + "min_replicas", + "max_replicas", + "metrics" ], - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'build', - 'image', + "required": [ + "build", + "image" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': 'A set of named services that need to be run and persisted in order to power this component.', - 'type': 'object', + "description": "A set of named services that need to be run and persisted in order to power this component.", + "type": "object" }, - 'static': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'description': - 'Instructions on how to build the code into static files to be put into the `directory`. Builds will be done just-in-time (JIT) for deployments to ensure that environment variables are specific to the target environment.', - 'properties': { - 'command': { - 'description': 'Command to run to build the code', - 'type': 'string', - }, - 'context': { - 'description': 'Folder to consider the context for the build relative to the component root', - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - 'boolean', - ], + "static": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "description": "Instructions on how to build the code into static files to be put into the `directory`. Builds will be done just-in-time (JIT) for deployments to ensure that environment variables are specific to the target environment.", + "properties": { + "command": { + "description": "Command to run to build the code", + "type": "string" + }, + "context": { + "description": "Folder to consider the context for the build relative to the component root", + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number", + "boolean" + ] }, - 'description': 'Environment variables to inject into the build process', - 'type': 'object', - }, + "description": "Environment variables to inject into the build process", + "type": "object" + } }, - 'required': [ - 'context', - 'command', + "required": [ + "context", + "command" ], - 'type': 'object', + "type": "object" }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'command': { - 'type': 'string', - }, - 'context': { - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - 'boolean', - ], - }, - 'type': 'object', - }, + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "command": { + "type": "string" + }, + "context": { + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number", + "boolean" + ] + }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'directory': { - 'type': 'string', + "directory": { + "type": "string" }, - 'ingress': { - 'additionalProperties': false, - 'properties': { - 'internal': { - 'type': 'boolean', - }, - 'path': { - 'type': 'string', + "ingress": { + "additionalProperties": false, + "properties": { + "internal": { + "type": "boolean" }, - 'subdomain': { - 'type': 'string', + "path": { + "type": "string" }, + "subdomain": { + "type": "string" + } }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'directory': { - 'description': 'Directory containing the static assets to be shipped to the bucket', - 'type': 'string', + "directory": { + "description": "Directory containing the static assets to be shipped to the bucket", + "type": "string" }, - 'ingress': { - 'additionalProperties': false, - 'description': 'Configure a DNS route to point to this static bucket', - 'properties': { - 'internal': { - 'default': false, - 'description': 'Whether or not this bucket should be exposed internally vs externally', - 'type': 'boolean', - }, - 'path': { - 'description': 'Sub-path to listen on when re-routing traffic from the ingress rule to the bucket', - 'type': 'string', - }, - 'subdomain': { - 'description': 'Subdomain to use for the ingress rule', - 'type': 'string', - }, + "ingress": { + "additionalProperties": false, + "description": "Configure a DNS route to point to this static bucket", + "properties": { + "internal": { + "default": false, + "description": "Whether or not this bucket should be exposed internally vs externally", + "type": "boolean" + }, + "path": { + "description": "Sub-path to listen on when re-routing traffic from the ingress rule to the bucket", + "type": "string" + }, + "subdomain": { + "description": "Subdomain to use for the ingress rule", + "type": "string" + } }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'directory', + "required": [ + "directory" ], - 'type': 'object', + "type": "object" }, - 'description': 'A set of static asset buckets to create and load with content.', - 'type': 'object', + "description": "A set of static asset buckets to create and load with content.", + "type": "object" }, - 'tasks': { - 'additionalProperties': { - 'anyOf': [ + "tasks": { + "additionalProperties": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'command': { - 'anyOf': [ + "additionalProperties": false, + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'context': { - 'type': 'string', + "context": { + "type": "string" }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'entrypoint': { - 'anyOf': [ + "type": "string" + } + ] + }, + "cpu": { + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'deprecated': true, - 'type': 'string', + "language": { + "deprecated": true, + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', - }, - 'host_path': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'image': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'mount_path': { - 'type': 'string', + "image": { + "type": "string" }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', - }, - 'type': 'object', - }, - 'context': { - 'type': 'string', - }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', - }, + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "context": { + "type": "string" + }, + "dockerfile": { + "type": "string" + }, + "target": { + "type": "string" + } }, - 'required': [ - 'context', + "required": [ + "context" ], - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'context': { - 'type': 'string', + "context": { + "type": "string" }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'entrypoint': { - 'anyOf': [ + "type": "string" + } + ] + }, + "cpu": { + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'host_path': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'mount_path': { - 'type': 'string', - }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'deprecated': true, - 'type': 'string', + "language": { + "deprecated": true, + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'host_path': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'mount_path': { - 'type': 'string', - }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'build', + "required": [ + "build" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', - }, - 'type': 'object', - }, - 'context': { - 'type': 'string', - }, - 'dockerfile': { - 'type': 'string', - }, - 'target': { - 'type': 'string', - }, + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "context": { + "type": "string" + }, + "dockerfile": { + "type": "string" + }, + "target": { + "type": "string" + } }, - 'required': [ - 'context', + "required": [ + "context" ], - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], + "cpu": { + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "properties": { + "build": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', - }, - 'context': { - 'type': 'string', + "type": "object" }, - 'dockerfile': { - 'type': 'string', + "context": { + "type": "string" }, - 'target': { - 'type': 'string', + "dockerfile": { + "type": "string" }, + "target": { + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], - }, - 'cpu': { - 'type': [ - 'number', - 'string', - ], - }, - 'entrypoint': { - 'anyOf': [ + "type": "string" + } + ] + }, + "cpu": { + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, { - 'type': 'string', - }, - ], + "type": "string" + } + ] }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'type': 'string', + "language": { + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'host_path': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'mount_path': { - 'type': 'string', - }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - ], - }, - 'environment': { - 'additionalProperties': { - 'type': [ - 'string', - 'number', - ], + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "environment": { + "additionalProperties": { + "type": [ + "string", + "number" + ] }, - 'type': 'object', + "type": "object" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'type': 'object', + "type": "object" }, - 'language': { - 'deprecated': true, - 'type': 'string', + "language": { + "deprecated": true, + "type": "string" }, - 'memory': { - 'type': 'string', + "memory": { + "type": "string" }, - 'platform': { - 'type': 'string', + "platform": { + "type": "string" }, - 'schedule': { - 'type': 'string', + "schedule": { + "type": "string" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'type': 'string', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" }, - 'host_path': { - 'type': 'string', + "host_path": { + "type": "string" }, - 'image': { - 'type': 'string', + "image": { + "type": "string" }, - 'mount_path': { - 'type': 'string', - }, - 'readonly': { - 'type': [ - 'boolean', - 'string', - ], + "mount_path": { + "type": "string" }, + "readonly": { + "type": [ + "boolean", + "string" + ] + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'build', - 'image', + "required": [ + "build", + "image" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': - 'A set of scheduled and triggerable tasks that get registered alongside the component. Tasks are great for data translation, reporting, and much more.', - 'type': 'object', + "description": "A set of scheduled and triggerable tasks that get registered alongside the component. Tasks are great for data translation, reporting, and much more.", + "type": "object" }, - 'variables': { - 'additionalProperties': { - 'anyOf': [ + "variables": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'default': { - 'description': - 'The default value to apply to the parameter when one wasn\'t provided by the operator', - 'type': [ - 'string', - 'number', - ], - }, - 'description': { - 'description': - 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', - 'type': 'string', - }, - 'merge': { - 'default': false, - 'description': 'Whether or not to merge results from multiple sources into a single array', - 'type': 'boolean', - }, - 'required': { - 'default': false, - 'description': 'A boolean indicating whether or not an operator is required ot provide a value', - 'type': 'boolean', - }, + "additionalProperties": false, + "properties": { + "default": { + "description": "The default value to apply to the parameter when one wasn't provided by the operator", + "type": [ + "string", + "number" + ] + }, + "description": { + "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", + "type": "string" + }, + "merge": { + "default": false, + "description": "Whether or not to merge results from multiple sources into a single array", + "type": "boolean" + }, + "required": { + "default": false, + "description": "A boolean indicating whether or not an operator is required ot provide a value", + "type": "boolean" + } }, - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': - 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `parameters` field.', - 'type': 'object', - }, - 'version': { - 'const': 'v1', - 'type': 'string', + "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `parameters` field.", + "type": "object" }, + "version": { + "const": "v1", + "type": "string" + } }, - 'required': [ - 'version', + "required": [ + "version" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'builds': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "buckets": { + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "CSV reporting dumps" + ], + "type": "string" + }, + "directory": { + "description": "The directory containing the contents to upload to the bucket", + "examples": [ + "./reports" + ], + "type": "string" + }, + "image": { + "description": "The built image containing the contents to upload inside the workdir", + "examples": [ + "registry.architect.io/my-org/my-image:latest" + ], + "type": "string" + } }, - 'description': 'A set of arguments to pass to the build job', - 'examples': [ - { - 'BUILDKIT_INLINE_CACHE': '1', + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deploy": { + "additionalProperties": false, + "description": "Settings outlining a step that should be run when the component gets deployed", + "properties": { + "command": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Command to use when the container is booted up", + "examples": [ + [ + "npm", + "start" + ] + ] + }, + "cpu": { + "description": "The amount of CPU to allocate to each instance of the deployment", + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "" + ], + "description": "The executable to run every time the container is booted up" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables to pass to the service", + "examples": [ + { + "NODE_ENV": "production" + }, + { + "BACKEND_URL": "${{ ingresses.backend.url }}" + } + ], + "type": "object" + }, + "image": { + "description": "Docker image to use for the deployment", + "examples": [ + "${{ builds.frontend.image }}", + "my-registry.com/my-app:latest" + ], + "type": "string" + }, + "memory": { + "description": "The amount of memory to allocate to each instance of the deployment", + "type": "string" + }, + "platform": { + "description": "Set platform if server is multi-platform capable", + "examples": [ + "linux/amd64" + ], + "type": "string" + }, + "publish": { + "description": "The path to the directory containing the contents to upload to the bucket", + "examples": [ + "./dist" + ], + "type": "string" + }, + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "Path on the host machine to sync with the volume", + "examples": [ + "/Users/batman/app/src" + ], + "type": "string" + }, + "image": { + "description": "OCI image containing the contents to seed the volume with", + "type": "string" + }, + "mount_path": { + "description": "Path inside the container to mount the volume to", + "examples": [ + "/app/src" + ], + "type": "string" + } + }, + "required": [ + "mount_path" + ], + "type": "object" + }, + "description": "Volumes that should be created and attached to each replica", + "type": "object" + } + }, + "required": [ + "image", + "publish" + ], + "type": "object" }, + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "A static website" + ], + "type": "string" + } + }, + "required": [ + "deploy" ], - 'type': 'object', + "type": "object" + } + ] + }, + "description": "Buckets that can be used to store and serve files", + "type": "object" + }, + "builds": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "args": { + "additionalProperties": { + "type": "string" + }, + "description": "A set of arguments to pass to the build job", + "examples": [ + { + "BUILDKIT_INLINE_CACHE": "1" + } + ], + "type": "object" }, - 'context': { - 'description': 'Path to the folder containing the code to build', - 'examples': [ - './', + "context": { + "description": "Path to the folder containing the code to build", + "examples": [ + "./" ], - 'type': 'string', + "type": "string" }, - 'debug': { - 'additionalProperties': false, - 'description': 'Debugging options for the build step', - 'properties': { - 'args': { - 'additionalProperties': { - 'type': 'string', + "debug": { + "additionalProperties": false, + "description": "Debugging options for the build step", + "properties": { + "args": { + "additionalProperties": { + "type": "string" }, - 'description': 'A set of arguments to pass to the build job', - 'examples': [ + "description": "A set of arguments to pass to the build job", + "examples": [ { - 'BUILDKIT_INLINE_CACHE': '1', - }, + "BUILDKIT_INLINE_CACHE": "1" + } ], - 'type': 'object', + "type": "object" }, - 'context': { - 'description': 'Path to the folder containing the code to build', - 'examples': [ - './', + "context": { + "description": "Path to the folder containing the code to build", + "examples": [ + "./" ], - 'type': 'string', + "type": "string" }, - 'description': { - 'description': 'Description of the build artifact', - 'examples': [ - 'Builds the source code for the application', + "description": { + "description": "Description of the build artifact", + "examples": [ + "Builds the source code for the application" ], - 'type': 'string', - }, - 'dockerfile': { - 'default': 'Dockerfile', - 'description': 'The path to the dockerfile defining this build step', - 'type': 'string', - }, - 'image': { - 'description': - 'The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.', - 'examples': [ - 'my-registry.com/my-app:latest', - ], - 'type': 'string', + "type": "string" + }, + "dockerfile": { + "default": "Dockerfile", + "description": "The path to the dockerfile defining this build step", + "type": "string" }, - 'target': { - 'description': 'The docker target to use during the build process', - 'examples': [ - 'builder', + "image": { + "description": "The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.", + "examples": [ + "my-registry.com/my-app:latest" ], - 'type': 'string', + "type": "string" }, + "target": { + "description": "The docker target to use during the build process", + "examples": [ + "builder" + ], + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'description': { - 'description': 'Description of the build artifact', - 'examples': [ - 'Builds the source code for the application', + "description": { + "description": "Description of the build artifact", + "examples": [ + "Builds the source code for the application" ], - 'type': 'string', + "type": "string" }, - 'dockerfile': { - 'default': 'Dockerfile', - 'description': 'The path to the dockerfile defining this build step', - 'type': 'string', + "dockerfile": { + "default": "Dockerfile", + "description": "The path to the dockerfile defining this build step", + "type": "string" }, - 'image': { - 'description': - 'The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.', - 'examples': [ - 'my-registry.com/my-app:latest', + "image": { + "description": "The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.", + "examples": [ + "my-registry.com/my-app:latest" ], - 'type': 'string', + "type": "string" }, - 'target': { - 'description': 'The docker target to use during the build process', - 'examples': [ - 'builder', + "target": { + "description": "The docker target to use during the build process", + "examples": [ + "builder" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'context', + "required": [ + "context" ], - 'type': 'object', + "type": "object" }, - 'description': 'A set of build jobs to run to power other deployments or tasks', - 'type': 'object', + "description": "A set of build jobs to run to power other deployments or tasks", + "type": "object" }, - 'databases': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'description': { - 'default': '', - 'description': 'A human-readable description of the use-case for the database', - 'type': 'string', + "databases": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "default": "", + "description": "A human-readable description of the use-case for the database", + "type": "string" }, - 'migrate': { - 'additionalProperties': false, - 'description': 'Configuration details for how to run database migrations', - 'properties': { - 'command': { - 'anyOf': [ + "migrate": { + "additionalProperties": false, + "description": "Configuration details for how to run database migrations", + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'description': 'A command to run in the container to execute the migration', - 'examples': [ + "description": "A command to run in the container to execute the migration", + "examples": [ [ - 'npm', - 'run', - 'migrate', - ], - ], - }, - 'entrypoint': { - 'anyOf': [ + "npm", + "run", + "migrate" + ] + ] + }, + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'default': [ - '', + "default": [ + "" ], - 'description': 'An entrypoint to use for the docker container', + "description": "An entrypoint to use for the docker container" }, - 'environment': { - 'additionalProperties': { - 'anyOf': [ + "environment": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'boolean', + "type": "boolean" }, { - 'type': 'null', + "type": "null" }, { - 'not': {}, - }, - ], + "not": {} + } + ] }, - 'description': 'Environment variables to set in the container', - 'examples': [ + "description": "Environment variables to set in the container", + "examples": [ { - 'DATABASE_URL': '${{ databases.auth.url }}', - }, + "DATABASE_URL": "${{ databases.auth.url }}" + } ], - 'type': 'object', + "type": "object" }, - 'image': { - 'description': 'The docker image containing the migration tooling and files', - 'examples': [ - '${{ builds.api.image }}', + "image": { + "description": "The docker image containing the migration tooling and files", + "examples": [ + "${{ builds.api.image }}" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, - 'seed': { - 'additionalProperties': false, - 'description': 'Configuration details for how to seed the database', - 'properties': { - 'command': { - 'anyOf': [ + "seed": { + "additionalProperties": false, + "description": "Configuration details for how to seed the database", + "properties": { + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'description': 'A command to run in the container to execute the seeding', - 'examples': [ + "description": "A command to run in the container to execute the seeding", + "examples": [ [ - 'npm', - 'run', - 'seed', - ], - ], - }, - 'entrypoint': { - 'anyOf': [ + "npm", + "run", + "seed" + ] + ] + }, + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'default': [ - '', + "default": [ + "" ], - 'description': 'An entrypoint to use for the docker container', + "description": "An entrypoint to use for the docker container" }, - 'environment': { - 'additionalProperties': { - 'anyOf': [ + "environment": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'boolean', + "type": "boolean" }, { - 'type': 'null', + "type": "null" }, { - 'not': {}, - }, - ], + "not": {} + } + ] }, - 'description': 'Environment variables to set in the container', - 'examples': [ + "description": "Environment variables to set in the container", + "examples": [ { - 'DATABASE_URL': '${{ databases.auth.url }}', - }, + "DATABASE_URL": "${{ databases.auth.url }}" + } ], - 'type': 'object', + "type": "object" }, - 'image': { - 'description': 'The docker image containing the seeding tooling and files', - 'examples': [ - '${{ builds.api.image }}', + "image": { + "description": "The docker image containing the seeding tooling and files", + "examples": [ + "${{ builds.api.image }}" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, - 'type': { - 'description': 'The type of database and version to use', - 'examples': [ - 'postgres:15', - 'mysql:8', - 'redis:5', + "type": { + "description": "The type of database and version to use", + "examples": [ + "postgres:15", + "mysql:8", + "redis:5" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'type', + "required": [ + "type" ], - 'type': 'object', + "type": "object" }, - 'description': 'A set of databases that this component requires', - 'type': 'object', + "description": "A set of databases that this component requires", + "type": "object" }, - 'dependencies': { - 'additionalProperties': { - 'anyOf': [ + "dependencies": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'additionalProperties': false, - 'properties': { - 'component': { - 'description': 'The repo the component is in', - 'type': 'string', - }, - 'variables': { - 'additionalProperties': { - 'anyOf': [ + "additionalProperties": false, + "properties": { + "component": { + "description": "The repo the component is in", + "type": "string" + }, + "variables": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'description': 'Input values to provide to the component if `merge` is turned on', - 'examples': [ + "description": "Input values to provide to the component if `merge` is turned on", + "examples": [ { - 'allowed_return_urls': [ - 'https://architect.io', - '${{ ingresses.frontend.url }}', - ], - }, + "allowed_return_urls": [ + "https://architect.io", + "${{ ingresses.frontend.url }}" + ] + } ], - 'type': 'object', - }, + "type": "object" + } }, - 'required': [ - 'component', + "required": [ + "component" ], - 'type': 'object', - }, - ], + "type": "object" + } + ] }, - 'description': 'A set of other components that this component depends on', - 'examples': [ + "description": "A set of other components that this component depends on", + "examples": [ { - 'auth': { - 'component': 'architect/auth-component', - 'variables': { - 'allowed_return_urls': [ - 'https://architect.io', - '${{ ingresses.frontend.url }}', - ], - }, + "auth": { + "component": "architect/auth-component", + "variables": { + "allowed_return_urls": [ + "https://architect.io", + "${{ ingresses.frontend.url }}" + ] + } }, - 'payments': 'architect/payments-component', - }, + "payments": "architect/payments-component" + } ], - 'type': 'object', + "type": "object" }, - 'deployments': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'autoscaling': { - 'additionalProperties': false, - 'description': 'Configuration settings for how to automatically scale the application up and down', - 'properties': { - 'cpu': { - 'description': 'Maximum number of CPUs to allocate to each replica', - 'examples': [ - '0.5', - '1', + "deployments": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "autoscaling": { + "additionalProperties": false, + "description": "Configuration settings for how to automatically scale the application up and down", + "properties": { + "cpu": { + "description": "Maximum number of CPUs to allocate to each replica", + "examples": [ + "0.5", + "1" ], - 'type': [ - 'number', - 'string', - ], - }, - 'memory': { - 'description': 'Maximum memory usage per replica before scaling up', - 'examples': [ - '200Mi', - '2Gi', + "type": [ + "number", + "string" + ] + }, + "memory": { + "description": "Maximum memory usage per replica before scaling up", + "examples": [ + "200Mi", + "2Gi" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'description': 'Command to use when the container is booted up', - 'examples': [ + "description": "Command to use when the container is booted up", + "examples": [ [ - 'npm', - 'start', - ], - ], + "npm", + "start" + ] + ] }, - 'cpu': { - 'description': 'The amount of CPU to allocate to each instance of the deployment', - 'type': [ - 'number', - 'string', - ], + "cpu": { + "description": "The amount of CPU to allocate to each instance of the deployment", + "type": [ + "number", + "string" + ] }, - 'debug': { - 'additionalProperties': false, - 'description': 'Debugging options for the deployment', - 'properties': { - 'autoscaling': { - 'additionalProperties': false, - 'description': 'Configuration settings for how to automatically scale the application up and down', - 'properties': { - 'cpu': { - 'description': 'Maximum number of CPUs to allocate to each replica', - 'examples': [ - '0.5', - '1', - ], - 'type': [ - 'number', - 'string', + "debug": { + "additionalProperties": false, + "description": "Debugging options for the deployment", + "properties": { + "autoscaling": { + "additionalProperties": false, + "description": "Configuration settings for how to automatically scale the application up and down", + "properties": { + "cpu": { + "description": "Maximum number of CPUs to allocate to each replica", + "examples": [ + "0.5", + "1" ], - }, - 'memory': { - 'description': 'Maximum memory usage per replica before scaling up', - 'examples': [ - '200Mi', - '2Gi', + "type": [ + "number", + "string" + ] + }, + "memory": { + "description": "Maximum memory usage per replica before scaling up", + "examples": [ + "200Mi", + "2Gi" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'command': { - 'anyOf': [ + "command": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'description': 'Command to use when the container is booted up', - 'examples': [ + "description": "Command to use when the container is booted up", + "examples": [ [ - 'npm', - 'start', - ], - ], - }, - 'cpu': { - 'description': 'The amount of CPU to allocate to each instance of the deployment', - 'type': [ - 'number', - 'string', + "npm", + "start" + ] + ] + }, + "cpu": { + "description": "The amount of CPU to allocate to each instance of the deployment", + "type": [ + "number", + "string" + ] + }, + "description": { + "description": "Human readable description of the deployment", + "examples": [ + "Runs the frontend web application" ], + "type": "string" }, - 'description': { - 'description': 'Human readable description of the deployment', - 'examples': [ - 'Runs the frontend web application', - ], - 'type': 'string', - }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'default': [ - '', + "default": [ + "" ], - 'description': 'The executable to run every time the container is booted up', + "description": "The executable to run every time the container is booted up" }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': 'Environment variables to pass to the service', - 'examples': [ + "description": "Environment variables to pass to the service", + "examples": [ { - 'NODE_ENV': 'production', + "NODE_ENV": "production" }, { - 'BACKEND_URL': '${{ ingresses.backend.url }}', - }, + "BACKEND_URL": "${{ ingresses.backend.url }}" + } ], - 'type': 'object', + "type": "object" }, - 'image': { - 'description': 'Docker image to use for the deployment', - 'examples': [ - '${{ builds.frontend.image }}', - 'my-registry.com/my-app:latest', + "image": { + "description": "Docker image to use for the deployment", + "examples": [ + "${{ builds.frontend.image }}", + "my-registry.com/my-app:latest" ], - 'type': 'string', + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'description': 'The labels to apply to the deployment', - 'type': 'object', + "description": "The labels to apply to the deployment", + "type": "object" }, - 'memory': { - 'description': 'The amount of memory to allocate to each instance of the deployment', - 'type': 'string', + "memory": { + "description": "The amount of memory to allocate to each instance of the deployment", + "type": "string" }, - 'platform': { - 'description': 'Set platform if server is multi-platform capable', - 'examples': [ - 'linux/amd64', + "platform": { + "description": "Set platform if server is multi-platform capable", + "examples": [ + "linux/amd64" ], - 'type': 'string', - }, - 'probes': { - 'additionalProperties': false, - 'description': 'Configuration details for probes that check each replicas status', - 'properties': { - 'liveness': { - 'anyOf': [ + "type": "string" + }, + "probes": { + "additionalProperties": false, + "description": "Configuration details for probes that check each replicas status", + "properties": { + "liveness": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'command': { - 'description': 'Command to run inside the container to determine if its healthy', - 'items': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "command": { + "description": "Command to run inside the container to determine if its healthy", + "items": { + "type": "string" }, - 'type': 'array', + "type": "array" }, - 'failure_threshold': { - 'default': 3, - 'description': - 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', - 'minimum': 1, - 'type': 'number', + "failure_threshold": { + "default": 3, + "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", + "minimum": 1, + "type": "number" }, - 'initial_delay': { - 'default': 0, - 'description': - 'Number of seconds after the container starts before the probe is initiated.', - 'minimum': 0, - 'type': 'number', + "initial_delay": { + "default": 0, + "description": "Number of seconds after the container starts before the probe is initiated.", + "minimum": 0, + "type": "number" }, - 'interval': { - 'default': 10, - 'description': 'How often (in seconds) to perform the probe.', - 'minimum': 1, - 'type': 'number', + "interval": { + "default": 10, + "description": "How often (in seconds) to perform the probe.", + "minimum": 1, + "type": "number" }, - 'success_threshold': { - 'default': 1, - 'description': - 'Minimum consecutive successes for the probe to be considered successful after having failed.', - 'minimum': 1, - 'type': 'number', + "success_threshold": { + "default": 1, + "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", + "minimum": 1, + "type": "number" }, - 'timeout': { - 'default': 1, - 'description': 'Number of seconds after which the probe times out', - 'minimum': 1, - 'type': 'number', + "timeout": { + "default": 1, + "description": "Number of seconds after which the probe times out", + "minimum": 1, + "type": "number" }, - 'type': { - 'const': 'exec', - 'type': 'string', - }, - }, - 'required': [ - 'command', - 'type', + "type": { + "const": "exec", + "type": "string" + } + }, + "required": [ + "command", + "type" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'failure_threshold': { - 'default': 3, - 'description': - 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', - 'minimum': 1, - 'type': 'number', + "additionalProperties": false, + "properties": { + "failure_threshold": { + "default": 3, + "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", + "minimum": 1, + "type": "number" }, - 'headers': { - 'description': 'Custom headers to set in the request.', - 'items': { - 'additionalProperties': false, - 'properties': { - 'name': { - 'type': 'string', - }, - 'value': { - 'type': 'string', + "headers": { + "description": "Custom headers to set in the request.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" }, + "value": { + "type": "string" + } }, - 'required': [ - 'name', - 'value', + "required": [ + "name", + "value" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', - }, - 'initial_delay': { - 'default': 0, - 'description': - 'Number of seconds after the container starts before the probe is initiated.', - 'minimum': 0, - 'type': 'number', + "type": "array" }, - 'interval': { - 'default': 10, - 'description': 'How often (in seconds) to perform the probe.', - 'minimum': 1, - 'type': 'number', + "initial_delay": { + "default": 0, + "description": "Number of seconds after the container starts before the probe is initiated.", + "minimum": 0, + "type": "number" }, - 'path': { - 'default': '/', - 'description': 'Path to access on the http server', - 'type': 'string', + "interval": { + "default": 10, + "description": "How often (in seconds) to perform the probe.", + "minimum": 1, + "type": "number" }, - 'port': { - 'description': 'Port to access on the container', - 'type': 'number', + "path": { + "default": "/", + "description": "Path to access on the http server", + "type": "string" }, - 'scheme': { - 'default': 'http', - 'description': 'Scheme to use for connecting to the host (http or https).', - 'type': 'string', + "port": { + "description": "Port to access on the container", + "type": "number" }, - 'success_threshold': { - 'default': 1, - 'description': - 'Minimum consecutive successes for the probe to be considered successful after having failed.', - 'minimum': 1, - 'type': 'number', + "scheme": { + "default": "http", + "description": "Scheme to use for connecting to the host (http or https).", + "type": "string" }, - 'timeout': { - 'default': 1, - 'description': 'Number of seconds after which the probe times out', - 'minimum': 1, - 'type': 'number', + "success_threshold": { + "default": 1, + "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", + "minimum": 1, + "type": "number" }, - 'type': { - 'const': 'http', - 'type': 'string', + "timeout": { + "default": 1, + "description": "Number of seconds after which the probe times out", + "minimum": 1, + "type": "number" }, + "type": { + "const": "http", + "type": "string" + } }, - 'required': [ - 'type', + "required": [ + "type" ], - 'type': 'object', - }, + "type": "object" + } ], - 'description': - 'Configuration settings to determine if the deployment is ready to receive traffic', - }, + "description": "Configuration settings to determine if the deployment is ready to receive traffic" + } }, - 'type': 'object', - }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'Path on the host machine to sync with the volume', - 'examples': [ - '/Users/batman/app/src', + "type": "object" + }, + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "Path on the host machine to sync with the volume", + "examples": [ + "/Users/batman/app/src" ], - 'type': 'string', + "type": "string" }, - 'image': { - 'description': 'OCI image containing the contents to seed the volume with', - 'type': 'string', + "image": { + "description": "OCI image containing the contents to seed the volume with", + "type": "string" }, - 'mount_path': { - 'description': 'Path inside the container to mount the volume to', - 'examples': [ - '/app/src', + "mount_path": { + "description": "Path inside the container to mount the volume to", + "examples": [ + "/app/src" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'description': 'Volumes that should be created and attached to each replica', - 'type': 'object', - }, + "description": "Volumes that should be created and attached to each replica", + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'description': { - 'description': 'Human readable description of the deployment', - 'examples': [ - 'Runs the frontend web application', + "description": { + "description": "Human readable description of the deployment", + "examples": [ + "Runs the frontend web application" ], - 'type': 'string', + "type": "string" }, - 'entrypoint': { - 'anyOf': [ + "entrypoint": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, + "type": "array" + } ], - 'default': [ - '', + "default": [ + "" ], - 'description': 'The executable to run every time the container is booted up', + "description": "The executable to run every time the container is booted up" }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': 'Environment variables to pass to the service', - 'examples': [ + "description": "Environment variables to pass to the service", + "examples": [ { - 'NODE_ENV': 'production', + "NODE_ENV": "production" }, { - 'BACKEND_URL': '${{ ingresses.backend.url }}', - }, + "BACKEND_URL": "${{ ingresses.backend.url }}" + } ], - 'type': 'object', + "type": "object" }, - 'image': { - 'description': 'Docker image to use for the deployment', - 'examples': [ - '${{ builds.frontend.image }}', - 'my-registry.com/my-app:latest', + "image": { + "description": "Docker image to use for the deployment", + "examples": [ + "${{ builds.frontend.image }}", + "my-registry.com/my-app:latest" ], - 'type': 'string', + "type": "string" }, - 'labels': { - 'additionalProperties': { - 'type': 'string', + "labels": { + "additionalProperties": { + "type": "string" }, - 'description': 'The labels to apply to the deployment', - 'type': 'object', + "description": "The labels to apply to the deployment", + "type": "object" }, - 'memory': { - 'description': 'The amount of memory to allocate to each instance of the deployment', - 'type': 'string', + "memory": { + "description": "The amount of memory to allocate to each instance of the deployment", + "type": "string" }, - 'platform': { - 'description': 'Set platform if server is multi-platform capable', - 'examples': [ - 'linux/amd64', + "platform": { + "description": "Set platform if server is multi-platform capable", + "examples": [ + "linux/amd64" ], - 'type': 'string', + "type": "string" }, - 'probes': { - 'additionalProperties': false, - 'description': 'Configuration details for probes that check each replicas status', - 'properties': { - 'liveness': { - 'anyOf': [ + "probes": { + "additionalProperties": false, + "description": "Configuration details for probes that check each replicas status", + "properties": { + "liveness": { + "anyOf": [ { - 'additionalProperties': false, - 'properties': { - 'command': { - 'description': 'Command to run inside the container to determine if its healthy', - 'items': { - 'type': 'string', - }, - 'type': 'array', - }, - 'failure_threshold': { - 'default': 3, - 'description': - 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', - 'minimum': 1, - 'type': 'number', - }, - 'initial_delay': { - 'default': 0, - 'description': - 'Number of seconds after the container starts before the probe is initiated.', - 'minimum': 0, - 'type': 'number', - }, - 'interval': { - 'default': 10, - 'description': 'How often (in seconds) to perform the probe.', - 'minimum': 1, - 'type': 'number', - }, - 'success_threshold': { - 'default': 1, - 'description': - 'Minimum consecutive successes for the probe to be considered successful after having failed.', - 'minimum': 1, - 'type': 'number', - }, - 'timeout': { - 'default': 1, - 'description': 'Number of seconds after which the probe times out', - 'minimum': 1, - 'type': 'number', - }, - 'type': { - 'const': 'exec', - 'type': 'string', - }, - }, - 'required': [ - 'command', - 'type', + "additionalProperties": false, + "properties": { + "command": { + "description": "Command to run inside the container to determine if its healthy", + "items": { + "type": "string" + }, + "type": "array" + }, + "failure_threshold": { + "default": 3, + "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", + "minimum": 1, + "type": "number" + }, + "initial_delay": { + "default": 0, + "description": "Number of seconds after the container starts before the probe is initiated.", + "minimum": 0, + "type": "number" + }, + "interval": { + "default": 10, + "description": "How often (in seconds) to perform the probe.", + "minimum": 1, + "type": "number" + }, + "success_threshold": { + "default": 1, + "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", + "minimum": 1, + "type": "number" + }, + "timeout": { + "default": 1, + "description": "Number of seconds after which the probe times out", + "minimum": 1, + "type": "number" + }, + "type": { + "const": "exec", + "type": "string" + } + }, + "required": [ + "command", + "type" ], - 'type': 'object', + "type": "object" }, { - 'additionalProperties': false, - 'properties': { - 'failure_threshold': { - 'default': 3, - 'description': - 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', - 'minimum': 1, - 'type': 'number', - }, - 'headers': { - 'description': 'Custom headers to set in the request.', - 'items': { - 'additionalProperties': false, - 'properties': { - 'name': { - 'type': 'string', - }, - 'value': { - 'type': 'string', + "additionalProperties": false, + "properties": { + "failure_threshold": { + "default": 3, + "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", + "minimum": 1, + "type": "number" + }, + "headers": { + "description": "Custom headers to set in the request.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" }, + "value": { + "type": "string" + } }, - 'required': [ - 'name', - 'value', + "required": [ + "name", + "value" ], - 'type': 'object', - }, - 'type': 'array', - }, - 'initial_delay': { - 'default': 0, - 'description': - 'Number of seconds after the container starts before the probe is initiated.', - 'minimum': 0, - 'type': 'number', - }, - 'interval': { - 'default': 10, - 'description': 'How often (in seconds) to perform the probe.', - 'minimum': 1, - 'type': 'number', - }, - 'path': { - 'default': '/', - 'description': 'Path to access on the http server', - 'type': 'string', - }, - 'port': { - 'description': 'Port to access on the container', - 'type': 'number', - }, - 'scheme': { - 'default': 'http', - 'description': 'Scheme to use for connecting to the host (http or https).', - 'type': 'string', - }, - 'success_threshold': { - 'default': 1, - 'description': - 'Minimum consecutive successes for the probe to be considered successful after having failed.', - 'minimum': 1, - 'type': 'number', - }, - 'timeout': { - 'default': 1, - 'description': 'Number of seconds after which the probe times out', - 'minimum': 1, - 'type': 'number', - }, - 'type': { - 'const': 'http', - 'type': 'string', - }, - }, - 'required': [ - 'type', + "type": "object" + }, + "type": "array" + }, + "initial_delay": { + "default": 0, + "description": "Number of seconds after the container starts before the probe is initiated.", + "minimum": 0, + "type": "number" + }, + "interval": { + "default": 10, + "description": "How often (in seconds) to perform the probe.", + "minimum": 1, + "type": "number" + }, + "path": { + "default": "/", + "description": "Path to access on the http server", + "type": "string" + }, + "port": { + "description": "Port to access on the container", + "type": "number" + }, + "scheme": { + "default": "http", + "description": "Scheme to use for connecting to the host (http or https).", + "type": "string" + }, + "success_threshold": { + "default": 1, + "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", + "minimum": 1, + "type": "number" + }, + "timeout": { + "default": 1, + "description": "Number of seconds after which the probe times out", + "minimum": 1, + "type": "number" + }, + "type": { + "const": "http", + "type": "string" + } + }, + "required": [ + "type" ], - 'type': 'object', - }, + "type": "object" + } ], - 'description': 'Configuration settings to determine if the deployment is ready to receive traffic', - }, + "description": "Configuration settings to determine if the deployment is ready to receive traffic" + } }, - 'type': 'object', + "type": "object" }, - 'volumes': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'Path on the host machine to sync with the volume', - 'examples': [ - '/Users/batman/app/src', + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "Path on the host machine to sync with the volume", + "examples": [ + "/Users/batman/app/src" ], - 'type': 'string', + "type": "string" }, - 'image': { - 'description': 'OCI image containing the contents to seed the volume with', - 'type': 'string', + "image": { + "description": "OCI image containing the contents to seed the volume with", + "type": "string" }, - 'mount_path': { - 'description': 'Path inside the container to mount the volume to', - 'examples': [ - '/app/src', + "mount_path": { + "description": "Path inside the container to mount the volume to", + "examples": [ + "/app/src" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'mount_path', + "required": [ + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'description': 'Volumes that should be created and attached to each replica', - 'type': 'object', - }, + "description": "Volumes that should be created and attached to each replica", + "type": "object" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, - 'description': 'Workloads that should be deployed', - 'type': 'object', + "description": "Workloads that should be deployed", + "type": "object" }, - 'ingresses': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'headers': { - 'additionalProperties': { - 'type': 'string', - }, - 'description': 'Additional headers to include in responses', - 'examples': [ - { - 'Access-Control-Allow-Credentials': 'true', - 'Access-Control-Allow-Origin': '${{ variables.allowed_return_urls }}', + "ingresses": { + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Additional headers to include in responses", + "examples": [ + { + "Access-Control-Allow-Credentials": "true", + "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" + } + ], + "type": "object" }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + }, + "service": { + "description": "Service the ingress rule forwards traffic to", + "examples": [ + "backend" + ], + "type": "string" + } + }, + "required": [ + "service" ], - 'type': 'object', - }, - 'internal': { - 'default': false, - 'description': 'Whether or not the ingress rule should be attached to an internal gateway', - 'type': 'boolean', + "type": "object" }, - 'service': { - 'description': 'Service the ingress rule forwards traffic to', - 'examples': [ - 'backend', + { + "additionalProperties": false, + "properties": { + "bucket": { + "description": "The static bucket to serve content from", + "examples": [ + "my-bucket" + ], + "type": "string" + }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + } + }, + "required": [ + "bucket" ], - 'type': 'string', - }, - }, - 'required': [ - 'service', - ], - 'type': 'object', + "type": "object" + } + ] }, - 'description': 'Claims for external (e.g. client) access to a service', - 'type': 'object', + "description": "Claims for external (e.g. client) access to a service", + "type": "object" }, - 'services': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'deployment': { - 'description': 'Deployment the service sends requests to', - 'examples': [ - 'backend', + "services": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "deployment": { + "description": "Deployment the service sends requests to", + "examples": [ + "backend" ], - 'type': 'string', + "type": "string" }, - 'description': { - 'description': 'Description of the service', - 'examples': [ - 'Exposes the backend to other applications', + "description": { + "description": "Description of the service", + "examples": [ + "Exposes the backend to other applications" ], - 'type': 'string', + "type": "string" }, - 'password': { - 'description': 'Basic auth password', - 'type': 'string', + "password": { + "description": "Basic auth password", + "type": "string" }, - 'port': { - 'description': 'Port the service listens on', - 'examples': [ - 8080, + "port": { + "description": "Port the service listens on", + "examples": [ + 8080 ], - 'type': 'number', - }, - 'protocol': { - 'default': 'http', - 'description': 'Protocol the service listens on', - 'type': 'string', + "type": "number" }, - 'username': { - 'description': 'Basic auth username', - 'type': 'string', + "protocol": { + "default": "http", + "description": "Protocol the service listens on", + "type": "string" }, + "username": { + "description": "Basic auth username", + "type": "string" + } }, - 'required': [ - 'deployment', - 'port', + "required": [ + "deployment", + "port" ], - 'type': 'object', + "type": "object" }, - 'description': 'Services that can receive network traffic', - 'type': 'object', + "description": "Services that can receive network traffic", + "type": "object" }, - 'variables': { - 'additionalProperties': { - 'additionalProperties': false, - 'properties': { - 'default': { - 'anyOf': [ + "variables": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "default": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], - 'description': 'A default value to use if one isn\'t provided', - 'examples': [ - 'https://architect.io', + "type": "array" + } ], + "description": "A default value to use if one isn't provided", + "examples": [ + "https://architect.io" + ] }, - 'description': { - 'description': 'A human-readable description', - 'examples': [ - 'API key used to authenticate with Stripe', + "description": { + "description": "A human-readable description", + "examples": [ + "API key used to authenticate with Stripe" ], - 'type': 'string', + "type": "string" }, - 'merge': { - 'default': false, - 'description': - 'If true, upstream components can pass in values that will be merged together with each other and environment-provided values', - 'type': 'boolean', + "merge": { + "default": false, + "description": "If true, upstream components can pass in values that will be merged together with each other and environment-provided values", + "type": "boolean" }, - 'required': { - 'default': false, - 'description': 'If true, a value is required or the component won\'t run.', - 'type': 'boolean', - }, - 'sensitive': { - 'default': false, - 'description': 'Whether or not the data should be considered sensitive and stripped from logs', - 'type': 'boolean', + "required": { + "default": false, + "description": "If true, a value is required or the component won't run.", + "type": "boolean" }, + "sensitive": { + "default": false, + "description": "Whether or not the data should be considered sensitive and stripped from logs", + "type": "boolean" + } }, - 'type': 'object', + "type": "object" }, - 'description': 'A set of inputs the component expects to be provided', - 'type': 'object', - }, - 'version': { - 'const': 'v2', - 'type': 'string', + "description": "A set of inputs the component expects to be provided", + "type": "object" }, + "version": { + "const": "v2", + "type": "string" + } }, - 'required': [ - 'version', + "required": [ + "version" ], - 'type': 'object', - }, + "type": "object" + } ], - '$schema': 'https://json-schema.org/draft/2019-09/schema', - '$id': 'https://architect.io/.schemas/component.json', - 'type': 'object', - 'required': [ - 'version', + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://architect.io/.schemas/component.json", + "type": "object", + "required": [ + "version" ], - 'discriminator': { - 'propertyName': 'version', - }, -}; + "discriminator": { + "propertyName": "version" + } +} \ No newline at end of file diff --git a/src/components/component.schema.json b/src/components/component.schema.json index 79a349bb8..00de43bee 100644 --- a/src/components/component.schema.json +++ b/src/components/component.schema.json @@ -2729,6 +2729,184 @@ { "additionalProperties": false, "properties": { + "buckets": { + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "CSV reporting dumps" + ], + "type": "string" + }, + "directory": { + "description": "The directory containing the contents to upload to the bucket", + "examples": [ + "./reports" + ], + "type": "string" + }, + "image": { + "description": "The built image containing the contents to upload inside the workdir", + "examples": [ + "registry.architect.io/my-org/my-image:latest" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deploy": { + "additionalProperties": false, + "description": "Settings outlining a step that should be run when the component gets deployed", + "properties": { + "command": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Command to use when the container is booted up", + "examples": [ + [ + "npm", + "start" + ] + ] + }, + "cpu": { + "description": "The amount of CPU to allocate to each instance of the deployment", + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "" + ], + "description": "The executable to run every time the container is booted up" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables to pass to the service", + "examples": [ + { + "NODE_ENV": "production" + }, + { + "BACKEND_URL": "${{ ingresses.backend.url }}" + } + ], + "type": "object" + }, + "image": { + "description": "Docker image to use for the deployment", + "examples": [ + "${{ builds.frontend.image }}", + "my-registry.com/my-app:latest" + ], + "type": "string" + }, + "memory": { + "description": "The amount of memory to allocate to each instance of the deployment", + "type": "string" + }, + "platform": { + "description": "Set platform if server is multi-platform capable", + "examples": [ + "linux/amd64" + ], + "type": "string" + }, + "publish": { + "description": "The path to the directory containing the contents to upload to the bucket", + "examples": [ + "./dist" + ], + "type": "string" + }, + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "Path on the host machine to sync with the volume", + "examples": [ + "/Users/batman/app/src" + ], + "type": "string" + }, + "image": { + "description": "OCI image containing the contents to seed the volume with", + "type": "string" + }, + "mount_path": { + "description": "Path inside the container to mount the volume to", + "examples": [ + "/app/src" + ], + "type": "string" + } + }, + "required": [ + "mount_path" + ], + "type": "object" + }, + "description": "Volumes that should be created and attached to each replica", + "type": "object" + } + }, + "required": [ + "image", + "publish" + ], + "type": "object" + }, + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "A static website" + ], + "type": "string" + } + }, + "required": [ + "deploy" + ], + "type": "object" + } + ] + }, + "description": "Buckets that can be used to store and serve files", + "type": "object" + }, "builds": { "additionalProperties": { "additionalProperties": false, @@ -3695,38 +3873,63 @@ }, "ingresses": { "additionalProperties": { - "additionalProperties": false, - "properties": { - "headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Additional headers to include in responses", - "examples": [ - { - "Access-Control-Allow-Credentials": "true", - "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Additional headers to include in responses", + "examples": [ + { + "Access-Control-Allow-Credentials": "true", + "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" + } + ], + "type": "object" + }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + }, + "service": { + "description": "Service the ingress rule forwards traffic to", + "examples": [ + "backend" + ], + "type": "string" } + }, + "required": [ + "service" ], "type": "object" }, - "internal": { - "default": false, - "description": "Whether or not the ingress rule should be attached to an internal gateway", - "type": "boolean" - }, - "service": { - "description": "Service the ingress rule forwards traffic to", - "examples": [ - "backend" + { + "additionalProperties": false, + "properties": { + "bucket": { + "description": "The static bucket to serve content from", + "examples": [ + "my-bucket" + ], + "type": "string" + }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + } + }, + "required": [ + "bucket" ], - "type": "string" + "type": "object" } - }, - "required": [ - "service" - ], - "type": "object" + ] }, "description": "Claims for external (e.g. client) access to a service", "type": "object" diff --git a/src/components/component.ts b/src/components/component.ts index fe3a86abe..ce2a4f2eb 100644 --- a/src/components/component.ts +++ b/src/components/component.ts @@ -9,12 +9,6 @@ export type GraphContext = { }; }; -export type VolumeBuildFn = (options: { - deployment_name: string; - volume_name: string; - host_path: string; -}) => Promise; - export type DockerBuildFn = (options: { name: string; context: string; @@ -28,12 +22,6 @@ export type DockerTagFn = ( targetName: string, ) => Promise; -export type VolumeTagFn = ( - digest: string, - deploymentName: string, - volumeName: string, -) => Promise; - export type DockerPushFn = (image: string) => Promise; export type ComponentDependencies = Array<{ @@ -46,9 +34,9 @@ export abstract class Component { public abstract getGraph(context: GraphContext): AppGraph; - public abstract build(buildFn: DockerBuildFn, volumeFn: VolumeBuildFn): Promise; + public abstract build(buildFn: DockerBuildFn): Promise; - public abstract tag(tagFn: DockerTagFn, volumeTagFn: VolumeTagFn): Promise; + public abstract tag(tagFn: DockerTagFn): Promise; public abstract push(pushFn: DockerPushFn): Promise; } diff --git a/src/components/schema.ts b/src/components/schema.ts index 44c54456a..a54e99350 100644 --- a/src/components/schema.ts +++ b/src/components/schema.ts @@ -7,7 +7,8 @@ export type ComponentSchema = } & component_v1) | ({ version: 'v2'; - } & component_v2); + } & component_v2) +; export const buildComponent = (data: ComponentSchema) => { switch (data.version) { diff --git a/src/components/v1/__tests__/index.test.ts b/src/components/v1/__tests__/index.test.ts index 903c0e688..003407187 100644 --- a/src/components/v1/__tests__/index.test.ts +++ b/src/components/v1/__tests__/index.test.ts @@ -389,7 +389,6 @@ describe('Component Schema: v1', () => { port: `\${{ ${interface_node.getId()}.port }}`, protocol: `\${{ ${interface_node.getId()}.protocol }}`, }, - port: `\${{ ${interface_node.getId()}.port }}`, internal: false, path: '/', }, @@ -454,7 +453,6 @@ describe('Component Schema: v1', () => { port: `\${{ ${service_node.getId()}.port }}`, protocol: `\${{ ${service_node.getId()}.protocol }}`, }, - port: `\${{ ${service_node.getId()}.port }}`, internal: false, path: '/', }, diff --git a/src/components/v1/index.ts b/src/components/v1/index.ts index b69751221..56726bf24 100644 --- a/src/components/v1/index.ts +++ b/src/components/v1/index.ts @@ -1,3 +1,4 @@ +import * as path from 'std/path/mod.ts'; import { ResourceInputs } from '../../@resources/index.ts'; import { GraphEdge } from '../../graphs/edge.ts'; import { AppGraph, AppGraphNode } from '../../graphs/index.ts'; @@ -8,8 +9,6 @@ import { DockerPushFn, DockerTagFn, GraphContext, - VolumeBuildFn, - VolumeTagFn, } from '../component.ts'; import { ComponentSchema } from '../schema.ts'; import { DatabaseSchemaV1 } from './database-schema-v1.ts'; @@ -210,7 +209,6 @@ export default class ComponentV1 extends Component { type: 'volume', component: context.component.name, inputs: { - name: `${context.component.name}/${service_name}-${volume_name}`, ...(volume_config.host_path ? { hostPath: volume_config.host_path } : {}), }, }); @@ -298,7 +296,6 @@ export default class ComponentV1 extends Component { type: 'ingress', component: context.component.name, inputs: { - port: `\${{ ${service_node.getId()}.port }}`, ...(interface_config.ingress.subdomain ? { subdomain: interface_config.ingress.subdomain } : {}), ...(interface_config.ingress.path ? { path: interface_config.ingress.path } : {}), ...(interface_config.ingress.internal !== undefined @@ -327,6 +324,13 @@ export default class ComponentV1 extends Component { }), ); + if (!('service' in ingress_node.inputs)) { + // This should never be hit. Typescript can't seem to infer the conditional type from the above inputs + throw new Error( + `Ingress expects to target a service, but does not (${ingress_node.getId()})`, + ); + } + deployment_node.inputs.ingresses = deployment_node.inputs.ingresses || []; deployment_node.inputs.ingresses?.push({ service: ingress_node.inputs.service.name, @@ -448,7 +452,6 @@ export default class ComponentV1 extends Component { type: 'volume', component: context.component.name, inputs: { - name: `${context.component.name}/${task_name}-${volume_name}`, ...(volume_config.host_path ? { hostPath: volume_config.host_path } : {}), }, }); @@ -547,7 +550,6 @@ export default class ComponentV1 extends Component { port: `\${{ ${interface_node.getId()}.port }}`, protocol: `\${{ ${interface_node.getId()}.protocol }}`, }, - port: `\${{ ${interface_node.getId()}.port }}`, ...(interface_config.ingress.subdomain ? { subdomain: interface_config.ingress.subdomain } : {}), ...(interface_config.ingress.path ? { path: interface_config.ingress.path } : {}), ...(interface_config.ingress.internal !== undefined ? { internal: interface_config.ingress.internal } : {}), @@ -666,11 +668,11 @@ export default class ComponentV1 extends Component { return res; } - public async build(buildFn: DockerBuildFn, volumeBuildFn: VolumeBuildFn): Promise { + public async build(buildFn: DockerBuildFn): Promise { for (const [svcName, svcConfig] of Object.entries(this.services || {})) { if ('build' in svcConfig) { const digest = await buildFn({ - name: svcName, + name: `services-${svcName}`, context: svcConfig.build.context, dockerfile: svcConfig.build.dockerfile, args: svcConfig.build.args, @@ -684,10 +686,21 @@ export default class ComponentV1 extends Component { for (const [volumeName, volumeConfig] of Object.entries(svcConfig.volumes || {})) { if (volumeConfig.host_path) { - volumeConfig.image = await volumeBuildFn({ - host_path: volumeConfig.host_path, - volume_name: volumeName, - deployment_name: svcName, + const tmpDir = Deno.makeTempDirSync(); + const dockerfile = path.join(tmpDir, 'Dockerfile'); + Deno.writeTextFileSync( + dockerfile, + ` + FROM alpine:latest + COPY . . + CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] + `, + ); + + volumeConfig.image = await buildFn({ + context: volumeConfig.host_path, + dockerfile, + name: 'services-' + svcName + '-volumes-' + volumeName, }); } } @@ -696,7 +709,7 @@ export default class ComponentV1 extends Component { for (const [taskName, taskConfig] of Object.entries(this.tasks || {})) { if ('build' in taskConfig) { const digest = await buildFn({ - name: taskName, + name: `tasks-${taskName}`, context: taskConfig.build.context, dockerfile: taskConfig.build.dockerfile, args: taskConfig.build.args, @@ -710,10 +723,21 @@ export default class ComponentV1 extends Component { for (const [volumeName, volumeConfig] of Object.entries(taskConfig.volumes || {})) { if (volumeConfig.host_path) { - volumeConfig.image = await volumeBuildFn({ - host_path: volumeConfig.host_path, - volume_name: volumeName, - deployment_name: taskName, + const tmpDir = Deno.makeTempDirSync(); + const dockerfile = path.join(tmpDir, 'Dockerfile'); + Deno.writeTextFileSync( + dockerfile, + ` + FROM alpine:latest + COPY . . + CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] + `, + ); + + volumeConfig.image = await buildFn({ + context: volumeConfig.host_path, + dockerfile, + name: `tasks-${taskName}-volumes-${volumeName}`, }); } } @@ -722,29 +746,35 @@ export default class ComponentV1 extends Component { return this; } - public async tag(dockerTagFn: DockerTagFn, volumeTagFn: VolumeTagFn): Promise { + public async tag(dockerTagFn: DockerTagFn): Promise { for (const [svcName, svcConfig] of Object.entries(this.services || {})) { if ('image' in svcConfig) { - svcConfig.image = await dockerTagFn(svcConfig.image, svcName); + svcConfig.image = await dockerTagFn(svcConfig.image, `services-${svcName}`); this.services![svcName] = svcConfig; } for (const [volumeName, volumeConfig] of Object.entries(svcConfig.volumes || {})) { if (volumeConfig.image) { - svcConfig.volumes![volumeName].image = await volumeTagFn(volumeConfig.image, svcName, volumeName); + svcConfig.volumes![volumeName].image = await dockerTagFn( + volumeConfig.image, + `services-${svcName}-volumes-${volumeName}`, + ); } } } for (const [taskName, taskConfig] of Object.entries(this.tasks || {})) { if ('image' in taskConfig) { - taskConfig.image = await dockerTagFn(taskConfig.image, taskName); + taskConfig.image = await dockerTagFn(taskConfig.image, `tasks-${taskName}`); this.tasks![taskName] = taskConfig; } for (const [volumeName, volumeConfig] of Object.entries(taskConfig.volumes || {})) { if (volumeConfig.image) { - taskConfig.volumes![volumeName].image = await volumeTagFn(volumeConfig.image, taskName, volumeName); + taskConfig.volumes![volumeName].image = await dockerTagFn( + volumeConfig.image, + `tasks-${taskName}-volumes-${volumeName}`, + ); } } } diff --git a/src/components/v2/__tests__/index.test.ts b/src/components/v2/__tests__/index.test.ts index bd0842d3b..ada6eb3bb 100644 --- a/src/components/v2/__tests__/index.test.ts +++ b/src/components/v2/__tests__/index.test.ts @@ -217,7 +217,6 @@ describe('Component Schema: v2', () => { type: 'volume', component: 'component', inputs: { - name: 'component/main-src', hostPath: '/fake/source/src', }, }); @@ -363,7 +362,6 @@ describe('Component Schema: v2', () => { type: 'ingress', component: 'component', inputs: { - port: `\${{ ${svc_node.getId()}.port }}`, username: `\${{ ${svc_node.getId()}.username }}`, password: `\${{ ${svc_node.getId()}.password }}`, protocol: `\${{ ${svc_node.getId()}.protocol }}`, diff --git a/src/components/v2/bucket.ts b/src/components/v2/bucket.ts new file mode 100644 index 000000000..c5d5f156f --- /dev/null +++ b/src/components/v2/bucket.ts @@ -0,0 +1,41 @@ +import { ContainerSchemaV2 } from './container.ts'; + +export type BucketSchemaV2 = { + /** + * A human-readable description of the bucket + * + * @example "CSV reporting dumps" + */ + description?: string; + + /** + * The directory containing the contents to upload to the bucket + * @example "./reports" + */ + directory?: string; + + /** + * The built image containing the contents to upload inside the workdir + * @example "registry.architect.io/my-org/my-image:latest" + */ + image?: string; +} | { + /** + * A human-readable description of the bucket + * + * @example "A static website" + */ + description?: string; + + /** + * Settings outlining a step that should be run when the component gets deployed + */ + deploy: ContainerSchemaV2 & { + /** + * The path to the directory containing the contents to upload to the bucket + * + * @example "./dist" + */ + publish: string; + }; +}; diff --git a/src/components/v2/container.ts b/src/components/v2/container.ts new file mode 100644 index 000000000..a2b18d48d --- /dev/null +++ b/src/components/v2/container.ts @@ -0,0 +1,75 @@ +export type ContainerSchemaV2 = { + /** + * Docker image to use for the deployment + * + * @example "${{ builds.frontend.image }}" + * @example "my-registry.com/my-app:latest" + */ + image: string; + + /** + * Set platform if server is multi-platform capable + * + * @example "linux/amd64" + */ + platform?: string; + + /** + * Command to use when the container is booted up + * + * @example ["npm", "start"] + */ + command?: string | string[]; + + /** + * The executable to run every time the container is booted up + * + * @default [""] + */ + entrypoint?: string | string[]; + + /** + * Environment variables to pass to the service + * + * @example { "NODE_ENV": "production" } + * @example + * { + * "BACKEND_URL": "${{ ingresses.backend.url }}", + * } + */ + environment?: Record; + + /** + * The amount of CPU to allocate to each instance of the deployment + */ + cpu?: number | string; + + /** + * The amount of memory to allocate to each instance of the deployment + */ + memory?: string; + + /** + * Volumes that should be created and attached to each replica + */ + volumes?: Record; +}; diff --git a/src/components/v2/deployment.ts b/src/components/v2/deployment.ts index b3b477ecd..dd3f34b62 100644 --- a/src/components/v2/deployment.ts +++ b/src/components/v2/deployment.ts @@ -1,6 +1,7 @@ +import { ContainerSchemaV2 } from './container.ts'; import { ProbeSchema } from './probe.ts'; -export type DeploymentSchemaV2 = { +export type DeploymentSchemaV2 = ContainerSchemaV2 & { /** * Human readable description of the deployment * @@ -8,56 +9,6 @@ export type DeploymentSchemaV2 = { */ description?: string; - /** - * Docker image to use for the deployment - * - * @example "${{ builds.frontend.image }}" - * @example "my-registry.com/my-app:latest" - */ - image: string; - - /** - * Set platform if server is multi-platform capable - * - * @example "linux/amd64" - */ - platform?: string; - - /** - * Command to use when the container is booted up - * - * @example ["npm", "start"] - */ - command?: string | string[]; - - /** - * The executable to run every time the container is booted up - * - * @default [""] - */ - entrypoint?: string | string[]; - - /** - * Environment variables to pass to the service - * - * @example { "NODE_ENV": "production" } - * @example - * { - * "BACKEND_URL": "${{ ingresses.backend.url }}", - * } - */ - environment?: Record; - - /** - * The amount of CPU to allocate to each instance of the deployment - */ - cpu?: number | string; - - /** - * The amount of memory to allocate to each instance of the deployment - */ - memory?: string; - /** * The labels to apply to the deployment */ @@ -93,30 +44,6 @@ export type DeploymentSchemaV2 = { */ memory?: string; }; - - /** - * Volumes that should be created and attached to each replica - */ - volumes?: Record; }; export type DebuggableDeploymentSchemaV2 = DeploymentSchemaV2 & { diff --git a/src/components/v2/index.ts b/src/components/v2/index.ts index 314ff31c9..6a4815a13 100644 --- a/src/components/v2/index.ts +++ b/src/components/v2/index.ts @@ -9,10 +9,9 @@ import { DockerPushFn, DockerTagFn, GraphContext, - VolumeBuildFn, - VolumeTagFn, } from '../component.ts'; import { ComponentSchema } from '../schema.ts'; +import { BucketSchemaV2 } from './bucket.ts'; import { DebuggableBuildSchemaV2 } from './build.ts'; import { DependencySchemaV2 } from './dependency.ts'; import { DebuggableDeploymentSchemaV2 } from './deployment.ts'; @@ -189,6 +188,11 @@ export default class ComponentV2 extends Component { DebuggableDeploymentSchemaV2 >; + /** + * Buckets that can be used to store and serve files + */ + buckets?: Record; + /** * Services that can receive network traffic */ @@ -268,6 +272,20 @@ export default class ComponentV2 extends Component { * } */ headers?: Record; + } | { + /** + * The static bucket to serve content from + * + * @example "my-bucket" + */ + bucket: string; + + /** + * Whether or not the ingress rule should be attached to an internal gateway + * + * @default false + */ + internal?: boolean; } >; @@ -444,7 +462,6 @@ export default class ComponentV2 extends Component { type: 'volume', component: context.component.name, inputs: { - name: `${context.component.name}/${deployment_key}-${volumeKey}`, hostPath: host_path, }, }); @@ -584,6 +601,176 @@ export default class ComponentV2 extends Component { return graph; } + private addBucketsToGraph( + graph: AppGraph, + context: GraphContext, + ): AppGraph { + for (const [bucket_key, bucket_config] of Object.entries(this.buckets || {})) { + const bucket_node = new AppGraphNode({ + name: bucket_key, + type: 'bucket', + component: context.component.name, + inputs: {}, + }); + graph.insertNodes(bucket_node); + + // Check if we intend to seed the bucket + if ('deploy' in bucket_config || bucket_config.image || bucket_config.directory) { + const volume_node = new AppGraphNode({ + name: `${bucket_key}-bucket-contents`, + type: 'volume', + component: context.component.name, + inputs: {}, + }); + graph.insertNodes(volume_node); + + // TODO: Task that moves contents from volume to bucket + const data_migration_node = new AppGraphNode({ + name: `${bucket_key}-bucket-data-migration`, + type: 'task', + component: context.component.name, + inputs: { + image: 'architectio/s3cmd:main', + command: [ + 'sync', + '/data', + 's3://$BUCKET_ID', + ], + volume_mounts: [{ + volume: `\${{ ${volume_node.getId()}.id }}`, + mount_path: '/data', + readonly: true, + }], + environment: { + BUCKET_ID: `\${{ ${bucket_node.getId()}.id }}`, + ACCESS_KEY_ID: `\${{ ${bucket_node.getId()}.access_key_id }}`, + SECRET_ACCESS_KEY: `\${{ ${bucket_node.getId()}.secret_access_key }}`, + }, + }, + }); + graph.insertNodes(data_migration_node); + + // Handle bucket seeding + if ('deploy' in bucket_config) { + const deploy_hook_node = new AppGraphNode({ + name: `${bucket_key}-bucket-before-hook`, + type: 'task', + component: context.component.name, + inputs: { + image: bucket_config.deploy.image, + ...(bucket_config.deploy.platform ? { platform: bucket_config.deploy.platform } : {}), + ...(bucket_config.deploy.environment ? { environment: bucket_config.deploy.environment } : {}), + ...(bucket_config.deploy.command ? { command: bucket_config.deploy.command } : {}), + ...(bucket_config.deploy.entrypoint ? { entrypoint: bucket_config.deploy.entrypoint } : {}), + ...(bucket_config.deploy.cpu ? { cpu: Number(bucket_config.deploy.cpu) } : {}), + ...(bucket_config.deploy.memory ? { memory: bucket_config.deploy.memory } : {}), + volume_mounts: [{ + volume: `\${{ ${volume_node.getId()}.id }}`, + mount_path: bucket_config.deploy.publish, + readonly: false, + }], + }, + }); + graph.insertNodes(deploy_hook_node); + graph.insertEdges( + new GraphEdge({ + from: deploy_hook_node.getId(), + to: volume_node.getId(), + }), + // Ensures the data migration doesn't get run until the deploy hook is finished + new GraphEdge({ + from: data_migration_node.getId(), + to: deploy_hook_node.getId(), + }), + ); + } else if (bucket_config.image || bucket_config.directory) { + let build_contents_node: AppGraphNode<'dockerBuild'> | undefined; + + // Build the directory into an image containing its contents + if (bucket_config.directory && !bucket_config.image) { + const tmpDir = Deno.makeTempDirSync(); + const dockerfile = path.join(tmpDir, 'Dockerfile'); + Deno.writeTextFileSync( + dockerfile, + ` + FROM alpine:latest + COPY . . + CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] + `, + ); + + build_contents_node = new AppGraphNode({ + name: `${bucket_key}-bucket-before-hook`, + type: 'dockerBuild', + component: context.component.name, + inputs: { + context: bucket_config.directory, + dockerfile: dockerfile, + component_source: context.component.source, + }, + }); + graph.insertNodes(build_contents_node); + graph.insertEdges( + new GraphEdge({ + from: build_contents_node.getId(), + to: volume_node.getId(), + }), + // Ensures the data migration doesn't get run until the deploy hook is finished + new GraphEdge({ + from: data_migration_node.getId(), + to: build_contents_node.getId(), + }), + ); + } + + // If there are contents for the bucket, queue up a task to move said contents to a volume + if (bucket_config.image || build_contents_node) { + const move_data_to_volume_node = new AppGraphNode({ + name: `${bucket_key}-bucket-before-hook`, + type: 'task', + component: context.component.name, + inputs: { + image: (build_contents_node ? `\${{ ${build_contents_node.getId()}.image }}` : bucket_config.image)!, + command: ['sh', '-c', 'cp -r ./* $TARGET_DIR'], + volume_mounts: [{ + volume: `\${{ ${volume_node.getId()}.id }}`, + mount_path: '/data', + readonly: false, + }], + environment: { + TARGET_DIR: '/data', + }, + }, + }); + graph.insertNodes(move_data_to_volume_node); + graph.insertEdges( + new GraphEdge({ + from: move_data_to_volume_node.getId(), + to: volume_node.getId(), + }), + // Ensures the data migration doesn't get run until the deploy hook is finished + new GraphEdge({ + from: data_migration_node.getId(), + to: move_data_to_volume_node.getId(), + }), + ); + + if (build_contents_node) { + graph.insertEdges( + new GraphEdge({ + from: move_data_to_volume_node.getId(), + to: build_contents_node.getId(), + }), + ); + } + } + } + } + } + + return graph; + } + private addIngressesToGraph( graph: AppGraph, context: GraphContext, @@ -593,84 +780,127 @@ export default class ComponentV2 extends Component { this.ingresses || {}, ) ) { - const service_node = graph.nodes.find( - (n) => n.name === ingress_config.service && n.type === 'service', - ) as AppGraphNode<'service'> | undefined; - if (!service_node) { - throw new Error(`The service, ${ingress_config.service}, does not exist`); - } - - graph.insertNodes(service_node); + if ('service' in ingress_config) { + const service_node = graph.nodes.find( + (n) => n.name === ingress_config.service && n.type === 'service', + ) as AppGraphNode<'service'> | undefined; + if (!service_node) { + throw new Error(`The service, ${ingress_config.service}, does not exist`); + } - const ingress_node = new AppGraphNode({ - name: ingress_key, - type: 'ingress', - component: context.component.name, - inputs: { - port: `\${{ ${service_node.getId()}.port }}`, - service: { - name: `\${{ ${service_node.getId()}.name }}`, - host: `\${{ ${service_node.getId()}.host }}`, - port: `\${{ ${service_node.getId()}.port }}`, + const ingress_node = new AppGraphNode({ + name: ingress_key, + type: 'ingress', + component: context.component.name, + inputs: { + service: { + name: `\${{ ${service_node.getId()}.name }}`, + host: `\${{ ${service_node.getId()}.host }}`, + port: `\${{ ${service_node.getId()}.port }}`, + protocol: `\${{ ${service_node.getId()}.protocol }}`, + }, protocol: `\${{ ${service_node.getId()}.protocol }}`, + username: `\${{ ${service_node.getId()}.username }}`, + password: `\${{ ${service_node.getId()}.password }}`, + internal: ingress_config.internal ?? false, + path: '/', + ...(ingress_config.headers ? { headers: ingress_config.headers } : {}), }, - protocol: `\${{ ${service_node.getId()}.protocol }}`, - username: `\${{ ${service_node.getId()}.username }}`, - password: `\${{ ${service_node.getId()}.password }}`, - internal: false, - path: '/', - ...(ingress_config.internal !== undefined ? { internal: ingress_config.internal } : {}), - ...(ingress_config.headers ? { headers: ingress_config.headers } : {}), - }, - }); + }); - ingress_node.inputs = parseExpressionRefs( - graph, - this.normalizedDependencies, - context, - ingress_node.getId(), - ingress_node.inputs, - ); - graph.insertNodes(ingress_node); - graph.insertEdges( - new GraphEdge({ - from: ingress_node.getId(), - to: service_node.getId(), - }), - ); + ingress_node.inputs = parseExpressionRefs( + graph, + this.normalizedDependencies, + context, + ingress_node.getId(), + ingress_node.inputs, + ); + graph.insertNodes(ingress_node); + graph.insertEdges( + new GraphEdge({ + from: ingress_node.getId(), + to: service_node.getId(), + }), + ); + + if ('deployment' in service_node.inputs) { + const deployment_name = service_node.inputs.deployment; + const deployment_node = graph.nodes.find((n) => + n.type === 'deployment' && (n.inputs as AppGraphNode<'deployment'>).name === deployment_name + ) as + | AppGraphNode<'deployment'> + | undefined; + if (!deployment_node) { + throw new Error( + `No deployment named ${service_node.inputs.deployment}. Referenced by the service, ${service_node.name}`, + ); + } + + if (!('service' in ingress_node.inputs)) { + // This should never be hit. Typescript can't seem to infer the conditional type from the above inputs + throw new Error( + `Ingress expects to target a service, but does not (${ingress_node.getId()})`, + ); + } + + // Update deployment node with service references + deployment_node.inputs.ingresses = deployment_node.inputs.ingresses || []; + deployment_node.inputs.ingresses.push({ + service: ingress_node.inputs.service.name, + host: `\${{ ${ingress_node.getId()}.host }}`, + protocol: `\${{ ${ingress_node.getId()}.protocol }}`, + port: `\${{ ${ingress_node.getId()}.port }}`, + path: `\${{ ${ingress_node.getId()}.path }}`, + subdomain: `\${{ ${ingress_node.getId()}.subdomain }}`, + dns_zone: `\${{ ${ingress_node.getId()}.dns_zone }}`, + }); + graph.insertNodes(deployment_node); - if ('deployment' in service_node.inputs) { - const deployment_name = service_node.inputs.deployment; - const deployment_node = graph.nodes.find((n) => - n.type === 'deployment' && (n.inputs as AppGraphNode<'deployment'>).name === deployment_name - ) as - | AppGraphNode<'deployment'> - | undefined; - if (!deployment_node) { - throw new Error( - `No deployment named ${service_node.inputs.deployment}. Referenced by the service, ${service_node.name}`, + graph.insertEdges( + new GraphEdge({ + from: deployment_node.getId(), + to: ingress_node.getId(), + }), ); } + } else { + const bucket_node = graph.nodes.find( + (n) => n.name === ingress_config.bucket && n.type === 'bucket', + ) as AppGraphNode<'bucket'> | undefined; + if (!bucket_node) { + throw new Error(`The bucket, ${ingress_config.bucket}, does not exist`); + } - // Update deployment node with service references - deployment_node.inputs.ingresses = deployment_node.inputs.ingresses || []; - deployment_node.inputs.ingresses!.push({ - service: ingress_node.inputs.service.name, - host: `\${{ ${ingress_node.getId()}.host }}`, - protocol: `\${{ ${ingress_node.getId()}.protocol }}`, - port: `\${{ ${ingress_node.getId()}.port }}`, - path: `\${{ ${ingress_node.getId()}.path }}`, - subdomain: `\${{ ${ingress_node.getId()}.subdomain }}`, - dns_zone: `\${{ ${ingress_node.getId()}.dns_zone }}`, + const ingress_node = new AppGraphNode({ + name: ingress_key, + type: 'ingress', + component: context.component.name, + inputs: { + bucket: { + id: `\${{ ${bucket_node.getId()}.id }}`, + }, + protocol: 'http', + internal: ingress_config.internal ?? false, + path: '/', + }, }); - graph.insertNodes(deployment_node); + ingress_node.inputs = parseExpressionRefs( + graph, + this.normalizedDependencies, + context, + ingress_node.getId(), + ingress_node.inputs, + ); + graph.insertNodes(ingress_node); graph.insertEdges( new GraphEdge({ - from: deployment_node.getId(), - to: ingress_node.getId(), + from: ingress_node.getId(), + to: bucket_node.getId(), }), ); + + bucket_node.inputs; } } @@ -708,6 +938,7 @@ export default class ComponentV2 extends Component { let graph = new AppGraph(); graph = this.addVariablestoGraph(graph, context); graph = this.addBuildsToGraph(graph, context); + graph = this.addBucketsToGraph(graph, context); graph = this.addDatabasesToGraph(graph, context); graph = this.addDeploymentsToGraph(graph, context); graph = this.addServicesToGraph(graph, context); @@ -715,7 +946,7 @@ export default class ComponentV2 extends Component { return graph; } - public async build(buildFn: DockerBuildFn, volumeBuildFn: VolumeBuildFn): Promise { + public async build(buildFn: DockerBuildFn): Promise { for (const [buildName, buildConfig] of Object.entries(this.builds || {})) { const digest = await buildFn({ name: buildName, @@ -731,10 +962,21 @@ export default class ComponentV2 extends Component { for (const [deploymentName, deploymentConfig] of Object.entries(this.deployments || {})) { for (const [volumeName, volumeConfig] of Object.entries(deploymentConfig.volumes || {})) { if (volumeConfig.host_path) { - volumeConfig.image = await volumeBuildFn({ - host_path: volumeConfig.host_path, - volume_name: volumeName, - deployment_name: deploymentName, + const tmpDir = Deno.makeTempDirSync(); + const dockerfile = path.join(tmpDir, 'Dockerfile'); + Deno.writeTextFileSync( + dockerfile, + ` + FROM alpine:latest + COPY . . + CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] + `, + ); + + this.deployments![deploymentName].volumes![volumeName].image = await buildFn({ + context: volumeConfig.host_path, + dockerfile, + name: 'deployments-' + deploymentName + '-volumes-' + volumeName, }); } } @@ -742,10 +984,31 @@ export default class ComponentV2 extends Component { delete this.deployments?.[deploymentName].debug; } + for (const [bucket_key, bucket_config] of Object.entries(this.buckets || {})) { + if ('directory' in bucket_config && bucket_config.directory) { + const tmpDir = Deno.makeTempDirSync(); + const dockerfile = path.join(tmpDir, 'Dockerfile'); + Deno.writeTextFileSync( + dockerfile, + ` + FROM alpine:latest + COPY . . + CMD ["sh", "-c", "cp -r ./* $TARGET_DIR"] + `, + ); + + bucket_config.image = await buildFn({ + context: bucket_config.directory, + dockerfile, + name: 'buckets-' + bucket_key, + }); + } + } + return this; } - public async tag(tagFn: DockerTagFn, volumeTagFn: VolumeTagFn): Promise { + public async tag(tagFn: DockerTagFn): Promise { for (const [buildName, buildConfig] of Object.entries(this.builds || {})) { if (buildConfig.image) { const newTag = await tagFn(buildConfig.image, buildName); @@ -756,15 +1019,20 @@ export default class ComponentV2 extends Component { for (const [deploymentName, deploymentConfig] of Object.entries(this.deployments || {})) { for (const [volumeName, volumeConfig] of Object.entries(deploymentConfig.volumes || {})) { if (volumeConfig.image) { - deploymentConfig.volumes![volumeName].image = await volumeTagFn( + deploymentConfig.volumes![volumeName].image = await tagFn( volumeConfig.image, - deploymentName, - volumeName, + `deployments-${deploymentName}-volumes-${volumeName}`, ); } } } + for (const [bucket_key, bucket_config] of Object.entries(this.buckets || {})) { + if ('image' in bucket_config && bucket_config.image) { + bucket_config.image = await tagFn(bucket_config.image, `buckets-${bucket_key}`); + } + } + return this; } @@ -783,6 +1051,12 @@ export default class ComponentV2 extends Component { } } + for (const bucketConfig of Object.values(this.buckets || {})) { + if ('image' in bucketConfig && bucketConfig.image) { + await pushFn(bucketConfig.image); + } + } + return this; } } diff --git a/src/components/v2/schema.json b/src/components/v2/schema.json index 48158b4b9..433805ab0 100644 --- a/src/components/v2/schema.json +++ b/src/components/v2/schema.json @@ -5,6 +5,184 @@ "ComponentV2": { "additionalProperties": false, "properties": { + "buckets": { + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "CSV reporting dumps" + ], + "type": "string" + }, + "directory": { + "description": "The directory containing the contents to upload to the bucket", + "examples": [ + "./reports" + ], + "type": "string" + }, + "image": { + "description": "The built image containing the contents to upload inside the workdir", + "examples": [ + "registry.architect.io/my-org/my-image:latest" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deploy": { + "additionalProperties": false, + "description": "Settings outlining a step that should be run when the component gets deployed", + "properties": { + "command": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Command to use when the container is booted up", + "examples": [ + [ + "npm", + "start" + ] + ] + }, + "cpu": { + "description": "The amount of CPU to allocate to each instance of the deployment", + "type": [ + "number", + "string" + ] + }, + "entrypoint": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "" + ], + "description": "The executable to run every time the container is booted up" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables to pass to the service", + "examples": [ + { + "NODE_ENV": "production" + }, + { + "BACKEND_URL": "${{ ingresses.backend.url }}" + } + ], + "type": "object" + }, + "image": { + "description": "Docker image to use for the deployment", + "examples": [ + "${{ builds.frontend.image }}", + "my-registry.com/my-app:latest" + ], + "type": "string" + }, + "memory": { + "description": "The amount of memory to allocate to each instance of the deployment", + "type": "string" + }, + "platform": { + "description": "Set platform if server is multi-platform capable", + "examples": [ + "linux/amd64" + ], + "type": "string" + }, + "publish": { + "description": "The path to the directory containing the contents to upload to the bucket", + "examples": [ + "./dist" + ], + "type": "string" + }, + "volumes": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "Path on the host machine to sync with the volume", + "examples": [ + "/Users/batman/app/src" + ], + "type": "string" + }, + "image": { + "description": "OCI image containing the contents to seed the volume with", + "type": "string" + }, + "mount_path": { + "description": "Path inside the container to mount the volume to", + "examples": [ + "/app/src" + ], + "type": "string" + } + }, + "required": [ + "mount_path" + ], + "type": "object" + }, + "description": "Volumes that should be created and attached to each replica", + "type": "object" + } + }, + "required": [ + "image", + "publish" + ], + "type": "object" + }, + "description": { + "description": "A human-readable description of the bucket", + "examples": [ + "A static website" + ], + "type": "string" + } + }, + "required": [ + "deploy" + ], + "type": "object" + } + ] + }, + "description": "Buckets that can be used to store and serve files", + "type": "object" + }, "builds": { "additionalProperties": { "additionalProperties": false, @@ -971,38 +1149,63 @@ }, "ingresses": { "additionalProperties": { - "additionalProperties": false, - "properties": { - "headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Additional headers to include in responses", - "examples": [ - { - "Access-Control-Allow-Credentials": "true", - "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Additional headers to include in responses", + "examples": [ + { + "Access-Control-Allow-Credentials": "true", + "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" + } + ], + "type": "object" + }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + }, + "service": { + "description": "Service the ingress rule forwards traffic to", + "examples": [ + "backend" + ], + "type": "string" } + }, + "required": [ + "service" ], "type": "object" }, - "internal": { - "default": false, - "description": "Whether or not the ingress rule should be attached to an internal gateway", - "type": "boolean" - }, - "service": { - "description": "Service the ingress rule forwards traffic to", - "examples": [ - "backend" + { + "additionalProperties": false, + "properties": { + "bucket": { + "description": "The static bucket to serve content from", + "examples": [ + "my-bucket" + ], + "type": "string" + }, + "internal": { + "default": false, + "description": "Whether or not the ingress rule should be attached to an internal gateway", + "type": "boolean" + } + }, + "required": [ + "bucket" ], - "type": "string" + "type": "object" } - }, - "required": [ - "service" - ], - "type": "object" + ] }, "description": "Claims for external (e.g. client) access to a service", "type": "object" diff --git a/src/datacenters/datacenter-schema.ts b/src/datacenters/datacenter-schema.ts index 930a1b124..ad53c6379 100644 --- a/src/datacenters/datacenter-schema.ts +++ b/src/datacenters/datacenter-schema.ts @@ -1,1877 +1,2172 @@ export default { - '$ref': '#/definitions/DatacenterSchema', - '$schema': 'http://json-schema.org/draft-07/schema#', - 'definitions': { - 'DatacenterSchema': { - 'additionalProperties': false, - 'properties': { - 'environment': { - 'description': - 'Rules dictating what resources should be created in each environment hosted by the datacenter', - 'items': { - 'additionalProperties': false, - 'properties': { - 'cronjob': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "$ref": "#/definitions/DatacenterSchema", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "DatacenterSchema": { + "additionalProperties": false, + "properties": { + "environment": { + "description": "Rules dictating what resources should be created in each environment hosted by the datacenter", + "items": { + "additionalProperties": false, + "properties": { + "bucket": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': {}, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "properties": { + "access_key_id": { + "description": "Access key ID used to authenticate with the bucket", + "type": "string" }, + "endpoint": { + "description": "Endpoint that hosts the bucket", + "examples": [ + "https://nyc3.digitaloceanspaces.com", + "https://bucket.s3.region.amazonaws.com" + ], + "type": "string" + }, + "id": { + "description": "Unique ID of the bucket that was created", + "examples": [ + "abc123" + ], + "type": "string" + }, + "region": { + "description": "Region the bucket was created in", + "type": "string" + }, + "secret_access_key": { + "description": "Secret access key used to authenticate with the bucket", + "type": "string" + } + }, + "required": [ + "id", + "endpoint", + "region", + "access_key_id", + "secret_access_key" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'database': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "cronjob": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } }, - ], + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'examples': [ - 'opentofu', + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": {}, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "database": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } ], - 'type': 'string', + "type": "object" }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'certificate': { - 'description': 'SSL certificate used to authenticate with the database', - 'type': 'string', + "properties": { + "certificate": { + "description": "SSL certificate used to authenticate with the database", + "type": "string" }, - 'database': { - 'description': 'Name of the new database schema', - 'examples': [ - 'my-schema', + "database": { + "description": "Name of the new database schema", + "examples": [ + "my-schema" ], - 'type': 'string', + "type": "string" }, - 'host': { - 'description': 'Host address of the underlying database', - 'examples': [ - 'my-database.example.com', + "host": { + "description": "Host address of the underlying database", + "examples": [ + "my-database.example.com" ], - 'type': 'string', + "type": "string" }, - 'password': { - 'description': 'Passowrd used to authenticate with the schema', - 'examples': [ - 'pass', + "password": { + "description": "Passowrd used to authenticate with the schema", + "examples": [ + "pass" ], - 'type': 'string', + "type": "string" }, - 'port': { - 'description': 'Port the underlying database listens on', - 'examples': [ - 5432, - ], - 'type': [ - 'string', - 'number', + "port": { + "description": "Port the underlying database listens on", + "examples": [ + 5432 ], + "type": [ + "string", + "number" + ] }, - 'protocol': { - 'description': 'Protocol of the underlying database', - 'examples': [ - 'postgresql', + "protocol": { + "description": "Protocol of the underlying database", + "examples": [ + "postgresql" ], - 'type': 'string', + "type": "string" }, - 'url': { - 'description': 'Full connection string for the database', - 'examples': [ - 'postgresql://user:pass@my-database.example.com:5432/my-schema', + "url": { + "description": "Full connection string for the database", + "examples": [ + "postgresql://user:pass@my-database.example.com:5432/my-schema" ], - 'type': 'string', + "type": "string" }, - 'username': { - 'description': 'Username used to authenticate with the schema', - 'examples': [ - 'user', + "username": { + "description": "Username used to authenticate with the schema", + "examples": [ + "user" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'protocol', - 'host', - 'port', - 'database', - 'url', - 'username', - 'password', + "required": [ + "protocol", + "host", + "port", + "database", + "url", + "username", + "password" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'databaseUser': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "databaseUser": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'certificate': { - 'description': 'The certificate used to connect to the database', - 'type': 'string', + "properties": { + "certificate": { + "description": "The certificate used to connect to the database", + "type": "string" }, - 'database': { - 'description': 'The name of the database to connect to', - 'examples': [ - 'database', + "database": { + "description": "The name of the database to connect to", + "examples": [ + "database" ], - 'type': 'string', + "type": "string" }, - 'host': { - 'description': 'The host the database listens on', - 'examples': [ - 'rds.amazonwebservices.com/abc123', + "host": { + "description": "The host the database listens on", + "examples": [ + "rds.amazonwebservices.com/abc123" ], - 'type': 'string', + "type": "string" }, - 'password': { - 'description': 'Password used to authenticate with the database', - 'examples': [ - 'password', + "password": { + "description": "Password used to authenticate with the database", + "examples": [ + "password" ], - 'type': 'string', + "type": "string" }, - 'port': { - 'description': 'The port the database listens on', - 'examples': [ - 5432, - ], - 'type': [ - 'number', - 'string', + "port": { + "description": "The port the database listens on", + "examples": [ + 5432 ], + "type": [ + "number", + "string" + ] }, - 'protocol': { - 'description': 'The protocol the database responds to', - 'examples': [ - 'postgresql', + "protocol": { + "description": "The protocol the database responds to", + "examples": [ + "postgresql" ], - 'type': 'string', + "type": "string" }, - 'url': { - 'description': 'Fully resolvable URL used to connect to the database', - 'examples': [ - 'postgresql://admin:password@rds.amazonwebservices.com:5432/database', + "url": { + "description": "Fully resolvable URL used to connect to the database", + "examples": [ + "postgresql://admin:password@rds.amazonwebservices.com:5432/database" ], - 'type': 'string', + "type": "string" }, - 'username': { - 'description': 'Username used to authenticate with the database', - 'examples': [ - 'admin', + "username": { + "description": "Username used to authenticate with the database", + "examples": [ + "admin" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'protocol', - 'host', - 'port', - 'database', - 'username', - 'password', - 'url', + "required": [ + "protocol", + "host", + "port", + "database", + "username", + "password", + "url" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'deployment': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "deployment": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'labels': { - 'additionalProperties': { - 'type': 'string', + "properties": { + "labels": { + "additionalProperties": { + "type": "string" }, - 'description': 'A set of labels that were used to annotate the cloud resource', - 'examples': [ + "description": "A set of labels that were used to annotate the cloud resource", + "examples": [ { - 'app.kubernetes.io/name': 'my-app', - }, + "app.kubernetes.io/name": "my-app" + } ], - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'dockerBuild': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "dockerBuild": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'image': { - 'description': 'The resulting image address of the built artifact', - 'examples': [ - 'registry.architect.io/my-component:latest', + "properties": { + "image": { + "description": "The resulting image address of the built artifact", + "examples": [ + "registry.architect.io/my-component:latest" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'image', + "required": [ + "image" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'ingress': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "ingress": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'dns_zone': { - 'description': 'DNS zone the ingress rule responds to', - 'examples': [ - 'example.com', + "properties": { + "dns_zone": { + "description": "DNS zone the ingress rule responds to", + "examples": [ + "example.com" ], - 'type': 'string', + "type": "string" }, - 'host': { - 'description': 'Host the ingress rule responds to', - 'examples': [ - 'api.example.com', + "host": { + "description": "Host the ingress rule responds to", + "examples": [ + "api.example.com" ], - 'type': 'string', + "type": "string" }, - 'password': { - 'description': 'Password for basic auth', - 'examples': [ - 'password', + "password": { + "description": "Password for basic auth", + "examples": [ + "password" ], - 'type': 'string', + "type": "string" }, - 'path': { - 'description': 'Path the ingress rule responds to', - 'examples': [ - '/path', + "path": { + "description": "Path the ingress rule responds to", + "examples": [ + "/path" ], - 'type': 'string', + "type": "string" }, - 'port': { - 'description': 'Port the ingress rule responds to', - 'examples': [ - 80, - ], - 'type': [ - 'string', - 'number', + "port": { + "description": "Port the ingress rule responds to", + "examples": [ + 80 ], + "type": [ + "string", + "number" + ] }, - 'protocol': { - 'description': 'Protocol the ingress rule responds to', - 'examples': [ - 'http', + "protocol": { + "description": "Protocol the ingress rule responds to", + "examples": [ + "http" ], - 'type': 'string', + "type": "string" }, - 'subdomain': { - 'description': 'Subdomain the ingress rule responds to', - 'examples': [ - 'api', + "subdomain": { + "description": "Subdomain the ingress rule responds to", + "examples": [ + "api" ], - 'type': 'string', + "type": "string" }, - 'url': { - 'description': 'URL the ingress rule responds to', - 'examples': [ - 'http://admin:password@api.example.com/path', + "url": { + "description": "URL the ingress rule responds to", + "examples": [ + "http://admin:password@api.example.com/path" ], - 'type': 'string', + "type": "string" }, - 'username': { - 'description': 'Username for basic auth', - 'examples': [ - 'admin', + "username": { + "description": "Username for basic auth", + "examples": [ + "admin" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'protocol', - 'host', - 'port', - 'url', - 'path', - 'subdomain', - 'dns_zone', + "required": [ + "protocol", + "host", + "port", + "url", + "path", + "subdomain", + "dns_zone" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" ], - 'type': 'string', + "type": "string" }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], + "image": "nginx:latest", + "port": 8080 + } + ] }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" ], - 'examples': [ - 'opentofu', + "examples": [ + "opentofu" ], - 'type': 'string', + "type": "string" }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" ], - 'type': 'string', + "type": "string" }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', - ], - 'type': 'string', - }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', - ], - 'type': 'string', - }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per environment', - 'type': 'object', + "description": "Modules that will be created once per environment", + "type": "object" }, - 'secret': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "secret": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'data': { - 'description': 'The contents of the secret', - 'examples': [ - '...', + "properties": { + "data": { + "description": "The contents of the secret", + "examples": [ + "..." ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'data', + "required": [ + "data" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'service': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "service": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], - }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', - ], - 'examples': [ - 'opentofu', - ], - 'type': 'string', - }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', - ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': false, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'properties': { - 'host': { - 'description': 'Host the service listens on', - 'examples': [ - 'my-service', + "properties": { + "host": { + "description": "Host the service listens on", + "examples": [ + "my-service" ], - 'type': 'string', + "type": "string" }, - 'name': { - 'description': 'Name of the service', - 'examples': [ - 'my-service', + "name": { + "description": "Name of the service", + "examples": [ + "my-service" ], - 'type': 'string', + "type": "string" }, - 'port': { - 'description': 'Port the service listens on', - 'examples': [ - 80, - ], - 'type': [ - 'number', - 'string', + "port": { + "description": "Port the service listens on", + "examples": [ + 80 ], + "type": [ + "number", + "string" + ] }, - 'protocol': { - 'description': 'Protocol the service listens on', - 'examples': [ - 'http', + "protocol": { + "description": "Protocol the service listens on", + "examples": [ + "http" ], - 'type': 'string', + "type": "string" }, - 'target_port': { - 'description': 'The port the service forwards traffic to', - 'examples': [ - 8080, - ], - 'type': [ - 'number', - 'string', + "target_port": { + "description": "The port the service forwards traffic to", + "examples": [ + 8080 ], + "type": [ + "number", + "string" + ] }, - 'url': { - 'description': 'Fully resolvable URL of the service', - 'examples': [ - 'http://my-service:80', + "url": { + "description": "Fully resolvable URL of the service", + "examples": [ + "http://my-service:80" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'name', - 'target_port', - 'protocol', - 'host', - 'port', - 'url', + "required": [ + "name", + "target_port", + "protocol", + "host", + "port", + "url" ], - 'type': 'object', + "type": "object" }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'volume': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', - ], - 'type': 'string', - }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "task": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': - 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } }, - ], + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'examples': [ - 'opentofu', + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "volume": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } ], - 'type': 'string', + "type": "object" }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } ], - 'type': 'string', - }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per matching application resource', - 'type': 'object', + "description": "Modules that will be created once per matching application resource", + "type": "object" }, - 'outputs': { - 'additionalProperties': {}, - 'description': 'A map of output values to be passed to upstream application resources', - 'examples': [ + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ { - 'host': '${module.database.host}', - 'id': '${module.database.id}', - 'password': '${module.database.password}', - 'port': '${module.database.port}', - 'username': '${module.database.username}', - }, + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } ], - 'type': 'object', - }, - 'when': { - 'description': - 'A condition that restricts when the hook should be active. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "properties": { + "id": { + "description": "The unique ID of the volume", + "examples": [ + "my-volume" + ], + "type": "string" + } + }, + "required": [ + "id" ], - 'type': 'string', + "type": "object" }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', - }, + "type": "array" + } }, - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'module': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'build': { - 'description': 'The path to a module that will be built during the build step.', - 'examples': [ - './my-module', + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" ], - 'type': 'string', + "type": "string" }, - 'environment': { - 'additionalProperties': { - 'type': 'string', + "environment": { + "additionalProperties": { + "type": "string" }, - 'description': 'Environment variables that should be provided to the container executing the module', - 'examples': [ + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ { - 'MY_ENV_VAR': 'my-value', - }, + "MY_ENV_VAR": "my-value" + } ], - 'type': 'object', + "type": "object" }, - 'inputs': { - 'anyOf': [ + "inputs": { + "anyOf": [ { - 'additionalProperties': {}, - 'type': 'object', + "additionalProperties": {}, + "type": "object" }, { - 'type': 'string', - }, + "type": "string" + } ], - 'description': 'Input values for the module.', - 'examples': [ + "description": "Input values for the module.", + "examples": [ { - 'image': 'nginx:latest', - 'port': 8080, - }, - ], + "image": "nginx:latest", + "port": 8080 + } + ] }, - 'plugin': { - 'default': 'pulumi', - 'description': 'The plugin used to build the module. Defaults to pulumi.', - 'enum': [ - 'pulumi', - 'opentofu', + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" ], - 'examples': [ - 'opentofu', + "examples": [ + "opentofu" ], - 'type': 'string', + "type": "string" }, - 'source': { - 'description': 'The image source of the module.', - 'examples': [ - 'my-registry.com/my-image:latest', + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" ], - 'type': 'string', + "type": "string" }, - 'volume': { - 'description': 'Volumes that should be mounted to the container executing the module', - 'items': { - 'additionalProperties': false, - 'properties': { - 'host_path': { - 'description': 'The path on the host machine to mount to the container', - 'examples': [ - '/Users/batman/my-volume', + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" ], - 'type': 'string', + "type": "string" }, - 'mount_path': { - 'description': 'The path in the container to mount the volume to', - 'examples': [ - '/app/my-volume', + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'host_path', - 'mount_path', + "required": [ + "host_path", + "mount_path" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'when': { - 'description': - 'A condition that restricts when the module should be created. Must resolve to a boolean.', - 'examples': [ - 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', - 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'inputs', + "required": [ + "inputs" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Modules that will be created once per datacenter', - 'type': 'object', + "description": "Modules that will be created once per datacenter", + "type": "object" }, - 'variable': { - 'additionalProperties': { - 'items': { - 'additionalProperties': false, - 'properties': { - 'default': { - 'description': 'The default value of the variable', - 'examples': [ - 'my-value', + "variable": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "default": { + "description": "The default value of the variable", + "examples": [ + "my-value" ], - 'type': 'string', + "type": "string" }, - 'description': { - 'description': 'A human-readable description of the variable', - 'examples': [ - 'An example description', + "description": { + "description": "A human-readable description of the variable", + "examples": [ + "An example description" ], - 'type': 'string', + "type": "string" }, - 'type': { - 'description': 'The type of the variable', - 'enum': [ - 'string', - 'number', - 'boolean', + "type": { + "description": "The type of the variable", + "enum": [ + "string", + "number", + "boolean" ], - 'examples': [ - 'string', + "examples": [ + "string" ], - 'type': 'string', - }, + "type": "string" + } }, - 'required': [ - 'type', + "required": [ + "type" ], - 'type': 'object', + "type": "object" }, - 'type': 'array', + "type": "array" }, - 'description': 'Variables necessary for the datacenter to run', - 'type': 'object', - }, - 'version': { - 'const': 'v1', - 'type': 'string', + "description": "Variables necessary for the datacenter to run", + "type": "object" }, + "version": { + "const": "v1", + "type": "string" + } }, - 'required': [ - 'version', + "required": [ + "version" ], - 'type': 'object', - }, + "type": "object" + } }, - '$id': 'https://architect.io/.schemas/datacenter.json', -}; + "$id": "https://architect.io/.schemas/datacenter.json" +} \ No newline at end of file diff --git a/src/datacenters/datacenter.schema.json b/src/datacenters/datacenter.schema.json index 88dcfbefb..716d3cbcf 100644 --- a/src/datacenters/datacenter.schema.json +++ b/src/datacenters/datacenter.schema.json @@ -10,6 +10,181 @@ "items": { "additionalProperties": false, "properties": { + "bucket": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } + ], + "type": "object" + }, + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } + }, + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" + }, + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "properties": { + "access_key_id": { + "description": "Access key ID used to authenticate with the bucket", + "type": "string" + }, + "endpoint": { + "description": "Endpoint that hosts the bucket", + "examples": [ + "https://nyc3.digitaloceanspaces.com", + "https://bucket.s3.region.amazonaws.com" + ], + "type": "string" + }, + "id": { + "description": "Unique ID of the bucket that was created", + "examples": [ + "abc123" + ], + "type": "string" + }, + "region": { + "description": "Region the bucket was created in", + "type": "string" + }, + "secret_access_key": { + "description": "Secret access key used to authenticate with the bucket", + "type": "string" + } + }, + "required": [ + "id", + "endpoint", + "region", + "access_key_id", + "secret_access_key" + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, "cronjob": { "items": { "additionalProperties": false, @@ -1537,6 +1712,145 @@ }, "type": "array" }, + "task": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } + ], + "type": "object" + }, + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } + }, + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" + }, + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, "volume": { "items": { "additionalProperties": false, @@ -1650,7 +1964,7 @@ "type": "object" }, "outputs": { - "additionalProperties": {}, + "additionalProperties": false, "description": "A map of output values to be passed to upstream application resources", "examples": [ { @@ -1661,6 +1975,18 @@ "username": "${module.database.username}" } ], + "properties": { + "id": { + "description": "The unique ID of the volume", + "examples": [ + "my-volume" + ], + "type": "string" + } + }, + "required": [ + "id" + ], "type": "object" }, "when": { diff --git a/src/datacenters/schema.ts b/src/datacenters/schema.ts index dd1c64d52..712adc4cd 100644 --- a/src/datacenters/schema.ts +++ b/src/datacenters/schema.ts @@ -1,9 +1,11 @@ import { Datacenter } from './datacenter.ts'; import datacenter_v1 from './v1/index.ts'; -export type DatacenterSchema = { - version: 'v1'; -} & datacenter_v1; +export type DatacenterSchema = + | ({ + version: 'v1'; + } & datacenter_v1) +; export const buildDatacenter = (data: DatacenterSchema): Datacenter => { switch (data.version) { @@ -11,4 +13,4 @@ export const buildDatacenter = (data: DatacenterSchema): Datacenter => { return new datacenter_v1(data); } } -}; +}; \ No newline at end of file diff --git a/src/datacenters/v1/__tests__/datacenter.test.ts b/src/datacenters/v1/__tests__/datacenter.test.ts index d106e63bf..a1ae5ae06 100644 --- a/src/datacenters/v1/__tests__/datacenter.test.ts +++ b/src/datacenters/v1/__tests__/datacenter.test.ts @@ -1081,7 +1081,6 @@ describe('DatacenterV1', () => { port: '8080', protocol: 'http', }, - port: 8080, protocol: 'http', path: '/', internal: false, @@ -1281,7 +1280,6 @@ describe('DatacenterV1', () => { port: `\${{ ${serviceNode.getId()}.port }}`, protocol: `\${{ ${serviceNode.getId()}.protocol }}`, }, - port: `\${{ ${serviceNode.getId()}.port }}`, protocol: `\${{ ${serviceNode.getId()}.protocol }}`, path: '/', internal: false, @@ -1379,7 +1377,6 @@ describe('DatacenterV1', () => { port: `port`, protocol: `protocol`, }, - port: 'port', protocol: `protocol`, path: '/', internal: false, @@ -1408,7 +1405,6 @@ describe('DatacenterV1', () => { dns_zone: 'architect.io', internal: false, path: '/', - port: 'port', protocol: 'protocol', service: { name: 'host', diff --git a/src/datacenters/v1/schema.json b/src/datacenters/v1/schema.json index 9cae4d9df..b96bf3743 100644 --- a/src/datacenters/v1/schema.json +++ b/src/datacenters/v1/schema.json @@ -10,6 +10,181 @@ "items": { "additionalProperties": false, "properties": { + "bucket": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } + ], + "type": "object" + }, + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } + }, + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" + }, + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "properties": { + "access_key_id": { + "description": "Access key ID used to authenticate with the bucket", + "type": "string" + }, + "endpoint": { + "description": "Endpoint that hosts the bucket", + "examples": [ + "https://nyc3.digitaloceanspaces.com", + "https://bucket.s3.region.amazonaws.com" + ], + "type": "string" + }, + "id": { + "description": "Unique ID of the bucket that was created", + "examples": [ + "abc123" + ], + "type": "string" + }, + "region": { + "description": "Region the bucket was created in", + "type": "string" + }, + "secret_access_key": { + "description": "Secret access key used to authenticate with the bucket", + "type": "string" + } + }, + "required": [ + "id", + "endpoint", + "region", + "access_key_id", + "secret_access_key" + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, "cronjob": { "items": { "additionalProperties": false, @@ -1537,6 +1712,145 @@ }, "type": "array" }, + "task": { + "items": { + "additionalProperties": false, + "properties": { + "module": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "build": { + "description": "The path to a module that will be built during the build step.", + "examples": [ + "./my-module" + ], + "type": "string" + }, + "environment": { + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables that should be provided to the container executing the module", + "examples": [ + { + "MY_ENV_VAR": "my-value" + } + ], + "type": "object" + }, + "inputs": { + "anyOf": [ + { + "additionalProperties": {}, + "type": "object" + }, + { + "type": "string" + } + ], + "description": "Input values for the module.", + "examples": [ + { + "image": "nginx:latest", + "port": 8080 + } + ] + }, + "plugin": { + "default": "pulumi", + "description": "The plugin used to build the module. Defaults to pulumi.", + "enum": [ + "pulumi", + "opentofu" + ], + "examples": [ + "opentofu" + ], + "type": "string" + }, + "source": { + "description": "The image source of the module.", + "examples": [ + "my-registry.com/my-image:latest" + ], + "type": "string" + }, + "volume": { + "description": "Volumes that should be mounted to the container executing the module", + "items": { + "additionalProperties": false, + "properties": { + "host_path": { + "description": "The path on the host machine to mount to the container", + "examples": [ + "/Users/batman/my-volume" + ], + "type": "string" + }, + "mount_path": { + "description": "The path in the container to mount the volume to", + "examples": [ + "/app/my-volume" + ], + "type": "string" + } + }, + "required": [ + "host_path", + "mount_path" + ], + "type": "object" + }, + "type": "array" + }, + "when": { + "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "required": [ + "inputs" + ], + "type": "object" + }, + "type": "array" + }, + "description": "Modules that will be created once per matching application resource", + "type": "object" + }, + "outputs": { + "additionalProperties": false, + "description": "A map of output values to be passed to upstream application resources", + "examples": [ + { + "host": "${module.database.host}", + "id": "${module.database.id}", + "password": "${module.database.password}", + "port": "${module.database.port}", + "username": "${module.database.username}" + } + ], + "type": "object" + }, + "when": { + "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", + "examples": [ + "node.type == 'database' && node.inputs.databaseType == 'postgres'", + "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, "volume": { "items": { "additionalProperties": false, @@ -1650,7 +1964,7 @@ "type": "object" }, "outputs": { - "additionalProperties": {}, + "additionalProperties": false, "description": "A map of output values to be passed to upstream application resources", "examples": [ { @@ -1661,6 +1975,18 @@ "username": "${module.database.username}" } ], + "properties": { + "id": { + "description": "The unique ID of the volume", + "examples": [ + "my-volume" + ], + "type": "string" + } + }, + "required": [ + "id" + ], "type": "object" }, "when": { diff --git a/src/environments/environment-schema.ts b/src/environments/environment-schema.ts index a15d230f5..7885cb01c 100644 --- a/src/environments/environment-schema.ts +++ b/src/environments/environment-schema.ts @@ -1,230 +1,226 @@ export default { - '$ref': '#/definitions/EnvironmentSchema', - '$schema': 'https://json-schema.org/draft/2019-09/schema', - 'definitions': { - 'EnvironmentSchema': { - 'additionalProperties': false, - 'properties': { - 'components': { - 'additionalProperties': { - 'additionalProperties': false, - 'description': 'The name of the component that will be used to fulfill dependencies', - 'properties': { - 'deployments': { - 'additionalProperties': { - 'additionalProperties': false, - 'description': 'The name of the deployment to configure', - 'properties': { - 'autoscaling': { - 'additionalProperties': false, - 'description': 'Autoscaling rules for the deployment within the environment', - 'properties': { - 'max_replicas': { - 'default': 1, - 'description': 'Maximum number of replicas to maintain', - 'type': 'number', - }, - 'min_replicas': { - 'default': 1, - 'description': 'Minimum number of replicas to maintain', - 'type': 'number', + "$ref": "#/definitions/EnvironmentSchema", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "definitions": { + "EnvironmentSchema": { + "additionalProperties": false, + "properties": { + "components": { + "additionalProperties": { + "additionalProperties": false, + "description": "The name of the component that will be used to fulfill dependencies", + "properties": { + "deployments": { + "additionalProperties": { + "additionalProperties": false, + "description": "The name of the deployment to configure", + "properties": { + "autoscaling": { + "additionalProperties": false, + "description": "Autoscaling rules for the deployment within the environment", + "properties": { + "max_replicas": { + "default": 1, + "description": "Maximum number of replicas to maintain", + "type": "number" }, + "min_replicas": { + "default": 1, + "description": "Minimum number of replicas to maintain", + "type": "number" + } }, - 'type': 'object', + "type": "object" }, - 'enabled': { - 'default': true, - 'description': 'Set to false to make sure the deployment doesn\'t run in this environment', - 'type': 'boolean', + "enabled": { + "default": true, + "description": "Set to false to make sure the deployment doesn't run in this environment", + "type": "boolean" }, - 'environment': { - 'additionalProperties': { - 'anyOf': [ + "environment": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'type': 'number', + "type": "number" }, { - 'type': 'boolean', + "type": "boolean" }, { - 'type': 'null', + "type": "null" }, { - 'not': {}, - }, - ], + "not": {} + } + ] }, - 'description': 'Values for environment variables in the deployment', - 'examples': [ + "description": "Values for environment variables in the deployment", + "examples": [ { - 'STRIPE_API_KEY': 'sk_test_1234', - }, + "STRIPE_API_KEY": "sk_test_1234" + } ], - 'type': 'object', - }, - 'replicas': { - 'default': 1, - 'description': 'Number of replicas of the deployment to maintain', - 'type': 'number', + "type": "object" }, + "replicas": { + "default": 1, + "description": "Number of replicas of the deployment to maintain", + "type": "number" + } }, - 'type': 'object', + "type": "object" }, - 'description': 'Configuration for each deployment in the component', - 'type': 'object', + "description": "Configuration for each deployment in the component", + "type": "object" }, - 'ingresses': { - 'additionalProperties': { - 'additionalProperties': false, - 'description': 'The name of the ingress to configure', - 'properties': { - 'internal': { - 'description': - 'Set to true to make the ingress only available from a private gateway (no public IP)', - 'examples': [ - true, + "ingresses": { + "additionalProperties": { + "additionalProperties": false, + "description": "The name of the ingress to configure", + "properties": { + "internal": { + "description": "Set to true to make the ingress only available from a private gateway (no public IP)", + "examples": [ + true ], - 'type': 'boolean', + "type": "boolean" }, - 'path': { - 'description': 'A path that the ingress listens on', - 'examples': [ - '/api', + "path": { + "description": "A path that the ingress listens on", + "examples": [ + "/api" ], - 'type': 'string', + "type": "string" }, - 'subdomain': { - 'description': 'A subdomain that the ingress listens on', - 'examples': [ - 'api', + "subdomain": { + "description": "A subdomain that the ingress listens on", + "examples": [ + "api" ], - 'type': 'string', + "type": "string" }, - 'tls': { - 'additionalProperties': false, - 'description': 'Custom TLS configuration for the ingress rule', - 'properties': { - 'ca': { - 'description': 'The certificate authority', - 'type': 'string', - }, - 'crt': { - 'description': 'The certificate file contents', - 'type': 'string', + "tls": { + "additionalProperties": false, + "description": "Custom TLS configuration for the ingress rule", + "properties": { + "ca": { + "description": "The certificate authority", + "type": "string" }, - 'key': { - 'description': 'The key file contents', - 'type': 'string', + "crt": { + "description": "The certificate file contents", + "type": "string" }, + "key": { + "description": "The key file contents", + "type": "string" + } }, - 'required': [ - 'crt', - 'key', + "required": [ + "crt", + "key" ], - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'description': 'Configuration for each ingress in the component', - 'type': 'object', + "description": "Configuration for each ingress in the component", + "type": "object" }, - 'services': { - 'additionalProperties': { - 'additionalProperties': false, - 'description': 'The name of the service to configure', - 'properties': { - 'host': { - 'description': - 'Existing hostname that should act as the interface host instead of creating a new one', - 'examples': [ - 'example.com', + "services": { + "additionalProperties": { + "additionalProperties": false, + "description": "The name of the service to configure", + "properties": { + "host": { + "description": "Existing hostname that should act as the interface host instead of creating a new one", + "examples": [ + "example.com" ], - 'type': 'string', + "type": "string" }, - 'port': { - 'description': - 'Existing port that should act as the interface port instead of registering a new one', - 'examples': [ - 443, + "port": { + "description": "Existing port that should act as the interface port instead of registering a new one", + "examples": [ + 443 ], - 'type': 'number', + "type": "number" }, - 'url': { - 'description': 'Existing URL to point the service to instead of', - 'examples': [ - 'https://example.com', + "url": { + "description": "Existing URL to point the service to instead of", + "examples": [ + "https://example.com" ], - 'type': 'string', - }, + "type": "string" + } }, - 'type': 'object', + "type": "object" }, - 'description': 'Configuration for each service in the component', - 'type': 'object', + "description": "Configuration for each service in the component", + "type": "object" }, - 'source': { - 'description': - 'The source of the component to deploy. Can either be a docker registry repository or a reference to the local filesystem prefixed with `file:`', - 'examples': [ - 'architectio/kratos:v1', - 'file:/path/to/component', + "source": { + "description": "The source of the component to deploy. Can either be a docker registry repository or a reference to the local filesystem prefixed with `file:`", + "examples": [ + "architectio/kratos:v1", + "file:/path/to/component" ], - 'type': 'string', + "type": "string" }, - 'variables': { - 'additionalProperties': { - 'anyOf': [ + "variables": { + "additionalProperties": { + "anyOf": [ { - 'type': 'string', + "type": "string" }, { - 'items': { - 'type': 'string', + "items": { + "type": "string" }, - 'type': 'array', - }, - ], + "type": "array" + } + ] }, - 'description': 'Values for variables the component expects', - 'examples': [ + "description": "Values for variables the component expects", + "examples": [ { - 'log_level': 'debug', - }, + "log_level": "debug" + } ], - 'type': 'object', - }, + "type": "object" + } }, - 'type': 'object', + "type": "object" }, - 'description': 'Configuration settings for the components that may be deployed inside this environment', - 'type': 'object', + "description": "Configuration settings for the components that may be deployed inside this environment", + "type": "object" }, - 'locals': { - 'additionalProperties': { - 'type': 'string', + "locals": { + "additionalProperties": { + "type": "string" }, - 'description': 'Local variables that can be used to parameterize the environment', - 'examples': [ + "description": "Local variables that can be used to parameterize the environment", + "examples": [ { - 'log_level': 'debug', - }, + "log_level": "debug" + } ], - 'type': 'object', - }, - 'version': { - 'const': 'v1', - 'type': 'string', + "type": "object" }, + "version": { + "const": "v1", + "type": "string" + } }, - 'required': [ - 'version', + "required": [ + "version" ], - 'type': 'object', - }, + "type": "object" + } }, - '$id': 'https://architect.io/.schemas/environment.json', -}; + "$id": "https://architect.io/.schemas/environment.json" +} \ No newline at end of file diff --git a/src/environments/schema.ts b/src/environments/schema.ts index c9b11117a..83ca27e77 100644 --- a/src/environments/schema.ts +++ b/src/environments/schema.ts @@ -4,9 +4,11 @@ import environment_v1 from './v1/index.ts'; /** * @discriminatorOpenApi version */ -export type EnvironmentSchema = { - version: 'v1'; -} & environment_v1; +export type EnvironmentSchema = + | ({ + version: 'v1'; + } & environment_v1) +; export const buildEnvironment = (data: EnvironmentSchema): Environment => { switch (data.version) { @@ -15,7 +17,9 @@ export const buildEnvironment = (data: EnvironmentSchema): Environment => { } default: { throw new Error( - `Invalid schema version: ${'version' in data ? data.version : 'none'}`, + `Invalid schema version: ${ + 'version' in data ? data.version : 'none' + }` ); } } From eee90ecc4e8bb7ed14bfc1c8c90ad6d4666a01d9 Mon Sep 17 00:00:00 2001 From: David Thor Date: Wed, 6 Dec 2023 16:32:40 -0500 Subject: [PATCH 2/3] WIP: got static buckets working --- deno.lock | 782 +++++++++++++++++- examples/datacenters/local/datacenter.arc | 141 +++- .../datacenters/local/deployment/index.ts | 17 +- examples/datacenters/local/network/index.ts | 16 - src/commands/apply/datacenter.ts | 9 +- src/commands/apply/environment.ts | 8 +- src/commands/apply/utils.ts | 77 +- src/components/v2/index.ts | 2 +- 8 files changed, 945 insertions(+), 107 deletions(-) diff --git a/deno.lock b/deno.lock index b23a68668..93d600b66 100644 --- a/deno.lock +++ b/deno.lock @@ -2,7 +2,10 @@ "version": "3", "packages": { "specifiers": { + "npm:@types/node": "npm:@types/node@18.16.19", + "npm:@types/pg@^8.6.5": "npm:@types/pg@8.10.9", "npm:mustache": "npm:mustache@4.2.0", + "npm:pg@8.8.0": "npm:pg@8.8.0", "npm:ts-json-schema-generator": "npm:ts-json-schema-generator@1.2.0" }, "npm": { @@ -10,6 +13,18 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dependencies": {} }, + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "@types/pg@8.10.9": { + "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "dependencies": { + "@types/node": "@types/node@18.16.19", + "pg-protocol": "pg-protocol@1.6.0", + "pg-types": "pg-types@4.0.1" + } + }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dependencies": {} @@ -20,6 +35,10 @@ "balanced-match": "balanced-match@1.0.2" } }, + "buffer-writer@2.0.0": { + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "dependencies": {} + }, "commander@9.5.0": { "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dependencies": {} @@ -67,16 +86,130 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dependencies": {} }, + "obuf@1.1.2": { + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dependencies": {} + }, "once@1.4.0": { "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "wrappy@1.0.2" } }, + "packet-reader@1.0.0": { + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==", + "dependencies": {} + }, + "pg-connection-string@2.6.2": { + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==", + "dependencies": {} + }, + "pg-int8@1.0.1": { + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dependencies": {} + }, + "pg-numeric@1.0.2": { + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dependencies": {} + }, + "pg-pool@3.6.1_pg@8.8.0": { + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "dependencies": { + "pg": "pg@8.8.0" + } + }, + "pg-protocol@1.6.0": { + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==", + "dependencies": {} + }, + "pg-types@2.2.0": { + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "pg-int8@1.0.1", + "postgres-array": "postgres-array@2.0.0", + "postgres-bytea": "postgres-bytea@1.0.0", + "postgres-date": "postgres-date@1.0.7", + "postgres-interval": "postgres-interval@1.2.0" + } + }, + "pg-types@4.0.1": { + "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dependencies": { + "pg-int8": "pg-int8@1.0.1", + "pg-numeric": "pg-numeric@1.0.2", + "postgres-array": "postgres-array@3.0.2", + "postgres-bytea": "postgres-bytea@3.0.0", + "postgres-date": "postgres-date@2.0.1", + "postgres-interval": "postgres-interval@3.0.0", + "postgres-range": "postgres-range@1.1.3" + } + }, + "pg@8.8.0": { + "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==", + "dependencies": { + "buffer-writer": "buffer-writer@2.0.0", + "packet-reader": "packet-reader@1.0.0", + "pg-connection-string": "pg-connection-string@2.6.2", + "pg-pool": "pg-pool@3.6.1_pg@8.8.0", + "pg-protocol": "pg-protocol@1.6.0", + "pg-types": "pg-types@2.2.0", + "pgpass": "pgpass@1.0.5" + } + }, + "pgpass@1.0.5": { + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "split2@4.2.0" + } + }, + "postgres-array@2.0.0": { + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dependencies": {} + }, + "postgres-array@3.0.2": { + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dependencies": {} + }, + "postgres-bytea@1.0.0": { + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "dependencies": {} + }, + "postgres-bytea@3.0.0": { + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dependencies": { + "obuf": "obuf@1.1.2" + } + }, + "postgres-date@1.0.7": { + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "dependencies": {} + }, + "postgres-date@2.0.1": { + "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dependencies": {} + }, + "postgres-interval@1.2.0": { + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "xtend@4.0.2" + } + }, + "postgres-interval@3.0.0": { + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dependencies": {} + }, + "postgres-range@1.1.3": { + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", + "dependencies": {} + }, "safe-stable-stringify@2.4.3": { "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", "dependencies": {} }, + "split2@4.2.0": { + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dependencies": {} + }, "ts-json-schema-generator@1.2.0": { "integrity": "sha512-tUMeO3ZvA12d3HHh7T/AK8W5hmUhDRNtqWRHSMN3ZRbUFt+UmV0oX8k1RK4SA+a+BKNHpmW2v06MS49e8Fi3Yg==", "dependencies": { @@ -96,9 +229,21 @@ "wrappy@1.0.2": { "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dependencies": {} + }, + "xtend@4.0.2": { + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dependencies": {} } } }, + "redirects": { + "https://esm.sh/v124/@types/escodegen@latest/index.d.ts": "https://esm.sh/v124/@types/escodegen@0.0.9/index.d.ts", + "https://esm.sh/v124/@types/estraverse@^5/index.d.ts": "https://esm.sh/v124/@types/estraverse@5.1.4/index.d.ts", + "https://esm.sh/v124/@types/events@~1.1/index.d.ts": "https://esm.sh/v124/@types/events@1.1.0/index.d.ts", + "https://esm.sh/v124/@types/js-yaml@^4/index.d.ts": "https://esm.sh/v124/@types/js-yaml@4.0.5/index.d.ts", + "https://esm.sh/v124/@types/slice-ansi@~5.0/index.d.ts": "https://esm.sh/v124/@types/slice-ansi@5.0.0/index.d.ts", + "https://esm.sh/v124/@types/tar@^6/index.d.ts": "https://esm.sh/v124/@types/tar@6.1.6/index.d.ts" + }, "remote": { "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", @@ -120,8 +265,295 @@ "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757", "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", + "https://deno.land/std@0.153.0/_deno_unstable.ts": "4ddb8672d49d58b5bbc4a5a7a2f1b3bce4fd06aa4c8b8476728334391667de7b", + "https://deno.land/std@0.153.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.153.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", + "https://deno.land/std@0.153.0/_wasm_crypto/lib/deno_std_wasm_crypto.generated.mjs": "dfcd6777d05345362c70f9f2c49abba3ed3f925fccfcf725abe2d16d51819433", + "https://deno.land/std@0.153.0/_wasm_crypto/mod.ts": "6c60d332716147ded0eece0861780678d51b560f533b27db2e15c64a4ef83665", + "https://deno.land/std@0.153.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06", + "https://deno.land/std@0.153.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", + "https://deno.land/std@0.153.0/async/debounce.ts": "de5433bff08a2bb61416fc53b3bd2d5867090c8a815465e5b4a10a77495b1051", + "https://deno.land/std@0.153.0/async/deferred.ts": "c01de44b9192359cebd3fe93273fcebf9e95110bf3360023917da9a2d1489fae", + "https://deno.land/std@0.153.0/async/delay.ts": "d5a169caede8e1c5d46b3f25eab97db5fd1ab193fc82a53bafd3642ac42ca3c7", + "https://deno.land/std@0.153.0/async/mod.ts": "dd0a8ed4f3984ffabe2fcca7c9f466b7932d57b1864ffee148a5d5388316db6b", + "https://deno.land/std@0.153.0/async/mux_async_iterator.ts": "3447b28a2a582224a3d4d3596bccbba6e85040da3b97ed64012f7decce98d093", + "https://deno.land/std@0.153.0/async/pool.ts": "ef9eb97b388543acbf0ac32647121e4dbe629236899586c4d4311a8770fbb239", + "https://deno.land/std@0.153.0/async/tee.ts": "d27680d911816fcb3d231e16d690e7588079e66a9b2e5ce8cc354db94fdce95f", + "https://deno.land/std@0.153.0/bytes/bytes_list.ts": "aba5e2369e77d426b10af1de0dcc4531acecec27f9b9056f4f7bfbf8ac147ab4", + "https://deno.land/std@0.153.0/bytes/equals.ts": "3c3558c3ae85526f84510aa2b48ab2ad7bdd899e2e0f5b7a8ffc85acb3a6043a", + "https://deno.land/std@0.153.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf", + "https://deno.land/std@0.153.0/crypto/timing_safe_equal.ts": "82a29b737bc8932d75d7a20c404136089d5d23629e94ba14efa98a8cc066c73e", + "https://deno.land/std@0.153.0/encoding/base64.ts": "c57868ca7fa2fbe919f57f88a623ad34e3d970d675bdc1ff3a9d02bba7409db2", + "https://deno.land/std@0.153.0/encoding/base64url.ts": "a5f82a9fa703bd85a5eb8e7c1296bc6529e601ebd9642cc2b5eaa6b38fa9e05a", + "https://deno.land/std@0.153.0/encoding/hex.ts": "4cc5324417cbb4ac9b828453d35aed45b9cc29506fad658f1f138d981ae33795", + "https://deno.land/std@0.153.0/flags/mod.ts": "d920e6675c31d5ef7efcb2087958923caf252e28fee724d7f7444c6b7b235204", + "https://deno.land/std@0.153.0/fmt/colors.ts": "ff7dc9c9f33a72bd48bc24b21bbc1b4545d8494a431f17894dbc5fe92a938fc4", + "https://deno.land/std@0.153.0/fmt/printf.ts": "111a4df40a81799da778421ae0260f278e5d79877e30e92403cd57d197a8d1b0", + "https://deno.land/std@0.153.0/io/buffer.ts": "8232dcd8c4c7f14b95f28444454ad63750267be23e0fd7f88320c68b0f87a3b5", + "https://deno.land/std@0.153.0/node/_buffer.mjs": "4e3e6b0f0613300340705a99a1998c655ba22bf08644c49df21f4aaa44e951d0", + "https://deno.land/std@0.153.0/node/_core.ts": "83860ad91022fe1ed759acc3f012dd7e2a4258bd4ee7eab8332110cba0d0be10", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/base/buffer.js": "73beb8294eb29bd61458bbaaeeb51dfad4ec9c9868a62207a061d908f1637261", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/base/node.js": "4b777980d2a23088698fd2ff065bb311a2c713497d359e674cb6ef6baf267a0f", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/base/reporter.js": "8e4886e8ae311c9a92caf58bbbd8670326ceeae97430f4884e558e4acf8e8598", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/constants/der.js": "354b255479bff22a31d25bf08b217a295071700e37d0991cc05cac9f95e5e7ca", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/decoders/der.js": "c6faf66761daa43fbf79221308443893587c317774047b508a04c570713b76fb", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/decoders/pem.js": "8316ef7ce2ce478bc3dc1e9df1b75225d1eb8fb5d1378f8adf0cf19ecea5b501", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/encoders/der.js": "408336c88d17c5605ea64081261cf42267d8f9fda90098cb560aa6635bb00877", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/encoders/pem.js": "42a00c925b68c0858d6de0ba41ab89935b39fae9117bbf72a9abb2f4b755a2e7", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/asn1.js/mod.js": "7b78859707be10a0a1e4faccdd28cd5a4f71ad74a3e7bebda030757da97cd232", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/bn.js/bn.js": "abd1badd659fd0ae54e6a421a573a25aef4e795edc392178360cf716b144286d", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/aes.js": "1cf4c354c5bb341ffc9ab7207f471229835b021947225bce2e1642f26643847a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/auth_cipher.js": "19b4dbb903e8406eb733176e6318d5e1a3bd382b67b72f7cf8e1c46cc6321ba4", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/decrypter.js": "05c1676942fd8e95837115bc2d1371bcf62e9bf19f6c3348870961fc64ddad0b", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/encrypter.js": "93ec98ab26fbeb5969eae2943e42fb66780f377b9b0ff0ecc32a9ed11201b142", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/ghash.js": "667b64845764a84f0096ef8cf7debed1a5f15ac9af26b379848237be57da399a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/incr32.js": "4a7f0107753e4390b4ccc4dbd5200c5527d43f894f768e131903df30a09dfd67", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/mod.js": "d8eb88e7a317467831473621f32e60d7db9d981f6a2ae45d2fb2af170eab2d22", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/cbc.js": "9790799cff181a074686c885708cb8eb473aeb3c86ff2e8d0ff911ae6c1e4431", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb.js": "a4e36ede6f26d8559d8f0528a134592761c706145a641bd9ad1100763e831cdb", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js": "c6372f4973a68ca742682e81d1165e8869aaabf0091a8b963d4d60e5ee8e6f6a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js": "bd29eebb89199b056ff2441f7fb5e0300f458e13dcaaddbb8bc00cbdb199db67", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/ctr.js": "9c2cbac1fc8f9b58334faacb98e6c57e8c3712f673ea4cf2d528a2894998ab2f", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/ecb.js": "9629d193433688f0cfc432eca52838db0fb28d9eb4f45563df952bde50b59763", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/mod.js": "7d8516ef8a20565539eb17cad5bb70add02ac06d1891e8f47cb981c22821787e", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/modes/ofb.js": "c23abaa6f1ec5343e9d7ba61d702acb3d81a0bd3d34dd2004e36975dc043d6ff", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/stream_cipher.js": "a533a03a2214c6b5934ce85a59eb1e04239fd6f429017c7ca3c443ec7e07e68f", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_aes/xor.ts": "4417711c026eb9a07475067cd31fa601e88c2d6ababd606d33d1e74da6fcfd09", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/browserify_rsa.js": "de8c98d2379a70d8c239b4886e2b3a11c7204eec39ae6b65d978d0d516ee6b08", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/cipher_base.js": "f565ad9daf3b3dd3b68381bed848da94fb093a9e4e5a48c92f47e26cc229df39", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/evp_bytes_to_key.ts": "006ecde1cc428b16f2d214637c35296279710b3a8d211dcf91d561c2cd692125", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/parse_asn1/asn1.js": "4f33b0197ffbe9cff62e5bad266e6b40d55874ea653552bb32ed251ad091f70a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/parse_asn1/certificate.js": "aab306870830a81ad188db8fa8e037d7f5dd6c5abdabbd9739558245d1a12224", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/parse_asn1/fix_proc.js": "af3052b76f441878e102ffcfc7420692e65777af765e96f786310ae1acf7f76a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/parse_asn1/mod.js": "9d445baecb55d4abbe6434be55d5bb7976ea752c3976a75b7e2684a7d440a576", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/mgf.js": "46cf72f2b9aa678a15daef8ed551241f2d0c1ca38b8b6c8e5226a4853540d7b2", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/mod.js": "eb8b64d7a58ee3823c1b642e799cc7ed1257d99f4d4aefa2b4796dd112ec094a", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/private_decrypt.js": "220de06bf9edcfa4def18c30a16aa0482b1ddc24f8712f46509e82b1e3be122c", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/public_encrypt.js": "4679188b9b38502ac21b5e1a5bcfbcd278f51854f5385aac8d9962d7c21b2a6e", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/with_public.js": "7373dac9b53b8331ccf3521c854a131dcb304a2e4d34cd116649118f7919ed0c", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/public_encrypt/xor.js": "900c6fc8b95e1861d796193c41988f5f70a09c7059e42887a243d0113ecaf0fd", + "https://deno.land/std@0.153.0/node/_crypto/crypto_browserify/randombytes.ts": "414e2a13f1ea79980acba7b4634821b7a636f1856eedbba7cce8fa528c11e9a0", + "https://deno.land/std@0.153.0/node/_events.mjs": "303e8aa60ace559e4ca0d19e8475f87311bee9e8330b4b497644d70f2002fc27", + "https://deno.land/std@0.153.0/node/_next_tick.ts": "ec6772f13b0b78edd1b679502501210abdcdd5b170aa6b90ec28dfd67dcd30ae", + "https://deno.land/std@0.153.0/node/_process/exiting.ts": "bc9694769139ffc596f962087155a8bfef10101d03423b9dcbc51ce6e1f88fce", + "https://deno.land/std@0.153.0/node/_process/process.ts": "71c22bd237ce970460dfd1e4f14aba42e6762febc31df9f3c505c3d7328b8232", + "https://deno.land/std@0.153.0/node/_process/stdio.mjs": "971c3b086040d8521562155db13f22f9971d5c42c852b2081d4d2f0d8b6ab6bd", + "https://deno.land/std@0.153.0/node/_stream.mjs": "07f6cbabaad0382fb4b9a25e70ac3093a44022b859247f64726746e6373f1c91", + "https://deno.land/std@0.153.0/node/_util/_util_callbackify.ts": "a71353d5fde3dc785cfdf6b6bcad1379a9c78b374720af4aaa7f88ffab2bac0e", + "https://deno.land/std@0.153.0/node/_utils.ts": "6a695598008a7bdf820b0785f3bc2fcbedbb48803365ae787e523e05b182cf73", + "https://deno.land/std@0.153.0/node/buffer.ts": "0e4e409bc03754e99c3e9fbdd10ff50834fd5d6e8654f70efeff054afde58821", + "https://deno.land/std@0.153.0/node/crypto.ts": "0bc90f0550c7d00ee11d8a086d57b2367ab3a083f4156ef68ae28582cd3cfcc2", + "https://deno.land/std@0.153.0/node/events.ts": "f848398d3591534ca94ac6b852a9f3c4dbb2da310c3a26059cf4ff06b7eae088", + "https://deno.land/std@0.153.0/node/internal/blob.mjs": "52080b2f40b114203df67f8a6650f9fe3c653912b8b3ef2f31f029853df4db53", + "https://deno.land/std@0.153.0/node/internal/buffer.mjs": "6662fe7fe517329453545be34cea27a24f8ccd6d09afd4f609f11ade2b6dfca7", + "https://deno.land/std@0.153.0/node/internal/crypto/_keys.ts": "7f993ece8c8e94a292944518cf4173521c6bf01785e75be014cd45a9cc2e4ad5", + "https://deno.land/std@0.153.0/node/internal/crypto/_randomBytes.ts": "0d80254f7be71aa3212956071d22f2cb2193aa1f957e48286f83ccf092abe4e5", + "https://deno.land/std@0.153.0/node/internal/crypto/_randomFill.ts": "4d9157fd8a4894f98c125c5870bd93e0203442ec0e09908158ebff2a71b4872e", + "https://deno.land/std@0.153.0/node/internal/crypto/_randomInt.ts": "fddc02fb68e94f12a2023b0f98a8bf3a9eecfd7118633eebb752b6387e8f3baf", + "https://deno.land/std@0.153.0/node/internal/crypto/certificate.ts": "e0660db45a9ff176c6f6cdf1b8ccceca535790afe37901e4c8abcbf419b1f68d", + "https://deno.land/std@0.153.0/node/internal/crypto/cipher.ts": "c073fbc4d2a818a6442e9283fad8cd5417c5f59efd9398d617cea6796dbd8ebc", + "https://deno.land/std@0.153.0/node/internal/crypto/constants.ts": "d2c8821977aef55e4d66414d623c24a2447791a8b49b6404b8db32d81e20c315", + "https://deno.land/std@0.153.0/node/internal/crypto/diffiehellman.ts": "cccd7359947dfbc495bdf23f90c6cd94dbd0dfe70baa0f31e1fd0440b4319e92", + "https://deno.land/std@0.153.0/node/internal/crypto/hash.ts": "e1eb6afe9a1db2781566ece05b290a58d1d93e11ceb54601cbba7ac2982d266b", + "https://deno.land/std@0.153.0/node/internal/crypto/hkdf.ts": "b73f687f06ae0844966b361bbbe3c780e7c9efc87bcb9853e190e0471d06b315", + "https://deno.land/std@0.153.0/node/internal/crypto/keygen.ts": "067c4e23b0f50b12522edea98db8de83434f0aa344bc23c3d07297c5d62483e4", + "https://deno.land/std@0.153.0/node/internal/crypto/keys.ts": "9a985a04f813cdc600afb8437e06a57abc2ac4bb82783557f65af5ebeb780c2f", + "https://deno.land/std@0.153.0/node/internal/crypto/pbkdf2.ts": "bed16fa96c93a4ac397473590c21f58c50e4333a96c85bed1cff00431bf2f33c", + "https://deno.land/std@0.153.0/node/internal/crypto/random.ts": "6e3fe98367b3715a1f9039f7291a75840f1b903d4b411ce7b44ff671e64d3572", + "https://deno.land/std@0.153.0/node/internal/crypto/scrypt.ts": "120ae83f72ddcee6c6af8db3593a86aa0c926f9e563f66b0ccc303526887f337", + "https://deno.land/std@0.153.0/node/internal/crypto/sig.ts": "9d86ae6d210a23ce379b1f85a2226d9ba0279699b643a43070d1bd94c3c452e8", + "https://deno.land/std@0.153.0/node/internal/crypto/types.ts": "51201006692f584f860cad16ce20f48e74c0a4a9d3e26e31fda1b48791033ae1", + "https://deno.land/std@0.153.0/node/internal/crypto/util.ts": "62ddabd6c6ee4dd326bd20914211178195c20b7db21e9be2d15674dad6ba0e83", + "https://deno.land/std@0.153.0/node/internal/crypto/x509.ts": "8fcc114549ee0e9aca22fbddaf2f59cf7feeeb74c0189b1035d3d223a01dbd09", + "https://deno.land/std@0.153.0/node/internal/error_codes.ts": "ac03c4eae33de3a69d6c98e8678003207eecf75a6900eb847e3fea3c8c9e6d8f", + "https://deno.land/std@0.153.0/node/internal/errors.ts": "ef73e8d8da8fa5b979f0dee10474e75a7cf581852be04cde68b707332d9aa1e2", + "https://deno.land/std@0.153.0/node/internal/fixed_queue.ts": "455b3c484de48e810b13bdf95cd1658ecb1ba6bcb8b9315ffe994efcde3ba5f5", + "https://deno.land/std@0.153.0/node/internal/hide_stack_frames.ts": "a91962ec84610bc7ec86022c4593cdf688156a5910c07b5bcd71994225c13a03", + "https://deno.land/std@0.153.0/node/internal/normalize_encoding.mjs": "3779ec8a7adf5d963b0224f9b85d1bc974a2ec2db0e858396b5d3c2c92138a0a", + "https://deno.land/std@0.153.0/node/internal/options.ts": "a23c285975e058cb26a19abcb048cd8b46ab12d21cfb028868ac8003fffb43ac", + "https://deno.land/std@0.153.0/node/internal/streams/_utils.ts": "77fceaa766679847e4d4c3c96b2573c00a790298d90551e8e4df1d5e0fdaad3b", + "https://deno.land/std@0.153.0/node/internal/streams/add-abort-signal.mjs": "5623b83fa64d439cc4a1f09ae47ec1db29512cc03479389614d8f62a37902f5e", + "https://deno.land/std@0.153.0/node/internal/streams/buffer_list.mjs": "c6a7b29204fae025ff5e9383332acaea5d44bc7c522a407a79b8f7a6bc6c312d", + "https://deno.land/std@0.153.0/node/internal/streams/compose.mjs": "b522daab35a80ae62296012a4254fd7edfc0366080ffe63ddda4e38fe6b6803e", + "https://deno.land/std@0.153.0/node/internal/streams/destroy.mjs": "9c9bbeb172a437041d529829f433df72cf0b63ae49f3ee6080a55ffbef7572ad", + "https://deno.land/std@0.153.0/node/internal/streams/duplex.mjs": "9ee2cc5d6d23f9be3432a50a7bdd7a15408bac2bfbf9ccd7424342388be6150c", + "https://deno.land/std@0.153.0/node/internal/streams/end-of-stream.mjs": "38be76eaceac231dfde643e72bc0940625446bf6d1dbd995c91c5ba9fd59b338", + "https://deno.land/std@0.153.0/node/internal/streams/from.mjs": "134255c698ed63b33199911eb8e042f8f67e9682409bb11552e6120041ed1872", + "https://deno.land/std@0.153.0/node/internal/streams/legacy.mjs": "6ea28db95d4503447473e62f0b23ff473bfe1751223c33a3c5816652e93b257a", + "https://deno.land/std@0.153.0/node/internal/streams/passthrough.mjs": "a51074193b959f3103d94de41e23a78dfcff532bdba53af9146b86340d85eded", + "https://deno.land/std@0.153.0/node/internal/streams/pipeline.mjs": "9890b121759ede869174ef70c011fde964ca94d81f2ed97b8622d7cb17b49285", + "https://deno.land/std@0.153.0/node/internal/streams/readable.mjs": "d566a47ad3bbda2fbd9e9d77acec729b63813b2f31c7a229526f849619d3dc28", + "https://deno.land/std@0.153.0/node/internal/streams/state.mjs": "9ef917392a9d8005a6e038260c5fd31518d2753aea0bc9e39824c199310434cb", + "https://deno.land/std@0.153.0/node/internal/streams/transform.mjs": "3b361abad2ac78f7ccb6f305012bafdc0e983dfa4bb6ecddb4626e34a781a5f5", + "https://deno.land/std@0.153.0/node/internal/streams/utils.mjs": "06c21d0db0d51f1bf1e3225a661c3c29909be80355d268e64ee5922fc5eb6c5e", + "https://deno.land/std@0.153.0/node/internal/streams/writable.mjs": "5133c66237bf31043aec98092d1589a14483077424bba862511846e9287d2eae", + "https://deno.land/std@0.153.0/node/internal/util.mjs": "98b26aa4eb6ca70fe6c140eb296759cea54fe1b46a87a91288073dbc88d46eb0", + "https://deno.land/std@0.153.0/node/internal/util/comparisons.ts": "666e75e01a85b5d3410e43625ab9fc165811439aa1298c14054acb64b670dc48", + "https://deno.land/std@0.153.0/node/internal/util/debuglog.ts": "6f12a764f5379e9d2675395d15d2fb48bd7376921ef64006ffb022fc7f44ab82", + "https://deno.land/std@0.153.0/node/internal/util/inspect.mjs": "1ddace0c97719d2cc0869ba177d375e96051301352ec235cbfb2ecbfcd4e8fba", + "https://deno.land/std@0.153.0/node/internal/util/types.ts": "de6e2b7f9b9985ab881b1e78f05ae51d1fc829ae1584063df21e57b35312f3c4", + "https://deno.land/std@0.153.0/node/internal/validators.mjs": "a7e82eafb7deb85c332d5f8d9ffef052f46a42d4a121eada4a54232451acc49a", + "https://deno.land/std@0.153.0/node/internal_binding/_libuv_winerror.ts": "801e05c2742ae6cd42a5f0fd555a255a7308a65732551e962e5345f55eedc519", + "https://deno.land/std@0.153.0/node/internal_binding/_node.ts": "e4075ba8a37aef4eb5b592c8e3807c39cb49ca8653faf8e01a43421938076c1b", + "https://deno.land/std@0.153.0/node/internal_binding/_timingSafeEqual.ts": "80640f055101071cb3680a2d8a1fead5fd260ca8bf183efb94296b69463e06cd", + "https://deno.land/std@0.153.0/node/internal_binding/_utils.ts": "1c50883b5751a9ea1b38951e62ed63bacfdc9d69ea665292edfa28e1b1c5bd94", + "https://deno.land/std@0.153.0/node/internal_binding/_winerror.ts": "8811d4be66f918c165370b619259c1f35e8c3e458b8539db64c704fbde0a7cd2", + "https://deno.land/std@0.153.0/node/internal_binding/buffer.ts": "781e1d13adc924864e6e37ecb5152e8a4e994cf394695136e451c47f00bda76c", + "https://deno.land/std@0.153.0/node/internal_binding/constants.ts": "f4afc504137fb21f3908ab549931604968dfa62432b285a0874f41c4cade9ed2", + "https://deno.land/std@0.153.0/node/internal_binding/crypto.ts": "d7f39700dc020364edf7f4785e5026bb91f099ce1bd02734182451b1af300c8c", + "https://deno.land/std@0.153.0/node/internal_binding/node_options.ts": "3cd5706153d28a4f5944b8b162c1c61b7b8e368a448fb1a2cff9f7957d3db360", + "https://deno.land/std@0.153.0/node/internal_binding/string_decoder.ts": "5cb1863763d1e9b458bc21d6f976f16d9c18b3b3f57eaf0ade120aee38fba227", + "https://deno.land/std@0.153.0/node/internal_binding/types.ts": "4c26fb74ba2e45de553c15014c916df6789529a93171e450d5afb016b4c765e7", + "https://deno.land/std@0.153.0/node/internal_binding/util.ts": "faf5146c3cc3b2d6c26026a818b4a16e91488ab26e63c069f36ba3c3ae24c97b", + "https://deno.land/std@0.153.0/node/internal_binding/uv.ts": "aa1db842936e77654522d9136bb2ae191bf334423f58962a8a7404b6635b5b49", + "https://deno.land/std@0.153.0/node/stream.ts": "d127faa074a9e3886e4a01dcfe9f9a6a4b5641f76f6acc356e8ded7da5dc2c81", + "https://deno.land/std@0.153.0/node/stream/promises.mjs": "b263c09f2d6bd715dc514fab3f99cca84f442e2d23e87adbe76e32ea46fc87e6", + "https://deno.land/std@0.153.0/node/string_decoder.ts": "51ce85a173d2e36ac580d418bb48b804adb41732fc8bd85f7d5d27b7accbc61f", + "https://deno.land/std@0.153.0/node/util.ts": "1bc9e881521b024818dc8727c746b54f835fe1b4c20ff049c5aa932f6c387593", + "https://deno.land/std@0.153.0/node/util/types.ts": "5948b43e834f73a4becf85b02049632560c65da9c1127e5c533c83d200d3dfcd", + "https://deno.land/std@0.153.0/streams/conversion.ts": "fc4eb76a14148c43f0b85e903a5a1526391aa40ed9434dc21e34f88304eb823e", + "https://deno.land/std@0.153.0/testing/_diff.ts": "141f978a283defc367eeee3ff7b58aa8763cf7c8e0c585132eae614468e9d7b8", + "https://deno.land/std@0.153.0/testing/_format.ts": "cd11136e1797791045e639e9f0f4640d5b4166148796cad37e6ef75f7d7f3832", + "https://deno.land/std@0.153.0/testing/asserts.ts": "d6595cfc330b4233546a047a0d7d57940771aa9d97a172ceb91e84ae6200b3af", + "https://deno.land/std@0.170.0/_util/asserts.ts": "d0844e9b62510f89ce1f9878b046f6a57bf88f208a10304aab50efcb48365272", + "https://deno.land/std@0.170.0/_util/os.ts": "8a33345f74990e627b9dfe2de9b040004b08ea5146c7c9e8fe9a29070d193934", + "https://deno.land/std@0.170.0/encoding/base64.ts": "8605e018e49211efc767686f6f687827d7f5fd5217163e981d8d693105640d7a", + "https://deno.land/std@0.170.0/fmt/colors.ts": "03ad95e543d2808bc43c17a3dd29d25b43d0f16287fe562a0be89bf632454a12", + "https://deno.land/std@0.170.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.170.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.170.0/path/_util.ts": "d16be2a16e1204b65f9d0dfc54a9bc472cafe5f4a190b3c8471ec2016ccd1677", + "https://deno.land/std@0.170.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.170.0/path/glob.ts": "81cc6c72be002cd546c7a22d1f263f82f63f37fe0035d9726aa96fc8f6e4afa1", + "https://deno.land/std@0.170.0/path/mod.ts": "cf7cec7ac11b7048bb66af8ae03513e66595c279c65cfa12bfc07d9599608b78", + "https://deno.land/std@0.170.0/path/posix.ts": "b859684bc4d80edfd4cad0a82371b50c716330bed51143d6dcdbe59e6278b30c", + "https://deno.land/std@0.170.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.170.0/path/win32.ts": "7cebd2bda6657371adc00061a1d23fdd87bcdf64b4843bb148b0b24c11b40f69", + "https://deno.land/std@0.177.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.177.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.177.0/bytes/index_of_needle.ts": "65c939607df609374c4415598fa4dad04a2f14c4d98cd15775216f0aaf597f24", + "https://deno.land/std@0.177.0/crypto/_wasm/lib/deno_std_wasm_crypto.generated.mjs": "5dedb7f9aa05f0e18ed017691c58df5f4686e4cbbd70368c6f896e5cca03f2b4", + "https://deno.land/std@0.177.0/crypto/_wasm/mod.ts": "e2df88236fc061eac7a89e8cb0b97843f5280b08b2a990e473b7397a3e566003", + "https://deno.land/std@0.177.0/crypto/timing_safe_equal.ts": "8d69ab611c67fe51b6127d97fcfb4d8e7d0e1b6b4f3e0cc4ab86744c3691f965", + "https://deno.land/std@0.177.0/encoding/base64.ts": "7de04c2f8aeeb41453b09b186480be90f2ff357613b988e99fabb91d2eeceba1", + "https://deno.land/std@0.177.0/encoding/base64url.ts": "3f1178f6446834457b16bfde8b559c1cd3481727fe384d3385e4a9995dc2d851", + "https://deno.land/std@0.177.0/encoding/hex.ts": "50f8c95b52eae24395d3dfcb5ec1ced37c5fe7610ef6fffdcc8b0fdc38e3b32f", + "https://deno.land/std@0.177.0/flags/mod.ts": "d1cdefa18472ef69858a17df5cf7c98445ed27ac10e1460183081303b0ebc270", + "https://deno.land/std@0.177.0/node/_core.ts": "9a58c0ef98ee77e9b8fcc405511d1b37a003a705eb6a9b6e95f75434d8009adc", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/base/buffer.js": "c9364c761681134015ec8ba6f33b39c067d6e5dd59860d55face8d5be8522744", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/base/node.js": "8f7f23bfa300990bbd6db7e7395e9688b54a04e3eb2fab5cab9a9a72e26c525f", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/base/reporter.js": "788aec7662991da549e5f7f3edbc3e3d6c6cecabc894b18d1a705b0f204e06c3", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/constants/der.js": "57181db0519bb3864a6cdf4e7eb9bfeb1bf5f80605187fbe80e27083b473e367", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/decoders/der.js": "fdc4de98c9b0b59db169a2b225895741e2ab34b00e14315ac2ff5e389d6db16e", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/decoders/pem.js": "fd7f0072c193c82959fec0374f4fd3adf3f4ac38594fd404d66b3e8724107151", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/encoders/der.js": "137bc4f8fe66b9950c743025e199789e25342f791e2d52353ceb016ad2854b42", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/encoders/pem.js": "e43bc706973c4c27e1e2f96262daba3d38822cb10f5b494f6944c726ee655160", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/asn1.js/mod.js": "1f88293688296be7a6c735bd8ea39425f5b274b94db1d6b7968dddfb54ac9d37", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/bn.js/bn.js": "f3f3c1dae1aa55de9e6472af1d6bec5ccda4b4890ee5c52a90961137fe99564e", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/aes.js": "698e1ed386b7dff27b2d59fa1c75f506beceec96b78670a15a734e438c08f138", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/auth_cipher.js": "5c245b5685b066356a7c9529a3a441bf5f57823a6946ce1b0ef2e1af32bb76f4", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/decrypter.js": "39152b2b3409893b8548feeab7e5997ceb1595f31df0dedaf765708be8f025c0", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/encrypter.js": "f9cc703d5a7b5255999c1a3600fbf48ff564b65f827744877526803093ceebff", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/ghash.js": "759d80b760f44cd3a454b4f161fd03a7d6c359901446f0a907a6870cb66d6767", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/incr32.js": "2bdea27b74b3990ee56807a1a5abe335f118826beabeeb905459c8768094b28f", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/mod.js": "fe4affebbd210d885b2e5135c668751f9d10bc14aa0cc3905cbfff66f04b4c58", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/cbc.js": "ff24b4506522a724ba7a03c1403ad8938aba45056f9fd47c7f0b4fcb3a640adf", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb.js": "643720a1db969b6bcc896c95523630838a8335513d02f340514fd524bb4113cb", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb1.js": "01c9a46aa3affd84a54ae33652fb0fa0ff7c862be2a459d9cb188cb8e2c4b11e", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/cfb8.js": "97476cee25103e02a02b196d7fe6f28a9f0f9e47ee344687d7492bc7282a59f8", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/ctr.js": "1e3835adb753cfe6761e4df8c43d190e31e1ca6a586fd582747c8255c82ed78d", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/ecb.js": "79677b96d4af50c49f0a4f698e5c7e5a64f1d2926b799e0d2eac2cdd5ec7488c", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/mod.js": "fe3db429b867a0a8066c64d7b33b840a1f24cad9174156384a763733f68cf518", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/modes/ofb.js": "3553308f98d078e2006eac39bb6d91818f8bb376b01d962ae98eabf6ee79ad4e", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/stream_cipher.js": "70f50f37ddec530ae95911ca2f286ebd2ddbd54d914ab0be461ec1dc3c61990f", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_aes/xor.ts": "7132baacdb39ba82c3bfe325a60e68ca87469c0ed0cdd0508caf6f40bab852b8", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/browserify_rsa.js": "96e0e4fee7c2cf75ef86d958c709bfc239297a080fd17ace5ea5ab699a1b6174", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/cipher_base.js": "9ebc6ccc364cf7b23024821054d2e72a2d8da8d8a2a36cacdc5aa6cc6770ef93", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/evp_bytes_to_key.ts": "7c4c27b6e321b2d7065a6703d90264921e9a805d91d9dfdb21103393228024e2", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/parse_asn1/asn1.js": "7d99b6df508164169a33377346e8840d519fe2defccb362a023c92c5bd503433", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/parse_asn1/certificate.js": "5795348417b3ec7aafa4854ba55f364e0148eadfdd29d1566c90e617237621bb", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/parse_asn1/fix_proc.js": "858dd3e6ce264d75822cadc21bb55114f4e4867a706abde1663548aa2710fc1b", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/parse_asn1/mod.js": "ea164fbd497ce3d710426742d4b72f71da8954c4ebaeb7eadc33316c5b0060f1", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/mgf.js": "dfac5008a550b3e7e6b851c4fb42e984aa9e7fae64707888f47f2aa0991c004d", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/mod.js": "0704326ff3ee2bb0764a964995d1aa62b1147b714ad5465e878ba4d57731e3db", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/private_decrypt.js": "8a1d11edb176d95d1e3bdf1aff5c3248a986bf9734d1a6b07508e29132d2f65c", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/public_encrypt.js": "f88b0e3c228d84096fdbc03e614e86bef86e56013cb9628b2425e31b3b142b2c", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/with_public.js": "752da754d253b5743d89c0f2432b6eb6f8815b80efd9ee588683e10a13d34400", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/public_encrypt/xor.js": "087ebef8f6fcb8ca4c7216cc22de728d9a61ec27b9a036b900681ff25d6409af", + "https://deno.land/std@0.177.0/node/_crypto/crypto_browserify/randombytes.ts": "23bde8be640e274d7bb88cf10d1da8bba252654252dc6a877fed86a77da5952c", + "https://deno.land/std@0.177.0/node/_events.mjs": "d4ba4e629abe3db9f1b14659fd5c282b7da8b2b95eaf13238eee4ebb142a2448", + "https://deno.land/std@0.177.0/node/_next_tick.ts": "9a3cf107d59b019a355d3cf32275b4c6157282e4b68ea85b46a799cb1d379305", + "https://deno.land/std@0.177.0/node/_process/exiting.ts": "6e336180aaabd1192bf99ffeb0d14b689116a3dec1dfb34a2afbacd6766e98ab", + "https://deno.land/std@0.177.0/node/_process/process.ts": "c96bb1f6253824c372f4866ee006dcefda02b7050d46759736e403f862d91051", + "https://deno.land/std@0.177.0/node/_process/stdio.mjs": "cf17727eac8da3a665851df700b5aca6a12bacc3ebbf33e63e4b919f80ba44a6", + "https://deno.land/std@0.177.0/node/_stream.mjs": "d6e2c86c1158ac65b4c2ca4fa019d7e84374ff12e21e2175345fe68c0823efe3", + "https://deno.land/std@0.177.0/node/_utils.ts": "7fd55872a0cf9275e3c080a60e2fa6d45b8de9e956ebcde9053e72a344185884", + "https://deno.land/std@0.177.0/node/buffer.ts": "85617be2063eccaf177dbb84c7580d1e32023724ed14bd9df4e453b152a26167", + "https://deno.land/std@0.177.0/node/crypto.ts": "2c94fa0f76e90190fbc34df891dc5c284bddb86c932fae8ac11747de3f75293c", + "https://deno.land/std@0.177.0/node/events.ts": "d2de352d509de11a375e2cb397d6b98f5fed4e562fc1d41be33214903a38e6b0", + "https://deno.land/std@0.177.0/node/internal/buffer.mjs": "e92303a3cc6d9aaabcd270a937ad9319825d9ba08cb332650944df4562029b27", + "https://deno.land/std@0.177.0/node/internal/crypto/_keys.ts": "8f3c3b5a141aa0331a53c205e9338655f1b3b307a08085fd6ff6dda6f7c4190b", + "https://deno.land/std@0.177.0/node/internal/crypto/_randomBytes.ts": "36dd164747f73b830ba86562abb160a8ac5bea34aaeb816a67f3005a00d41177", + "https://deno.land/std@0.177.0/node/internal/crypto/_randomFill.ts": "297186f290eba87a1ad7b8aa42a960ff4278a8b6b0c963fa81918c326d5c0b58", + "https://deno.land/std@0.177.0/node/internal/crypto/_randomInt.ts": "6cf19da9684b67520e67a2d99f2581a3f841140842c7ce2e014d166457550fe1", + "https://deno.land/std@0.177.0/node/internal/crypto/certificate.ts": "b4a6695f82e70a42e85247c74a7691ed4b3a904646451af0287e49efe1a28814", + "https://deno.land/std@0.177.0/node/internal/crypto/cipher.ts": "2bae9b4d94c465e4d1c70e5a9e8fd67ce20bcc66fecd2eec6be00d35144ca4eb", + "https://deno.land/std@0.177.0/node/internal/crypto/constants.ts": "544d605703053218499b08214f2e25cf4310651d535b7ab995891c4b7a217693", + "https://deno.land/std@0.177.0/node/internal/crypto/diffiehellman.ts": "9cfb219c5b2936db773f559b6affe6d25b0e40531010389f05df3f05ce7eebf5", + "https://deno.land/std@0.177.0/node/internal/crypto/hash.ts": "d01f5d3ad5477655b432036d2d553c7a0c31a901ac0e1e9e0d8b3975daae7624", + "https://deno.land/std@0.177.0/node/internal/crypto/hkdf.ts": "5bd801234e56468fbd47466f46e88bdadc66432d625e3616abe38878d410bb66", + "https://deno.land/std@0.177.0/node/internal/crypto/keygen.ts": "530cc1a00acf71a43719bb876a2dc563b6196095d080eba77c92c9f39658a5b9", + "https://deno.land/std@0.177.0/node/internal/crypto/keys.ts": "c4dfa5aa3420cf700178b87203593a0989c8a93934bfef2b29adb3399d687958", + "https://deno.land/std@0.177.0/node/internal/crypto/pbkdf2.ts": "0a0a3e0d3d45db0638fe75a4199c7ed7ca2164405750a520e786e4adebdb45a4", + "https://deno.land/std@0.177.0/node/internal/crypto/random.ts": "85f3147e14cb45c18e016da45d319a5c663309411232a956fdc09c2317acdd9f", + "https://deno.land/std@0.177.0/node/internal/crypto/scrypt.ts": "b55a0fcd12b295af4127d05b1c0bc3098b74fc0e3c62321c2a43c20f9ed18209", + "https://deno.land/std@0.177.0/node/internal/crypto/sig.ts": "25819a89d49c1ebfe3baa1f9464501ec599a36cf53e9b600ec0399e568b9dccc", + "https://deno.land/std@0.177.0/node/internal/crypto/types.ts": "52feb182bcbd59206f3e2f4a3cb8a5775d4452c2a8045c3e613e2178d32c2a86", + "https://deno.land/std@0.177.0/node/internal/crypto/util.ts": "db282c0413aeee28bc0665fcfc1c08a65fc96dc12ed4d03282f2da4907fcf0ce", + "https://deno.land/std@0.177.0/node/internal/crypto/x509.ts": "0e8a541c4f58ecb83862c373d3f7d2371aa8f5108f55bc837b190c4ab3408764", + "https://deno.land/std@0.177.0/node/internal/error_codes.ts": "8495e33f448a484518d76fa3d41d34fc20fe03c14b30130ad8e936b0035d4b8b", + "https://deno.land/std@0.177.0/node/internal/errors.ts": "1c699b8a3cb93174f697a348c004b1c6d576b66688eac8a48ebb78e65c720aae", + "https://deno.land/std@0.177.0/node/internal/fixed_queue.ts": "62bb119afa5b5ae8fc0c7048b50502347bec82e2588017d0b250c4671d6eff8f", + "https://deno.land/std@0.177.0/node/internal/hide_stack_frames.ts": "9dd1bad0a6e62a1042ce3a51eb1b1ecee2f246907bff44835f86e8f021de679a", + "https://deno.land/std@0.177.0/node/internal/normalize_encoding.mjs": "fd1d9df61c44d7196432f6e8244621468715131d18cc79cd299fc78ac549f707", + "https://deno.land/std@0.177.0/node/internal/options.ts": "888f267c3fe8f18dc7b2f2fbdbe7e4a0fd3302ff3e99f5d6645601e924f3e3fb", + "https://deno.land/std@0.177.0/node/internal/primordials.mjs": "a72d86b5aa55d3d50b8e916b6a59b7cc0dc5a31da8937114b4a113ad5aa08c74", + "https://deno.land/std@0.177.0/node/internal/streams/destroy.mjs": "b665fc71178919a34ddeac8389d162a81b4bc693ff7dc2557fa41b3a91011967", + "https://deno.land/std@0.177.0/node/internal/streams/end-of-stream.mjs": "a4fb1c2e32d58dff440d4e716e2c4daaa403b3095304a028bb428575cfeed716", + "https://deno.land/std@0.177.0/node/internal/streams/utils.mjs": "f2fe2e6bdc506da24c758970890cc2a21642045b129dee618bd3827c60dd9e33", + "https://deno.land/std@0.177.0/node/internal/streams/writable.mjs": "775928726d0483ace8e45a35f30db2019a22dd7b9a81b67b158420e21cc692c5", + "https://deno.land/std@0.177.0/node/internal/util.mjs": "f7fe2e1ca5e66f550ad0856b9f5ee4d666f0c071fe212ea7fc7f37cfa81f97a5", + "https://deno.land/std@0.177.0/node/internal/util/inspect.mjs": "11d7c9cab514b8e485acc3978c74b837263ff9c08ae4537fa18ad56bae633259", + "https://deno.land/std@0.177.0/node/internal/util/types.ts": "0e587b44ec5e017cf228589fc5ce9983b75beece6c39409c34170cfad49d6417", + "https://deno.land/std@0.177.0/node/internal/validators.mjs": "e02f2b02dd072a5d623970292588d541204dc82207b4c58985d933a5f4b382e6", + "https://deno.land/std@0.177.0/node/internal_binding/_libuv_winerror.ts": "30c9569603d4b97a1f1a034d88a3f74800d5ea1f12fcc3d225c9899d4e1a518b", + "https://deno.land/std@0.177.0/node/internal_binding/_node.ts": "cb2389b0eab121df99853eb6a5e3a684e4537e065fb8bf2cca0cbf219ce4e32e", + "https://deno.land/std@0.177.0/node/internal_binding/_timingSafeEqual.ts": "7d9732464d3c669ff07713868ce5d25bc974a06112edbfb5f017fc3c70c0853e", + "https://deno.land/std@0.177.0/node/internal_binding/_utils.ts": "7c58a2fbb031a204dee9583ba211cf9c67922112fe77e7f0b3226112469e9fe1", + "https://deno.land/std@0.177.0/node/internal_binding/_winerror.ts": "3e8cfdfe22e89f13d2b28529bab35155e6b1730c0221ec5a6fc7077dc037be13", + "https://deno.land/std@0.177.0/node/internal_binding/buffer.ts": "31729e0537921d6c730ad0afea44a7e8a0a1044d070ade8368226cb6f7390c8b", + "https://deno.land/std@0.177.0/node/internal_binding/constants.ts": "21ff9d1ee71d0a2086541083a7711842fc6ae25e264dbf45c73815aadce06f4c", + "https://deno.land/std@0.177.0/node/internal_binding/crypto.ts": "29e8f94f283a2e7d4229d3551369c6a40c2af9737fad948cb9be56bef6c468cd", + "https://deno.land/std@0.177.0/node/internal_binding/node_options.ts": "0b5cb0bf4379a39278d7b7bb6bb2c2751baf428fe437abe5ed3e8441fae1f18b", + "https://deno.land/std@0.177.0/node/internal_binding/string_decoder.ts": "54c3c1cbd5a9254881be58bf22637965dc69535483014dab60487e299cb95445", + "https://deno.land/std@0.177.0/node/internal_binding/types.ts": "2187595a58d2cf0134f4db6cc2a12bf777f452f52b15b6c3aed73fa072aa5fc3", + "https://deno.land/std@0.177.0/node/internal_binding/util.ts": "808ff3b92740284184ab824adfc420e75398c88c8bccf5111f0c24ac18c48f10", + "https://deno.land/std@0.177.0/node/internal_binding/uv.ts": "eb0048e30af4db407fb3f95563e30d70efd6187051c033713b0a5b768593a3a3", + "https://deno.land/std@0.177.0/node/stream.ts": "09e348302af40dcc7dc58aa5e40fdff868d11d8d6b0cfb85cbb9c75b9fe450c7", + "https://deno.land/std@0.177.0/node/string_decoder.ts": "1a17e3572037c512cc5fc4b29076613e90f225474362d18da908cb7e5ccb7e88", "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", "https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.181.0/bytes/bytes_list.ts": "b4cbdfd2c263a13e8a904b12d082f6177ea97d9297274a4be134e989450dfa6a", + "https://deno.land/std@0.181.0/bytes/concat.ts": "d26d6f3d7922e6d663dacfcd357563b7bf4a380ce5b9c2bbe0c8586662f25ce2", + "https://deno.land/std@0.181.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", + "https://deno.land/std@0.181.0/bytes/ends_with.ts": "4228811ebc71615d27f065c54b5e815ec1972538772b0f413c0efe05245b472e", + "https://deno.land/std@0.181.0/bytes/equals.ts": "b87494ce5442dc786db46f91378100028c402f83a14a2f7bbff6bda7810aefe3", + "https://deno.land/std@0.181.0/bytes/includes_needle.ts": "76a8163126fb2f8bf86fd7f22192c3bb04bf6a20b987a095127c2ca08adf3ba6", + "https://deno.land/std@0.181.0/bytes/index_of_needle.ts": "65c939607df609374c4415598fa4dad04a2f14c4d98cd15775216f0aaf597f24", + "https://deno.land/std@0.181.0/bytes/last_index_of_needle.ts": "7181072883cb4908c6ce8f7a5bb1d96787eef2c2ab3aa94fe4268ab326a53cbf", + "https://deno.land/std@0.181.0/bytes/mod.ts": "e869bba1e7a2e3a9cc6c2d55471888429a544e70a840c087672e656e7ba21815", + "https://deno.land/std@0.181.0/bytes/repeat.ts": "6f5e490d8d72bcbf8d84a6bb04690b9b3eb5822c5a11687bca73a2318a842294", + "https://deno.land/std@0.181.0/bytes/starts_with.ts": "3e607a70c9c09f5140b7a7f17a695221abcc7244d20af3eb47ccbb63f5885135", + "https://deno.land/std@0.181.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", "https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", "https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", "https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", @@ -135,6 +567,9 @@ "https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", "https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", "https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.181.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.181.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.181.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", "https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", "https://deno.land/std@0.182.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", "https://deno.land/std@0.182.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", @@ -154,6 +589,13 @@ "https://deno.land/std@0.192.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", "https://deno.land/std@0.192.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", "https://deno.land/std@0.192.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", + "https://deno.land/std@0.192.0/collections/_utils.ts": "5114abc026ddef71207a79609b984614e66a63a4bda17d819d56b0e72c51527e", + "https://deno.land/std@0.192.0/collections/deep_merge.ts": "5a8ed29030f4471a5272785c57c3455fa79697b9a8f306013a8feae12bafc99a", + "https://deno.land/std@0.192.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/std@0.192.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", + "https://deno.land/std@0.192.0/fs/copy.ts": "14214efd94fc3aa6db1e4af2b4b9578e50f7362b7f3725d5a14ad259a5df26c8", + "https://deno.land/std@0.192.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", + "https://deno.land/std@0.192.0/fs/exists.ts": "29c26bca8584a22876be7cb8844f1b6c8fc35e9af514576b78f5c6884d7ed02d", "https://deno.land/std@0.192.0/io/buffer.ts": "17f4410eaaa60a8a85733e8891349a619eadfbbe42e2f319283ce2b8f29723ab", "https://deno.land/std@0.192.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", "https://deno.land/std@0.192.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", @@ -164,6 +606,95 @@ "https://deno.land/std@0.192.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", "https://deno.land/std@0.192.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", "https://deno.land/std@0.192.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.192.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.192.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.192.0/testing/_test_suite.ts": "30f018feeb3835f12ab198d8a518f9089b1bcb2e8c838a8b615ab10d5005465c", + "https://deno.land/std@0.192.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", + "https://deno.land/std@0.192.0/testing/bdd.ts": "59f7f7503066d66a12e50ace81bfffae5b735b6be1208f5684b630ae6b4de1d0", + "https://deno.land/std@0.192.0/testing/mock.ts": "220ed9b8151cb2cac141043d4cfea7c47673fab5d18d1c1f0943297c8afb5d13", + "https://deno.land/std@0.195.0/encoding/base64.ts": "144ae6234c1fbe5b68666c711dc15b1e9ee2aef6d42b3b4345bf9a6c91d70d0d", + "https://deno.land/std@0.50.0/path/_constants.ts": "f6c332625f21d49d5a69414ba0956ac784dbf4b26a278041308e4914ba1c7e2e", + "https://deno.land/std@0.50.0/path/_util.ts": "b678a7ecbac6b04c1166832ae54e1024c0431dd2b340b013c46eb2956ab24d4c", + "https://deno.land/std@0.50.0/path/interface.ts": "89f6e68b0e3bba1401a740c8d688290957de028ed86f95eafe76fe93790ae450", + "https://deno.land/std@0.50.0/path/posix.ts": "b742fe902d5d6821c39c02319eb32fc5a92b4d4424b533c47f1a50610afbf381", + "https://deno.land/x/cliffy@v0.25.7/_utils/distance.ts": "02af166952c7c358ac83beae397aa2fbca4ad630aecfcd38d92edb1ea429f004", + "https://deno.land/x/cliffy@v0.25.7/ansi/ansi_escapes.ts": "885f61f343223f27b8ec69cc138a54bea30542924eacd0f290cd84edcf691387", + "https://deno.land/x/cliffy@v0.25.7/ansi/chain.ts": "31fb9fcbf72fed9f3eb9b9487270d2042ccd46a612d07dd5271b1a80ae2140a0", + "https://deno.land/x/cliffy@v0.25.7/ansi/colors.ts": "5f71993af5bd1aa0a795b15f41692d556d7c89584a601fed75997df844b832c9", + "https://deno.land/x/cliffy@v0.25.7/ansi/cursor_position.ts": "d537491e31d9c254b208277448eff92ff7f55978c4928dea363df92c0df0813f", + "https://deno.land/x/cliffy@v0.25.7/ansi/deps.ts": "0f35cb7e91868ce81561f6a77426ea8bc55dc15e13f84c7352f211023af79053", + "https://deno.land/x/cliffy@v0.25.7/ansi/tty.ts": "8fb064c17ead6cdf00c2d3bc87a9fd17b1167f2daa575c42b516f38bdb604673", + "https://deno.land/x/cliffy@v0.25.7/command/_errors.ts": "a9bd23dc816b32ec96c9b8f3057218241778d8c40333b43341138191450965e5", + "https://deno.land/x/cliffy@v0.25.7/command/_utils.ts": "9ab3d69fabab6c335b881b8a5229cbd5db0c68f630a1c307aff988b6396d9baf", + "https://deno.land/x/cliffy@v0.25.7/command/command.ts": "a2b83c612acd65c69116f70dec872f6da383699b83874b70fcf38cddf790443f", + "https://deno.land/x/cliffy@v0.25.7/command/completions/_bash_completions_generator.ts": "43b4abb543d4dc60233620d51e69d82d3b7c44e274e723681e0dce2a124f69f9", + "https://deno.land/x/cliffy@v0.25.7/command/completions/_fish_completions_generator.ts": "d0289985f5cf0bd288c05273bfa286b24c27feb40822eb7fd9d7fee64e6580e8", + "https://deno.land/x/cliffy@v0.25.7/command/completions/_zsh_completions_generator.ts": "14461eb274954fea4953ee75938821f721da7da607dc49bcc7db1e3f33a207bd", + "https://deno.land/x/cliffy@v0.25.7/command/completions/bash.ts": "053aa2006ec327ccecacb00ba28e5eb836300e5c1bec1b3cfaee9ddcf8189756", + "https://deno.land/x/cliffy@v0.25.7/command/completions/complete.ts": "58df61caa5e6220ff2768636a69337923ad9d4b8c1932aeb27165081c4d07d8b", + "https://deno.land/x/cliffy@v0.25.7/command/completions/fish.ts": "9938beaa6458c6cf9e2eeda46a09e8cd362d4f8c6c9efe87d3cd8ca7477402a5", + "https://deno.land/x/cliffy@v0.25.7/command/completions/mod.ts": "aeef7ec8e319bb157c39a4bab8030c9fe8fa327b4c1e94c9c1025077b45b40c0", + "https://deno.land/x/cliffy@v0.25.7/command/completions/zsh.ts": "8b04ab244a0b582f7927d405e17b38602428eeb347a9968a657e7ea9f40e721a", + "https://deno.land/x/cliffy@v0.25.7/command/deprecated.ts": "bbe6670f1d645b773d04b725b8b8e7814c862c9f1afba460c4d599ffe9d4983c", + "https://deno.land/x/cliffy@v0.25.7/command/deps.ts": "275b964ce173770bae65f6b8ebe9d2fd557dc10292cdd1ed3db1735f0d77fa1d", + "https://deno.land/x/cliffy@v0.25.7/command/help/_help_generator.ts": "f7c349cb2ddb737e70dc1f89bcb1943ca9017a53506be0d4138e0aadb9970a49", + "https://deno.land/x/cliffy@v0.25.7/command/help/mod.ts": "09d74d3eb42d21285407cda688074c29595d9c927b69aedf9d05ff3f215820d3", + "https://deno.land/x/cliffy@v0.25.7/command/mod.ts": "d0a32df6b14028e43bb2d41fa87d24bc00f9662a44e5a177b3db02f93e473209", + "https://deno.land/x/cliffy@v0.25.7/command/type.ts": "24e88e3085e1574662b856ccce70d589959648817135d4469fab67b9cce1b364", + "https://deno.land/x/cliffy@v0.25.7/command/types.ts": "ae02eec0ed7a769f7dba2dd5d3a931a61724b3021271b1b565cf189d9adfd4a0", + "https://deno.land/x/cliffy@v0.25.7/command/types/action_list.ts": "33c98d449617c7a563a535c9ceb3741bde9f6363353fd492f90a74570c611c27", + "https://deno.land/x/cliffy@v0.25.7/command/types/boolean.ts": "3879ec16092b4b5b1a0acb8675f8c9250c0b8a972e1e4c7adfba8335bd2263ed", + "https://deno.land/x/cliffy@v0.25.7/command/types/child_command.ts": "f1fca390c7fbfa7a713ca15ef55c2c7656bcbb394d50e8ef54085bdf6dc22559", + "https://deno.land/x/cliffy@v0.25.7/command/types/command.ts": "325d0382e383b725fd8d0ef34ebaeae082c5b76a1f6f2e843fee5dbb1a4fe3ac", + "https://deno.land/x/cliffy@v0.25.7/command/types/enum.ts": "2178345972adf7129a47e5f02856ca3e6852a91442a1c78307dffb8a6a3c6c9f", + "https://deno.land/x/cliffy@v0.25.7/command/types/file.ts": "8618f16ac9015c8589cbd946b3de1988cc4899b90ea251f3325c93c46745140e", + "https://deno.land/x/cliffy@v0.25.7/command/types/integer.ts": "29864725fd48738579d18123d7ee78fed37515e6dc62146c7544c98a82f1778d", + "https://deno.land/x/cliffy@v0.25.7/command/types/number.ts": "aeba96e6f470309317a16b308c82e0e4138a830ec79c9877e4622c682012bc1f", + "https://deno.land/x/cliffy@v0.25.7/command/types/string.ts": "e4dadb08a11795474871c7967beab954593813bb53d9f69ea5f9b734e43dc0e0", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/mod.ts": "17e2df3b620905583256684415e6c4a31e8de5c59066eb6d6c9c133919292dc4", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/provider.ts": "d6fb846043232cbd23c57d257100c7fc92274984d75a5fead0f3e4266dc76ab8", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/provider/deno_land.ts": "24f8d82e38c51e09be989f30f8ad21f9dd41ac1bb1973b443a13883e8ba06d6d", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/provider/github.ts": "99e1b133dd446c6aa79f69e69c46eb8bc1c968dd331c2a7d4064514a317c7b59", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/provider/nest_land.ts": "0e07936cea04fa41ac9297f32d87f39152ea873970c54cb5b4934b12fee1885e", + "https://deno.land/x/cliffy@v0.25.7/command/upgrade/upgrade_command.ts": "3640a287d914190241ea1e636774b1b4b0e1828fa75119971dd5304784061e05", + "https://deno.land/x/cliffy@v0.25.7/flags/_errors.ts": "f1fbb6bfa009e7950508c9d491cfb4a5551027d9f453389606adb3f2327d048f", + "https://deno.land/x/cliffy@v0.25.7/flags/_utils.ts": "340d3ecab43cde9489187e1f176504d2c58485df6652d1cdd907c0e9c3ce4cc2", + "https://deno.land/x/cliffy@v0.25.7/flags/_validate_flags.ts": "16eb5837986c6f6f7620817820161a78d66ce92d690e3697068726bbef067452", + "https://deno.land/x/cliffy@v0.25.7/flags/deprecated.ts": "a72a35de3cc7314e5ebea605ca23d08385b218ef171c32a3f135fb4318b08126", + "https://deno.land/x/cliffy@v0.25.7/flags/flags.ts": "68a9dfcacc4983a84c07ba19b66e5e9fccd04389fad215210c60fb414cc62576", + "https://deno.land/x/cliffy@v0.25.7/flags/types.ts": "7452ea5296758fb7af89930349ce40d8eb9a43b24b3f5759283e1cb5113075fd", + "https://deno.land/x/cliffy@v0.25.7/flags/types/boolean.ts": "4c026dd66ec9c5436860dc6d0241427bdb8d8e07337ad71b33c08193428a2236", + "https://deno.land/x/cliffy@v0.25.7/flags/types/integer.ts": "b60d4d590f309ddddf066782d43e4dc3799f0e7d08e5ede7dc62a5ee94b9a6d9", + "https://deno.land/x/cliffy@v0.25.7/flags/types/number.ts": "610936e2d29de7c8c304b65489a75ebae17b005c6122c24e791fbed12444d51e", + "https://deno.land/x/cliffy@v0.25.7/flags/types/string.ts": "e89b6a5ce322f65a894edecdc48b44956ec246a1d881f03e97bbda90dd8638c5", + "https://deno.land/x/cliffy@v0.25.7/keycode/key_code.ts": "c4ab0ffd102c2534962b765ded6d8d254631821bf568143d9352c1cdcf7a24be", + "https://deno.land/x/cliffy@v0.25.7/keycode/key_codes.ts": "917f0a2da0dbace08cf29bcfdaaa2257da9fe7e705fff8867d86ed69dfb08cfe", + "https://deno.land/x/cliffy@v0.25.7/keycode/mod.ts": "292d2f295316c6e0da6955042a7b31ab2968ff09f2300541d00f05ed6c2aa2d4", + "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_input.ts": "737cff2de02c8ce35250f5dd79c67b5fc176423191a2abd1f471a90dd725659e", + "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_list.ts": "79b301bf09eb19f0d070d897f613f78d4e9f93100d7e9a26349ef0bfaa7408d2", + "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_prompt.ts": "8630ce89a66d83e695922df41721cada52900b515385d86def597dea35971bb2", + "https://deno.land/x/cliffy@v0.25.7/prompt/_generic_suggestions.ts": "2a8b619f91e8f9a270811eff557f10f1343a444a527b5fc22c94de832939920c", + "https://deno.land/x/cliffy@v0.25.7/prompt/_utils.ts": "676cca30762656ed1a9bcb21a7254244278a23ffc591750e98a501644b6d2df3", + "https://deno.land/x/cliffy@v0.25.7/prompt/checkbox.ts": "e5a5a9adbb86835dffa2afbd23c6f7a8fe25a9d166485388ef25aba5dc3fbf9e", + "https://deno.land/x/cliffy@v0.25.7/prompt/confirm.ts": "94c8e55de3bbcd53732804420935c432eab29945497d1c47c357d236a89cb5f6", + "https://deno.land/x/cliffy@v0.25.7/prompt/deps.ts": "4c38ab18e55a792c9a136c1c29b2b6e21ea4820c45de7ef4cf517ce94012c57d", + "https://deno.land/x/cliffy@v0.25.7/prompt/figures.ts": "26af0fbfe21497220e4b887bb550fab997498cde14703b98e78faf370fbb4b94", + "https://deno.land/x/cliffy@v0.25.7/prompt/input.ts": "ee45532e0a30c2463e436e08ae291d79d1c2c40872e17364c96d2b97c279bf4d", + "https://deno.land/x/cliffy@v0.25.7/prompt/list.ts": "6780427ff2a932a48c9b882d173c64802081d6cdce9ff618d66ba6504b6abc50", + "https://deno.land/x/cliffy@v0.25.7/prompt/mod.ts": "195aed14d10d279914eaa28c696dec404d576ca424c097a5bc2b4a7a13b66c89", + "https://deno.land/x/cliffy@v0.25.7/prompt/number.ts": "015305a76b50138234dde4fd50eb886c6c7c0baa1b314caf811484644acdc2cf", + "https://deno.land/x/cliffy@v0.25.7/prompt/prompt.ts": "0e7f6a1d43475ee33fb25f7d50749b2f07fc0bcddd9579f3f9af12d05b4a4412", + "https://deno.land/x/cliffy@v0.25.7/prompt/secret.ts": "58745f5231fb2c44294c4acf2511f8c5bfddfa1e12f259580ff90dedea2703d6", + "https://deno.land/x/cliffy@v0.25.7/prompt/select.ts": "1e982eae85718e4e15a3ee10a5ae2233e532d7977d55888f3a309e8e3982b784", + "https://deno.land/x/cliffy@v0.25.7/prompt/toggle.ts": "842c3754a40732f2e80bcd4670098713e402e64bd930e6cab2b787f7ad4d931a", + "https://deno.land/x/cliffy@v0.25.7/table/border.ts": "2514abae4e4f51eda60a5f8c927ba24efd464a590027e900926b38f68e01253c", + "https://deno.land/x/cliffy@v0.25.7/table/cell.ts": "1d787d8006ac8302020d18ec39f8d7f1113612c20801b973e3839de9c3f8b7b3", + "https://deno.land/x/cliffy@v0.25.7/table/deps.ts": "5b05fa56c1a5e2af34f2103fd199e5f87f0507549963019563eae519271819d2", + "https://deno.land/x/cliffy@v0.25.7/table/layout.ts": "46bf10ae5430cf4fbb92f23d588230e9c6336edbdb154e5c9581290562b169f4", + "https://deno.land/x/cliffy@v0.25.7/table/mod.ts": "e74f69f38810ee6139a71132783765feb94436a6619c07474ada45b465189834", + "https://deno.land/x/cliffy@v0.25.7/table/row.ts": "5f519ba7488d2ef76cbbf50527f10f7957bfd668ce5b9169abbc44ec88302645", + "https://deno.land/x/cliffy@v0.25.7/table/table.ts": "ec204c9d08bb3ff1939c5ac7412a4c9ed7d00925d4fc92aff9bfe07bd269258d", + "https://deno.land/x/cliffy@v0.25.7/table/utils.ts": "187bb7dcbcfb16199a5d906113f584740901dfca1007400cba0df7dcd341bc29", "https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5", "https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff", "https://deno.land/x/deno_cache@0.4.1/auth_tokens.ts": "5fee7e9155e78cedf3f6ff3efacffdb76ac1a76c86978658d9066d4fb0f7326e", @@ -176,6 +707,7 @@ "https://deno.land/x/deno_cache@0.4.1/http_cache.ts": "f632e0d6ec4a5d61ae3987737a72caf5fcdb93670d21032ddb78df41131360cd", "https://deno.land/x/deno_cache@0.4.1/mod.ts": "ef1cda9235a93b89cb175fe648372fc0f785add2a43aa29126567a05e3e36195", "https://deno.land/x/deno_cache@0.4.1/util.ts": "8cb686526f4be5205b92c819ca2ce82220aa0a8dd3613ef0913f6dc269dbbcfe", + "https://deno.land/x/dir@1.5.1/home_dir/mod.ts": "53777e4fb2586ae02ce94adf2c99f2edb2dcf6e72d07ac289b71593cfacbdbbf", "https://deno.land/x/dnt@0.36.0/lib/compiler.ts": "209ad2e1b294f93f87ec02ade9a0821f942d2e524104552d0aa8ff87021050a5", "https://deno.land/x/dnt@0.36.0/lib/compiler_transforms.ts": "cbb1fd5948f5ced1aa5c5aed9e45134e2357ce1e7220924c1d7bded30dcd0dd0", "https://deno.land/x/dnt@0.36.0/lib/mod.deps.ts": "30367fc68bcd2acf3b7020cf5cdd26f817f7ac9ac35c4bfb6c4551475f91bc3e", @@ -191,11 +723,259 @@ "https://deno.land/x/dnt@0.36.0/lib/utils.ts": "878b7ac7003a10c16e6061aa49dbef9b42bd43174853ebffc9b67ea47eeb11d8", "https://deno.land/x/dnt@0.36.0/mod.ts": "670f1820f2115e6b6aa4f79999bc796e30cc0d0b45096b84a4e1db9f62b82984", "https://deno.land/x/dnt@0.36.0/transform.ts": "1b127c5f22699c8ab2545b98aeca38c4e5c21405b0f5342ea17e9c46280ed277", + "https://deno.land/x/mock_file@v1.1.2/mod.ts": "57b111ba84b5611c09ed82ef300dd063eb278ef68bd286d5149e5b018eb8948d", + "https://deno.land/x/mock_file@v1.1.2/src/memory_file.ts": "24817e782c819cdfb48b9459dc8ad568e8fb2cd2934cd5b775688147e6dc4cbd", + "https://deno.land/x/mock_file@v1.1.2/src/polyfill.ts": "f10f05ec2493cb1e029b30cd211a21803b7683d811813d519696aa2939529b35", "https://deno.land/x/ts_morph@18.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9", "https://deno.land/x/ts_morph@18.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06", "https://deno.land/x/ts_morph@18.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d", "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed", "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700", - "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59" + "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59", + "https://esm.sh/ansi-escapes@6.2.0": "508d1d1d8f44b52c45e9c701cd5a78c56d7764a14d005d5328f0cff72b0291b4", + "https://esm.sh/v124/*acorn-loose@8.4.0": "5255c5344625c52612c421cb99b66d401af8772342a5de8bac38d1d78d0f94b4", + "https://esm.sh/v124/*log-update@5.0.1": "49199324effae77a660f21ea75937847315fdb5f67a86881496717314bb95b2a", + "https://esm.sh/v124/@aws-crypto/crc32@3.0.0/denonext/crc32.mjs": "28103a74b87c49846c0f2851adc7d6ca8f8d677f079819cd786d8f9b0af5e08e", + "https://esm.sh/v124/@aws-crypto/crc32c@3.0.0/denonext/crc32c.mjs": "d36a9fdaecbae336cfbf55cbce7e947b0da04ce5a0a04cd9320f59b2631d6684", + "https://esm.sh/v124/@aws-crypto/ie11-detection@3.0.0/denonext/ie11-detection.mjs": "077960aa8a6a4c99c943bdc0d929e5b0b2da81b4b873f09d843f76af9647c24e", + "https://esm.sh/v124/@aws-crypto/sha1-browser@3.0.0/denonext/sha1-browser.mjs": "6898ad925393fab02c3ec2ae0dde86235f6cfa0bbac5c819413b210006a2b2cf", + "https://esm.sh/v124/@aws-crypto/sha256-browser@3.0.0/denonext/sha256-browser.mjs": "22f2c022fcf4e406bfc53d97c7433602c477668d03161bf9a565a59aeef3443a", + "https://esm.sh/v124/@aws-crypto/sha256-js@3.0.0/denonext/sha256-js.mjs": "4561a232d7d8be18ba02da23d55861945c8362bddeb69706f764c8cfb9b3cbe8", + "https://esm.sh/v124/@aws-crypto/supports-web-crypto@3.0.0/denonext/supports-web-crypto.mjs": "ef0309ac7a602ef50e8ff4a8aa1d5d4b49b160c3457ddb921a4b7ece5aaf7ba0", + "https://esm.sh/v124/@aws-crypto/util@3.0.0/denonext/util.mjs": "ffe9b389f26641a28adc535dd76b8303d8a40c902cc81a2ab6cf1ba588a40b24", + "https://esm.sh/v124/@aws-sdk/client-s3@3.427.0": "b4e0532b663209f075a8c96ccea6af3986fce3f10f7acad1349bfffb42410279", + "https://esm.sh/v124/@aws-sdk/client-s3@3.427.0/denonext/client-s3.mjs": "a6367661c0f0c80b8452ecabfaecd4fdeba6032508b36f41c163dda9818139dc", + "https://esm.sh/v124/@aws-sdk/middleware-expect-continue@3.425.0/denonext/middleware-expect-continue.mjs": "7041dbda8d385dc7d6c363bf8560f2c52d2b451a530f25d4ce8dd4c5b2ec7aab", + "https://esm.sh/v124/@aws-sdk/middleware-flexible-checksums@3.425.0/denonext/middleware-flexible-checksums.mjs": "f95dcd79e93535e43e085daafe2c4e30a3af87b8204e2f52eff2a4e8a39a9282", + "https://esm.sh/v124/@aws-sdk/middleware-host-header@3.425.0/denonext/middleware-host-header.mjs": "af9a8d612b8db2fcb29a37de21f833e254a2bc1ed472d8db78e822cd8f8583a4", + "https://esm.sh/v124/@aws-sdk/middleware-location-constraint@3.425.0/denonext/middleware-location-constraint.mjs": "46832c0b072cc9ac9cbc3926bdf6709d314edb1b1e095dbab54f41851c0cde69", + "https://esm.sh/v124/@aws-sdk/middleware-logger@3.425.0/denonext/middleware-logger.mjs": "141b05d0045771c1755cc9f41af8d44c21c6226e120e5bdacc93ccc01e7c418e", + "https://esm.sh/v124/@aws-sdk/middleware-recursion-detection@3.425.0/denonext/middleware-recursion-detection.mjs": "b563f88e4a6d27e68eef876366b86f2f44dcc199a5c24efbefe4292d17128178", + "https://esm.sh/v124/@aws-sdk/middleware-sdk-s3@3.427.0/denonext/middleware-sdk-s3.mjs": "50b5f10777353dcb3f82c896bbdb93f854ced9ff05786c83b0973cc9db1e36c5", + "https://esm.sh/v124/@aws-sdk/middleware-signing@3.425.0/denonext/middleware-signing.mjs": "37e17e4988d30c94f18b54ced816129b4ee4b958847f1821efa185dce2a2db94", + "https://esm.sh/v124/@aws-sdk/middleware-ssec@3.425.0/denonext/middleware-ssec.mjs": "6d97aaeaa11ffb69ed190e793545e00c08d12593163250ea84c59dd490f99730", + "https://esm.sh/v124/@aws-sdk/middleware-user-agent@3.427.0/denonext/middleware-user-agent.mjs": "d41c9562c6552fa820cefc8b9bfe5359c448e89e5ffa4efcfeb80a1822232fba", + "https://esm.sh/v124/@aws-sdk/region-config-resolver@3.425.0/denonext/region-config-resolver.mjs": "688335a898a96baad29a75b9f20ec587f736435f65e762fadb85a9d057c51de1", + "https://esm.sh/v124/@aws-sdk/signature-v4-multi-region@3.425.0/denonext/signature-v4-multi-region.mjs": "4d1894990271ca40ae8d6c5caf1ae76ef3bc14aafec1ea9e51d47eaa72340ba5", + "https://esm.sh/v124/@aws-sdk/types@3.425.0/denonext/types.mjs": "7d973fb48fb70de149d7f7a87e2f31f24bb653b7fe07f0a1cebd9f6061ad1d8f", + "https://esm.sh/v124/@aws-sdk/util-arn-parser@3.310.0/denonext/util-arn-parser.mjs": "da6927c63827861d70a20f1581d399fd5510ebb311f6ba23bb4f41ee6cb13ee4", + "https://esm.sh/v124/@aws-sdk/util-endpoints@3.427.0/denonext/util-endpoints.mjs": "094949955e2ee26d54221c52b97ede2c717a09d07d26942ec812d5d2ef8a6e8f", + "https://esm.sh/v124/@aws-sdk/util-locate-window@3.310.0/denonext/util-locate-window.mjs": "f603c22f24f63bc910225cedf716e3fa9cd860a5b84db32ed70e06f77e2f84f0", + "https://esm.sh/v124/@aws-sdk/util-user-agent-browser@3.425.0/denonext/util-user-agent-browser.mjs": "febd0be98b4bd07cd13d8bf6394579aa5970b2bbadc433f6b8da75f94aac4c2f", + "https://esm.sh/v124/@aws-sdk/util-utf8-browser@3.259.0/denonext/util-utf8-browser.mjs": "79fc8ce5cd61204fe274363d637902a5d49ea40688e8d40cbd5b6ecf56f782b7", + "https://esm.sh/v124/@aws-sdk/xml-builder@3.310.0/denonext/xml-builder.mjs": "ed2644fee6c25c3859dd2f4300d6bfe3cfad645ca6b2a41e2b932eae575ebcea", + "https://esm.sh/v124/@colors/colors@1.5.0/denonext/safe.js": "0ac89c10d0d3772a939e427ec2ec8d5c98a2ea06f3e37dfbf73a34f22789d9bc", + "https://esm.sh/v124/@dabh/diagnostics@2.0.3/denonext/diagnostics.mjs": "5dc113c079ceab4bf26f73d838462de298f2ffaf74fd14309ed1f8afb208c2af", + "https://esm.sh/v124/@smithy/chunked-blob-reader@2.0.0/denonext/chunked-blob-reader.mjs": "0504bd4f11f64e54235e13527a47f22c67abef5d50e05a1e0697e36139451121", + "https://esm.sh/v124/@smithy/config-resolver@2.0.14/denonext/config-resolver.mjs": "b0d4e4ad0cef2455fe87854ea6cc9c687433278954aceb2dcd20f8ccc3b1c93a", + "https://esm.sh/v124/@smithy/eventstream-codec@2.0.11/denonext/eventstream-codec.mjs": "4a3071396a643d805add482d66d44b452347f346989be1c5a6738bec3e0896e1", + "https://esm.sh/v124/@smithy/eventstream-serde-browser@2.0.11/denonext/eventstream-serde-browser.mjs": "d98d5bf7b3ccaaea876f0da994648ee764f70c9f1dabdca35f37a0e379cccba4", + "https://esm.sh/v124/@smithy/eventstream-serde-config-resolver@2.0.11/denonext/eventstream-serde-config-resolver.mjs": "d0217652cce1e433e0ab68cb19149ff40c6eb33b0fe058b126c3fb686bf83020", + "https://esm.sh/v124/@smithy/eventstream-serde-universal@2.0.11/denonext/eventstream-serde-universal.mjs": "c71f97e7d2523e44b290808ffe08dd42f83eadfd065c537ffb9f262bf100f4c2", + "https://esm.sh/v124/@smithy/fetch-http-handler@2.2.3/denonext/fetch-http-handler.mjs": "1fc3874e3b4839c5c485ba5a4ac053e88d31d58745c9ff74bf38be7e99b3029a", + "https://esm.sh/v124/@smithy/hash-blob-browser@2.0.11/denonext/hash-blob-browser.mjs": "0d1bbbc07175165532a17e057931da4a446494399017b4995402493058576973", + "https://esm.sh/v124/@smithy/invalid-dependency@2.0.11/denonext/invalid-dependency.mjs": "c0b98fb159705a44d92134ff16ff26bdc7422db7dd106c3c9069225811a55372", + "https://esm.sh/v124/@smithy/is-array-buffer@2.0.0/denonext/is-array-buffer.mjs": "8fcbe490a3730ac1eac71766b5e1cb41ccba2f2abf646badb0e50a95340b3623", + "https://esm.sh/v124/@smithy/md5-js@2.0.11/denonext/md5-js.mjs": "2267b2625dba321662c3f20e766795519c2c85d908188eaa0b0775408af4c78a", + "https://esm.sh/v124/@smithy/middleware-content-length@2.0.13/denonext/middleware-content-length.mjs": "fca949473623758e876aeecd7fb968488f022ea789fd3de74e354c32b6bb0e26", + "https://esm.sh/v124/@smithy/middleware-endpoint@2.0.11/denonext/middleware-endpoint.mjs": "3ceaea710d87ca8b91fac200fd94c3c3394be44503d02ff0f6721c354cd5ffec", + "https://esm.sh/v124/@smithy/middleware-retry@2.0.16/denonext/middleware-retry.mjs": "2bac12e80437c0a543021c1eeff4190d0f86ccb5c3c5b24c49e79d9ce435a72e", + "https://esm.sh/v124/@smithy/middleware-serde@2.0.11/denonext/middleware-serde.mjs": "be0a8bd41b35f58fd94ebf1c749995768112a09a98265745c6a729de7799ea07", + "https://esm.sh/v124/@smithy/middleware-stack@2.0.5/denonext/middleware-stack.mjs": "54d9ddbd56220623e7133ab2e26b876b82beded5740af3547d928bd9927edf6a", + "https://esm.sh/v124/@smithy/property-provider@2.0.12/denonext/property-provider.mjs": "22728c55a848d583f805d06512ecbe4ccf648a4f41c3c5de79defde7feaf591b", + "https://esm.sh/v124/@smithy/protocol-http@3.0.7/denonext/protocol-http.mjs": "328707244a07a17f590d5f65803b1bf0d94b23f44e1ef8f99cdace40edc2cf08", + "https://esm.sh/v124/@smithy/querystring-builder@2.0.11/denonext/querystring-builder.mjs": "43b4ff6e0b94673755e3e097c0c8c63d32ad52da76578e5affcdc418bf98fba0", + "https://esm.sh/v124/@smithy/querystring-parser@2.0.11/denonext/querystring-parser.mjs": "28b5d91a8334ac8e8ae8bc2140ab3f2b74cb3a2f6561053468c93de64ff6de41", + "https://esm.sh/v124/@smithy/service-error-classification@2.0.4/denonext/service-error-classification.mjs": "7c45dffa05c128178c4d00caa368fc49360be1cab9e68e4b2a7c3d26179910ca", + "https://esm.sh/v124/@smithy/signature-v4@2.0.11/denonext/signature-v4.mjs": "8dd5d075d7a630bd0c52551b3a32c5cec91894baed80ca51147eb40bc801345f", + "https://esm.sh/v124/@smithy/smithy-client@2.1.11/denonext/smithy-client.mjs": "362b7b705c3c7f59c8c0767d10a406cf0d8cfa2e408a6143af7c7591c3e4676e", + "https://esm.sh/v124/@smithy/types@2.3.5/denonext/types.mjs": "ac5460dbbf752f3c0803a9a420932205c560b778dec8f68afa77f9f7cac771c8", + "https://esm.sh/v124/@smithy/url-parser@2.0.11/denonext/url-parser.mjs": "0e0e45f13da78d1a9066b8879489d473ebfd0612406781f2cf6f76759579d665", + "https://esm.sh/v124/@smithy/util-base64@2.0.0/denonext/util-base64.mjs": "5e68cff865aed7e15bb3fae3ae1d598af176528f1a43096fb87cbadfbc325eb7", + "https://esm.sh/v124/@smithy/util-body-length-browser@2.0.0/denonext/util-body-length-browser.mjs": "ca194ebec4cdc33005acc555ea85a7355a069092a2ba1aafa719183b4fef4390", + "https://esm.sh/v124/@smithy/util-config-provider@2.0.0/denonext/util-config-provider.mjs": "b07b2dfe445f7a73f7fb03725a03ce0cfa3dd8614c9c3806492a23b3d8b61fe8", + "https://esm.sh/v124/@smithy/util-defaults-mode-browser@2.0.14/denonext/util-defaults-mode-browser.mjs": "8e84a5cb6afa65f70cef753216b049713e3b6ce49ec47c6c525b958e60ef780c", + "https://esm.sh/v124/@smithy/util-hex-encoding@2.0.0/denonext/util-hex-encoding.mjs": "48b73551d6dc8f87fff840debe36f207f56b04a36c3c21fe2099613457c9d22d", + "https://esm.sh/v124/@smithy/util-middleware@2.0.4/denonext/util-middleware.mjs": "b123110bf635f5b7ff8a437ae3f82c03a413e3d6dae15070b1599e1cb914b65c", + "https://esm.sh/v124/@smithy/util-retry@2.0.4/denonext/util-retry.mjs": "614fe88f0777d2d9fa86889b20f53d4ddfb1b9fe2232bddfd82e41962a6a1142", + "https://esm.sh/v124/@smithy/util-stream@2.0.16/denonext/util-stream.mjs": "fb26b9da38949c31046f1da99003b031024bf831d678383d58b13196ce419e5e", + "https://esm.sh/v124/@smithy/util-uri-escape@2.0.0/denonext/util-uri-escape.mjs": "1e46ae4ab088b9dfcb5dd73715de2a2530747e920cf5b405012aed7d944e2976", + "https://esm.sh/v124/@smithy/util-utf8@2.0.0/denonext/util-utf8.mjs": "c50f8d6d64a39a8717e88184dee0fec145cb2d17a0d0a456e007eae02062bae5", + "https://esm.sh/v124/@smithy/util-waiter@2.0.11/denonext/util-waiter.mjs": "37e480f50842de5149ac3a3cb592b03ae1de23f709550a2158062a1f72a44c4f", + "https://esm.sh/v124/acorn-loose@8.4.0/X-ZS8q/denonext/acorn-loose.mjs": "14c27dc175609579a9c52b3003f86a1a0b1f06db4197720cbdb84a1cf1ca98f7", + "https://esm.sh/v124/acorn@8.11.0": "5c027fd61ad3c4c00a3d19ea92587e07bcc044dd0ce4604ff9c15fcd10507e83", + "https://esm.sh/v124/acorn@8.11.0/denonext/acorn.mjs": "5cfa11057423a0a2ce11224cf82f6c5616e12c72c48b3362ba8b778292872f54", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/2019.js": "46e3436284f2efe40b2c6b6d072793283f2f06a6c7592505785122f364ea64a1", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile.js": "1378daa49af3b45021e3b8d40d3a3180da04e50241714cdc0de444f84d2b9eab", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/codegen.js": "092106f381af11db8a32f3df3a9cb8d2794d4865ede8786f045db00d6fb46206", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/codegen/code.js": "d467da34c2949832b4368bb3aa9c0abff077b04bb30f5a475317d3dff476a73a", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/codegen/scope.js": "ec8cf20cad6c485e34116974856b785224a9732d7adad085b05e0ec820065a67", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/errors.js": "b1dd7b46143e06c44f505110bfa073803b6e6bbaa01b72a32a780c86ea13193a", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/names.js": "411531e4dca8bee76dd868468b51701e99fec99a2ce8023f50eecbff0aa2ee6e", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/ref_error.js": "a3aaa89f0323cca4089c9762ee2e3b353d3f89bb871990cea91d3d6da3432a79", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/resolve.js": "0ab575b72e1ab9f1a79b14ca51f81af932a4002c07a43851f300e2cbe1de69ad", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/rules.js": "9a059833a0a38366b807d371fa2dc65e387f5badde34b370e1abc4710bd7917f", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/util.js": "c64f495f88dcc9b6af1e03f31a849235e4310470a74d5ec44a84944307e3f9cc", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate.js": "6484462b77df6320117afbbd0edbdb3208b0c89ae8d164f05810a46ab8dcfed6", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/applicability.js": "d50d084b87afb8a03f88a5faffb3c95e7a89f0377420336e9432a9bdd01d8b65", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/boolSchema.js": "5bb50ab8f73f675414cfb5ab5a468a41d8e9ec3dc4ba4f628c55c535ae203175", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/dataType.js": "4311b4c8b478b448f666c948afbf2738614f4a5df17eb7cbabd4e161885fa7ed", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/defaults.js": "a4a72dac5bbeb80440a267e580226184e4e392be65111785921b3b919d7af865", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/keyword.js": "35ce4ae2365f87f665754eb4e9f1c6c10fc540c812566009e269207f454e11fd", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/compile/validate/subschema.js": "2e0e570955bef26c6030d9baa5b1a824574866041a3fd5b2201c4eb5686fb01f", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/core.js": "0d6670e6b6de3387ed2a6cd2fe7e7ec836498a353701852ef2ff7e1363cb780d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/refs/json-schema-2019-09.js": "d8ebc7fc774215a297fc804cf8fb91ed8061955faf63ec643eb8e21c6c687046", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/runtime/equal.js": "67c313860f2ac014da284e4b1ffc453f7c537a459f57e0cddd1dc93208d45262", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/runtime/ucs2length.js": "c1808bcef70a0da2f0f4074de8ad827184db50fa082896770fb63e0f9120f5f7", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/runtime/uri.js": "35c9c5472336b11f43fbc3658b747dfefbd081bef1118071f68316a2acb55e9e", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/runtime/validation_error.js": "291b014d16c4dd5f68317c3c8131d2b426573b3238033c27c0277701b5c7f9aa", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator.js": "37d6d557cb42c6aaad1b98ddd58362eba628c5fae202aa46ce75535c19f92a18", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/additionalItems.js": "67685be156c248532af5c64f08bdf216f0fc4f213974f66bd5fc74513292ad09", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/additionalProperties.js": "9d031ad70e1dba07aeba5f8ef7ce1fd4377c2a5efe05e86b09139ae8aeb925bf", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/allOf.js": "430e7d85a9cb124d0f845fb0e3e4bcafb0e6475925319e8c4ebd390d0d936543", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/anyOf.js": "35ea0062ed5dbf13c8c7b4add66665ad46abc5072c8812ac0e6df6b4ef144069", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/contains.js": "86a23d3497ce1f7fd1f9cba9a109e199a26d8d3ec77878610bb41236ff0b059d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/dependencies.js": "150bb6d810728b4811018296a7bd080fe52ec117905b29612446c3dac679a04d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/dependentSchemas.js": "44c848a508b01659e495fcbab90c6dc9ff49541e5990db2d2fb5301edb83cd1e", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/if.js": "26b17db767c24f5f58c09ff02643b4c945c9e58f05fdc25b2d4383b6917fd753", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/items.js": "c74a01d2f70b492f30403c5f934ec16d86aa97d22a59621519ee02ea08d22c65", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/items2020.js": "601a0437ba54ef2a0802c4a331e5eab86248bc8f71be44fdb53de3933831b65e", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/not.js": "f7e8cb2c5baae656d0b0dde86331704de39f0ce5db08bf5ceb445a9c943e5842", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/oneOf.js": "5014fb39cecb2e1b9f300cb6f23d3fd41336e75073244f587627b7ca7bb1dbe1", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/patternProperties.js": "38487dd941f835c5803e1f3ff2e1e09ac01883b8ee15a68d07271942d37675c3", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/prefixItems.js": "e7fa9bd524ddd784b689b1badfbde411d66808ddec04e42237c34177fb334393", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/properties.js": "17df86946d32b28cafd712a56bf7eaab36cef5243cbe4c1600a31e3d2f4fd5f8", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/propertyNames.js": "ad89ab1d78dd5dad2cdcc3b986bdf5b2a8e734d59e41897cec5d05977dbca8a5", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/applicator/thenElse.js": "431bb9e7f39f091ff7a8b16b953b48a8e7e8b229ad3193662062764d51cc9d2c", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/code.js": "68439a222c5e621689018edae27adc87f9d6a15aac5eda8e6d62a3c14395ee39", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/core.js": "f0e7debbb2aeb4b85a3e994eaaa4a6651b1f14da7cac6f732a56d4935790fb38", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/core/id.js": "7e22249fb857b03eb525f1d0af5a1a7c34a926a244ab7b1b74a8fb66c78a9ba3", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/core/ref.js": "7b5dbe5f060d693cb2343b8f4d6d6a72e9dcdb229649c20a6476ade4907ca116", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/discriminator.js": "a3cabc58d1c7f70910c2daf1a3494b8e8c9659f4622feb26c4e1bcf8ae55512f", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/discriminator/types.js": "6bdf5bb4b0d3a0ff7d682b771ba74b35ae8fc6bed5d51f51bc169e142fb96754", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/draft7.js": "bc8956f43e43f0e9d922915a2187e44589a834ce95816ee7409d947820a423df", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/dynamic.js": "76f2cfdc2e2fcfb440a8bf5ee204aa09be2abb3fbad460b26d9f202b7d72953f", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/dynamic/dynamicAnchor.js": "32a9dc1bc30d4a5d4e27a3f9f72232bfcaaa90345274f759a769976c15f43446", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/dynamic/dynamicRef.js": "0e2d40bec486a8dda2735477800a841fc91a2374112d2a7d015c29a4c723a8b8", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/dynamic/recursiveAnchor.js": "11c54c6121e80064c2faefcb569296856a185f5b4b49983e6964f4c44c170e72", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/dynamic/recursiveRef.js": "54bec184ce6bcb550bbeda4c430cde54defa880baa314c1c390ec870a9d4317b", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/format.js": "83cff2241b50109cf4f38babed8a2c46a80479c347370ca409a80bd79352b9f2", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/format/format.js": "48ec551d8a99b3feeaeb2f63131e39d0a0f54539edd825233dd844a0bde446b4", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/metadata.js": "34d26433134bd71ec016e42393d2157f1d18b3f64244b041bb8f474c3f17e5e8", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/next.js": "8c7f43aee25741fbf1d2038c3a70dc708cbd90ec954c7675e025fc15de0739ee", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/unevaluated.js": "f8da742c2256a94832917852f6d728474e931256fb51b3b0f7be2e05e31d4626", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/unevaluated/unevaluatedItems.js": "a9baa444bb623742fabdcd544a962e5f1830ce6ac163235829df40030423f69b", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/unevaluated/unevaluatedProperties.js": "0e792a2348a8f3bdce88c0e052ae234b28e914d4dd7a374f3b36dcd65f24a60a", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation.js": "4c6ddcf2cc75b748b9f1558985d8324e5291e1e1de980f1fb8295ce81aa299e2", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/const.js": "30fd3e9ac9bea4b624ebee5d035089e2017148d787fec11f88be5d89bcdce43d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/dependentRequired.js": "f0030eeeb06e9344ede95f88790f0e0910ee5befb21449493725abffb6a5363d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/enum.js": "16270f5b5f868c9a2daa4c1287b146d3cbbb07f6aa9ee186a6d8506bddfb259b", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/limitContains.js": "92267764743650aa11a90e523fc5f08cf4105c3a8c562a4d469c3f719ec17a03", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/limitItems.js": "bb7b91b0c0fd7c8743aa2a752beb9064b1351c2fbbabae6ed4bf7253e33ca16d", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/limitLength.js": "6eac7a3eaf9993c2abfc54a1fcd6590ce002ad6b813c4b6e639e41d5e7273300", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/limitNumber.js": "76949d424bce959d70c8f0d37408b4426424d762bc9b9803a9445b1dca7093ea", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/limitProperties.js": "ee2041d31122907a584a703781ad240181fb53bf88d828c14b98a004be441547", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/multipleOf.js": "2fd75abe7efe7e8c8fd3f7a2cc1f65d0a960687a4ca2dff0d040368f0b701249", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/pattern.js": "1b8d65fdf083c30992901ab9558d1bede4f3605eaa795d81472bc5ef2c58fbc9", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/required.js": "945988a3e33e21322f240fa5304a3dbbb4a80b2cf8c56032bfd27df9294c9793", + "https://esm.sh/v124/ajv@8.11.0/denonext/dist/vocabularies/validation/uniqueItems.js": "77bf5a6f1bdd56129e0a217865e9d2beb2fd6623a6b288cc4b5af93c49cad69b", + "https://esm.sh/v124/ajv@8.11.0/dist/2019.js": "646df403ae1a0d94045d530fe3b7ca65e4bd4a1163e6041d34bc9d321bb7334f", + "https://esm.sh/v124/ajv@8.11.0/dist/core": "7af19c4e1b07edc97c97d9a4e1b2859154d626fc9d10b618c8fda3b178ce26c0", + "https://esm.sh/v124/ajv@8.12.0": "7621f26ca63271c26d3c0d3812be6a826809bb56036db0bf3ffb3e82bb7482d1", + "https://esm.sh/v124/ajv@8.12.0/denonext/ajv.mjs": "dd2ce45ec01492d9d6bf91bc6bf0e2608fc8977d70cc4bbc0d2d7c1453d514b9", + "https://esm.sh/v124/ajv@8.12.0/denonext/dist/2019.js": "26aae2b10cb7a43fe6527beae125ade89406357ddb58019e63d3414ca7c6a3f2", + "https://esm.sh/v124/ajv@8.12.0/dist/2019.js": "d926e40c1ce87266be912519e15dceb76c5a2701770db7d0b5b2e051f37aa556", + "https://esm.sh/v124/ansi-regex@6.0.1/denonext/ansi-regex.mjs": "9b72c27d642eff10be605f8b170084bdf8a9729e1fd525aad5139977fc80dc59", + "https://esm.sh/v124/ansi-styles@6.2.1/denonext/ansi-styles.mjs": "d40ccc0e5be3eced4c723f48dbdb5249efa00b7f8561a90999b7487db3ee5c09", + "https://esm.sh/v124/async@3.2.4/denonext/forEach.js": "c265bae8dbe1a8b9bbc26bf012f89f0c37fbb5864df1232af585596f13896ace", + "https://esm.sh/v124/async@3.2.4/denonext/series.js": "a555746f7a024becc7b63f37ed3cf00aaa32302855e0c07cdfc0b3aa9abee3c2", + "https://esm.sh/v124/base64-js@1.5.1/denonext/base64-js.mjs": "fc961905a7e7a9a1c753f006903a610306d299569a0b3af9c48318a28ac48b84", + "https://esm.sh/v124/bowser@2.11.0/denonext/bowser.mjs": "9876a6f4cb94547829dc82a448b1b7a02b590a819aeb0a29f7e6416fca3a446a", + "https://esm.sh/v124/buffer@4.9.2": "97db8c9b70e6b09f4a09440a62cb9a8a577c1a28787ece11dcaaed918d790840", + "https://esm.sh/v124/buffer@4.9.2/denonext/buffer.mjs": "b41fd0012d60aea2ec448dddefa54c90b4d9dd2a3a1bdb224679c8861a9cb28f", + "https://esm.sh/v124/chownr@2.0.0/denonext/chownr.mjs": "230f6e23902418045f5057ff9a7cee6a7a28a21655eeb98f5671395d32839a1a", + "https://esm.sh/v124/cli-cursor@4.0.0": "2ed1740a92df113d48f30ac950b174042c2f904556219b3165f04d4e50392cac", + "https://esm.sh/v124/cli-cursor@4.0.0/denonext/cli-cursor.mjs": "0904486398e7456058b337418d8af5338924f07682b96f1b3016a01b94009ecc", + "https://esm.sh/v124/cli-spinners@2.7.0": "8c361d3c00214f793f340219fef26fe3b5ee1e8ab4ff5aa757d0738a0266329c", + "https://esm.sh/v124/cli-spinners@2.7.0/denonext/cli-spinners.mjs": "0c26bb5125565e8589d8de5c142dcd435134b6bac34ac920b08f024b766e50ef", + "https://esm.sh/v124/eastasianwidth@0.2.0/denonext/eastasianwidth.mjs": "d306d000e83384edac47a6b796e8d92b0f1c5a61e05baaecaca5fe6d33fd6476", + "https://esm.sh/v124/emoji-regex@9.2.2/denonext/emoji-regex.mjs": "bf5936f0325f687ac4f870f668876f97cf8b9e84e7d8816a6a8c1c1f3e3976d2", + "https://esm.sh/v124/escodegen@2.1.0": "7dfb21a027c42092dc58e1b81c54193a8310ec04f9511989ad81f914d033c400", + "https://esm.sh/v124/escodegen@2.1.0/denonext/escodegen.mjs": "3afba81255c7fd7c09ededfb979351195993fbf6c6056412592ba448a3db551d", + "https://esm.sh/v124/estraverse@5.3.0": "a172212d2f4a87f930430cb7e0462cb507891b9f390e17025533f572d895092c", + "https://esm.sh/v124/estraverse@5.3.0/denonext/estraverse.mjs": "3e3574b932e1b7c1476f467e6103559d7b978df412e50b6b97299679d4556004", + "https://esm.sh/v124/esutils@2.0.3/denonext/esutils.mjs": "56b9038ae71de0a374c86435a347793030afc96deb151466a5009cb5384a85d0", + "https://esm.sh/v124/events@1.1.1": "aa42c257bbfdbd6e635628110bc65ef7d66d7110ffcdcdf894e3afc722e0c87b", + "https://esm.sh/v124/events@1.1.1/denonext/events.mjs": "cafdffd6a39d45b8282efe4b29a0b902ce76e3fd426840fb54eb3e6cec208fab", + "https://esm.sh/v124/fast-deep-equal@3.1.3/denonext/fast-deep-equal.mjs": "6313b3e05436550e1c0aeb2a282206b9b8d9213b4c6f247964dd7bb4835fb9e5", + "https://esm.sh/v124/fast-xml-parser@4.2.5/denonext/fast-xml-parser.mjs": "0132711d650c1ba44721b4bcf6e0636cd0e0f81894694e8e5b36242434eceb9c", + "https://esm.sh/v124/fecha@4.2.3/denonext/fecha.mjs": "d87efb3f6dd068229dcaaf6ce19072720634695668c49da74e6d7289fc67ee48", + "https://esm.sh/v124/fn.name@1.1.0/denonext/fn.name.mjs": "ddba0c68ee94f7248c7f4988c68c7c040be5c624f955b4fb738739aa42c7f888", + "https://esm.sh/v124/fs-minipass@2.1.0/denonext/fs-minipass.mjs": "e3ee6d0df9871f490d05b070b47cd6495f8f33ae4eed90167242cd9819c82cca", + "https://esm.sh/v124/hcl2-json-parser@1.0.1": "c50574c485772ae59ed44a3b8f679b85e6ff61788b76f9849e3da1065c249823", + "https://esm.sh/v124/hcl2-json-parser@1.0.1/denonext/hcl2-json-parser.mjs": "a51581a1181c31284bfb1ff0907f79a34b248e3fcb1b333c986b8273781fb39f", + "https://esm.sh/v124/ieee754@1.2.1/denonext/ieee754.mjs": "9ec2806065f50afcd4cf3f3f2f38d93e777a92a5954dda00d219f57d4b24832f", + "https://esm.sh/v124/inherits@2.0.4/denonext/inherits.mjs": "8095f3d6aea060c904fb24ae50f2882779c0acbe5d56814514c8b5153f3b4b3b", + "https://esm.sh/v124/is-fullwidth-code-point@4.0.0/denonext/is-fullwidth-code-point.mjs": "e9801323732e385027651be9a815a58a6f340484316c9f6ed27a0eec6c48c161", + "https://esm.sh/v124/is-stream@2.0.1/denonext/is-stream.mjs": "456bc690361378c52fac24a7f362044f036942b1298e812799a67882d6c1febf", + "https://esm.sh/v124/isarray@1.0.0/denonext/isarray.mjs": "6368a41cf02c83843453ac571deb4c393c14e6f5e1d9ca6bbe43a4623f3856c8", + "https://esm.sh/v124/isexe@2.0.0/denonext/isexe.mjs": "733c6d04662ec8e40a169a321fcdfaaafb5fce27a3113408c09f17becbd1acd8", + "https://esm.sh/v124/js-yaml@4.1.0": "546cd3718747e8cc7d431a079df570c6c62417b338387f6e0a059b4c102d3847", + "https://esm.sh/v124/js-yaml@4.1.0/denonext/js-yaml.mjs": "b4e4f1b1cadcc873d4079f242cdc811b1a36fdd0eb01b9b54ca2ae6e2ff2a92f", + "https://esm.sh/v124/json-schema-traverse@1.0.0/denonext/json-schema-traverse.mjs": "c5da8353bc014e49ebbb1a2c0162d29969a14c325da19644e511f96ba670cc45", + "https://esm.sh/v124/log-update@5.0.1/X-ZS8q/denonext/log-update.mjs": "fb4b88d17be9478cfcd97d14aa971028ec5f6681ecaf32b6f7790bb242f15125", + "https://esm.sh/v124/logform@2.5.1/denonext/json.js": "c7f923ba5d3c3144bcf8bd0a0ab71ffb69a3bc458f05f179ddeef1b456aaa8bb", + "https://esm.sh/v124/logform@2.5.1/denonext/logform.mjs": "5d0ddaa5a654ad3744b8d64699e6acf3867583311db38ce30f825840c049c96e", + "https://esm.sh/v124/lru-cache@6.0.0/denonext/lru-cache.mjs": "2244b3331e49a346b08c58f564478d71b52ab533e177e702006679881a467c61", + "https://esm.sh/v124/mimic-fn@2.1.0/denonext/mimic-fn.mjs": "eb833a5f55567c0a0099c2194d8de27175d0cc65e6a17fbed872a6ab8411a600", + "https://esm.sh/v124/minipass@3.3.6/denonext/minipass.mjs": "727dc8f045218c22f1dbf47b75de9b07b70bb5a4ffa9477c6b100fcdc3d6e98c", + "https://esm.sh/v124/minipass@5.0.0/denonext/minipass.mjs": "4bb4803ad04bacc66d7580f95de8566f9f99e7da42442a1e49facd0fbef0f965", + "https://esm.sh/v124/minizlib@2.1.2/denonext/minizlib.mjs": "39075b0e4e1b6ed5e465814732d3e226c924b5dc6e9f8cba91040aa4a2f8fd36", + "https://esm.sh/v124/mkdirp@1.0.4/denonext/mkdirp.mjs": "efcefe8d72c229ab6de93af24f69ec0eb32e4017da14e6a8bd23deebfa59f5de", + "https://esm.sh/v124/ms@2.1.3/denonext/ms.mjs": "0f06597e493998793b8f52232868976128fca326eec3bcd56f10e66e6efd1839", + "https://esm.sh/v124/one-time@1.0.0/denonext/one-time.mjs": "b3a4b3d5de194c6f2bf7a9556607a622f9ac27b08a35ac6e87d9f9e7580afcc4", + "https://esm.sh/v124/onetime@5.1.2/denonext/onetime.mjs": "dcdb53bfa68b0d43d301c1fd4bb131150a6e58ba843db9b61e6dcd282c9434da", + "https://esm.sh/v124/querystring@0.2.0": "c426159c0d0a6c8732e9e3e976230edb77cb7b225ae7f5b4fc1c131563bf9537", + "https://esm.sh/v124/querystring@0.2.0/denonext/querystring.mjs": "0cc5ad58cddf88b56ccd9bbb47ecdb8707f037c9a25ad47cf38a7fdc4189ae1b", + "https://esm.sh/v124/readable-stream@3.6.2/denonext/lib/_stream_writable.js": "fcd380d7da84d0708692263c1e46b1a673d7ab64da9f654b73abfad0219a7560", + "https://esm.sh/v124/readable-stream@3.6.2/denonext/readable-stream.mjs": "061037c060d88267d4cbbd57688f0bf2ed6cceda918e17d407f83248a6aad672", + "https://esm.sh/v124/restore-cursor@4.0.0/denonext/restore-cursor.mjs": "9c2be16e5018dcfeed7503897c1113d9427016b1b907013ee36cb1aa27173fb9", + "https://esm.sh/v124/rxjs@7.5.6": "c8ec6b36accd063ef43b06b690b477770e403c935c15b1e4f646c5f8a994ff15", + "https://esm.sh/v124/rxjs@7.5.6/denonext/rxjs.mjs": "532946f953dfa26e3eb2445416fe3625882a5d4287e1954d9409d2a6c110de2e", + "https://esm.sh/v124/safe-stable-stringify@2.4.3/denonext/safe-stable-stringify.mjs": "e3651b3a9166007dfb807b962fa16a50c1c31c9c62844b9f80939e54b091af61", + "https://esm.sh/v124/semver@7.5.3": "9763ac4bfebc5955d9a82f07c852f893c97b9e193673f18ba0a1093805b901a9", + "https://esm.sh/v124/semver@7.5.3/denonext/semver.mjs": "2d2cd5fbd4fdf80d11587d7c998c1f2770599e25f23f206b58748246d0c05ab4", + "https://esm.sh/v124/signal-exit@3.0.7/denonext/signal-exit.mjs": "936ef3023461bad429e4679e7f1db46fdd615f3c13ddcef3ae0867eaffbe77c7", + "https://esm.sh/v124/slice-ansi@5.0.0": "05484db6da2a54c3a9f9021885bc0c5024ae3d53b2ba1981bbc97a1b297743df", + "https://esm.sh/v124/slice-ansi@5.0.0/denonext/slice-ansi.mjs": "fc7fe47f070c571308b1530938aeb719e3a3d9dc9f13360018cd8457075a5897", + "https://esm.sh/v124/source-map@0.6.1/denonext/source-map.mjs": "ccff3bb06dea7c01a2c83cf12113697592e418fd06b55ae2bb4cb0a4e51a98b8", + "https://esm.sh/v124/stack-trace@0.0.10/denonext/stack-trace.mjs": "52bd59853fd0757561297ed6c54f5cdd143c7647c4de0bc3221b5bed2a72a74b", + "https://esm.sh/v124/string-width@5.1.2/denonext/string-width.mjs": "63a17a4ea73fe9269b3fe896ea2baeb3f6ea4625ba54aabcf6967e2d6c97ea77", + "https://esm.sh/v124/strip-ansi@7.0.1": "aaf76d5c99ebeee0bf963b6a9831a3e5e96d8093a6ea6c1f3ee717708ec87152", + "https://esm.sh/v124/strip-ansi@7.0.1/denonext/strip-ansi.mjs": "a699825f9523ef4a6370fd0db90d526b69ee9f277fab31d2154100cb84680310", + "https://esm.sh/v124/strip-ansi@7.1.0/denonext/strip-ansi.mjs": "dba43184e2609694e194889d949cc821e6b843adfde7f059eb3543c1fe71ac48", + "https://esm.sh/v124/strnum@1.0.5/denonext/strnum.mjs": "1ffef4adec2f74139e36a2bfed8381880541396fe1c315779fb22e081b17468b", + "https://esm.sh/v124/tar@6.2.0": "97839abdc8be119b0b99434b73518fd3f81d18f2102b2208e975f0139415e305", + "https://esm.sh/v124/tar@6.2.0/denonext/tar.mjs": "8e66b793d65e5b3d84cc2d5cdf56fdbfc6886495366a81e6729f7861a9b6eb30", + "https://esm.sh/v124/triple-beam@1.4.1/denonext/triple-beam.mjs": "56c3bf240276d9392f9a7722d58af78bf96f1b919a95bfe2367cb79aa382358e", + "https://esm.sh/v124/tslib@1.14.1/denonext/tslib.mjs": "5e49e8960f064d11fb709e3338f5437e2ede57e7df873a09d7834c2a0bf533f7", + "https://esm.sh/v124/tslib@2.6.0/denonext/tslib.mjs": "2215292e6fcf28a7a081eee911f127bb3c44cdd61ff0651e3e384d7a49b4e42b", + "https://esm.sh/v124/unique-names-generator@4.7.1": "6d61270c703d91c6fb27bd9b68a06f241659c3f01df03f76f4e8b540acf45c44", + "https://esm.sh/v124/unique-names-generator@4.7.1/denonext/unique-names-generator.mjs": "b40a40ff6a8533a2f35c6a4b6883a5e5737d75287f2d635a863176247bcb7f19", + "https://esm.sh/v124/uri-js@4.4.1/denonext/uri-js.mjs": "4b46d46cd678979debedbf2d05fa39b50ec17656e3960a9ec3418e7763aa7c34", + "https://esm.sh/v124/url@0.10.3": "07386e574238e0e64451b25c1d699146b6bace90f58e1e751dae337d003fe44c", + "https://esm.sh/v124/url@0.10.3/denonext/url.mjs": "ba58c05c534164ab58a98e7e9f9ba67400750a2d71031658c4580d7112ac4144", + "https://esm.sh/v124/util-deprecate@1.0.2/denonext/util-deprecate.mjs": "e7f4e3a1ec5eb3f2e04dbfaf90e4874f535ca298a7c91512f1d083e1ba765c37", + "https://esm.sh/v124/uuid@8.3.2/denonext/uuid.mjs": "c0da38266b24ac79d62b02290f17caba7e75d078f6771bbe8fb61bdef60f837c", + "https://esm.sh/v124/which@3.0.1": "f27ee01cac772029a95d37fad83158ebe6a6cc4222ee9396f5f54bfe4903da6c", + "https://esm.sh/v124/which@3.0.1/denonext/which.mjs": "8dbd9dfb50443fa820cbe5812838014939e71660be6310ceec17668ab2a0ec50", + "https://esm.sh/v124/winston-transport@4.5.0/denonext/legacy.js": "1449f47c35b0c73565a8f6f6edf3977a421f011df971a1ee037e0c1183248721", + "https://esm.sh/v124/winston-transport@4.5.0/denonext/winston-transport.mjs": "4f27dbfc17ab4fd685658271acd061c373c5ee1b7f082d2469d3204fb569d7f3", + "https://esm.sh/v124/winston@3.8.2": "70cfec3efd0bae3c2183ae342cd1f2e7fab6988ceda8353abb6f2ed52edf8351", + "https://esm.sh/v124/winston@3.8.2/denonext/winston.mjs": "cd88f004dd09908a782d94ea6a56691b0092ef74dcc842fd720bf70c3d3d4a58", + "https://esm.sh/v124/wrap-ansi@8.1.0": "da576a84619b45bf324bfb582b74f3c38b23deb5abb204d3b3aca329f6cd970d", + "https://esm.sh/v124/wrap-ansi@8.1.0/denonext/wrap-ansi.mjs": "1804d60795c6034323e4b8dc92425aa9ab28385b87bb700772e16cb92bb0d8f8", + "https://esm.sh/v124/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v129/ansi-escapes@6.2.0/denonext/ansi-escapes.mjs": "e82f350a4e3ef3113cd99b6d99513de1821bb9ae50bb4ed1dbbd6b9789af560d" } } diff --git a/examples/datacenters/local/datacenter.arc b/examples/datacenters/local/datacenter.arc index 21496e8b0..dd3036f89 100644 --- a/examples/datacenters/local/datacenter.arc +++ b/examples/datacenters/local/datacenter.arc @@ -19,6 +19,7 @@ module "traefik" { name = "${datacenter.name}-gateway" image = "traefik:v2.10" command = [ + "--accesslog=true", "--providers.docker=true", "--api.insecure=true", "--api.dashboard=true" @@ -92,6 +93,33 @@ environment { } } + module "localstack" { + // when = contains(environment.nodes.*.type, "bucket") + build = "./deployment" + + volume { + host_path = "/var/run/docker.sock" + mount_path = "/var/run/docker.sock" + } + + environment = { + DOCKER_HOST = "unix:///var/run/docker.sock" + } + + inputs = { + name = "localstack" + image = "localstack/localstack" + ports = [{ + internal = 4566 + external = 4566 + }] + environment = { + DOCKER_HOST = "unix:///var/run/docker.sock" + GATEWAY_LISTEN = "0.0.0.0:4566" + } + } + } + database { when = node.inputs.databaseType == "postgres" @@ -228,10 +256,9 @@ environment { } } - bucket { - module "dynamicBucket" { - when = node.inputs.deploy - build = "./deployment" + volume { + module "volume" { + build = "./volume" environment = { DOCKER_HOST = "unix:///var/run/docker.sock" @@ -242,22 +269,18 @@ environment { mount_path = "/var/run/docker.sock" } - # This volume is shared with the nginx webserver - volume { - host_path = "${var.secretsDir}/${environment.name}/buckets/" - mount_path = "/data" + inputs = { + name = "${node.component}-${node.name}" } + } - inputs = merge(node.inputs.deploy, { - volume_mounts = [{ - host_path = "/data" - mount_path = node.inputs.deploy.publish - }] - }) + outputs = { + id = module.volume.id } + } - module "staticBucket" { - when = node.inputs.directory + task { + module "task" { build = "./deployment" environment = { @@ -269,24 +292,74 @@ environment { mount_path = "/var/run/docker.sock" } - # This volume is shared with the nginx webserver - volume { - host_path = "${var.secretsDir}/${environment.name}/buckets/" - mount_path = "/data" - } - - inputs = { - image = "alpine" - command = [ - "sh", - "-c", - "cp -r ${node.inputs.directory} /data" - ] - volume_mounts = [{ - host_path = "/data" - mount_path = "/data" - }] - } + inputs = "${merge(node.inputs, { + volume_mounts = merge(node.inputs.volume_mounts, [{ + host_path = "/var/run/docker.sock", + mount_path = "/var/run/docker.sock" + }]) + })}" } } + + // bucket { + // module "dynamicBucket" { + // when = node.inputs.deploy + // build = "./deployment" + + // environment = { + // DOCKER_HOST = "unix:///var/run/docker.sock" + // } + + // volume { + // host_path = "/var/run/docker.sock" + // mount_path = "/var/run/docker.sock" + // } + + // # This volume is shared with the nginx webserver + // volume { + // host_path = "${var.secretsDir}/${environment.name}/buckets/" + // mount_path = "/data" + // } + + // inputs = merge(node.inputs.deploy, { + // volume_mounts = [{ + // host_path = "/data" + // mount_path = node.inputs.deploy.publish + // }] + // }) + // } + + // module "staticBucket" { + // when = node.inputs.directory + // build = "./deployment" + + // environment = { + // DOCKER_HOST = "unix:///var/run/docker.sock" + // } + + // volume { + // host_path = "/var/run/docker.sock" + // mount_path = "/var/run/docker.sock" + // } + + // # This volume is shared with the nginx webserver + // volume { + // host_path = "${var.secretsDir}/${environment.name}/buckets/" + // mount_path = "/data" + // } + + // inputs = { + // image = "alpine" + // command = [ + // "sh", + // "-c", + // "cp -r ${node.inputs.directory} /data" + // ] + // volume_mounts = [{ + // host_path = "/data" + // mount_path = "/data" + // }] + // } + // } + // } } \ No newline at end of file diff --git a/examples/datacenters/local/deployment/index.ts b/examples/datacenters/local/deployment/index.ts index 3cf7ef1b6..97e5aeab9 100644 --- a/examples/datacenters/local/deployment/index.ts +++ b/examples/datacenters/local/deployment/index.ts @@ -6,7 +6,7 @@ const config = new pulumi.Config(); export const name = config.require('name'); type Config = { - name?: string; + name: string; image: string; command?: string[]; entrypoint?: string[]; @@ -90,23 +90,26 @@ for (const key in inputServices) { const inputIngresses = config.getObject('ingresses') || []; for (const key in inputIngresses) { const value = inputIngresses[key]; + const routerKey = value.subdomain.replace(/\./g, '-').replace(/\*/g, 'star'); if (value.protocol === 'http') { labels.push({ - label: `traefik.http.routers.${value.subdomain}.rule`, - value: `Host(\`${value.host}\`) && PathPrefix(\`${value.path || '/'}\`)`, + label: `traefik.http.routers.${routerKey}.rule`, + value: value.host.includes('*') + ? `HostRegexp(\`${value.host.replace('*', '{subdomain:[a-z_-]+}')}\`) && PathPrefix(\`${value.path || '/'}\`)` + : `Host(\`${value.host}\`) && PathPrefix(\`${value.path || '/'}\`)`, }, { - label: `traefik.http.routers.${value.subdomain}.service`, + label: `traefik.http.routers.${routerKey}.service`, value: value.service, }); } else { labels.push({ - label: `traefik.tcp.routers.${value.subdomain}.rule`, + label: `traefik.tcp.routers.${routerKey}.rule`, value: `HostSNI(\`${value.host}\`)` }, { - label: `traefik.tcp.routers.${value.subdomain}.service`, + label: `traefik.tcp.routers.${routerKey}.service`, value: value.service, }, { - label: `traefik.tcp.routers.${value.subdomain}.tls.passthrough`, + label: `traefik.tcp.routers.${routerKey}.tls.passthrough`, value: 'true', }); } diff --git a/examples/datacenters/local/network/index.ts b/examples/datacenters/local/network/index.ts index 68f34f037..94ea98baa 100644 --- a/examples/datacenters/local/network/index.ts +++ b/examples/datacenters/local/network/index.ts @@ -3,22 +3,6 @@ import * as pulumi from "@pulumi/pulumi"; let config = new pulumi.Config(); -type Config = { - name?: string; - image: string; - command?: string[]; - labels?: Record; - services?: Record; - ports?: { - internal: number; - external?: number; - }[]; -}; - const network = new docker.Network('network', { name: config.get('name'), }); diff --git a/src/commands/apply/datacenter.ts b/src/commands/apply/datacenter.ts index b12c7f2d6..e2355490c 100644 --- a/src/commands/apply/datacenter.ts +++ b/src/commands/apply/datacenter.ts @@ -113,15 +113,20 @@ async function apply_datacenter_action(options: ApplyDatacenterOptions, name: st if (datacenterEnvironments.length > 0) { for (const environmentRecord of datacenterEnvironments) { console.log(`Updating environment ${environmentRecord.name}`); - await applyEnvironment({ + const { success } = await applyEnvironment({ command_helper, name: environmentRecord.name, logger, autoApprove: true, targetEnvironment: environmentRecord.config, }); + + if (success) { + console.log(`Environment ${environmentRecord.name} updated successfully`); + } else { + console.error(`%cEnvironment ${environmentRecord.name} update failed`, 'color: red'); + } } - console.log('Environments updated successfully'); command_helper.infraRenderer.doneRenderingGraph(); } }).catch(async (err) => { diff --git a/src/commands/apply/environment.ts b/src/commands/apply/environment.ts index 46093f5c0..7a32b2ab0 100644 --- a/src/commands/apply/environment.ts +++ b/src/commands/apply/environment.ts @@ -31,7 +31,7 @@ export async function applyEnvironmentAction(options: ApplyEnvironmentOptions, n }); } - return applyEnvironment({ + const { success, update } = await applyEnvironment({ command_helper, logger, name, @@ -39,6 +39,12 @@ export async function applyEnvironmentAction(options: ApplyEnvironmentOptions, n datacenter: options.datacenter, targetEnvironment: await parseEnvironment(config_path || {}), }); + + if (!success) { + console.log(`Environment ${update ? 'update' : 'creation'} failed`); + } else { + console.log(`Environment ${name} ${update ? 'updated' : 'created'} successfully`); + } } export default ApplyEnvironmentCommand; diff --git a/src/commands/apply/utils.ts b/src/commands/apply/utils.ts index 252f8b794..317de7cad 100644 --- a/src/commands/apply/utils.ts +++ b/src/commands/apply/utils.ts @@ -44,70 +44,58 @@ export const promptForDatacenter = async (command_helper: CommandHelper, name?: return selected; }; -export const applyEnvironment = async (options: ApplyEnvironmentOptions) => { - const environmentRecord = await options.command_helper.environmentStore.get(options.name); - const notHasDatacenter = !options.datacenter && !environmentRecord; - - let datacenterRecord: DatacenterRecord | undefined; - if (notHasDatacenter) { - datacenterRecord = await ArcctlConfig.getDefaultDatacenter(options.command_helper); +export const applyEnvironment = async ( + options: ApplyEnvironmentOptions, +): Promise<{ success: boolean; update: boolean }> => { + const existingEnvironmentRecord = await options.command_helper.environmentStore.get(options.name); + let datacenterRecord = options.datacenter + ? await options.command_helper.datacenterStore.get(options.datacenter) + : existingEnvironmentRecord + ? await options.command_helper.datacenterStore.get(existingEnvironmentRecord.datacenter) + : await ArcctlConfig.getDefaultDatacenter(options.command_helper); + + if (!datacenterRecord) { + datacenterRecord = await promptForDatacenter(options.command_helper); } - const targetDatacenterName = !datacenterRecord - ? (await promptForDatacenter(options.command_helper, options.datacenter)).name - : datacenterRecord.name || environmentRecord?.datacenter; - - const targetDatacenter = targetDatacenterName - ? await options.command_helper.datacenterStore.get(targetDatacenterName) - : undefined; - if (!targetDatacenter) { - console.error(`Couldn't find a datacenter named ${targetDatacenterName}`); - Deno.exit(1); + if (!datacenterRecord) { + throw new Error(`No valid datacenter provided`); } const targetEnvironment = options.targetEnvironment || await parseEnvironment({}); - - const environmentGraph = await targetEnvironment.getGraph( + const targetAppGraph = await targetEnvironment.getGraph( options.name, options.command_helper.componentStore, options.debug, ); - const targetGraph = targetDatacenter.config.getGraph(environmentGraph, { + const targetInfraGraph = datacenterRecord.config.getGraph(targetAppGraph, { environmentName: options.name, - datacenterName: targetDatacenter.name, + datacenterName: datacenterRecord.name, }); - targetGraph.validate(); + targetInfraGraph.validate(); - const startingDatacenter = (await options.command_helper.datacenterStore.get(targetDatacenterName!))!; - startingDatacenter.config.getGraph(environmentGraph, { - environmentName: options.name, - datacenterName: targetDatacenter.name, - }); - - const startingGraph = environmentRecord ? environmentRecord.priorState : targetDatacenter.priorState; - - const infraGraph = await InfraGraph.plan({ - before: startingGraph, - after: targetGraph, + const plannedChanges = await InfraGraph.plan({ + before: existingEnvironmentRecord ? existingEnvironmentRecord.priorState : datacenterRecord.priorState, + after: targetInfraGraph, context: PlanContext.Environment, }); - infraGraph.validate(); - await options.command_helper.infraRenderer.confirmGraph(infraGraph, options.autoApprove); + plannedChanges.validate(); + await options.command_helper.infraRenderer.confirmGraph(plannedChanges, options.autoApprove); let interval: number | undefined = undefined; if (!options.logger) { interval = setInterval(() => { - options.command_helper.infraRenderer.renderGraph(infraGraph, { clear: true }); + options.command_helper.infraRenderer.renderGraph(plannedChanges, { clear: true }); }, 1000 / cliSpinners.dots.frames.length); } const success = await options.command_helper.environmentUtils.applyEnvironment( options.name, - startingDatacenter, - targetEnvironment!, - infraGraph, + datacenterRecord, + targetEnvironment, + plannedChanges, { logger: options.logger, }, @@ -116,12 +104,11 @@ export const applyEnvironment = async (options: ApplyEnvironmentOptions) => { if (interval) { clearInterval(interval); } - options.command_helper.infraRenderer.renderGraph(infraGraph, { clear: !options.logger, disableSpinner: true }); + options.command_helper.infraRenderer.renderGraph(plannedChanges, { clear: !options.logger, disableSpinner: true }); options.command_helper.infraRenderer.doneRenderingGraph(); - if (!success) { - console.log(`Environment ${environmentRecord ? 'update' : 'creation'} failed`); - } else { - console.log(`Environment ${options.name} ${environmentRecord ? 'updated' : 'created'} successfully`); - } + return { + success, + update: !!existingEnvironmentRecord, + }; }; diff --git a/src/components/v2/index.ts b/src/components/v2/index.ts index 6a4815a13..ee332bafc 100644 --- a/src/components/v2/index.ts +++ b/src/components/v2/index.ts @@ -630,7 +630,7 @@ export default class ComponentV2 extends Component { type: 'task', component: context.component.name, inputs: { - image: 'architectio/s3cmd:main', + image: 'architectio/s3cmd', command: [ 'sync', '/data', From 0be0fe24633c9b609dfb6d3f3aec0cd7f9b44c73 Mon Sep 17 00:00:00 2001 From: David Thor Date: Wed, 6 Dec 2023 16:41:44 -0500 Subject: [PATCH 3/3] Fixed formatting --- deno.lock | 2 + src/@resources/bucket/README.md | 1 - src/@resources/task/outputs.schema.json | 2 +- src/@resources/task/outputs.ts | 2 +- src/@resources/types.ts | 3 +- src/components/component-schema.ts | 6406 ++++++++++++----------- src/components/schema.ts | 3 +- src/datacenters/datacenter-schema.ts | 3628 ++++++------- src/datacenters/schema.ts | 10 +- src/environments/environment-schema.ts | 334 +- src/environments/schema.ts | 12 +- 11 files changed, 5248 insertions(+), 5155 deletions(-) diff --git a/deno.lock b/deno.lock index 93d600b66..7a2b9b466 100644 --- a/deno.lock +++ b/deno.lock @@ -733,6 +733,7 @@ "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700", "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59", "https://esm.sh/ansi-escapes@6.2.0": "508d1d1d8f44b52c45e9c701cd5a78c56d7764a14d005d5328f0cff72b0291b4", + "https://esm.sh/mustache@4.2.0": "da4f1d45c3fec1e78a516e6ce01ab4582ffc5b868ace8a244cc640fc25282c60", "https://esm.sh/v124/*acorn-loose@8.4.0": "5255c5344625c52612c421cb99b66d401af8772342a5de8bac38d1d78d0f94b4", "https://esm.sh/v124/*log-update@5.0.1": "49199324effae77a660f21ea75937847315fdb5f67a86881496717314bb95b2a", "https://esm.sh/v124/@aws-crypto/crc32@3.0.0/denonext/crc32.mjs": "28103a74b87c49846c0f2851adc7d6ca8f8d677f079819cd786d8f9b0af5e08e", @@ -976,6 +977,7 @@ "https://esm.sh/v124/wrap-ansi@8.1.0": "da576a84619b45bf324bfb582b74f3c38b23deb5abb204d3b3aca329f6cd970d", "https://esm.sh/v124/wrap-ansi@8.1.0/denonext/wrap-ansi.mjs": "1804d60795c6034323e4b8dc92425aa9ab28385b87bb700772e16cb92bb0d8f8", "https://esm.sh/v124/yallist@4.0.0/denonext/yallist.mjs": "61f180d807dda50bac17028eda05d5722a3fecef6e98a9064e2353ea6864fd82", + "https://esm.sh/v128/mustache@4.2.0/denonext/mustache.mjs": "8c046aa4755b9beb2f203e01fdab7d36e4c75dd1bc22021be44ac31723ead9f0", "https://esm.sh/v129/ansi-escapes@6.2.0/denonext/ansi-escapes.mjs": "e82f350a4e3ef3113cd99b6d99513de1821bb9ae50bb4ed1dbbd6b9789af560d" } } diff --git a/src/@resources/bucket/README.md b/src/@resources/bucket/README.md index 5cff8ce21..94d562ae3 100644 --- a/src/@resources/bucket/README.md +++ b/src/@resources/bucket/README.md @@ -1,2 +1 @@ # The `bucket` resource - diff --git a/src/@resources/task/outputs.schema.json b/src/@resources/task/outputs.schema.json index 2cab15f55..1f45b2852 100644 --- a/src/@resources/task/outputs.schema.json +++ b/src/@resources/task/outputs.schema.json @@ -3,7 +3,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "TaskOutputs": { - "additionalProperties": false, + "additionalProperties": {}, "type": "object" } } diff --git a/src/@resources/task/outputs.ts b/src/@resources/task/outputs.ts index bf18a2da7..f4b444a93 100644 --- a/src/@resources/task/outputs.ts +++ b/src/@resources/task/outputs.ts @@ -1,3 +1,3 @@ -export type TaskOutputs = {}; +export type TaskOutputs = Record; export default TaskOutputs; diff --git a/src/@resources/types.ts b/src/@resources/types.ts index 8a82f957d..e7b84527a 100644 --- a/src/@resources/types.ts +++ b/src/@resources/types.ts @@ -32,8 +32,7 @@ export type ResourceType = | 'secret' | 'service' | 'task' - | 'volume' -; + | 'volume'; export const ResourceTypeList: ResourceType[] = [ 'bucket', diff --git a/src/components/component-schema.ts b/src/components/component-schema.ts index 957050a0c..315a2e9af 100644 --- a/src/components/component-schema.ts +++ b/src/components/component-schema.ts @@ -1,4054 +1,4100 @@ export default { - "oneOf": [ + 'oneOf': [ { - "additionalProperties": false, - "properties": { - "databases": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "description": "A human-readable description of the database and its purpose", - "type": "string" - }, - "type": { - "description": "Type of database and version required by the application", - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'databases': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'description': 'A human-readable description of the database and its purpose', + 'type': 'string', + }, + 'type': { + 'description': 'Type of database and version required by the application', + 'type': 'string', + }, }, - "required": [ - "type" + 'required': [ + 'type', ], - "type": "object" + 'type': 'object', }, - "description": "A set of databases required by the component", - "type": "object" + 'description': 'A set of databases required by the component', + 'type': 'object', }, - "dependencies": { - "additionalProperties": { - "anyOf": [ + 'dependencies': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "component": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'component': { + 'type': 'string', }, - "inputs": { - "additionalProperties": { - "items": { - "type": "string" + 'inputs': { + 'additionalProperties': { + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "component" + 'required': [ + 'component', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A set of components and associated versions that this component depends on.", - "type": "object" + 'description': 'A set of components and associated versions that this component depends on.', + 'type': 'object', }, - "description": { - "description": "A human-readable description of the component and what it should be used for", - "type": "string" + 'description': { + 'description': 'A human-readable description of the component and what it should be used for', + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "description": { - "description": "A human-readable description of the interface and how it should be used.", - "type": "string" - }, - "ingress": { - "additionalProperties": false, - "description": "Ingress configuration to allow the interface to be exposed publicly", - "properties": { - "internal": { - "default": false, - "description": "Indicates whether the ingress rule should be attached to a public or private load balancer", - "type": "boolean" - }, - "path": { - "description": "Path that the interface should be exposed under", - "type": "string" - }, - "subdomain": { - "description": "Subdomain the interface should be accessed on", - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'description': { + 'description': 'A human-readable description of the interface and how it should be used.', + 'type': 'string', + }, + 'ingress': { + 'additionalProperties': false, + 'description': 'Ingress configuration to allow the interface to be exposed publicly', + 'properties': { + 'internal': { + 'default': false, + 'description': + 'Indicates whether the ingress rule should be attached to a public or private load balancer', + 'type': 'boolean', + }, + 'path': { + 'description': 'Path that the interface should be exposed under', + 'type': 'string', + }, + 'subdomain': { + 'description': 'Subdomain the interface should be accessed on', + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', + }, + 'url': { + 'description': + 'The url of the downstream interfaces that should be exposed. This will usually be a reference to one of your services interfaces.', + 'type': 'string', }, - "url": { - "description": "The url of the downstream interfaces that should be exposed. This will usually be a reference to one of your services interfaces.", - "type": "string" - } }, - "required": [ - "url" + 'required': [ + 'url', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A dictionary of named interfaces that the component makes available to upstreams, including other components via dependencies or environments via interface mapping.\n\nInterfaces can either be an object describing the interface, or a string shorthand that directly applies to the `url` value.", - "type": "object" + 'description': + 'A dictionary of named interfaces that the component makes available to upstreams, including other components via dependencies or environments via interface mapping.\n\nInterfaces can either be an object describing the interface, or a string shorthand that directly applies to the `url` value.', + 'type': 'object', }, - "keywords": { - "description": "An array of keywords that can be used to index the component and make it discoverable for others", - "items": { - "type": "string" + 'keywords': { + 'description': + 'An array of keywords that can be used to index the component and make it discoverable for others', + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "name": { - "description": "Unique name of the component. Must be of the format, /", - "type": "string" + 'name': { + 'description': 'Unique name of the component. Must be of the format, /', + 'type': 'string', }, - "parameters": { - "additionalProperties": { - "anyOf": [ + 'parameters': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "default": { - "description": "The default value to apply to the parameter when one wasn't provided by the operator", - "type": [ - "string", - "number" - ] - }, - "description": { - "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", - "type": "string" - }, - "merge": { - "default": false, - "description": "Whether or not to merge results from multiple sources into a single array", - "type": "boolean" - }, - "required": { - "default": false, - "description": "A boolean indicating whether or not an operator is required ot provide a value", - "type": "boolean" - } + 'additionalProperties': false, + 'properties': { + 'default': { + 'description': + 'The default value to apply to the parameter when one wasn\'t provided by the operator', + 'type': [ + 'string', + 'number', + ], + }, + 'description': { + 'description': + 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', + 'type': 'string', + }, + 'merge': { + 'default': false, + 'description': 'Whether or not to merge results from multiple sources into a single array', + 'type': 'boolean', + }, + 'required': { + 'default': false, + 'description': 'A boolean indicating whether or not an operator is required ot provide a value', + 'type': 'boolean', + }, }, - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.", - "type": "object" + 'description': + 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.', + 'type': 'object', }, - "secrets": { - "additionalProperties": { - "anyOf": [ + 'secrets': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "default": { - "description": "The default value to apply to the parameter when one wasn't provided by the operator", - "type": [ - "string", - "number" - ] - }, - "description": { - "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", - "type": "string" - }, - "merge": { - "default": false, - "description": "Whether or not to merge results from multiple sources into a single array", - "type": "boolean" - }, - "required": { - "default": false, - "description": "A boolean indicating whether or not an operator is required ot provide a value", - "type": "boolean" - } + 'additionalProperties': false, + 'properties': { + 'default': { + 'description': + 'The default value to apply to the parameter when one wasn\'t provided by the operator', + 'type': [ + 'string', + 'number', + ], + }, + 'description': { + 'description': + 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', + 'type': 'string', + }, + 'merge': { + 'default': false, + 'description': 'Whether or not to merge results from multiple sources into a single array', + 'type': 'boolean', + }, + 'required': { + 'default': false, + 'description': 'A boolean indicating whether or not an operator is required ot provide a value', + 'type': 'boolean', + }, }, - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.", - "type": "object" + 'description': + 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `inputs` field.', + 'type': 'object', }, - "services": { - "additionalProperties": { - "anyOf": [ + 'services': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "command": { - "anyOf": [ + 'additionalProperties': false, + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', + }, + 'context': { + 'type': 'string', }, - "context": { - "type": "string" + 'dockerfile': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "depends_on": { - "items": { - "type": "string" + 'depends_on': { + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', }, - "path": { - "type": "string" + 'path': { + 'type': 'string', + }, + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', + }, + 'password': { + 'type': 'string', }, - "password": { - "type": "string" + 'port': { + 'type': [ + 'number', + 'string', + ], }, - "port": { - "type": [ - "number", - "string" - ] + 'protocol': { + 'type': 'string', }, - "protocol": { - "type": "string" + 'url': { + 'type': 'string', }, - "url": { - "type": "string" + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, { - "type": "number" + 'type': 'number', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "liveness_probe": { - "additionalProperties": false, - "properties": { - "command": { - "anyOf": [ + 'liveness_probe': { + 'additionalProperties': false, + 'properties': { + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "failure_threshold": { - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "type": "string" - }, - "interval": { - "type": "string" - }, - "path": { - "type": "string" - }, - "port": { - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "type": [ - "number", - "string" - ] - }, - "timeout": { - "type": "string" - } - }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] + 'type': 'string', }, - "memory": { - "type": "string" - } - }, - "type": "object" + ], + }, + 'failure_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'initial_delay': { + 'type': 'string', + }, + 'interval': { + 'type': 'string', + }, + 'path': { + 'type': 'string', + }, + 'port': { + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'timeout': { + 'type': 'string', }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } }, - "type": "object" + 'type': 'object', + }, + 'memory': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'platform': { + 'type': 'string', + }, + 'replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'scaling': { + 'additionalProperties': false, + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'type': 'string', + }, }, - "host_path": { - "type": "string" + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + }, + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "image": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'image': { + 'type': 'string', + }, + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "depends_on": { - "description": "Specify other services that you want to wait for before starting this one", - "items": { - "type": "string" + 'depends_on': { + 'description': 'Specify other services that you want to wait for before starting this one', + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "type": "number" + 'type': 'number', }, { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" - }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', + }, + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', + }, + 'path': { + 'type': 'string', }, - "path": { - "type": "string" + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "password": { - "type": "string" + 'password': { + 'type': 'string', + }, + 'port': { + 'type': [ + 'number', + 'string', + ], }, - "port": { - "type": [ - "number", - "string" - ] + 'protocol': { + 'type': 'string', }, - "protocol": { - "type": "string" + 'url': { + 'type': 'string', }, - "url": { - "type": "string" + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "required": [ - "port" + 'required': [ + 'port', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" - }, - "language": { - "deprecated": true, - "type": "string" - }, - "liveness_probe": { - "additionalProperties": false, - "description": "Task run continuously to determine if each service replica is healthy", - "properties": { - "command": { - "anyOf": [ + 'type': 'object', + }, + 'language': { + 'deprecated': true, + 'type': 'string', + }, + 'liveness_probe': { + 'additionalProperties': false, + 'description': 'Task run continuously to determine if each service replica is healthy', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, + ], + 'description': + 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', + }, + 'failure_threshold': { + 'default': 3, + 'description': + 'The number of times to retry a failed health check before the container is considered unhealthy', + 'type': [ + 'number', + 'string', ], - "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." - }, - "failure_threshold": { - "default": 3, - "description": "The number of times to retry a failed health check before the container is considered unhealthy", - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "default": "0s", - "description": "Delays the check from running for the specified amount of time", - "type": "string" - }, - "interval": { - "default": "30s", - "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", - "type": "string" - }, - "path": { - "deprecated": true, - "type": "string" - }, - "port": { - "deprecated": true, - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "default": 1, - "description": "The number of times to retry a health check before the container is considered healthy", - "type": [ - "number", - "string" - ] - }, - "timeout": { - "default": "5s", - "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", - "type": "string" - } + }, + 'initial_delay': { + 'default': '0s', + 'description': 'Delays the check from running for the specified amount of time', + 'type': 'string', + }, + 'interval': { + 'default': '30s', + 'description': + 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', + 'type': 'string', + }, + 'path': { + 'deprecated': true, + 'type': 'string', + }, + 'port': { + 'deprecated': true, + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'default': 1, + 'description': + 'The number of times to retry a health check before the container is considered healthy', + 'type': [ + 'number', + 'string', + ], + }, + 'timeout': { + 'default': '5s', + 'description': + 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', + 'type': 'string', + }, }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "description": "Number of replicas of the deployment to run", - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "description": "Autoscaling rules for the deployment", - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "description": "Metrics to be used to trigger autoscaling", - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] - }, - "memory": { - "type": "string" - } - }, - "type": "object" - }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } + 'type': 'object', + }, + 'memory': { + 'type': 'string', + }, + 'platform': { + 'type': 'string', + }, + 'replicas': { + 'description': 'Number of replicas of the deployment to run', + 'type': [ + 'number', + 'string', + ], + }, + 'scaling': { + 'additionalProperties': false, + 'description': 'Autoscaling rules for the deployment', + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'description': 'Metrics to be used to trigger autoscaling', + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'type': 'string', + }, + }, + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', + ], + }, }, - "required": [ - "min_replicas", - "max_replicas", - "metrics" - ], - "type": "object" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" - }, - "host_path": { - "type": "string" - }, - "image": { - "type": "string" - }, - "mount_path": { - "type": "string" - }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } - }, - "required": [ - "mount_path" + 'required': [ + 'min_replicas', + 'max_replicas', + 'metrics', + ], + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', + }, + 'host_path': { + 'type': 'string', + }, + 'image': { + 'type': 'string', + }, + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], + }, + }, + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - "context": { - "type": "string" - }, - "dockerfile": { - "type": "string" - }, - "target": { - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', + }, + 'type': 'object', + }, + 'context': { + 'type': 'string', + }, + 'dockerfile': { + 'type': 'string', + }, + 'target': { + 'type': 'string', + }, }, - "required": [ - "context" + 'required': [ + 'context', ], - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "context": { - "type": "string" + 'context': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'dockerfile': { + 'type': 'string', + }, + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "depends_on": { - "items": { - "type": "string" + 'depends_on': { + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', + }, + 'path': { + 'type': 'string', }, - "path": { - "type": "string" + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "password": { - "type": "string" + 'password': { + 'type': 'string', }, - "port": { - "type": [ - "number", - "string" - ] + 'port': { + 'type': [ + 'number', + 'string', + ], }, - "protocol": { - "type": "string" + 'protocol': { + 'type': 'string', }, - "url": { - "type": "string" + 'url': { + 'type': 'string', + }, + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, { - "type": "number" + 'type': 'number', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "liveness_probe": { - "additionalProperties": false, - "properties": { - "command": { - "anyOf": [ + 'liveness_probe': { + 'additionalProperties': false, + 'properties': { + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "failure_threshold": { - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "type": "string" - }, - "interval": { - "type": "string" - }, - "path": { - "type": "string" - }, - "port": { - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "type": [ - "number", - "string" - ] - }, - "timeout": { - "type": "string" - } - }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] + 'type': 'string', }, - "memory": { - "type": "string" - } - }, - "type": "object" + ], + }, + 'failure_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'initial_delay': { + 'type': 'string', + }, + 'interval': { + 'type': 'string', + }, + 'path': { + 'type': 'string', + }, + 'port': { + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'timeout': { + 'type': 'string', }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } }, - "type": "object" + 'type': 'object', + }, + 'memory': { + 'type': 'string', + }, + 'platform': { + 'type': 'string', + }, + 'replicas': { + 'type': [ + 'number', + 'string', + ], }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'scaling': { + 'additionalProperties': false, + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'type': 'string', + }, }, - "host_path": { - "type": "string" + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + }, + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', + }, + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "depends_on": { - "description": "Specify other services that you want to wait for before starting this one", - "items": { - "type": "string" + 'depends_on': { + 'description': 'Specify other services that you want to wait for before starting this one', + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "type": "number" + 'type': 'number', }, { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" - }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', + }, + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', }, - "path": { - "type": "string" + 'path': { + 'type': 'string', + }, + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', + }, + 'password': { + 'type': 'string', }, - "password": { - "type": "string" + 'port': { + 'type': [ + 'number', + 'string', + ], }, - "port": { - "type": [ - "number", - "string" - ] + 'protocol': { + 'type': 'string', }, - "protocol": { - "type": "string" + 'url': { + 'type': 'string', }, - "url": { - "type": "string" + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "required": [ - "port" + 'required': [ + 'port', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" - }, - "language": { - "deprecated": true, - "type": "string" - }, - "liveness_probe": { - "additionalProperties": false, - "description": "Task run continuously to determine if each service replica is healthy", - "properties": { - "command": { - "anyOf": [ + 'type': 'object', + }, + 'language': { + 'deprecated': true, + 'type': 'string', + }, + 'liveness_probe': { + 'additionalProperties': false, + 'description': 'Task run continuously to determine if each service replica is healthy', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, + ], + 'description': + 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', + }, + 'failure_threshold': { + 'default': 3, + 'description': + 'The number of times to retry a failed health check before the container is considered unhealthy', + 'type': [ + 'number', + 'string', + ], + }, + 'initial_delay': { + 'default': '0s', + 'description': 'Delays the check from running for the specified amount of time', + 'type': 'string', + }, + 'interval': { + 'default': '30s', + 'description': + 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', + 'type': 'string', + }, + 'path': { + 'deprecated': true, + 'type': 'string', + }, + 'port': { + 'deprecated': true, + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'default': 1, + 'description': + 'The number of times to retry a health check before the container is considered healthy', + 'type': [ + 'number', + 'string', ], - "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." - }, - "failure_threshold": { - "default": 3, - "description": "The number of times to retry a failed health check before the container is considered unhealthy", - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "default": "0s", - "description": "Delays the check from running for the specified amount of time", - "type": "string" - }, - "interval": { - "default": "30s", - "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", - "type": "string" - }, - "path": { - "deprecated": true, - "type": "string" - }, - "port": { - "deprecated": true, - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "default": 1, - "description": "The number of times to retry a health check before the container is considered healthy", - "type": [ - "number", - "string" - ] - }, - "timeout": { - "default": "5s", - "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", - "type": "string" - } + }, + 'timeout': { + 'default': '5s', + 'description': + 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', + 'type': 'string', + }, }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "description": "Number of replicas of the deployment to run", - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "description": "Autoscaling rules for the deployment", - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "description": "Metrics to be used to trigger autoscaling", - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] - }, - "memory": { - "type": "string" - } - }, - "type": "object" - }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } + 'type': 'object', + }, + 'memory': { + 'type': 'string', + }, + 'platform': { + 'type': 'string', + }, + 'replicas': { + 'description': 'Number of replicas of the deployment to run', + 'type': [ + 'number', + 'string', + ], + }, + 'scaling': { + 'additionalProperties': false, + 'description': 'Autoscaling rules for the deployment', + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'description': 'Metrics to be used to trigger autoscaling', + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'type': 'string', + }, + }, + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', + ], + }, }, - "required": [ - "min_replicas", - "max_replicas", - "metrics" - ], - "type": "object" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" - }, - "host_path": { - "type": "string" - }, - "image": { - "type": "string" - }, - "mount_path": { - "type": "string" - }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } - }, - "required": [ - "mount_path" + 'required': [ + 'min_replicas', + 'max_replicas', + 'metrics', + ], + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', + }, + 'host_path': { + 'type': 'string', + }, + 'image': { + 'type': 'string', + }, + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], + }, + }, + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "build" + 'required': [ + 'build', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - "context": { - "type": "string" - }, - "dockerfile": { - "type": "string" - }, - "target": { - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', + }, + 'type': 'object', + }, + 'context': { + 'type': 'string', + }, + 'dockerfile': { + 'type': 'string', + }, + 'target': { + 'type': 'string', + }, }, - "required": [ - "context" + 'required': [ + 'context', ], - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', + }, + 'context': { + 'type': 'string', }, - "context": { - "type": "string" + 'dockerfile': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "depends_on": { - "items": { - "type": "string" + 'depends_on': { + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', + }, + 'path': { + 'type': 'string', }, - "path": { - "type": "string" + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "password": { - "type": "string" + 'password': { + 'type': 'string', }, - "port": { - "type": [ - "number", - "string" - ] + 'port': { + 'type': [ + 'number', + 'string', + ], + }, + 'protocol': { + 'type': 'string', }, - "protocol": { - "type": "string" + 'url': { + 'type': 'string', }, - "url": { - "type": "string" + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, { - "type": "number" + 'type': 'number', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "liveness_probe": { - "additionalProperties": false, - "properties": { - "command": { - "anyOf": [ + 'liveness_probe': { + 'additionalProperties': false, + 'properties': { + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "failure_threshold": { - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "type": "string" - }, - "interval": { - "type": "string" - }, - "path": { - "type": "string" - }, - "port": { - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "type": [ - "number", - "string" - ] - }, - "timeout": { - "type": "string" - } - }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] + 'type': 'string', }, - "memory": { - "type": "string" - } - }, - "type": "object" + ], + }, + 'failure_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'initial_delay': { + 'type': 'string', + }, + 'interval': { + 'type': 'string', + }, + 'path': { + 'type': 'string', + }, + 'port': { + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'type': [ + 'number', + 'string', + ], + }, + 'timeout': { + 'type': 'string', }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } }, - "type": "object" + 'type': 'object', + }, + 'memory': { + 'type': 'string', + }, + 'platform': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'scaling': { + 'additionalProperties': false, + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'type': 'string', + }, + }, + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + }, + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "depends_on": { - "description": "Specify other services that you want to wait for before starting this one", - "items": { - "type": "string" + 'depends_on': { + 'description': 'Specify other services that you want to wait for before starting this one', + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "interfaces": { - "additionalProperties": { - "anyOf": [ + 'interfaces': { + 'additionalProperties': { + 'anyOf': [ { - "type": "number" + 'type': 'number', }, { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "host": { - "type": "string" - }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'additionalProperties': false, + 'properties': { + 'host': { + 'type': 'string', + }, + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', + }, + 'path': { + 'type': 'string', }, - "path": { - "type": "string" + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "password": { - "type": "string" + 'password': { + 'type': 'string', }, - "port": { - "type": [ - "number", - "string" - ] + 'port': { + 'type': [ + 'number', + 'string', + ], + }, + 'protocol': { + 'type': 'string', }, - "protocol": { - "type": "string" + 'url': { + 'type': 'string', }, - "url": { - "type": "string" + 'username': { + 'type': 'string', }, - "username": { - "type": "string" - } }, - "required": [ - "port" + 'required': [ + 'port', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" - }, - "language": { - "deprecated": true, - "type": "string" - }, - "liveness_probe": { - "additionalProperties": false, - "description": "Task run continuously to determine if each service replica is healthy", - "properties": { - "command": { - "anyOf": [ + 'type': 'object', + }, + 'language': { + 'deprecated': true, + 'type': 'string', + }, + 'liveness_probe': { + 'additionalProperties': false, + 'description': 'Task run continuously to determine if each service replica is healthy', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', + }, + { + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + 'description': + 'Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set).', + }, + 'failure_threshold': { + 'default': 3, + 'description': + 'The number of times to retry a failed health check before the container is considered unhealthy', + 'type': [ + 'number', + 'string', + ], + }, + 'initial_delay': { + 'default': '0s', + 'description': 'Delays the check from running for the specified amount of time', + 'type': 'string', + }, + 'interval': { + 'default': '30s', + 'description': + 'The time period in seconds between each health check execution. You may specify any value between: 5s and 300s', + 'type': 'string', + }, + 'path': { + 'deprecated': true, + 'type': 'string', + }, + 'port': { + 'deprecated': true, + 'type': [ + 'number', + 'string', + ], + }, + 'success_threshold': { + 'default': 1, + 'description': + 'The number of times to retry a health check before the container is considered healthy', + 'type': [ + 'number', + 'string', + ], + }, + 'timeout': { + 'default': '5s', + 'description': + 'The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.', + 'type': 'string', + }, + }, + 'type': 'object', + }, + 'memory': { + 'type': 'string', + }, + 'platform': { + 'type': 'string', + }, + 'replicas': { + 'description': 'Number of replicas of the deployment to run', + 'type': [ + 'number', + 'string', + ], + }, + 'scaling': { + 'additionalProperties': false, + 'description': 'Autoscaling rules for the deployment', + 'properties': { + 'max_replicas': { + 'type': [ + 'number', + 'string', + ], + }, + 'metrics': { + 'additionalProperties': false, + 'description': 'Metrics to be used to trigger autoscaling', + 'properties': { + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - { - "items": { - "type": "string" - }, - "type": "array" - } + 'memory': { + 'type': 'string', + }, + }, + 'type': 'object', + }, + 'min_replicas': { + 'type': [ + 'number', + 'string', ], - "description": "Command that runs the http check. This field is disjunctive with `path` and `port` (only one of `command` or `path`/`port` can be set)." - }, - "failure_threshold": { - "default": 3, - "description": "The number of times to retry a failed health check before the container is considered unhealthy", - "type": [ - "number", - "string" - ] - }, - "initial_delay": { - "default": "0s", - "description": "Delays the check from running for the specified amount of time", - "type": "string" - }, - "interval": { - "default": "30s", - "description": "The time period in seconds between each health check execution. You may specify any value between: 5s and 300s", - "type": "string" - }, - "path": { - "deprecated": true, - "type": "string" - }, - "port": { - "deprecated": true, - "type": [ - "number", - "string" - ] - }, - "success_threshold": { - "default": 1, - "description": "The number of times to retry a health check before the container is considered healthy", - "type": [ - "number", - "string" - ] - }, - "timeout": { - "default": "5s", - "description": "The time period to wait for a health check to succeed before it is considered a failure. You may specify any value between 2s and 60s.", - "type": "string" - } - }, - "type": "object" - }, - "memory": { - "type": "string" - }, - "platform": { - "type": "string" - }, - "replicas": { - "description": "Number of replicas of the deployment to run", - "type": [ - "number", - "string" - ] - }, - "scaling": { - "additionalProperties": false, - "description": "Autoscaling rules for the deployment", - "properties": { - "max_replicas": { - "type": [ - "number", - "string" - ] - }, - "metrics": { - "additionalProperties": false, - "description": "Metrics to be used to trigger autoscaling", - "properties": { - "cpu": { - "type": [ - "number", - "string" - ] - }, - "memory": { - "type": "string" - } - }, - "type": "object" - }, - "min_replicas": { - "type": [ - "number", - "string" - ] - } + }, }, - "required": [ - "min_replicas", - "max_replicas", - "metrics" - ], - "type": "object" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" - }, - "host_path": { - "type": "string" - }, - "image": { - "type": "string" - }, - "mount_path": { - "type": "string" - }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } - }, - "required": [ - "mount_path" + 'required': [ + 'min_replicas', + 'max_replicas', + 'metrics', + ], + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', + }, + 'host_path': { + 'type': 'string', + }, + 'image': { + 'type': 'string', + }, + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], + }, + }, + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "build", - "image" + 'required': [ + 'build', + 'image', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A set of named services that need to be run and persisted in order to power this component.", - "type": "object" + 'description': 'A set of named services that need to be run and persisted in order to power this component.', + 'type': 'object', }, - "static": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "description": "Instructions on how to build the code into static files to be put into the `directory`. Builds will be done just-in-time (JIT) for deployments to ensure that environment variables are specific to the target environment.", - "properties": { - "command": { - "description": "Command to run to build the code", - "type": "string" - }, - "context": { - "description": "Folder to consider the context for the build relative to the component root", - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number", - "boolean" - ] + 'static': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'description': + 'Instructions on how to build the code into static files to be put into the `directory`. Builds will be done just-in-time (JIT) for deployments to ensure that environment variables are specific to the target environment.', + 'properties': { + 'command': { + 'description': 'Command to run to build the code', + 'type': 'string', + }, + 'context': { + 'description': 'Folder to consider the context for the build relative to the component root', + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + 'boolean', + ], }, - "description": "Environment variables to inject into the build process", - "type": "object" - } + 'description': 'Environment variables to inject into the build process', + 'type': 'object', + }, }, - "required": [ - "context", - "command" + 'required': [ + 'context', + 'command', ], - "type": "object" - }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "command": { - "type": "string" - }, - "context": { - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number", - "boolean" - ] - }, - "type": "object" - } + 'type': 'object', + }, + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'command': { + 'type': 'string', + }, + 'context': { + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + 'boolean', + ], + }, + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "directory": { - "type": "string" + 'directory': { + 'type': 'string', }, - "ingress": { - "additionalProperties": false, - "properties": { - "internal": { - "type": "boolean" + 'ingress': { + 'additionalProperties': false, + 'properties': { + 'internal': { + 'type': 'boolean', }, - "path": { - "type": "string" + 'path': { + 'type': 'string', + }, + 'subdomain': { + 'type': 'string', }, - "subdomain": { - "type": "string" - } }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" - }, - "directory": { - "description": "Directory containing the static assets to be shipped to the bucket", - "type": "string" - }, - "ingress": { - "additionalProperties": false, - "description": "Configure a DNS route to point to this static bucket", - "properties": { - "internal": { - "default": false, - "description": "Whether or not this bucket should be exposed internally vs externally", - "type": "boolean" - }, - "path": { - "description": "Sub-path to listen on when re-routing traffic from the ingress rule to the bucket", - "type": "string" - }, - "subdomain": { - "description": "Subdomain to use for the ingress rule", - "type": "string" - } + 'type': 'object', + }, + 'directory': { + 'description': 'Directory containing the static assets to be shipped to the bucket', + 'type': 'string', + }, + 'ingress': { + 'additionalProperties': false, + 'description': 'Configure a DNS route to point to this static bucket', + 'properties': { + 'internal': { + 'default': false, + 'description': 'Whether or not this bucket should be exposed internally vs externally', + 'type': 'boolean', + }, + 'path': { + 'description': 'Sub-path to listen on when re-routing traffic from the ingress rule to the bucket', + 'type': 'string', + }, + 'subdomain': { + 'description': 'Subdomain to use for the ingress rule', + 'type': 'string', + }, }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "directory" + 'required': [ + 'directory', ], - "type": "object" + 'type': 'object', }, - "description": "A set of static asset buckets to create and load with content.", - "type": "object" + 'description': 'A set of static asset buckets to create and load with content.', + 'type': 'object', }, - "tasks": { - "additionalProperties": { - "anyOf": [ + 'tasks': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "command": { - "anyOf": [ + 'additionalProperties': false, + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', + }, + 'context': { + 'type': 'string', }, - "context": { - "type": "string" + 'dockerfile': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "cpu": { - "type": [ - "number", - "string" - ] - }, - "entrypoint": { - "anyOf": [ + 'type': 'string', + }, + ], + }, + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "deprecated": true, - "type": "string" + 'language': { + 'deprecated': true, + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - "context": { - "type": "string" - }, - "dockerfile": { - "type": "string" - }, - "target": { - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', + }, + 'type': 'object', + }, + 'context': { + 'type': 'string', + }, + 'dockerfile': { + 'type': 'string', + }, + 'target': { + 'type': 'string', + }, }, - "required": [ - "context" + 'required': [ + 'context', ], - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', + }, + 'context': { + 'type': 'string', }, - "context": { - "type": "string" + 'dockerfile': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "cpu": { - "type": [ - "number", - "string" - ] - }, - "entrypoint": { - "anyOf": [ + 'type': 'string', + }, + ], + }, + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "deprecated": true, - "type": "string" + 'language': { + 'deprecated': true, + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "build" + 'required': [ + 'build', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - }, - "context": { - "type": "string" - }, - "dockerfile": { - "type": "string" - }, - "target": { - "type": "string" - } + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', + }, + 'type': 'object', + }, + 'context': { + 'type': 'string', + }, + 'dockerfile': { + 'type': 'string', + }, + 'target': { + 'type': 'string', + }, }, - "required": [ - "context" + 'required': [ + 'context', ], - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "cpu": { - "type": [ - "number", - "string" - ] + 'cpu': { + 'type': [ + 'number', + 'string', + ], }, - "debug": { - "additionalProperties": false, - "properties": { - "build": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'debug': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', + }, + 'context': { + 'type': 'string', }, - "context": { - "type": "string" + 'dockerfile': { + 'type': 'string', }, - "dockerfile": { - "type": "string" + 'target': { + 'type': 'string', }, - "target": { - "type": "string" - } }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] - }, - "cpu": { - "type": [ - "number", - "string" - ] - }, - "entrypoint": { - "anyOf": [ + 'type': 'string', + }, + ], + }, + 'cpu': { + 'type': [ + 'number', + 'string', + ], + }, + 'entrypoint': { + 'anyOf': [ { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', }, { - "type": "string" - } - ] + 'type': 'string', + }, + ], }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "type": "string" + 'language': { + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" - }, - "type": "array" - } - ] - }, - "environment": { - "additionalProperties": { - "type": [ - "string", - "number" - ] + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + ], + }, + 'environment': { + 'additionalProperties': { + 'type': [ + 'string', + 'number', + ], }, - "type": "object" + 'type': 'object', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "type": "object" + 'type': 'object', }, - "language": { - "deprecated": true, - "type": "string" + 'language': { + 'deprecated': true, + 'type': 'string', }, - "memory": { - "type": "string" + 'memory': { + 'type': 'string', }, - "platform": { - "type": "string" + 'platform': { + 'type': 'string', }, - "schedule": { - "type": "string" + 'schedule': { + 'type': 'string', }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "type": "string" + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'type': 'string', }, - "host_path": { - "type": "string" + 'host_path': { + 'type': 'string', }, - "image": { - "type": "string" + 'image': { + 'type': 'string', }, - "mount_path": { - "type": "string" + 'mount_path': { + 'type': 'string', + }, + 'readonly': { + 'type': [ + 'boolean', + 'string', + ], }, - "readonly": { - "type": [ - "boolean", - "string" - ] - } }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "object" - } + 'type': 'object', + }, }, - "required": [ - "build", - "image" + 'required': [ + 'build', + 'image', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A set of scheduled and triggerable tasks that get registered alongside the component. Tasks are great for data translation, reporting, and much more.", - "type": "object" + 'description': + 'A set of scheduled and triggerable tasks that get registered alongside the component. Tasks are great for data translation, reporting, and much more.', + 'type': 'object', }, - "variables": { - "additionalProperties": { - "anyOf": [ + 'variables': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "default": { - "description": "The default value to apply to the parameter when one wasn't provided by the operator", - "type": [ - "string", - "number" - ] - }, - "description": { - "description": "A human-readable description of the parameter, how it should be used, and what kinds of values it supports.", - "type": "string" - }, - "merge": { - "default": false, - "description": "Whether or not to merge results from multiple sources into a single array", - "type": "boolean" - }, - "required": { - "default": false, - "description": "A boolean indicating whether or not an operator is required ot provide a value", - "type": "boolean" - } + 'additionalProperties': false, + 'properties': { + 'default': { + 'description': + 'The default value to apply to the parameter when one wasn\'t provided by the operator', + 'type': [ + 'string', + 'number', + ], + }, + 'description': { + 'description': + 'A human-readable description of the parameter, how it should be used, and what kinds of values it supports.', + 'type': 'string', + }, + 'merge': { + 'default': false, + 'description': 'Whether or not to merge results from multiple sources into a single array', + 'type': 'boolean', + }, + 'required': { + 'default': false, + 'description': 'A boolean indicating whether or not an operator is required ot provide a value', + 'type': 'boolean', + }, }, - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `parameters` field.", - "type": "object" + 'description': + 'A dictionary of named parameters that this component uses to configure services.\n\nParameters can either be an object describing the parameter or a string shorthand that directly applies to the `default` value.\n\nThis is an alias for the `parameters` field.', + 'type': 'object', + }, + 'version': { + 'const': 'v1', + 'type': 'string', }, - "version": { - "const": "v1", - "type": "string" - } }, - "required": [ - "version" + 'required': [ + 'version', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "buckets": { - "additionalProperties": { - "anyOf": [ + 'additionalProperties': false, + 'properties': { + 'buckets': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "description": { - "description": "A human-readable description of the bucket", - "examples": [ - "CSV reporting dumps" + 'additionalProperties': false, + 'properties': { + 'description': { + 'description': 'A human-readable description of the bucket', + 'examples': [ + 'CSV reporting dumps', ], - "type": "string" + 'type': 'string', }, - "directory": { - "description": "The directory containing the contents to upload to the bucket", - "examples": [ - "./reports" + 'directory': { + 'description': 'The directory containing the contents to upload to the bucket', + 'examples': [ + './reports', ], - "type": "string" + 'type': 'string', }, - "image": { - "description": "The built image containing the contents to upload inside the workdir", - "examples": [ - "registry.architect.io/my-org/my-image:latest" + 'image': { + 'description': 'The built image containing the contents to upload inside the workdir', + 'examples': [ + 'registry.architect.io/my-org/my-image:latest', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "deploy": { - "additionalProperties": false, - "description": "Settings outlining a step that should be run when the component gets deployed", - "properties": { - "command": { - "anyOf": [ + 'additionalProperties': false, + 'properties': { + 'deploy': { + 'additionalProperties': false, + 'description': 'Settings outlining a step that should be run when the component gets deployed', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "Command to use when the container is booted up", - "examples": [ + 'description': 'Command to use when the container is booted up', + 'examples': [ [ - "npm", - "start" - ] - ] - }, - "cpu": { - "description": "The amount of CPU to allocate to each instance of the deployment", - "type": [ - "number", - "string" - ] - }, - "entrypoint": { - "anyOf": [ + 'npm', + 'start', + ], + ], + }, + 'cpu': { + 'description': 'The amount of CPU to allocate to each instance of the deployment', + 'type': [ + 'number', + 'string', + ], + }, + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "default": [ - "" + 'default': [ + '', ], - "description": "The executable to run every time the container is booted up" + 'description': 'The executable to run every time the container is booted up', }, - "environment": { - "additionalProperties": { - "type": "string" + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables to pass to the service", - "examples": [ + 'description': 'Environment variables to pass to the service', + 'examples': [ { - "NODE_ENV": "production" + 'NODE_ENV': 'production', }, { - "BACKEND_URL": "${{ ingresses.backend.url }}" - } + 'BACKEND_URL': '${{ ingresses.backend.url }}', + }, ], - "type": "object" + 'type': 'object', }, - "image": { - "description": "Docker image to use for the deployment", - "examples": [ - "${{ builds.frontend.image }}", - "my-registry.com/my-app:latest" + 'image': { + 'description': 'Docker image to use for the deployment', + 'examples': [ + '${{ builds.frontend.image }}', + 'my-registry.com/my-app:latest', ], - "type": "string" + 'type': 'string', }, - "memory": { - "description": "The amount of memory to allocate to each instance of the deployment", - "type": "string" + 'memory': { + 'description': 'The amount of memory to allocate to each instance of the deployment', + 'type': 'string', }, - "platform": { - "description": "Set platform if server is multi-platform capable", - "examples": [ - "linux/amd64" + 'platform': { + 'description': 'Set platform if server is multi-platform capable', + 'examples': [ + 'linux/amd64', ], - "type": "string" + 'type': 'string', }, - "publish": { - "description": "The path to the directory containing the contents to upload to the bucket", - "examples": [ - "./dist" + 'publish': { + 'description': 'The path to the directory containing the contents to upload to the bucket', + 'examples': [ + './dist', ], - "type": "string" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "Path on the host machine to sync with the volume", - "examples": [ - "/Users/batman/app/src" + 'type': 'string', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'Path on the host machine to sync with the volume', + 'examples': [ + '/Users/batman/app/src', ], - "type": "string" + 'type': 'string', }, - "image": { - "description": "OCI image containing the contents to seed the volume with", - "type": "string" + 'image': { + 'description': 'OCI image containing the contents to seed the volume with', + 'type': 'string', }, - "mount_path": { - "description": "Path inside the container to mount the volume to", - "examples": [ - "/app/src" + 'mount_path': { + 'description': 'Path inside the container to mount the volume to', + 'examples': [ + '/app/src', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "description": "Volumes that should be created and attached to each replica", - "type": "object" - } + 'description': 'Volumes that should be created and attached to each replica', + 'type': 'object', + }, }, - "required": [ - "image", - "publish" + 'required': [ + 'image', + 'publish', ], - "type": "object" + 'type': 'object', }, - "description": { - "description": "A human-readable description of the bucket", - "examples": [ - "A static website" + 'description': { + 'description': 'A human-readable description of the bucket', + 'examples': [ + 'A static website', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "deploy" + 'required': [ + 'deploy', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "Buckets that can be used to store and serve files", - "type": "object" + 'description': 'Buckets that can be used to store and serve files', + 'type': 'object', }, - "builds": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'builds': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "description": "A set of arguments to pass to the build job", - "examples": [ + 'description': 'A set of arguments to pass to the build job', + 'examples': [ { - "BUILDKIT_INLINE_CACHE": "1" - } + 'BUILDKIT_INLINE_CACHE': '1', + }, ], - "type": "object" + 'type': 'object', }, - "context": { - "description": "Path to the folder containing the code to build", - "examples": [ - "./" + 'context': { + 'description': 'Path to the folder containing the code to build', + 'examples': [ + './', ], - "type": "string" - }, - "debug": { - "additionalProperties": false, - "description": "Debugging options for the build step", - "properties": { - "args": { - "additionalProperties": { - "type": "string" + 'type': 'string', + }, + 'debug': { + 'additionalProperties': false, + 'description': 'Debugging options for the build step', + 'properties': { + 'args': { + 'additionalProperties': { + 'type': 'string', }, - "description": "A set of arguments to pass to the build job", - "examples": [ + 'description': 'A set of arguments to pass to the build job', + 'examples': [ { - "BUILDKIT_INLINE_CACHE": "1" - } + 'BUILDKIT_INLINE_CACHE': '1', + }, ], - "type": "object" + 'type': 'object', }, - "context": { - "description": "Path to the folder containing the code to build", - "examples": [ - "./" + 'context': { + 'description': 'Path to the folder containing the code to build', + 'examples': [ + './', ], - "type": "string" + 'type': 'string', }, - "description": { - "description": "Description of the build artifact", - "examples": [ - "Builds the source code for the application" + 'description': { + 'description': 'Description of the build artifact', + 'examples': [ + 'Builds the source code for the application', ], - "type": "string" - }, - "dockerfile": { - "default": "Dockerfile", - "description": "The path to the dockerfile defining this build step", - "type": "string" - }, - "image": { - "description": "The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.", - "examples": [ - "my-registry.com/my-app:latest" + 'type': 'string', + }, + 'dockerfile': { + 'default': 'Dockerfile', + 'description': 'The path to the dockerfile defining this build step', + 'type': 'string', + }, + 'image': { + 'description': + 'The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.', + 'examples': [ + 'my-registry.com/my-app:latest', ], - "type": "string" + 'type': 'string', }, - "target": { - "description": "The docker target to use during the build process", - "examples": [ - "builder" + 'target': { + 'description': 'The docker target to use during the build process', + 'examples': [ + 'builder', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "description": { - "description": "Description of the build artifact", - "examples": [ - "Builds the source code for the application" + 'description': { + 'description': 'Description of the build artifact', + 'examples': [ + 'Builds the source code for the application', ], - "type": "string" + 'type': 'string', }, - "dockerfile": { - "default": "Dockerfile", - "description": "The path to the dockerfile defining this build step", - "type": "string" + 'dockerfile': { + 'default': 'Dockerfile', + 'description': 'The path to the dockerfile defining this build step', + 'type': 'string', }, - "image": { - "description": "The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.", - "examples": [ - "my-registry.com/my-app:latest" + 'image': { + 'description': + 'The resulting image that was created once the build is complete. This will change whenever the component is tagged as well.', + 'examples': [ + 'my-registry.com/my-app:latest', ], - "type": "string" + 'type': 'string', }, - "target": { - "description": "The docker target to use during the build process", - "examples": [ - "builder" + 'target': { + 'description': 'The docker target to use during the build process', + 'examples': [ + 'builder', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "context" + 'required': [ + 'context', ], - "type": "object" + 'type': 'object', }, - "description": "A set of build jobs to run to power other deployments or tasks", - "type": "object" + 'description': 'A set of build jobs to run to power other deployments or tasks', + 'type': 'object', }, - "databases": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "description": { - "default": "", - "description": "A human-readable description of the use-case for the database", - "type": "string" - }, - "migrate": { - "additionalProperties": false, - "description": "Configuration details for how to run database migrations", - "properties": { - "command": { - "anyOf": [ + 'databases': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'description': { + 'default': '', + 'description': 'A human-readable description of the use-case for the database', + 'type': 'string', + }, + 'migrate': { + 'additionalProperties': false, + 'description': 'Configuration details for how to run database migrations', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "A command to run in the container to execute the migration", - "examples": [ + 'description': 'A command to run in the container to execute the migration', + 'examples': [ [ - "npm", - "run", - "migrate" - ] - ] - }, - "entrypoint": { - "anyOf": [ + 'npm', + 'run', + 'migrate', + ], + ], + }, + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "default": [ - "" + 'default': [ + '', ], - "description": "An entrypoint to use for the docker container" + 'description': 'An entrypoint to use for the docker container', }, - "environment": { - "additionalProperties": { - "anyOf": [ + 'environment': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "type": "number" + 'type': 'number', }, { - "type": "boolean" + 'type': 'boolean', }, { - "type": "null" + 'type': 'null', }, { - "not": {} - } - ] + 'not': {}, + }, + ], }, - "description": "Environment variables to set in the container", - "examples": [ + 'description': 'Environment variables to set in the container', + 'examples': [ { - "DATABASE_URL": "${{ databases.auth.url }}" - } + 'DATABASE_URL': '${{ databases.auth.url }}', + }, ], - "type": "object" + 'type': 'object', }, - "image": { - "description": "The docker image containing the migration tooling and files", - "examples": [ - "${{ builds.api.image }}" + 'image': { + 'description': 'The docker image containing the migration tooling and files', + 'examples': [ + '${{ builds.api.image }}', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" - }, - "seed": { - "additionalProperties": false, - "description": "Configuration details for how to seed the database", - "properties": { - "command": { - "anyOf": [ + 'type': 'object', + }, + 'seed': { + 'additionalProperties': false, + 'description': 'Configuration details for how to seed the database', + 'properties': { + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "A command to run in the container to execute the seeding", - "examples": [ + 'description': 'A command to run in the container to execute the seeding', + 'examples': [ [ - "npm", - "run", - "seed" - ] - ] - }, - "entrypoint": { - "anyOf": [ + 'npm', + 'run', + 'seed', + ], + ], + }, + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "default": [ - "" + 'default': [ + '', ], - "description": "An entrypoint to use for the docker container" + 'description': 'An entrypoint to use for the docker container', }, - "environment": { - "additionalProperties": { - "anyOf": [ + 'environment': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "type": "number" + 'type': 'number', }, { - "type": "boolean" + 'type': 'boolean', }, { - "type": "null" + 'type': 'null', }, { - "not": {} - } - ] + 'not': {}, + }, + ], }, - "description": "Environment variables to set in the container", - "examples": [ + 'description': 'Environment variables to set in the container', + 'examples': [ { - "DATABASE_URL": "${{ databases.auth.url }}" - } + 'DATABASE_URL': '${{ databases.auth.url }}', + }, ], - "type": "object" + 'type': 'object', }, - "image": { - "description": "The docker image containing the seeding tooling and files", - "examples": [ - "${{ builds.api.image }}" + 'image': { + 'description': 'The docker image containing the seeding tooling and files', + 'examples': [ + '${{ builds.api.image }}', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" - }, - "type": { - "description": "The type of database and version to use", - "examples": [ - "postgres:15", - "mysql:8", - "redis:5" + 'type': 'object', + }, + 'type': { + 'description': 'The type of database and version to use', + 'examples': [ + 'postgres:15', + 'mysql:8', + 'redis:5', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "type" + 'required': [ + 'type', ], - "type": "object" + 'type': 'object', }, - "description": "A set of databases that this component requires", - "type": "object" + 'description': 'A set of databases that this component requires', + 'type': 'object', }, - "dependencies": { - "additionalProperties": { - "anyOf": [ + 'dependencies': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "additionalProperties": false, - "properties": { - "component": { - "description": "The repo the component is in", - "type": "string" - }, - "variables": { - "additionalProperties": { - "anyOf": [ + 'additionalProperties': false, + 'properties': { + 'component': { + 'description': 'The repo the component is in', + 'type': 'string', + }, + 'variables': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "description": "Input values to provide to the component if `merge` is turned on", - "examples": [ + 'description': 'Input values to provide to the component if `merge` is turned on', + 'examples': [ { - "allowed_return_urls": [ - "https://architect.io", - "${{ ingresses.frontend.url }}" - ] - } - ], - "type": "object" - } + 'allowed_return_urls': [ + 'https://architect.io', + '${{ ingresses.frontend.url }}', + ], + }, + ], + 'type': 'object', + }, }, - "required": [ - "component" + 'required': [ + 'component', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "A set of other components that this component depends on", - "examples": [ + 'description': 'A set of other components that this component depends on', + 'examples': [ { - "auth": { - "component": "architect/auth-component", - "variables": { - "allowed_return_urls": [ - "https://architect.io", - "${{ ingresses.frontend.url }}" - ] - } - }, - "payments": "architect/payments-component" - } + 'auth': { + 'component': 'architect/auth-component', + 'variables': { + 'allowed_return_urls': [ + 'https://architect.io', + '${{ ingresses.frontend.url }}', + ], + }, + }, + 'payments': 'architect/payments-component', + }, ], - "type": "object" + 'type': 'object', }, - "deployments": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "autoscaling": { - "additionalProperties": false, - "description": "Configuration settings for how to automatically scale the application up and down", - "properties": { - "cpu": { - "description": "Maximum number of CPUs to allocate to each replica", - "examples": [ - "0.5", - "1" - ], - "type": [ - "number", - "string" - ] - }, - "memory": { - "description": "Maximum memory usage per replica before scaling up", - "examples": [ - "200Mi", - "2Gi" - ], - "type": "string" - } + 'deployments': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'autoscaling': { + 'additionalProperties': false, + 'description': 'Configuration settings for how to automatically scale the application up and down', + 'properties': { + 'cpu': { + 'description': 'Maximum number of CPUs to allocate to each replica', + 'examples': [ + '0.5', + '1', + ], + 'type': [ + 'number', + 'string', + ], + }, + 'memory': { + 'description': 'Maximum memory usage per replica before scaling up', + 'examples': [ + '200Mi', + '2Gi', + ], + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "Command to use when the container is booted up", - "examples": [ + 'description': 'Command to use when the container is booted up', + 'examples': [ [ - "npm", - "start" - ] - ] - }, - "cpu": { - "description": "The amount of CPU to allocate to each instance of the deployment", - "type": [ - "number", - "string" - ] - }, - "debug": { - "additionalProperties": false, - "description": "Debugging options for the deployment", - "properties": { - "autoscaling": { - "additionalProperties": false, - "description": "Configuration settings for how to automatically scale the application up and down", - "properties": { - "cpu": { - "description": "Maximum number of CPUs to allocate to each replica", - "examples": [ - "0.5", - "1" + 'npm', + 'start', + ], + ], + }, + 'cpu': { + 'description': 'The amount of CPU to allocate to each instance of the deployment', + 'type': [ + 'number', + 'string', + ], + }, + 'debug': { + 'additionalProperties': false, + 'description': 'Debugging options for the deployment', + 'properties': { + 'autoscaling': { + 'additionalProperties': false, + 'description': 'Configuration settings for how to automatically scale the application up and down', + 'properties': { + 'cpu': { + 'description': 'Maximum number of CPUs to allocate to each replica', + 'examples': [ + '0.5', + '1', + ], + 'type': [ + 'number', + 'string', ], - "type": [ - "number", - "string" - ] - }, - "memory": { - "description": "Maximum memory usage per replica before scaling up", - "examples": [ - "200Mi", - "2Gi" + }, + 'memory': { + 'description': 'Maximum memory usage per replica before scaling up', + 'examples': [ + '200Mi', + '2Gi', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "command": { - "anyOf": [ + 'command': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "Command to use when the container is booted up", - "examples": [ + 'description': 'Command to use when the container is booted up', + 'examples': [ [ - "npm", - "start" - ] - ] - }, - "cpu": { - "description": "The amount of CPU to allocate to each instance of the deployment", - "type": [ - "number", - "string" - ] - }, - "description": { - "description": "Human readable description of the deployment", - "examples": [ - "Runs the frontend web application" - ], - "type": "string" - }, - "entrypoint": { - "anyOf": [ + 'npm', + 'start', + ], + ], + }, + 'cpu': { + 'description': 'The amount of CPU to allocate to each instance of the deployment', + 'type': [ + 'number', + 'string', + ], + }, + 'description': { + 'description': 'Human readable description of the deployment', + 'examples': [ + 'Runs the frontend web application', + ], + 'type': 'string', + }, + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "default": [ - "" + 'default': [ + '', ], - "description": "The executable to run every time the container is booted up" + 'description': 'The executable to run every time the container is booted up', }, - "environment": { - "additionalProperties": { - "type": "string" + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables to pass to the service", - "examples": [ + 'description': 'Environment variables to pass to the service', + 'examples': [ { - "NODE_ENV": "production" + 'NODE_ENV': 'production', }, { - "BACKEND_URL": "${{ ingresses.backend.url }}" - } + 'BACKEND_URL': '${{ ingresses.backend.url }}', + }, ], - "type": "object" + 'type': 'object', }, - "image": { - "description": "Docker image to use for the deployment", - "examples": [ - "${{ builds.frontend.image }}", - "my-registry.com/my-app:latest" + 'image': { + 'description': 'Docker image to use for the deployment', + 'examples': [ + '${{ builds.frontend.image }}', + 'my-registry.com/my-app:latest', ], - "type": "string" + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "description": "The labels to apply to the deployment", - "type": "object" - }, - "memory": { - "description": "The amount of memory to allocate to each instance of the deployment", - "type": "string" - }, - "platform": { - "description": "Set platform if server is multi-platform capable", - "examples": [ - "linux/amd64" - ], - "type": "string" - }, - "probes": { - "additionalProperties": false, - "description": "Configuration details for probes that check each replicas status", - "properties": { - "liveness": { - "anyOf": [ + 'description': 'The labels to apply to the deployment', + 'type': 'object', + }, + 'memory': { + 'description': 'The amount of memory to allocate to each instance of the deployment', + 'type': 'string', + }, + 'platform': { + 'description': 'Set platform if server is multi-platform capable', + 'examples': [ + 'linux/amd64', + ], + 'type': 'string', + }, + 'probes': { + 'additionalProperties': false, + 'description': 'Configuration details for probes that check each replicas status', + 'properties': { + 'liveness': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "command": { - "description": "Command to run inside the container to determine if its healthy", - "items": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'command': { + 'description': 'Command to run inside the container to determine if its healthy', + 'items': { + 'type': 'string', }, - "type": "array" + 'type': 'array', + }, + 'failure_threshold': { + 'default': 3, + 'description': + 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', + 'minimum': 1, + 'type': 'number', }, - "failure_threshold": { - "default": 3, - "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", - "minimum": 1, - "type": "number" + 'initial_delay': { + 'default': 0, + 'description': + 'Number of seconds after the container starts before the probe is initiated.', + 'minimum': 0, + 'type': 'number', }, - "initial_delay": { - "default": 0, - "description": "Number of seconds after the container starts before the probe is initiated.", - "minimum": 0, - "type": "number" + 'interval': { + 'default': 10, + 'description': 'How often (in seconds) to perform the probe.', + 'minimum': 1, + 'type': 'number', }, - "interval": { - "default": 10, - "description": "How often (in seconds) to perform the probe.", - "minimum": 1, - "type": "number" + 'success_threshold': { + 'default': 1, + 'description': + 'Minimum consecutive successes for the probe to be considered successful after having failed.', + 'minimum': 1, + 'type': 'number', }, - "success_threshold": { - "default": 1, - "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", - "minimum": 1, - "type": "number" + 'timeout': { + 'default': 1, + 'description': 'Number of seconds after which the probe times out', + 'minimum': 1, + 'type': 'number', }, - "timeout": { - "default": 1, - "description": "Number of seconds after which the probe times out", - "minimum": 1, - "type": "number" + 'type': { + 'const': 'exec', + 'type': 'string', }, - "type": { - "const": "exec", - "type": "string" - } - }, - "required": [ - "command", - "type" + }, + 'required': [ + 'command', + 'type', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "failure_threshold": { - "default": 3, - "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", - "minimum": 1, - "type": "number" + 'additionalProperties': false, + 'properties': { + 'failure_threshold': { + 'default': 3, + 'description': + 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', + 'minimum': 1, + 'type': 'number', }, - "headers": { - "description": "Custom headers to set in the request.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "type": "string" + 'headers': { + 'description': 'Custom headers to set in the request.', + 'items': { + 'additionalProperties': false, + 'properties': { + 'name': { + 'type': 'string', + }, + 'value': { + 'type': 'string', }, - "value": { - "type": "string" - } }, - "required": [ - "name", - "value" + 'required': [ + 'name', + 'value', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "initial_delay": { - "default": 0, - "description": "Number of seconds after the container starts before the probe is initiated.", - "minimum": 0, - "type": "number" + 'initial_delay': { + 'default': 0, + 'description': + 'Number of seconds after the container starts before the probe is initiated.', + 'minimum': 0, + 'type': 'number', }, - "interval": { - "default": 10, - "description": "How often (in seconds) to perform the probe.", - "minimum": 1, - "type": "number" + 'interval': { + 'default': 10, + 'description': 'How often (in seconds) to perform the probe.', + 'minimum': 1, + 'type': 'number', }, - "path": { - "default": "/", - "description": "Path to access on the http server", - "type": "string" + 'path': { + 'default': '/', + 'description': 'Path to access on the http server', + 'type': 'string', }, - "port": { - "description": "Port to access on the container", - "type": "number" + 'port': { + 'description': 'Port to access on the container', + 'type': 'number', }, - "scheme": { - "default": "http", - "description": "Scheme to use for connecting to the host (http or https).", - "type": "string" + 'scheme': { + 'default': 'http', + 'description': 'Scheme to use for connecting to the host (http or https).', + 'type': 'string', }, - "success_threshold": { - "default": 1, - "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", - "minimum": 1, - "type": "number" + 'success_threshold': { + 'default': 1, + 'description': + 'Minimum consecutive successes for the probe to be considered successful after having failed.', + 'minimum': 1, + 'type': 'number', }, - "timeout": { - "default": 1, - "description": "Number of seconds after which the probe times out", - "minimum": 1, - "type": "number" + 'timeout': { + 'default': 1, + 'description': 'Number of seconds after which the probe times out', + 'minimum': 1, + 'type': 'number', + }, + 'type': { + 'const': 'http', + 'type': 'string', }, - "type": { - "const": "http", - "type": "string" - } }, - "required": [ - "type" + 'required': [ + 'type', ], - "type": "object" - } + 'type': 'object', + }, ], - "description": "Configuration settings to determine if the deployment is ready to receive traffic" - } + 'description': + 'Configuration settings to determine if the deployment is ready to receive traffic', + }, }, - "type": "object" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "Path on the host machine to sync with the volume", - "examples": [ - "/Users/batman/app/src" + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'Path on the host machine to sync with the volume', + 'examples': [ + '/Users/batman/app/src', ], - "type": "string" + 'type': 'string', }, - "image": { - "description": "OCI image containing the contents to seed the volume with", - "type": "string" + 'image': { + 'description': 'OCI image containing the contents to seed the volume with', + 'type': 'string', }, - "mount_path": { - "description": "Path inside the container to mount the volume to", - "examples": [ - "/app/src" + 'mount_path': { + 'description': 'Path inside the container to mount the volume to', + 'examples': [ + '/app/src', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "description": "Volumes that should be created and attached to each replica", - "type": "object" - } + 'description': 'Volumes that should be created and attached to each replica', + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "description": { - "description": "Human readable description of the deployment", - "examples": [ - "Runs the frontend web application" + 'description': { + 'description': 'Human readable description of the deployment', + 'examples': [ + 'Runs the frontend web application', ], - "type": "string" + 'type': 'string', }, - "entrypoint": { - "anyOf": [ + 'entrypoint': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "default": [ - "" + 'default': [ + '', ], - "description": "The executable to run every time the container is booted up" + 'description': 'The executable to run every time the container is booted up', }, - "environment": { - "additionalProperties": { - "type": "string" + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables to pass to the service", - "examples": [ + 'description': 'Environment variables to pass to the service', + 'examples': [ { - "NODE_ENV": "production" + 'NODE_ENV': 'production', }, { - "BACKEND_URL": "${{ ingresses.backend.url }}" - } + 'BACKEND_URL': '${{ ingresses.backend.url }}', + }, ], - "type": "object" + 'type': 'object', }, - "image": { - "description": "Docker image to use for the deployment", - "examples": [ - "${{ builds.frontend.image }}", - "my-registry.com/my-app:latest" + 'image': { + 'description': 'Docker image to use for the deployment', + 'examples': [ + '${{ builds.frontend.image }}', + 'my-registry.com/my-app:latest', ], - "type": "string" + 'type': 'string', }, - "labels": { - "additionalProperties": { - "type": "string" + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "description": "The labels to apply to the deployment", - "type": "object" + 'description': 'The labels to apply to the deployment', + 'type': 'object', }, - "memory": { - "description": "The amount of memory to allocate to each instance of the deployment", - "type": "string" + 'memory': { + 'description': 'The amount of memory to allocate to each instance of the deployment', + 'type': 'string', }, - "platform": { - "description": "Set platform if server is multi-platform capable", - "examples": [ - "linux/amd64" + 'platform': { + 'description': 'Set platform if server is multi-platform capable', + 'examples': [ + 'linux/amd64', ], - "type": "string" - }, - "probes": { - "additionalProperties": false, - "description": "Configuration details for probes that check each replicas status", - "properties": { - "liveness": { - "anyOf": [ + 'type': 'string', + }, + 'probes': { + 'additionalProperties': false, + 'description': 'Configuration details for probes that check each replicas status', + 'properties': { + 'liveness': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "command": { - "description": "Command to run inside the container to determine if its healthy", - "items": { - "type": "string" - }, - "type": "array" - }, - "failure_threshold": { - "default": 3, - "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", - "minimum": 1, - "type": "number" - }, - "initial_delay": { - "default": 0, - "description": "Number of seconds after the container starts before the probe is initiated.", - "minimum": 0, - "type": "number" - }, - "interval": { - "default": 10, - "description": "How often (in seconds) to perform the probe.", - "minimum": 1, - "type": "number" - }, - "success_threshold": { - "default": 1, - "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", - "minimum": 1, - "type": "number" - }, - "timeout": { - "default": 1, - "description": "Number of seconds after which the probe times out", - "minimum": 1, - "type": "number" - }, - "type": { - "const": "exec", - "type": "string" - } - }, - "required": [ - "command", - "type" + 'additionalProperties': false, + 'properties': { + 'command': { + 'description': 'Command to run inside the container to determine if its healthy', + 'items': { + 'type': 'string', + }, + 'type': 'array', + }, + 'failure_threshold': { + 'default': 3, + 'description': + 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', + 'minimum': 1, + 'type': 'number', + }, + 'initial_delay': { + 'default': 0, + 'description': + 'Number of seconds after the container starts before the probe is initiated.', + 'minimum': 0, + 'type': 'number', + }, + 'interval': { + 'default': 10, + 'description': 'How often (in seconds) to perform the probe.', + 'minimum': 1, + 'type': 'number', + }, + 'success_threshold': { + 'default': 1, + 'description': + 'Minimum consecutive successes for the probe to be considered successful after having failed.', + 'minimum': 1, + 'type': 'number', + }, + 'timeout': { + 'default': 1, + 'description': 'Number of seconds after which the probe times out', + 'minimum': 1, + 'type': 'number', + }, + 'type': { + 'const': 'exec', + 'type': 'string', + }, + }, + 'required': [ + 'command', + 'type', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "failure_threshold": { - "default": 3, - "description": "Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.", - "minimum": 1, - "type": "number" - }, - "headers": { - "description": "Custom headers to set in the request.", - "items": { - "additionalProperties": false, - "properties": { - "name": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'failure_threshold': { + 'default': 3, + 'description': + 'Number of times the probe will tolerate failure before giving up. Giving up in the case of liveness probe means restarting the container.', + 'minimum': 1, + 'type': 'number', + }, + 'headers': { + 'description': 'Custom headers to set in the request.', + 'items': { + 'additionalProperties': false, + 'properties': { + 'name': { + 'type': 'string', + }, + 'value': { + 'type': 'string', }, - "value": { - "type": "string" - } }, - "required": [ - "name", - "value" + 'required': [ + 'name', + 'value', ], - "type": "object" - }, - "type": "array" - }, - "initial_delay": { - "default": 0, - "description": "Number of seconds after the container starts before the probe is initiated.", - "minimum": 0, - "type": "number" - }, - "interval": { - "default": 10, - "description": "How often (in seconds) to perform the probe.", - "minimum": 1, - "type": "number" - }, - "path": { - "default": "/", - "description": "Path to access on the http server", - "type": "string" - }, - "port": { - "description": "Port to access on the container", - "type": "number" - }, - "scheme": { - "default": "http", - "description": "Scheme to use for connecting to the host (http or https).", - "type": "string" - }, - "success_threshold": { - "default": 1, - "description": "Minimum consecutive successes for the probe to be considered successful after having failed.", - "minimum": 1, - "type": "number" - }, - "timeout": { - "default": 1, - "description": "Number of seconds after which the probe times out", - "minimum": 1, - "type": "number" - }, - "type": { - "const": "http", - "type": "string" - } - }, - "required": [ - "type" + 'type': 'object', + }, + 'type': 'array', + }, + 'initial_delay': { + 'default': 0, + 'description': + 'Number of seconds after the container starts before the probe is initiated.', + 'minimum': 0, + 'type': 'number', + }, + 'interval': { + 'default': 10, + 'description': 'How often (in seconds) to perform the probe.', + 'minimum': 1, + 'type': 'number', + }, + 'path': { + 'default': '/', + 'description': 'Path to access on the http server', + 'type': 'string', + }, + 'port': { + 'description': 'Port to access on the container', + 'type': 'number', + }, + 'scheme': { + 'default': 'http', + 'description': 'Scheme to use for connecting to the host (http or https).', + 'type': 'string', + }, + 'success_threshold': { + 'default': 1, + 'description': + 'Minimum consecutive successes for the probe to be considered successful after having failed.', + 'minimum': 1, + 'type': 'number', + }, + 'timeout': { + 'default': 1, + 'description': 'Number of seconds after which the probe times out', + 'minimum': 1, + 'type': 'number', + }, + 'type': { + 'const': 'http', + 'type': 'string', + }, + }, + 'required': [ + 'type', ], - "type": "object" - } + 'type': 'object', + }, ], - "description": "Configuration settings to determine if the deployment is ready to receive traffic" - } + 'description': 'Configuration settings to determine if the deployment is ready to receive traffic', + }, }, - "type": "object" - }, - "volumes": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "Path on the host machine to sync with the volume", - "examples": [ - "/Users/batman/app/src" + 'type': 'object', + }, + 'volumes': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'Path on the host machine to sync with the volume', + 'examples': [ + '/Users/batman/app/src', ], - "type": "string" + 'type': 'string', }, - "image": { - "description": "OCI image containing the contents to seed the volume with", - "type": "string" + 'image': { + 'description': 'OCI image containing the contents to seed the volume with', + 'type': 'string', }, - "mount_path": { - "description": "Path inside the container to mount the volume to", - "examples": [ - "/app/src" + 'mount_path': { + 'description': 'Path inside the container to mount the volume to', + 'examples': [ + '/app/src', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "mount_path" + 'required': [ + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "description": "Volumes that should be created and attached to each replica", - "type": "object" - } + 'description': 'Volumes that should be created and attached to each replica', + 'type': 'object', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" + 'type': 'object', }, - "description": "Workloads that should be deployed", - "type": "object" + 'description': 'Workloads that should be deployed', + 'type': 'object', }, - "ingresses": { - "additionalProperties": { - "anyOf": [ + 'ingresses': { + 'additionalProperties': { + 'anyOf': [ { - "additionalProperties": false, - "properties": { - "headers": { - "additionalProperties": { - "type": "string" + 'additionalProperties': false, + 'properties': { + 'headers': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Additional headers to include in responses", - "examples": [ + 'description': 'Additional headers to include in responses', + 'examples': [ { - "Access-Control-Allow-Credentials": "true", - "Access-Control-Allow-Origin": "${{ variables.allowed_return_urls }}" - } + 'Access-Control-Allow-Credentials': 'true', + 'Access-Control-Allow-Origin': '${{ variables.allowed_return_urls }}', + }, ], - "type": "object" + 'type': 'object', }, - "internal": { - "default": false, - "description": "Whether or not the ingress rule should be attached to an internal gateway", - "type": "boolean" + 'internal': { + 'default': false, + 'description': 'Whether or not the ingress rule should be attached to an internal gateway', + 'type': 'boolean', }, - "service": { - "description": "Service the ingress rule forwards traffic to", - "examples": [ - "backend" + 'service': { + 'description': 'Service the ingress rule forwards traffic to', + 'examples': [ + 'backend', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "service" + 'required': [ + 'service', ], - "type": "object" + 'type': 'object', }, { - "additionalProperties": false, - "properties": { - "bucket": { - "description": "The static bucket to serve content from", - "examples": [ - "my-bucket" - ], - "type": "string" - }, - "internal": { - "default": false, - "description": "Whether or not the ingress rule should be attached to an internal gateway", - "type": "boolean" - } + 'additionalProperties': false, + 'properties': { + 'bucket': { + 'description': 'The static bucket to serve content from', + 'examples': [ + 'my-bucket', + ], + 'type': 'string', + }, + 'internal': { + 'default': false, + 'description': 'Whether or not the ingress rule should be attached to an internal gateway', + 'type': 'boolean', + }, }, - "required": [ - "bucket" + 'required': [ + 'bucket', ], - "type": "object" - } - ] + 'type': 'object', + }, + ], }, - "description": "Claims for external (e.g. client) access to a service", - "type": "object" + 'description': 'Claims for external (e.g. client) access to a service', + 'type': 'object', }, - "services": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "deployment": { - "description": "Deployment the service sends requests to", - "examples": [ - "backend" + 'services': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'deployment': { + 'description': 'Deployment the service sends requests to', + 'examples': [ + 'backend', ], - "type": "string" + 'type': 'string', }, - "description": { - "description": "Description of the service", - "examples": [ - "Exposes the backend to other applications" + 'description': { + 'description': 'Description of the service', + 'examples': [ + 'Exposes the backend to other applications', ], - "type": "string" + 'type': 'string', }, - "password": { - "description": "Basic auth password", - "type": "string" + 'password': { + 'description': 'Basic auth password', + 'type': 'string', }, - "port": { - "description": "Port the service listens on", - "examples": [ - 8080 + 'port': { + 'description': 'Port the service listens on', + 'examples': [ + 8080, ], - "type": "number" + 'type': 'number', }, - "protocol": { - "default": "http", - "description": "Protocol the service listens on", - "type": "string" + 'protocol': { + 'default': 'http', + 'description': 'Protocol the service listens on', + 'type': 'string', + }, + 'username': { + 'description': 'Basic auth username', + 'type': 'string', }, - "username": { - "description": "Basic auth username", - "type": "string" - } }, - "required": [ - "deployment", - "port" + 'required': [ + 'deployment', + 'port', ], - "type": "object" + 'type': 'object', }, - "description": "Services that can receive network traffic", - "type": "object" + 'description': 'Services that can receive network traffic', + 'type': 'object', }, - "variables": { - "additionalProperties": { - "additionalProperties": false, - "properties": { - "default": { - "anyOf": [ + 'variables': { + 'additionalProperties': { + 'additionalProperties': false, + 'properties': { + 'default': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } + 'type': 'array', + }, ], - "description": "A default value to use if one isn't provided", - "examples": [ - "https://architect.io" - ] - }, - "description": { - "description": "A human-readable description", - "examples": [ - "API key used to authenticate with Stripe" + 'description': 'A default value to use if one isn\'t provided', + 'examples': [ + 'https://architect.io', ], - "type": "string" - }, - "merge": { - "default": false, - "description": "If true, upstream components can pass in values that will be merged together with each other and environment-provided values", - "type": "boolean" - }, - "required": { - "default": false, - "description": "If true, a value is required or the component won't run.", - "type": "boolean" - }, - "sensitive": { - "default": false, - "description": "Whether or not the data should be considered sensitive and stripped from logs", - "type": "boolean" - } + }, + 'description': { + 'description': 'A human-readable description', + 'examples': [ + 'API key used to authenticate with Stripe', + ], + 'type': 'string', + }, + 'merge': { + 'default': false, + 'description': + 'If true, upstream components can pass in values that will be merged together with each other and environment-provided values', + 'type': 'boolean', + }, + 'required': { + 'default': false, + 'description': 'If true, a value is required or the component won\'t run.', + 'type': 'boolean', + }, + 'sensitive': { + 'default': false, + 'description': 'Whether or not the data should be considered sensitive and stripped from logs', + 'type': 'boolean', + }, }, - "type": "object" + 'type': 'object', }, - "description": "A set of inputs the component expects to be provided", - "type": "object" + 'description': 'A set of inputs the component expects to be provided', + 'type': 'object', + }, + 'version': { + 'const': 'v2', + 'type': 'string', }, - "version": { - "const": "v2", - "type": "string" - } }, - "required": [ - "version" + 'required': [ + 'version', ], - "type": "object" - } + 'type': 'object', + }, ], - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://architect.io/.schemas/component.json", - "type": "object", - "required": [ - "version" + '$schema': 'https://json-schema.org/draft/2019-09/schema', + '$id': 'https://architect.io/.schemas/component.json', + 'type': 'object', + 'required': [ + 'version', ], - "discriminator": { - "propertyName": "version" - } -} \ No newline at end of file + 'discriminator': { + 'propertyName': 'version', + }, +}; diff --git a/src/components/schema.ts b/src/components/schema.ts index a54e99350..44c54456a 100644 --- a/src/components/schema.ts +++ b/src/components/schema.ts @@ -7,8 +7,7 @@ export type ComponentSchema = } & component_v1) | ({ version: 'v2'; - } & component_v2) -; + } & component_v2); export const buildComponent = (data: ComponentSchema) => { switch (data.version) { diff --git a/src/datacenters/datacenter-schema.ts b/src/datacenters/datacenter-schema.ts index 0bc2a0025..21636e9e3 100644 --- a/src/datacenters/datacenter-schema.ts +++ b/src/datacenters/datacenter-schema.ts @@ -1,2263 +1,2313 @@ export default { - "$ref": "#/definitions/DatacenterSchema", - "$schema": "http://json-schema.org/draft-07/schema#", - "definitions": { - "DatacenterSchema": { - "additionalProperties": false, - "properties": { - "environment": { - "description": "Rules dictating what resources should be created in each environment hosted by the datacenter", - "items": { - "additionalProperties": false, - "properties": { - "bucket": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + '$ref': '#/definitions/DatacenterSchema', + '$schema': 'http://json-schema.org/draft-07/schema#', + 'definitions': { + 'DatacenterSchema': { + 'additionalProperties': false, + 'properties': { + 'environment': { + 'description': + 'Rules dictating what resources should be created in each environment hosted by the datacenter', + 'items': { + 'additionalProperties': false, + 'properties': { + 'bucket': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "access_key_id": { - "description": "Access key ID used to authenticate with the bucket", - "type": "string" - }, - "endpoint": { - "description": "Endpoint that hosts the bucket", - "examples": [ - "https://nyc3.digitaloceanspaces.com", - "https://bucket.s3.region.amazonaws.com" + 'properties': { + 'access_key_id': { + 'description': 'Access key ID used to authenticate with the bucket', + 'type': 'string', + }, + 'endpoint': { + 'description': 'Endpoint that hosts the bucket', + 'examples': [ + 'https://nyc3.digitaloceanspaces.com', + 'https://bucket.s3.region.amazonaws.com', ], - "type": "string" + 'type': 'string', }, - "id": { - "description": "Unique ID of the bucket that was created", - "examples": [ - "abc123" + 'id': { + 'description': 'Unique ID of the bucket that was created', + 'examples': [ + 'abc123', ], - "type": "string" + 'type': 'string', }, - "region": { - "description": "Region the bucket was created in", - "type": "string" + 'region': { + 'description': 'Region the bucket was created in', + 'type': 'string', + }, + 'secret_access_key': { + 'description': 'Secret access key used to authenticate with the bucket', + 'type': 'string', }, - "secret_access_key": { - "description": "Secret access key used to authenticate with the bucket", - "type": "string" - } }, - "required": [ - "id", - "endpoint", - "region", - "access_key_id", - "secret_access_key" + 'required': [ + 'id', + 'endpoint', + 'region', + 'access_key_id', + 'secret_access_key', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "cronjob": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'cronjob': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": {}, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': {}, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "database": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'database': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "certificate": { - "description": "SSL certificate used to authenticate with the database", - "type": "string" - }, - "database": { - "description": "Name of the new database schema", - "examples": [ - "my-schema" + 'properties': { + 'certificate': { + 'description': 'SSL certificate used to authenticate with the database', + 'type': 'string', + }, + 'database': { + 'description': 'Name of the new database schema', + 'examples': [ + 'my-schema', ], - "type": "string" + 'type': 'string', }, - "host": { - "description": "Host address of the underlying database", - "examples": [ - "my-database.example.com" + 'host': { + 'description': 'Host address of the underlying database', + 'examples': [ + 'my-database.example.com', ], - "type": "string" + 'type': 'string', }, - "password": { - "description": "Passowrd used to authenticate with the schema", - "examples": [ - "pass" + 'password': { + 'description': 'Passowrd used to authenticate with the schema', + 'examples': [ + 'pass', ], - "type": "string" + 'type': 'string', }, - "port": { - "description": "Port the underlying database listens on", - "examples": [ - 5432 + 'port': { + 'description': 'Port the underlying database listens on', + 'examples': [ + 5432, + ], + 'type': [ + 'string', + 'number', ], - "type": [ - "string", - "number" - ] - }, - "protocol": { - "description": "Protocol of the underlying database", - "examples": [ - "postgresql" + }, + 'protocol': { + 'description': 'Protocol of the underlying database', + 'examples': [ + 'postgresql', ], - "type": "string" + 'type': 'string', }, - "url": { - "description": "Full connection string for the database", - "examples": [ - "postgresql://user:pass@my-database.example.com:5432/my-schema" + 'url': { + 'description': 'Full connection string for the database', + 'examples': [ + 'postgresql://user:pass@my-database.example.com:5432/my-schema', ], - "type": "string" + 'type': 'string', }, - "username": { - "description": "Username used to authenticate with the schema", - "examples": [ - "user" + 'username': { + 'description': 'Username used to authenticate with the schema', + 'examples': [ + 'user', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "protocol", - "host", - "port", - "database", - "url", - "username", - "password" + 'required': [ + 'protocol', + 'host', + 'port', + 'database', + 'url', + 'username', + 'password', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "databaseUser": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'databaseUser': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "certificate": { - "description": "The certificate used to connect to the database", - "type": "string" - }, - "database": { - "description": "The name of the database to connect to", - "examples": [ - "database" + 'properties': { + 'certificate': { + 'description': 'The certificate used to connect to the database', + 'type': 'string', + }, + 'database': { + 'description': 'The name of the database to connect to', + 'examples': [ + 'database', ], - "type": "string" + 'type': 'string', }, - "host": { - "description": "The host the database listens on", - "examples": [ - "rds.amazonwebservices.com/abc123" + 'host': { + 'description': 'The host the database listens on', + 'examples': [ + 'rds.amazonwebservices.com/abc123', ], - "type": "string" + 'type': 'string', }, - "password": { - "description": "Password used to authenticate with the database", - "examples": [ - "password" + 'password': { + 'description': 'Password used to authenticate with the database', + 'examples': [ + 'password', ], - "type": "string" + 'type': 'string', }, - "port": { - "description": "The port the database listens on", - "examples": [ - 5432 + 'port': { + 'description': 'The port the database listens on', + 'examples': [ + 5432, + ], + 'type': [ + 'number', + 'string', ], - "type": [ - "number", - "string" - ] - }, - "protocol": { - "description": "The protocol the database responds to", - "examples": [ - "postgresql" + }, + 'protocol': { + 'description': 'The protocol the database responds to', + 'examples': [ + 'postgresql', ], - "type": "string" + 'type': 'string', }, - "url": { - "description": "Fully resolvable URL used to connect to the database", - "examples": [ - "postgresql://admin:password@rds.amazonwebservices.com:5432/database" + 'url': { + 'description': 'Fully resolvable URL used to connect to the database', + 'examples': [ + 'postgresql://admin:password@rds.amazonwebservices.com:5432/database', ], - "type": "string" + 'type': 'string', }, - "username": { - "description": "Username used to authenticate with the database", - "examples": [ - "admin" + 'username': { + 'description': 'Username used to authenticate with the database', + 'examples': [ + 'admin', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "protocol", - "host", - "port", - "database", - "username", - "password", - "url" + 'required': [ + 'protocol', + 'host', + 'port', + 'database', + 'username', + 'password', + 'url', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "deployment": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'deployment': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "labels": { - "additionalProperties": { - "type": "string" + 'properties': { + 'labels': { + 'additionalProperties': { + 'type': 'string', }, - "description": "A set of labels that were used to annotate the cloud resource", - "examples": [ + 'description': 'A set of labels that were used to annotate the cloud resource', + 'examples': [ { - "app.kubernetes.io/name": "my-app" - } + 'app.kubernetes.io/name': 'my-app', + }, ], - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "dockerBuild": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'dockerBuild': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "image": { - "description": "The resulting image address of the built artifact", - "examples": [ - "registry.architect.io/my-component:latest" + 'properties': { + 'image': { + 'description': 'The resulting image address of the built artifact', + 'examples': [ + 'registry.architect.io/my-component:latest', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "image" + 'required': [ + 'image', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "ingress": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'ingress': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "dns_zone": { - "description": "DNS zone the ingress rule responds to", - "examples": [ - "example.com" + 'properties': { + 'dns_zone': { + 'description': 'DNS zone the ingress rule responds to', + 'examples': [ + 'example.com', ], - "type": "string" + 'type': 'string', }, - "host": { - "description": "Host the ingress rule responds to", - "examples": [ - "api.example.com" + 'host': { + 'description': 'Host the ingress rule responds to', + 'examples': [ + 'api.example.com', ], - "type": "string" + 'type': 'string', }, - "password": { - "description": "Password for basic auth", - "examples": [ - "password" + 'password': { + 'description': 'Password for basic auth', + 'examples': [ + 'password', ], - "type": "string" + 'type': 'string', }, - "path": { - "description": "Path the ingress rule responds to", - "examples": [ - "/path" + 'path': { + 'description': 'Path the ingress rule responds to', + 'examples': [ + '/path', ], - "type": "string" + 'type': 'string', }, - "port": { - "description": "Port the ingress rule responds to", - "examples": [ - 80 + 'port': { + 'description': 'Port the ingress rule responds to', + 'examples': [ + 80, + ], + 'type': [ + 'string', + 'number', ], - "type": [ - "string", - "number" - ] - }, - "protocol": { - "description": "Protocol the ingress rule responds to", - "examples": [ - "http" + }, + 'protocol': { + 'description': 'Protocol the ingress rule responds to', + 'examples': [ + 'http', ], - "type": "string" + 'type': 'string', }, - "subdomain": { - "description": "Subdomain the ingress rule responds to", - "examples": [ - "api" + 'subdomain': { + 'description': 'Subdomain the ingress rule responds to', + 'examples': [ + 'api', ], - "type": "string" + 'type': 'string', }, - "url": { - "description": "URL the ingress rule responds to", - "examples": [ - "http://admin:password@api.example.com/path" + 'url': { + 'description': 'URL the ingress rule responds to', + 'examples': [ + 'http://admin:password@api.example.com/path', ], - "type": "string" + 'type': 'string', }, - "username": { - "description": "Username for basic auth", - "examples": [ - "admin" + 'username': { + 'description': 'Username for basic auth', + 'examples': [ + 'admin', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "protocol", - "host", - "port", - "url", - "path", - "subdomain", - "dns_zone" + 'required': [ + 'protocol', + 'host', + 'port', + 'url', + 'path', + 'subdomain', + 'dns_zone', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', ], - "type": "string" + 'type': 'string', }, - "environment": { - "additionalProperties": { - "type": "string" + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] + 'image': 'nginx:latest', + 'port': 8080, + }, + ], }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', ], - "examples": [ - "opentofu" + 'examples': [ + 'opentofu', ], - "type": "string" + 'type': 'string', }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', ], - "type": "string" + 'type': 'string', }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', ], - "type": "string" + 'type': 'string', }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" - ], - "type": "string" - }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" - ], - "type": "string" - } + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', + ], + 'type': 'string', + }, + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', + ], + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per environment", - "type": "object" + 'description': 'Modules that will be created once per environment', + 'type': 'object', }, - "secret": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'secret': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "data": { - "description": "The contents of the secret", - "examples": [ - "..." + 'properties': { + 'data': { + 'description': 'The contents of the secret', + 'examples': [ + '...', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "data" + 'required': [ + 'data', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "service": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'service': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "host": { - "description": "Host the service listens on", - "examples": [ - "my-service" + 'properties': { + 'host': { + 'description': 'Host the service listens on', + 'examples': [ + 'my-service', ], - "type": "string" + 'type': 'string', }, - "name": { - "description": "Name of the service", - "examples": [ - "my-service" + 'name': { + 'description': 'Name of the service', + 'examples': [ + 'my-service', ], - "type": "string" + 'type': 'string', }, - "port": { - "description": "Port the service listens on", - "examples": [ - 80 + 'port': { + 'description': 'Port the service listens on', + 'examples': [ + 80, + ], + 'type': [ + 'number', + 'string', ], - "type": [ - "number", - "string" - ] - }, - "protocol": { - "description": "Protocol the service listens on", - "examples": [ - "http" + }, + 'protocol': { + 'description': 'Protocol the service listens on', + 'examples': [ + 'http', ], - "type": "string" + 'type': 'string', }, - "target_port": { - "description": "The port the service forwards traffic to", - "examples": [ - 8080 + 'target_port': { + 'description': 'The port the service forwards traffic to', + 'examples': [ + 8080, + ], + 'type': [ + 'number', + 'string', ], - "type": [ - "number", - "string" - ] - }, - "url": { - "description": "Fully resolvable URL of the service", - "examples": [ - "http://my-service:80" + }, + 'url': { + 'description': 'Fully resolvable URL of the service', + 'examples': [ + 'http://my-service:80', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "name", - "target_port", - "protocol", - "host", - "port", - "url" + 'required': [ + 'name', + 'target_port', + 'protocol', + 'host', + 'port', + 'url', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "task": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'task': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "volume": { - "items": { - "additionalProperties": false, - "properties": { - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" - ], - "type": "string" - }, - "environment": { - "additionalProperties": { - "type": "string" + 'volume': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', + ], + 'type': 'string', + }, + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': + 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] - }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" - ], - "examples": [ - "opentofu" - ], - "type": "string" - }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" - ], - "type": "string" - }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" - ], - "type": "string" - }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'image': 'nginx:latest', + 'port': 8080, + }, + ], + }, + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', + ], + 'examples': [ + 'opentofu', + ], + 'type': 'string', + }, + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', + ], + 'type': 'string', + }, + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', + ], + 'type': 'string', + }, + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per matching application resource", - "type": "object" + 'description': 'Modules that will be created once per matching application resource', + 'type': 'object', }, - "outputs": { - "additionalProperties": false, - "description": "A map of output values to be passed to upstream application resources", - "examples": [ + 'outputs': { + 'additionalProperties': false, + 'description': 'A map of output values to be passed to upstream application resources', + 'examples': [ { - "host": "${module.database.host}", - "id": "${module.database.id}", - "password": "${module.database.password}", - "port": "${module.database.port}", - "username": "${module.database.username}" - } + 'host': '${module.database.host}', + 'id': '${module.database.id}', + 'password': '${module.database.password}', + 'port': '${module.database.port}', + 'username': '${module.database.username}', + }, ], - "properties": { - "id": { - "description": "The unique ID of the volume", - "examples": [ - "my-volume" + 'properties': { + 'id': { + 'description': 'The unique ID of the volume', + 'examples': [ + 'my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "id" + 'required': [ + 'id', ], - "type": "object" + 'type': 'object', }, - "when": { - "description": "A condition that restricts when the hook should be active. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the hook should be active. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" - } + 'type': 'array', + }, }, - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "module": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "build": { - "description": "The path to a module that will be built during the build step.", - "examples": [ - "./my-module" + 'module': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'build': { + 'description': 'The path to a module that will be built during the build step.', + 'examples': [ + './my-module', ], - "type": "string" + 'type': 'string', }, - "environment": { - "additionalProperties": { - "type": "string" + 'environment': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Environment variables that should be provided to the container executing the module", - "examples": [ + 'description': 'Environment variables that should be provided to the container executing the module', + 'examples': [ { - "MY_ENV_VAR": "my-value" - } + 'MY_ENV_VAR': 'my-value', + }, ], - "type": "object" + 'type': 'object', }, - "inputs": { - "anyOf": [ + 'inputs': { + 'anyOf': [ { - "additionalProperties": {}, - "type": "object" + 'additionalProperties': {}, + 'type': 'object', }, { - "type": "string" - } + 'type': 'string', + }, ], - "description": "Input values for the module.", - "examples": [ + 'description': 'Input values for the module.', + 'examples': [ { - "image": "nginx:latest", - "port": 8080 - } - ] + 'image': 'nginx:latest', + 'port': 8080, + }, + ], }, - "plugin": { - "default": "pulumi", - "description": "The plugin used to build the module. Defaults to pulumi.", - "enum": [ - "pulumi", - "opentofu" + 'plugin': { + 'default': 'pulumi', + 'description': 'The plugin used to build the module. Defaults to pulumi.', + 'enum': [ + 'pulumi', + 'opentofu', ], - "examples": [ - "opentofu" + 'examples': [ + 'opentofu', ], - "type": "string" + 'type': 'string', }, - "source": { - "description": "The image source of the module.", - "examples": [ - "my-registry.com/my-image:latest" + 'source': { + 'description': 'The image source of the module.', + 'examples': [ + 'my-registry.com/my-image:latest', ], - "type": "string" + 'type': 'string', }, - "ttl": { - "description": "The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.", - "examples": [ - "24*60*60" + 'ttl': { + 'description': + 'The Time to Live (in seconds) for a module. When the TTL for a module is expired, the next deploy will force an update of the module.', + 'examples': [ + '24*60*60', ], - "type": "string" + 'type': 'string', }, - "volume": { - "description": "Volumes that should be mounted to the container executing the module", - "items": { - "additionalProperties": false, - "properties": { - "host_path": { - "description": "The path on the host machine to mount to the container", - "examples": [ - "/Users/batman/my-volume" + 'volume': { + 'description': 'Volumes that should be mounted to the container executing the module', + 'items': { + 'additionalProperties': false, + 'properties': { + 'host_path': { + 'description': 'The path on the host machine to mount to the container', + 'examples': [ + '/Users/batman/my-volume', ], - "type": "string" + 'type': 'string', }, - "mount_path": { - "description": "The path in the container to mount the volume to", - "examples": [ - "/app/my-volume" + 'mount_path': { + 'description': 'The path in the container to mount the volume to', + 'examples': [ + '/app/my-volume', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "host_path", - "mount_path" + 'required': [ + 'host_path', + 'mount_path', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "when": { - "description": "A condition that restricts when the module should be created. Must resolve to a boolean.", - "examples": [ - "node.type == 'database' && node.inputs.databaseType == 'postgres'", - "contains(environment.nodes.*.inputs.databaseType, 'postgres')" + 'when': { + 'description': + 'A condition that restricts when the module should be created. Must resolve to a boolean.', + 'examples': [ + 'node.type == \'database\' && node.inputs.databaseType == \'postgres\'', + 'contains(environment.nodes.*.inputs.databaseType, \'postgres\')', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "inputs" + 'required': [ + 'inputs', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Modules that will be created once per datacenter", - "type": "object" + 'description': 'Modules that will be created once per datacenter', + 'type': 'object', }, - "variable": { - "additionalProperties": { - "items": { - "additionalProperties": false, - "properties": { - "default": { - "description": "The default value of the variable", - "examples": [ - "my-value" + 'variable': { + 'additionalProperties': { + 'items': { + 'additionalProperties': false, + 'properties': { + 'default': { + 'description': 'The default value of the variable', + 'examples': [ + 'my-value', ], - "type": "string" + 'type': 'string', }, - "description": { - "description": "A human-readable description of the variable", - "examples": [ - "An example description" + 'description': { + 'description': 'A human-readable description of the variable', + 'examples': [ + 'An example description', ], - "type": "string" + 'type': 'string', }, - "type": { - "description": "The type of the variable", - "enum": [ - "string", - "number", - "boolean" + 'type': { + 'description': 'The type of the variable', + 'enum': [ + 'string', + 'number', + 'boolean', ], - "examples": [ - "string" + 'examples': [ + 'string', ], - "type": "string" - } + 'type': 'string', + }, }, - "required": [ - "type" + 'required': [ + 'type', ], - "type": "object" + 'type': 'object', }, - "type": "array" + 'type': 'array', }, - "description": "Variables necessary for the datacenter to run", - "type": "object" + 'description': 'Variables necessary for the datacenter to run', + 'type': 'object', + }, + 'version': { + 'const': 'v1', + 'type': 'string', }, - "version": { - "const": "v1", - "type": "string" - } }, - "required": [ - "version" + 'required': [ + 'version', ], - "type": "object" - } + 'type': 'object', + }, }, - "$id": "https://architect.io/.schemas/datacenter.json" -} \ No newline at end of file + '$id': 'https://architect.io/.schemas/datacenter.json', +}; diff --git a/src/datacenters/schema.ts b/src/datacenters/schema.ts index 712adc4cd..dd1c64d52 100644 --- a/src/datacenters/schema.ts +++ b/src/datacenters/schema.ts @@ -1,11 +1,9 @@ import { Datacenter } from './datacenter.ts'; import datacenter_v1 from './v1/index.ts'; -export type DatacenterSchema = - | ({ - version: 'v1'; - } & datacenter_v1) -; +export type DatacenterSchema = { + version: 'v1'; +} & datacenter_v1; export const buildDatacenter = (data: DatacenterSchema): Datacenter => { switch (data.version) { @@ -13,4 +11,4 @@ export const buildDatacenter = (data: DatacenterSchema): Datacenter => { return new datacenter_v1(data); } } -}; \ No newline at end of file +}; diff --git a/src/environments/environment-schema.ts b/src/environments/environment-schema.ts index 7885cb01c..a15d230f5 100644 --- a/src/environments/environment-schema.ts +++ b/src/environments/environment-schema.ts @@ -1,226 +1,230 @@ export default { - "$ref": "#/definitions/EnvironmentSchema", - "$schema": "https://json-schema.org/draft/2019-09/schema", - "definitions": { - "EnvironmentSchema": { - "additionalProperties": false, - "properties": { - "components": { - "additionalProperties": { - "additionalProperties": false, - "description": "The name of the component that will be used to fulfill dependencies", - "properties": { - "deployments": { - "additionalProperties": { - "additionalProperties": false, - "description": "The name of the deployment to configure", - "properties": { - "autoscaling": { - "additionalProperties": false, - "description": "Autoscaling rules for the deployment within the environment", - "properties": { - "max_replicas": { - "default": 1, - "description": "Maximum number of replicas to maintain", - "type": "number" + '$ref': '#/definitions/EnvironmentSchema', + '$schema': 'https://json-schema.org/draft/2019-09/schema', + 'definitions': { + 'EnvironmentSchema': { + 'additionalProperties': false, + 'properties': { + 'components': { + 'additionalProperties': { + 'additionalProperties': false, + 'description': 'The name of the component that will be used to fulfill dependencies', + 'properties': { + 'deployments': { + 'additionalProperties': { + 'additionalProperties': false, + 'description': 'The name of the deployment to configure', + 'properties': { + 'autoscaling': { + 'additionalProperties': false, + 'description': 'Autoscaling rules for the deployment within the environment', + 'properties': { + 'max_replicas': { + 'default': 1, + 'description': 'Maximum number of replicas to maintain', + 'type': 'number', + }, + 'min_replicas': { + 'default': 1, + 'description': 'Minimum number of replicas to maintain', + 'type': 'number', }, - "min_replicas": { - "default": 1, - "description": "Minimum number of replicas to maintain", - "type": "number" - } }, - "type": "object" + 'type': 'object', }, - "enabled": { - "default": true, - "description": "Set to false to make sure the deployment doesn't run in this environment", - "type": "boolean" + 'enabled': { + 'default': true, + 'description': 'Set to false to make sure the deployment doesn\'t run in this environment', + 'type': 'boolean', }, - "environment": { - "additionalProperties": { - "anyOf": [ + 'environment': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "type": "number" + 'type': 'number', }, { - "type": "boolean" + 'type': 'boolean', }, { - "type": "null" + 'type': 'null', }, { - "not": {} - } - ] + 'not': {}, + }, + ], }, - "description": "Values for environment variables in the deployment", - "examples": [ + 'description': 'Values for environment variables in the deployment', + 'examples': [ { - "STRIPE_API_KEY": "sk_test_1234" - } + 'STRIPE_API_KEY': 'sk_test_1234', + }, ], - "type": "object" + 'type': 'object', + }, + 'replicas': { + 'default': 1, + 'description': 'Number of replicas of the deployment to maintain', + 'type': 'number', }, - "replicas": { - "default": 1, - "description": "Number of replicas of the deployment to maintain", - "type": "number" - } }, - "type": "object" + 'type': 'object', }, - "description": "Configuration for each deployment in the component", - "type": "object" + 'description': 'Configuration for each deployment in the component', + 'type': 'object', }, - "ingresses": { - "additionalProperties": { - "additionalProperties": false, - "description": "The name of the ingress to configure", - "properties": { - "internal": { - "description": "Set to true to make the ingress only available from a private gateway (no public IP)", - "examples": [ - true + 'ingresses': { + 'additionalProperties': { + 'additionalProperties': false, + 'description': 'The name of the ingress to configure', + 'properties': { + 'internal': { + 'description': + 'Set to true to make the ingress only available from a private gateway (no public IP)', + 'examples': [ + true, ], - "type": "boolean" + 'type': 'boolean', }, - "path": { - "description": "A path that the ingress listens on", - "examples": [ - "/api" + 'path': { + 'description': 'A path that the ingress listens on', + 'examples': [ + '/api', ], - "type": "string" + 'type': 'string', }, - "subdomain": { - "description": "A subdomain that the ingress listens on", - "examples": [ - "api" + 'subdomain': { + 'description': 'A subdomain that the ingress listens on', + 'examples': [ + 'api', ], - "type": "string" + 'type': 'string', }, - "tls": { - "additionalProperties": false, - "description": "Custom TLS configuration for the ingress rule", - "properties": { - "ca": { - "description": "The certificate authority", - "type": "string" + 'tls': { + 'additionalProperties': false, + 'description': 'Custom TLS configuration for the ingress rule', + 'properties': { + 'ca': { + 'description': 'The certificate authority', + 'type': 'string', + }, + 'crt': { + 'description': 'The certificate file contents', + 'type': 'string', }, - "crt": { - "description": "The certificate file contents", - "type": "string" + 'key': { + 'description': 'The key file contents', + 'type': 'string', }, - "key": { - "description": "The key file contents", - "type": "string" - } }, - "required": [ - "crt", - "key" + 'required': [ + 'crt', + 'key', ], - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "description": "Configuration for each ingress in the component", - "type": "object" + 'description': 'Configuration for each ingress in the component', + 'type': 'object', }, - "services": { - "additionalProperties": { - "additionalProperties": false, - "description": "The name of the service to configure", - "properties": { - "host": { - "description": "Existing hostname that should act as the interface host instead of creating a new one", - "examples": [ - "example.com" + 'services': { + 'additionalProperties': { + 'additionalProperties': false, + 'description': 'The name of the service to configure', + 'properties': { + 'host': { + 'description': + 'Existing hostname that should act as the interface host instead of creating a new one', + 'examples': [ + 'example.com', ], - "type": "string" + 'type': 'string', }, - "port": { - "description": "Existing port that should act as the interface port instead of registering a new one", - "examples": [ - 443 + 'port': { + 'description': + 'Existing port that should act as the interface port instead of registering a new one', + 'examples': [ + 443, ], - "type": "number" + 'type': 'number', }, - "url": { - "description": "Existing URL to point the service to instead of", - "examples": [ - "https://example.com" + 'url': { + 'description': 'Existing URL to point the service to instead of', + 'examples': [ + 'https://example.com', ], - "type": "string" - } + 'type': 'string', + }, }, - "type": "object" + 'type': 'object', }, - "description": "Configuration for each service in the component", - "type": "object" + 'description': 'Configuration for each service in the component', + 'type': 'object', }, - "source": { - "description": "The source of the component to deploy. Can either be a docker registry repository or a reference to the local filesystem prefixed with `file:`", - "examples": [ - "architectio/kratos:v1", - "file:/path/to/component" + 'source': { + 'description': + 'The source of the component to deploy. Can either be a docker registry repository or a reference to the local filesystem prefixed with `file:`', + 'examples': [ + 'architectio/kratos:v1', + 'file:/path/to/component', ], - "type": "string" + 'type': 'string', }, - "variables": { - "additionalProperties": { - "anyOf": [ + 'variables': { + 'additionalProperties': { + 'anyOf': [ { - "type": "string" + 'type': 'string', }, { - "items": { - "type": "string" + 'items': { + 'type': 'string', }, - "type": "array" - } - ] + 'type': 'array', + }, + ], }, - "description": "Values for variables the component expects", - "examples": [ + 'description': 'Values for variables the component expects', + 'examples': [ { - "log_level": "debug" - } + 'log_level': 'debug', + }, ], - "type": "object" - } + 'type': 'object', + }, }, - "type": "object" + 'type': 'object', }, - "description": "Configuration settings for the components that may be deployed inside this environment", - "type": "object" + 'description': 'Configuration settings for the components that may be deployed inside this environment', + 'type': 'object', }, - "locals": { - "additionalProperties": { - "type": "string" + 'locals': { + 'additionalProperties': { + 'type': 'string', }, - "description": "Local variables that can be used to parameterize the environment", - "examples": [ + 'description': 'Local variables that can be used to parameterize the environment', + 'examples': [ { - "log_level": "debug" - } + 'log_level': 'debug', + }, ], - "type": "object" + 'type': 'object', + }, + 'version': { + 'const': 'v1', + 'type': 'string', }, - "version": { - "const": "v1", - "type": "string" - } }, - "required": [ - "version" + 'required': [ + 'version', ], - "type": "object" - } + 'type': 'object', + }, }, - "$id": "https://architect.io/.schemas/environment.json" -} \ No newline at end of file + '$id': 'https://architect.io/.schemas/environment.json', +}; diff --git a/src/environments/schema.ts b/src/environments/schema.ts index 83ca27e77..c9b11117a 100644 --- a/src/environments/schema.ts +++ b/src/environments/schema.ts @@ -4,11 +4,9 @@ import environment_v1 from './v1/index.ts'; /** * @discriminatorOpenApi version */ -export type EnvironmentSchema = - | ({ - version: 'v1'; - } & environment_v1) -; +export type EnvironmentSchema = { + version: 'v1'; +} & environment_v1; export const buildEnvironment = (data: EnvironmentSchema): Environment => { switch (data.version) { @@ -17,9 +15,7 @@ export const buildEnvironment = (data: EnvironmentSchema): Environment => { } default: { throw new Error( - `Invalid schema version: ${ - 'version' in data ? data.version : 'none' - }` + `Invalid schema version: ${'version' in data ? data.version : 'none'}`, ); } }