A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

ci: publish a new container image on push to master

+10738 -2
+2
.fluentci/.env.example
··· 1 + # This file is a "template" of which env vars need to be defined for your Pipeline. 2 + HELLO=123
+3
.fluentci/.gitignore
··· 1 + coverage/ 2 + coverage.lcov 3 + .env
+132
.fluentci/CODE_OF_CONDUCT.md
··· 1 + # Contributor Covenant Code of Conduct 2 + 3 + ## Our Pledge 4 + 5 + We as members, contributors, and leaders pledge to make participation in our 6 + community a harassment-free experience for everyone, regardless of age, body 7 + size, visible or invisible disability, ethnicity, sex characteristics, gender 8 + identity and expression, level of experience, education, socio-economic status, 9 + nationality, personal appearance, race, caste, color, religion, or sexual 10 + identity and orientation. 11 + 12 + We pledge to act and interact in ways that contribute to an open, welcoming, 13 + diverse, inclusive, and healthy community. 14 + 15 + ## Our Standards 16 + 17 + Examples of behavior that contributes to a positive environment for our 18 + community include: 19 + 20 + * Demonstrating empathy and kindness toward other people 21 + * Being respectful of differing opinions, viewpoints, and experiences 22 + * Giving and gracefully accepting constructive feedback 23 + * Accepting responsibility and apologizing to those affected by our mistakes, 24 + and learning from the experience 25 + * Focusing on what is best not just for us as individuals, but for the overall 26 + community 27 + 28 + Examples of unacceptable behavior include: 29 + 30 + * The use of sexualized language or imagery, and sexual attention or advances of 31 + any kind 32 + * Trolling, insulting or derogatory comments, and personal or political attacks 33 + * Public or private harassment 34 + * Publishing others' private information, such as a physical or email address, 35 + without their explicit permission 36 + * Other conduct which could reasonably be considered inappropriate in a 37 + professional setting 38 + 39 + ## Enforcement Responsibilities 40 + 41 + Community leaders are responsible for clarifying and enforcing our standards of 42 + acceptable behavior and will take appropriate and fair corrective action in 43 + response to any behavior that they deem inappropriate, threatening, offensive, 44 + or harmful. 45 + 46 + Community leaders have the right and responsibility to remove, edit, or reject 47 + comments, commits, code, wiki edits, issues, and other contributions that are 48 + not aligned to this Code of Conduct, and will communicate reasons for moderation 49 + decisions when appropriate. 50 + 51 + ## Scope 52 + 53 + This Code of Conduct applies within all community spaces, and also applies when 54 + an individual is officially representing the community in public spaces. 55 + Examples of representing our community include using an official e-mail address, 56 + posting via an official social media account, or acting as an appointed 57 + representative at an online or offline event. 58 + 59 + ## Enforcement 60 + 61 + Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 + reported to the community leaders responsible for enforcement at 63 + [GitHub Issues](https://github.com/fluent-ci-templates/base-pipeline/issues). 64 + All complaints will be reviewed and investigated promptly and fairly. 65 + 66 + All community leaders are obligated to respect the privacy and security of the 67 + reporter of any incident. 68 + 69 + ## Enforcement Guidelines 70 + 71 + Community leaders will follow these Community Impact Guidelines in determining 72 + the consequences for any action they deem in violation of this Code of Conduct: 73 + 74 + ### 1. Correction 75 + 76 + **Community Impact**: Use of inappropriate language or other behavior deemed 77 + unprofessional or unwelcome in the community. 78 + 79 + **Consequence**: A private, written warning from community leaders, providing 80 + clarity around the nature of the violation and an explanation of why the 81 + behavior was inappropriate. A public apology may be requested. 82 + 83 + ### 2. Warning 84 + 85 + **Community Impact**: A violation through a single incident or series of 86 + actions. 87 + 88 + **Consequence**: A warning with consequences for continued behavior. No 89 + interaction with the people involved, including unsolicited interaction with 90 + those enforcing the Code of Conduct, for a specified period of time. This 91 + includes avoiding interactions in community spaces as well as external channels 92 + like social media. Violating these terms may lead to a temporary or permanent 93 + ban. 94 + 95 + ### 3. Temporary Ban 96 + 97 + **Community Impact**: A serious violation of community standards, including 98 + sustained inappropriate behavior. 99 + 100 + **Consequence**: A temporary ban from any sort of interaction or public 101 + communication with the community for a specified period of time. No public or 102 + private interaction with the people involved, including unsolicited interaction 103 + with those enforcing the Code of Conduct, is allowed during this period. 104 + Violating these terms may lead to a permanent ban. 105 + 106 + ### 4. Permanent Ban 107 + 108 + **Community Impact**: Demonstrating a pattern of violation of community 109 + standards, including sustained inappropriate behavior, harassment of an 110 + individual, or aggression toward or disparagement of classes of individuals. 111 + 112 + **Consequence**: A permanent ban from any sort of public interaction within the 113 + community. 114 + 115 + ## Attribution 116 + 117 + This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 + version 2.1, available at 119 + [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 + 121 + Community Impact Guidelines were inspired by 122 + [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 + 124 + For answers to common questions about this code of conduct, see the FAQ at 125 + [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 126 + [https://www.contributor-covenant.org/translations][translations]. 127 + 128 + [homepage]: https://www.contributor-covenant.org 129 + [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 + [Mozilla CoC]: https://github.com/mozilla/diversity 131 + [FAQ]: https://www.contributor-covenant.org/faq 132 + [translations]: https://www.contributor-covenant.org/translations
+53
.fluentci/CONTRIBUTING.md
··· 1 + # Contributing Guidelines 2 + 3 + Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 + documentation, we greatly value feedback and contributions from our community. 5 + 6 + Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 + information to effectively respond to your bug report or contribution. 8 + 9 + 10 + ## Reporting Bugs/Feature Requests 11 + 12 + We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 + 14 + When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 + reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 + 17 + * A reproducible test case or series of steps 18 + * The version of our code being used 19 + * Any modifications you've made relevant to the bug 20 + * Anything unusual about your environment or deployment 21 + 22 + 23 + ## Contributing via Pull Requests 24 + Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 + 26 + 1. You are working against the latest source on the *master* branch. 27 + 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 + 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 + 30 + To send us a pull request, please: 31 + 32 + 1. Fork the repository. 33 + 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 + 3. Ensure local tests pass. 35 + 4. Commit to your fork using clear commit messages. 36 + 5. Send us a pull request, answering any default questions in the pull request interface. 37 + 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 + 39 + GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 + [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 + 42 + 43 + ## Finding contributions to work on 44 + Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 + 46 + 47 + ## Code of Conduct 48 + This project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. 49 + 50 + 51 + ## Licensing 52 + 53 + See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
+19
.fluentci/LICENSE
··· 1 + Copyright (c) 2023 Tsiry Sandratraina <tsiry.sndr@aol.com> 2 + 3 + Permission is hereby granted, free of charge, to any person obtaining a copy 4 + of this software and associated documentation files (the "Software"), to deal 5 + in the Software without restriction, including without limitation the rights 6 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 + copies of the Software, and to permit persons to whom the Software is 8 + furnished to do so, subject to the following conditions: 9 + 10 + The above copyright notice and this permission notice shall be included in all 11 + copies or substantial portions of the Software. 12 + 13 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 + SOFTWARE.
+22
.fluentci/README.md
··· 1 + # Base Pipeline 2 + 3 + [![fluentci pipeline](https://img.shields.io/badge/dynamic/json?label=pkg.fluentci.io&labelColor=%23000&color=%23460cf1&url=https%3A%2F%2Fapi.fluentci.io%2Fv1%2Fpipeline%2Fbase_pipeline&query=%24.version)](https://pkg.fluentci.io/base_pipeline) 4 + ![deno compatibility](https://shield.deno.dev/deno/^1.42) 5 + 6 + This repository contains a minimal pipeline for a [Fluent CI](https://fluentci.io) project. It is intended to be used as a template for new projects. 7 + Reusing this template will allow you to get started with Fluent CI in a matter of minutes, just run the following command: 8 + 9 + ```bash 10 + fluentci init 11 + ``` 12 + 13 + ## Files Tree Layout 14 + 15 + ```plaintext 16 + src 17 + |-- helpers.ts : Contains helper functions 18 + |-- jobs.ts : Contains the job definitions 19 + |-- mod.ts : This is the entry point of the module 20 + |-- pipeline.ts : Contains the pipeline definition 21 + `-- runner.ts : Contains the runner function 22 + ```
+3
.fluentci/ci.ts
··· 1 + import { hello } from "https://pkg.fluentci.io/base_pipeline@v0.5.3/mod.ts"; 2 + 3 + await hello();
+13
.fluentci/dagger.json
··· 1 + { 2 + "name": "rockbox", 3 + "sdk": "github.com/fluentci-io/daggerverse/deno-sdk@main", 4 + "version": "v0.1.0", 5 + "description": "CI/CD for Rockbox", 6 + "keywords": [ 7 + "rockbox", 8 + "zig", 9 + "rust" 10 + ], 11 + "author": "Tsiry Sandratraina <tsiry.sndr@fluentci.io>", 12 + "license": "MIT" 13 + }
+31
.fluentci/deno.json
··· 1 + { 2 + "importMap": "import_map.json", 3 + "tasks": { 4 + "esm:add": "deno run -A https://esm.sh/v128 add", 5 + "esm:update": "deno run -A https://esm.sh/v128 update", 6 + "esm:remove": "deno run -A https://esm.sh/v128 remove", 7 + "schema": "deno run -A src/dagger/schema.ts", 8 + "clean": "rm -rf gen schema.graphql" 9 + }, 10 + "fmt": { 11 + "exclude": [ 12 + "example/", 13 + ".fluentci/", 14 + "gen/" 15 + ] 16 + }, 17 + "lint": { 18 + "exclude": [ 19 + "example/", 20 + ".fluentci/", 21 + "gen/" 22 + ] 23 + }, 24 + "test": { 25 + "exclude": [ 26 + "example/", 27 + ".fluentci/", 28 + "gen/" 29 + ] 30 + } 31 + }
+206
.fluentci/deno.lock
··· 1 + { 2 + "version": "3", 3 + "packages": { 4 + "specifiers": { 5 + "jsr:@std/assert@^0.217.0": "jsr:@std/assert@0.217.0", 6 + "jsr:@std/assert@^0.218.2": "jsr:@std/assert@0.218.2", 7 + "jsr:@std/flags@0.218.2": "jsr:@std/flags@0.218.2", 8 + "jsr:@std/fmt@0.218.2": "jsr:@std/fmt@0.218.2", 9 + "jsr:@std/fmt@^0.217.0": "jsr:@std/fmt@0.217.0", 10 + "jsr:@std/fmt@^0.218.2": "jsr:@std/fmt@0.218.2", 11 + "jsr:@std/path@0.218.2": "jsr:@std/path@0.218.2", 12 + "jsr:@std/testing@0.217.0": "jsr:@std/testing@0.217.0", 13 + "jsr:@std/testing@0.218.2": "jsr:@std/testing@0.218.2", 14 + "jsr:@tsirysndr/env-js@0.1.2": "jsr:@tsirysndr/env-js@0.1.2", 15 + "jsr:@tsirysndr/exit-js@0.1.0": "jsr:@tsirysndr/exit-js@0.1.0", 16 + "jsr:@tsirysndr/fluent-az-pipelines@0.3": "jsr:@tsirysndr/fluent-az-pipelines@0.3.1", 17 + "jsr:@tsirysndr/fluent-circleci@0.3": "jsr:@tsirysndr/fluent-circleci@0.3.1", 18 + "jsr:@tsirysndr/fluent-codepipeline@0.3": "jsr:@tsirysndr/fluent-codepipeline@0.3.0", 19 + "jsr:@tsirysndr/fluent-gh-actions@0.3": "jsr:@tsirysndr/fluent-gh-actions@0.3.0", 20 + "jsr:@tsirysndr/fluent-gitlab-ci@0.5": "jsr:@tsirysndr/fluent-gitlab-ci@0.5.0", 21 + "npm:graphql-request@6.1.0": "npm:graphql-request@6.1.0_graphql@16.8.1", 22 + "npm:graphql@16.8.1": "npm:graphql@16.8.1", 23 + "npm:lodash@4.17.21": "npm:lodash@4.17.21", 24 + "npm:node-color-log@11.0.2": "npm:node-color-log@11.0.2", 25 + "npm:stringify-tree@1.1.1": "npm:stringify-tree@1.1.1", 26 + "npm:yaml@2.3.1": "npm:yaml@2.3.1", 27 + "npm:zod@3.22.1": "npm:zod@3.22.1" 28 + }, 29 + "jsr": { 30 + "@std/assert@0.217.0": { 31 + "integrity": "c98e279362ca6982d5285c3b89517b757c1e3477ee9f14eb2fdf80a45aaa9642", 32 + "dependencies": [ 33 + "jsr:@std/fmt@^0.217.0" 34 + ] 35 + }, 36 + "@std/assert@0.218.2": { 37 + "integrity": "7f0a5a1a8cf86607cd6c2c030584096e1ffad27fc9271429a8cb48cfbdee5eaf", 38 + "dependencies": [ 39 + "jsr:@std/fmt@^0.218.2" 40 + ] 41 + }, 42 + "@std/flags@0.218.2": { 43 + "integrity": "0d4e8ac15e7dfede26153c63a6d55d0aad56ae88beb2ede38c14c775dfc5b25e", 44 + "dependencies": [ 45 + "jsr:@std/assert@^0.218.2" 46 + ] 47 + }, 48 + "@std/fmt@0.217.0": { 49 + "integrity": "cb99f82500b8da20202fedfa8bb94dd0222e81f0494ed9087de20ee3d8a39a8d" 50 + }, 51 + "@std/fmt@0.218.2": { 52 + "integrity": "99526449d2505aa758b6cbef81e7dd471d8b28ec0dcb1491d122b284c548788a" 53 + }, 54 + "@std/path@0.218.2": { 55 + "integrity": "b568fd923d9e53ad76d17c513e7310bda8e755a3e825e6289a0ce536404e2662", 56 + "dependencies": [ 57 + "jsr:@std/assert@^0.218.2" 58 + ] 59 + }, 60 + "@std/testing@0.217.0": { 61 + "integrity": "97508b254ca1888d512215288bfb3f192a4e6e84336ba56b189c7862258a058b", 62 + "dependencies": [ 63 + "jsr:@std/assert@^0.217.0" 64 + ] 65 + }, 66 + "@std/testing@0.218.2": { 67 + "integrity": "49410b23584c924533786e6c117d71486c1daa65f4911fd6cfc95e4edba9de7f", 68 + "dependencies": [ 69 + "jsr:@std/assert@^0.218.2" 70 + ] 71 + }, 72 + "@tsirysndr/env-js@0.1.2": { 73 + "integrity": "16a8cf4e60c8b43f4d62dd762006de40d56e5b144a56c0954a11f99ee12c5d3a" 74 + }, 75 + "@tsirysndr/exit-js@0.1.0": { 76 + "integrity": "4ea378ce2575931426bcf60d4588c9e9cf489fa93d3907cd9ee60feb38960230" 77 + }, 78 + "@tsirysndr/fluent-az-pipelines@0.3.1": { 79 + "integrity": "50f25c5d21908debf3d7218c3ec4c0f987ed891a85a0b3e133e497492c57361b", 80 + "dependencies": [ 81 + "jsr:@std/testing@0.217.0", 82 + "npm:yaml@2.3.1", 83 + "npm:zod@3.22.1" 84 + ] 85 + }, 86 + "@tsirysndr/fluent-circleci@0.3.1": { 87 + "integrity": "74bab37b52a2289d8a093b57ea41092afbf2ed488f17795d440811ac9ebc2543", 88 + "dependencies": [ 89 + "jsr:@std/testing@0.217.0", 90 + "npm:lodash@4.17.21", 91 + "npm:yaml@2.3.1", 92 + "npm:zod@3.22.1" 93 + ] 94 + }, 95 + "@tsirysndr/fluent-codepipeline@0.3.0": { 96 + "integrity": "3050df3fed469d6791831a0a83529de77732d14c27f4a1446788de2c740c73df", 97 + "dependencies": [ 98 + "jsr:@std/testing@0.217.0", 99 + "npm:yaml@2.3.1", 100 + "npm:zod@3.22.1" 101 + ] 102 + }, 103 + "@tsirysndr/fluent-gh-actions@0.3.0": { 104 + "integrity": "2eaff18fbe9b25042fbb321d3bec61a34a15f736ec95bd2da214dcd1c3b8d5cd", 105 + "dependencies": [ 106 + "jsr:@std/testing@0.217.0", 107 + "npm:yaml@2.3.1", 108 + "npm:zod@3.22.1" 109 + ] 110 + }, 111 + "@tsirysndr/fluent-gitlab-ci@0.5.0": { 112 + "integrity": "57e7d231375902358d2bd5b63766f8ffb7030157a9e3764d5e0b0fb7533dd3f9", 113 + "dependencies": [ 114 + "jsr:@std/testing@0.217.0", 115 + "npm:yaml@2.3.1", 116 + "npm:zod@3.22.1" 117 + ] 118 + } 119 + }, 120 + "npm": { 121 + "@graphql-typed-document-node/core@3.2.0_graphql@16.8.1": { 122 + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", 123 + "dependencies": { 124 + "graphql": "graphql@16.8.1" 125 + } 126 + }, 127 + "@types/lodash.flatten@4.4.9": { 128 + "integrity": "sha512-JCW9xofpn9oJfFSccpBRF8IrB5guqmcKZIa7J9DnZqLd9wgGYbewaYnjbNw3Fb+St8BHVsnGmmS0A3j99LII3Q==", 129 + "dependencies": { 130 + "@types/lodash": "@types/lodash@4.17.7" 131 + } 132 + }, 133 + "@types/lodash@4.17.7": { 134 + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", 135 + "dependencies": {} 136 + }, 137 + "cross-fetch@3.1.8": { 138 + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", 139 + "dependencies": { 140 + "node-fetch": "node-fetch@2.7.0" 141 + } 142 + }, 143 + "graphql-request@6.1.0_graphql@16.8.1": { 144 + "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", 145 + "dependencies": { 146 + "@graphql-typed-document-node/core": "@graphql-typed-document-node/core@3.2.0_graphql@16.8.1", 147 + "cross-fetch": "cross-fetch@3.1.8", 148 + "graphql": "graphql@16.8.1" 149 + } 150 + }, 151 + "graphql@16.8.1": { 152 + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", 153 + "dependencies": {} 154 + }, 155 + "lodash.flatten@4.4.0": { 156 + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", 157 + "dependencies": {} 158 + }, 159 + "lodash@4.17.21": { 160 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 161 + "dependencies": {} 162 + }, 163 + "node-color-log@11.0.2": { 164 + "integrity": "sha512-+gD5pQpVpEkEA3He9STku4VL1EO9SaOW3HElumCd3xWorulnfr2053NCSVwPCXrkwI5ihPYucQxSCSOuS1q+Eg==", 165 + "dependencies": {} 166 + }, 167 + "node-fetch@2.7.0": { 168 + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 169 + "dependencies": { 170 + "whatwg-url": "whatwg-url@5.0.0" 171 + } 172 + }, 173 + "stringify-tree@1.1.1": { 174 + "integrity": "sha512-lVfVX+HJ9Gx2NUv0vJTRhqCPYlgzbdR25MF34Md1Bjq6jvJocOLgfHhusYtBSKi/bwpkgLGjtF/dVZlBbA6oZw==", 175 + "dependencies": { 176 + "@types/lodash.flatten": "@types/lodash.flatten@4.4.9", 177 + "lodash.flatten": "lodash.flatten@4.4.0" 178 + } 179 + }, 180 + "tr46@0.0.3": { 181 + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 182 + "dependencies": {} 183 + }, 184 + "webidl-conversions@3.0.1": { 185 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 186 + "dependencies": {} 187 + }, 188 + "whatwg-url@5.0.0": { 189 + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 190 + "dependencies": { 191 + "tr46": "tr46@0.0.3", 192 + "webidl-conversions": "webidl-conversions@3.0.1" 193 + } 194 + }, 195 + "yaml@2.3.1": { 196 + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", 197 + "dependencies": {} 198 + }, 199 + "zod@3.22.1": { 200 + "integrity": "sha512-+qUhAMl414+Elh+fRNtpU+byrwjDFOS1N7NioLY+tSlcADTx4TkCUua/hxJvxwDXcV4397/nZ420jy4n4+3WUg==", 201 + "dependencies": {} 202 + } 203 + } 204 + }, 205 + "remote": {} 206 + }
+48
.fluentci/deps.ts
··· 1 + export { assertEquals } from "jsr:@std/testing@0.218.2/asserts"; 2 + 3 + export type { DirectoryID, SecretID } from "./sdk/client.gen.ts"; 4 + export { 5 + Directory, 6 + Secret, 7 + File, 8 + type Platform, 9 + Container, 10 + dag, 11 + } from "./sdk/client.gen.ts"; 12 + export { brightGreen } from "jsr:@std/fmt@0.218.2/colors"; 13 + export { stringifyTree } from "npm:stringify-tree@1.1.1"; 14 + import { gql } from "npm:graphql-request@6.1.0"; 15 + export { gql }; 16 + export { dirname, join, resolve } from "jsr:@std/path@0.218.2"; 17 + export { parse } from "jsr:@std/flags@0.218.2"; 18 + 19 + import * as _ from "npm:lodash@4.17.21"; 20 + const snakeCase = _.default.snakeCase; 21 + const camelCase = _.default.camelCase; 22 + export { snakeCase, camelCase }; 23 + 24 + import * as env from "jsr:@tsirysndr/env-js@0.1.2"; 25 + export { env }; 26 + export { exit } from "jsr:@tsirysndr/exit-js@0.1.0"; 27 + 28 + export { ClientError, GraphQLClient } from "npm:graphql-request@6.1.0"; 29 + export { 30 + DaggerSDKError, 31 + UnknownDaggerError, 32 + DockerImageRefValidationError, 33 + EngineSessionConnectParamsParseError, 34 + ExecError, 35 + GraphQLRequestError, 36 + InitEngineSessionBinaryError, 37 + TooManyNestedObjectsError, 38 + EngineSessionError, 39 + EngineSessionConnectionTimeoutError, 40 + NotAwaitedRequestError, 41 + ERROR_CODES, 42 + } from "./sdk/common/errors/index.ts"; 43 + 44 + export * as FluentGitlabCI from "jsr:@tsirysndr/fluent-gitlab-ci@0.5"; 45 + export * as FluentGithubActions from "jsr:@tsirysndr/fluent-gh-actions@0.3"; 46 + export * as FluentCircleCI from "jsr:@tsirysndr/fluent-circleci@0.3"; 47 + export * as FluentAzurePipelines from "jsr:@tsirysndr/fluent-az-pipelines@0.3"; 48 + export * as FluentAWSCodePipeline from "jsr:@tsirysndr/fluent-codepipeline@0.3";
+28
.fluentci/fixtures/.gitlab-ci.yml
··· 1 + # Do not edit this file directly. It is generated by https://deno.land/x/fluent_gitlab_ci 2 + 3 + .docker: 4 + image: denoland/deno:alpine 5 + services: 6 + - docker:${DOCKER_VERSION}-dind 7 + variables: 8 + DOCKER_HOST: tcp://docker:2376 9 + DOCKER_TLS_VERIFY: "1" 10 + DOCKER_TLS_CERTDIR: /certs 11 + DOCKER_CERT_PATH: /certs/client 12 + DOCKER_DRIVER: overlay2 13 + DOCKER_VERSION: 20.10.16 14 + 15 + .dagger: 16 + extends: .docker 17 + before_script: 18 + - apk add docker-cli curl unzip 19 + - deno install -A -r https://cli.fluentci.io -n fluentci 20 + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.9.7 sh 21 + - mv bin/dagger /usr/local/bin 22 + - dagger version 23 + 24 + base: 25 + extends: .dagger 26 + script: 27 + - fluentci run . 28 +
+22
.fluentci/fixtures/azure-pipelines.yml
··· 1 + # Do not edit this file directly. It is generated by https://deno.land/x/fluent_azure_pipelines 2 + 3 + trigger: 4 + - main 5 + pool: 6 + name: Default 7 + vmImage: ubuntu-latest 8 + steps: 9 + - script: | 10 + curl -fsSL https://deno.land/x/install/install.sh | sh 11 + export DENO_INSTALL="$HOME/.deno" 12 + export PATH="$DENO_INSTALL/bin:$PATH" 13 + displayName: Install Deno 14 + - script: deno install -A -r https://cli.fluentci.io -n fluentci 15 + displayName: Setup Fluent CI CLI 16 + - script: | 17 + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.9.7 sh 18 + sudo mv bin/dagger /usr/local/bin 19 + dagger version 20 + displayName: Setup Dagger 21 + - script: fluentci run . 22 + displayName: Run Dagger Pipelines
+16
.fluentci/fixtures/base.yml
··· 1 + # Do not edit this file directly. It is generated by https://deno.land/x/fluent_github_actions 2 + 3 + name: base 4 + on: 5 + push: 6 + branches: 7 + - main 8 + jobs: 9 + tests: 10 + runs-on: ubuntu-latest 11 + steps: 12 + - uses: actions/checkout@v3 13 + - name: Setup Fluent CI 14 + uses: fluentci-io/setup-fluentci@v3 15 + - name: Run Dagger Pipelines 16 + run: fluentci run .
+19
.fluentci/fixtures/buildspec.yml
··· 1 + # Do not edit this file directly. It is generated by https://deno.land/x/fluent_aws_codepipeline 2 + 3 + version: 0.2 4 + phases: 5 + install: 6 + commands: 7 + - curl -fsSL https://deno.land/x/install/install.sh | sh 8 + - export DENO_INSTALL="$HOME/.deno" 9 + - export PATH="$DENO_INSTALL/bin:$PATH" 10 + - deno install -A -r https://cli.fluentci.io -n fluentci 11 + - curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.9.7 sh 12 + - mv bin/dagger /usr/local/bin 13 + - dagger version 14 + build: 15 + commands: 16 + - fluentci run . 17 + post_build: 18 + commands: 19 + - echo Build completed on `date`
+26
.fluentci/fixtures/config.yml
··· 1 + # Do not edit this file directly. It is generated by https://deno.land/x/fluent_circleci 2 + 3 + version: 2.1 4 + jobs: 5 + base: 6 + steps: 7 + - checkout 8 + - run: sudo apt-get update && sudo apt-get install -y curl unzip 9 + - run: | 10 + curl -fsSL https://deno.land/x/install/install.sh | sh 11 + export DENO_INSTALL="$HOME/.deno" 12 + export PATH="$DENO_INSTALL/bin:$PATH" 13 + - run: deno install -A -r https://cli.fluentci.io -n fluentci 14 + - run: | 15 + curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.9.7 sh 16 + sudo mv bin/dagger /usr/local/bin 17 + dagger version 18 + - run: 19 + name: Run Dagger Pipelines 20 + command: fluentci run . 21 + machine: 22 + image: ubuntu-2004:2023.07.1 23 + workflows: 24 + dagger: 25 + jobs: 26 + - base
+61
.fluentci/flake.lock
··· 1 + { 2 + "nodes": { 3 + "flake-utils": { 4 + "inputs": { 5 + "systems": "systems" 6 + }, 7 + "locked": { 8 + "lastModified": 1689068808, 9 + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", 10 + "owner": "numtide", 11 + "repo": "flake-utils", 12 + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", 13 + "type": "github" 14 + }, 15 + "original": { 16 + "owner": "numtide", 17 + "repo": "flake-utils", 18 + "type": "github" 19 + } 20 + }, 21 + "nixpkgs": { 22 + "locked": { 23 + "lastModified": 1692638711, 24 + "narHash": "sha256-J0LgSFgJVGCC1+j5R2QndadWI1oumusg6hCtYAzLID4=", 25 + "owner": "NixOS", 26 + "repo": "nixpkgs", 27 + "rev": "91a22f76cd1716f9d0149e8a5c68424bb691de15", 28 + "type": "github" 29 + }, 30 + "original": { 31 + "owner": "NixOS", 32 + "ref": "nixos-unstable", 33 + "repo": "nixpkgs", 34 + "type": "github" 35 + } 36 + }, 37 + "root": { 38 + "inputs": { 39 + "flake-utils": "flake-utils", 40 + "nixpkgs": "nixpkgs" 41 + } 42 + }, 43 + "systems": { 44 + "locked": { 45 + "lastModified": 1681028828, 46 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 + "owner": "nix-systems", 48 + "repo": "default", 49 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 + "type": "github" 51 + }, 52 + "original": { 53 + "owner": "nix-systems", 54 + "repo": "default", 55 + "type": "github" 56 + } 57 + } 58 + }, 59 + "root": "root", 60 + "version": 7 61 + }
+26
.fluentci/flake.nix
··· 1 + { 2 + description = "A Nix-flake-based Deno development environment"; 3 + 4 + inputs = { 5 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 + flake-utils.url = "github:numtide/flake-utils"; 7 + }; 8 + 9 + outputs = { 10 + self, 11 + nixpkgs, 12 + flake-utils, 13 + }: 14 + flake-utils.lib.eachDefaultSystem 15 + (system: let 16 + pkgs = import nixpkgs { 17 + inherit system; 18 + }; 19 + in { 20 + devShells.default = pkgs.mkShell { 21 + buildInputs = [ 22 + pkgs.deno 23 + ]; 24 + }; 25 + }); 26 + }
+8
.fluentci/fluentci.toml
··· 1 + 2 + [package] 3 + authors = ["Tsiry Sandratraina <tsiry.sndr@fluentci.io>"] 4 + description = "CI/CD for Rockbox" 5 + license = "MIT" 6 + name = "rockbox" 7 + version = "0.1.0" 8 + keywords = ["rockbox","zig","rust"]
+34
.fluentci/import_map.json
··· 1 + { 2 + "imports": { 3 + "@fluentci.io/dagger": "https://sdk.fluentci.io/v0.1.9/mod.ts", 4 + "@dagger.io/dagger": "https://esm.sh/v128/*@dagger.io/dagger@0.8.4", 5 + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", 6 + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", 7 + "fluent_gitlab_ci": "https://deno.land/x/fluent_gitlab_ci@v0.4.2/mod.ts", 8 + "fluent_github_actions": "https://deno.land/x/fluent_github_actions@v0.2.1/mod.ts", 9 + "fluent_circleci": "https://deno.land/x/fluent_circleci@v0.2.5/mod.ts", 10 + "fluent_azure_pipelines": "https://deno.land/x/fluent_azure_pipelines@v0.2.0/mod.ts", 11 + "fluent_aws_codepipeline": "https://deno.land/x/fluent_aws_codepipeline@v0.2.3/mod.ts", 12 + "url": "node:url", 13 + "readline": "node:readline", 14 + "process": "node:process", 15 + "path": "node:path", 16 + "os": "node:os", 17 + "fs": "node:fs", 18 + "crypto": "node:crypto" 19 + }, 20 + "scopes": { 21 + "https://esm.sh/v128/": { 22 + "@lifeomic/axios-fetch": "https://esm.sh/v128/@lifeomic/axios-fetch@3.0.1", 23 + "adm-zip": "https://esm.sh/v128/adm-zip@0.5.10", 24 + "env-paths": "https://esm.sh/v128/env-paths@3.0.0", 25 + "execa": "https://esm.sh/v128/execa@7.1.1", 26 + "graphql-request": "https://esm.sh/v128/graphql-request@6.1.0", 27 + "graphql-tag": "https://esm.sh/v128/graphql-tag@2.12.6", 28 + "graphql": "https://esm.sh/v128/graphql@16.7.1", 29 + "node-color-log": "https://esm.sh/v128/node-color-log@10.0.2", 30 + "node-fetch": "https://esm.sh/v128/node-fetch@3.3.1", 31 + "tar": "https://esm.sh/v128/tar@6.1.15" 32 + } 33 + } 34 + }
+1
.fluentci/mod.ts
··· 1 + export * from "./src/mod.ts";
+1
.fluentci/plugin/.gitignore
··· 1 + target/*
+395
.fluentci/plugin/Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "anyhow" 7 + version = "1.0.81" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" 10 + 11 + [[package]] 12 + name = "autocfg" 13 + version = "1.2.0" 14 + source = "registry+https://github.com/rust-lang/crates.io-index" 15 + checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 16 + 17 + [[package]] 18 + name = "base" 19 + version = "0.10.1" 20 + dependencies = [ 21 + "extism-pdk", 22 + "fluentci-pdk", 23 + ] 24 + 25 + [[package]] 26 + name = "base64" 27 + version = "0.21.7" 28 + source = "registry+https://github.com/rust-lang/crates.io-index" 29 + checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 30 + 31 + [[package]] 32 + name = "base64" 33 + version = "0.22.0" 34 + source = "registry+https://github.com/rust-lang/crates.io-index" 35 + checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" 36 + 37 + [[package]] 38 + name = "bytemuck" 39 + version = "1.15.0" 40 + source = "registry+https://github.com/rust-lang/crates.io-index" 41 + checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" 42 + 43 + [[package]] 44 + name = "byteorder" 45 + version = "1.5.0" 46 + source = "registry+https://github.com/rust-lang/crates.io-index" 47 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 48 + 49 + [[package]] 50 + name = "bytes" 51 + version = "1.6.0" 52 + source = "registry+https://github.com/rust-lang/crates.io-index" 53 + checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 54 + 55 + [[package]] 56 + name = "either" 57 + version = "1.10.0" 58 + source = "registry+https://github.com/rust-lang/crates.io-index" 59 + checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 60 + 61 + [[package]] 62 + name = "equivalent" 63 + version = "1.0.1" 64 + source = "registry+https://github.com/rust-lang/crates.io-index" 65 + checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 66 + 67 + [[package]] 68 + name = "extism-convert" 69 + version = "1.2.0" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "a63bfc6d371d3b51d6094fd96c4c32a084ceefece3b4f4b328f30067d29da064" 72 + dependencies = [ 73 + "anyhow", 74 + "base64 0.22.0", 75 + "bytemuck", 76 + "extism-convert-macros", 77 + "prost", 78 + "rmp-serde", 79 + "serde", 80 + "serde_json", 81 + ] 82 + 83 + [[package]] 84 + name = "extism-convert-macros" 85 + version = "1.2.0" 86 + source = "registry+https://github.com/rust-lang/crates.io-index" 87 + checksum = "519ccf960500c87244bef99caf8e58222ac95bf1abb06a32f5217b4788857aa6" 88 + dependencies = [ 89 + "manyhow", 90 + "proc-macro-crate", 91 + "proc-macro2", 92 + "quote", 93 + "syn", 94 + ] 95 + 96 + [[package]] 97 + name = "extism-manifest" 98 + version = "1.2.0" 99 + source = "registry+https://github.com/rust-lang/crates.io-index" 100 + checksum = "05c7d16695dc6b72418e23b58c943411a08264332af403ae9870997b4d495c3d" 101 + dependencies = [ 102 + "base64 0.22.0", 103 + "serde", 104 + "serde_json", 105 + ] 106 + 107 + [[package]] 108 + name = "extism-pdk" 109 + version = "1.1.0" 110 + source = "registry+https://github.com/rust-lang/crates.io-index" 111 + checksum = "1f9a87d636d30b75e697642dd4f6cff2054db5a7a5d69d6601041a76265bb681" 112 + dependencies = [ 113 + "anyhow", 114 + "base64 0.21.7", 115 + "extism-convert", 116 + "extism-manifest", 117 + "extism-pdk-derive", 118 + "serde", 119 + "serde_json", 120 + ] 121 + 122 + [[package]] 123 + name = "extism-pdk-derive" 124 + version = "1.1.0" 125 + source = "registry+https://github.com/rust-lang/crates.io-index" 126 + checksum = "d83995c2023720a0fd5ef2a349c89c1670efb37a979228b0218705f5ddb50d4b" 127 + dependencies = [ 128 + "proc-macro2", 129 + "quote", 130 + "syn", 131 + ] 132 + 133 + [[package]] 134 + name = "fluentci-pdk" 135 + version = "0.1.9" 136 + source = "registry+https://github.com/rust-lang/crates.io-index" 137 + checksum = "4d8004273f0e173b96811a72cb742fc9010fc54fec89c59c2c4e7e159fc2bde7" 138 + dependencies = [ 139 + "extism-pdk", 140 + "fluentci-types", 141 + "serde", 142 + ] 143 + 144 + [[package]] 145 + name = "fluentci-types" 146 + version = "0.1.3" 147 + source = "registry+https://github.com/rust-lang/crates.io-index" 148 + checksum = "7592ba0dd1c48f06166fa485af48c8df942e7266c62216fe01360b33e33fe047" 149 + dependencies = [ 150 + "serde", 151 + ] 152 + 153 + [[package]] 154 + name = "hashbrown" 155 + version = "0.14.3" 156 + source = "registry+https://github.com/rust-lang/crates.io-index" 157 + checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 158 + 159 + [[package]] 160 + name = "indexmap" 161 + version = "2.2.6" 162 + source = "registry+https://github.com/rust-lang/crates.io-index" 163 + checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 164 + dependencies = [ 165 + "equivalent", 166 + "hashbrown", 167 + ] 168 + 169 + [[package]] 170 + name = "itertools" 171 + version = "0.12.1" 172 + source = "registry+https://github.com/rust-lang/crates.io-index" 173 + checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 174 + dependencies = [ 175 + "either", 176 + ] 177 + 178 + [[package]] 179 + name = "itoa" 180 + version = "1.0.11" 181 + source = "registry+https://github.com/rust-lang/crates.io-index" 182 + checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 183 + 184 + [[package]] 185 + name = "manyhow" 186 + version = "0.11.1" 187 + source = "registry+https://github.com/rust-lang/crates.io-index" 188 + checksum = "02bc2a348104913df6d14170bedef54faf224a0970ec7b1f8750748ab94fcd52" 189 + dependencies = [ 190 + "manyhow-macros", 191 + "proc-macro2", 192 + "quote", 193 + "syn", 194 + ] 195 + 196 + [[package]] 197 + name = "manyhow-macros" 198 + version = "0.11.0" 199 + source = "registry+https://github.com/rust-lang/crates.io-index" 200 + checksum = "532aa12d5846b38a524b3acd99fb74dc8a5f193b33e65dac142ef92bd60f9416" 201 + dependencies = [ 202 + "proc-macro-utils", 203 + "proc-macro2", 204 + "quote", 205 + ] 206 + 207 + [[package]] 208 + name = "memchr" 209 + version = "2.7.2" 210 + source = "registry+https://github.com/rust-lang/crates.io-index" 211 + checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 212 + 213 + [[package]] 214 + name = "num-traits" 215 + version = "0.2.18" 216 + source = "registry+https://github.com/rust-lang/crates.io-index" 217 + checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 218 + dependencies = [ 219 + "autocfg", 220 + ] 221 + 222 + [[package]] 223 + name = "paste" 224 + version = "1.0.14" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 227 + 228 + [[package]] 229 + name = "proc-macro-crate" 230 + version = "3.1.0" 231 + source = "registry+https://github.com/rust-lang/crates.io-index" 232 + checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 233 + dependencies = [ 234 + "toml_edit", 235 + ] 236 + 237 + [[package]] 238 + name = "proc-macro-utils" 239 + version = "0.8.0" 240 + source = "registry+https://github.com/rust-lang/crates.io-index" 241 + checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8" 242 + dependencies = [ 243 + "proc-macro2", 244 + "quote", 245 + "smallvec", 246 + ] 247 + 248 + [[package]] 249 + name = "proc-macro2" 250 + version = "1.0.79" 251 + source = "registry+https://github.com/rust-lang/crates.io-index" 252 + checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 253 + dependencies = [ 254 + "unicode-ident", 255 + ] 256 + 257 + [[package]] 258 + name = "prost" 259 + version = "0.12.4" 260 + source = "registry+https://github.com/rust-lang/crates.io-index" 261 + checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" 262 + dependencies = [ 263 + "bytes", 264 + "prost-derive", 265 + ] 266 + 267 + [[package]] 268 + name = "prost-derive" 269 + version = "0.12.4" 270 + source = "registry+https://github.com/rust-lang/crates.io-index" 271 + checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" 272 + dependencies = [ 273 + "anyhow", 274 + "itertools", 275 + "proc-macro2", 276 + "quote", 277 + "syn", 278 + ] 279 + 280 + [[package]] 281 + name = "quote" 282 + version = "1.0.35" 283 + source = "registry+https://github.com/rust-lang/crates.io-index" 284 + checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 285 + dependencies = [ 286 + "proc-macro2", 287 + ] 288 + 289 + [[package]] 290 + name = "rmp" 291 + version = "0.8.12" 292 + source = "registry+https://github.com/rust-lang/crates.io-index" 293 + checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" 294 + dependencies = [ 295 + "byteorder", 296 + "num-traits", 297 + "paste", 298 + ] 299 + 300 + [[package]] 301 + name = "rmp-serde" 302 + version = "1.1.2" 303 + source = "registry+https://github.com/rust-lang/crates.io-index" 304 + checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" 305 + dependencies = [ 306 + "byteorder", 307 + "rmp", 308 + "serde", 309 + ] 310 + 311 + [[package]] 312 + name = "ryu" 313 + version = "1.0.17" 314 + source = "registry+https://github.com/rust-lang/crates.io-index" 315 + checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 316 + 317 + [[package]] 318 + name = "serde" 319 + version = "1.0.197" 320 + source = "registry+https://github.com/rust-lang/crates.io-index" 321 + checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 322 + dependencies = [ 323 + "serde_derive", 324 + ] 325 + 326 + [[package]] 327 + name = "serde_derive" 328 + version = "1.0.197" 329 + source = "registry+https://github.com/rust-lang/crates.io-index" 330 + checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 331 + dependencies = [ 332 + "proc-macro2", 333 + "quote", 334 + "syn", 335 + ] 336 + 337 + [[package]] 338 + name = "serde_json" 339 + version = "1.0.115" 340 + source = "registry+https://github.com/rust-lang/crates.io-index" 341 + checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" 342 + dependencies = [ 343 + "itoa", 344 + "ryu", 345 + "serde", 346 + ] 347 + 348 + [[package]] 349 + name = "smallvec" 350 + version = "1.13.2" 351 + source = "registry+https://github.com/rust-lang/crates.io-index" 352 + checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 353 + 354 + [[package]] 355 + name = "syn" 356 + version = "2.0.58" 357 + source = "registry+https://github.com/rust-lang/crates.io-index" 358 + checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" 359 + dependencies = [ 360 + "proc-macro2", 361 + "quote", 362 + "unicode-ident", 363 + ] 364 + 365 + [[package]] 366 + name = "toml_datetime" 367 + version = "0.6.5" 368 + source = "registry+https://github.com/rust-lang/crates.io-index" 369 + checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 370 + 371 + [[package]] 372 + name = "toml_edit" 373 + version = "0.21.1" 374 + source = "registry+https://github.com/rust-lang/crates.io-index" 375 + checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 376 + dependencies = [ 377 + "indexmap", 378 + "toml_datetime", 379 + "winnow", 380 + ] 381 + 382 + [[package]] 383 + name = "unicode-ident" 384 + version = "1.0.12" 385 + source = "registry+https://github.com/rust-lang/crates.io-index" 386 + checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 387 + 388 + [[package]] 389 + name = "winnow" 390 + version = "0.5.40" 391 + source = "registry+https://github.com/rust-lang/crates.io-index" 392 + checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 393 + dependencies = [ 394 + "memchr", 395 + ]
+13
.fluentci/plugin/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "base" 4 + version = "0.10.1" 5 + 6 + [lib] 7 + crate-type = ["cdylib"] 8 + 9 + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 + 11 + [dependencies] 12 + extism-pdk = "1.1.0" 13 + fluentci-pdk = "0.1.9"
+11
.fluentci/plugin/src/lib.rs
··· 1 + use extism_pdk::*; 2 + use fluentci_pdk::dag; 3 + 4 + #[plugin_fn] 5 + pub fn hello(args: String) -> FnResult<String> { 6 + let stdout = dag() 7 + .pipeline("hello")? 8 + .with_exec(vec!["echo Hello", &args])? 9 + .stdout()?; 10 + Ok(stdout) 11 + }
+31
.fluentci/sdk/builder.ts
··· 1 + import { createGQLClient } from "./client.ts"; 2 + import { Context } from "./context.ts"; 3 + import { env } from "../deps.ts"; 4 + 5 + /** 6 + * @hidden 7 + * 8 + * Initialize a default client context from environment. 9 + */ 10 + export function initDefaultContext(): Context { 11 + let ctx = new Context(); 12 + 13 + // Prefer DAGGER_SESSION_PORT if set 14 + const daggerSessionPort = env.get("DAGGER_SESSION_PORT"); 15 + if (daggerSessionPort) { 16 + const sessionToken = env.get("DAGGER_SESSION_TOKEN"); 17 + if (!sessionToken) { 18 + throw new Error( 19 + "DAGGER_SESSION_TOKEN must be set when using DAGGER_SESSION_PORT" 20 + ); 21 + } 22 + 23 + ctx = new Context({ 24 + client: createGQLClient(Number(daggerSessionPort), sessionToken), 25 + }); 26 + } else { 27 + throw new Error("DAGGER_SESSION_PORT must be set"); 28 + } 29 + 30 + return ctx; 31 + }
+8231
.fluentci/sdk/client.gen.ts
··· 1 + /** 2 + * This file was auto-generated by `client-gen`. 3 + * Do not make direct changes to the file. 4 + */ 5 + import { Context, defaultContext } from "./context.ts"; 6 + import { computeQuery } from "./utils.ts"; 7 + 8 + /** 9 + * @hidden 10 + */ 11 + export type QueryTree = { 12 + operation: string; 13 + args?: Record<string, unknown>; 14 + }; 15 + 16 + /** 17 + * @hidden 18 + */ 19 + export type Metadata = { 20 + [key: string]: { 21 + is_enum?: boolean; 22 + }; 23 + }; 24 + 25 + interface ClientConfig { 26 + queryTree?: QueryTree[]; 27 + ctx?: Context; 28 + } 29 + 30 + class BaseClient { 31 + protected _queryTree: QueryTree[]; 32 + protected _ctx: Context; 33 + 34 + /** 35 + * @hidden 36 + */ 37 + constructor({ queryTree, ctx }: ClientConfig = {}) { 38 + this._queryTree = queryTree || []; 39 + this._ctx = ctx || new Context(); 40 + } 41 + 42 + /** 43 + * @hidden 44 + */ 45 + get queryTree() { 46 + return this._queryTree; 47 + } 48 + } 49 + 50 + export type BuildArg = { 51 + /** 52 + * The build argument name. 53 + */ 54 + name: string; 55 + 56 + /** 57 + * The build argument value. 58 + */ 59 + value: string; 60 + }; 61 + 62 + /** 63 + * Sharing mode of the cache volume. 64 + */ 65 + export enum CacheSharingMode { 66 + /** 67 + * Shares the cache volume amongst many build pipelines, but will serialize the writes 68 + */ 69 + Locked = "LOCKED", 70 + 71 + /** 72 + * Keeps a cache volume for a single build pipeline 73 + */ 74 + Private = "PRIVATE", 75 + 76 + /** 77 + * Shares the cache volume amongst many build pipelines 78 + */ 79 + Shared = "SHARED", 80 + } 81 + /** 82 + * The `CacheVolumeID` scalar type represents an identifier for an object of type CacheVolume. 83 + */ 84 + export type CacheVolumeID = string & { __CacheVolumeID: never }; 85 + 86 + export type ContainerAsTarballOpts = { 87 + /** 88 + * Identifiers for other platform specific containers. 89 + * 90 + * Used for multi-platform images. 91 + */ 92 + platformVariants?: Container[]; 93 + 94 + /** 95 + * Force each layer of the image to use the specified compression algorithm. 96 + * 97 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 98 + */ 99 + forcedCompression?: ImageLayerCompression; 100 + 101 + /** 102 + * Use the specified media types for the image's layers. 103 + * 104 + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. 105 + */ 106 + mediaTypes?: ImageMediaTypes; 107 + }; 108 + 109 + export type ContainerBuildOpts = { 110 + /** 111 + * Path to the Dockerfile to use. 112 + */ 113 + dockerfile?: string; 114 + 115 + /** 116 + * Target build stage to build. 117 + */ 118 + target?: string; 119 + 120 + /** 121 + * Additional build arguments. 122 + */ 123 + buildArgs?: BuildArg[]; 124 + 125 + /** 126 + * Secrets to pass to the build. 127 + * 128 + * They will be mounted at /run/secrets/[secret-name] in the build container 129 + * 130 + * They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl [http://example.com?token=$(cat /run/secrets/my-secret)](http://example.com?token=$(cat /run/secrets/my-secret)) 131 + */ 132 + secrets?: Secret[]; 133 + }; 134 + 135 + export type ContainerExportOpts = { 136 + /** 137 + * Identifiers for other platform specific containers. 138 + * 139 + * Used for multi-platform image. 140 + */ 141 + platformVariants?: Container[]; 142 + 143 + /** 144 + * Force each layer of the exported image to use the specified compression algorithm. 145 + * 146 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 147 + */ 148 + forcedCompression?: ImageLayerCompression; 149 + 150 + /** 151 + * Use the specified media types for the exported image's layers. 152 + * 153 + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. 154 + */ 155 + mediaTypes?: ImageMediaTypes; 156 + }; 157 + 158 + export type ContainerImportOpts = { 159 + /** 160 + * Identifies the tag to import from the archive, if the archive bundles multiple tags. 161 + */ 162 + tag?: string; 163 + }; 164 + 165 + export type ContainerPipelineOpts = { 166 + /** 167 + * Description of the sub-pipeline. 168 + */ 169 + description?: string; 170 + 171 + /** 172 + * Labels to apply to the sub-pipeline. 173 + */ 174 + labels?: PipelineLabel[]; 175 + }; 176 + 177 + export type ContainerPublishOpts = { 178 + /** 179 + * Identifiers for other platform specific containers. 180 + * 181 + * Used for multi-platform image. 182 + */ 183 + platformVariants?: Container[]; 184 + 185 + /** 186 + * Force each layer of the published image to use the specified compression algorithm. 187 + * 188 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 189 + */ 190 + forcedCompression?: ImageLayerCompression; 191 + 192 + /** 193 + * Use the specified media types for the published image's layers. 194 + * 195 + * Defaults to OCI, which is largely compatible with most recent registries, but Docker may be needed for older registries without OCI support. 196 + */ 197 + mediaTypes?: ImageMediaTypes; 198 + }; 199 + 200 + export type ContainerTerminalOpts = { 201 + /** 202 + * If set, override the container's default terminal command and invoke these command arguments instead. 203 + */ 204 + cmd?: string[]; 205 + }; 206 + 207 + export type ContainerWithDirectoryOpts = { 208 + /** 209 + * Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). 210 + */ 211 + exclude?: string[]; 212 + 213 + /** 214 + * Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). 215 + */ 216 + include?: string[]; 217 + 218 + /** 219 + * A user:group to set for the directory and its contents. 220 + * 221 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 222 + * 223 + * If the group is omitted, it defaults to the same as the user. 224 + */ 225 + owner?: string; 226 + }; 227 + 228 + export type ContainerWithEntrypointOpts = { 229 + /** 230 + * Don't remove the default arguments when setting the entrypoint. 231 + */ 232 + keepDefaultArgs?: boolean; 233 + }; 234 + 235 + export type ContainerWithEnvVariableOpts = { 236 + /** 237 + * Replace `${VAR}` or `$VAR` in the value according to the current environment variables defined in the container (e.g., "/opt/bin:$PATH"). 238 + */ 239 + expand?: boolean; 240 + }; 241 + 242 + export type ContainerWithExecOpts = { 243 + /** 244 + * If the container has an entrypoint, ignore it for args rather than using it to wrap them. 245 + */ 246 + skipEntrypoint?: boolean; 247 + 248 + /** 249 + * Content to write to the command's standard input before closing (e.g., "Hello world"). 250 + */ 251 + stdin?: string; 252 + 253 + /** 254 + * Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). 255 + */ 256 + redirectStdout?: string; 257 + 258 + /** 259 + * Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). 260 + */ 261 + redirectStderr?: string; 262 + 263 + /** 264 + * Provides dagger access to the executed command. 265 + * 266 + * Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. 267 + */ 268 + experimentalPrivilegedNesting?: boolean; 269 + 270 + /** 271 + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. 272 + */ 273 + insecureRootCapabilities?: boolean; 274 + }; 275 + 276 + export type ContainerWithExposedPortOpts = { 277 + /** 278 + * Transport layer network protocol 279 + */ 280 + protocol?: NetworkProtocol; 281 + 282 + /** 283 + * Optional port description 284 + */ 285 + description?: string; 286 + 287 + /** 288 + * Skip the health check when run as a service. 289 + */ 290 + experimentalSkipHealthcheck?: boolean; 291 + }; 292 + 293 + export type ContainerWithFileOpts = { 294 + /** 295 + * Permission given to the copied file (e.g., 0600). 296 + */ 297 + permissions?: number; 298 + 299 + /** 300 + * A user:group to set for the file. 301 + * 302 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 303 + * 304 + * If the group is omitted, it defaults to the same as the user. 305 + */ 306 + owner?: string; 307 + }; 308 + 309 + export type ContainerWithFilesOpts = { 310 + /** 311 + * Permission given to the copied files (e.g., 0600). 312 + */ 313 + permissions?: number; 314 + 315 + /** 316 + * A user:group to set for the files. 317 + * 318 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 319 + * 320 + * If the group is omitted, it defaults to the same as the user. 321 + */ 322 + owner?: string; 323 + }; 324 + 325 + export type ContainerWithMountedCacheOpts = { 326 + /** 327 + * Identifier of the directory to use as the cache volume's root. 328 + */ 329 + source?: Directory; 330 + 331 + /** 332 + * Sharing mode of the cache volume. 333 + */ 334 + sharing?: CacheSharingMode; 335 + 336 + /** 337 + * A user:group to set for the mounted cache directory. 338 + * 339 + * Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. 340 + * 341 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 342 + * 343 + * If the group is omitted, it defaults to the same as the user. 344 + */ 345 + owner?: string; 346 + }; 347 + 348 + export type ContainerWithMountedDirectoryOpts = { 349 + /** 350 + * A user:group to set for the mounted directory and its contents. 351 + * 352 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 353 + * 354 + * If the group is omitted, it defaults to the same as the user. 355 + */ 356 + owner?: string; 357 + }; 358 + 359 + export type ContainerWithMountedFileOpts = { 360 + /** 361 + * A user or user:group to set for the mounted file. 362 + * 363 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 364 + * 365 + * If the group is omitted, it defaults to the same as the user. 366 + */ 367 + owner?: string; 368 + }; 369 + 370 + export type ContainerWithMountedSecretOpts = { 371 + /** 372 + * A user:group to set for the mounted secret. 373 + * 374 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 375 + * 376 + * If the group is omitted, it defaults to the same as the user. 377 + */ 378 + owner?: string; 379 + 380 + /** 381 + * Permission given to the mounted secret (e.g., 0600). 382 + * 383 + * This option requires an owner to be set to be active. 384 + */ 385 + mode?: number; 386 + }; 387 + 388 + export type ContainerWithNewFileOpts = { 389 + /** 390 + * Content of the file to write (e.g., "Hello world!"). 391 + */ 392 + contents?: string; 393 + 394 + /** 395 + * Permission given to the written file (e.g., 0600). 396 + */ 397 + permissions?: number; 398 + 399 + /** 400 + * A user:group to set for the file. 401 + * 402 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 403 + * 404 + * If the group is omitted, it defaults to the same as the user. 405 + */ 406 + owner?: string; 407 + }; 408 + 409 + export type ContainerWithUnixSocketOpts = { 410 + /** 411 + * A user:group to set for the mounted socket. 412 + * 413 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 414 + * 415 + * If the group is omitted, it defaults to the same as the user. 416 + */ 417 + owner?: string; 418 + }; 419 + 420 + export type ContainerWithoutEntrypointOpts = { 421 + /** 422 + * Don't remove the default arguments when unsetting the entrypoint. 423 + */ 424 + keepDefaultArgs?: boolean; 425 + }; 426 + 427 + export type ContainerWithoutExposedPortOpts = { 428 + /** 429 + * Port protocol to unexpose 430 + */ 431 + protocol?: NetworkProtocol; 432 + }; 433 + 434 + /** 435 + * The `ContainerID` scalar type represents an identifier for an object of type Container. 436 + */ 437 + export type ContainerID = string & { __ContainerID: never }; 438 + 439 + export type CurrentModuleWorkdirOpts = { 440 + /** 441 + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 442 + */ 443 + exclude?: string[]; 444 + 445 + /** 446 + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 447 + */ 448 + include?: string[]; 449 + }; 450 + 451 + /** 452 + * The `CurrentModuleID` scalar type represents an identifier for an object of type CurrentModule. 453 + */ 454 + export type CurrentModuleID = string & { __CurrentModuleID: never }; 455 + 456 + export type DirectoryAsModuleOpts = { 457 + /** 458 + * An optional subpath of the directory which contains the module's configuration file. 459 + * 460 + * This is needed when the module code is in a subdirectory but requires parent directories to be loaded in order to execute. For example, the module source code may need a go.mod, project.toml, package.json, etc. file from a parent directory. 461 + * 462 + * If not set, the module source code is loaded from the root of the directory. 463 + */ 464 + sourceRootPath?: string; 465 + }; 466 + 467 + export type DirectoryDockerBuildOpts = { 468 + /** 469 + * The platform to build. 470 + */ 471 + platform?: Platform; 472 + 473 + /** 474 + * Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). 475 + */ 476 + dockerfile?: string; 477 + 478 + /** 479 + * Target build stage to build. 480 + */ 481 + target?: string; 482 + 483 + /** 484 + * Build arguments to use in the build. 485 + */ 486 + buildArgs?: BuildArg[]; 487 + 488 + /** 489 + * Secrets to pass to the build. 490 + * 491 + * They will be mounted at /run/secrets/[secret-name]. 492 + */ 493 + secrets?: Secret[]; 494 + }; 495 + 496 + export type DirectoryEntriesOpts = { 497 + /** 498 + * Location of the directory to look at (e.g., "/src"). 499 + */ 500 + path?: string; 501 + }; 502 + 503 + export type DirectoryPipelineOpts = { 504 + /** 505 + * Description of the sub-pipeline. 506 + */ 507 + description?: string; 508 + 509 + /** 510 + * Labels to apply to the sub-pipeline. 511 + */ 512 + labels?: PipelineLabel[]; 513 + }; 514 + 515 + export type DirectoryWithDirectoryOpts = { 516 + /** 517 + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 518 + */ 519 + exclude?: string[]; 520 + 521 + /** 522 + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 523 + */ 524 + include?: string[]; 525 + }; 526 + 527 + export type DirectoryWithFileOpts = { 528 + /** 529 + * Permission given to the copied file (e.g., 0600). 530 + */ 531 + permissions?: number; 532 + }; 533 + 534 + export type DirectoryWithFilesOpts = { 535 + /** 536 + * Permission given to the copied files (e.g., 0600). 537 + */ 538 + permissions?: number; 539 + }; 540 + 541 + export type DirectoryWithNewDirectoryOpts = { 542 + /** 543 + * Permission granted to the created directory (e.g., 0777). 544 + */ 545 + permissions?: number; 546 + }; 547 + 548 + export type DirectoryWithNewFileOpts = { 549 + /** 550 + * Permission given to the copied file (e.g., 0600). 551 + */ 552 + permissions?: number; 553 + }; 554 + 555 + /** 556 + * The `DirectoryID` scalar type represents an identifier for an object of type Directory. 557 + */ 558 + export type DirectoryID = string & { __DirectoryID: never }; 559 + 560 + /** 561 + * The `EnvVariableID` scalar type represents an identifier for an object of type EnvVariable. 562 + */ 563 + export type EnvVariableID = string & { __EnvVariableID: never }; 564 + 565 + /** 566 + * The `FieldTypeDefID` scalar type represents an identifier for an object of type FieldTypeDef. 567 + */ 568 + export type FieldTypeDefID = string & { __FieldTypeDefID: never }; 569 + 570 + export type FileExportOpts = { 571 + /** 572 + * If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. 573 + */ 574 + allowParentDirPath?: boolean; 575 + }; 576 + 577 + /** 578 + * The `FileID` scalar type represents an identifier for an object of type File. 579 + */ 580 + export type FileID = string & { __FileID: never }; 581 + 582 + export type FunctionWithArgOpts = { 583 + /** 584 + * A doc string for the argument, if any 585 + */ 586 + description?: string; 587 + 588 + /** 589 + * A default value to use for this argument if not explicitly set by the caller, if any 590 + */ 591 + defaultValue?: JSON; 592 + }; 593 + 594 + /** 595 + * The `FunctionArgID` scalar type represents an identifier for an object of type FunctionArg. 596 + */ 597 + export type FunctionArgID = string & { __FunctionArgID: never }; 598 + 599 + /** 600 + * The `FunctionCallArgValueID` scalar type represents an identifier for an object of type FunctionCallArgValue. 601 + */ 602 + export type FunctionCallArgValueID = string & { 603 + __FunctionCallArgValueID: never; 604 + }; 605 + 606 + /** 607 + * The `FunctionCallID` scalar type represents an identifier for an object of type FunctionCall. 608 + */ 609 + export type FunctionCallID = string & { __FunctionCallID: never }; 610 + 611 + /** 612 + * The `FunctionID` scalar type represents an identifier for an object of type Function. 613 + */ 614 + export type FunctionID = string & { __FunctionID: never }; 615 + 616 + /** 617 + * The `GeneratedCodeID` scalar type represents an identifier for an object of type GeneratedCode. 618 + */ 619 + export type GeneratedCodeID = string & { __GeneratedCodeID: never }; 620 + 621 + /** 622 + * The `GitModuleSourceID` scalar type represents an identifier for an object of type GitModuleSource. 623 + */ 624 + export type GitModuleSourceID = string & { __GitModuleSourceID: never }; 625 + 626 + export type GitRefTreeOpts = { 627 + /** 628 + * DEPRECATED: This option should be passed to `git` instead. 629 + */ 630 + sshKnownHosts?: string; 631 + 632 + /** 633 + * DEPRECATED: This option should be passed to `git` instead. 634 + */ 635 + sshAuthSocket?: Socket; 636 + }; 637 + 638 + /** 639 + * The `GitRefID` scalar type represents an identifier for an object of type GitRef. 640 + */ 641 + export type GitRefID = string & { __GitRefID: never }; 642 + 643 + /** 644 + * The `GitRepositoryID` scalar type represents an identifier for an object of type GitRepository. 645 + */ 646 + export type GitRepositoryID = string & { __GitRepositoryID: never }; 647 + 648 + export type HostDirectoryOpts = { 649 + /** 650 + * Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 651 + */ 652 + exclude?: string[]; 653 + 654 + /** 655 + * Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 656 + */ 657 + include?: string[]; 658 + }; 659 + 660 + export type HostServiceOpts = { 661 + /** 662 + * Upstream host to forward traffic to. 663 + */ 664 + host?: string; 665 + 666 + /** 667 + * Ports to expose via the service, forwarding through the host network. 668 + * 669 + * If a port's frontend is unspecified or 0, it defaults to the same as the backend port. 670 + * 671 + * An empty set of ports is not valid; an error will be returned. 672 + */ 673 + ports: PortForward[]; 674 + }; 675 + 676 + export type HostTunnelOpts = { 677 + /** 678 + * Configure explicit port forwarding rules for the tunnel. 679 + * 680 + * If a port's frontend is unspecified or 0, a random port will be chosen by the host. 681 + * 682 + * If no ports are given, all of the service's ports are forwarded. If native is true, each port maps to the same port on the host. If native is false, each port maps to a random port chosen by the host. 683 + * 684 + * If ports are given and native is true, the ports are additive. 685 + */ 686 + ports?: PortForward[]; 687 + 688 + /** 689 + * Map each service port to the same port on the host, as if the service were running natively. 690 + * 691 + * Note: enabling may result in port conflicts. 692 + */ 693 + native?: boolean; 694 + }; 695 + 696 + /** 697 + * The `HostID` scalar type represents an identifier for an object of type Host. 698 + */ 699 + export type HostID = string & { __HostID: never }; 700 + 701 + /** 702 + * Compression algorithm to use for image layers. 703 + */ 704 + export enum ImageLayerCompression { 705 + Estargz = "EStarGZ", 706 + Gzip = "Gzip", 707 + Uncompressed = "Uncompressed", 708 + Zstd = "Zstd", 709 + } 710 + /** 711 + * Mediatypes to use in published or exported image metadata. 712 + */ 713 + export enum ImageMediaTypes { 714 + Dockermediatypes = "DockerMediaTypes", 715 + Ocimediatypes = "OCIMediaTypes", 716 + } 717 + /** 718 + * The `InputTypeDefID` scalar type represents an identifier for an object of type InputTypeDef. 719 + */ 720 + export type InputTypeDefID = string & { __InputTypeDefID: never }; 721 + 722 + /** 723 + * The `InterfaceTypeDefID` scalar type represents an identifier for an object of type InterfaceTypeDef. 724 + */ 725 + export type InterfaceTypeDefID = string & { __InterfaceTypeDefID: never }; 726 + 727 + /** 728 + * An arbitrary JSON-encoded value. 729 + */ 730 + export type JSON = string & { __JSON: never }; 731 + 732 + /** 733 + * The `LabelID` scalar type represents an identifier for an object of type Label. 734 + */ 735 + export type LabelID = string & { __LabelID: never }; 736 + 737 + /** 738 + * The `ListTypeDefID` scalar type represents an identifier for an object of type ListTypeDef. 739 + */ 740 + export type ListTypeDefID = string & { __ListTypeDefID: never }; 741 + 742 + /** 743 + * The `LocalModuleSourceID` scalar type represents an identifier for an object of type LocalModuleSource. 744 + */ 745 + export type LocalModuleSourceID = string & { __LocalModuleSourceID: never }; 746 + 747 + /** 748 + * The `ModuleDependencyID` scalar type represents an identifier for an object of type ModuleDependency. 749 + */ 750 + export type ModuleDependencyID = string & { __ModuleDependencyID: never }; 751 + 752 + /** 753 + * The `ModuleID` scalar type represents an identifier for an object of type Module. 754 + */ 755 + export type ModuleID = string & { __ModuleID: never }; 756 + 757 + /** 758 + * The `ModuleSourceID` scalar type represents an identifier for an object of type ModuleSource. 759 + */ 760 + export type ModuleSourceID = string & { __ModuleSourceID: never }; 761 + 762 + /** 763 + * The kind of module source. 764 + */ 765 + export enum ModuleSourceKind { 766 + GitSource = "GIT_SOURCE", 767 + LocalSource = "LOCAL_SOURCE", 768 + } 769 + /** 770 + * Transport layer network protocol associated to a port. 771 + */ 772 + export enum NetworkProtocol { 773 + Tcp = "TCP", 774 + Udp = "UDP", 775 + } 776 + /** 777 + * The `ObjectTypeDefID` scalar type represents an identifier for an object of type ObjectTypeDef. 778 + */ 779 + export type ObjectTypeDefID = string & { __ObjectTypeDefID: never }; 780 + 781 + export type PipelineLabel = { 782 + /** 783 + * Label name. 784 + */ 785 + name: string; 786 + 787 + /** 788 + * Label value. 789 + */ 790 + value: string; 791 + }; 792 + 793 + /** 794 + * The platform config OS and architecture in a Container. 795 + * 796 + * The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64"). 797 + */ 798 + export type Platform = string & { __Platform: never }; 799 + 800 + export type PortForward = { 801 + /** 802 + * Destination port for traffic. 803 + */ 804 + backend: number; 805 + 806 + /** 807 + * Port to expose to clients. If unspecified, a default will be chosen. 808 + */ 809 + frontend?: number; 810 + 811 + /** 812 + * Transport layer protocol to use for traffic. 813 + */ 814 + protocol?: NetworkProtocol; 815 + }; 816 + 817 + /** 818 + * The `PortID` scalar type represents an identifier for an object of type Port. 819 + */ 820 + export type PortID = string & { __PortID: never }; 821 + 822 + export type ClientContainerOpts = { 823 + /** 824 + * DEPRECATED: Use `loadContainerFromID` instead. 825 + */ 826 + id?: ContainerID; 827 + 828 + /** 829 + * Platform to initialize the container with. 830 + */ 831 + platform?: Platform; 832 + }; 833 + 834 + export type ClientDirectoryOpts = { 835 + /** 836 + * DEPRECATED: Use `loadDirectoryFromID` isntead. 837 + */ 838 + id?: DirectoryID; 839 + }; 840 + 841 + export type ClientGitOpts = { 842 + /** 843 + * Set to true to keep .git directory. 844 + */ 845 + keepGitDir?: boolean; 846 + 847 + /** 848 + * A service which must be started before the repo is fetched. 849 + */ 850 + experimentalServiceHost?: Service; 851 + 852 + /** 853 + * Set SSH known hosts 854 + */ 855 + sshKnownHosts?: string; 856 + 857 + /** 858 + * Set SSH auth socket 859 + */ 860 + sshAuthSocket?: Socket; 861 + }; 862 + 863 + export type ClientHttpOpts = { 864 + /** 865 + * A service which must be started before the URL is fetched. 866 + */ 867 + experimentalServiceHost?: Service; 868 + }; 869 + 870 + export type ClientModuleDependencyOpts = { 871 + /** 872 + * If set, the name to use for the dependency. Otherwise, once installed to a parent module, the name of the dependency module will be used by default. 873 + */ 874 + name?: string; 875 + }; 876 + 877 + export type ClientModuleSourceOpts = { 878 + /** 879 + * If true, enforce that the source is a stable version for source kinds that support versioning. 880 + */ 881 + stable?: boolean; 882 + }; 883 + 884 + export type ClientPipelineOpts = { 885 + /** 886 + * Description of the sub-pipeline. 887 + */ 888 + description?: string; 889 + 890 + /** 891 + * Labels to apply to the sub-pipeline. 892 + */ 893 + labels?: PipelineLabel[]; 894 + }; 895 + 896 + export type ClientSecretOpts = { 897 + accessor?: string; 898 + }; 899 + 900 + /** 901 + * The `SecretID` scalar type represents an identifier for an object of type Secret. 902 + */ 903 + export type SecretID = string & { __SecretID: never }; 904 + 905 + export type ServiceEndpointOpts = { 906 + /** 907 + * The exposed port number for the endpoint 908 + */ 909 + port?: number; 910 + 911 + /** 912 + * Return a URL with the given scheme, eg. http for http:// 913 + */ 914 + scheme?: string; 915 + }; 916 + 917 + export type ServiceStopOpts = { 918 + /** 919 + * Immediately kill the service without waiting for a graceful exit 920 + */ 921 + kill?: boolean; 922 + }; 923 + 924 + export type ServiceUpOpts = { 925 + /** 926 + * List of frontend/backend port mappings to forward. 927 + * 928 + * Frontend is the port accepting traffic on the host, backend is the service port. 929 + */ 930 + ports?: PortForward[]; 931 + 932 + /** 933 + * Bind each tunnel port to a random port on the host. 934 + */ 935 + random?: boolean; 936 + }; 937 + 938 + /** 939 + * The `ServiceID` scalar type represents an identifier for an object of type Service. 940 + */ 941 + export type ServiceID = string & { __ServiceID: never }; 942 + 943 + /** 944 + * The `SocketID` scalar type represents an identifier for an object of type Socket. 945 + */ 946 + export type SocketID = string & { __SocketID: never }; 947 + 948 + /** 949 + * The `TerminalID` scalar type represents an identifier for an object of type Terminal. 950 + */ 951 + export type TerminalID = string & { __TerminalID: never }; 952 + 953 + export type TypeDefWithFieldOpts = { 954 + /** 955 + * A doc string for the field, if any 956 + */ 957 + description?: string; 958 + }; 959 + 960 + export type TypeDefWithInterfaceOpts = { 961 + description?: string; 962 + }; 963 + 964 + export type TypeDefWithObjectOpts = { 965 + description?: string; 966 + }; 967 + 968 + /** 969 + * The `TypeDefID` scalar type represents an identifier for an object of type TypeDef. 970 + */ 971 + export type TypeDefID = string & { __TypeDefID: never }; 972 + 973 + /** 974 + * Distinguishes the different kinds of TypeDefs. 975 + */ 976 + export enum TypeDefKind { 977 + /** 978 + * A boolean value. 979 + */ 980 + BooleanKind = "BOOLEAN_KIND", 981 + 982 + /** 983 + * A graphql input type, used only when representing the core API via TypeDefs. 984 + */ 985 + InputKind = "INPUT_KIND", 986 + 987 + /** 988 + * An integer value. 989 + */ 990 + IntegerKind = "INTEGER_KIND", 991 + 992 + /** 993 + * A named type of functions that can be matched+implemented by other objects+interfaces. 994 + * 995 + * Always paired with an InterfaceTypeDef. 996 + */ 997 + InterfaceKind = "INTERFACE_KIND", 998 + 999 + /** 1000 + * A list of values all having the same type. 1001 + * 1002 + * Always paired with a ListTypeDef. 1003 + */ 1004 + ListKind = "LIST_KIND", 1005 + 1006 + /** 1007 + * A named type defined in the GraphQL schema, with fields and functions. 1008 + * 1009 + * Always paired with an ObjectTypeDef. 1010 + */ 1011 + ObjectKind = "OBJECT_KIND", 1012 + 1013 + /** 1014 + * A string value. 1015 + */ 1016 + StringKind = "STRING_KIND", 1017 + 1018 + /** 1019 + * A special kind used to signify that no value is returned. 1020 + * 1021 + * This is used for functions that have no return value. The outer TypeDef specifying this Kind is always Optional, as the Void is never actually represented. 1022 + */ 1023 + VoidKind = "VOID_KIND", 1024 + } 1025 + /** 1026 + * The absence of a value. 1027 + * 1028 + * A Null Void is used as a placeholder for resolvers that do not return anything. 1029 + */ 1030 + export type Void = string & { __Void: never }; 1031 + 1032 + export type __TypeEnumValuesOpts = { 1033 + includeDeprecated?: boolean; 1034 + }; 1035 + 1036 + export type __TypeFieldsOpts = { 1037 + includeDeprecated?: boolean; 1038 + }; 1039 + 1040 + /** 1041 + * A directory whose contents persist across runs. 1042 + */ 1043 + export class CacheVolume extends BaseClient { 1044 + private readonly _id?: CacheVolumeID = undefined; 1045 + 1046 + /** 1047 + * Constructor is used for internal usage only, do not create object from it. 1048 + */ 1049 + constructor( 1050 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 1051 + _id?: CacheVolumeID 1052 + ) { 1053 + super(parent); 1054 + 1055 + this._id = _id; 1056 + } 1057 + 1058 + /** 1059 + * A unique identifier for this CacheVolume. 1060 + */ 1061 + id = async (): Promise<CacheVolumeID> => { 1062 + if (this._id) { 1063 + return this._id; 1064 + } 1065 + 1066 + const response: Awaited<CacheVolumeID> = await computeQuery( 1067 + [ 1068 + ...this._queryTree, 1069 + { 1070 + operation: "id", 1071 + }, 1072 + ], 1073 + await this._ctx.connection() 1074 + ); 1075 + 1076 + return response; 1077 + }; 1078 + } 1079 + 1080 + /** 1081 + * An OCI-compatible container, also known as a Docker container. 1082 + */ 1083 + export class Container extends BaseClient { 1084 + private readonly _id?: ContainerID = undefined; 1085 + private readonly _envVariable?: string = undefined; 1086 + private readonly _export?: boolean = undefined; 1087 + private readonly _imageRef?: string = undefined; 1088 + private readonly _label?: string = undefined; 1089 + private readonly _platform?: Platform = undefined; 1090 + private readonly _publish?: string = undefined; 1091 + private readonly _stderr?: string = undefined; 1092 + private readonly _stdout?: string = undefined; 1093 + private readonly _sync?: ContainerID = undefined; 1094 + private readonly _user?: string = undefined; 1095 + private readonly _workdir?: string = undefined; 1096 + 1097 + /** 1098 + * Constructor is used for internal usage only, do not create object from it. 1099 + */ 1100 + constructor( 1101 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 1102 + _id?: ContainerID, 1103 + _envVariable?: string, 1104 + _export?: boolean, 1105 + _imageRef?: string, 1106 + _label?: string, 1107 + _platform?: Platform, 1108 + _publish?: string, 1109 + _stderr?: string, 1110 + _stdout?: string, 1111 + _sync?: ContainerID, 1112 + _user?: string, 1113 + _workdir?: string 1114 + ) { 1115 + super(parent); 1116 + 1117 + this._id = _id; 1118 + this._envVariable = _envVariable; 1119 + this._export = _export; 1120 + this._imageRef = _imageRef; 1121 + this._label = _label; 1122 + this._platform = _platform; 1123 + this._publish = _publish; 1124 + this._stderr = _stderr; 1125 + this._stdout = _stdout; 1126 + this._sync = _sync; 1127 + this._user = _user; 1128 + this._workdir = _workdir; 1129 + } 1130 + 1131 + /** 1132 + * A unique identifier for this Container. 1133 + */ 1134 + id = async (): Promise<ContainerID> => { 1135 + if (this._id) { 1136 + return this._id; 1137 + } 1138 + 1139 + const response: Awaited<ContainerID> = await computeQuery( 1140 + [ 1141 + ...this._queryTree, 1142 + { 1143 + operation: "id", 1144 + }, 1145 + ], 1146 + await this._ctx.connection() 1147 + ); 1148 + 1149 + return response; 1150 + }; 1151 + 1152 + /** 1153 + * Turn the container into a Service. 1154 + * 1155 + * Be sure to set any exposed ports before this conversion. 1156 + */ 1157 + asService = (): Service => { 1158 + return new Service({ 1159 + queryTree: [ 1160 + ...this._queryTree, 1161 + { 1162 + operation: "asService", 1163 + }, 1164 + ], 1165 + ctx: this._ctx, 1166 + }); 1167 + }; 1168 + 1169 + /** 1170 + * Returns a File representing the container serialized to a tarball. 1171 + * @param opts.platformVariants Identifiers for other platform specific containers. 1172 + * 1173 + * Used for multi-platform images. 1174 + * @param opts.forcedCompression Force each layer of the image to use the specified compression algorithm. 1175 + * 1176 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 1177 + * @param opts.mediaTypes Use the specified media types for the image's layers. 1178 + * 1179 + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. 1180 + */ 1181 + asTarball = (opts?: ContainerAsTarballOpts): File => { 1182 + const metadata: Metadata = { 1183 + forcedCompression: { is_enum: true }, 1184 + mediaTypes: { is_enum: true }, 1185 + }; 1186 + 1187 + return new File({ 1188 + queryTree: [ 1189 + ...this._queryTree, 1190 + { 1191 + operation: "asTarball", 1192 + args: { ...opts, __metadata: metadata }, 1193 + }, 1194 + ], 1195 + ctx: this._ctx, 1196 + }); 1197 + }; 1198 + 1199 + /** 1200 + * Initializes this container from a Dockerfile build. 1201 + * @param context Directory context used by the Dockerfile. 1202 + * @param opts.dockerfile Path to the Dockerfile to use. 1203 + * @param opts.target Target build stage to build. 1204 + * @param opts.buildArgs Additional build arguments. 1205 + * @param opts.secrets Secrets to pass to the build. 1206 + * 1207 + * They will be mounted at /run/secrets/[secret-name] in the build container 1208 + * 1209 + * They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl [http://example.com?token=$(cat /run/secrets/my-secret)](http://example.com?token=$(cat /run/secrets/my-secret)) 1210 + */ 1211 + build = (context: Directory, opts?: ContainerBuildOpts): Container => { 1212 + return new Container({ 1213 + queryTree: [ 1214 + ...this._queryTree, 1215 + { 1216 + operation: "build", 1217 + args: { context, ...opts }, 1218 + }, 1219 + ], 1220 + ctx: this._ctx, 1221 + }); 1222 + }; 1223 + 1224 + /** 1225 + * Retrieves default arguments for future commands. 1226 + */ 1227 + defaultArgs = async (): Promise<string[]> => { 1228 + const response: Awaited<string[]> = await computeQuery( 1229 + [ 1230 + ...this._queryTree, 1231 + { 1232 + operation: "defaultArgs", 1233 + }, 1234 + ], 1235 + await this._ctx.connection() 1236 + ); 1237 + 1238 + return response; 1239 + }; 1240 + 1241 + /** 1242 + * Retrieves a directory at the given path. 1243 + * 1244 + * Mounts are included. 1245 + * @param path The path of the directory to retrieve (e.g., "./src"). 1246 + */ 1247 + directory = (path: string): Directory => { 1248 + return new Directory({ 1249 + queryTree: [ 1250 + ...this._queryTree, 1251 + { 1252 + operation: "directory", 1253 + args: { path }, 1254 + }, 1255 + ], 1256 + ctx: this._ctx, 1257 + }); 1258 + }; 1259 + 1260 + /** 1261 + * Retrieves entrypoint to be prepended to the arguments of all commands. 1262 + */ 1263 + entrypoint = async (): Promise<string[]> => { 1264 + const response: Awaited<string[]> = await computeQuery( 1265 + [ 1266 + ...this._queryTree, 1267 + { 1268 + operation: "entrypoint", 1269 + }, 1270 + ], 1271 + await this._ctx.connection() 1272 + ); 1273 + 1274 + return response; 1275 + }; 1276 + 1277 + /** 1278 + * Retrieves the value of the specified environment variable. 1279 + * @param name The name of the environment variable to retrieve (e.g., "PATH"). 1280 + */ 1281 + envVariable = async (name: string): Promise<string> => { 1282 + if (this._envVariable) { 1283 + return this._envVariable; 1284 + } 1285 + 1286 + const response: Awaited<string> = await computeQuery( 1287 + [ 1288 + ...this._queryTree, 1289 + { 1290 + operation: "envVariable", 1291 + args: { name }, 1292 + }, 1293 + ], 1294 + await this._ctx.connection() 1295 + ); 1296 + 1297 + return response; 1298 + }; 1299 + 1300 + /** 1301 + * Retrieves the list of environment variables passed to commands. 1302 + */ 1303 + envVariables = async (): Promise<EnvVariable[]> => { 1304 + type envVariables = { 1305 + id: EnvVariableID; 1306 + }; 1307 + 1308 + const response: Awaited<envVariables[]> = await computeQuery( 1309 + [ 1310 + ...this._queryTree, 1311 + { 1312 + operation: "envVariables", 1313 + }, 1314 + { 1315 + operation: "id", 1316 + }, 1317 + ], 1318 + await this._ctx.connection() 1319 + ); 1320 + 1321 + return response.map( 1322 + (r) => 1323 + new EnvVariable( 1324 + { 1325 + queryTree: [ 1326 + { 1327 + operation: "loadEnvVariableFromID", 1328 + args: { id: r.id }, 1329 + }, 1330 + ], 1331 + ctx: this._ctx, 1332 + }, 1333 + r.id 1334 + ) 1335 + ); 1336 + }; 1337 + 1338 + /** 1339 + * EXPERIMENTAL API! Subject to change/removal at any time. 1340 + * 1341 + * Configures all available GPUs on the host to be accessible to this container. 1342 + * 1343 + * This currently works for Nvidia devices only. 1344 + */ 1345 + experimentalWithAllGPUs = (): Container => { 1346 + return new Container({ 1347 + queryTree: [ 1348 + ...this._queryTree, 1349 + { 1350 + operation: "experimentalWithAllGPUs", 1351 + }, 1352 + ], 1353 + ctx: this._ctx, 1354 + }); 1355 + }; 1356 + 1357 + /** 1358 + * EXPERIMENTAL API! Subject to change/removal at any time. 1359 + * 1360 + * Configures the provided list of devices to be accesible to this container. 1361 + * 1362 + * This currently works for Nvidia devices only. 1363 + * @param devices List of devices to be accessible to this container. 1364 + */ 1365 + experimentalWithGPU = (devices: string[]): Container => { 1366 + return new Container({ 1367 + queryTree: [ 1368 + ...this._queryTree, 1369 + { 1370 + operation: "experimentalWithGPU", 1371 + args: { devices }, 1372 + }, 1373 + ], 1374 + ctx: this._ctx, 1375 + }); 1376 + }; 1377 + 1378 + /** 1379 + * Writes the container as an OCI tarball to the destination file path on the host. 1380 + * 1381 + * Return true on success. 1382 + * 1383 + * It can also export platform variants. 1384 + * @param path Host's destination path (e.g., "./tarball"). 1385 + * 1386 + * Path can be relative to the engine's workdir or absolute. 1387 + * @param opts.platformVariants Identifiers for other platform specific containers. 1388 + * 1389 + * Used for multi-platform image. 1390 + * @param opts.forcedCompression Force each layer of the exported image to use the specified compression algorithm. 1391 + * 1392 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 1393 + * @param opts.mediaTypes Use the specified media types for the exported image's layers. 1394 + * 1395 + * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. 1396 + */ 1397 + export = async ( 1398 + path: string, 1399 + opts?: ContainerExportOpts 1400 + ): Promise<boolean> => { 1401 + if (this._export) { 1402 + return this._export; 1403 + } 1404 + 1405 + const metadata: Metadata = { 1406 + forcedCompression: { is_enum: true }, 1407 + mediaTypes: { is_enum: true }, 1408 + }; 1409 + 1410 + const response: Awaited<boolean> = await computeQuery( 1411 + [ 1412 + ...this._queryTree, 1413 + { 1414 + operation: "export", 1415 + args: { path, ...opts, __metadata: metadata }, 1416 + }, 1417 + ], 1418 + await this._ctx.connection() 1419 + ); 1420 + 1421 + return response; 1422 + }; 1423 + 1424 + /** 1425 + * Retrieves the list of exposed ports. 1426 + * 1427 + * This includes ports already exposed by the image, even if not explicitly added with dagger. 1428 + */ 1429 + exposedPorts = async (): Promise<Port[]> => { 1430 + type exposedPorts = { 1431 + id: PortID; 1432 + }; 1433 + 1434 + const response: Awaited<exposedPorts[]> = await computeQuery( 1435 + [ 1436 + ...this._queryTree, 1437 + { 1438 + operation: "exposedPorts", 1439 + }, 1440 + { 1441 + operation: "id", 1442 + }, 1443 + ], 1444 + await this._ctx.connection() 1445 + ); 1446 + 1447 + return response.map( 1448 + (r) => 1449 + new Port( 1450 + { 1451 + queryTree: [ 1452 + { 1453 + operation: "loadPortFromID", 1454 + args: { id: r.id }, 1455 + }, 1456 + ], 1457 + ctx: this._ctx, 1458 + }, 1459 + r.id 1460 + ) 1461 + ); 1462 + }; 1463 + 1464 + /** 1465 + * Retrieves a file at the given path. 1466 + * 1467 + * Mounts are included. 1468 + * @param path The path of the file to retrieve (e.g., "./README.md"). 1469 + */ 1470 + file = (path: string): File => { 1471 + return new File({ 1472 + queryTree: [ 1473 + ...this._queryTree, 1474 + { 1475 + operation: "file", 1476 + args: { path }, 1477 + }, 1478 + ], 1479 + ctx: this._ctx, 1480 + }); 1481 + }; 1482 + 1483 + /** 1484 + * Initializes this container from a pulled base image. 1485 + * @param address Image's address from its registry. 1486 + * 1487 + * Formatted as [host]/[user]/[repo]:[tag] (e.g., "docker.io/dagger/dagger:main"). 1488 + */ 1489 + from = (address: string): Container => { 1490 + return new Container({ 1491 + queryTree: [ 1492 + ...this._queryTree, 1493 + { 1494 + operation: "from", 1495 + args: { address }, 1496 + }, 1497 + ], 1498 + ctx: this._ctx, 1499 + }); 1500 + }; 1501 + 1502 + /** 1503 + * The unique image reference which can only be retrieved immediately after the 'Container.From' call. 1504 + */ 1505 + imageRef = async (): Promise<string> => { 1506 + if (this._imageRef) { 1507 + return this._imageRef; 1508 + } 1509 + 1510 + const response: Awaited<string> = await computeQuery( 1511 + [ 1512 + ...this._queryTree, 1513 + { 1514 + operation: "imageRef", 1515 + }, 1516 + ], 1517 + await this._ctx.connection() 1518 + ); 1519 + 1520 + return response; 1521 + }; 1522 + 1523 + /** 1524 + * Reads the container from an OCI tarball. 1525 + * @param source File to read the container from. 1526 + * @param opts.tag Identifies the tag to import from the archive, if the archive bundles multiple tags. 1527 + */ 1528 + import_ = (source: File, opts?: ContainerImportOpts): Container => { 1529 + return new Container({ 1530 + queryTree: [ 1531 + ...this._queryTree, 1532 + { 1533 + operation: "import", 1534 + args: { source, ...opts }, 1535 + }, 1536 + ], 1537 + ctx: this._ctx, 1538 + }); 1539 + }; 1540 + 1541 + /** 1542 + * Retrieves the value of the specified label. 1543 + * @param name The name of the label (e.g., "org.opencontainers.artifact.created"). 1544 + */ 1545 + label = async (name: string): Promise<string> => { 1546 + if (this._label) { 1547 + return this._label; 1548 + } 1549 + 1550 + const response: Awaited<string> = await computeQuery( 1551 + [ 1552 + ...this._queryTree, 1553 + { 1554 + operation: "label", 1555 + args: { name }, 1556 + }, 1557 + ], 1558 + await this._ctx.connection() 1559 + ); 1560 + 1561 + return response; 1562 + }; 1563 + 1564 + /** 1565 + * Retrieves the list of labels passed to container. 1566 + */ 1567 + labels = async (): Promise<Label[]> => { 1568 + type labels = { 1569 + id: LabelID; 1570 + }; 1571 + 1572 + const response: Awaited<labels[]> = await computeQuery( 1573 + [ 1574 + ...this._queryTree, 1575 + { 1576 + operation: "labels", 1577 + }, 1578 + { 1579 + operation: "id", 1580 + }, 1581 + ], 1582 + await this._ctx.connection() 1583 + ); 1584 + 1585 + return response.map( 1586 + (r) => 1587 + new Label( 1588 + { 1589 + queryTree: [ 1590 + { 1591 + operation: "loadLabelFromID", 1592 + args: { id: r.id }, 1593 + }, 1594 + ], 1595 + ctx: this._ctx, 1596 + }, 1597 + r.id 1598 + ) 1599 + ); 1600 + }; 1601 + 1602 + /** 1603 + * Retrieves the list of paths where a directory is mounted. 1604 + */ 1605 + mounts = async (): Promise<string[]> => { 1606 + const response: Awaited<string[]> = await computeQuery( 1607 + [ 1608 + ...this._queryTree, 1609 + { 1610 + operation: "mounts", 1611 + }, 1612 + ], 1613 + await this._ctx.connection() 1614 + ); 1615 + 1616 + return response; 1617 + }; 1618 + 1619 + /** 1620 + * Creates a named sub-pipeline. 1621 + * @param name Name of the sub-pipeline. 1622 + * @param opts.description Description of the sub-pipeline. 1623 + * @param opts.labels Labels to apply to the sub-pipeline. 1624 + */ 1625 + pipeline = (name: string, opts?: ContainerPipelineOpts): Container => { 1626 + return new Container({ 1627 + queryTree: [ 1628 + ...this._queryTree, 1629 + { 1630 + operation: "pipeline", 1631 + args: { name, ...opts }, 1632 + }, 1633 + ], 1634 + ctx: this._ctx, 1635 + }); 1636 + }; 1637 + 1638 + /** 1639 + * The platform this container executes and publishes as. 1640 + */ 1641 + platform = async (): Promise<Platform> => { 1642 + if (this._platform) { 1643 + return this._platform; 1644 + } 1645 + 1646 + const response: Awaited<Platform> = await computeQuery( 1647 + [ 1648 + ...this._queryTree, 1649 + { 1650 + operation: "platform", 1651 + }, 1652 + ], 1653 + await this._ctx.connection() 1654 + ); 1655 + 1656 + return response; 1657 + }; 1658 + 1659 + /** 1660 + * Publishes this container as a new image to the specified address. 1661 + * 1662 + * Publish returns a fully qualified ref. 1663 + * 1664 + * It can also publish platform variants. 1665 + * @param address Registry's address to publish the image to. 1666 + * 1667 + * Formatted as [host]/[user]/[repo]:[tag] (e.g. "docker.io/dagger/dagger:main"). 1668 + * @param opts.platformVariants Identifiers for other platform specific containers. 1669 + * 1670 + * Used for multi-platform image. 1671 + * @param opts.forcedCompression Force each layer of the published image to use the specified compression algorithm. 1672 + * 1673 + * If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. 1674 + * @param opts.mediaTypes Use the specified media types for the published image's layers. 1675 + * 1676 + * Defaults to OCI, which is largely compatible with most recent registries, but Docker may be needed for older registries without OCI support. 1677 + */ 1678 + publish = async ( 1679 + address: string, 1680 + opts?: ContainerPublishOpts 1681 + ): Promise<string> => { 1682 + if (this._publish) { 1683 + return this._publish; 1684 + } 1685 + 1686 + const metadata: Metadata = { 1687 + forcedCompression: { is_enum: true }, 1688 + mediaTypes: { is_enum: true }, 1689 + }; 1690 + 1691 + const response: Awaited<string> = await computeQuery( 1692 + [ 1693 + ...this._queryTree, 1694 + { 1695 + operation: "publish", 1696 + args: { address, ...opts, __metadata: metadata }, 1697 + }, 1698 + ], 1699 + await this._ctx.connection() 1700 + ); 1701 + 1702 + return response; 1703 + }; 1704 + 1705 + /** 1706 + * Retrieves this container's root filesystem. Mounts are not included. 1707 + */ 1708 + rootfs = (): Directory => { 1709 + return new Directory({ 1710 + queryTree: [ 1711 + ...this._queryTree, 1712 + { 1713 + operation: "rootfs", 1714 + }, 1715 + ], 1716 + ctx: this._ctx, 1717 + }); 1718 + }; 1719 + 1720 + /** 1721 + * The error stream of the last executed command. 1722 + * 1723 + * Will execute default command if none is set, or error if there's no default. 1724 + */ 1725 + stderr = async (): Promise<string> => { 1726 + if (this._stderr) { 1727 + return this._stderr; 1728 + } 1729 + 1730 + const response: Awaited<string> = await computeQuery( 1731 + [ 1732 + ...this._queryTree, 1733 + { 1734 + operation: "stderr", 1735 + }, 1736 + ], 1737 + await this._ctx.connection() 1738 + ); 1739 + 1740 + return response; 1741 + }; 1742 + 1743 + /** 1744 + * The output stream of the last executed command. 1745 + * 1746 + * Will execute default command if none is set, or error if there's no default. 1747 + */ 1748 + stdout = async (): Promise<string> => { 1749 + if (this._stdout) { 1750 + return this._stdout; 1751 + } 1752 + 1753 + const response: Awaited<string> = await computeQuery( 1754 + [ 1755 + ...this._queryTree, 1756 + { 1757 + operation: "stdout", 1758 + }, 1759 + ], 1760 + await this._ctx.connection() 1761 + ); 1762 + 1763 + return response; 1764 + }; 1765 + 1766 + /** 1767 + * Forces evaluation of the pipeline in the engine. 1768 + * 1769 + * It doesn't run the default command if no exec has been set. 1770 + */ 1771 + sync = async (): Promise<Container> => { 1772 + await computeQuery( 1773 + [ 1774 + ...this._queryTree, 1775 + { 1776 + operation: "sync", 1777 + }, 1778 + ], 1779 + await this._ctx.connection() 1780 + ); 1781 + 1782 + return this; 1783 + }; 1784 + 1785 + /** 1786 + * Return an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default). 1787 + * @param opts.cmd If set, override the container's default terminal command and invoke these command arguments instead. 1788 + */ 1789 + terminal = (opts?: ContainerTerminalOpts): Terminal => { 1790 + return new Terminal({ 1791 + queryTree: [ 1792 + ...this._queryTree, 1793 + { 1794 + operation: "terminal", 1795 + args: { ...opts }, 1796 + }, 1797 + ], 1798 + ctx: this._ctx, 1799 + }); 1800 + }; 1801 + 1802 + /** 1803 + * Retrieves the user to be set for all commands. 1804 + */ 1805 + user = async (): Promise<string> => { 1806 + if (this._user) { 1807 + return this._user; 1808 + } 1809 + 1810 + const response: Awaited<string> = await computeQuery( 1811 + [ 1812 + ...this._queryTree, 1813 + { 1814 + operation: "user", 1815 + }, 1816 + ], 1817 + await this._ctx.connection() 1818 + ); 1819 + 1820 + return response; 1821 + }; 1822 + 1823 + /** 1824 + * Configures default arguments for future commands. 1825 + * @param args Arguments to prepend to future executions (e.g., ["-v", "--no-cache"]). 1826 + */ 1827 + withDefaultArgs = (args: string[]): Container => { 1828 + return new Container({ 1829 + queryTree: [ 1830 + ...this._queryTree, 1831 + { 1832 + operation: "withDefaultArgs", 1833 + args: { args }, 1834 + }, 1835 + ], 1836 + ctx: this._ctx, 1837 + }); 1838 + }; 1839 + 1840 + /** 1841 + * Set the default command to invoke for the container's terminal API. 1842 + * @param args The args of the command. 1843 + */ 1844 + withDefaultTerminalCmd = (args: string[]): Container => { 1845 + return new Container({ 1846 + queryTree: [ 1847 + ...this._queryTree, 1848 + { 1849 + operation: "withDefaultTerminalCmd", 1850 + args: { args }, 1851 + }, 1852 + ], 1853 + ctx: this._ctx, 1854 + }); 1855 + }; 1856 + 1857 + /** 1858 + * Retrieves this container plus a directory written at the given path. 1859 + * @param path Location of the written directory (e.g., "/tmp/directory"). 1860 + * @param directory Identifier of the directory to write 1861 + * @param opts.exclude Patterns to exclude in the written directory (e.g. ["node_modules/**", ".gitignore", ".git/"]). 1862 + * @param opts.include Patterns to include in the written directory (e.g. ["*.go", "go.mod", "go.sum"]). 1863 + * @param opts.owner A user:group to set for the directory and its contents. 1864 + * 1865 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 1866 + * 1867 + * If the group is omitted, it defaults to the same as the user. 1868 + */ 1869 + withDirectory = ( 1870 + path: string, 1871 + directory: Directory, 1872 + opts?: ContainerWithDirectoryOpts 1873 + ): Container => { 1874 + return new Container({ 1875 + queryTree: [ 1876 + ...this._queryTree, 1877 + { 1878 + operation: "withDirectory", 1879 + args: { path, directory, ...opts }, 1880 + }, 1881 + ], 1882 + ctx: this._ctx, 1883 + }); 1884 + }; 1885 + 1886 + /** 1887 + * Retrieves this container but with a different command entrypoint. 1888 + * @param args Entrypoint to use for future executions (e.g., ["go", "run"]). 1889 + * @param opts.keepDefaultArgs Don't remove the default arguments when setting the entrypoint. 1890 + */ 1891 + withEntrypoint = ( 1892 + args: string[], 1893 + opts?: ContainerWithEntrypointOpts 1894 + ): Container => { 1895 + return new Container({ 1896 + queryTree: [ 1897 + ...this._queryTree, 1898 + { 1899 + operation: "withEntrypoint", 1900 + args: { args, ...opts }, 1901 + }, 1902 + ], 1903 + ctx: this._ctx, 1904 + }); 1905 + }; 1906 + 1907 + /** 1908 + * Retrieves this container plus the given environment variable. 1909 + * @param name The name of the environment variable (e.g., "HOST"). 1910 + * @param value The value of the environment variable. (e.g., "localhost"). 1911 + * @param opts.expand Replace `${VAR}` or `$VAR` in the value according to the current environment variables defined in the container (e.g., "/opt/bin:$PATH"). 1912 + */ 1913 + withEnvVariable = ( 1914 + name: string, 1915 + value: string, 1916 + opts?: ContainerWithEnvVariableOpts 1917 + ): Container => { 1918 + return new Container({ 1919 + queryTree: [ 1920 + ...this._queryTree, 1921 + { 1922 + operation: "withEnvVariable", 1923 + args: { name, value, ...opts }, 1924 + }, 1925 + ], 1926 + ctx: this._ctx, 1927 + }); 1928 + }; 1929 + 1930 + /** 1931 + * Retrieves this container after executing the specified command inside it. 1932 + * @param args Command to run instead of the container's default command (e.g., ["run", "main.go"]). 1933 + * 1934 + * If empty, the container's default command is used. 1935 + * @param opts.skipEntrypoint If the container has an entrypoint, ignore it for args rather than using it to wrap them. 1936 + * @param opts.stdin Content to write to the command's standard input before closing (e.g., "Hello world"). 1937 + * @param opts.redirectStdout Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). 1938 + * @param opts.redirectStderr Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). 1939 + * @param opts.experimentalPrivilegedNesting Provides dagger access to the executed command. 1940 + * 1941 + * Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. 1942 + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. 1943 + */ 1944 + withExec = (args: string[], opts?: ContainerWithExecOpts): Container => { 1945 + return new Container({ 1946 + queryTree: [ 1947 + ...this._queryTree, 1948 + { 1949 + operation: "withExec", 1950 + args: { args, ...opts }, 1951 + }, 1952 + ], 1953 + ctx: this._ctx, 1954 + }); 1955 + }; 1956 + 1957 + /** 1958 + * Expose a network port. 1959 + * 1960 + * Exposed ports serve two purposes: 1961 + * 1962 + * - For health checks and introspection, when running services 1963 + * 1964 + * - For setting the EXPOSE OCI field when publishing the container 1965 + * @param port Port number to expose 1966 + * @param opts.protocol Transport layer network protocol 1967 + * @param opts.description Optional port description 1968 + * @param opts.experimentalSkipHealthcheck Skip the health check when run as a service. 1969 + */ 1970 + withExposedPort = ( 1971 + port: number, 1972 + opts?: ContainerWithExposedPortOpts 1973 + ): Container => { 1974 + const metadata: Metadata = { 1975 + protocol: { is_enum: true }, 1976 + }; 1977 + 1978 + return new Container({ 1979 + queryTree: [ 1980 + ...this._queryTree, 1981 + { 1982 + operation: "withExposedPort", 1983 + args: { port, ...opts, __metadata: metadata }, 1984 + }, 1985 + ], 1986 + ctx: this._ctx, 1987 + }); 1988 + }; 1989 + 1990 + /** 1991 + * Retrieves this container plus the contents of the given file copied to the given path. 1992 + * @param path Location of the copied file (e.g., "/tmp/file.txt"). 1993 + * @param source Identifier of the file to copy. 1994 + * @param opts.permissions Permission given to the copied file (e.g., 0600). 1995 + * @param opts.owner A user:group to set for the file. 1996 + * 1997 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 1998 + * 1999 + * If the group is omitted, it defaults to the same as the user. 2000 + */ 2001 + withFile = ( 2002 + path: string, 2003 + source: File, 2004 + opts?: ContainerWithFileOpts 2005 + ): Container => { 2006 + return new Container({ 2007 + queryTree: [ 2008 + ...this._queryTree, 2009 + { 2010 + operation: "withFile", 2011 + args: { path, source, ...opts }, 2012 + }, 2013 + ], 2014 + ctx: this._ctx, 2015 + }); 2016 + }; 2017 + 2018 + /** 2019 + * Retrieves this container plus the contents of the given files copied to the given path. 2020 + * @param path Location where copied files should be placed (e.g., "/src"). 2021 + * @param sources Identifiers of the files to copy. 2022 + * @param opts.permissions Permission given to the copied files (e.g., 0600). 2023 + * @param opts.owner A user:group to set for the files. 2024 + * 2025 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2026 + * 2027 + * If the group is omitted, it defaults to the same as the user. 2028 + */ 2029 + withFiles = ( 2030 + path: string, 2031 + sources: File[], 2032 + opts?: ContainerWithFilesOpts 2033 + ): Container => { 2034 + return new Container({ 2035 + queryTree: [ 2036 + ...this._queryTree, 2037 + { 2038 + operation: "withFiles", 2039 + args: { path, sources, ...opts }, 2040 + }, 2041 + ], 2042 + ctx: this._ctx, 2043 + }); 2044 + }; 2045 + 2046 + /** 2047 + * Indicate that subsequent operations should be featured more prominently in the UI. 2048 + */ 2049 + withFocus = (): Container => { 2050 + return new Container({ 2051 + queryTree: [ 2052 + ...this._queryTree, 2053 + { 2054 + operation: "withFocus", 2055 + }, 2056 + ], 2057 + ctx: this._ctx, 2058 + }); 2059 + }; 2060 + 2061 + /** 2062 + * Retrieves this container plus the given label. 2063 + * @param name The name of the label (e.g., "org.opencontainers.artifact.created"). 2064 + * @param value The value of the label (e.g., "2023-01-01T00:00:00Z"). 2065 + */ 2066 + withLabel = (name: string, value: string): Container => { 2067 + return new Container({ 2068 + queryTree: [ 2069 + ...this._queryTree, 2070 + { 2071 + operation: "withLabel", 2072 + args: { name, value }, 2073 + }, 2074 + ], 2075 + ctx: this._ctx, 2076 + }); 2077 + }; 2078 + 2079 + /** 2080 + * Retrieves this container plus a cache volume mounted at the given path. 2081 + * @param path Location of the cache directory (e.g., "/cache/node_modules"). 2082 + * @param cache Identifier of the cache volume to mount. 2083 + * @param opts.source Identifier of the directory to use as the cache volume's root. 2084 + * @param opts.sharing Sharing mode of the cache volume. 2085 + * @param opts.owner A user:group to set for the mounted cache directory. 2086 + * 2087 + * Note that this changes the ownership of the specified mount along with the initial filesystem provided by source (if any). It does not have any effect if/when the cache has already been created. 2088 + * 2089 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2090 + * 2091 + * If the group is omitted, it defaults to the same as the user. 2092 + */ 2093 + withMountedCache = ( 2094 + path: string, 2095 + cache: CacheVolume, 2096 + opts?: ContainerWithMountedCacheOpts 2097 + ): Container => { 2098 + const metadata: Metadata = { 2099 + sharing: { is_enum: true }, 2100 + }; 2101 + 2102 + return new Container({ 2103 + queryTree: [ 2104 + ...this._queryTree, 2105 + { 2106 + operation: "withMountedCache", 2107 + args: { path, cache, ...opts, __metadata: metadata }, 2108 + }, 2109 + ], 2110 + ctx: this._ctx, 2111 + }); 2112 + }; 2113 + 2114 + /** 2115 + * Retrieves this container plus a directory mounted at the given path. 2116 + * @param path Location of the mounted directory (e.g., "/mnt/directory"). 2117 + * @param source Identifier of the mounted directory. 2118 + * @param opts.owner A user:group to set for the mounted directory and its contents. 2119 + * 2120 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2121 + * 2122 + * If the group is omitted, it defaults to the same as the user. 2123 + */ 2124 + withMountedDirectory = ( 2125 + path: string, 2126 + source: Directory, 2127 + opts?: ContainerWithMountedDirectoryOpts 2128 + ): Container => { 2129 + return new Container({ 2130 + queryTree: [ 2131 + ...this._queryTree, 2132 + { 2133 + operation: "withMountedDirectory", 2134 + args: { path, source, ...opts }, 2135 + }, 2136 + ], 2137 + ctx: this._ctx, 2138 + }); 2139 + }; 2140 + 2141 + /** 2142 + * Retrieves this container plus a file mounted at the given path. 2143 + * @param path Location of the mounted file (e.g., "/tmp/file.txt"). 2144 + * @param source Identifier of the mounted file. 2145 + * @param opts.owner A user or user:group to set for the mounted file. 2146 + * 2147 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2148 + * 2149 + * If the group is omitted, it defaults to the same as the user. 2150 + */ 2151 + withMountedFile = ( 2152 + path: string, 2153 + source: File, 2154 + opts?: ContainerWithMountedFileOpts 2155 + ): Container => { 2156 + return new Container({ 2157 + queryTree: [ 2158 + ...this._queryTree, 2159 + { 2160 + operation: "withMountedFile", 2161 + args: { path, source, ...opts }, 2162 + }, 2163 + ], 2164 + ctx: this._ctx, 2165 + }); 2166 + }; 2167 + 2168 + /** 2169 + * Retrieves this container plus a secret mounted into a file at the given path. 2170 + * @param path Location of the secret file (e.g., "/tmp/secret.txt"). 2171 + * @param source Identifier of the secret to mount. 2172 + * @param opts.owner A user:group to set for the mounted secret. 2173 + * 2174 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2175 + * 2176 + * If the group is omitted, it defaults to the same as the user. 2177 + * @param opts.mode Permission given to the mounted secret (e.g., 0600). 2178 + * 2179 + * This option requires an owner to be set to be active. 2180 + */ 2181 + withMountedSecret = ( 2182 + path: string, 2183 + source: Secret, 2184 + opts?: ContainerWithMountedSecretOpts 2185 + ): Container => { 2186 + return new Container({ 2187 + queryTree: [ 2188 + ...this._queryTree, 2189 + { 2190 + operation: "withMountedSecret", 2191 + args: { path, source, ...opts }, 2192 + }, 2193 + ], 2194 + ctx: this._ctx, 2195 + }); 2196 + }; 2197 + 2198 + /** 2199 + * Retrieves this container plus a temporary directory mounted at the given path. 2200 + * @param path Location of the temporary directory (e.g., "/tmp/temp_dir"). 2201 + */ 2202 + withMountedTemp = (path: string): Container => { 2203 + return new Container({ 2204 + queryTree: [ 2205 + ...this._queryTree, 2206 + { 2207 + operation: "withMountedTemp", 2208 + args: { path }, 2209 + }, 2210 + ], 2211 + ctx: this._ctx, 2212 + }); 2213 + }; 2214 + 2215 + /** 2216 + * Retrieves this container plus a new file written at the given path. 2217 + * @param path Location of the written file (e.g., "/tmp/file.txt"). 2218 + * @param opts.contents Content of the file to write (e.g., "Hello world!"). 2219 + * @param opts.permissions Permission given to the written file (e.g., 0600). 2220 + * @param opts.owner A user:group to set for the file. 2221 + * 2222 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2223 + * 2224 + * If the group is omitted, it defaults to the same as the user. 2225 + */ 2226 + withNewFile = (path: string, opts?: ContainerWithNewFileOpts): Container => { 2227 + return new Container({ 2228 + queryTree: [ 2229 + ...this._queryTree, 2230 + { 2231 + operation: "withNewFile", 2232 + args: { path, ...opts }, 2233 + }, 2234 + ], 2235 + ctx: this._ctx, 2236 + }); 2237 + }; 2238 + 2239 + /** 2240 + * Retrieves this container with a registry authentication for a given address. 2241 + * @param address Registry's address to bind the authentication to. 2242 + * 2243 + * Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main). 2244 + * @param username The username of the registry's account (e.g., "Dagger"). 2245 + * @param secret The API key, password or token to authenticate to this registry. 2246 + */ 2247 + withRegistryAuth = ( 2248 + address: string, 2249 + username: string, 2250 + secret: Secret 2251 + ): Container => { 2252 + return new Container({ 2253 + queryTree: [ 2254 + ...this._queryTree, 2255 + { 2256 + operation: "withRegistryAuth", 2257 + args: { address, username, secret }, 2258 + }, 2259 + ], 2260 + ctx: this._ctx, 2261 + }); 2262 + }; 2263 + 2264 + /** 2265 + * Retrieves the container with the given directory mounted to /. 2266 + * @param directory Directory to mount. 2267 + */ 2268 + withRootfs = (directory: Directory): Container => { 2269 + return new Container({ 2270 + queryTree: [ 2271 + ...this._queryTree, 2272 + { 2273 + operation: "withRootfs", 2274 + args: { directory }, 2275 + }, 2276 + ], 2277 + ctx: this._ctx, 2278 + }); 2279 + }; 2280 + 2281 + /** 2282 + * Retrieves this container plus an env variable containing the given secret. 2283 + * @param name The name of the secret variable (e.g., "API_SECRET"). 2284 + * @param secret The identifier of the secret value. 2285 + */ 2286 + withSecretVariable = (name: string, secret: Secret): Container => { 2287 + return new Container({ 2288 + queryTree: [ 2289 + ...this._queryTree, 2290 + { 2291 + operation: "withSecretVariable", 2292 + args: { name, secret }, 2293 + }, 2294 + ], 2295 + ctx: this._ctx, 2296 + }); 2297 + }; 2298 + 2299 + /** 2300 + * Establish a runtime dependency on a service. 2301 + * 2302 + * The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set. 2303 + * 2304 + * The service will be reachable from the container via the provided hostname alias. 2305 + * 2306 + * The service dependency will also convey to any files or directories produced by the container. 2307 + * @param alias A name that can be used to reach the service from the container 2308 + * @param service Identifier of the service container 2309 + */ 2310 + withServiceBinding = (alias: string, service: Service): Container => { 2311 + return new Container({ 2312 + queryTree: [ 2313 + ...this._queryTree, 2314 + { 2315 + operation: "withServiceBinding", 2316 + args: { alias, service }, 2317 + }, 2318 + ], 2319 + ctx: this._ctx, 2320 + }); 2321 + }; 2322 + 2323 + /** 2324 + * Retrieves this container plus a socket forwarded to the given Unix socket path. 2325 + * @param path Location of the forwarded Unix socket (e.g., "/tmp/socket"). 2326 + * @param source Identifier of the socket to forward. 2327 + * @param opts.owner A user:group to set for the mounted socket. 2328 + * 2329 + * The user and group can either be an ID (1000:1000) or a name (foo:bar). 2330 + * 2331 + * If the group is omitted, it defaults to the same as the user. 2332 + */ 2333 + withUnixSocket = ( 2334 + path: string, 2335 + source: Socket, 2336 + opts?: ContainerWithUnixSocketOpts 2337 + ): Container => { 2338 + return new Container({ 2339 + queryTree: [ 2340 + ...this._queryTree, 2341 + { 2342 + operation: "withUnixSocket", 2343 + args: { path, source, ...opts }, 2344 + }, 2345 + ], 2346 + ctx: this._ctx, 2347 + }); 2348 + }; 2349 + 2350 + /** 2351 + * Retrieves this container with a different command user. 2352 + * @param name The user to set (e.g., "root"). 2353 + */ 2354 + withUser = (name: string): Container => { 2355 + return new Container({ 2356 + queryTree: [ 2357 + ...this._queryTree, 2358 + { 2359 + operation: "withUser", 2360 + args: { name }, 2361 + }, 2362 + ], 2363 + ctx: this._ctx, 2364 + }); 2365 + }; 2366 + 2367 + /** 2368 + * Retrieves this container with a different working directory. 2369 + * @param path The path to set as the working directory (e.g., "/app"). 2370 + */ 2371 + withWorkdir = (path: string): Container => { 2372 + return new Container({ 2373 + queryTree: [ 2374 + ...this._queryTree, 2375 + { 2376 + operation: "withWorkdir", 2377 + args: { path }, 2378 + }, 2379 + ], 2380 + ctx: this._ctx, 2381 + }); 2382 + }; 2383 + 2384 + /** 2385 + * Retrieves this container with unset default arguments for future commands. 2386 + */ 2387 + withoutDefaultArgs = (): Container => { 2388 + return new Container({ 2389 + queryTree: [ 2390 + ...this._queryTree, 2391 + { 2392 + operation: "withoutDefaultArgs", 2393 + }, 2394 + ], 2395 + ctx: this._ctx, 2396 + }); 2397 + }; 2398 + 2399 + /** 2400 + * Retrieves this container with an unset command entrypoint. 2401 + * @param opts.keepDefaultArgs Don't remove the default arguments when unsetting the entrypoint. 2402 + */ 2403 + withoutEntrypoint = (opts?: ContainerWithoutEntrypointOpts): Container => { 2404 + return new Container({ 2405 + queryTree: [ 2406 + ...this._queryTree, 2407 + { 2408 + operation: "withoutEntrypoint", 2409 + args: { ...opts }, 2410 + }, 2411 + ], 2412 + ctx: this._ctx, 2413 + }); 2414 + }; 2415 + 2416 + /** 2417 + * Retrieves this container minus the given environment variable. 2418 + * @param name The name of the environment variable (e.g., "HOST"). 2419 + */ 2420 + withoutEnvVariable = (name: string): Container => { 2421 + return new Container({ 2422 + queryTree: [ 2423 + ...this._queryTree, 2424 + { 2425 + operation: "withoutEnvVariable", 2426 + args: { name }, 2427 + }, 2428 + ], 2429 + ctx: this._ctx, 2430 + }); 2431 + }; 2432 + 2433 + /** 2434 + * Unexpose a previously exposed port. 2435 + * @param port Port number to unexpose 2436 + * @param opts.protocol Port protocol to unexpose 2437 + */ 2438 + withoutExposedPort = ( 2439 + port: number, 2440 + opts?: ContainerWithoutExposedPortOpts 2441 + ): Container => { 2442 + const metadata: Metadata = { 2443 + protocol: { is_enum: true }, 2444 + }; 2445 + 2446 + return new Container({ 2447 + queryTree: [ 2448 + ...this._queryTree, 2449 + { 2450 + operation: "withoutExposedPort", 2451 + args: { port, ...opts, __metadata: metadata }, 2452 + }, 2453 + ], 2454 + ctx: this._ctx, 2455 + }); 2456 + }; 2457 + 2458 + /** 2459 + * Indicate that subsequent operations should not be featured more prominently in the UI. 2460 + * 2461 + * This is the initial state of all containers. 2462 + */ 2463 + withoutFocus = (): Container => { 2464 + return new Container({ 2465 + queryTree: [ 2466 + ...this._queryTree, 2467 + { 2468 + operation: "withoutFocus", 2469 + }, 2470 + ], 2471 + ctx: this._ctx, 2472 + }); 2473 + }; 2474 + 2475 + /** 2476 + * Retrieves this container minus the given environment label. 2477 + * @param name The name of the label to remove (e.g., "org.opencontainers.artifact.created"). 2478 + */ 2479 + withoutLabel = (name: string): Container => { 2480 + return new Container({ 2481 + queryTree: [ 2482 + ...this._queryTree, 2483 + { 2484 + operation: "withoutLabel", 2485 + args: { name }, 2486 + }, 2487 + ], 2488 + ctx: this._ctx, 2489 + }); 2490 + }; 2491 + 2492 + /** 2493 + * Retrieves this container after unmounting everything at the given path. 2494 + * @param path Location of the cache directory (e.g., "/cache/node_modules"). 2495 + */ 2496 + withoutMount = (path: string): Container => { 2497 + return new Container({ 2498 + queryTree: [ 2499 + ...this._queryTree, 2500 + { 2501 + operation: "withoutMount", 2502 + args: { path }, 2503 + }, 2504 + ], 2505 + ctx: this._ctx, 2506 + }); 2507 + }; 2508 + 2509 + /** 2510 + * Retrieves this container without the registry authentication of a given address. 2511 + * @param address Registry's address to remove the authentication from. 2512 + * 2513 + * Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main). 2514 + */ 2515 + withoutRegistryAuth = (address: string): Container => { 2516 + return new Container({ 2517 + queryTree: [ 2518 + ...this._queryTree, 2519 + { 2520 + operation: "withoutRegistryAuth", 2521 + args: { address }, 2522 + }, 2523 + ], 2524 + ctx: this._ctx, 2525 + }); 2526 + }; 2527 + 2528 + /** 2529 + * Retrieves this container with a previously added Unix socket removed. 2530 + * @param path Location of the socket to remove (e.g., "/tmp/socket"). 2531 + */ 2532 + withoutUnixSocket = (path: string): Container => { 2533 + return new Container({ 2534 + queryTree: [ 2535 + ...this._queryTree, 2536 + { 2537 + operation: "withoutUnixSocket", 2538 + args: { path }, 2539 + }, 2540 + ], 2541 + ctx: this._ctx, 2542 + }); 2543 + }; 2544 + 2545 + /** 2546 + * Retrieves this container with an unset command user. 2547 + * 2548 + * Should default to root. 2549 + */ 2550 + withoutUser = (): Container => { 2551 + return new Container({ 2552 + queryTree: [ 2553 + ...this._queryTree, 2554 + { 2555 + operation: "withoutUser", 2556 + }, 2557 + ], 2558 + ctx: this._ctx, 2559 + }); 2560 + }; 2561 + 2562 + /** 2563 + * Retrieves this container with an unset working directory. 2564 + * 2565 + * Should default to "/". 2566 + */ 2567 + withoutWorkdir = (): Container => { 2568 + return new Container({ 2569 + queryTree: [ 2570 + ...this._queryTree, 2571 + { 2572 + operation: "withoutWorkdir", 2573 + }, 2574 + ], 2575 + ctx: this._ctx, 2576 + }); 2577 + }; 2578 + 2579 + /** 2580 + * Retrieves the working directory for all commands. 2581 + */ 2582 + workdir = async (): Promise<string> => { 2583 + if (this._workdir) { 2584 + return this._workdir; 2585 + } 2586 + 2587 + const response: Awaited<string> = await computeQuery( 2588 + [ 2589 + ...this._queryTree, 2590 + { 2591 + operation: "workdir", 2592 + }, 2593 + ], 2594 + await this._ctx.connection() 2595 + ); 2596 + 2597 + return response; 2598 + }; 2599 + 2600 + /** 2601 + * Call the provided function with current Container. 2602 + * 2603 + * This is useful for reusability and readability by not breaking the calling chain. 2604 + */ 2605 + with = (arg: (param: Container) => Container) => { 2606 + return arg(this); 2607 + }; 2608 + } 2609 + 2610 + /** 2611 + * Reflective module API provided to functions at runtime. 2612 + */ 2613 + export class CurrentModule extends BaseClient { 2614 + private readonly _id?: CurrentModuleID = undefined; 2615 + private readonly _name?: string = undefined; 2616 + 2617 + /** 2618 + * Constructor is used for internal usage only, do not create object from it. 2619 + */ 2620 + constructor( 2621 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 2622 + _id?: CurrentModuleID, 2623 + _name?: string 2624 + ) { 2625 + super(parent); 2626 + 2627 + this._id = _id; 2628 + this._name = _name; 2629 + } 2630 + 2631 + /** 2632 + * A unique identifier for this CurrentModule. 2633 + */ 2634 + id = async (): Promise<CurrentModuleID> => { 2635 + if (this._id) { 2636 + return this._id; 2637 + } 2638 + 2639 + const response: Awaited<CurrentModuleID> = await computeQuery( 2640 + [ 2641 + ...this._queryTree, 2642 + { 2643 + operation: "id", 2644 + }, 2645 + ], 2646 + await this._ctx.connection() 2647 + ); 2648 + 2649 + return response; 2650 + }; 2651 + 2652 + /** 2653 + * The name of the module being executed in 2654 + */ 2655 + name = async (): Promise<string> => { 2656 + if (this._name) { 2657 + return this._name; 2658 + } 2659 + 2660 + const response: Awaited<string> = await computeQuery( 2661 + [ 2662 + ...this._queryTree, 2663 + { 2664 + operation: "name", 2665 + }, 2666 + ], 2667 + await this._ctx.connection() 2668 + ); 2669 + 2670 + return response; 2671 + }; 2672 + 2673 + /** 2674 + * The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). 2675 + */ 2676 + source = (): Directory => { 2677 + return new Directory({ 2678 + queryTree: [ 2679 + ...this._queryTree, 2680 + { 2681 + operation: "source", 2682 + }, 2683 + ], 2684 + ctx: this._ctx, 2685 + }); 2686 + }; 2687 + 2688 + /** 2689 + * Load a directory from the module's scratch working directory, including any changes that may have been made to it during module function execution. 2690 + * @param path Location of the directory to access (e.g., "."). 2691 + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 2692 + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 2693 + */ 2694 + workdir = (path: string, opts?: CurrentModuleWorkdirOpts): Directory => { 2695 + return new Directory({ 2696 + queryTree: [ 2697 + ...this._queryTree, 2698 + { 2699 + operation: "workdir", 2700 + args: { path, ...opts }, 2701 + }, 2702 + ], 2703 + ctx: this._ctx, 2704 + }); 2705 + }; 2706 + 2707 + /** 2708 + * Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution.Load a file from the module's scratch working directory, including any changes that may have been made to it during module function execution. 2709 + * @param path Location of the file to retrieve (e.g., "README.md"). 2710 + */ 2711 + workdirFile = (path: string): File => { 2712 + return new File({ 2713 + queryTree: [ 2714 + ...this._queryTree, 2715 + { 2716 + operation: "workdirFile", 2717 + args: { path }, 2718 + }, 2719 + ], 2720 + ctx: this._ctx, 2721 + }); 2722 + }; 2723 + } 2724 + 2725 + /** 2726 + * A directory. 2727 + */ 2728 + export class Directory extends BaseClient { 2729 + private readonly _id?: DirectoryID = undefined; 2730 + private readonly _export?: boolean = undefined; 2731 + private readonly _sync?: DirectoryID = undefined; 2732 + 2733 + /** 2734 + * Constructor is used for internal usage only, do not create object from it. 2735 + */ 2736 + constructor( 2737 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 2738 + _id?: DirectoryID, 2739 + _export?: boolean, 2740 + _sync?: DirectoryID 2741 + ) { 2742 + super(parent); 2743 + 2744 + this._id = _id; 2745 + this._export = _export; 2746 + this._sync = _sync; 2747 + } 2748 + 2749 + /** 2750 + * A unique identifier for this Directory. 2751 + */ 2752 + id = async (): Promise<DirectoryID> => { 2753 + if (this._id) { 2754 + return this._id; 2755 + } 2756 + 2757 + const response: Awaited<DirectoryID> = await computeQuery( 2758 + [ 2759 + ...this._queryTree, 2760 + { 2761 + operation: "id", 2762 + }, 2763 + ], 2764 + await this._ctx.connection() 2765 + ); 2766 + 2767 + return response; 2768 + }; 2769 + 2770 + /** 2771 + * Load the directory as a Dagger module 2772 + * @param opts.sourceRootPath An optional subpath of the directory which contains the module's configuration file. 2773 + * 2774 + * This is needed when the module code is in a subdirectory but requires parent directories to be loaded in order to execute. For example, the module source code may need a go.mod, project.toml, package.json, etc. file from a parent directory. 2775 + * 2776 + * If not set, the module source code is loaded from the root of the directory. 2777 + */ 2778 + asModule = (opts?: DirectoryAsModuleOpts): Module_ => { 2779 + return new Module_({ 2780 + queryTree: [ 2781 + ...this._queryTree, 2782 + { 2783 + operation: "asModule", 2784 + args: { ...opts }, 2785 + }, 2786 + ], 2787 + ctx: this._ctx, 2788 + }); 2789 + }; 2790 + 2791 + /** 2792 + * Gets the difference between this directory and an another directory. 2793 + * @param other Identifier of the directory to compare. 2794 + */ 2795 + diff = (other: Directory): Directory => { 2796 + return new Directory({ 2797 + queryTree: [ 2798 + ...this._queryTree, 2799 + { 2800 + operation: "diff", 2801 + args: { other }, 2802 + }, 2803 + ], 2804 + ctx: this._ctx, 2805 + }); 2806 + }; 2807 + 2808 + /** 2809 + * Retrieves a directory at the given path. 2810 + * @param path Location of the directory to retrieve (e.g., "/src"). 2811 + */ 2812 + directory = (path: string): Directory => { 2813 + return new Directory({ 2814 + queryTree: [ 2815 + ...this._queryTree, 2816 + { 2817 + operation: "directory", 2818 + args: { path }, 2819 + }, 2820 + ], 2821 + ctx: this._ctx, 2822 + }); 2823 + }; 2824 + 2825 + /** 2826 + * Builds a new Docker container from this directory. 2827 + * @param opts.platform The platform to build. 2828 + * @param opts.dockerfile Path to the Dockerfile to use (e.g., "frontend.Dockerfile"). 2829 + * @param opts.target Target build stage to build. 2830 + * @param opts.buildArgs Build arguments to use in the build. 2831 + * @param opts.secrets Secrets to pass to the build. 2832 + * 2833 + * They will be mounted at /run/secrets/[secret-name]. 2834 + */ 2835 + dockerBuild = (opts?: DirectoryDockerBuildOpts): Container => { 2836 + return new Container({ 2837 + queryTree: [ 2838 + ...this._queryTree, 2839 + { 2840 + operation: "dockerBuild", 2841 + args: { ...opts }, 2842 + }, 2843 + ], 2844 + ctx: this._ctx, 2845 + }); 2846 + }; 2847 + 2848 + /** 2849 + * Returns a list of files and directories at the given path. 2850 + * @param opts.path Location of the directory to look at (e.g., "/src"). 2851 + */ 2852 + entries = async (opts?: DirectoryEntriesOpts): Promise<string[]> => { 2853 + const response: Awaited<string[]> = await computeQuery( 2854 + [ 2855 + ...this._queryTree, 2856 + { 2857 + operation: "entries", 2858 + args: { ...opts }, 2859 + }, 2860 + ], 2861 + await this._ctx.connection() 2862 + ); 2863 + 2864 + return response; 2865 + }; 2866 + 2867 + /** 2868 + * Writes the contents of the directory to a path on the host. 2869 + * @param path Location of the copied directory (e.g., "logs/"). 2870 + */ 2871 + export = async (path: string): Promise<boolean> => { 2872 + if (this._export) { 2873 + return this._export; 2874 + } 2875 + 2876 + const response: Awaited<boolean> = await computeQuery( 2877 + [ 2878 + ...this._queryTree, 2879 + { 2880 + operation: "export", 2881 + args: { path }, 2882 + }, 2883 + ], 2884 + await this._ctx.connection() 2885 + ); 2886 + 2887 + return response; 2888 + }; 2889 + 2890 + /** 2891 + * Retrieves a file at the given path. 2892 + * @param path Location of the file to retrieve (e.g., "README.md"). 2893 + */ 2894 + file = (path: string): File => { 2895 + return new File({ 2896 + queryTree: [ 2897 + ...this._queryTree, 2898 + { 2899 + operation: "file", 2900 + args: { path }, 2901 + }, 2902 + ], 2903 + ctx: this._ctx, 2904 + }); 2905 + }; 2906 + 2907 + /** 2908 + * Returns a list of files and directories that matche the given pattern. 2909 + * @param pattern Pattern to match (e.g., "*.md"). 2910 + */ 2911 + glob = async (pattern: string): Promise<string[]> => { 2912 + const response: Awaited<string[]> = await computeQuery( 2913 + [ 2914 + ...this._queryTree, 2915 + { 2916 + operation: "glob", 2917 + args: { pattern }, 2918 + }, 2919 + ], 2920 + await this._ctx.connection() 2921 + ); 2922 + 2923 + return response; 2924 + }; 2925 + 2926 + /** 2927 + * Creates a named sub-pipeline. 2928 + * @param name Name of the sub-pipeline. 2929 + * @param opts.description Description of the sub-pipeline. 2930 + * @param opts.labels Labels to apply to the sub-pipeline. 2931 + */ 2932 + pipeline = (name: string, opts?: DirectoryPipelineOpts): Directory => { 2933 + return new Directory({ 2934 + queryTree: [ 2935 + ...this._queryTree, 2936 + { 2937 + operation: "pipeline", 2938 + args: { name, ...opts }, 2939 + }, 2940 + ], 2941 + ctx: this._ctx, 2942 + }); 2943 + }; 2944 + 2945 + /** 2946 + * Force evaluation in the engine. 2947 + */ 2948 + sync = async (): Promise<Directory> => { 2949 + await computeQuery( 2950 + [ 2951 + ...this._queryTree, 2952 + { 2953 + operation: "sync", 2954 + }, 2955 + ], 2956 + await this._ctx.connection() 2957 + ); 2958 + 2959 + return this; 2960 + }; 2961 + 2962 + /** 2963 + * Retrieves this directory plus a directory written at the given path. 2964 + * @param path Location of the written directory (e.g., "/src/"). 2965 + * @param directory Identifier of the directory to copy. 2966 + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 2967 + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 2968 + */ 2969 + withDirectory = ( 2970 + path: string, 2971 + directory: Directory, 2972 + opts?: DirectoryWithDirectoryOpts 2973 + ): Directory => { 2974 + return new Directory({ 2975 + queryTree: [ 2976 + ...this._queryTree, 2977 + { 2978 + operation: "withDirectory", 2979 + args: { path, directory, ...opts }, 2980 + }, 2981 + ], 2982 + ctx: this._ctx, 2983 + }); 2984 + }; 2985 + 2986 + /** 2987 + * Retrieves this directory plus the contents of the given file copied to the given path. 2988 + * @param path Location of the copied file (e.g., "/file.txt"). 2989 + * @param source Identifier of the file to copy. 2990 + * @param opts.permissions Permission given to the copied file (e.g., 0600). 2991 + */ 2992 + withFile = ( 2993 + path: string, 2994 + source: File, 2995 + opts?: DirectoryWithFileOpts 2996 + ): Directory => { 2997 + return new Directory({ 2998 + queryTree: [ 2999 + ...this._queryTree, 3000 + { 3001 + operation: "withFile", 3002 + args: { path, source, ...opts }, 3003 + }, 3004 + ], 3005 + ctx: this._ctx, 3006 + }); 3007 + }; 3008 + 3009 + /** 3010 + * Retrieves this directory plus the contents of the given files copied to the given path. 3011 + * @param path Location where copied files should be placed (e.g., "/src"). 3012 + * @param sources Identifiers of the files to copy. 3013 + * @param opts.permissions Permission given to the copied files (e.g., 0600). 3014 + */ 3015 + withFiles = ( 3016 + path: string, 3017 + sources: File[], 3018 + opts?: DirectoryWithFilesOpts 3019 + ): Directory => { 3020 + return new Directory({ 3021 + queryTree: [ 3022 + ...this._queryTree, 3023 + { 3024 + operation: "withFiles", 3025 + args: { path, sources, ...opts }, 3026 + }, 3027 + ], 3028 + ctx: this._ctx, 3029 + }); 3030 + }; 3031 + 3032 + /** 3033 + * Retrieves this directory plus a new directory created at the given path. 3034 + * @param path Location of the directory created (e.g., "/logs"). 3035 + * @param opts.permissions Permission granted to the created directory (e.g., 0777). 3036 + */ 3037 + withNewDirectory = ( 3038 + path: string, 3039 + opts?: DirectoryWithNewDirectoryOpts 3040 + ): Directory => { 3041 + return new Directory({ 3042 + queryTree: [ 3043 + ...this._queryTree, 3044 + { 3045 + operation: "withNewDirectory", 3046 + args: { path, ...opts }, 3047 + }, 3048 + ], 3049 + ctx: this._ctx, 3050 + }); 3051 + }; 3052 + 3053 + /** 3054 + * Retrieves this directory plus a new file written at the given path. 3055 + * @param path Location of the written file (e.g., "/file.txt"). 3056 + * @param contents Content of the written file (e.g., "Hello world!"). 3057 + * @param opts.permissions Permission given to the copied file (e.g., 0600). 3058 + */ 3059 + withNewFile = ( 3060 + path: string, 3061 + contents: string, 3062 + opts?: DirectoryWithNewFileOpts 3063 + ): Directory => { 3064 + return new Directory({ 3065 + queryTree: [ 3066 + ...this._queryTree, 3067 + { 3068 + operation: "withNewFile", 3069 + args: { path, contents, ...opts }, 3070 + }, 3071 + ], 3072 + ctx: this._ctx, 3073 + }); 3074 + }; 3075 + 3076 + /** 3077 + * Retrieves this directory with all file/dir timestamps set to the given time. 3078 + * @param timestamp Timestamp to set dir/files in. 3079 + * 3080 + * Formatted in seconds following Unix epoch (e.g., 1672531199). 3081 + */ 3082 + withTimestamps = (timestamp: number): Directory => { 3083 + return new Directory({ 3084 + queryTree: [ 3085 + ...this._queryTree, 3086 + { 3087 + operation: "withTimestamps", 3088 + args: { timestamp }, 3089 + }, 3090 + ], 3091 + ctx: this._ctx, 3092 + }); 3093 + }; 3094 + 3095 + /** 3096 + * Retrieves this directory with the directory at the given path removed. 3097 + * @param path Location of the directory to remove (e.g., ".github/"). 3098 + */ 3099 + withoutDirectory = (path: string): Directory => { 3100 + return new Directory({ 3101 + queryTree: [ 3102 + ...this._queryTree, 3103 + { 3104 + operation: "withoutDirectory", 3105 + args: { path }, 3106 + }, 3107 + ], 3108 + ctx: this._ctx, 3109 + }); 3110 + }; 3111 + 3112 + /** 3113 + * Retrieves this directory with the file at the given path removed. 3114 + * @param path Location of the file to remove (e.g., "/file.txt"). 3115 + */ 3116 + withoutFile = (path: string): Directory => { 3117 + return new Directory({ 3118 + queryTree: [ 3119 + ...this._queryTree, 3120 + { 3121 + operation: "withoutFile", 3122 + args: { path }, 3123 + }, 3124 + ], 3125 + ctx: this._ctx, 3126 + }); 3127 + }; 3128 + 3129 + /** 3130 + * Call the provided function with current Directory. 3131 + * 3132 + * This is useful for reusability and readability by not breaking the calling chain. 3133 + */ 3134 + with = (arg: (param: Directory) => Directory) => { 3135 + return arg(this); 3136 + }; 3137 + } 3138 + 3139 + /** 3140 + * An environment variable name and value. 3141 + */ 3142 + export class EnvVariable extends BaseClient { 3143 + private readonly _id?: EnvVariableID = undefined; 3144 + private readonly _name?: string = undefined; 3145 + private readonly _value?: string = undefined; 3146 + 3147 + /** 3148 + * Constructor is used for internal usage only, do not create object from it. 3149 + */ 3150 + constructor( 3151 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3152 + _id?: EnvVariableID, 3153 + _name?: string, 3154 + _value?: string 3155 + ) { 3156 + super(parent); 3157 + 3158 + this._id = _id; 3159 + this._name = _name; 3160 + this._value = _value; 3161 + } 3162 + 3163 + /** 3164 + * A unique identifier for this EnvVariable. 3165 + */ 3166 + id = async (): Promise<EnvVariableID> => { 3167 + if (this._id) { 3168 + return this._id; 3169 + } 3170 + 3171 + const response: Awaited<EnvVariableID> = await computeQuery( 3172 + [ 3173 + ...this._queryTree, 3174 + { 3175 + operation: "id", 3176 + }, 3177 + ], 3178 + await this._ctx.connection() 3179 + ); 3180 + 3181 + return response; 3182 + }; 3183 + 3184 + /** 3185 + * The environment variable name. 3186 + */ 3187 + name = async (): Promise<string> => { 3188 + if (this._name) { 3189 + return this._name; 3190 + } 3191 + 3192 + const response: Awaited<string> = await computeQuery( 3193 + [ 3194 + ...this._queryTree, 3195 + { 3196 + operation: "name", 3197 + }, 3198 + ], 3199 + await this._ctx.connection() 3200 + ); 3201 + 3202 + return response; 3203 + }; 3204 + 3205 + /** 3206 + * The environment variable value. 3207 + */ 3208 + value = async (): Promise<string> => { 3209 + if (this._value) { 3210 + return this._value; 3211 + } 3212 + 3213 + const response: Awaited<string> = await computeQuery( 3214 + [ 3215 + ...this._queryTree, 3216 + { 3217 + operation: "value", 3218 + }, 3219 + ], 3220 + await this._ctx.connection() 3221 + ); 3222 + 3223 + return response; 3224 + }; 3225 + } 3226 + 3227 + /** 3228 + * A definition of a field on a custom object defined in a Module. 3229 + * 3230 + * A field on an object has a static value, as opposed to a function on an object whose value is computed by invoking code (and can accept arguments). 3231 + */ 3232 + export class FieldTypeDef extends BaseClient { 3233 + private readonly _id?: FieldTypeDefID = undefined; 3234 + private readonly _description?: string = undefined; 3235 + private readonly _name?: string = undefined; 3236 + 3237 + /** 3238 + * Constructor is used for internal usage only, do not create object from it. 3239 + */ 3240 + constructor( 3241 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3242 + _id?: FieldTypeDefID, 3243 + _description?: string, 3244 + _name?: string 3245 + ) { 3246 + super(parent); 3247 + 3248 + this._id = _id; 3249 + this._description = _description; 3250 + this._name = _name; 3251 + } 3252 + 3253 + /** 3254 + * A unique identifier for this FieldTypeDef. 3255 + */ 3256 + id = async (): Promise<FieldTypeDefID> => { 3257 + if (this._id) { 3258 + return this._id; 3259 + } 3260 + 3261 + const response: Awaited<FieldTypeDefID> = await computeQuery( 3262 + [ 3263 + ...this._queryTree, 3264 + { 3265 + operation: "id", 3266 + }, 3267 + ], 3268 + await this._ctx.connection() 3269 + ); 3270 + 3271 + return response; 3272 + }; 3273 + 3274 + /** 3275 + * A doc string for the field, if any. 3276 + */ 3277 + description = async (): Promise<string> => { 3278 + if (this._description) { 3279 + return this._description; 3280 + } 3281 + 3282 + const response: Awaited<string> = await computeQuery( 3283 + [ 3284 + ...this._queryTree, 3285 + { 3286 + operation: "description", 3287 + }, 3288 + ], 3289 + await this._ctx.connection() 3290 + ); 3291 + 3292 + return response; 3293 + }; 3294 + 3295 + /** 3296 + * The name of the field in lowerCamelCase format. 3297 + */ 3298 + name = async (): Promise<string> => { 3299 + if (this._name) { 3300 + return this._name; 3301 + } 3302 + 3303 + const response: Awaited<string> = await computeQuery( 3304 + [ 3305 + ...this._queryTree, 3306 + { 3307 + operation: "name", 3308 + }, 3309 + ], 3310 + await this._ctx.connection() 3311 + ); 3312 + 3313 + return response; 3314 + }; 3315 + 3316 + /** 3317 + * The type of the field. 3318 + */ 3319 + typeDef = (): TypeDef => { 3320 + return new TypeDef({ 3321 + queryTree: [ 3322 + ...this._queryTree, 3323 + { 3324 + operation: "typeDef", 3325 + }, 3326 + ], 3327 + ctx: this._ctx, 3328 + }); 3329 + }; 3330 + } 3331 + 3332 + /** 3333 + * A file. 3334 + */ 3335 + export class File extends BaseClient { 3336 + private readonly _id?: FileID = undefined; 3337 + private readonly _contents?: string = undefined; 3338 + private readonly _export?: boolean = undefined; 3339 + private readonly _name?: string = undefined; 3340 + private readonly _size?: number = undefined; 3341 + private readonly _sync?: FileID = undefined; 3342 + 3343 + /** 3344 + * Constructor is used for internal usage only, do not create object from it. 3345 + */ 3346 + constructor( 3347 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3348 + _id?: FileID, 3349 + _contents?: string, 3350 + _export?: boolean, 3351 + _name?: string, 3352 + _size?: number, 3353 + _sync?: FileID 3354 + ) { 3355 + super(parent); 3356 + 3357 + this._id = _id; 3358 + this._contents = _contents; 3359 + this._export = _export; 3360 + this._name = _name; 3361 + this._size = _size; 3362 + this._sync = _sync; 3363 + } 3364 + 3365 + /** 3366 + * A unique identifier for this File. 3367 + */ 3368 + id = async (): Promise<FileID> => { 3369 + if (this._id) { 3370 + return this._id; 3371 + } 3372 + 3373 + const response: Awaited<FileID> = await computeQuery( 3374 + [ 3375 + ...this._queryTree, 3376 + { 3377 + operation: "id", 3378 + }, 3379 + ], 3380 + await this._ctx.connection() 3381 + ); 3382 + 3383 + return response; 3384 + }; 3385 + 3386 + /** 3387 + * Retrieves the contents of the file. 3388 + */ 3389 + contents = async (): Promise<string> => { 3390 + if (this._contents) { 3391 + return this._contents; 3392 + } 3393 + 3394 + const response: Awaited<string> = await computeQuery( 3395 + [ 3396 + ...this._queryTree, 3397 + { 3398 + operation: "contents", 3399 + }, 3400 + ], 3401 + await this._ctx.connection() 3402 + ); 3403 + 3404 + return response; 3405 + }; 3406 + 3407 + /** 3408 + * Writes the file to a file path on the host. 3409 + * @param path Location of the written directory (e.g., "output.txt"). 3410 + * @param opts.allowParentDirPath If allowParentDirPath is true, the path argument can be a directory path, in which case the file will be created in that directory. 3411 + */ 3412 + export = async (path: string, opts?: FileExportOpts): Promise<boolean> => { 3413 + if (this._export) { 3414 + return this._export; 3415 + } 3416 + 3417 + const response: Awaited<boolean> = await computeQuery( 3418 + [ 3419 + ...this._queryTree, 3420 + { 3421 + operation: "export", 3422 + args: { path, ...opts }, 3423 + }, 3424 + ], 3425 + await this._ctx.connection() 3426 + ); 3427 + 3428 + return response; 3429 + }; 3430 + 3431 + /** 3432 + * Retrieves the name of the file. 3433 + */ 3434 + name = async (): Promise<string> => { 3435 + if (this._name) { 3436 + return this._name; 3437 + } 3438 + 3439 + const response: Awaited<string> = await computeQuery( 3440 + [ 3441 + ...this._queryTree, 3442 + { 3443 + operation: "name", 3444 + }, 3445 + ], 3446 + await this._ctx.connection() 3447 + ); 3448 + 3449 + return response; 3450 + }; 3451 + 3452 + /** 3453 + * Retrieves the size of the file, in bytes. 3454 + */ 3455 + size = async (): Promise<number> => { 3456 + if (this._size) { 3457 + return this._size; 3458 + } 3459 + 3460 + const response: Awaited<number> = await computeQuery( 3461 + [ 3462 + ...this._queryTree, 3463 + { 3464 + operation: "size", 3465 + }, 3466 + ], 3467 + await this._ctx.connection() 3468 + ); 3469 + 3470 + return response; 3471 + }; 3472 + 3473 + /** 3474 + * Force evaluation in the engine. 3475 + */ 3476 + sync = async (): Promise<File> => { 3477 + await computeQuery( 3478 + [ 3479 + ...this._queryTree, 3480 + { 3481 + operation: "sync", 3482 + }, 3483 + ], 3484 + await this._ctx.connection() 3485 + ); 3486 + 3487 + return this; 3488 + }; 3489 + 3490 + /** 3491 + * Retrieves this file with its created/modified timestamps set to the given time. 3492 + * @param timestamp Timestamp to set dir/files in. 3493 + * 3494 + * Formatted in seconds following Unix epoch (e.g., 1672531199). 3495 + */ 3496 + withTimestamps = (timestamp: number): File => { 3497 + return new File({ 3498 + queryTree: [ 3499 + ...this._queryTree, 3500 + { 3501 + operation: "withTimestamps", 3502 + args: { timestamp }, 3503 + }, 3504 + ], 3505 + ctx: this._ctx, 3506 + }); 3507 + }; 3508 + 3509 + /** 3510 + * Call the provided function with current File. 3511 + * 3512 + * This is useful for reusability and readability by not breaking the calling chain. 3513 + */ 3514 + with = (arg: (param: File) => File) => { 3515 + return arg(this); 3516 + }; 3517 + } 3518 + 3519 + /** 3520 + * Function represents a resolver provided by a Module. 3521 + * 3522 + * A function always evaluates against a parent object and is given a set of named arguments. 3523 + */ 3524 + export class Function_ extends BaseClient { 3525 + private readonly _id?: FunctionID = undefined; 3526 + private readonly _description?: string = undefined; 3527 + private readonly _name?: string = undefined; 3528 + 3529 + /** 3530 + * Constructor is used for internal usage only, do not create object from it. 3531 + */ 3532 + constructor( 3533 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3534 + _id?: FunctionID, 3535 + _description?: string, 3536 + _name?: string 3537 + ) { 3538 + super(parent); 3539 + 3540 + this._id = _id; 3541 + this._description = _description; 3542 + this._name = _name; 3543 + } 3544 + 3545 + /** 3546 + * A unique identifier for this Function. 3547 + */ 3548 + id = async (): Promise<FunctionID> => { 3549 + if (this._id) { 3550 + return this._id; 3551 + } 3552 + 3553 + const response: Awaited<FunctionID> = await computeQuery( 3554 + [ 3555 + ...this._queryTree, 3556 + { 3557 + operation: "id", 3558 + }, 3559 + ], 3560 + await this._ctx.connection() 3561 + ); 3562 + 3563 + return response; 3564 + }; 3565 + 3566 + /** 3567 + * Arguments accepted by the function, if any. 3568 + */ 3569 + args = async (): Promise<FunctionArg[]> => { 3570 + type args = { 3571 + id: FunctionArgID; 3572 + }; 3573 + 3574 + const response: Awaited<args[]> = await computeQuery( 3575 + [ 3576 + ...this._queryTree, 3577 + { 3578 + operation: "args", 3579 + }, 3580 + { 3581 + operation: "id", 3582 + }, 3583 + ], 3584 + await this._ctx.connection() 3585 + ); 3586 + 3587 + return response.map( 3588 + (r) => 3589 + new FunctionArg( 3590 + { 3591 + queryTree: [ 3592 + { 3593 + operation: "loadFunctionArgFromID", 3594 + args: { id: r.id }, 3595 + }, 3596 + ], 3597 + ctx: this._ctx, 3598 + }, 3599 + r.id 3600 + ) 3601 + ); 3602 + }; 3603 + 3604 + /** 3605 + * A doc string for the function, if any. 3606 + */ 3607 + description = async (): Promise<string> => { 3608 + if (this._description) { 3609 + return this._description; 3610 + } 3611 + 3612 + const response: Awaited<string> = await computeQuery( 3613 + [ 3614 + ...this._queryTree, 3615 + { 3616 + operation: "description", 3617 + }, 3618 + ], 3619 + await this._ctx.connection() 3620 + ); 3621 + 3622 + return response; 3623 + }; 3624 + 3625 + /** 3626 + * The name of the function. 3627 + */ 3628 + name = async (): Promise<string> => { 3629 + if (this._name) { 3630 + return this._name; 3631 + } 3632 + 3633 + const response: Awaited<string> = await computeQuery( 3634 + [ 3635 + ...this._queryTree, 3636 + { 3637 + operation: "name", 3638 + }, 3639 + ], 3640 + await this._ctx.connection() 3641 + ); 3642 + 3643 + return response; 3644 + }; 3645 + 3646 + /** 3647 + * The type returned by the function. 3648 + */ 3649 + returnType = (): TypeDef => { 3650 + return new TypeDef({ 3651 + queryTree: [ 3652 + ...this._queryTree, 3653 + { 3654 + operation: "returnType", 3655 + }, 3656 + ], 3657 + ctx: this._ctx, 3658 + }); 3659 + }; 3660 + 3661 + /** 3662 + * Returns the function with the provided argument 3663 + * @param name The name of the argument 3664 + * @param typeDef The type of the argument 3665 + * @param opts.description A doc string for the argument, if any 3666 + * @param opts.defaultValue A default value to use for this argument if not explicitly set by the caller, if any 3667 + */ 3668 + withArg = ( 3669 + name: string, 3670 + typeDef: TypeDef, 3671 + opts?: FunctionWithArgOpts 3672 + ): Function_ => { 3673 + return new Function_({ 3674 + queryTree: [ 3675 + ...this._queryTree, 3676 + { 3677 + operation: "withArg", 3678 + args: { name, typeDef, ...opts }, 3679 + }, 3680 + ], 3681 + ctx: this._ctx, 3682 + }); 3683 + }; 3684 + 3685 + /** 3686 + * Returns the function with the given doc string. 3687 + * @param description The doc string to set. 3688 + */ 3689 + withDescription = (description: string): Function_ => { 3690 + return new Function_({ 3691 + queryTree: [ 3692 + ...this._queryTree, 3693 + { 3694 + operation: "withDescription", 3695 + args: { description }, 3696 + }, 3697 + ], 3698 + ctx: this._ctx, 3699 + }); 3700 + }; 3701 + 3702 + /** 3703 + * Call the provided function with current Function. 3704 + * 3705 + * This is useful for reusability and readability by not breaking the calling chain. 3706 + */ 3707 + with = (arg: (param: Function_) => Function_) => { 3708 + return arg(this); 3709 + }; 3710 + } 3711 + 3712 + /** 3713 + * An argument accepted by a function. 3714 + * 3715 + * This is a specification for an argument at function definition time, not an argument passed at function call time. 3716 + */ 3717 + export class FunctionArg extends BaseClient { 3718 + private readonly _id?: FunctionArgID = undefined; 3719 + private readonly _defaultValue?: JSON = undefined; 3720 + private readonly _description?: string = undefined; 3721 + private readonly _name?: string = undefined; 3722 + 3723 + /** 3724 + * Constructor is used for internal usage only, do not create object from it. 3725 + */ 3726 + constructor( 3727 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3728 + _id?: FunctionArgID, 3729 + _defaultValue?: JSON, 3730 + _description?: string, 3731 + _name?: string 3732 + ) { 3733 + super(parent); 3734 + 3735 + this._id = _id; 3736 + this._defaultValue = _defaultValue; 3737 + this._description = _description; 3738 + this._name = _name; 3739 + } 3740 + 3741 + /** 3742 + * A unique identifier for this FunctionArg. 3743 + */ 3744 + id = async (): Promise<FunctionArgID> => { 3745 + if (this._id) { 3746 + return this._id; 3747 + } 3748 + 3749 + const response: Awaited<FunctionArgID> = await computeQuery( 3750 + [ 3751 + ...this._queryTree, 3752 + { 3753 + operation: "id", 3754 + }, 3755 + ], 3756 + await this._ctx.connection() 3757 + ); 3758 + 3759 + return response; 3760 + }; 3761 + 3762 + /** 3763 + * A default value to use for this argument when not explicitly set by the caller, if any. 3764 + */ 3765 + defaultValue = async (): Promise<JSON> => { 3766 + if (this._defaultValue) { 3767 + return this._defaultValue; 3768 + } 3769 + 3770 + const response: Awaited<JSON> = await computeQuery( 3771 + [ 3772 + ...this._queryTree, 3773 + { 3774 + operation: "defaultValue", 3775 + }, 3776 + ], 3777 + await this._ctx.connection() 3778 + ); 3779 + 3780 + return response; 3781 + }; 3782 + 3783 + /** 3784 + * A doc string for the argument, if any. 3785 + */ 3786 + description = async (): Promise<string> => { 3787 + if (this._description) { 3788 + return this._description; 3789 + } 3790 + 3791 + const response: Awaited<string> = await computeQuery( 3792 + [ 3793 + ...this._queryTree, 3794 + { 3795 + operation: "description", 3796 + }, 3797 + ], 3798 + await this._ctx.connection() 3799 + ); 3800 + 3801 + return response; 3802 + }; 3803 + 3804 + /** 3805 + * The name of the argument in lowerCamelCase format. 3806 + */ 3807 + name = async (): Promise<string> => { 3808 + if (this._name) { 3809 + return this._name; 3810 + } 3811 + 3812 + const response: Awaited<string> = await computeQuery( 3813 + [ 3814 + ...this._queryTree, 3815 + { 3816 + operation: "name", 3817 + }, 3818 + ], 3819 + await this._ctx.connection() 3820 + ); 3821 + 3822 + return response; 3823 + }; 3824 + 3825 + /** 3826 + * The type of the argument. 3827 + */ 3828 + typeDef = (): TypeDef => { 3829 + return new TypeDef({ 3830 + queryTree: [ 3831 + ...this._queryTree, 3832 + { 3833 + operation: "typeDef", 3834 + }, 3835 + ], 3836 + ctx: this._ctx, 3837 + }); 3838 + }; 3839 + } 3840 + 3841 + /** 3842 + * An active function call. 3843 + */ 3844 + export class FunctionCall extends BaseClient { 3845 + private readonly _id?: FunctionCallID = undefined; 3846 + private readonly _name?: string = undefined; 3847 + private readonly _parent?: JSON = undefined; 3848 + private readonly _parentName?: string = undefined; 3849 + private readonly _returnValue?: Void = undefined; 3850 + 3851 + /** 3852 + * Constructor is used for internal usage only, do not create object from it. 3853 + */ 3854 + constructor( 3855 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 3856 + _id?: FunctionCallID, 3857 + _name?: string, 3858 + _parent?: JSON, 3859 + _parentName?: string, 3860 + _returnValue?: Void 3861 + ) { 3862 + super(parent); 3863 + 3864 + this._id = _id; 3865 + this._name = _name; 3866 + this._parent = _parent; 3867 + this._parentName = _parentName; 3868 + this._returnValue = _returnValue; 3869 + } 3870 + 3871 + /** 3872 + * A unique identifier for this FunctionCall. 3873 + */ 3874 + id = async (): Promise<FunctionCallID> => { 3875 + if (this._id) { 3876 + return this._id; 3877 + } 3878 + 3879 + const response: Awaited<FunctionCallID> = await computeQuery( 3880 + [ 3881 + ...this._queryTree, 3882 + { 3883 + operation: "id", 3884 + }, 3885 + ], 3886 + await this._ctx.connection() 3887 + ); 3888 + 3889 + return response; 3890 + }; 3891 + 3892 + /** 3893 + * The argument values the function is being invoked with. 3894 + */ 3895 + inputArgs = async (): Promise<FunctionCallArgValue[]> => { 3896 + type inputArgs = { 3897 + id: FunctionCallArgValueID; 3898 + }; 3899 + 3900 + const response: Awaited<inputArgs[]> = await computeQuery( 3901 + [ 3902 + ...this._queryTree, 3903 + { 3904 + operation: "inputArgs", 3905 + }, 3906 + { 3907 + operation: "id", 3908 + }, 3909 + ], 3910 + await this._ctx.connection() 3911 + ); 3912 + 3913 + return response.map( 3914 + (r) => 3915 + new FunctionCallArgValue( 3916 + { 3917 + queryTree: [ 3918 + { 3919 + operation: "loadFunctionCallArgValueFromID", 3920 + args: { id: r.id }, 3921 + }, 3922 + ], 3923 + ctx: this._ctx, 3924 + }, 3925 + r.id 3926 + ) 3927 + ); 3928 + }; 3929 + 3930 + /** 3931 + * The name of the function being called. 3932 + */ 3933 + name = async (): Promise<string> => { 3934 + if (this._name) { 3935 + return this._name; 3936 + } 3937 + 3938 + const response: Awaited<string> = await computeQuery( 3939 + [ 3940 + ...this._queryTree, 3941 + { 3942 + operation: "name", 3943 + }, 3944 + ], 3945 + await this._ctx.connection() 3946 + ); 3947 + 3948 + return response; 3949 + }; 3950 + 3951 + /** 3952 + * The value of the parent object of the function being called. If the function is top-level to the module, this is always an empty object. 3953 + */ 3954 + parent = async (): Promise<JSON> => { 3955 + if (this._parent) { 3956 + return this._parent; 3957 + } 3958 + 3959 + const response: Awaited<JSON> = await computeQuery( 3960 + [ 3961 + ...this._queryTree, 3962 + { 3963 + operation: "parent", 3964 + }, 3965 + ], 3966 + await this._ctx.connection() 3967 + ); 3968 + 3969 + return response; 3970 + }; 3971 + 3972 + /** 3973 + * The name of the parent object of the function being called. If the function is top-level to the module, this is the name of the module. 3974 + */ 3975 + parentName = async (): Promise<string> => { 3976 + if (this._parentName) { 3977 + return this._parentName; 3978 + } 3979 + 3980 + const response: Awaited<string> = await computeQuery( 3981 + [ 3982 + ...this._queryTree, 3983 + { 3984 + operation: "parentName", 3985 + }, 3986 + ], 3987 + await this._ctx.connection() 3988 + ); 3989 + 3990 + return response; 3991 + }; 3992 + 3993 + /** 3994 + * Set the return value of the function call to the provided value. 3995 + * @param value JSON serialization of the return value. 3996 + */ 3997 + returnValue = async (value: JSON): Promise<Void> => { 3998 + if (this._returnValue) { 3999 + return this._returnValue; 4000 + } 4001 + 4002 + const response: Awaited<Void> = await computeQuery( 4003 + [ 4004 + ...this._queryTree, 4005 + { 4006 + operation: "returnValue", 4007 + args: { value }, 4008 + }, 4009 + ], 4010 + await this._ctx.connection() 4011 + ); 4012 + 4013 + return response; 4014 + }; 4015 + } 4016 + 4017 + /** 4018 + * A value passed as a named argument to a function call. 4019 + */ 4020 + export class FunctionCallArgValue extends BaseClient { 4021 + private readonly _id?: FunctionCallArgValueID = undefined; 4022 + private readonly _name?: string = undefined; 4023 + private readonly _value?: JSON = undefined; 4024 + 4025 + /** 4026 + * Constructor is used for internal usage only, do not create object from it. 4027 + */ 4028 + constructor( 4029 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4030 + _id?: FunctionCallArgValueID, 4031 + _name?: string, 4032 + _value?: JSON 4033 + ) { 4034 + super(parent); 4035 + 4036 + this._id = _id; 4037 + this._name = _name; 4038 + this._value = _value; 4039 + } 4040 + 4041 + /** 4042 + * A unique identifier for this FunctionCallArgValue. 4043 + */ 4044 + id = async (): Promise<FunctionCallArgValueID> => { 4045 + if (this._id) { 4046 + return this._id; 4047 + } 4048 + 4049 + const response: Awaited<FunctionCallArgValueID> = await computeQuery( 4050 + [ 4051 + ...this._queryTree, 4052 + { 4053 + operation: "id", 4054 + }, 4055 + ], 4056 + await this._ctx.connection() 4057 + ); 4058 + 4059 + return response; 4060 + }; 4061 + 4062 + /** 4063 + * The name of the argument. 4064 + */ 4065 + name = async (): Promise<string> => { 4066 + if (this._name) { 4067 + return this._name; 4068 + } 4069 + 4070 + const response: Awaited<string> = await computeQuery( 4071 + [ 4072 + ...this._queryTree, 4073 + { 4074 + operation: "name", 4075 + }, 4076 + ], 4077 + await this._ctx.connection() 4078 + ); 4079 + 4080 + return response; 4081 + }; 4082 + 4083 + /** 4084 + * The value of the argument represented as a JSON serialized string. 4085 + */ 4086 + value = async (): Promise<JSON> => { 4087 + if (this._value) { 4088 + return this._value; 4089 + } 4090 + 4091 + const response: Awaited<JSON> = await computeQuery( 4092 + [ 4093 + ...this._queryTree, 4094 + { 4095 + operation: "value", 4096 + }, 4097 + ], 4098 + await this._ctx.connection() 4099 + ); 4100 + 4101 + return response; 4102 + }; 4103 + } 4104 + 4105 + /** 4106 + * The result of running an SDK's codegen. 4107 + */ 4108 + export class GeneratedCode extends BaseClient { 4109 + private readonly _id?: GeneratedCodeID = undefined; 4110 + 4111 + /** 4112 + * Constructor is used for internal usage only, do not create object from it. 4113 + */ 4114 + constructor( 4115 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4116 + _id?: GeneratedCodeID 4117 + ) { 4118 + super(parent); 4119 + 4120 + this._id = _id; 4121 + } 4122 + 4123 + /** 4124 + * A unique identifier for this GeneratedCode. 4125 + */ 4126 + id = async (): Promise<GeneratedCodeID> => { 4127 + if (this._id) { 4128 + return this._id; 4129 + } 4130 + 4131 + const response: Awaited<GeneratedCodeID> = await computeQuery( 4132 + [ 4133 + ...this._queryTree, 4134 + { 4135 + operation: "id", 4136 + }, 4137 + ], 4138 + await this._ctx.connection() 4139 + ); 4140 + 4141 + return response; 4142 + }; 4143 + 4144 + /** 4145 + * The directory containing the generated code. 4146 + */ 4147 + code = (): Directory => { 4148 + return new Directory({ 4149 + queryTree: [ 4150 + ...this._queryTree, 4151 + { 4152 + operation: "code", 4153 + }, 4154 + ], 4155 + ctx: this._ctx, 4156 + }); 4157 + }; 4158 + 4159 + /** 4160 + * List of paths to mark generated in version control (i.e. .gitattributes). 4161 + */ 4162 + vcsGeneratedPaths = async (): Promise<string[]> => { 4163 + const response: Awaited<string[]> = await computeQuery( 4164 + [ 4165 + ...this._queryTree, 4166 + { 4167 + operation: "vcsGeneratedPaths", 4168 + }, 4169 + ], 4170 + await this._ctx.connection() 4171 + ); 4172 + 4173 + return response; 4174 + }; 4175 + 4176 + /** 4177 + * List of paths to ignore in version control (i.e. .gitignore). 4178 + */ 4179 + vcsIgnoredPaths = async (): Promise<string[]> => { 4180 + const response: Awaited<string[]> = await computeQuery( 4181 + [ 4182 + ...this._queryTree, 4183 + { 4184 + operation: "vcsIgnoredPaths", 4185 + }, 4186 + ], 4187 + await this._ctx.connection() 4188 + ); 4189 + 4190 + return response; 4191 + }; 4192 + 4193 + /** 4194 + * Set the list of paths to mark generated in version control. 4195 + */ 4196 + withVCSGeneratedPaths = (paths: string[]): GeneratedCode => { 4197 + return new GeneratedCode({ 4198 + queryTree: [ 4199 + ...this._queryTree, 4200 + { 4201 + operation: "withVCSGeneratedPaths", 4202 + args: { paths }, 4203 + }, 4204 + ], 4205 + ctx: this._ctx, 4206 + }); 4207 + }; 4208 + 4209 + /** 4210 + * Set the list of paths to ignore in version control. 4211 + */ 4212 + withVCSIgnoredPaths = (paths: string[]): GeneratedCode => { 4213 + return new GeneratedCode({ 4214 + queryTree: [ 4215 + ...this._queryTree, 4216 + { 4217 + operation: "withVCSIgnoredPaths", 4218 + args: { paths }, 4219 + }, 4220 + ], 4221 + ctx: this._ctx, 4222 + }); 4223 + }; 4224 + 4225 + /** 4226 + * Call the provided function with current GeneratedCode. 4227 + * 4228 + * This is useful for reusability and readability by not breaking the calling chain. 4229 + */ 4230 + with = (arg: (param: GeneratedCode) => GeneratedCode) => { 4231 + return arg(this); 4232 + }; 4233 + } 4234 + 4235 + /** 4236 + * Module source originating from a git repo. 4237 + */ 4238 + export class GitModuleSource extends BaseClient { 4239 + private readonly _id?: GitModuleSourceID = undefined; 4240 + private readonly _cloneURL?: string = undefined; 4241 + private readonly _commit?: string = undefined; 4242 + private readonly _htmlURL?: string = undefined; 4243 + private readonly _rootSubpath?: string = undefined; 4244 + private readonly _version?: string = undefined; 4245 + 4246 + /** 4247 + * Constructor is used for internal usage only, do not create object from it. 4248 + */ 4249 + constructor( 4250 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4251 + _id?: GitModuleSourceID, 4252 + _cloneURL?: string, 4253 + _commit?: string, 4254 + _htmlURL?: string, 4255 + _rootSubpath?: string, 4256 + _version?: string 4257 + ) { 4258 + super(parent); 4259 + 4260 + this._id = _id; 4261 + this._cloneURL = _cloneURL; 4262 + this._commit = _commit; 4263 + this._htmlURL = _htmlURL; 4264 + this._rootSubpath = _rootSubpath; 4265 + this._version = _version; 4266 + } 4267 + 4268 + /** 4269 + * A unique identifier for this GitModuleSource. 4270 + */ 4271 + id = async (): Promise<GitModuleSourceID> => { 4272 + if (this._id) { 4273 + return this._id; 4274 + } 4275 + 4276 + const response: Awaited<GitModuleSourceID> = await computeQuery( 4277 + [ 4278 + ...this._queryTree, 4279 + { 4280 + operation: "id", 4281 + }, 4282 + ], 4283 + await this._ctx.connection() 4284 + ); 4285 + 4286 + return response; 4287 + }; 4288 + 4289 + /** 4290 + * The URL from which the source's git repo can be cloned. 4291 + */ 4292 + cloneURL = async (): Promise<string> => { 4293 + if (this._cloneURL) { 4294 + return this._cloneURL; 4295 + } 4296 + 4297 + const response: Awaited<string> = await computeQuery( 4298 + [ 4299 + ...this._queryTree, 4300 + { 4301 + operation: "cloneURL", 4302 + }, 4303 + ], 4304 + await this._ctx.connection() 4305 + ); 4306 + 4307 + return response; 4308 + }; 4309 + 4310 + /** 4311 + * The resolved commit of the git repo this source points to. 4312 + */ 4313 + commit = async (): Promise<string> => { 4314 + if (this._commit) { 4315 + return this._commit; 4316 + } 4317 + 4318 + const response: Awaited<string> = await computeQuery( 4319 + [ 4320 + ...this._queryTree, 4321 + { 4322 + operation: "commit", 4323 + }, 4324 + ], 4325 + await this._ctx.connection() 4326 + ); 4327 + 4328 + return response; 4329 + }; 4330 + 4331 + /** 4332 + * The directory containing everything needed to load load and use the module. 4333 + */ 4334 + contextDirectory = (): Directory => { 4335 + return new Directory({ 4336 + queryTree: [ 4337 + ...this._queryTree, 4338 + { 4339 + operation: "contextDirectory", 4340 + }, 4341 + ], 4342 + ctx: this._ctx, 4343 + }); 4344 + }; 4345 + 4346 + /** 4347 + * The URL to the source's git repo in a web browser 4348 + */ 4349 + htmlURL = async (): Promise<string> => { 4350 + if (this._htmlURL) { 4351 + return this._htmlURL; 4352 + } 4353 + 4354 + const response: Awaited<string> = await computeQuery( 4355 + [ 4356 + ...this._queryTree, 4357 + { 4358 + operation: "htmlURL", 4359 + }, 4360 + ], 4361 + await this._ctx.connection() 4362 + ); 4363 + 4364 + return response; 4365 + }; 4366 + 4367 + /** 4368 + * The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). 4369 + */ 4370 + rootSubpath = async (): Promise<string> => { 4371 + if (this._rootSubpath) { 4372 + return this._rootSubpath; 4373 + } 4374 + 4375 + const response: Awaited<string> = await computeQuery( 4376 + [ 4377 + ...this._queryTree, 4378 + { 4379 + operation: "rootSubpath", 4380 + }, 4381 + ], 4382 + await this._ctx.connection() 4383 + ); 4384 + 4385 + return response; 4386 + }; 4387 + 4388 + /** 4389 + * The specified version of the git repo this source points to. 4390 + */ 4391 + version = async (): Promise<string> => { 4392 + if (this._version) { 4393 + return this._version; 4394 + } 4395 + 4396 + const response: Awaited<string> = await computeQuery( 4397 + [ 4398 + ...this._queryTree, 4399 + { 4400 + operation: "version", 4401 + }, 4402 + ], 4403 + await this._ctx.connection() 4404 + ); 4405 + 4406 + return response; 4407 + }; 4408 + } 4409 + 4410 + /** 4411 + * A git ref (tag, branch, or commit). 4412 + */ 4413 + export class GitRef extends BaseClient { 4414 + private readonly _id?: GitRefID = undefined; 4415 + private readonly _commit?: string = undefined; 4416 + 4417 + /** 4418 + * Constructor is used for internal usage only, do not create object from it. 4419 + */ 4420 + constructor( 4421 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4422 + _id?: GitRefID, 4423 + _commit?: string 4424 + ) { 4425 + super(parent); 4426 + 4427 + this._id = _id; 4428 + this._commit = _commit; 4429 + } 4430 + 4431 + /** 4432 + * A unique identifier for this GitRef. 4433 + */ 4434 + id = async (): Promise<GitRefID> => { 4435 + if (this._id) { 4436 + return this._id; 4437 + } 4438 + 4439 + const response: Awaited<GitRefID> = await computeQuery( 4440 + [ 4441 + ...this._queryTree, 4442 + { 4443 + operation: "id", 4444 + }, 4445 + ], 4446 + await this._ctx.connection() 4447 + ); 4448 + 4449 + return response; 4450 + }; 4451 + 4452 + /** 4453 + * The resolved commit id at this ref. 4454 + */ 4455 + commit = async (): Promise<string> => { 4456 + if (this._commit) { 4457 + return this._commit; 4458 + } 4459 + 4460 + const response: Awaited<string> = await computeQuery( 4461 + [ 4462 + ...this._queryTree, 4463 + { 4464 + operation: "commit", 4465 + }, 4466 + ], 4467 + await this._ctx.connection() 4468 + ); 4469 + 4470 + return response; 4471 + }; 4472 + 4473 + /** 4474 + * The filesystem tree at this ref. 4475 + * @param opts.sshKnownHosts DEPRECATED: This option should be passed to `git` instead. 4476 + * @param opts.sshAuthSocket DEPRECATED: This option should be passed to `git` instead. 4477 + */ 4478 + tree = (opts?: GitRefTreeOpts): Directory => { 4479 + return new Directory({ 4480 + queryTree: [ 4481 + ...this._queryTree, 4482 + { 4483 + operation: "tree", 4484 + args: { ...opts }, 4485 + }, 4486 + ], 4487 + ctx: this._ctx, 4488 + }); 4489 + }; 4490 + } 4491 + 4492 + /** 4493 + * A git repository. 4494 + */ 4495 + export class GitRepository extends BaseClient { 4496 + private readonly _id?: GitRepositoryID = undefined; 4497 + 4498 + /** 4499 + * Constructor is used for internal usage only, do not create object from it. 4500 + */ 4501 + constructor( 4502 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4503 + _id?: GitRepositoryID 4504 + ) { 4505 + super(parent); 4506 + 4507 + this._id = _id; 4508 + } 4509 + 4510 + /** 4511 + * A unique identifier for this GitRepository. 4512 + */ 4513 + id = async (): Promise<GitRepositoryID> => { 4514 + if (this._id) { 4515 + return this._id; 4516 + } 4517 + 4518 + const response: Awaited<GitRepositoryID> = await computeQuery( 4519 + [ 4520 + ...this._queryTree, 4521 + { 4522 + operation: "id", 4523 + }, 4524 + ], 4525 + await this._ctx.connection() 4526 + ); 4527 + 4528 + return response; 4529 + }; 4530 + 4531 + /** 4532 + * Returns details of a branch. 4533 + * @param name Branch's name (e.g., "main"). 4534 + */ 4535 + branch = (name: string): GitRef => { 4536 + return new GitRef({ 4537 + queryTree: [ 4538 + ...this._queryTree, 4539 + { 4540 + operation: "branch", 4541 + args: { name }, 4542 + }, 4543 + ], 4544 + ctx: this._ctx, 4545 + }); 4546 + }; 4547 + 4548 + /** 4549 + * Returns details of a commit. 4550 + * @param id Identifier of the commit (e.g., "b6315d8f2810962c601af73f86831f6866ea798b"). 4551 + */ 4552 + commit = (id: string): GitRef => { 4553 + return new GitRef({ 4554 + queryTree: [ 4555 + ...this._queryTree, 4556 + { 4557 + operation: "commit", 4558 + args: { id }, 4559 + }, 4560 + ], 4561 + ctx: this._ctx, 4562 + }); 4563 + }; 4564 + 4565 + /** 4566 + * Returns details of a ref. 4567 + * @param name Ref's name (can be a commit identifier, a tag name, a branch name, or a fully-qualified ref). 4568 + */ 4569 + ref = (name: string): GitRef => { 4570 + return new GitRef({ 4571 + queryTree: [ 4572 + ...this._queryTree, 4573 + { 4574 + operation: "ref", 4575 + args: { name }, 4576 + }, 4577 + ], 4578 + ctx: this._ctx, 4579 + }); 4580 + }; 4581 + 4582 + /** 4583 + * Returns details of a tag. 4584 + * @param name Tag's name (e.g., "v0.3.9"). 4585 + */ 4586 + tag = (name: string): GitRef => { 4587 + return new GitRef({ 4588 + queryTree: [ 4589 + ...this._queryTree, 4590 + { 4591 + operation: "tag", 4592 + args: { name }, 4593 + }, 4594 + ], 4595 + ctx: this._ctx, 4596 + }); 4597 + }; 4598 + } 4599 + 4600 + /** 4601 + * Information about the host environment. 4602 + */ 4603 + export class Host extends BaseClient { 4604 + private readonly _id?: HostID = undefined; 4605 + 4606 + /** 4607 + * Constructor is used for internal usage only, do not create object from it. 4608 + */ 4609 + constructor( 4610 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4611 + _id?: HostID 4612 + ) { 4613 + super(parent); 4614 + 4615 + this._id = _id; 4616 + } 4617 + 4618 + /** 4619 + * A unique identifier for this Host. 4620 + */ 4621 + id = async (): Promise<HostID> => { 4622 + if (this._id) { 4623 + return this._id; 4624 + } 4625 + 4626 + const response: Awaited<HostID> = await computeQuery( 4627 + [ 4628 + ...this._queryTree, 4629 + { 4630 + operation: "id", 4631 + }, 4632 + ], 4633 + await this._ctx.connection() 4634 + ); 4635 + 4636 + return response; 4637 + }; 4638 + 4639 + /** 4640 + * Accesses a directory on the host. 4641 + * @param path Location of the directory to access (e.g., "."). 4642 + * @param opts.exclude Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]). 4643 + * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). 4644 + */ 4645 + directory = (path: string, opts?: HostDirectoryOpts): Directory => { 4646 + return new Directory({ 4647 + queryTree: [ 4648 + ...this._queryTree, 4649 + { 4650 + operation: "directory", 4651 + args: { path, ...opts }, 4652 + }, 4653 + ], 4654 + ctx: this._ctx, 4655 + }); 4656 + }; 4657 + 4658 + /** 4659 + * Accesses a file on the host. 4660 + * @param path Location of the file to retrieve (e.g., "README.md"). 4661 + */ 4662 + file = (path: string): File => { 4663 + return new File({ 4664 + queryTree: [ 4665 + ...this._queryTree, 4666 + { 4667 + operation: "file", 4668 + args: { path }, 4669 + }, 4670 + ], 4671 + ctx: this._ctx, 4672 + }); 4673 + }; 4674 + 4675 + /** 4676 + * Creates a service that forwards traffic to a specified address via the host. 4677 + * @param opts.host Upstream host to forward traffic to. 4678 + * @param opts.ports Ports to expose via the service, forwarding through the host network. 4679 + * 4680 + * If a port's frontend is unspecified or 0, it defaults to the same as the backend port. 4681 + * 4682 + * An empty set of ports is not valid; an error will be returned. 4683 + */ 4684 + service = (opts?: HostServiceOpts): Service => { 4685 + return new Service({ 4686 + queryTree: [ 4687 + ...this._queryTree, 4688 + { 4689 + operation: "service", 4690 + args: { ...opts }, 4691 + }, 4692 + ], 4693 + ctx: this._ctx, 4694 + }); 4695 + }; 4696 + 4697 + /** 4698 + * Sets a secret given a user-defined name and the file path on the host, and returns the secret. 4699 + * 4700 + * The file is limited to a size of 512000 bytes. 4701 + * @param name The user defined name for this secret. 4702 + * @param path Location of the file to set as a secret. 4703 + */ 4704 + setSecretFile = (name: string, path: string): Secret => { 4705 + return new Secret({ 4706 + queryTree: [ 4707 + ...this._queryTree, 4708 + { 4709 + operation: "setSecretFile", 4710 + args: { name, path }, 4711 + }, 4712 + ], 4713 + ctx: this._ctx, 4714 + }); 4715 + }; 4716 + 4717 + /** 4718 + * Creates a tunnel that forwards traffic from the host to a service. 4719 + * @param service Service to send traffic from the tunnel. 4720 + * @param opts.ports Configure explicit port forwarding rules for the tunnel. 4721 + * 4722 + * If a port's frontend is unspecified or 0, a random port will be chosen by the host. 4723 + * 4724 + * If no ports are given, all of the service's ports are forwarded. If native is true, each port maps to the same port on the host. If native is false, each port maps to a random port chosen by the host. 4725 + * 4726 + * If ports are given and native is true, the ports are additive. 4727 + * @param opts.native Map each service port to the same port on the host, as if the service were running natively. 4728 + * 4729 + * Note: enabling may result in port conflicts. 4730 + */ 4731 + tunnel = (service: Service, opts?: HostTunnelOpts): Service => { 4732 + return new Service({ 4733 + queryTree: [ 4734 + ...this._queryTree, 4735 + { 4736 + operation: "tunnel", 4737 + args: { service, ...opts }, 4738 + }, 4739 + ], 4740 + ctx: this._ctx, 4741 + }); 4742 + }; 4743 + 4744 + /** 4745 + * Accesses a Unix socket on the host. 4746 + * @param path Location of the Unix socket (e.g., "/var/run/docker.sock"). 4747 + */ 4748 + unixSocket = (path: string): Socket => { 4749 + return new Socket({ 4750 + queryTree: [ 4751 + ...this._queryTree, 4752 + { 4753 + operation: "unixSocket", 4754 + args: { path }, 4755 + }, 4756 + ], 4757 + ctx: this._ctx, 4758 + }); 4759 + }; 4760 + } 4761 + 4762 + /** 4763 + * A graphql input type, which is essentially just a group of named args. 4764 + * This is currently only used to represent pre-existing usage of graphql input types 4765 + * in the core API. It is not used by user modules and shouldn't ever be as user 4766 + * module accept input objects via their id rather than graphql input types. 4767 + */ 4768 + export class InputTypeDef extends BaseClient { 4769 + private readonly _id?: InputTypeDefID = undefined; 4770 + private readonly _name?: string = undefined; 4771 + 4772 + /** 4773 + * Constructor is used for internal usage only, do not create object from it. 4774 + */ 4775 + constructor( 4776 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4777 + _id?: InputTypeDefID, 4778 + _name?: string 4779 + ) { 4780 + super(parent); 4781 + 4782 + this._id = _id; 4783 + this._name = _name; 4784 + } 4785 + 4786 + /** 4787 + * A unique identifier for this InputTypeDef. 4788 + */ 4789 + id = async (): Promise<InputTypeDefID> => { 4790 + if (this._id) { 4791 + return this._id; 4792 + } 4793 + 4794 + const response: Awaited<InputTypeDefID> = await computeQuery( 4795 + [ 4796 + ...this._queryTree, 4797 + { 4798 + operation: "id", 4799 + }, 4800 + ], 4801 + await this._ctx.connection() 4802 + ); 4803 + 4804 + return response; 4805 + }; 4806 + 4807 + /** 4808 + * Static fields defined on this input object, if any. 4809 + */ 4810 + fields = async (): Promise<FieldTypeDef[]> => { 4811 + type fields = { 4812 + id: FieldTypeDefID; 4813 + }; 4814 + 4815 + const response: Awaited<fields[]> = await computeQuery( 4816 + [ 4817 + ...this._queryTree, 4818 + { 4819 + operation: "fields", 4820 + }, 4821 + { 4822 + operation: "id", 4823 + }, 4824 + ], 4825 + await this._ctx.connection() 4826 + ); 4827 + 4828 + return response.map( 4829 + (r) => 4830 + new FieldTypeDef( 4831 + { 4832 + queryTree: [ 4833 + { 4834 + operation: "loadFieldTypeDefFromID", 4835 + args: { id: r.id }, 4836 + }, 4837 + ], 4838 + ctx: this._ctx, 4839 + }, 4840 + r.id 4841 + ) 4842 + ); 4843 + }; 4844 + 4845 + /** 4846 + * The name of the input object. 4847 + */ 4848 + name = async (): Promise<string> => { 4849 + if (this._name) { 4850 + return this._name; 4851 + } 4852 + 4853 + const response: Awaited<string> = await computeQuery( 4854 + [ 4855 + ...this._queryTree, 4856 + { 4857 + operation: "name", 4858 + }, 4859 + ], 4860 + await this._ctx.connection() 4861 + ); 4862 + 4863 + return response; 4864 + }; 4865 + } 4866 + 4867 + /** 4868 + * A definition of a custom interface defined in a Module. 4869 + */ 4870 + export class InterfaceTypeDef extends BaseClient { 4871 + private readonly _id?: InterfaceTypeDefID = undefined; 4872 + private readonly _description?: string = undefined; 4873 + private readonly _name?: string = undefined; 4874 + private readonly _sourceModuleName?: string = undefined; 4875 + 4876 + /** 4877 + * Constructor is used for internal usage only, do not create object from it. 4878 + */ 4879 + constructor( 4880 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 4881 + _id?: InterfaceTypeDefID, 4882 + _description?: string, 4883 + _name?: string, 4884 + _sourceModuleName?: string 4885 + ) { 4886 + super(parent); 4887 + 4888 + this._id = _id; 4889 + this._description = _description; 4890 + this._name = _name; 4891 + this._sourceModuleName = _sourceModuleName; 4892 + } 4893 + 4894 + /** 4895 + * A unique identifier for this InterfaceTypeDef. 4896 + */ 4897 + id = async (): Promise<InterfaceTypeDefID> => { 4898 + if (this._id) { 4899 + return this._id; 4900 + } 4901 + 4902 + const response: Awaited<InterfaceTypeDefID> = await computeQuery( 4903 + [ 4904 + ...this._queryTree, 4905 + { 4906 + operation: "id", 4907 + }, 4908 + ], 4909 + await this._ctx.connection() 4910 + ); 4911 + 4912 + return response; 4913 + }; 4914 + 4915 + /** 4916 + * The doc string for the interface, if any. 4917 + */ 4918 + description = async (): Promise<string> => { 4919 + if (this._description) { 4920 + return this._description; 4921 + } 4922 + 4923 + const response: Awaited<string> = await computeQuery( 4924 + [ 4925 + ...this._queryTree, 4926 + { 4927 + operation: "description", 4928 + }, 4929 + ], 4930 + await this._ctx.connection() 4931 + ); 4932 + 4933 + return response; 4934 + }; 4935 + 4936 + /** 4937 + * Functions defined on this interface, if any. 4938 + */ 4939 + functions = async (): Promise<Function_[]> => { 4940 + type functions = { 4941 + id: FunctionID; 4942 + }; 4943 + 4944 + const response: Awaited<functions[]> = await computeQuery( 4945 + [ 4946 + ...this._queryTree, 4947 + { 4948 + operation: "functions", 4949 + }, 4950 + { 4951 + operation: "id", 4952 + }, 4953 + ], 4954 + await this._ctx.connection() 4955 + ); 4956 + 4957 + return response.map( 4958 + (r) => 4959 + new Function_( 4960 + { 4961 + queryTree: [ 4962 + { 4963 + operation: "loadFunction_FromID", 4964 + args: { id: r.id }, 4965 + }, 4966 + ], 4967 + ctx: this._ctx, 4968 + }, 4969 + r.id 4970 + ) 4971 + ); 4972 + }; 4973 + 4974 + /** 4975 + * The name of the interface. 4976 + */ 4977 + name = async (): Promise<string> => { 4978 + if (this._name) { 4979 + return this._name; 4980 + } 4981 + 4982 + const response: Awaited<string> = await computeQuery( 4983 + [ 4984 + ...this._queryTree, 4985 + { 4986 + operation: "name", 4987 + }, 4988 + ], 4989 + await this._ctx.connection() 4990 + ); 4991 + 4992 + return response; 4993 + }; 4994 + 4995 + /** 4996 + * If this InterfaceTypeDef is associated with a Module, the name of the module. Unset otherwise. 4997 + */ 4998 + sourceModuleName = async (): Promise<string> => { 4999 + if (this._sourceModuleName) { 5000 + return this._sourceModuleName; 5001 + } 5002 + 5003 + const response: Awaited<string> = await computeQuery( 5004 + [ 5005 + ...this._queryTree, 5006 + { 5007 + operation: "sourceModuleName", 5008 + }, 5009 + ], 5010 + await this._ctx.connection() 5011 + ); 5012 + 5013 + return response; 5014 + }; 5015 + } 5016 + 5017 + /** 5018 + * A simple key value object that represents a label. 5019 + */ 5020 + export class Label extends BaseClient { 5021 + private readonly _id?: LabelID = undefined; 5022 + private readonly _name?: string = undefined; 5023 + private readonly _value?: string = undefined; 5024 + 5025 + /** 5026 + * Constructor is used for internal usage only, do not create object from it. 5027 + */ 5028 + constructor( 5029 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5030 + _id?: LabelID, 5031 + _name?: string, 5032 + _value?: string 5033 + ) { 5034 + super(parent); 5035 + 5036 + this._id = _id; 5037 + this._name = _name; 5038 + this._value = _value; 5039 + } 5040 + 5041 + /** 5042 + * A unique identifier for this Label. 5043 + */ 5044 + id = async (): Promise<LabelID> => { 5045 + if (this._id) { 5046 + return this._id; 5047 + } 5048 + 5049 + const response: Awaited<LabelID> = await computeQuery( 5050 + [ 5051 + ...this._queryTree, 5052 + { 5053 + operation: "id", 5054 + }, 5055 + ], 5056 + await this._ctx.connection() 5057 + ); 5058 + 5059 + return response; 5060 + }; 5061 + 5062 + /** 5063 + * The label name. 5064 + */ 5065 + name = async (): Promise<string> => { 5066 + if (this._name) { 5067 + return this._name; 5068 + } 5069 + 5070 + const response: Awaited<string> = await computeQuery( 5071 + [ 5072 + ...this._queryTree, 5073 + { 5074 + operation: "name", 5075 + }, 5076 + ], 5077 + await this._ctx.connection() 5078 + ); 5079 + 5080 + return response; 5081 + }; 5082 + 5083 + /** 5084 + * The label value. 5085 + */ 5086 + value = async (): Promise<string> => { 5087 + if (this._value) { 5088 + return this._value; 5089 + } 5090 + 5091 + const response: Awaited<string> = await computeQuery( 5092 + [ 5093 + ...this._queryTree, 5094 + { 5095 + operation: "value", 5096 + }, 5097 + ], 5098 + await this._ctx.connection() 5099 + ); 5100 + 5101 + return response; 5102 + }; 5103 + } 5104 + 5105 + /** 5106 + * A definition of a list type in a Module. 5107 + */ 5108 + export class ListTypeDef extends BaseClient { 5109 + private readonly _id?: ListTypeDefID = undefined; 5110 + 5111 + /** 5112 + * Constructor is used for internal usage only, do not create object from it. 5113 + */ 5114 + constructor( 5115 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5116 + _id?: ListTypeDefID 5117 + ) { 5118 + super(parent); 5119 + 5120 + this._id = _id; 5121 + } 5122 + 5123 + /** 5124 + * A unique identifier for this ListTypeDef. 5125 + */ 5126 + id = async (): Promise<ListTypeDefID> => { 5127 + if (this._id) { 5128 + return this._id; 5129 + } 5130 + 5131 + const response: Awaited<ListTypeDefID> = await computeQuery( 5132 + [ 5133 + ...this._queryTree, 5134 + { 5135 + operation: "id", 5136 + }, 5137 + ], 5138 + await this._ctx.connection() 5139 + ); 5140 + 5141 + return response; 5142 + }; 5143 + 5144 + /** 5145 + * The type of the elements in the list. 5146 + */ 5147 + elementTypeDef = (): TypeDef => { 5148 + return new TypeDef({ 5149 + queryTree: [ 5150 + ...this._queryTree, 5151 + { 5152 + operation: "elementTypeDef", 5153 + }, 5154 + ], 5155 + ctx: this._ctx, 5156 + }); 5157 + }; 5158 + } 5159 + 5160 + /** 5161 + * Module source that that originates from a path locally relative to an arbitrary directory. 5162 + */ 5163 + export class LocalModuleSource extends BaseClient { 5164 + private readonly _id?: LocalModuleSourceID = undefined; 5165 + private readonly _rootSubpath?: string = undefined; 5166 + 5167 + /** 5168 + * Constructor is used for internal usage only, do not create object from it. 5169 + */ 5170 + constructor( 5171 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5172 + _id?: LocalModuleSourceID, 5173 + _rootSubpath?: string 5174 + ) { 5175 + super(parent); 5176 + 5177 + this._id = _id; 5178 + this._rootSubpath = _rootSubpath; 5179 + } 5180 + 5181 + /** 5182 + * A unique identifier for this LocalModuleSource. 5183 + */ 5184 + id = async (): Promise<LocalModuleSourceID> => { 5185 + if (this._id) { 5186 + return this._id; 5187 + } 5188 + 5189 + const response: Awaited<LocalModuleSourceID> = await computeQuery( 5190 + [ 5191 + ...this._queryTree, 5192 + { 5193 + operation: "id", 5194 + }, 5195 + ], 5196 + await this._ctx.connection() 5197 + ); 5198 + 5199 + return response; 5200 + }; 5201 + 5202 + /** 5203 + * The directory containing everything needed to load load and use the module. 5204 + */ 5205 + contextDirectory = (): Directory => { 5206 + return new Directory({ 5207 + queryTree: [ 5208 + ...this._queryTree, 5209 + { 5210 + operation: "contextDirectory", 5211 + }, 5212 + ], 5213 + ctx: this._ctx, 5214 + }); 5215 + }; 5216 + 5217 + /** 5218 + * The path to the root of the module source under the context directory. This directory contains its configuration file. It also contains its source code (possibly as a subdirectory). 5219 + */ 5220 + rootSubpath = async (): Promise<string> => { 5221 + if (this._rootSubpath) { 5222 + return this._rootSubpath; 5223 + } 5224 + 5225 + const response: Awaited<string> = await computeQuery( 5226 + [ 5227 + ...this._queryTree, 5228 + { 5229 + operation: "rootSubpath", 5230 + }, 5231 + ], 5232 + await this._ctx.connection() 5233 + ); 5234 + 5235 + return response; 5236 + }; 5237 + } 5238 + 5239 + /** 5240 + * A Dagger module. 5241 + */ 5242 + export class Module_ extends BaseClient { 5243 + private readonly _id?: ModuleID = undefined; 5244 + private readonly _description?: string = undefined; 5245 + private readonly _name?: string = undefined; 5246 + private readonly _sdk?: string = undefined; 5247 + private readonly _serve?: Void = undefined; 5248 + 5249 + /** 5250 + * Constructor is used for internal usage only, do not create object from it. 5251 + */ 5252 + constructor( 5253 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5254 + _id?: ModuleID, 5255 + _description?: string, 5256 + _name?: string, 5257 + _sdk?: string, 5258 + _serve?: Void 5259 + ) { 5260 + super(parent); 5261 + 5262 + this._id = _id; 5263 + this._description = _description; 5264 + this._name = _name; 5265 + this._sdk = _sdk; 5266 + this._serve = _serve; 5267 + } 5268 + 5269 + /** 5270 + * A unique identifier for this Module. 5271 + */ 5272 + id = async (): Promise<ModuleID> => { 5273 + if (this._id) { 5274 + return this._id; 5275 + } 5276 + 5277 + const response: Awaited<ModuleID> = await computeQuery( 5278 + [ 5279 + ...this._queryTree, 5280 + { 5281 + operation: "id", 5282 + }, 5283 + ], 5284 + await this._ctx.connection() 5285 + ); 5286 + 5287 + return response; 5288 + }; 5289 + 5290 + /** 5291 + * Modules used by this module. 5292 + */ 5293 + dependencies = async (): Promise<Module_[]> => { 5294 + type dependencies = { 5295 + id: ModuleID; 5296 + }; 5297 + 5298 + const response: Awaited<dependencies[]> = await computeQuery( 5299 + [ 5300 + ...this._queryTree, 5301 + { 5302 + operation: "dependencies", 5303 + }, 5304 + { 5305 + operation: "id", 5306 + }, 5307 + ], 5308 + await this._ctx.connection() 5309 + ); 5310 + 5311 + return response.map( 5312 + (r) => 5313 + new Module_( 5314 + { 5315 + queryTree: [ 5316 + { 5317 + operation: "loadModule_FromID", 5318 + args: { id: r.id }, 5319 + }, 5320 + ], 5321 + ctx: this._ctx, 5322 + }, 5323 + r.id 5324 + ) 5325 + ); 5326 + }; 5327 + 5328 + /** 5329 + * The dependencies as configured by the module. 5330 + */ 5331 + dependencyConfig = async (): Promise<ModuleDependency[]> => { 5332 + type dependencyConfig = { 5333 + id: ModuleDependencyID; 5334 + }; 5335 + 5336 + const response: Awaited<dependencyConfig[]> = await computeQuery( 5337 + [ 5338 + ...this._queryTree, 5339 + { 5340 + operation: "dependencyConfig", 5341 + }, 5342 + { 5343 + operation: "id", 5344 + }, 5345 + ], 5346 + await this._ctx.connection() 5347 + ); 5348 + 5349 + return response.map( 5350 + (r) => 5351 + new ModuleDependency( 5352 + { 5353 + queryTree: [ 5354 + { 5355 + operation: "loadModuleDependencyFromID", 5356 + args: { id: r.id }, 5357 + }, 5358 + ], 5359 + ctx: this._ctx, 5360 + }, 5361 + r.id 5362 + ) 5363 + ); 5364 + }; 5365 + 5366 + /** 5367 + * The doc string of the module, if any 5368 + */ 5369 + description = async (): Promise<string> => { 5370 + if (this._description) { 5371 + return this._description; 5372 + } 5373 + 5374 + const response: Awaited<string> = await computeQuery( 5375 + [ 5376 + ...this._queryTree, 5377 + { 5378 + operation: "description", 5379 + }, 5380 + ], 5381 + await this._ctx.connection() 5382 + ); 5383 + 5384 + return response; 5385 + }; 5386 + 5387 + /** 5388 + * The generated files and directories made on top of the module source's context directory. 5389 + */ 5390 + generatedContextDiff = (): Directory => { 5391 + return new Directory({ 5392 + queryTree: [ 5393 + ...this._queryTree, 5394 + { 5395 + operation: "generatedContextDiff", 5396 + }, 5397 + ], 5398 + ctx: this._ctx, 5399 + }); 5400 + }; 5401 + 5402 + /** 5403 + * The module source's context plus any configuration and source files created by codegen. 5404 + */ 5405 + generatedContextDirectory = (): Directory => { 5406 + return new Directory({ 5407 + queryTree: [ 5408 + ...this._queryTree, 5409 + { 5410 + operation: "generatedContextDirectory", 5411 + }, 5412 + ], 5413 + ctx: this._ctx, 5414 + }); 5415 + }; 5416 + 5417 + /** 5418 + * Retrieves the module with the objects loaded via its SDK. 5419 + */ 5420 + initialize = (): Module_ => { 5421 + return new Module_({ 5422 + queryTree: [ 5423 + ...this._queryTree, 5424 + { 5425 + operation: "initialize", 5426 + }, 5427 + ], 5428 + ctx: this._ctx, 5429 + }); 5430 + }; 5431 + 5432 + /** 5433 + * Interfaces served by this module. 5434 + */ 5435 + interfaces = async (): Promise<TypeDef[]> => { 5436 + type interfaces = { 5437 + id: TypeDefID; 5438 + }; 5439 + 5440 + const response: Awaited<interfaces[]> = await computeQuery( 5441 + [ 5442 + ...this._queryTree, 5443 + { 5444 + operation: "interfaces", 5445 + }, 5446 + { 5447 + operation: "id", 5448 + }, 5449 + ], 5450 + await this._ctx.connection() 5451 + ); 5452 + 5453 + return response.map( 5454 + (r) => 5455 + new TypeDef( 5456 + { 5457 + queryTree: [ 5458 + { 5459 + operation: "loadTypeDefFromID", 5460 + args: { id: r.id }, 5461 + }, 5462 + ], 5463 + ctx: this._ctx, 5464 + }, 5465 + r.id 5466 + ) 5467 + ); 5468 + }; 5469 + 5470 + /** 5471 + * The name of the module 5472 + */ 5473 + name = async (): Promise<string> => { 5474 + if (this._name) { 5475 + return this._name; 5476 + } 5477 + 5478 + const response: Awaited<string> = await computeQuery( 5479 + [ 5480 + ...this._queryTree, 5481 + { 5482 + operation: "name", 5483 + }, 5484 + ], 5485 + await this._ctx.connection() 5486 + ); 5487 + 5488 + return response; 5489 + }; 5490 + 5491 + /** 5492 + * Objects served by this module. 5493 + */ 5494 + objects = async (): Promise<TypeDef[]> => { 5495 + type objects = { 5496 + id: TypeDefID; 5497 + }; 5498 + 5499 + const response: Awaited<objects[]> = await computeQuery( 5500 + [ 5501 + ...this._queryTree, 5502 + { 5503 + operation: "objects", 5504 + }, 5505 + { 5506 + operation: "id", 5507 + }, 5508 + ], 5509 + await this._ctx.connection() 5510 + ); 5511 + 5512 + return response.map( 5513 + (r) => 5514 + new TypeDef( 5515 + { 5516 + queryTree: [ 5517 + { 5518 + operation: "loadTypeDefFromID", 5519 + args: { id: r.id }, 5520 + }, 5521 + ], 5522 + ctx: this._ctx, 5523 + }, 5524 + r.id 5525 + ) 5526 + ); 5527 + }; 5528 + 5529 + /** 5530 + * The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. 5531 + */ 5532 + runtime = (): Container => { 5533 + return new Container({ 5534 + queryTree: [ 5535 + ...this._queryTree, 5536 + { 5537 + operation: "runtime", 5538 + }, 5539 + ], 5540 + ctx: this._ctx, 5541 + }); 5542 + }; 5543 + 5544 + /** 5545 + * The SDK used by this module. Either a name of a builtin SDK or a module source ref string pointing to the SDK's implementation. 5546 + */ 5547 + sdk = async (): Promise<string> => { 5548 + if (this._sdk) { 5549 + return this._sdk; 5550 + } 5551 + 5552 + const response: Awaited<string> = await computeQuery( 5553 + [ 5554 + ...this._queryTree, 5555 + { 5556 + operation: "sdk", 5557 + }, 5558 + ], 5559 + await this._ctx.connection() 5560 + ); 5561 + 5562 + return response; 5563 + }; 5564 + 5565 + /** 5566 + * Serve a module's API in the current session. 5567 + * 5568 + * Note: this can only be called once per session. In the future, it could return a stream or service to remove the side effect. 5569 + */ 5570 + serve = async (): Promise<Void> => { 5571 + if (this._serve) { 5572 + return this._serve; 5573 + } 5574 + 5575 + const response: Awaited<Void> = await computeQuery( 5576 + [ 5577 + ...this._queryTree, 5578 + { 5579 + operation: "serve", 5580 + }, 5581 + ], 5582 + await this._ctx.connection() 5583 + ); 5584 + 5585 + return response; 5586 + }; 5587 + 5588 + /** 5589 + * The source for the module. 5590 + */ 5591 + source = (): ModuleSource => { 5592 + return new ModuleSource({ 5593 + queryTree: [ 5594 + ...this._queryTree, 5595 + { 5596 + operation: "source", 5597 + }, 5598 + ], 5599 + ctx: this._ctx, 5600 + }); 5601 + }; 5602 + 5603 + /** 5604 + * Retrieves the module with the given description 5605 + * @param description The description to set 5606 + */ 5607 + withDescription = (description: string): Module_ => { 5608 + return new Module_({ 5609 + queryTree: [ 5610 + ...this._queryTree, 5611 + { 5612 + operation: "withDescription", 5613 + args: { description }, 5614 + }, 5615 + ], 5616 + ctx: this._ctx, 5617 + }); 5618 + }; 5619 + 5620 + /** 5621 + * This module plus the given Interface type and associated functions 5622 + */ 5623 + withInterface = (iface: TypeDef): Module_ => { 5624 + return new Module_({ 5625 + queryTree: [ 5626 + ...this._queryTree, 5627 + { 5628 + operation: "withInterface", 5629 + args: { iface }, 5630 + }, 5631 + ], 5632 + ctx: this._ctx, 5633 + }); 5634 + }; 5635 + 5636 + /** 5637 + * This module plus the given Object type and associated functions. 5638 + */ 5639 + withObject = (object: TypeDef): Module_ => { 5640 + return new Module_({ 5641 + queryTree: [ 5642 + ...this._queryTree, 5643 + { 5644 + operation: "withObject", 5645 + args: { object }, 5646 + }, 5647 + ], 5648 + ctx: this._ctx, 5649 + }); 5650 + }; 5651 + 5652 + /** 5653 + * Retrieves the module with basic configuration loaded if present. 5654 + * @param source The module source to initialize from. 5655 + */ 5656 + withSource = (source: ModuleSource): Module_ => { 5657 + return new Module_({ 5658 + queryTree: [ 5659 + ...this._queryTree, 5660 + { 5661 + operation: "withSource", 5662 + args: { source }, 5663 + }, 5664 + ], 5665 + ctx: this._ctx, 5666 + }); 5667 + }; 5668 + 5669 + /** 5670 + * Call the provided function with current Module. 5671 + * 5672 + * This is useful for reusability and readability by not breaking the calling chain. 5673 + */ 5674 + with = (arg: (param: Module_) => Module_) => { 5675 + return arg(this); 5676 + }; 5677 + } 5678 + 5679 + /** 5680 + * The configuration of dependency of a module. 5681 + */ 5682 + export class ModuleDependency extends BaseClient { 5683 + private readonly _id?: ModuleDependencyID = undefined; 5684 + private readonly _name?: string = undefined; 5685 + 5686 + /** 5687 + * Constructor is used for internal usage only, do not create object from it. 5688 + */ 5689 + constructor( 5690 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5691 + _id?: ModuleDependencyID, 5692 + _name?: string 5693 + ) { 5694 + super(parent); 5695 + 5696 + this._id = _id; 5697 + this._name = _name; 5698 + } 5699 + 5700 + /** 5701 + * A unique identifier for this ModuleDependency. 5702 + */ 5703 + id = async (): Promise<ModuleDependencyID> => { 5704 + if (this._id) { 5705 + return this._id; 5706 + } 5707 + 5708 + const response: Awaited<ModuleDependencyID> = await computeQuery( 5709 + [ 5710 + ...this._queryTree, 5711 + { 5712 + operation: "id", 5713 + }, 5714 + ], 5715 + await this._ctx.connection() 5716 + ); 5717 + 5718 + return response; 5719 + }; 5720 + 5721 + /** 5722 + * The name of the dependency module. 5723 + */ 5724 + name = async (): Promise<string> => { 5725 + if (this._name) { 5726 + return this._name; 5727 + } 5728 + 5729 + const response: Awaited<string> = await computeQuery( 5730 + [ 5731 + ...this._queryTree, 5732 + { 5733 + operation: "name", 5734 + }, 5735 + ], 5736 + await this._ctx.connection() 5737 + ); 5738 + 5739 + return response; 5740 + }; 5741 + 5742 + /** 5743 + * The source for the dependency module. 5744 + */ 5745 + source = (): ModuleSource => { 5746 + return new ModuleSource({ 5747 + queryTree: [ 5748 + ...this._queryTree, 5749 + { 5750 + operation: "source", 5751 + }, 5752 + ], 5753 + ctx: this._ctx, 5754 + }); 5755 + }; 5756 + } 5757 + 5758 + /** 5759 + * The source needed to load and run a module, along with any metadata about the source such as versions/urls/etc. 5760 + */ 5761 + export class ModuleSource extends BaseClient { 5762 + private readonly _id?: ModuleSourceID = undefined; 5763 + private readonly _asString?: string = undefined; 5764 + private readonly _configExists?: boolean = undefined; 5765 + private readonly _kind?: ModuleSourceKind = undefined; 5766 + private readonly _moduleName?: string = undefined; 5767 + private readonly _moduleOriginalName?: string = undefined; 5768 + private readonly _resolveContextPathFromCaller?: string = undefined; 5769 + private readonly _sourceRootSubpath?: string = undefined; 5770 + private readonly _sourceSubpath?: string = undefined; 5771 + 5772 + /** 5773 + * Constructor is used for internal usage only, do not create object from it. 5774 + */ 5775 + constructor( 5776 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 5777 + _id?: ModuleSourceID, 5778 + _asString?: string, 5779 + _configExists?: boolean, 5780 + _kind?: ModuleSourceKind, 5781 + _moduleName?: string, 5782 + _moduleOriginalName?: string, 5783 + _resolveContextPathFromCaller?: string, 5784 + _sourceRootSubpath?: string, 5785 + _sourceSubpath?: string 5786 + ) { 5787 + super(parent); 5788 + 5789 + this._id = _id; 5790 + this._asString = _asString; 5791 + this._configExists = _configExists; 5792 + this._kind = _kind; 5793 + this._moduleName = _moduleName; 5794 + this._moduleOriginalName = _moduleOriginalName; 5795 + this._resolveContextPathFromCaller = _resolveContextPathFromCaller; 5796 + this._sourceRootSubpath = _sourceRootSubpath; 5797 + this._sourceSubpath = _sourceSubpath; 5798 + } 5799 + 5800 + /** 5801 + * A unique identifier for this ModuleSource. 5802 + */ 5803 + id = async (): Promise<ModuleSourceID> => { 5804 + if (this._id) { 5805 + return this._id; 5806 + } 5807 + 5808 + const response: Awaited<ModuleSourceID> = await computeQuery( 5809 + [ 5810 + ...this._queryTree, 5811 + { 5812 + operation: "id", 5813 + }, 5814 + ], 5815 + await this._ctx.connection() 5816 + ); 5817 + 5818 + return response; 5819 + }; 5820 + 5821 + /** 5822 + * If the source is a of kind git, the git source representation of it. 5823 + */ 5824 + asGitSource = (): GitModuleSource => { 5825 + return new GitModuleSource({ 5826 + queryTree: [ 5827 + ...this._queryTree, 5828 + { 5829 + operation: "asGitSource", 5830 + }, 5831 + ], 5832 + ctx: this._ctx, 5833 + }); 5834 + }; 5835 + 5836 + /** 5837 + * If the source is of kind local, the local source representation of it. 5838 + */ 5839 + asLocalSource = (): LocalModuleSource => { 5840 + return new LocalModuleSource({ 5841 + queryTree: [ 5842 + ...this._queryTree, 5843 + { 5844 + operation: "asLocalSource", 5845 + }, 5846 + ], 5847 + ctx: this._ctx, 5848 + }); 5849 + }; 5850 + 5851 + /** 5852 + * Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation 5853 + */ 5854 + asModule = (): Module_ => { 5855 + return new Module_({ 5856 + queryTree: [ 5857 + ...this._queryTree, 5858 + { 5859 + operation: "asModule", 5860 + }, 5861 + ], 5862 + ctx: this._ctx, 5863 + }); 5864 + }; 5865 + 5866 + /** 5867 + * A human readable ref string representation of this module source. 5868 + */ 5869 + asString = async (): Promise<string> => { 5870 + if (this._asString) { 5871 + return this._asString; 5872 + } 5873 + 5874 + const response: Awaited<string> = await computeQuery( 5875 + [ 5876 + ...this._queryTree, 5877 + { 5878 + operation: "asString", 5879 + }, 5880 + ], 5881 + await this._ctx.connection() 5882 + ); 5883 + 5884 + return response; 5885 + }; 5886 + 5887 + /** 5888 + * Returns whether the module source has a configuration file. 5889 + */ 5890 + configExists = async (): Promise<boolean> => { 5891 + if (this._configExists) { 5892 + return this._configExists; 5893 + } 5894 + 5895 + const response: Awaited<boolean> = await computeQuery( 5896 + [ 5897 + ...this._queryTree, 5898 + { 5899 + operation: "configExists", 5900 + }, 5901 + ], 5902 + await this._ctx.connection() 5903 + ); 5904 + 5905 + return response; 5906 + }; 5907 + 5908 + /** 5909 + * The directory containing everything needed to load load and use the module. 5910 + */ 5911 + contextDirectory = (): Directory => { 5912 + return new Directory({ 5913 + queryTree: [ 5914 + ...this._queryTree, 5915 + { 5916 + operation: "contextDirectory", 5917 + }, 5918 + ], 5919 + ctx: this._ctx, 5920 + }); 5921 + }; 5922 + 5923 + /** 5924 + * The dependencies of the module source. Includes dependencies from the configuration and any extras from withDependencies calls. 5925 + */ 5926 + dependencies = async (): Promise<ModuleDependency[]> => { 5927 + type dependencies = { 5928 + id: ModuleDependencyID; 5929 + }; 5930 + 5931 + const response: Awaited<dependencies[]> = await computeQuery( 5932 + [ 5933 + ...this._queryTree, 5934 + { 5935 + operation: "dependencies", 5936 + }, 5937 + { 5938 + operation: "id", 5939 + }, 5940 + ], 5941 + await this._ctx.connection() 5942 + ); 5943 + 5944 + return response.map( 5945 + (r) => 5946 + new ModuleDependency( 5947 + { 5948 + queryTree: [ 5949 + { 5950 + operation: "loadModuleDependencyFromID", 5951 + args: { id: r.id }, 5952 + }, 5953 + ], 5954 + ctx: this._ctx, 5955 + }, 5956 + r.id 5957 + ) 5958 + ); 5959 + }; 5960 + 5961 + /** 5962 + * The directory containing the module configuration and source code (source code may be in a subdir). 5963 + * @param path The path from the source directory to select. 5964 + */ 5965 + directory = (path: string): Directory => { 5966 + return new Directory({ 5967 + queryTree: [ 5968 + ...this._queryTree, 5969 + { 5970 + operation: "directory", 5971 + args: { path }, 5972 + }, 5973 + ], 5974 + ctx: this._ctx, 5975 + }); 5976 + }; 5977 + 5978 + /** 5979 + * The kind of source (e.g. local, git, etc.) 5980 + */ 5981 + kind = async (): Promise<ModuleSourceKind> => { 5982 + if (this._kind) { 5983 + return this._kind; 5984 + } 5985 + 5986 + const response: Awaited<ModuleSourceKind> = await computeQuery( 5987 + [ 5988 + ...this._queryTree, 5989 + { 5990 + operation: "kind", 5991 + }, 5992 + ], 5993 + await this._ctx.connection() 5994 + ); 5995 + 5996 + return response; 5997 + }; 5998 + 5999 + /** 6000 + * If set, the name of the module this source references, including any overrides at runtime by callers. 6001 + */ 6002 + moduleName = async (): Promise<string> => { 6003 + if (this._moduleName) { 6004 + return this._moduleName; 6005 + } 6006 + 6007 + const response: Awaited<string> = await computeQuery( 6008 + [ 6009 + ...this._queryTree, 6010 + { 6011 + operation: "moduleName", 6012 + }, 6013 + ], 6014 + await this._ctx.connection() 6015 + ); 6016 + 6017 + return response; 6018 + }; 6019 + 6020 + /** 6021 + * The original name of the module this source references, as defined in the module configuration. 6022 + */ 6023 + moduleOriginalName = async (): Promise<string> => { 6024 + if (this._moduleOriginalName) { 6025 + return this._moduleOriginalName; 6026 + } 6027 + 6028 + const response: Awaited<string> = await computeQuery( 6029 + [ 6030 + ...this._queryTree, 6031 + { 6032 + operation: "moduleOriginalName", 6033 + }, 6034 + ], 6035 + await this._ctx.connection() 6036 + ); 6037 + 6038 + return response; 6039 + }; 6040 + 6041 + /** 6042 + * The path to the module source's context directory on the caller's filesystem. Only valid for local sources. 6043 + */ 6044 + resolveContextPathFromCaller = async (): Promise<string> => { 6045 + if (this._resolveContextPathFromCaller) { 6046 + return this._resolveContextPathFromCaller; 6047 + } 6048 + 6049 + const response: Awaited<string> = await computeQuery( 6050 + [ 6051 + ...this._queryTree, 6052 + { 6053 + operation: "resolveContextPathFromCaller", 6054 + }, 6055 + ], 6056 + await this._ctx.connection() 6057 + ); 6058 + 6059 + return response; 6060 + }; 6061 + 6062 + /** 6063 + * Resolve the provided module source arg as a dependency relative to this module source. 6064 + * @param dep The dependency module source to resolve. 6065 + */ 6066 + resolveDependency = (dep: ModuleSource): ModuleSource => { 6067 + return new ModuleSource({ 6068 + queryTree: [ 6069 + ...this._queryTree, 6070 + { 6071 + operation: "resolveDependency", 6072 + args: { dep }, 6073 + }, 6074 + ], 6075 + ctx: this._ctx, 6076 + }); 6077 + }; 6078 + 6079 + /** 6080 + * Load the source from its path on the caller's filesystem, including only needed+configured files and directories. Only valid for local sources. 6081 + */ 6082 + resolveFromCaller = (): ModuleSource => { 6083 + return new ModuleSource({ 6084 + queryTree: [ 6085 + ...this._queryTree, 6086 + { 6087 + operation: "resolveFromCaller", 6088 + }, 6089 + ], 6090 + ctx: this._ctx, 6091 + }); 6092 + }; 6093 + 6094 + /** 6095 + * The path relative to context of the root of the module source, which contains dagger.json. It also contains the module implementation source code, but that may or may not being a subdir of this root. 6096 + */ 6097 + sourceRootSubpath = async (): Promise<string> => { 6098 + if (this._sourceRootSubpath) { 6099 + return this._sourceRootSubpath; 6100 + } 6101 + 6102 + const response: Awaited<string> = await computeQuery( 6103 + [ 6104 + ...this._queryTree, 6105 + { 6106 + operation: "sourceRootSubpath", 6107 + }, 6108 + ], 6109 + await this._ctx.connection() 6110 + ); 6111 + 6112 + return response; 6113 + }; 6114 + 6115 + /** 6116 + * The path relative to context of the module implementation source code. 6117 + */ 6118 + sourceSubpath = async (): Promise<string> => { 6119 + if (this._sourceSubpath) { 6120 + return this._sourceSubpath; 6121 + } 6122 + 6123 + const response: Awaited<string> = await computeQuery( 6124 + [ 6125 + ...this._queryTree, 6126 + { 6127 + operation: "sourceSubpath", 6128 + }, 6129 + ], 6130 + await this._ctx.connection() 6131 + ); 6132 + 6133 + return response; 6134 + }; 6135 + 6136 + /** 6137 + * Update the module source with a new context directory. Only valid for local sources. 6138 + * @param dir The directory to set as the context directory. 6139 + */ 6140 + withContextDirectory = (dir: Directory): ModuleSource => { 6141 + return new ModuleSource({ 6142 + queryTree: [ 6143 + ...this._queryTree, 6144 + { 6145 + operation: "withContextDirectory", 6146 + args: { dir }, 6147 + }, 6148 + ], 6149 + ctx: this._ctx, 6150 + }); 6151 + }; 6152 + 6153 + /** 6154 + * Append the provided dependencies to the module source's dependency list. 6155 + * @param dependencies The dependencies to append. 6156 + */ 6157 + withDependencies = (dependencies: ModuleDependency[]): ModuleSource => { 6158 + return new ModuleSource({ 6159 + queryTree: [ 6160 + ...this._queryTree, 6161 + { 6162 + operation: "withDependencies", 6163 + args: { dependencies }, 6164 + }, 6165 + ], 6166 + ctx: this._ctx, 6167 + }); 6168 + }; 6169 + 6170 + /** 6171 + * Update the module source with a new name. 6172 + * @param name The name to set. 6173 + */ 6174 + withName = (name: string): ModuleSource => { 6175 + return new ModuleSource({ 6176 + queryTree: [ 6177 + ...this._queryTree, 6178 + { 6179 + operation: "withName", 6180 + args: { name }, 6181 + }, 6182 + ], 6183 + ctx: this._ctx, 6184 + }); 6185 + }; 6186 + 6187 + /** 6188 + * Update the module source with a new SDK. 6189 + * @param sdk The SDK to set. 6190 + */ 6191 + withSDK = (sdk: string): ModuleSource => { 6192 + return new ModuleSource({ 6193 + queryTree: [ 6194 + ...this._queryTree, 6195 + { 6196 + operation: "withSDK", 6197 + args: { sdk }, 6198 + }, 6199 + ], 6200 + ctx: this._ctx, 6201 + }); 6202 + }; 6203 + 6204 + /** 6205 + * Update the module source with a new source subpath. 6206 + * @param path The path to set as the source subpath. 6207 + */ 6208 + withSourceSubpath = (path: string): ModuleSource => { 6209 + return new ModuleSource({ 6210 + queryTree: [ 6211 + ...this._queryTree, 6212 + { 6213 + operation: "withSourceSubpath", 6214 + args: { path }, 6215 + }, 6216 + ], 6217 + ctx: this._ctx, 6218 + }); 6219 + }; 6220 + 6221 + /** 6222 + * Call the provided function with current ModuleSource. 6223 + * 6224 + * This is useful for reusability and readability by not breaking the calling chain. 6225 + */ 6226 + with = (arg: (param: ModuleSource) => ModuleSource) => { 6227 + return arg(this); 6228 + }; 6229 + } 6230 + 6231 + /** 6232 + * A definition of a custom object defined in a Module. 6233 + */ 6234 + export class ObjectTypeDef extends BaseClient { 6235 + private readonly _id?: ObjectTypeDefID = undefined; 6236 + private readonly _description?: string = undefined; 6237 + private readonly _name?: string = undefined; 6238 + private readonly _sourceModuleName?: string = undefined; 6239 + 6240 + /** 6241 + * Constructor is used for internal usage only, do not create object from it. 6242 + */ 6243 + constructor( 6244 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 6245 + _id?: ObjectTypeDefID, 6246 + _description?: string, 6247 + _name?: string, 6248 + _sourceModuleName?: string 6249 + ) { 6250 + super(parent); 6251 + 6252 + this._id = _id; 6253 + this._description = _description; 6254 + this._name = _name; 6255 + this._sourceModuleName = _sourceModuleName; 6256 + } 6257 + 6258 + /** 6259 + * A unique identifier for this ObjectTypeDef. 6260 + */ 6261 + id = async (): Promise<ObjectTypeDefID> => { 6262 + if (this._id) { 6263 + return this._id; 6264 + } 6265 + 6266 + const response: Awaited<ObjectTypeDefID> = await computeQuery( 6267 + [ 6268 + ...this._queryTree, 6269 + { 6270 + operation: "id", 6271 + }, 6272 + ], 6273 + await this._ctx.connection() 6274 + ); 6275 + 6276 + return response; 6277 + }; 6278 + 6279 + /** 6280 + * The function used to construct new instances of this object, if any 6281 + */ 6282 + constructor_ = (): Function_ => { 6283 + return new Function_({ 6284 + queryTree: [ 6285 + ...this._queryTree, 6286 + { 6287 + operation: "constructor", 6288 + }, 6289 + ], 6290 + ctx: this._ctx, 6291 + }); 6292 + }; 6293 + 6294 + /** 6295 + * The doc string for the object, if any. 6296 + */ 6297 + description = async (): Promise<string> => { 6298 + if (this._description) { 6299 + return this._description; 6300 + } 6301 + 6302 + const response: Awaited<string> = await computeQuery( 6303 + [ 6304 + ...this._queryTree, 6305 + { 6306 + operation: "description", 6307 + }, 6308 + ], 6309 + await this._ctx.connection() 6310 + ); 6311 + 6312 + return response; 6313 + }; 6314 + 6315 + /** 6316 + * Static fields defined on this object, if any. 6317 + */ 6318 + fields = async (): Promise<FieldTypeDef[]> => { 6319 + type fields = { 6320 + id: FieldTypeDefID; 6321 + }; 6322 + 6323 + const response: Awaited<fields[]> = await computeQuery( 6324 + [ 6325 + ...this._queryTree, 6326 + { 6327 + operation: "fields", 6328 + }, 6329 + { 6330 + operation: "id", 6331 + }, 6332 + ], 6333 + await this._ctx.connection() 6334 + ); 6335 + 6336 + return response.map( 6337 + (r) => 6338 + new FieldTypeDef( 6339 + { 6340 + queryTree: [ 6341 + { 6342 + operation: "loadFieldTypeDefFromID", 6343 + args: { id: r.id }, 6344 + }, 6345 + ], 6346 + ctx: this._ctx, 6347 + }, 6348 + r.id 6349 + ) 6350 + ); 6351 + }; 6352 + 6353 + /** 6354 + * Functions defined on this object, if any. 6355 + */ 6356 + functions = async (): Promise<Function_[]> => { 6357 + type functions = { 6358 + id: FunctionID; 6359 + }; 6360 + 6361 + const response: Awaited<functions[]> = await computeQuery( 6362 + [ 6363 + ...this._queryTree, 6364 + { 6365 + operation: "functions", 6366 + }, 6367 + { 6368 + operation: "id", 6369 + }, 6370 + ], 6371 + await this._ctx.connection() 6372 + ); 6373 + 6374 + return response.map( 6375 + (r) => 6376 + new Function_( 6377 + { 6378 + queryTree: [ 6379 + { 6380 + operation: "loadFunction_FromID", 6381 + args: { id: r.id }, 6382 + }, 6383 + ], 6384 + ctx: this._ctx, 6385 + }, 6386 + r.id 6387 + ) 6388 + ); 6389 + }; 6390 + 6391 + /** 6392 + * The name of the object. 6393 + */ 6394 + name = async (): Promise<string> => { 6395 + if (this._name) { 6396 + return this._name; 6397 + } 6398 + 6399 + const response: Awaited<string> = await computeQuery( 6400 + [ 6401 + ...this._queryTree, 6402 + { 6403 + operation: "name", 6404 + }, 6405 + ], 6406 + await this._ctx.connection() 6407 + ); 6408 + 6409 + return response; 6410 + }; 6411 + 6412 + /** 6413 + * If this ObjectTypeDef is associated with a Module, the name of the module. Unset otherwise. 6414 + */ 6415 + sourceModuleName = async (): Promise<string> => { 6416 + if (this._sourceModuleName) { 6417 + return this._sourceModuleName; 6418 + } 6419 + 6420 + const response: Awaited<string> = await computeQuery( 6421 + [ 6422 + ...this._queryTree, 6423 + { 6424 + operation: "sourceModuleName", 6425 + }, 6426 + ], 6427 + await this._ctx.connection() 6428 + ); 6429 + 6430 + return response; 6431 + }; 6432 + } 6433 + 6434 + /** 6435 + * A port exposed by a container. 6436 + */ 6437 + export class Port extends BaseClient { 6438 + private readonly _id?: PortID = undefined; 6439 + private readonly _description?: string = undefined; 6440 + private readonly _experimentalSkipHealthcheck?: boolean = undefined; 6441 + private readonly _port?: number = undefined; 6442 + private readonly _protocol?: NetworkProtocol = undefined; 6443 + 6444 + /** 6445 + * Constructor is used for internal usage only, do not create object from it. 6446 + */ 6447 + constructor( 6448 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 6449 + _id?: PortID, 6450 + _description?: string, 6451 + _experimentalSkipHealthcheck?: boolean, 6452 + _port?: number, 6453 + _protocol?: NetworkProtocol 6454 + ) { 6455 + super(parent); 6456 + 6457 + this._id = _id; 6458 + this._description = _description; 6459 + this._experimentalSkipHealthcheck = _experimentalSkipHealthcheck; 6460 + this._port = _port; 6461 + this._protocol = _protocol; 6462 + } 6463 + 6464 + /** 6465 + * A unique identifier for this Port. 6466 + */ 6467 + id = async (): Promise<PortID> => { 6468 + if (this._id) { 6469 + return this._id; 6470 + } 6471 + 6472 + const response: Awaited<PortID> = await computeQuery( 6473 + [ 6474 + ...this._queryTree, 6475 + { 6476 + operation: "id", 6477 + }, 6478 + ], 6479 + await this._ctx.connection() 6480 + ); 6481 + 6482 + return response; 6483 + }; 6484 + 6485 + /** 6486 + * The port description. 6487 + */ 6488 + description = async (): Promise<string> => { 6489 + if (this._description) { 6490 + return this._description; 6491 + } 6492 + 6493 + const response: Awaited<string> = await computeQuery( 6494 + [ 6495 + ...this._queryTree, 6496 + { 6497 + operation: "description", 6498 + }, 6499 + ], 6500 + await this._ctx.connection() 6501 + ); 6502 + 6503 + return response; 6504 + }; 6505 + 6506 + /** 6507 + * Skip the health check when run as a service. 6508 + */ 6509 + experimentalSkipHealthcheck = async (): Promise<boolean> => { 6510 + if (this._experimentalSkipHealthcheck) { 6511 + return this._experimentalSkipHealthcheck; 6512 + } 6513 + 6514 + const response: Awaited<boolean> = await computeQuery( 6515 + [ 6516 + ...this._queryTree, 6517 + { 6518 + operation: "experimentalSkipHealthcheck", 6519 + }, 6520 + ], 6521 + await this._ctx.connection() 6522 + ); 6523 + 6524 + return response; 6525 + }; 6526 + 6527 + /** 6528 + * The port number. 6529 + */ 6530 + port = async (): Promise<number> => { 6531 + if (this._port) { 6532 + return this._port; 6533 + } 6534 + 6535 + const response: Awaited<number> = await computeQuery( 6536 + [ 6537 + ...this._queryTree, 6538 + { 6539 + operation: "port", 6540 + }, 6541 + ], 6542 + await this._ctx.connection() 6543 + ); 6544 + 6545 + return response; 6546 + }; 6547 + 6548 + /** 6549 + * The transport layer protocol. 6550 + */ 6551 + protocol = async (): Promise<NetworkProtocol> => { 6552 + if (this._protocol) { 6553 + return this._protocol; 6554 + } 6555 + 6556 + const response: Awaited<NetworkProtocol> = await computeQuery( 6557 + [ 6558 + ...this._queryTree, 6559 + { 6560 + operation: "protocol", 6561 + }, 6562 + ], 6563 + await this._ctx.connection() 6564 + ); 6565 + 6566 + return response; 6567 + }; 6568 + } 6569 + 6570 + /** 6571 + * The root of the DAG. 6572 + */ 6573 + export class Client extends BaseClient { 6574 + private readonly _checkVersionCompatibility?: boolean = undefined; 6575 + private readonly _defaultPlatform?: Platform = undefined; 6576 + 6577 + /** 6578 + * Constructor is used for internal usage only, do not create object from it. 6579 + */ 6580 + constructor( 6581 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 6582 + _checkVersionCompatibility?: boolean, 6583 + _defaultPlatform?: Platform 6584 + ) { 6585 + super(parent); 6586 + 6587 + this._checkVersionCompatibility = _checkVersionCompatibility; 6588 + this._defaultPlatform = _defaultPlatform; 6589 + } 6590 + 6591 + /** 6592 + * Retrieves a content-addressed blob. 6593 + * @param digest Digest of the blob 6594 + * @param size Size of the blob 6595 + * @param mediaType Media type of the blob 6596 + * @param uncompressed Digest of the uncompressed blob 6597 + */ 6598 + blob = ( 6599 + digest: string, 6600 + size: number, 6601 + mediaType: string, 6602 + uncompressed: string 6603 + ): Directory => { 6604 + return new Directory({ 6605 + queryTree: [ 6606 + ...this._queryTree, 6607 + { 6608 + operation: "blob", 6609 + args: { digest, size, mediaType, uncompressed }, 6610 + }, 6611 + ], 6612 + ctx: this._ctx, 6613 + }); 6614 + }; 6615 + 6616 + /** 6617 + * Retrieves a container builtin to the engine. 6618 + * @param digest Digest of the image manifest 6619 + */ 6620 + builtinContainer = (digest: string): Container => { 6621 + return new Container({ 6622 + queryTree: [ 6623 + ...this._queryTree, 6624 + { 6625 + operation: "builtinContainer", 6626 + args: { digest }, 6627 + }, 6628 + ], 6629 + ctx: this._ctx, 6630 + }); 6631 + }; 6632 + 6633 + /** 6634 + * Constructs a cache volume for a given cache key. 6635 + * @param key A string identifier to target this cache volume (e.g., "modules-cache"). 6636 + */ 6637 + cacheVolume = (key: string): CacheVolume => { 6638 + return new CacheVolume({ 6639 + queryTree: [ 6640 + ...this._queryTree, 6641 + { 6642 + operation: "cacheVolume", 6643 + args: { key }, 6644 + }, 6645 + ], 6646 + ctx: this._ctx, 6647 + }); 6648 + }; 6649 + 6650 + /** 6651 + * Checks if the current Dagger Engine is compatible with an SDK's required version. 6652 + * @param version Version required by the SDK. 6653 + */ 6654 + checkVersionCompatibility = async (version: string): Promise<boolean> => { 6655 + const response: Awaited<boolean> = await computeQuery( 6656 + [ 6657 + ...this._queryTree, 6658 + { 6659 + operation: "checkVersionCompatibility", 6660 + args: { version }, 6661 + }, 6662 + ], 6663 + await this._ctx.connection() 6664 + ); 6665 + 6666 + return response; 6667 + }; 6668 + 6669 + /** 6670 + * Creates a scratch container. 6671 + * 6672 + * Optional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host. 6673 + * @param opts.id DEPRECATED: Use `loadContainerFromID` instead. 6674 + * @param opts.platform Platform to initialize the container with. 6675 + */ 6676 + container = (opts?: ClientContainerOpts): Container => { 6677 + return new Container({ 6678 + queryTree: [ 6679 + ...this._queryTree, 6680 + { 6681 + operation: "container", 6682 + args: { ...opts }, 6683 + }, 6684 + ], 6685 + ctx: this._ctx, 6686 + }); 6687 + }; 6688 + 6689 + /** 6690 + * The FunctionCall context that the SDK caller is currently executing in. 6691 + * 6692 + * If the caller is not currently executing in a function, this will return an error. 6693 + */ 6694 + currentFunctionCall = (): FunctionCall => { 6695 + return new FunctionCall({ 6696 + queryTree: [ 6697 + ...this._queryTree, 6698 + { 6699 + operation: "currentFunctionCall", 6700 + }, 6701 + ], 6702 + ctx: this._ctx, 6703 + }); 6704 + }; 6705 + 6706 + /** 6707 + * The module currently being served in the session, if any. 6708 + */ 6709 + currentModule = (): CurrentModule => { 6710 + return new CurrentModule({ 6711 + queryTree: [ 6712 + ...this._queryTree, 6713 + { 6714 + operation: "currentModule", 6715 + }, 6716 + ], 6717 + ctx: this._ctx, 6718 + }); 6719 + }; 6720 + 6721 + /** 6722 + * The TypeDef representations of the objects currently being served in the session. 6723 + */ 6724 + currentTypeDefs = async (): Promise<TypeDef[]> => { 6725 + type currentTypeDefs = { 6726 + id: TypeDefID; 6727 + }; 6728 + 6729 + const response: Awaited<currentTypeDefs[]> = await computeQuery( 6730 + [ 6731 + ...this._queryTree, 6732 + { 6733 + operation: "currentTypeDefs", 6734 + }, 6735 + { 6736 + operation: "id", 6737 + }, 6738 + ], 6739 + await this._ctx.connection() 6740 + ); 6741 + 6742 + return response.map( 6743 + (r) => 6744 + new TypeDef( 6745 + { 6746 + queryTree: [ 6747 + { 6748 + operation: "loadTypeDefFromID", 6749 + args: { id: r.id }, 6750 + }, 6751 + ], 6752 + ctx: this._ctx, 6753 + }, 6754 + r.id 6755 + ) 6756 + ); 6757 + }; 6758 + 6759 + /** 6760 + * The default platform of the engine. 6761 + */ 6762 + defaultPlatform = async (): Promise<Platform> => { 6763 + const response: Awaited<Platform> = await computeQuery( 6764 + [ 6765 + ...this._queryTree, 6766 + { 6767 + operation: "defaultPlatform", 6768 + }, 6769 + ], 6770 + await this._ctx.connection() 6771 + ); 6772 + 6773 + return response; 6774 + }; 6775 + 6776 + /** 6777 + * Creates an empty directory. 6778 + * @param opts.id DEPRECATED: Use `loadDirectoryFromID` isntead. 6779 + */ 6780 + directory = (opts?: ClientDirectoryOpts): Directory => { 6781 + return new Directory({ 6782 + queryTree: [ 6783 + ...this._queryTree, 6784 + { 6785 + operation: "directory", 6786 + args: { ...opts }, 6787 + }, 6788 + ], 6789 + ctx: this._ctx, 6790 + }); 6791 + }; 6792 + 6793 + /** 6794 + * @deprecated Use loadFileFromID instead. 6795 + */ 6796 + file = (id: FileID): File => { 6797 + return new File({ 6798 + queryTree: [ 6799 + ...this._queryTree, 6800 + { 6801 + operation: "file", 6802 + args: { id }, 6803 + }, 6804 + ], 6805 + ctx: this._ctx, 6806 + }); 6807 + }; 6808 + 6809 + /** 6810 + * Creates a function. 6811 + * @param name Name of the function, in its original format from the implementation language. 6812 + * @param returnType Return type of the function. 6813 + */ 6814 + function_ = (name: string, returnType: TypeDef): Function_ => { 6815 + return new Function_({ 6816 + queryTree: [ 6817 + ...this._queryTree, 6818 + { 6819 + operation: "function", 6820 + args: { name, returnType }, 6821 + }, 6822 + ], 6823 + ctx: this._ctx, 6824 + }); 6825 + }; 6826 + 6827 + /** 6828 + * Create a code generation result, given a directory containing the generated code. 6829 + */ 6830 + generatedCode = (code: Directory): GeneratedCode => { 6831 + return new GeneratedCode({ 6832 + queryTree: [ 6833 + ...this._queryTree, 6834 + { 6835 + operation: "generatedCode", 6836 + args: { code }, 6837 + }, 6838 + ], 6839 + ctx: this._ctx, 6840 + }); 6841 + }; 6842 + 6843 + /** 6844 + * Queries a Git repository. 6845 + * @param url URL of the git repository. 6846 + * 6847 + * Can be formatted as `https://{host}/{owner}/{repo}`, `git@{host}:{owner}/{repo}`. 6848 + * 6849 + * Suffix ".git" is optional. 6850 + * @param opts.keepGitDir Set to true to keep .git directory. 6851 + * @param opts.experimentalServiceHost A service which must be started before the repo is fetched. 6852 + * @param opts.sshKnownHosts Set SSH known hosts 6853 + * @param opts.sshAuthSocket Set SSH auth socket 6854 + */ 6855 + git = (url: string, opts?: ClientGitOpts): GitRepository => { 6856 + return new GitRepository({ 6857 + queryTree: [ 6858 + ...this._queryTree, 6859 + { 6860 + operation: "git", 6861 + args: { url, ...opts }, 6862 + }, 6863 + ], 6864 + ctx: this._ctx, 6865 + }); 6866 + }; 6867 + 6868 + /** 6869 + * Queries the host environment. 6870 + */ 6871 + host = (): Host => { 6872 + return new Host({ 6873 + queryTree: [ 6874 + ...this._queryTree, 6875 + { 6876 + operation: "host", 6877 + }, 6878 + ], 6879 + ctx: this._ctx, 6880 + }); 6881 + }; 6882 + 6883 + /** 6884 + * Returns a file containing an http remote url content. 6885 + * @param url HTTP url to get the content from (e.g., "https://docs.dagger.io"). 6886 + * @param opts.experimentalServiceHost A service which must be started before the URL is fetched. 6887 + */ 6888 + http = (url: string, opts?: ClientHttpOpts): File => { 6889 + return new File({ 6890 + queryTree: [ 6891 + ...this._queryTree, 6892 + { 6893 + operation: "http", 6894 + args: { url, ...opts }, 6895 + }, 6896 + ], 6897 + ctx: this._ctx, 6898 + }); 6899 + }; 6900 + 6901 + /** 6902 + * Load a CacheVolume from its ID. 6903 + */ 6904 + loadCacheVolumeFromID = (id: CacheVolumeID): CacheVolume => { 6905 + return new CacheVolume({ 6906 + queryTree: [ 6907 + ...this._queryTree, 6908 + { 6909 + operation: "loadCacheVolumeFromID", 6910 + args: { id }, 6911 + }, 6912 + ], 6913 + ctx: this._ctx, 6914 + }); 6915 + }; 6916 + 6917 + /** 6918 + * Load a Container from its ID. 6919 + */ 6920 + loadContainerFromID = (id: ContainerID): Container => { 6921 + return new Container({ 6922 + queryTree: [ 6923 + ...this._queryTree, 6924 + { 6925 + operation: "loadContainerFromID", 6926 + args: { id }, 6927 + }, 6928 + ], 6929 + ctx: this._ctx, 6930 + }); 6931 + }; 6932 + 6933 + /** 6934 + * Load a CurrentModule from its ID. 6935 + */ 6936 + loadCurrentModuleFromID = (id: CurrentModuleID): CurrentModule => { 6937 + return new CurrentModule({ 6938 + queryTree: [ 6939 + ...this._queryTree, 6940 + { 6941 + operation: "loadCurrentModuleFromID", 6942 + args: { id }, 6943 + }, 6944 + ], 6945 + ctx: this._ctx, 6946 + }); 6947 + }; 6948 + 6949 + /** 6950 + * Load a Directory from its ID. 6951 + */ 6952 + loadDirectoryFromID = (id: DirectoryID): Directory => { 6953 + return new Directory({ 6954 + queryTree: [ 6955 + ...this._queryTree, 6956 + { 6957 + operation: "loadDirectoryFromID", 6958 + args: { id }, 6959 + }, 6960 + ], 6961 + ctx: this._ctx, 6962 + }); 6963 + }; 6964 + 6965 + /** 6966 + * Load a EnvVariable from its ID. 6967 + */ 6968 + loadEnvVariableFromID = (id: EnvVariableID): EnvVariable => { 6969 + return new EnvVariable({ 6970 + queryTree: [ 6971 + ...this._queryTree, 6972 + { 6973 + operation: "loadEnvVariableFromID", 6974 + args: { id }, 6975 + }, 6976 + ], 6977 + ctx: this._ctx, 6978 + }); 6979 + }; 6980 + 6981 + /** 6982 + * Load a FieldTypeDef from its ID. 6983 + */ 6984 + loadFieldTypeDefFromID = (id: FieldTypeDefID): FieldTypeDef => { 6985 + return new FieldTypeDef({ 6986 + queryTree: [ 6987 + ...this._queryTree, 6988 + { 6989 + operation: "loadFieldTypeDefFromID", 6990 + args: { id }, 6991 + }, 6992 + ], 6993 + ctx: this._ctx, 6994 + }); 6995 + }; 6996 + 6997 + /** 6998 + * Load a File from its ID. 6999 + */ 7000 + loadFileFromID = (id: FileID): File => { 7001 + return new File({ 7002 + queryTree: [ 7003 + ...this._queryTree, 7004 + { 7005 + operation: "loadFileFromID", 7006 + args: { id }, 7007 + }, 7008 + ], 7009 + ctx: this._ctx, 7010 + }); 7011 + }; 7012 + 7013 + /** 7014 + * Load a FunctionArg from its ID. 7015 + */ 7016 + loadFunctionArgFromID = (id: FunctionArgID): FunctionArg => { 7017 + return new FunctionArg({ 7018 + queryTree: [ 7019 + ...this._queryTree, 7020 + { 7021 + operation: "loadFunctionArgFromID", 7022 + args: { id }, 7023 + }, 7024 + ], 7025 + ctx: this._ctx, 7026 + }); 7027 + }; 7028 + 7029 + /** 7030 + * Load a FunctionCallArgValue from its ID. 7031 + */ 7032 + loadFunctionCallArgValueFromID = ( 7033 + id: FunctionCallArgValueID 7034 + ): FunctionCallArgValue => { 7035 + return new FunctionCallArgValue({ 7036 + queryTree: [ 7037 + ...this._queryTree, 7038 + { 7039 + operation: "loadFunctionCallArgValueFromID", 7040 + args: { id }, 7041 + }, 7042 + ], 7043 + ctx: this._ctx, 7044 + }); 7045 + }; 7046 + 7047 + /** 7048 + * Load a FunctionCall from its ID. 7049 + */ 7050 + loadFunctionCallFromID = (id: FunctionCallID): FunctionCall => { 7051 + return new FunctionCall({ 7052 + queryTree: [ 7053 + ...this._queryTree, 7054 + { 7055 + operation: "loadFunctionCallFromID", 7056 + args: { id }, 7057 + }, 7058 + ], 7059 + ctx: this._ctx, 7060 + }); 7061 + }; 7062 + 7063 + /** 7064 + * Load a Function from its ID. 7065 + */ 7066 + loadFunctionFromID = (id: FunctionID): Function_ => { 7067 + return new Function_({ 7068 + queryTree: [ 7069 + ...this._queryTree, 7070 + { 7071 + operation: "loadFunctionFromID", 7072 + args: { id }, 7073 + }, 7074 + ], 7075 + ctx: this._ctx, 7076 + }); 7077 + }; 7078 + 7079 + /** 7080 + * Load a GeneratedCode from its ID. 7081 + */ 7082 + loadGeneratedCodeFromID = (id: GeneratedCodeID): GeneratedCode => { 7083 + return new GeneratedCode({ 7084 + queryTree: [ 7085 + ...this._queryTree, 7086 + { 7087 + operation: "loadGeneratedCodeFromID", 7088 + args: { id }, 7089 + }, 7090 + ], 7091 + ctx: this._ctx, 7092 + }); 7093 + }; 7094 + 7095 + /** 7096 + * Load a GitModuleSource from its ID. 7097 + */ 7098 + loadGitModuleSourceFromID = (id: GitModuleSourceID): GitModuleSource => { 7099 + return new GitModuleSource({ 7100 + queryTree: [ 7101 + ...this._queryTree, 7102 + { 7103 + operation: "loadGitModuleSourceFromID", 7104 + args: { id }, 7105 + }, 7106 + ], 7107 + ctx: this._ctx, 7108 + }); 7109 + }; 7110 + 7111 + /** 7112 + * Load a GitRef from its ID. 7113 + */ 7114 + loadGitRefFromID = (id: GitRefID): GitRef => { 7115 + return new GitRef({ 7116 + queryTree: [ 7117 + ...this._queryTree, 7118 + { 7119 + operation: "loadGitRefFromID", 7120 + args: { id }, 7121 + }, 7122 + ], 7123 + ctx: this._ctx, 7124 + }); 7125 + }; 7126 + 7127 + /** 7128 + * Load a GitRepository from its ID. 7129 + */ 7130 + loadGitRepositoryFromID = (id: GitRepositoryID): GitRepository => { 7131 + return new GitRepository({ 7132 + queryTree: [ 7133 + ...this._queryTree, 7134 + { 7135 + operation: "loadGitRepositoryFromID", 7136 + args: { id }, 7137 + }, 7138 + ], 7139 + ctx: this._ctx, 7140 + }); 7141 + }; 7142 + 7143 + /** 7144 + * Load a Host from its ID. 7145 + */ 7146 + loadHostFromID = (id: HostID): Host => { 7147 + return new Host({ 7148 + queryTree: [ 7149 + ...this._queryTree, 7150 + { 7151 + operation: "loadHostFromID", 7152 + args: { id }, 7153 + }, 7154 + ], 7155 + ctx: this._ctx, 7156 + }); 7157 + }; 7158 + 7159 + /** 7160 + * Load a InputTypeDef from its ID. 7161 + */ 7162 + loadInputTypeDefFromID = (id: InputTypeDefID): InputTypeDef => { 7163 + return new InputTypeDef({ 7164 + queryTree: [ 7165 + ...this._queryTree, 7166 + { 7167 + operation: "loadInputTypeDefFromID", 7168 + args: { id }, 7169 + }, 7170 + ], 7171 + ctx: this._ctx, 7172 + }); 7173 + }; 7174 + 7175 + /** 7176 + * Load a InterfaceTypeDef from its ID. 7177 + */ 7178 + loadInterfaceTypeDefFromID = (id: InterfaceTypeDefID): InterfaceTypeDef => { 7179 + return new InterfaceTypeDef({ 7180 + queryTree: [ 7181 + ...this._queryTree, 7182 + { 7183 + operation: "loadInterfaceTypeDefFromID", 7184 + args: { id }, 7185 + }, 7186 + ], 7187 + ctx: this._ctx, 7188 + }); 7189 + }; 7190 + 7191 + /** 7192 + * Load a Label from its ID. 7193 + */ 7194 + loadLabelFromID = (id: LabelID): Label => { 7195 + return new Label({ 7196 + queryTree: [ 7197 + ...this._queryTree, 7198 + { 7199 + operation: "loadLabelFromID", 7200 + args: { id }, 7201 + }, 7202 + ], 7203 + ctx: this._ctx, 7204 + }); 7205 + }; 7206 + 7207 + /** 7208 + * Load a ListTypeDef from its ID. 7209 + */ 7210 + loadListTypeDefFromID = (id: ListTypeDefID): ListTypeDef => { 7211 + return new ListTypeDef({ 7212 + queryTree: [ 7213 + ...this._queryTree, 7214 + { 7215 + operation: "loadListTypeDefFromID", 7216 + args: { id }, 7217 + }, 7218 + ], 7219 + ctx: this._ctx, 7220 + }); 7221 + }; 7222 + 7223 + /** 7224 + * Load a LocalModuleSource from its ID. 7225 + */ 7226 + loadLocalModuleSourceFromID = ( 7227 + id: LocalModuleSourceID 7228 + ): LocalModuleSource => { 7229 + return new LocalModuleSource({ 7230 + queryTree: [ 7231 + ...this._queryTree, 7232 + { 7233 + operation: "loadLocalModuleSourceFromID", 7234 + args: { id }, 7235 + }, 7236 + ], 7237 + ctx: this._ctx, 7238 + }); 7239 + }; 7240 + 7241 + /** 7242 + * Load a ModuleDependency from its ID. 7243 + */ 7244 + loadModuleDependencyFromID = (id: ModuleDependencyID): ModuleDependency => { 7245 + return new ModuleDependency({ 7246 + queryTree: [ 7247 + ...this._queryTree, 7248 + { 7249 + operation: "loadModuleDependencyFromID", 7250 + args: { id }, 7251 + }, 7252 + ], 7253 + ctx: this._ctx, 7254 + }); 7255 + }; 7256 + 7257 + /** 7258 + * Load a Module from its ID. 7259 + */ 7260 + loadModuleFromID = (id: ModuleID): Module_ => { 7261 + return new Module_({ 7262 + queryTree: [ 7263 + ...this._queryTree, 7264 + { 7265 + operation: "loadModuleFromID", 7266 + args: { id }, 7267 + }, 7268 + ], 7269 + ctx: this._ctx, 7270 + }); 7271 + }; 7272 + 7273 + /** 7274 + * Load a ModuleSource from its ID. 7275 + */ 7276 + loadModuleSourceFromID = (id: ModuleSourceID): ModuleSource => { 7277 + return new ModuleSource({ 7278 + queryTree: [ 7279 + ...this._queryTree, 7280 + { 7281 + operation: "loadModuleSourceFromID", 7282 + args: { id }, 7283 + }, 7284 + ], 7285 + ctx: this._ctx, 7286 + }); 7287 + }; 7288 + 7289 + /** 7290 + * Load a ObjectTypeDef from its ID. 7291 + */ 7292 + loadObjectTypeDefFromID = (id: ObjectTypeDefID): ObjectTypeDef => { 7293 + return new ObjectTypeDef({ 7294 + queryTree: [ 7295 + ...this._queryTree, 7296 + { 7297 + operation: "loadObjectTypeDefFromID", 7298 + args: { id }, 7299 + }, 7300 + ], 7301 + ctx: this._ctx, 7302 + }); 7303 + }; 7304 + 7305 + /** 7306 + * Load a Port from its ID. 7307 + */ 7308 + loadPortFromID = (id: PortID): Port => { 7309 + return new Port({ 7310 + queryTree: [ 7311 + ...this._queryTree, 7312 + { 7313 + operation: "loadPortFromID", 7314 + args: { id }, 7315 + }, 7316 + ], 7317 + ctx: this._ctx, 7318 + }); 7319 + }; 7320 + 7321 + /** 7322 + * Load a Secret from its ID. 7323 + */ 7324 + loadSecretFromID = (id: SecretID): Secret => { 7325 + return new Secret({ 7326 + queryTree: [ 7327 + ...this._queryTree, 7328 + { 7329 + operation: "loadSecretFromID", 7330 + args: { id }, 7331 + }, 7332 + ], 7333 + ctx: this._ctx, 7334 + }); 7335 + }; 7336 + 7337 + /** 7338 + * Load a Service from its ID. 7339 + */ 7340 + loadServiceFromID = (id: ServiceID): Service => { 7341 + return new Service({ 7342 + queryTree: [ 7343 + ...this._queryTree, 7344 + { 7345 + operation: "loadServiceFromID", 7346 + args: { id }, 7347 + }, 7348 + ], 7349 + ctx: this._ctx, 7350 + }); 7351 + }; 7352 + 7353 + /** 7354 + * Load a Socket from its ID. 7355 + */ 7356 + loadSocketFromID = (id: SocketID): Socket => { 7357 + return new Socket({ 7358 + queryTree: [ 7359 + ...this._queryTree, 7360 + { 7361 + operation: "loadSocketFromID", 7362 + args: { id }, 7363 + }, 7364 + ], 7365 + ctx: this._ctx, 7366 + }); 7367 + }; 7368 + 7369 + /** 7370 + * Load a Terminal from its ID. 7371 + */ 7372 + loadTerminalFromID = (id: TerminalID): Terminal => { 7373 + return new Terminal({ 7374 + queryTree: [ 7375 + ...this._queryTree, 7376 + { 7377 + operation: "loadTerminalFromID", 7378 + args: { id }, 7379 + }, 7380 + ], 7381 + ctx: this._ctx, 7382 + }); 7383 + }; 7384 + 7385 + /** 7386 + * Load a TypeDef from its ID. 7387 + */ 7388 + loadTypeDefFromID = (id: TypeDefID): TypeDef => { 7389 + return new TypeDef({ 7390 + queryTree: [ 7391 + ...this._queryTree, 7392 + { 7393 + operation: "loadTypeDefFromID", 7394 + args: { id }, 7395 + }, 7396 + ], 7397 + ctx: this._ctx, 7398 + }); 7399 + }; 7400 + 7401 + /** 7402 + * Create a new module. 7403 + */ 7404 + module_ = (): Module_ => { 7405 + return new Module_({ 7406 + queryTree: [ 7407 + ...this._queryTree, 7408 + { 7409 + operation: "module", 7410 + }, 7411 + ], 7412 + ctx: this._ctx, 7413 + }); 7414 + }; 7415 + 7416 + /** 7417 + * Create a new module dependency configuration from a module source and name 7418 + * @param source The source of the dependency 7419 + * @param opts.name If set, the name to use for the dependency. Otherwise, once installed to a parent module, the name of the dependency module will be used by default. 7420 + */ 7421 + moduleDependency = ( 7422 + source: ModuleSource, 7423 + opts?: ClientModuleDependencyOpts 7424 + ): ModuleDependency => { 7425 + return new ModuleDependency({ 7426 + queryTree: [ 7427 + ...this._queryTree, 7428 + { 7429 + operation: "moduleDependency", 7430 + args: { source, ...opts }, 7431 + }, 7432 + ], 7433 + ctx: this._ctx, 7434 + }); 7435 + }; 7436 + 7437 + /** 7438 + * Create a new module source instance from a source ref string. 7439 + * @param refString The string ref representation of the module source 7440 + * @param opts.stable If true, enforce that the source is a stable version for source kinds that support versioning. 7441 + */ 7442 + moduleSource = ( 7443 + refString: string, 7444 + opts?: ClientModuleSourceOpts 7445 + ): ModuleSource => { 7446 + return new ModuleSource({ 7447 + queryTree: [ 7448 + ...this._queryTree, 7449 + { 7450 + operation: "moduleSource", 7451 + args: { refString, ...opts }, 7452 + }, 7453 + ], 7454 + ctx: this._ctx, 7455 + }); 7456 + }; 7457 + 7458 + /** 7459 + * Creates a named sub-pipeline. 7460 + * @param name Name of the sub-pipeline. 7461 + * @param opts.description Description of the sub-pipeline. 7462 + * @param opts.labels Labels to apply to the sub-pipeline. 7463 + */ 7464 + pipeline = (name: string, opts?: ClientPipelineOpts): Client => { 7465 + return new Client({ 7466 + queryTree: [ 7467 + ...this._queryTree, 7468 + { 7469 + operation: "pipeline", 7470 + args: { name, ...opts }, 7471 + }, 7472 + ], 7473 + ctx: this._ctx, 7474 + }); 7475 + }; 7476 + 7477 + /** 7478 + * Reference a secret by name. 7479 + */ 7480 + secret = (name: string, opts?: ClientSecretOpts): Secret => { 7481 + return new Secret({ 7482 + queryTree: [ 7483 + ...this._queryTree, 7484 + { 7485 + operation: "secret", 7486 + args: { name, ...opts }, 7487 + }, 7488 + ], 7489 + ctx: this._ctx, 7490 + }); 7491 + }; 7492 + 7493 + /** 7494 + * Sets a secret given a user defined name to its plaintext and returns the secret. 7495 + * 7496 + * The plaintext value is limited to a size of 128000 bytes. 7497 + * @param name The user defined name for this secret 7498 + * @param plaintext The plaintext of the secret 7499 + */ 7500 + setSecret = (name: string, plaintext: string): Secret => { 7501 + return new Secret({ 7502 + queryTree: [ 7503 + ...this._queryTree, 7504 + { 7505 + operation: "setSecret", 7506 + args: { name, plaintext }, 7507 + }, 7508 + ], 7509 + ctx: this._ctx, 7510 + }); 7511 + }; 7512 + 7513 + /** 7514 + * Loads a socket by its ID. 7515 + * @deprecated Use loadSocketFromID instead. 7516 + */ 7517 + socket = (id: SocketID): Socket => { 7518 + return new Socket({ 7519 + queryTree: [ 7520 + ...this._queryTree, 7521 + { 7522 + operation: "socket", 7523 + args: { id }, 7524 + }, 7525 + ], 7526 + ctx: this._ctx, 7527 + }); 7528 + }; 7529 + 7530 + /** 7531 + * Create a new TypeDef. 7532 + */ 7533 + typeDef = (): TypeDef => { 7534 + return new TypeDef({ 7535 + queryTree: [ 7536 + ...this._queryTree, 7537 + { 7538 + operation: "typeDef", 7539 + }, 7540 + ], 7541 + ctx: this._ctx, 7542 + }); 7543 + }; 7544 + 7545 + /** 7546 + * Call the provided function with current Client. 7547 + * 7548 + * This is useful for reusability and readability by not breaking the calling chain. 7549 + */ 7550 + with = (arg: (param: Client) => Client) => { 7551 + return arg(this); 7552 + }; 7553 + } 7554 + 7555 + /** 7556 + * A reference to a secret value, which can be handled more safely than the value itself. 7557 + */ 7558 + export class Secret extends BaseClient { 7559 + private readonly _id?: SecretID = undefined; 7560 + private readonly _plaintext?: string = undefined; 7561 + 7562 + /** 7563 + * Constructor is used for internal usage only, do not create object from it. 7564 + */ 7565 + constructor( 7566 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 7567 + _id?: SecretID, 7568 + _plaintext?: string 7569 + ) { 7570 + super(parent); 7571 + 7572 + this._id = _id; 7573 + this._plaintext = _plaintext; 7574 + } 7575 + 7576 + /** 7577 + * A unique identifier for this Secret. 7578 + */ 7579 + id = async (): Promise<SecretID> => { 7580 + if (this._id) { 7581 + return this._id; 7582 + } 7583 + 7584 + const response: Awaited<SecretID> = await computeQuery( 7585 + [ 7586 + ...this._queryTree, 7587 + { 7588 + operation: "id", 7589 + }, 7590 + ], 7591 + await this._ctx.connection() 7592 + ); 7593 + 7594 + return response; 7595 + }; 7596 + 7597 + /** 7598 + * The value of this secret. 7599 + */ 7600 + plaintext = async (): Promise<string> => { 7601 + if (this._plaintext) { 7602 + return this._plaintext; 7603 + } 7604 + 7605 + const response: Awaited<string> = await computeQuery( 7606 + [ 7607 + ...this._queryTree, 7608 + { 7609 + operation: "plaintext", 7610 + }, 7611 + ], 7612 + await this._ctx.connection() 7613 + ); 7614 + 7615 + return response; 7616 + }; 7617 + } 7618 + 7619 + /** 7620 + * A content-addressed service providing TCP connectivity. 7621 + */ 7622 + export class Service extends BaseClient { 7623 + private readonly _id?: ServiceID = undefined; 7624 + private readonly _endpoint?: string = undefined; 7625 + private readonly _hostname?: string = undefined; 7626 + private readonly _start?: ServiceID = undefined; 7627 + private readonly _stop?: ServiceID = undefined; 7628 + private readonly _up?: Void = undefined; 7629 + 7630 + /** 7631 + * Constructor is used for internal usage only, do not create object from it. 7632 + */ 7633 + constructor( 7634 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 7635 + _id?: ServiceID, 7636 + _endpoint?: string, 7637 + _hostname?: string, 7638 + _start?: ServiceID, 7639 + _stop?: ServiceID, 7640 + _up?: Void 7641 + ) { 7642 + super(parent); 7643 + 7644 + this._id = _id; 7645 + this._endpoint = _endpoint; 7646 + this._hostname = _hostname; 7647 + this._start = _start; 7648 + this._stop = _stop; 7649 + this._up = _up; 7650 + } 7651 + 7652 + /** 7653 + * A unique identifier for this Service. 7654 + */ 7655 + id = async (): Promise<ServiceID> => { 7656 + if (this._id) { 7657 + return this._id; 7658 + } 7659 + 7660 + const response: Awaited<ServiceID> = await computeQuery( 7661 + [ 7662 + ...this._queryTree, 7663 + { 7664 + operation: "id", 7665 + }, 7666 + ], 7667 + await this._ctx.connection() 7668 + ); 7669 + 7670 + return response; 7671 + }; 7672 + 7673 + /** 7674 + * Retrieves an endpoint that clients can use to reach this container. 7675 + * 7676 + * If no port is specified, the first exposed port is used. If none exist an error is returned. 7677 + * 7678 + * If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. 7679 + * @param opts.port The exposed port number for the endpoint 7680 + * @param opts.scheme Return a URL with the given scheme, eg. http for http:// 7681 + */ 7682 + endpoint = async (opts?: ServiceEndpointOpts): Promise<string> => { 7683 + if (this._endpoint) { 7684 + return this._endpoint; 7685 + } 7686 + 7687 + const response: Awaited<string> = await computeQuery( 7688 + [ 7689 + ...this._queryTree, 7690 + { 7691 + operation: "endpoint", 7692 + args: { ...opts }, 7693 + }, 7694 + ], 7695 + await this._ctx.connection() 7696 + ); 7697 + 7698 + return response; 7699 + }; 7700 + 7701 + /** 7702 + * Retrieves a hostname which can be used by clients to reach this container. 7703 + */ 7704 + hostname = async (): Promise<string> => { 7705 + if (this._hostname) { 7706 + return this._hostname; 7707 + } 7708 + 7709 + const response: Awaited<string> = await computeQuery( 7710 + [ 7711 + ...this._queryTree, 7712 + { 7713 + operation: "hostname", 7714 + }, 7715 + ], 7716 + await this._ctx.connection() 7717 + ); 7718 + 7719 + return response; 7720 + }; 7721 + 7722 + /** 7723 + * Retrieves the list of ports provided by the service. 7724 + */ 7725 + ports = async (): Promise<Port[]> => { 7726 + type ports = { 7727 + id: PortID; 7728 + }; 7729 + 7730 + const response: Awaited<ports[]> = await computeQuery( 7731 + [ 7732 + ...this._queryTree, 7733 + { 7734 + operation: "ports", 7735 + }, 7736 + { 7737 + operation: "id", 7738 + }, 7739 + ], 7740 + await this._ctx.connection() 7741 + ); 7742 + 7743 + return response.map( 7744 + (r) => 7745 + new Port( 7746 + { 7747 + queryTree: [ 7748 + { 7749 + operation: "loadPortFromID", 7750 + args: { id: r.id }, 7751 + }, 7752 + ], 7753 + ctx: this._ctx, 7754 + }, 7755 + r.id 7756 + ) 7757 + ); 7758 + }; 7759 + 7760 + /** 7761 + * Start the service and wait for its health checks to succeed. 7762 + * 7763 + * Services bound to a Container do not need to be manually started. 7764 + */ 7765 + start = async (): Promise<Service> => { 7766 + await computeQuery( 7767 + [ 7768 + ...this._queryTree, 7769 + { 7770 + operation: "start", 7771 + }, 7772 + ], 7773 + await this._ctx.connection() 7774 + ); 7775 + 7776 + return this; 7777 + }; 7778 + 7779 + /** 7780 + * Stop the service. 7781 + * @param opts.kill Immediately kill the service without waiting for a graceful exit 7782 + */ 7783 + stop = async (opts?: ServiceStopOpts): Promise<Service> => { 7784 + await computeQuery( 7785 + [ 7786 + ...this._queryTree, 7787 + { 7788 + operation: "stop", 7789 + args: { ...opts }, 7790 + }, 7791 + ], 7792 + await this._ctx.connection() 7793 + ); 7794 + 7795 + return this; 7796 + }; 7797 + 7798 + /** 7799 + * Creates a tunnel that forwards traffic from the caller's network to this service. 7800 + * @param opts.ports List of frontend/backend port mappings to forward. 7801 + * 7802 + * Frontend is the port accepting traffic on the host, backend is the service port. 7803 + * @param opts.random Bind each tunnel port to a random port on the host. 7804 + */ 7805 + up = async (opts?: ServiceUpOpts): Promise<Void> => { 7806 + if (this._up) { 7807 + return this._up; 7808 + } 7809 + 7810 + const response: Awaited<Void> = await computeQuery( 7811 + [ 7812 + ...this._queryTree, 7813 + { 7814 + operation: "up", 7815 + args: { ...opts }, 7816 + }, 7817 + ], 7818 + await this._ctx.connection() 7819 + ); 7820 + 7821 + return response; 7822 + }; 7823 + } 7824 + 7825 + /** 7826 + * A Unix or TCP/IP socket that can be mounted into a container. 7827 + */ 7828 + export class Socket extends BaseClient { 7829 + private readonly _id?: SocketID = undefined; 7830 + 7831 + /** 7832 + * Constructor is used for internal usage only, do not create object from it. 7833 + */ 7834 + constructor( 7835 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 7836 + _id?: SocketID 7837 + ) { 7838 + super(parent); 7839 + 7840 + this._id = _id; 7841 + } 7842 + 7843 + /** 7844 + * A unique identifier for this Socket. 7845 + */ 7846 + id = async (): Promise<SocketID> => { 7847 + if (this._id) { 7848 + return this._id; 7849 + } 7850 + 7851 + const response: Awaited<SocketID> = await computeQuery( 7852 + [ 7853 + ...this._queryTree, 7854 + { 7855 + operation: "id", 7856 + }, 7857 + ], 7858 + await this._ctx.connection() 7859 + ); 7860 + 7861 + return response; 7862 + }; 7863 + } 7864 + 7865 + /** 7866 + * An interactive terminal that clients can connect to. 7867 + */ 7868 + export class Terminal extends BaseClient { 7869 + private readonly _id?: TerminalID = undefined; 7870 + private readonly _websocketEndpoint?: string = undefined; 7871 + 7872 + /** 7873 + * Constructor is used for internal usage only, do not create object from it. 7874 + */ 7875 + constructor( 7876 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 7877 + _id?: TerminalID, 7878 + _websocketEndpoint?: string 7879 + ) { 7880 + super(parent); 7881 + 7882 + this._id = _id; 7883 + this._websocketEndpoint = _websocketEndpoint; 7884 + } 7885 + 7886 + /** 7887 + * A unique identifier for this Terminal. 7888 + */ 7889 + id = async (): Promise<TerminalID> => { 7890 + if (this._id) { 7891 + return this._id; 7892 + } 7893 + 7894 + const response: Awaited<TerminalID> = await computeQuery( 7895 + [ 7896 + ...this._queryTree, 7897 + { 7898 + operation: "id", 7899 + }, 7900 + ], 7901 + await this._ctx.connection() 7902 + ); 7903 + 7904 + return response; 7905 + }; 7906 + 7907 + /** 7908 + * An http endpoint at which this terminal can be connected to over a websocket. 7909 + */ 7910 + websocketEndpoint = async (): Promise<string> => { 7911 + if (this._websocketEndpoint) { 7912 + return this._websocketEndpoint; 7913 + } 7914 + 7915 + const response: Awaited<string> = await computeQuery( 7916 + [ 7917 + ...this._queryTree, 7918 + { 7919 + operation: "websocketEndpoint", 7920 + }, 7921 + ], 7922 + await this._ctx.connection() 7923 + ); 7924 + 7925 + return response; 7926 + }; 7927 + } 7928 + 7929 + /** 7930 + * A definition of a parameter or return type in a Module. 7931 + */ 7932 + export class TypeDef extends BaseClient { 7933 + private readonly _id?: TypeDefID = undefined; 7934 + private readonly _kind?: TypeDefKind = undefined; 7935 + private readonly _optional?: boolean = undefined; 7936 + 7937 + /** 7938 + * Constructor is used for internal usage only, do not create object from it. 7939 + */ 7940 + constructor( 7941 + parent?: { queryTree?: QueryTree[]; ctx: Context }, 7942 + _id?: TypeDefID, 7943 + _kind?: TypeDefKind, 7944 + _optional?: boolean 7945 + ) { 7946 + super(parent); 7947 + 7948 + this._id = _id; 7949 + this._kind = _kind; 7950 + this._optional = _optional; 7951 + } 7952 + 7953 + /** 7954 + * A unique identifier for this TypeDef. 7955 + */ 7956 + id = async (): Promise<TypeDefID> => { 7957 + if (this._id) { 7958 + return this._id; 7959 + } 7960 + 7961 + const response: Awaited<TypeDefID> = await computeQuery( 7962 + [ 7963 + ...this._queryTree, 7964 + { 7965 + operation: "id", 7966 + }, 7967 + ], 7968 + await this._ctx.connection() 7969 + ); 7970 + 7971 + return response; 7972 + }; 7973 + 7974 + /** 7975 + * If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. 7976 + */ 7977 + asInput = (): InputTypeDef => { 7978 + return new InputTypeDef({ 7979 + queryTree: [ 7980 + ...this._queryTree, 7981 + { 7982 + operation: "asInput", 7983 + }, 7984 + ], 7985 + ctx: this._ctx, 7986 + }); 7987 + }; 7988 + 7989 + /** 7990 + * If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. 7991 + */ 7992 + asInterface = (): InterfaceTypeDef => { 7993 + return new InterfaceTypeDef({ 7994 + queryTree: [ 7995 + ...this._queryTree, 7996 + { 7997 + operation: "asInterface", 7998 + }, 7999 + ], 8000 + ctx: this._ctx, 8001 + }); 8002 + }; 8003 + 8004 + /** 8005 + * If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. 8006 + */ 8007 + asList = (): ListTypeDef => { 8008 + return new ListTypeDef({ 8009 + queryTree: [ 8010 + ...this._queryTree, 8011 + { 8012 + operation: "asList", 8013 + }, 8014 + ], 8015 + ctx: this._ctx, 8016 + }); 8017 + }; 8018 + 8019 + /** 8020 + * If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. 8021 + */ 8022 + asObject = (): ObjectTypeDef => { 8023 + return new ObjectTypeDef({ 8024 + queryTree: [ 8025 + ...this._queryTree, 8026 + { 8027 + operation: "asObject", 8028 + }, 8029 + ], 8030 + ctx: this._ctx, 8031 + }); 8032 + }; 8033 + 8034 + /** 8035 + * The kind of type this is (e.g. primitive, list, object). 8036 + */ 8037 + kind = async (): Promise<TypeDefKind> => { 8038 + if (this._kind) { 8039 + return this._kind; 8040 + } 8041 + 8042 + const response: Awaited<TypeDefKind> = await computeQuery( 8043 + [ 8044 + ...this._queryTree, 8045 + { 8046 + operation: "kind", 8047 + }, 8048 + ], 8049 + await this._ctx.connection() 8050 + ); 8051 + 8052 + return response; 8053 + }; 8054 + 8055 + /** 8056 + * Whether this type can be set to null. Defaults to false. 8057 + */ 8058 + optional = async (): Promise<boolean> => { 8059 + if (this._optional) { 8060 + return this._optional; 8061 + } 8062 + 8063 + const response: Awaited<boolean> = await computeQuery( 8064 + [ 8065 + ...this._queryTree, 8066 + { 8067 + operation: "optional", 8068 + }, 8069 + ], 8070 + await this._ctx.connection() 8071 + ); 8072 + 8073 + return response; 8074 + }; 8075 + 8076 + /** 8077 + * Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. 8078 + */ 8079 + withConstructor = (function_: Function_): TypeDef => { 8080 + return new TypeDef({ 8081 + queryTree: [ 8082 + ...this._queryTree, 8083 + { 8084 + operation: "withConstructor", 8085 + args: { 8086 + function: function_, 8087 + }, 8088 + }, 8089 + ], 8090 + ctx: this._ctx, 8091 + }); 8092 + }; 8093 + 8094 + /** 8095 + * Adds a static field for an Object TypeDef, failing if the type is not an object. 8096 + * @param name The name of the field in the object 8097 + * @param typeDef The type of the field 8098 + * @param opts.description A doc string for the field, if any 8099 + */ 8100 + withField = ( 8101 + name: string, 8102 + typeDef: TypeDef, 8103 + opts?: TypeDefWithFieldOpts 8104 + ): TypeDef => { 8105 + return new TypeDef({ 8106 + queryTree: [ 8107 + ...this._queryTree, 8108 + { 8109 + operation: "withField", 8110 + args: { name, typeDef, ...opts }, 8111 + }, 8112 + ], 8113 + ctx: this._ctx, 8114 + }); 8115 + }; 8116 + 8117 + /** 8118 + * Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. 8119 + */ 8120 + withFunction = (function_: Function_): TypeDef => { 8121 + return new TypeDef({ 8122 + queryTree: [ 8123 + ...this._queryTree, 8124 + { 8125 + operation: "withFunction", 8126 + args: { 8127 + function: function_, 8128 + }, 8129 + }, 8130 + ], 8131 + ctx: this._ctx, 8132 + }); 8133 + }; 8134 + 8135 + /** 8136 + * Returns a TypeDef of kind Interface with the provided name. 8137 + */ 8138 + withInterface = (name: string, opts?: TypeDefWithInterfaceOpts): TypeDef => { 8139 + return new TypeDef({ 8140 + queryTree: [ 8141 + ...this._queryTree, 8142 + { 8143 + operation: "withInterface", 8144 + args: { name, ...opts }, 8145 + }, 8146 + ], 8147 + ctx: this._ctx, 8148 + }); 8149 + }; 8150 + 8151 + /** 8152 + * Sets the kind of the type. 8153 + */ 8154 + withKind = (kind: TypeDefKind): TypeDef => { 8155 + const metadata: Metadata = { 8156 + kind: { is_enum: true }, 8157 + }; 8158 + 8159 + return new TypeDef({ 8160 + queryTree: [ 8161 + ...this._queryTree, 8162 + { 8163 + operation: "withKind", 8164 + args: { kind, __metadata: metadata }, 8165 + }, 8166 + ], 8167 + ctx: this._ctx, 8168 + }); 8169 + }; 8170 + 8171 + /** 8172 + * Returns a TypeDef of kind List with the provided type for its elements. 8173 + */ 8174 + withListOf = (elementType: TypeDef): TypeDef => { 8175 + return new TypeDef({ 8176 + queryTree: [ 8177 + ...this._queryTree, 8178 + { 8179 + operation: "withListOf", 8180 + args: { elementType }, 8181 + }, 8182 + ], 8183 + ctx: this._ctx, 8184 + }); 8185 + }; 8186 + 8187 + /** 8188 + * Returns a TypeDef of kind Object with the provided name. 8189 + * 8190 + * Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. 8191 + */ 8192 + withObject = (name: string, opts?: TypeDefWithObjectOpts): TypeDef => { 8193 + return new TypeDef({ 8194 + queryTree: [ 8195 + ...this._queryTree, 8196 + { 8197 + operation: "withObject", 8198 + args: { name, ...opts }, 8199 + }, 8200 + ], 8201 + ctx: this._ctx, 8202 + }); 8203 + }; 8204 + 8205 + /** 8206 + * Sets whether this type can be set to null. 8207 + */ 8208 + withOptional = (optional: boolean): TypeDef => { 8209 + return new TypeDef({ 8210 + queryTree: [ 8211 + ...this._queryTree, 8212 + { 8213 + operation: "withOptional", 8214 + args: { optional }, 8215 + }, 8216 + ], 8217 + ctx: this._ctx, 8218 + }); 8219 + }; 8220 + 8221 + /** 8222 + * Call the provided function with current TypeDef. 8223 + * 8224 + * This is useful for reusability and readability by not breaking the calling chain. 8225 + */ 8226 + with = (arg: (param: TypeDef) => TypeDef) => { 8227 + return arg(this); 8228 + }; 8229 + } 8230 + 8231 + export const dag = new Client({ ctx: defaultContext });
+9
.fluentci/sdk/client.ts
··· 1 + import { GraphQLClient } from "../deps.ts"; 2 + 3 + export function createGQLClient(port: number, token: string): GraphQLClient { 4 + return new GraphQLClient(`http://127.0.0.1:${port}/query`, { 5 + headers: { 6 + Authorization: "Basic " + btoa(token + ":"), 7 + }, 8 + }); 9 + }
+46
.fluentci/sdk/common/errors/DaggerSDKError.ts
··· 1 + import { log } from "../utils.ts"; 2 + import { ErrorCodes, ErrorNames } from "./errors-codes.ts"; 3 + 4 + export interface DaggerSDKErrorOptions { 5 + cause?: Error; 6 + } 7 + 8 + /** 9 + * The base error. Every other error inherits this error. 10 + */ 11 + export abstract class DaggerSDKError extends Error { 12 + /** 13 + * The name of the dagger error. 14 + */ 15 + abstract readonly name: ErrorNames; 16 + 17 + /** 18 + * The dagger specific error code. 19 + * Use this to identify dagger errors programmatically. 20 + */ 21 + abstract readonly code: ErrorCodes; 22 + 23 + /** 24 + * The original error, which caused the DaggerSDKError. 25 + */ 26 + cause?: Error; 27 + 28 + protected constructor(message: string, options?: DaggerSDKErrorOptions) { 29 + super(message); 30 + this.cause = options?.cause; 31 + } 32 + 33 + /** 34 + * @hidden 35 + */ 36 + get [Symbol.toStringTag]() { 37 + return this.name; 38 + } 39 + 40 + /** 41 + * Pretty prints the error 42 + */ 43 + printStackTrace() { 44 + log(this.stack); 45 + } 46 + }
+28
.fluentci/sdk/common/errors/DockerImageRefValidationError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts" 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts" 3 + 4 + interface DockerImageRefValidationErrorOptions extends DaggerSDKErrorOptions { 5 + ref: string 6 + } 7 + 8 + /** 9 + * This error is thrown if the passed image reference does not pass validation and is not compliant with the 10 + * DockerImage constructor. 11 + */ 12 + export class DockerImageRefValidationError extends DaggerSDKError { 13 + name = ERROR_NAMES.DockerImageRefValidationError 14 + code = ERROR_CODES.DockerImageRefValidationError 15 + 16 + /** 17 + * The docker image reference, which caused the error. 18 + */ 19 + ref: string 20 + 21 + /** 22 + * @hidden 23 + */ 24 + constructor(message: string, options: DockerImageRefValidationErrorOptions) { 25 + super(message, options) 26 + this.ref = options?.ref 27 + } 28 + }
+31
.fluentci/sdk/common/errors/EngineSessionConnectParamsParseError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + interface EngineSessionConnectParamsParseErrorOptions 5 + extends DaggerSDKErrorOptions { 6 + parsedLine: string; 7 + } 8 + 9 + /** 10 + * This error is thrown if the EngineSession does not manage to parse the required connection parameters from the session binary 11 + */ 12 + export class EngineSessionConnectParamsParseError extends DaggerSDKError { 13 + name = ERROR_NAMES.EngineSessionConnectParamsParseError; 14 + code = ERROR_CODES.EngineSessionConnectParamsParseError; 15 + 16 + /** 17 + * the line, which caused the error during parsing, if the error was caused because of parsing. 18 + */ 19 + parsedLine: string; 20 + 21 + /** 22 + * @hidden 23 + */ 24 + constructor( 25 + message: string, 26 + options: EngineSessionConnectParamsParseErrorOptions 27 + ) { 28 + super(message, options); 29 + this.parsedLine = options.parsedLine; 30 + } 31 + }
+31
.fluentci/sdk/common/errors/EngineSessionConnectionTimeoutError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + interface EngineSessionConnectionTimeoutErrorOptions 5 + extends DaggerSDKErrorOptions { 6 + timeOutDuration: number; 7 + } 8 + 9 + /** 10 + * This error is thrown if the EngineSession does not manage to parse the required port successfully because the sessions connection timed out. 11 + */ 12 + export class EngineSessionConnectionTimeoutError extends DaggerSDKError { 13 + name = ERROR_NAMES.EngineSessionConnectionTimeoutError; 14 + code = ERROR_CODES.EngineSessionConnectionTimeoutError; 15 + 16 + /** 17 + * The duration until the timeout occurred in ms. 18 + */ 19 + timeOutDuration: number; 20 + 21 + /** 22 + * @hidden 23 + */ 24 + constructor( 25 + message: string, 26 + options: EngineSessionConnectionTimeoutErrorOptions 27 + ) { 28 + super(message, options); 29 + this.timeOutDuration = options.timeOutDuration; 30 + } 31 + }
+20
.fluentci/sdk/common/errors/EngineSessionErrorOptions.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + type EngineSessionErrorOptions = DaggerSDKErrorOptions; 5 + 6 + /** 7 + * This error is thrown if the EngineSession does not manage to parse the required port successfully because a EOF is read before any valid port. 8 + * This usually happens if no connection can be established. 9 + */ 10 + export class EngineSessionError extends DaggerSDKError { 11 + name = ERROR_NAMES.EngineSessionError; 12 + code = ERROR_CODES.EngineSessionError; 13 + 14 + /** 15 + * @hidden 16 + */ 17 + constructor(message: string, options?: EngineSessionErrorOptions) { 18 + super(message, options); 19 + } 20 + }
+54
.fluentci/sdk/common/errors/ExecError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + interface ExecErrorOptions extends DaggerSDKErrorOptions { 5 + cmd: string[]; 6 + exitCode: number; 7 + stdout: string; 8 + stderr: string; 9 + } 10 + 11 + /** 12 + * API error from an exec operation in a pipeline. 13 + */ 14 + export class ExecError extends DaggerSDKError { 15 + name = ERROR_NAMES.ExecError; 16 + code = ERROR_CODES.ExecError; 17 + 18 + /** 19 + * The command that caused the error. 20 + */ 21 + cmd: string[]; 22 + 23 + /** 24 + * The exit code of the command. 25 + */ 26 + exitCode: number; 27 + 28 + /** 29 + * The stdout of the command. 30 + */ 31 + stdout: string; 32 + 33 + /** 34 + * The stderr of the command. 35 + */ 36 + stderr: string; 37 + 38 + /** 39 + * @hidden 40 + */ 41 + constructor(message: string, options: ExecErrorOptions) { 42 + super(message, options); 43 + this.cmd = options.cmd; 44 + this.exitCode = options.exitCode; 45 + this.stdout = options.stdout; 46 + this.stderr = options.stderr; 47 + } 48 + 49 + toString(): string { 50 + return `${super.toString()}\nStdout:\n${this.stdout}\nStderr:\n${ 51 + this.stderr 52 + }`; 53 + } 54 + }
+36
.fluentci/sdk/common/errors/GraphQLRequestError.ts
··· 1 + import { GraphQLRequestContext, GraphQLResponse } from "./types.ts"; 2 + 3 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 4 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 5 + 6 + interface GraphQLRequestErrorOptions extends DaggerSDKErrorOptions { 7 + response: GraphQLResponse; 8 + request: GraphQLRequestContext; 9 + } 10 + 11 + /** 12 + * This error originates from the dagger engine. It means that some error was thrown and sent back via GraphQL. 13 + */ 14 + export class GraphQLRequestError extends DaggerSDKError { 15 + name = ERROR_NAMES.GraphQLRequestError; 16 + code = ERROR_CODES.GraphQLRequestError; 17 + 18 + /** 19 + * The query and variables, which caused the error. 20 + */ 21 + requestContext: GraphQLRequestContext; 22 + 23 + /** 24 + * the GraphQL response containing the error. 25 + */ 26 + response: GraphQLResponse; 27 + 28 + /** 29 + * @hidden 30 + */ 31 + constructor(message: string, options: GraphQLRequestErrorOptions) { 32 + super(message, options); 33 + this.requestContext = options.request; 34 + this.response = options.response; 35 + } 36 + }
+17
.fluentci/sdk/common/errors/InitEngineSessionBinaryError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + /** 5 + * This error is thrown if the dagger binary cannot be copied from the dagger docker image and copied to the local host. 6 + */ 7 + export class InitEngineSessionBinaryError extends DaggerSDKError { 8 + name = ERROR_NAMES.InitEngineSessionBinaryError; 9 + code = ERROR_CODES.InitEngineSessionBinaryError; 10 + 11 + /** 12 + * @hidden 13 + */ 14 + constructor(message: string, options?: DaggerSDKErrorOptions) { 15 + super(message, options); 16 + } 17 + }
+17
.fluentci/sdk/common/errors/NotAwaitedRequestError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + /** 5 + * This error is thrown when the compute function isn't awaited. 6 + */ 7 + export class NotAwaitedRequestError extends DaggerSDKError { 8 + name = ERROR_NAMES.NotAwaitedRequestError; 9 + code = ERROR_CODES.NotAwaitedRequestError; 10 + 11 + /** 12 + * @hidden 13 + */ 14 + constructor(message: string, options?: DaggerSDKErrorOptions) { 15 + super(message, options); 16 + } 17 + }
+27
.fluentci/sdk/common/errors/TooManyNestedObjectsError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + interface TooManyNestedObjectsErrorOptions extends DaggerSDKErrorOptions { 5 + response: unknown; 6 + } 7 + 8 + /** 9 + * Dagger only expects one response value from the engine. If the engine returns more than one value this error is thrown. 10 + */ 11 + export class TooManyNestedObjectsError extends DaggerSDKError { 12 + name = ERROR_NAMES.TooManyNestedObjectsError; 13 + code = ERROR_CODES.TooManyNestedObjectsError; 14 + 15 + /** 16 + * the response containing more than one value. 17 + */ 18 + response: unknown; 19 + 20 + /** 21 + * @hidden 22 + */ 23 + constructor(message: string, options: TooManyNestedObjectsErrorOptions) { 24 + super(message, options); 25 + this.response = options.response; 26 + } 27 + }
+17
.fluentci/sdk/common/errors/UnknownDaggerError.ts
··· 1 + import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.ts"; 2 + import { ERROR_CODES, ERROR_NAMES } from "./errors-codes.ts"; 3 + 4 + /** 5 + * This error is thrown if the dagger SDK does not identify the error and just wraps the cause. 6 + */ 7 + export class UnknownDaggerError extends DaggerSDKError { 8 + name = ERROR_NAMES.UnknownDaggerError; 9 + code = ERROR_CODES.UnknownDaggerError; 10 + 11 + /** 12 + * @hidden 13 + */ 14 + constructor(message: string, options: DaggerSDKErrorOptions) { 15 + super(message, options); 16 + } 17 + }
+63
.fluentci/sdk/common/errors/errors-codes.ts
··· 1 + export const ERROR_CODES = { 2 + /** 3 + * {@link GraphQLRequestError} 4 + */ 5 + GraphQLRequestError: "D100", 6 + 7 + /** 8 + * {@link UnknownDaggerError} 9 + */ 10 + UnknownDaggerError: "D101", 11 + 12 + /** 13 + * {@link TooManyNestedObjectsError} 14 + */ 15 + TooManyNestedObjectsError: "D102", 16 + 17 + /** 18 + * {@link EngineSessionConnectParamsParseError} 19 + */ 20 + EngineSessionConnectParamsParseError: "D103", 21 + 22 + /** 23 + * {@link EngineSessionConnectionTimeoutError} 24 + */ 25 + EngineSessionConnectionTimeoutError: "D104", 26 + 27 + /** 28 + * {@link EngineSessionError} 29 + */ 30 + EngineSessionError: "D105", 31 + 32 + /** 33 + * {@link InitEngineSessionBinaryError} 34 + */ 35 + InitEngineSessionBinaryError: "D106", 36 + 37 + /** 38 + * {@link DockerImageRefValidationError} 39 + */ 40 + DockerImageRefValidationError: "D107", 41 + 42 + /** 43 + * {@link NotAwaitedRequestError} 44 + */ 45 + NotAwaitedRequestError: "D108", 46 + 47 + /** 48 + * (@link ExecError} 49 + */ 50 + ExecError: "D109", 51 + } as const 52 + 53 + type ErrorCodesType = typeof ERROR_CODES 54 + export type ErrorNames = keyof ErrorCodesType 55 + export type ErrorCodes = ErrorCodesType[ErrorNames] 56 + 57 + type ErrorNamesMap = { readonly [Key in ErrorNames]: Key } 58 + export const ERROR_NAMES: ErrorNamesMap = ( 59 + Object.keys(ERROR_CODES) as Array<ErrorNames> 60 + ).reduce<ErrorNamesMap>( 61 + (obj, item) => ({ ...obj, [item]: item }), 62 + {} as ErrorNamesMap 63 + )
+12
.fluentci/sdk/common/errors/index.ts
··· 1 + export { DaggerSDKError } from "./DaggerSDKError.ts"; 2 + export { UnknownDaggerError } from "./UnknownDaggerError.ts"; 3 + export { DockerImageRefValidationError } from "./DockerImageRefValidationError.ts"; 4 + export { EngineSessionConnectParamsParseError } from "./EngineSessionConnectParamsParseError.ts"; 5 + export { ExecError } from "./ExecError.ts"; 6 + export { GraphQLRequestError } from "./GraphQLRequestError.ts"; 7 + export { InitEngineSessionBinaryError } from "./InitEngineSessionBinaryError.ts"; 8 + export { TooManyNestedObjectsError } from "./TooManyNestedObjectsError.ts"; 9 + export { EngineSessionError } from "./EngineSessionErrorOptions.ts"; 10 + export { EngineSessionConnectionTimeoutError } from "./EngineSessionConnectionTimeoutError.ts"; 11 + export { NotAwaitedRequestError } from "./NotAwaitedRequestError.ts"; 12 + export { ERROR_CODES } from "./errors-codes.ts";
+16
.fluentci/sdk/common/errors/types.ts
··· 1 + import { GraphQLError } from "npm:graphql@16.8.1"; 2 + 3 + export interface GraphQLResponse<T = unknown> { 4 + data?: T; 5 + errors?: GraphQLError[]; 6 + extensions?: unknown; 7 + status: number; 8 + [key: string]: unknown; 9 + } 10 + 11 + export type Variables = Record<string, unknown>; 12 + 13 + export interface GraphQLRequestContext<V extends Variables = Variables> { 14 + query: string | string[]; 15 + variables?: V; 16 + }
+4
.fluentci/sdk/common/utils.ts
··· 1 + import logger from "npm:node-color-log@11.0.2"; 2 + 3 + export const log = (stack?: string) => 4 + logger.bgColor("red").color("black").log(stack);
+53
.fluentci/sdk/connect.ts
··· 1 + import { Writable } from "node:stream"; 2 + import { Client } from "./client.gen.ts"; 3 + import { Context } from "./context.ts"; 4 + 5 + /** 6 + * ConnectOpts defines option used to connect to an engine. 7 + */ 8 + export interface ConnectOpts { 9 + /** 10 + * Use to overwrite Dagger workdir 11 + * @defaultValue process.cwd() 12 + */ 13 + Workdir?: string; 14 + /** 15 + * Enable logs output 16 + * @example 17 + * LogOutput 18 + * ```ts 19 + * connect(async (client: Client) => { 20 + const source = await client.host().workdir().id() 21 + ... 22 + }, {LogOutput: process.stdout}) 23 + ``` 24 + */ 25 + LogOutput?: Writable; 26 + } 27 + 28 + export type CallbackFct = (client: Client) => Promise<void>; 29 + 30 + export interface ConnectParams { 31 + port: number; 32 + session_token: string; 33 + } 34 + 35 + /** 36 + * connect runs GraphQL server and initializes a 37 + * GraphQL client to execute query on it through its callback. 38 + * This implementation is based on the existing Go SDK. 39 + */ 40 + export async function connect( 41 + cb: CallbackFct, 42 + _config: ConnectOpts = {} 43 + ): Promise<void> { 44 + const ctx = new Context(); 45 + const client = new Client({ ctx: ctx }); 46 + 47 + // Initialize connection 48 + await ctx.connection(); 49 + 50 + await cb(client).finally(() => { 51 + ctx.close(); 52 + }); 53 + }
+53
.fluentci/sdk/context.ts
··· 1 + import { GraphQLClient } from "../deps.ts"; 2 + 3 + import { initDefaultContext } from "./builder.ts"; 4 + 5 + interface ContextConfig { 6 + client?: GraphQLClient; 7 + } 8 + 9 + /** 10 + * Context abstracts the connection to the engine. 11 + * 12 + * It's required to implement the default global SDK. 13 + * Its purpose is to store and returns the connection to the graphQL API, if 14 + * no connection is set, it can create its own. 15 + * 16 + * This is also useful for lazy evaluation with the default global client, 17 + * this one should only run the engine if it actually executes something. 18 + */ 19 + export class Context { 20 + private _client?: GraphQLClient; 21 + 22 + constructor(config?: ContextConfig) { 23 + this._client = config?.client; 24 + } 25 + 26 + /** 27 + * Returns a GraphQL client connected to the engine. 28 + * 29 + * If no client is set, it will create one. 30 + */ 31 + public async connection(): Promise<GraphQLClient> { 32 + if (!this._client) { 33 + const defaultCtx = await initDefaultContext(); 34 + this._client = defaultCtx._client as GraphQLClient; 35 + } 36 + 37 + return this._client; 38 + } 39 + 40 + /** 41 + * Close the connection and the engine if this one was started by the node 42 + * SDK. 43 + */ 44 + public close(): void { 45 + // Reset client, so it can restart a new connection if necessary 46 + this._client = undefined; 47 + } 48 + } 49 + 50 + /** 51 + * Expose a default context for the global client 52 + */ 53 + export const defaultContext = new Context();
+17
.fluentci/sdk/nix/example.ts
··· 1 + import Client from "../../deps.ts"; 2 + import { connect } from "../connect.ts"; 3 + import { withNix } from "./steps.ts"; 4 + 5 + connect(async (client: Client) => { 6 + const ctr = withNix( 7 + client 8 + .pipeline("nix-installer") 9 + .container() 10 + .from("alpine") 11 + .withExec(["apk", "add", "curl"]) 12 + ); 13 + 14 + const result = await ctr.stdout(); 15 + 16 + console.log(result); 17 + });
+19
.fluentci/sdk/nix/example_with_devbox.ts
··· 1 + import Client from "../../deps.ts"; 2 + import { connect } from "../connect.ts"; 3 + import { withDevbox } from "./steps.ts"; 4 + 5 + connect(async (client: Client) => { 6 + const ctr = withDevbox( 7 + client 8 + .pipeline("nix-installer") 9 + .container() 10 + .from("alpine") 11 + .withExec(["apk", "add", "curl", "bash"]) 12 + ) 13 + .withExec(["devbox", "global", "add", "gh"]) 14 + .withExec(["sh", "-c", 'eval "$(devbox global shellenv)" && gh version']); 15 + 16 + const result = await ctr.stdout(); 17 + 18 + console.log(result); 19 + });
+21
.fluentci/sdk/nix/example_with_devbox_pkg.ts
··· 1 + import Client from "../../deps.ts"; 2 + import { connect } from "../connect.ts"; 3 + import { withDevboxExec, withPackageFromDevbox } from "./steps.ts"; 4 + 5 + connect(async (client: Client) => { 6 + const ctr = withDevboxExec( 7 + withPackageFromDevbox( 8 + client 9 + .pipeline("nix-installer") 10 + .container() 11 + .from("alpine") 12 + .withExec(["apk", "add", "curl", "bash"]), 13 + ["gh"] 14 + ), 15 + ["gh version"] 16 + ); 17 + 18 + const result = await ctr.stdout(); 19 + 20 + console.log(result); 21 + });
+17
.fluentci/sdk/nix/example_with_devenv.ts
··· 1 + import Client from "../../deps.ts"; 2 + import { connect } from "../connect.ts"; 3 + import { withDevenv } from "./steps.ts"; 4 + 5 + connect(async (client: Client) => { 6 + const ctr = withDevenv( 7 + client 8 + .pipeline("nix-installer") 9 + .container() 10 + .from("alpine") 11 + .withExec(["apk", "add", "curl"]) 12 + ); 13 + 14 + const result = await ctr.stdout(); 15 + 16 + console.log(result); 17 + });
+17
.fluentci/sdk/nix/example_with_flox.ts
··· 1 + import Client from "../../deps.ts"; 2 + import { connect } from "../connect.ts"; 3 + import { withFlox } from "./steps.ts"; 4 + 5 + connect(async (client: Client) => { 6 + const ctr = withFlox( 7 + client 8 + .pipeline("nix-installer") 9 + .container() 10 + .from("alpine") 11 + .withExec(["apk", "add", "curl"]) 12 + ); 13 + 14 + const result = await ctr.stdout(); 15 + 16 + console.log(result); 17 + });
+17
.fluentci/sdk/nix/index.ts
··· 1 + import { 2 + withDevbox, 3 + withDevboxExec, 4 + withDevenv, 5 + withFlox, 6 + withNix, 7 + withPackageFromDevbox, 8 + } from "./steps.ts"; 9 + 10 + export { 11 + withDevbox, 12 + withDevboxExec, 13 + withDevenv, 14 + withFlox, 15 + withNix, 16 + withPackageFromDevbox, 17 + };
+103
.fluentci/sdk/nix/steps.ts
··· 1 + import { Container } from "../client.gen.ts"; 2 + 3 + export const withNix = (ctr: Container) => 4 + ctr 5 + .withExec([ 6 + "sh", 7 + "-c", 8 + "[ -f /etc/nix/group ] && cp /etc/nix/group /etc/group; exit 0", 9 + ]) 10 + .withExec([ 11 + "sh", 12 + "-c", 13 + "[ -f /etc/nix/passwd ] && cp /etc/nix/passwd /etc/passwd; exit 0", 14 + ]) 15 + .withExec([ 16 + "sh", 17 + "-c", 18 + "[ -f /etc/nix/shadow ] && cp /etc/nix/shadow /etc/shadow; exit 0", 19 + ]) 20 + .withExec([ 21 + "sh", 22 + "-c", 23 + '[ ! -f "/nix/receipt.json" ] && curl --proto =https --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux --extra-conf "sandbox = false" --init none --no-confirm; exit 0', 24 + ]) 25 + .withExec(["cp", "/etc/group", "/etc/nix/group"]) 26 + .withExec(["cp", "/etc/passwd", "/etc/nix/passwd"]) 27 + .withExec(["cp", "/etc/shadow", "/etc/nix/shadow"]) 28 + .withExec([ 29 + "sed", 30 + "-i", 31 + "s/auto-allocate-uids = true/auto-allocate-uids = false/g", 32 + "/etc/nix/nix.conf", 33 + ]) 34 + .withEnvVariable("PATH", "${PATH}:/nix/var/nix/profiles/default/bin", { 35 + expand: true, 36 + }) 37 + .withExec(["nix", "run", "nixpkgs#hello"]); 38 + 39 + export const withDevbox = (ctr: Container) => 40 + withNix(ctr) 41 + .withExec(["adduser", "--disabled-password", "devbox"]) 42 + .withExec(["addgroup", "devbox", "nixbld"]) 43 + .withEnvVariable("FORCE", "1") 44 + .withExec(["sh", "-c", "curl -fsSL https://get.jetpack.io/devbox | bash"]) 45 + .withExec(["devbox", "version"]); 46 + 47 + export const withPackageFromDevbox = (ctr: Container, pkgs: string[]) => 48 + withDevbox(ctr).withExec(["devbox", "global", "add", ...pkgs]); 49 + 50 + export const withDevboxExec = (ctr: Container, cmds: string[]) => 51 + cmds.reduce( 52 + (ctr, cmd) => 53 + ctr.withExec(["sh", "-c", `eval "$(devbox global shellenv)" && ${cmd}`]), 54 + ctr 55 + ); 56 + 57 + export const withDevenv = (ctr: Container) => 58 + withNix(ctr) 59 + .withExec(["adduser", "--disabled-password", "devenv"]) 60 + .withExec(["addgroup", "devenv", "nixbld"]) 61 + .withEnvVariable("USER", "root") 62 + .withExec([ 63 + "sh", 64 + "-c", 65 + 'echo "trusted-users = root $USER" | tee -a /etc/nix/nix.conf', 66 + ]) 67 + .withExec([ 68 + "nix", 69 + "profile", 70 + "install", 71 + "--accept-flake-config", 72 + "github:cachix/cachix", 73 + ]) 74 + .withExec(["cachix", "use", "devenv"]) 75 + .withExec([ 76 + "nix", 77 + "profile", 78 + "install", 79 + "--accept-flake-config", 80 + "github:cachix/devenv/latest", 81 + ]) 82 + .withExec(["devenv", "version"]); 83 + 84 + export const withFlox = (ctr: Container) => 85 + withNix(ctr) 86 + .withExec(["adduser", "--disabled-password", "flox"]) 87 + .withExec(["addgroup", "flox", "nixbld"]) 88 + .withExec([ 89 + "sh", 90 + "-c", 91 + "echo 'extra-trusted-substituters = https://cache.floxdev.com' | tee -a /etc/nix/nix.conf && echo 'extra-trusted-public-keys = flox-store-public-0:8c/B+kjIaQ+BloCmNkRUKwaVPFWkriSAd0JJvuDu4F0=' | tee -a /etc/nix/nix.conf", 92 + ]) 93 + .withExec([ 94 + "nix", 95 + "profile", 96 + "install", 97 + "--impure", 98 + "--experimental-features", 99 + "nix-command flakes auto-allocate-uids", 100 + "--accept-flake-config", 101 + "github:flox/floxpkgs#flox.fromCatalog", 102 + ]) 103 + .withExec(["flox", "--version"]);
+244
.fluentci/sdk/utils.ts
··· 1 + // deno-lint-ignore-file no-explicit-any 2 + import { 3 + ClientError, 4 + gql, 5 + GraphQLClient, 6 + GraphQLRequestError, 7 + TooManyNestedObjectsError, 8 + UnknownDaggerError, 9 + NotAwaitedRequestError, 10 + ExecError, 11 + } from "../deps.ts"; 12 + 13 + import { Metadata, QueryTree } from "./client.gen.ts"; 14 + 15 + /** 16 + * Format argument into GraphQL query format. 17 + */ 18 + function buildArgs(args: any): string { 19 + const metadata: Metadata = args.__metadata || {}; 20 + 21 + // Remove unwanted quotes 22 + const formatValue = (key: string, value: string) => { 23 + // Special treatment for enumeration, they must be inserted without quotes 24 + if (metadata[key]?.is_enum) { 25 + return JSON.stringify(value).replace(/['"]+/g, ""); 26 + } 27 + 28 + return JSON.stringify(value).replace( 29 + /\{"[a-zA-Z]+":|,"[a-zA-Z]+":/gi, 30 + (str) => { 31 + return str.replace(/"/g, ""); 32 + } 33 + ); 34 + }; 35 + 36 + if (args === undefined || args === null) { 37 + return ""; 38 + } 39 + 40 + const formattedArgs = Object.entries(args).reduce( 41 + (acc: any, [key, value]) => { 42 + // Ignore internal metadata key 43 + if (key === "__metadata") { 44 + return acc; 45 + } 46 + 47 + if (value !== undefined && value !== null) { 48 + acc.push(`${key}: ${formatValue(key, value as string)}`); 49 + } 50 + 51 + return acc; 52 + }, 53 + [] 54 + ); 55 + 56 + if (formattedArgs.length === 0) { 57 + return ""; 58 + } 59 + 60 + return `(${formattedArgs})`; 61 + } 62 + 63 + /** 64 + * Find QueryTree, convert them into GraphQl query 65 + * then compute and return the result to the appropriate field 66 + */ 67 + async function computeNestedQuery( 68 + query: QueryTree[], 69 + client: GraphQLClient 70 + ): Promise<void> { 71 + // Check if there is a nested queryTree to be executed 72 + const isQueryTree = (value: any) => value["_queryTree"] !== undefined; 73 + 74 + // Check if there is a nested array of queryTree to be executed 75 + const isArrayQueryTree = (value: any[]) => 76 + value.every((v) => v instanceof Object && isQueryTree(v)); 77 + 78 + // Prepare query tree for final query by computing nested queries 79 + // and building it with their results. 80 + const computeQueryTree = async (value: any): Promise<string> => { 81 + // Resolve sub queries if operation's args is a subquery 82 + for (const op of value["_queryTree"]) { 83 + await computeNestedQuery([op], client); 84 + } 85 + 86 + // push an id that will be used by the container 87 + return buildQuery([ 88 + ...value["_queryTree"], 89 + { 90 + operation: "id", 91 + }, 92 + ]); 93 + }; 94 + 95 + // Remove all undefined args and assert args type 96 + const queryToExec = query.filter((q): q is Required<QueryTree> => !!q.args); 97 + 98 + for (const q of queryToExec) { 99 + await Promise.all( 100 + // Compute nested query for single object 101 + Object.entries(q.args).map(async ([key, value]: any) => { 102 + if (value instanceof Object && isQueryTree(value)) { 103 + // push an id that will be used by the container 104 + const getQueryTree = await computeQueryTree(value); 105 + 106 + q.args[key] = await compute(getQueryTree, client); 107 + } 108 + 109 + // Compute nested query for array of object 110 + if (Array.isArray(value) && isArrayQueryTree(value)) { 111 + const tmp: any = q.args[key]; 112 + 113 + for (let i = 0; i < value.length; i++) { 114 + // push an id that will be used by the container 115 + const getQueryTree = await computeQueryTree(value[i]); 116 + 117 + tmp[i] = await compute(getQueryTree, client); 118 + } 119 + 120 + q.args[key] = tmp; 121 + } 122 + }) 123 + ); 124 + } 125 + } 126 + 127 + /** 128 + * Convert the queryTree into a GraphQL query 129 + * @param q 130 + * @returns 131 + */ 132 + export function buildQuery(q: QueryTree[]): string { 133 + const query = q.reduce((acc, { operation, args }, i) => { 134 + const qLen = q.length; 135 + 136 + acc += ` ${operation} ${args ? `${buildArgs(args)}` : ""} ${ 137 + qLen - 1 !== i ? "{" : "}".repeat(qLen - 1) 138 + }`; 139 + 140 + return acc; 141 + }, ""); 142 + 143 + return `{${query} }`; 144 + } 145 + 146 + /** 147 + * Convert querytree into a Graphql query then compute it 148 + * @param q | QueryTree[] 149 + * @param client | GraphQLClient 150 + * @returns 151 + */ 152 + export async function computeQuery<T>( 153 + q: QueryTree[], 154 + client: GraphQLClient 155 + ): Promise<T> { 156 + await computeNestedQuery(q, client); 157 + 158 + const query = buildQuery(q); 159 + 160 + return await compute(query, client); 161 + } 162 + 163 + /** 164 + * Return a Graphql query result flattened 165 + * @param response any 166 + * @returns 167 + */ 168 + export function queryFlatten<T>(response: any): T { 169 + // Recursion break condition 170 + // If our response is not an object or an array we assume we reached the value 171 + if (!(response instanceof Object) || Array.isArray(response)) { 172 + return response; 173 + } 174 + 175 + const keys = Object.keys(response); 176 + 177 + if (keys.length != 1) { 178 + // Dagger is currently expecting to only return one value 179 + // If the response is nested in a way were more than one object is nested inside throw an error 180 + throw new TooManyNestedObjectsError( 181 + "Too many nested objects inside graphql response", 182 + { response: response } 183 + ); 184 + } 185 + 186 + const nestedKey = keys[0]; 187 + 188 + return queryFlatten(response[nestedKey]); 189 + } 190 + 191 + /** 192 + * Send a GraphQL document to the server 193 + * return a flatten result 194 + * @hidden 195 + */ 196 + export async function compute<T>( 197 + query: string, 198 + client: GraphQLClient 199 + ): Promise<T> { 200 + let computeQuery: Awaited<T>; 201 + try { 202 + computeQuery = await client.request( 203 + gql` 204 + ${query} 205 + ` 206 + ); 207 + } catch (e: any) { 208 + if (e instanceof ClientError) { 209 + const msg = e.response.errors?.[0]?.message ?? `API Error`; 210 + const ext = e.response.errors?.[0]?.extensions; 211 + 212 + if (ext?._type === "EXEC_ERROR") { 213 + throw new ExecError(msg, { 214 + cmd: (ext.cmd as string[]) ?? [], 215 + exitCode: (ext.exitCode as number) ?? -1, 216 + stdout: (ext.stdout as string) ?? "", 217 + stderr: (ext.stderr as string) ?? "", 218 + }); 219 + } 220 + 221 + throw new GraphQLRequestError(msg, { 222 + request: e.request, 223 + response: e.response, 224 + cause: e, 225 + }); 226 + } 227 + 228 + // Looking for connection error in case the function has not been awaited. 229 + if (e.errno === "ECONNREFUSED") { 230 + throw new NotAwaitedRequestError( 231 + "Encountered an error while requesting data via graphql through a synchronous call. Make sure the function called is awaited.", 232 + { cause: e } 233 + ); 234 + } 235 + 236 + // Just throw the unknown error 237 + throw new UnknownDaggerError( 238 + "Encountered an unknown error while requesting data via graphql", 239 + { cause: e } 240 + ); 241 + } 242 + 243 + return queryFlatten(computeQuery); 244 + }
+38
.fluentci/src/helpers.ts
··· 1 + import { dag, Directory, DirectoryID } from "../deps.ts"; 2 + 3 + const exclude = [ 4 + "build", 5 + ".zig-cache", 6 + "target", 7 + "zig-out", 8 + ".git", 9 + "tools/bmp2rb", 10 + "tools/codepages", 11 + "tools/convbdf", 12 + "tools/mkboot", 13 + "tools/rdfbinary", 14 + "tools/uclpack", 15 + "tools/scramble", 16 + ]; 17 + 18 + export const getDirectory = async ( 19 + src: string | Directory | undefined = "." 20 + ) => { 21 + if (src instanceof Directory) { 22 + return src; 23 + } 24 + if (typeof src === "string") { 25 + try { 26 + const directory = dag.loadDirectoryFromID(src as DirectoryID); 27 + await directory.id(); 28 + return directory; 29 + } catch (_) { 30 + return dag.host 31 + ? dag.host().directory(src, { exclude }) 32 + : dag.currentModule().source().directory(src); 33 + } 34 + } 35 + return dag.host 36 + ? dag.host().directory(src, { exclude }) 37 + : dag.currentModule().source().directory(src); 38 + };
+172
.fluentci/src/jobs.ts
··· 1 + import { Directory, Container, Platform, dag, env } from "../deps.ts"; 2 + import { getDirectory } from "./helpers.ts"; 3 + 4 + export enum Job { 5 + build = "build", 6 + publish = "publish", 7 + } 8 + 9 + export const exclude = []; 10 + 11 + const platforms: Platform[] = [ 12 + "linux/amd64" as Platform, 13 + "linux/arm64" as Platform, 14 + ]; 15 + 16 + /** 17 + * @function 18 + * @description Build Rockbox binary 19 + * @param src {src: string | Directory | undefined} 20 + * @returns {string} 21 + */ 22 + export async function build( 23 + src: string | Directory | undefined = ".", 24 + platform: string = "linux/amd64" 25 + ): Promise<Container> { 26 + const ZIG_VERSION = env.get("ZIG_VERSION") || "0.13.0"; 27 + const RUST_VERSION = env.get("RUST_VERSION") || "1.81-bookworm"; 28 + const context = await getDirectory(src); 29 + const cacheSuffix = platform.replace("/", "-"); 30 + const ctr = dag 31 + .container({ 32 + platform: platform as Platform, 33 + }) 34 + .from(`rust:${RUST_VERSION}`) 35 + .withExec(["apt-get", "update"]) 36 + .withExec([ 37 + "apt-get", 38 + "install", 39 + "-y", 40 + "build-essential", 41 + "libusb-dev", 42 + "libsdl1.2-dev", 43 + "libfreetype6-dev", 44 + "libunwind-dev", 45 + "curl", 46 + "zip", 47 + "unzip", 48 + "protobuf-compiler", 49 + ]) 50 + .withMountedCache( 51 + "/root/.local", 52 + dag.cacheVolume(`rockbox-local-${cacheSuffix}`) 53 + ) 54 + .withExec(["rm", "-rf", "/root/.local/share/pkgx"]) 55 + .withExec(["sh", "-c", "curl -Ssf https://pkgx.sh | sh"]) 56 + .withExec(["pkgx", "install", `zig@${ZIG_VERSION}`]) 57 + .withDirectory("/app", context) 58 + .withWorkdir("/app") 59 + .withExec(["mkdir", "-p", "build", "/root/.local/lib/rockbox"]) 60 + .withMountedCache( 61 + "/app/build", 62 + dag.cacheVolume(`rockbox-build-${cacheSuffix}`) 63 + ) 64 + .withMountedCache( 65 + "/app/.zig-cache", 66 + dag.cacheVolume(`zig-cache-${cacheSuffix}`) 67 + ) 68 + .withMountedCache("/app/zig-out", dag.cacheVolume(`zig-out-${cacheSuffix}`)) 69 + .withMountedCache( 70 + "/app/target", 71 + dag.cacheVolume(`rust-cache-${cacheSuffix}`) 72 + ) 73 + .withWorkdir("/app/build") 74 + .withExec([ 75 + "bash", 76 + "-c", 77 + "../tools/configure --target=sdlapp --type=N --lcdwidth=320 --lcdheight=240 --prefix=$HOME/.local", 78 + ]) 79 + .withExec(["bash", "-c", "make ziginstall -j$(nproc)"]); 80 + 81 + await ctr.stdout(); 82 + return ctr; 83 + } 84 + 85 + /** 86 + * @function 87 + * @description Publish Rockbox Docker image 88 + * @param src {src: string | Directory | undefined} 89 + * @returns {string} 90 + */ 91 + export async function publish( 92 + src: string | Directory | undefined = "." 93 + ): Promise<string> { 94 + const DEBIAN_VERSION = env.get("DEBIAN_VERSION") || "bookworm"; 95 + const platformVariants: Array<Container> = []; 96 + 97 + for (const platform of platforms) { 98 + await build(src, platform as string); 99 + } 100 + 101 + for (const platform of platforms) { 102 + const cacheSuffix = platform.replace("/", "-"); 103 + const ctr = dag 104 + .container({ 105 + platform: platform as Platform, 106 + }) 107 + .from(`debian:${DEBIAN_VERSION}`) 108 + .withExec(["apt-get", "update"]) 109 + .withExec([ 110 + "apt-get", 111 + "install", 112 + "-y", 113 + "libusb-dev", 114 + "libsdl1.2-dev", 115 + "libunwind-dev", 116 + ]) 117 + .withMountedCache( 118 + "/cache", 119 + dag.cacheVolume(`rockbox-local-${cacheSuffix}`) 120 + ) 121 + .withExec([ 122 + "bash", 123 + "-c", 124 + "mkdir -p /root/.local && cp -r /cache/* /root/.local && cp /cache/bin/rockbox /usr/bin", 125 + ]) 126 + .withExec([ 127 + "bash", 128 + "-c", 129 + "ls -la /root/.local/bin /root/.local/lib/rockbox/* /root/.local/share/rockbox", 130 + ]) 131 + .withEnvVariable("SDL_VIDEODRIVER", "dummy") 132 + .withEntrypoint(["rockbox"]); 133 + 134 + await ctr.stdout(); 135 + platformVariants.push(ctr); 136 + } 137 + 138 + const ROCKBOX_IMAGE = 139 + env.get("ROCKBOX_IMAGE") || "ghcr.io/tsirysndr/rockbox:latest"; 140 + 141 + const imageDigest = await dag 142 + .container() 143 + .withRegistryAuth( 144 + ROCKBOX_IMAGE, 145 + env.get("GITHUB_USERNAME")!, 146 + dag.setSecret("GITHUB_TOKEN", env.get("GITHUB_TOKEN")!) 147 + ) 148 + .publish(ROCKBOX_IMAGE, { platformVariants }); 149 + 150 + console.log(imageDigest); 151 + 152 + return "Successfully published Rockbox Docker image"; 153 + } 154 + 155 + export type JobExec = 156 + | ((src?: string, platform?: string) => Promise<Container>) 157 + | (( 158 + src?: string, 159 + options?: { 160 + ignore: string[]; 161 + } 162 + ) => Promise<string>); 163 + 164 + export const runnableJobs: Record<Job, JobExec> = { 165 + [Job.build]: build, 166 + [Job.publish]: publish, 167 + }; 168 + 169 + export const jobDescriptions: Record<Job, string> = { 170 + [Job.build]: "Build Rockbox binary", 171 + [Job.publish]: "Publish Rockbox Docker image", 172 + };
+4
.fluentci/src/mod.ts
··· 1 + import pipeline from "./pipeline.ts"; 2 + import { build, publish, jobDescriptions } from "./jobs.ts"; 3 + 4 + export { pipeline, build, publish, jobDescriptions };
+22
.fluentci/src/pipeline.ts
··· 1 + import * as jobs from "./jobs.ts"; 2 + 3 + const { build, runnableJobs } = jobs; 4 + 5 + export default async function pipeline(_src = ".", args: string[] = []) { 6 + if (args.length > 0) { 7 + await runSpecificJobs(args as jobs.Job[]); 8 + return; 9 + } 10 + 11 + await build(); 12 + } 13 + 14 + async function runSpecificJobs(args: jobs.Job[]) { 15 + for (const name of args) { 16 + const job = runnableJobs[name]; 17 + if (!job) { 18 + throw new Error(`Job ${name} not found`); 19 + } 20 + await job(); 21 + } 22 + }
+17
.fluentci/src/runner.ts
··· 1 + import pipeline from "./pipeline.ts"; 2 + import { parse, camelCase, snakeCase } from "../deps.ts"; 3 + 4 + const args = parse(Deno.args.map((x) => x.split(" ")).flat()); 5 + 6 + if (!Array.isArray(Deno.args)) { 7 + for (const param of Object.keys(args) 8 + .filter((x) => x !== "_") 9 + .map((x) => snakeCase(x).toUpperCase())) { 10 + Deno.env.set(param, args[camelCase(param)]); 11 + } 12 + } 13 + 14 + await pipeline( 15 + ".", 16 + Array.isArray(Deno.args) ? Deno.args : (args._ as string[]) 17 + );
+23
.github/workflows/ci.yml
··· 1 + name: ci 2 + on: 3 + push: 4 + branches: 5 + - master 6 + 7 + jobs: 8 + publish: 9 + runs-on: ubuntu-latest 10 + permissions: 11 + contents: read 12 + packages: write 13 + steps: 14 + - uses: actions/checkout@v3 15 + - name: Build and Publish image 16 + uses: fluentci-io/setup-fluentci@v5 17 + with: 18 + dagger-version: 0.13.0 19 + plugin: . 20 + args: publish 21 + env: 22 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 + GITHUB_USERNAME: tsirysndr
+4 -1
README.md
··· 5 5 6 6 # Rockbox Zig 🎵 ⚡ 7 7 8 + [![GPL-2.0 licensed](https://img.shields.io/badge/License-GPL-blue.svg)](./LICENSE) 9 + [![ci](https://github.com/tsirysndr/rockbox-zig/actions/workflows/ci.yml/badge.svg)](https://github.com/tsirysndr/rockbox-zig/actions/workflows/ci.yml) 10 + 8 11 Rockbox Zig is an incremental enhancement of the [Rockbox](https://www.rockbox.org) firmware for portable audio players in Zig and Rust. 9 12 10 13 > [!NOTE] ··· 17 20 Run the following commands to build the project: 18 21 19 22 ```sh 20 - sudo apt-get install libusb-dev libsdl1.2-dev libfreetype6-dev 23 + sudo apt-get install libusb-dev libsdl1.2-dev libfreetype6-dev libunwind-dev zip protobuf-compiler 21 24 mkdir -p build && cd build 22 25 ../tools/configure --target=sdlapp --type=N --lcdwidth=320 --lcdheight=240 --prefix=$HOME/.local 23 26 make zig
+13
dagger.json
··· 1 + { 2 + "name": "rockbox", 3 + "sdk": "github.com/fluentci-io/daggerverse/deno-sdk@main", 4 + "version": "v0.1.0", 5 + "description": "CI/CD for Rockbox", 6 + "keywords": [ 7 + "rockbox", 8 + "zig", 9 + "rust" 10 + ], 11 + "author": "Tsiry Sandratraina <tsiry.sndr@fluentci.io>", 12 + "license": "MIT" 13 + }
+1 -1
tools/root.make
··· 412 412 413 413 ziginstall: zig 414 414 @echo "Installing your build in your '$(RBPREFIX)' dir" 415 - cd .. && cargo build -p rockbox-server --release && zig build install-rockbox 415 + cd .. && cargo build -p rockbox-server --release && zig build install-rockbox && mkdir -p $(RBPREFIX)/bin $(RBPREFIX)/share/rockbox && cp zig-out/bin/rockbox $(RBPREFIX)/bin && cp -r assets/* $(RBPREFIX)/share/rockbox 416 416 417 417 symlinkinstall: simext1 418 418 @echo "Installing a full setup with links in your '$(RBPREFIX)' dir"