├── .github └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .goreleaser.yaml ├── LICENSE ├── README.md ├── docs ├── data-sources │ ├── await.md │ ├── conditional_operation.md │ ├── const.md │ ├── decrement.md │ ├── export.md │ ├── for.md │ ├── function.md │ ├── function_call.md │ ├── function_param.md │ ├── if.md │ ├── import.md │ ├── increment.md │ ├── index.md │ ├── let.md │ ├── new.md │ ├── operation.md │ ├── program.md │ ├── raw.md │ ├── return.md │ ├── throw.md │ ├── var.md │ └── while.md └── index.md ├── examples ├── data-sources │ ├── js_await │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_conditional_operation │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_const │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_decrement │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_export │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_for │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_function │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_function_call │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_if │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_import │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_increment │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_index │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_let │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_new │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_operation │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_program │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_raw │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_return │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_throw │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ ├── js_var │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf │ └── js_while │ │ ├── data-source.tf │ │ ├── data-source.tftest.hcl │ │ └── provider.tf ├── others │ └── aws_lambda │ │ ├── .gitignore │ │ ├── main.tf │ │ └── provider.tf ├── provider.tf └── provider │ ├── provider.tf │ └── terraform.tf ├── go.mod ├── go.sum ├── internal ├── datasources │ ├── await.go │ ├── conditional_operation.go │ ├── const.go │ ├── decrement.go │ ├── export.go │ ├── for.go │ ├── function.go │ ├── function_call.go │ ├── function_param.go │ ├── if.go │ ├── import.go │ ├── increment.go │ ├── index.go │ ├── let.go │ ├── new.go │ ├── operation.go │ ├── program.go │ ├── raw.go │ ├── return.go │ ├── throw.go │ ├── var.go │ └── while.go ├── provider │ └── provider.go └── util │ ├── util.go │ └── util_test.go ├── main.go ├── terraform-registry-manifest.json └── tools └── tools.go /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | permissions: 9 | contents: write 10 | 11 | jobs: 12 | goreleaser: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | - uses: actions/setup-go@v5 19 | with: 20 | go-version-file: "go.mod" 21 | cache: true 22 | - name: Import GPG key 23 | uses: crazy-max/ghaction-import-gpg@v6 24 | id: import_gpg 25 | with: 26 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 27 | passphrase: ${{ secrets.PASSPHRASE }} 28 | - name: Run GoReleaser 29 | uses: goreleaser/goreleaser-action@v6 30 | with: 31 | args: release --clean 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 35 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: push 4 | 5 | jobs: 6 | go-test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | - uses: actions/setup-go@v5 13 | with: 14 | go-version-file: "go.mod" 15 | cache: true 16 | - run: go test -v ./... 17 | 18 | go-lint: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | with: 23 | fetch-depth: 0 24 | - uses: actions/setup-go@v5 25 | with: 26 | go-version-file: "go.mod" 27 | cache: true 28 | - uses: golangci/golangci-lint-action@v6 29 | 30 | tf-fmt: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v4 34 | with: 35 | fetch-depth: 0 36 | - uses: hashicorp/setup-terraform@v3 37 | with: 38 | terraform_version: 1.9.2 39 | - run: terraform fmt -recursive -check 40 | 41 | tf-test: 42 | runs-on: ubuntu-latest 43 | strategy: 44 | matrix: 45 | examples: 46 | - data-sources 47 | steps: 48 | - uses: actions/checkout@v4 49 | with: 50 | fetch-depth: 0 51 | - uses: actions/setup-go@v5 52 | with: 53 | go-version-file: "go.mod" 54 | cache: true 55 | - uses: hashicorp/setup-terraform@v3 56 | with: 57 | terraform_version: 1.9.2 58 | - name: create terraformrc 59 | run: | 60 | cat < ~/.terraformrc 61 | provider_installation { 62 | dev_overrides { 63 | "registry.terraform.io/koki-develop/js" = "$HOME/go/bin" 64 | } 65 | 66 | direct {} 67 | } 68 | EOF 69 | - run: go install 70 | - name: test 71 | working-directory: examples/${{ matrix.examples }} 72 | run: | 73 | for wd in $(ls -d */); do 74 | echo "::group::${wd}" 75 | cd $wd 76 | terraform init 77 | terraform test 78 | cd .. 79 | echo "::endgroup::" 80 | done 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # goreleaser 2 | /dist/ 3 | 4 | # examples 5 | /examples/**/*.tfstate* 6 | /examples/**/.terraform/ 7 | /examples/**/.terraform.lock.hcl 8 | /examples/**/index.js 9 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | before: 3 | hooks: 4 | - go mod tidy 5 | builds: 6 | - env: 7 | - CGO_ENABLED=0 8 | mod_timestamp: '{{ .CommitTimestamp }}' 9 | flags: 10 | - -trimpath 11 | ldflags: 12 | - '-s -w -X main.version={{.Version}}' 13 | goos: 14 | - freebsd 15 | - windows 16 | - linux 17 | - darwin 18 | goarch: 19 | - amd64 20 | - '386' 21 | - arm 22 | - arm64 23 | ignore: 24 | - goos: darwin 25 | goarch: '386' 26 | binary: '{{ .ProjectName }}_v{{ .Version }}' 27 | archives: 28 | - format: zip 29 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 30 | checksum: 31 | extra_files: 32 | - glob: 'terraform-registry-manifest.json' 33 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 34 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 35 | algorithm: sha256 36 | signs: 37 | - artifacts: checksum 38 | args: 39 | - "--batch" 40 | - "--local-user" 41 | - "{{ .Env.GPG_FINGERPRINT }}" 42 | - "--output" 43 | - "${signature}" 44 | - "--detach-sign" 45 | - "${artifact}" 46 | release: 47 | extra_files: 48 | - glob: 'terraform-registry-manifest.json' 49 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 50 | changelog: 51 | disable: true 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Koki Sato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | JS.tf 3 |

4 | 5 |

6 | 7 | 8 | JavaScript × Terraform 9 | 10 | 11 |

12 | 13 |

14 | The Next Generation AltJS. 15 |

16 | 17 |

18 | GitHub release (latest by date) 19 | GitHub Workflow Status 20 | Go Report Card 21 | LICENSE 22 |

23 | 24 | ```hcl 25 | data "js_function_call" "hello_world" { 26 | caller = "console" 27 | function = "log" 28 | args = ["hello world"] 29 | } 30 | 31 | data "js_program" "main" { 32 | statements = [data.js_function_call.hello_world.statement] 33 | } 34 | 35 | resource "local_file" "main" { 36 | filename = "index.js" 37 | content = data.js_program.main.content 38 | } 39 | ``` 40 | 41 | ```console 42 | $ terraform init 43 | $ terraform apply 44 | $ node index.js 45 | hello world 46 | ``` 47 | 48 | # Getting Started 49 | 50 | JS.tf is a Terraform provider that allows you to write JavaScript code in Terraform configuration files. 51 | To use it, add the following provider configuration. 52 | 53 | ```hcl 54 | terraform { 55 | required_providers { 56 | js = { 57 | source = "koki-develop/js" 58 | } 59 | } 60 | } 61 | 62 | provider "js" {} 63 | ``` 64 | 65 | Next, run `terraform init`. 66 | 67 | ```console 68 | $ terraform init 69 | ``` 70 | 71 | That's it. You are ready to use JS.tf. 72 | 73 | # Examples 74 | 75 | - [`examples/`](./examples) 76 | 77 | # Documentation 78 | 79 | - [Terraform Registry](https://registry.terraform.io/providers/koki-develop/js/latest/docs) 80 | 81 | # LICENSE 82 | 83 | [MIT](./LICENSE) 84 | -------------------------------------------------------------------------------- /docs/data-sources/await.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_await Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_await (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_function_call" "fetch" { 17 | function = "fetch" 18 | args = ["https://example.com"] 19 | } 20 | 21 | data "js_await" "fetch" { 22 | value = data.js_function_call.fetch.expression 23 | } 24 | # => await fetch("https://example.com") 25 | ``` 26 | 27 | 28 | ## Schema 29 | 30 | ### Required 31 | 32 | - `value` (Dynamic) A Promise, a thenable object, or any value to wait for. 33 | 34 | ### Read-Only 35 | 36 | - `expression` (String) 37 | - `statement` (String) 38 | -------------------------------------------------------------------------------- /docs/data-sources/conditional_operation.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_conditional_operation Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_conditional_operation (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_conditional_operation" "main" { 17 | condition = true 18 | if_true = 1 19 | if_false = 2 20 | } 21 | ``` 22 | 23 | 24 | ## Schema 25 | 26 | ### Required 27 | 28 | - `condition` (Dynamic) An expression whose value is used as a condition. 29 | - `if_false` (Dynamic) An expression which is executed if the condition is falsy. 30 | - `if_true` (Dynamic) An expression which is executed if the condition evaluates to a truthy value. 31 | 32 | ### Read-Only 33 | 34 | - `expression` (String) 35 | - `statement` (String) 36 | -------------------------------------------------------------------------------- /docs/data-sources/const.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_const Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_const (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_const" "str" { 17 | name = "str" 18 | value = "hello" 19 | } 20 | # => const str = "hello"; 21 | 22 | data "js_const" "num" { 23 | name = "num" 24 | value = 10 25 | } 26 | # => const num = 10; 27 | 28 | data "js_const" "bool" { 29 | name = "bool" 30 | value = true 31 | } 32 | # => const bool = true; 33 | 34 | data "js_const" "arr" { 35 | name = "arr" 36 | value = [1, 2, 3] 37 | } 38 | # => const arr = [1, 2, 3]; 39 | 40 | data "js_const" "obj" { 41 | name = "obj" 42 | value = { 43 | hoge = "fuga" 44 | foo = 3 45 | } 46 | } 47 | # => const obj = { "hoge": "fuga", "foo": 3 }; 48 | ``` 49 | 50 | 51 | ## Schema 52 | 53 | ### Required 54 | 55 | - `name` (String) Name of variable to declare. 56 | - `value` (Dynamic) Initial value of the variable. 57 | 58 | ### Read-Only 59 | 60 | - `expression` (String) 61 | - `id` (String) The ID of this resource. 62 | - `statement` (String) 63 | -------------------------------------------------------------------------------- /docs/data-sources/decrement.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_decrement Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_decrement (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "num" { 17 | name = "i" 18 | value = 0 19 | } 20 | 21 | data "js_decrement" "i" { 22 | ref = data.js_let.num.id 23 | } 24 | # => i-- 25 | 26 | data "js_decrement" "i_postfix" { 27 | ref = data.js_let.num.id 28 | type = "postfix" 29 | } 30 | # => i-- 31 | 32 | data "js_decrement" "i_prefix" { 33 | ref = data.js_let.num.id 34 | type = "prefix" 35 | } 36 | # => --i 37 | ``` 38 | 39 | 40 | ## Schema 41 | 42 | ### Required 43 | 44 | - `ref` (String) Reference to decrement. 45 | 46 | ### Optional 47 | 48 | - `type` (String) Type of decrement to perform. (Valid values: `prefix`, `postfix`) 49 | 50 | ### Read-Only 51 | 52 | - `expression` (String) 53 | - `statement` (String) 54 | -------------------------------------------------------------------------------- /docs/data-sources/export.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_export Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_export (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_const" "message" { 17 | name = "message" 18 | value = "hello world" 19 | } 20 | 21 | data "js_export" "message" { 22 | value = data.js_const.message.id 23 | } 24 | # => export message 25 | ``` 26 | 27 | 28 | ## Schema 29 | 30 | ### Required 31 | 32 | - `value` (Dynamic) Value to be exported 33 | 34 | ### Read-Only 35 | 36 | - `statement` (String) 37 | -------------------------------------------------------------------------------- /docs/data-sources/for.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_for Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_for (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "i" { 17 | name = "i" 18 | value = 0 19 | } 20 | 21 | data "js_operation" "i_lt_10" { 22 | left = data.js_let.i.id 23 | operator = "<" 24 | right = 10 25 | } 26 | 27 | data "js_increment" "i" { 28 | ref = data.js_let.i.id 29 | } 30 | 31 | data "js_function_call" "log_i" { 32 | caller = "console" 33 | function = "log" 34 | args = [data.js_let.i.id] 35 | } 36 | 37 | data "js_for" "main" { 38 | init = data.js_let.i.statement 39 | condition = data.js_operation.i_lt_10.expression 40 | update = data.js_increment.i.statement 41 | body = [data.js_function_call.log_i.statement] 42 | } 43 | # => for (let i = 0; i < 10; i++) { 44 | # console.log(i); 45 | # } 46 | ``` 47 | 48 | 49 | ## Schema 50 | 51 | ### Optional 52 | 53 | - `body` (List of String) Statements that is executed as long as the condition evaluates to true. 54 | - `condition` (String) An expression to be evaluated before each loop iteration. 55 | - `init` (String) An expression or variable declaration evaluated once before the loop begins. 56 | - `update` (String) An expression to be evaluated at the end of each loop iteration. 57 | 58 | ### Read-Only 59 | 60 | - `statement` (String) 61 | -------------------------------------------------------------------------------- /docs/data-sources/function.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_function Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_function (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_function_call" "log_name" { 17 | caller = "console" 18 | function = "log" 19 | args = ["hello", data.js_function_param.name.id] 20 | } 21 | 22 | data "js_function_param" "name" { 23 | name = "name" 24 | } 25 | 26 | data "js_function" "hello" { 27 | name = "hello" 28 | params = [data.js_function_param.name.id] 29 | body = [data.js_function_call.log_name.statement] 30 | } 31 | # => function hello(name) { 32 | # console.log("hello", name); 33 | # } 34 | 35 | data "js_function" "anonymous" { 36 | params = [data.js_function_param.name.id] 37 | body = [data.js_function_call.log_name.statement] 38 | } 39 | 40 | data "js_const" "anonymous" { 41 | name = "anonymous" 42 | value = data.js_function.hello.expression 43 | } 44 | # => const anonymous = function(name) { 45 | # console.log("hello", name); 46 | # }; 47 | 48 | data "js_function" "async" { 49 | name = "hello" 50 | async = true 51 | params = [data.js_function_param.name.id] 52 | body = [data.js_function_call.log_name.statement] 53 | } 54 | # => async function hello(name) { 55 | # console.log("hello", name); 56 | # } 57 | ``` 58 | 59 | 60 | ## Schema 61 | 62 | ### Optional 63 | 64 | - `async` (Boolean) Whether function is async. 65 | - `body` (List of String) Body of function. 66 | - `name` (String) Name of function. 67 | - `params` (List of String) Parameters of function. 68 | 69 | ### Read-Only 70 | 71 | - `expression` (String) 72 | - `id` (String) The ID of this resource. 73 | - `statement` (String) 74 | -------------------------------------------------------------------------------- /docs/data-sources/function_call.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_function_call Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_function_call (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_function_call" "alert" { 17 | function = "alert" 18 | args = ["hello world"] 19 | } 20 | 21 | data "js_function_call" "console_log" { 22 | caller = "console" 23 | function = "log" 24 | args = ["hello", "world"] 25 | } 26 | # => console.log("hello", "world") 27 | ``` 28 | 29 | 30 | ## Schema 31 | 32 | ### Required 33 | 34 | - `function` (String) Name of function to call. 35 | 36 | ### Optional 37 | 38 | - `args` (Dynamic) Arguments to pass to function. 39 | - `caller` (String) Function caller. 40 | 41 | ### Read-Only 42 | 43 | - `expression` (String) 44 | - `statement` (String) 45 | -------------------------------------------------------------------------------- /docs/data-sources/function_param.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_function_param Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_function_param (Data Source) 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `name` (String) Name of parameter. 21 | 22 | ### Read-Only 23 | 24 | - `expression` (String) 25 | - `id` (String) The ID of this resource. 26 | -------------------------------------------------------------------------------- /docs/data-sources/if.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_if Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_if (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_function_call" "log_true" { 17 | caller = "console" 18 | function = "log" 19 | args = [true] 20 | } 21 | 22 | data "js_function_call" "log_false" { 23 | caller = "console" 24 | function = "log" 25 | args = [false] 26 | } 27 | 28 | data "js_raw" "true" { 29 | value = "true" 30 | } 31 | 32 | data "js_if" "main" { 33 | condition = data.js_raw.true.content 34 | then = [data.js_function_call.log_true.statement] 35 | else = [data.js_function_call.log_false.statement] 36 | } 37 | # => if (true) { 38 | # console.log(true); 39 | # } else { 40 | # console.log(false); 41 | # } 42 | ``` 43 | 44 | 45 | ## Schema 46 | 47 | ### Required 48 | 49 | - `condition` (String) An expression that is considered to be either truthy or falsy. 50 | 51 | ### Optional 52 | 53 | - `else` (List of String) Statements that are executed if condition is falsy. 54 | - `then` (List of String) Statements that are executed if condition is truthy. 55 | 56 | ### Read-Only 57 | 58 | - `statement` (String) 59 | -------------------------------------------------------------------------------- /docs/data-sources/import.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_import Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_import (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_import" "as" { 17 | from = "path/to/module" 18 | as = "name" 19 | } 20 | # => import * as name from "path/to/module" 21 | 22 | data "js_import" "default" { 23 | from = "path/to/module" 24 | as = "name" 25 | default = true 26 | } 27 | # => import name from "path/to/module" 28 | ``` 29 | 30 | 31 | ## Schema 32 | 33 | ### Required 34 | 35 | - `as` (String) Name of the module object that will be used as a kind of namespace when referring to the imports. 36 | - `from` (String) The module to import from. 37 | 38 | ### Optional 39 | 40 | - `default` (Boolean) Whether the import is default. 41 | 42 | ### Read-Only 43 | 44 | - `id` (String) The ID of this resource. 45 | - `statement` (String) 46 | -------------------------------------------------------------------------------- /docs/data-sources/increment.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_increment Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_increment (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "num" { 17 | name = "i" 18 | value = 0 19 | } 20 | 21 | data "js_increment" "i" { 22 | ref = data.js_let.num.id 23 | } 24 | # => i++ 25 | 26 | data "js_increment" "i_postfix" { 27 | ref = data.js_let.num.id 28 | type = "postfix" 29 | } 30 | # => i++ 31 | 32 | data "js_increment" "i_prefix" { 33 | ref = data.js_let.num.id 34 | type = "prefix" 35 | } 36 | # => ++i 37 | ``` 38 | 39 | 40 | ## Schema 41 | 42 | ### Required 43 | 44 | - `ref` (String) Reference to increment. 45 | 46 | ### Optional 47 | 48 | - `type` (String) Type of increment to perform. (Valid values: `prefix`, `postfix`) 49 | 50 | ### Read-Only 51 | 52 | - `expression` (String) 53 | - `statement` (String) 54 | -------------------------------------------------------------------------------- /docs/data-sources/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_index Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_index (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_const" "arr" { 17 | name = "arr" 18 | value = [1, 2, 3] 19 | } 20 | 21 | data "js_index" "arr_1" { 22 | ref = data.js_const.arr.id 23 | value = 1 24 | } 25 | # => arr[1] 26 | 27 | data "js_const" "obj" { 28 | name = "obj" 29 | value = { 30 | foo = "bar" 31 | } 32 | } 33 | 34 | data "js_index" "obj_foo" { 35 | ref = data.js_const.obj.id 36 | value = "foo" 37 | } 38 | # => obj["foo"] 39 | ``` 40 | 41 | 42 | ## Schema 43 | 44 | ### Required 45 | 46 | - `ref` (String) Referenced JavaScript object. 47 | - `value` (Dynamic) Index or property name within referenced object. 48 | 49 | ### Read-Only 50 | 51 | - `expression` (String) 52 | - `id` (String) The ID of this resource. 53 | - `statement` (String) 54 | -------------------------------------------------------------------------------- /docs/data-sources/let.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_let Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_let (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "str" { 17 | name = "str" 18 | value = "hello" 19 | } 20 | # => let str = "hello"; 21 | 22 | data "js_let" "num" { 23 | name = "num" 24 | value = 10 25 | } 26 | # => let num = 10; 27 | 28 | data "js_let" "bool" { 29 | name = "bool" 30 | value = true 31 | } 32 | # => let bool = true; 33 | 34 | data "js_let" "arr" { 35 | name = "arr" 36 | value = [1, 2, 3] 37 | } 38 | # => let arr = [1, 2, 3]; 39 | 40 | data "js_let" "obj" { 41 | name = "obj" 42 | value = { 43 | hoge = "fuga" 44 | foo = 3 45 | } 46 | } 47 | # => let obj = { "hoge": "fuga", "foo": 3 }; 48 | ``` 49 | 50 | 51 | ## Schema 52 | 53 | ### Required 54 | 55 | - `name` (String) Name of variable to declare. 56 | 57 | ### Optional 58 | 59 | - `value` (Dynamic) Initial value of the variable. 60 | 61 | ### Read-Only 62 | 63 | - `expression` (String) 64 | - `id` (String) The ID of this resource. 65 | - `statement` (String) 66 | -------------------------------------------------------------------------------- /docs/data-sources/new.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_new Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_new (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_new" "error" { 17 | constructor = "Error" 18 | args = ["something went wrong"] 19 | } 20 | # => new Error("something went wrong") 21 | ``` 22 | 23 | 24 | ## Schema 25 | 26 | ### Required 27 | 28 | - `constructor` (String) A class or function that specifies the type of the object instance. 29 | 30 | ### Optional 31 | 32 | - `args` (Dynamic) A list of values that the constructor will be called with. 33 | 34 | ### Read-Only 35 | 36 | - `expression` (String) 37 | - `statement` (String) 38 | -------------------------------------------------------------------------------- /docs/data-sources/operation.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_operation Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_operation (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "a" { 17 | name = "a" 18 | value = 0 19 | } 20 | 21 | data "js_let" "b" { 22 | name = "b" 23 | value = 10 24 | } 25 | 26 | data "js_operation" "a_plus_b" { 27 | left = data.js_let.a.id 28 | operator = "+" 29 | right = data.js_let.b.id 30 | } 31 | # => a + b 32 | 33 | data "js_operation" "a_minus_b" { 34 | left = data.js_let.a.id 35 | operator = "-" 36 | right = data.js_let.b.id 37 | } 38 | # => a - b 39 | 40 | data "js_operation" "a_times_b" { 41 | left = data.js_let.a.id 42 | operator = "*" 43 | right = data.js_let.b.id 44 | } 45 | # => a * b 46 | 47 | data "js_operation" "a_div_b" { 48 | left = data.js_let.a.id 49 | operator = "/" 50 | right = data.js_let.b.id 51 | } 52 | # => a / b 53 | 54 | data "js_operation" "a_mod_b" { 55 | left = data.js_let.a.id 56 | operator = "%" 57 | right = data.js_let.b.id 58 | } 59 | # => a % b 60 | 61 | data "js_operation" "a_lt_b" { 62 | left = data.js_let.a.id 63 | operator = "<" 64 | right = data.js_let.b.id 65 | } 66 | # => a < b 67 | 68 | data "js_operation" "a_lte_b" { 69 | left = data.js_let.a.id 70 | operator = "<=" 71 | right = data.js_let.b.id 72 | } 73 | # => a <= b 74 | 75 | data "js_operation" "a_gt_b" { 76 | left = data.js_let.a.id 77 | operator = ">" 78 | right = data.js_let.b.id 79 | } 80 | # => a > b 81 | 82 | data "js_operation" "a_gte_b" { 83 | left = data.js_let.a.id 84 | operator = ">=" 85 | right = data.js_let.b.id 86 | } 87 | # => a > b 88 | 89 | data "js_operation" "a_eq_b" { 90 | left = data.js_let.a.id 91 | operator = "===" 92 | right = data.js_let.b.id 93 | } 94 | # => a === b 95 | 96 | data "js_operation" "assign_a_to_b" { 97 | left = data.js_let.a.id 98 | operator = "=" 99 | right = data.js_let.b.id 100 | } 101 | # => a = b 102 | ``` 103 | 104 | 105 | ## Schema 106 | 107 | ### Required 108 | 109 | - `left` (Dynamic) Left operand. 110 | - `operator` (String) Operator to use in operation. 111 | - `right` (Dynamic) Right operand. 112 | 113 | ### Read-Only 114 | 115 | - `expression` (String) 116 | - `statement` (String) 117 | -------------------------------------------------------------------------------- /docs/data-sources/program.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_program Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_program (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_const" "message" { 17 | name = "message" 18 | value = "hello world" 19 | } 20 | 21 | data "js_function_call" "log_message" { 22 | caller = "console" 23 | function = "log" 24 | args = [data.js_const.message.id] 25 | } 26 | 27 | data "js_program" "main" { 28 | statements = [ 29 | data.js_const.message.statement, 30 | data.js_function_call.log_message.statement, 31 | ] 32 | } 33 | # => const message = "hello world"; 34 | # console.log(message); 35 | ``` 36 | 37 | 38 | ## Schema 39 | 40 | ### Required 41 | 42 | - `statements` (List of String) Statements that are executed in the program. 43 | 44 | ### Read-Only 45 | 46 | - `content` (String) 47 | -------------------------------------------------------------------------------- /docs/data-sources/raw.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_raw Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_raw (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_raw" "example" { 17 | value = "console.log('Hello, World!');" 18 | } 19 | ``` 20 | 21 | 22 | ## Schema 23 | 24 | ### Required 25 | 26 | - `value` (String) Raw JavaScript code. 27 | 28 | ### Read-Only 29 | 30 | - `content` (String) 31 | -------------------------------------------------------------------------------- /docs/data-sources/return.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_return Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_return (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_return" "hello" { 17 | value = "hello world" 18 | } 19 | 20 | data "js_function" "hello" { 21 | name = "hello" 22 | body = [data.js_return.hello.statement] 23 | } 24 | # => function hello() { 25 | # return "hello world" 26 | # } 27 | ``` 28 | 29 | 30 | ## Schema 31 | 32 | ### Optional 33 | 34 | - `value` (Dynamic) Expression whose value is to be returned. 35 | 36 | ### Read-Only 37 | 38 | - `statement` (String) 39 | -------------------------------------------------------------------------------- /docs/data-sources/throw.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_throw Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_throw (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_new" "error" { 17 | constructor = "Error" 18 | args = ["something went wrong"] 19 | } 20 | 21 | data "js_throw" "error" { 22 | value = data.js_new.error.expression 23 | } 24 | # => throw new Error("something went wrong") 25 | ``` 26 | 27 | 28 | ## Schema 29 | 30 | ### Required 31 | 32 | - `value` (String) Expression to throw. 33 | 34 | ### Read-Only 35 | 36 | - `statement` (String) 37 | -------------------------------------------------------------------------------- /docs/data-sources/var.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_var Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_var (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_var" "str" { 17 | name = "str" 18 | value = "hello" 19 | } 20 | # => var str = "hello"; 21 | 22 | data "js_var" "num" { 23 | name = "num" 24 | value = 10 25 | } 26 | # => var num = 10; 27 | 28 | data "js_var" "bool" { 29 | name = "bool" 30 | value = true 31 | } 32 | # => var bool = true; 33 | 34 | data "js_var" "arr" { 35 | name = "arr" 36 | value = [1, 2, 3] 37 | } 38 | # => var arr = [1, 2, 3]; 39 | 40 | data "js_var" "obj" { 41 | name = "obj" 42 | value = { 43 | hoge = "fuga" 44 | foo = 3 45 | } 46 | } 47 | # => var obj = { "hoge": "fuga", "foo": 3 }; 48 | ``` 49 | 50 | 51 | ## Schema 52 | 53 | ### Required 54 | 55 | - `name` (String) Name of variable to declare. 56 | 57 | ### Optional 58 | 59 | - `value` (Dynamic) Initial value of variable. 60 | 61 | ### Read-Only 62 | 63 | - `expression` (String) 64 | - `id` (String) The ID of this resource. 65 | - `statement` (String) 66 | -------------------------------------------------------------------------------- /docs/data-sources/while.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js_while Data Source - terraform-provider-js" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # js_while (Data Source) 10 | 11 | 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_let" "i" { 17 | name = "i" 18 | value = 0 19 | } 20 | 21 | data "js_operation" "i_lt_10" { 22 | left = data.js_let.i.id 23 | operator = "<" 24 | right = 10 25 | } 26 | 27 | data "js_function_call" "log_i" { 28 | caller = "console" 29 | function = "log" 30 | args = [data.js_let.i.id] 31 | } 32 | 33 | data "js_increment" "i" { 34 | ref = data.js_let.i.id 35 | } 36 | 37 | data "js_while" "main" { 38 | condition = data.js_operation.i_lt_10.expression 39 | body = [data.js_function_call.log_i.statement, data.js_increment.i.statement] 40 | } 41 | # => while (i < 10) { 42 | # console.log(i); 43 | # i++; 44 | # } 45 | ``` 46 | 47 | 48 | ## Schema 49 | 50 | ### Required 51 | 52 | - `condition` (String) An expression evaluated before each pass through the loop. 53 | 54 | ### Optional 55 | 56 | - `body` (List of String) Statements that are executed as long as the condition evaluates to true. 57 | 58 | ### Read-Only 59 | 60 | - `statement` (String) 61 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "js Provider" 4 | subcategory: "" 5 | description: |- 6 | The Next Generation AltJS. 7 | --- 8 | 9 | # js Provider 10 | 11 | The Next Generation AltJS. 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "js_function_call" "hello_world" { 17 | caller = "console" 18 | function = "log" 19 | args = ["hello world"] 20 | } 21 | 22 | data "js_program" "main" { 23 | statements = [data.js_function_call.hello_world.statement] 24 | } 25 | 26 | resource "local_file" "main" { 27 | filename = "index.js" 28 | content = data.js_program.main.content 29 | } 30 | ``` 31 | 32 | 33 | ## Schema 34 | -------------------------------------------------------------------------------- /examples/data-sources/js_await/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_function_call" "fetch" { 2 | function = "fetch" 3 | args = ["https://example.com"] 4 | } 5 | 6 | data "js_await" "fetch" { 7 | value = data.js_function_call.fetch.expression 8 | } 9 | # => await fetch("https://example.com") 10 | -------------------------------------------------------------------------------- /examples/data-sources/js_await/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "fetch_statement" { 2 | assert { 3 | condition = data.js_await.fetch.statement == "@js/raw:await (fetch)(\"https://example.com\")" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "fetch_expression" { 9 | assert { 10 | condition = data.js_await.fetch.expression == "@js/raw:await (fetch)(\"https://example.com\")" 11 | error_message = "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/js_await/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_conditional_operation/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_conditional_operation" "main" { 2 | condition = true 3 | if_true = 1 4 | if_false = 2 5 | } 6 | -------------------------------------------------------------------------------- /examples/data-sources/js_conditional_operation/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main_statement" { 2 | assert { 3 | condition = data.js_conditional_operation.main.statement == "@js/raw:(true?1:2)" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "main_expression" { 9 | assert { 10 | condition = data.js_conditional_operation.main.expression == "@js/raw:(true?1:2)" 11 | error_message = "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/js_conditional_operation/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_const/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_const" "str" { 2 | name = "str" 3 | value = "hello" 4 | } 5 | # => const str = "hello"; 6 | 7 | data "js_const" "num" { 8 | name = "num" 9 | value = 10 10 | } 11 | # => const num = 10; 12 | 13 | data "js_const" "bool" { 14 | name = "bool" 15 | value = true 16 | } 17 | # => const bool = true; 18 | 19 | data "js_const" "arr" { 20 | name = "arr" 21 | value = [1, 2, 3] 22 | } 23 | # => const arr = [1, 2, 3]; 24 | 25 | data "js_const" "obj" { 26 | name = "obj" 27 | value = { 28 | hoge = "fuga" 29 | foo = 3 30 | } 31 | } 32 | # => const obj = { "hoge": "fuga", "foo": 3 }; 33 | -------------------------------------------------------------------------------- /examples/data-sources/js_const/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "str" { 2 | assert { 3 | condition = data.js_const.str.statement == "@js/raw:const str=\"hello\"" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "num" { 9 | assert { 10 | condition = data.js_const.num.statement == "@js/raw:const num=10" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "bool" { 16 | assert { 17 | condition = data.js_const.bool.statement == "@js/raw:const bool=true" 18 | error_message = "" 19 | } 20 | } 21 | 22 | run "arr" { 23 | assert { 24 | condition = data.js_const.arr.statement == "@js/raw:const arr=[1,2,3]" 25 | error_message = "" 26 | } 27 | } 28 | 29 | run "obj" { 30 | assert { 31 | condition = data.js_const.obj.statement == "@js/raw:const obj={\"foo\":3,\"hoge\":\"fuga\"}" 32 | error_message = "" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/data-sources/js_const/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_decrement/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "num" { 2 | name = "i" 3 | value = 0 4 | } 5 | 6 | data "js_decrement" "i" { 7 | ref = data.js_let.num.id 8 | } 9 | # => i-- 10 | 11 | data "js_decrement" "i_postfix" { 12 | ref = data.js_let.num.id 13 | type = "postfix" 14 | } 15 | # => i-- 16 | 17 | data "js_decrement" "i_prefix" { 18 | ref = data.js_let.num.id 19 | type = "prefix" 20 | } 21 | # => --i 22 | -------------------------------------------------------------------------------- /examples/data-sources/js_decrement/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "i" { 2 | assert { 3 | condition = data.js_decrement.i.statement == "@js/raw:i--" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "i_postfix" { 9 | assert { 10 | condition = data.js_decrement.i_postfix.statement == "@js/raw:i--" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "i_prefix" { 16 | assert { 17 | condition = data.js_decrement.i_prefix.statement == "@js/raw:--i" 18 | error_message = "" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/data-sources/js_decrement/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_export/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_const" "message" { 2 | name = "message" 3 | value = "hello world" 4 | } 5 | 6 | data "js_export" "message" { 7 | value = data.js_const.message.id 8 | } 9 | # => export message 10 | -------------------------------------------------------------------------------- /examples/data-sources/js_export/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main" { 2 | assert { 3 | condition = data.js_export.message.statement == "@js/raw:export message" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_export/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_for/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "i" { 2 | name = "i" 3 | value = 0 4 | } 5 | 6 | data "js_operation" "i_lt_10" { 7 | left = data.js_let.i.id 8 | operator = "<" 9 | right = 10 10 | } 11 | 12 | data "js_increment" "i" { 13 | ref = data.js_let.i.id 14 | } 15 | 16 | data "js_function_call" "log_i" { 17 | caller = "console" 18 | function = "log" 19 | args = [data.js_let.i.id] 20 | } 21 | 22 | data "js_for" "main" { 23 | init = data.js_let.i.statement 24 | condition = data.js_operation.i_lt_10.expression 25 | update = data.js_increment.i.statement 26 | body = [data.js_function_call.log_i.statement] 27 | } 28 | # => for (let i = 0; i < 10; i++) { 29 | # console.log(i); 30 | # } 31 | -------------------------------------------------------------------------------- /examples/data-sources/js_for/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main" { 2 | assert { 3 | condition = data.js_for.main.statement == "@js/raw:for(let i=0;(i<10);i++){(console.log)(i)}" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_for/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_function/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_function_call" "log_name" { 2 | caller = "console" 3 | function = "log" 4 | args = ["hello", data.js_function_param.name.id] 5 | } 6 | 7 | data "js_function_param" "name" { 8 | name = "name" 9 | } 10 | 11 | data "js_function" "hello" { 12 | name = "hello" 13 | params = [data.js_function_param.name.id] 14 | body = [data.js_function_call.log_name.statement] 15 | } 16 | # => function hello(name) { 17 | # console.log("hello", name); 18 | # } 19 | 20 | data "js_function" "anonymous" { 21 | params = [data.js_function_param.name.id] 22 | body = [data.js_function_call.log_name.statement] 23 | } 24 | 25 | data "js_const" "anonymous" { 26 | name = "anonymous" 27 | value = data.js_function.hello.expression 28 | } 29 | # => const anonymous = function(name) { 30 | # console.log("hello", name); 31 | # }; 32 | 33 | data "js_function" "async" { 34 | name = "hello" 35 | async = true 36 | params = [data.js_function_param.name.id] 37 | body = [data.js_function_call.log_name.statement] 38 | } 39 | # => async function hello(name) { 40 | # console.log("hello", name); 41 | # } 42 | -------------------------------------------------------------------------------- /examples/data-sources/js_function/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "hello" { 2 | assert { 3 | condition = data.js_function.hello.statement == "@js/raw:function hello(name){(console.log)(\"hello\",name)}" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "anonymous" { 9 | assert { 10 | condition = data.js_function.anonymous.statement == "@js/raw:function(name){(console.log)(\"hello\",name)}" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "async" { 16 | assert { 17 | condition = data.js_function.async.statement == "@js/raw:async function hello(name){(console.log)(\"hello\",name)}" 18 | error_message = "" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/data-sources/js_function/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_function_call/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_function_call" "alert" { 2 | function = "alert" 3 | args = ["hello world"] 4 | } 5 | 6 | data "js_function_call" "console_log" { 7 | caller = "console" 8 | function = "log" 9 | args = ["hello", "world"] 10 | } 11 | # => console.log("hello", "world") 12 | -------------------------------------------------------------------------------- /examples/data-sources/js_function_call/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "alert" { 2 | assert { 3 | condition = data.js_function_call.alert.statement == "@js/raw:(alert)(\"hello world\")" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "console_log" { 9 | assert { 10 | condition = data.js_function_call.console_log.statement == "@js/raw:(console.log)(\"hello\",\"world\")" 11 | error_message = "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/js_function_call/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_if/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_function_call" "log_true" { 2 | caller = "console" 3 | function = "log" 4 | args = [true] 5 | } 6 | 7 | data "js_function_call" "log_false" { 8 | caller = "console" 9 | function = "log" 10 | args = [false] 11 | } 12 | 13 | data "js_raw" "true" { 14 | value = "true" 15 | } 16 | 17 | data "js_if" "main" { 18 | condition = data.js_raw.true.content 19 | then = [data.js_function_call.log_true.statement] 20 | else = [data.js_function_call.log_false.statement] 21 | } 22 | # => if (true) { 23 | # console.log(true); 24 | # } else { 25 | # console.log(false); 26 | # } 27 | -------------------------------------------------------------------------------- /examples/data-sources/js_if/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main" { 2 | assert { 3 | condition = data.js_if.main.statement == "@js/raw:if(true){(console.log)(true)}else{(console.log)(false)}" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_if/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_import/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_import" "as" { 2 | from = "path/to/module" 3 | as = "name" 4 | } 5 | # => import * as name from "path/to/module" 6 | 7 | data "js_import" "default" { 8 | from = "path/to/module" 9 | as = "name" 10 | default = true 11 | } 12 | # => import name from "path/to/module" 13 | -------------------------------------------------------------------------------- /examples/data-sources/js_import/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "as" { 2 | assert { 3 | condition = data.js_import.as.statement == "@js/raw:import * as name from \"path/to/module\"" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "default" { 9 | assert { 10 | condition = data.js_import.default.statement == "@js/raw:import name from \"path/to/module\"" 11 | error_message = "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/js_import/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_increment/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "num" { 2 | name = "i" 3 | value = 0 4 | } 5 | 6 | data "js_increment" "i" { 7 | ref = data.js_let.num.id 8 | } 9 | # => i++ 10 | 11 | data "js_increment" "i_postfix" { 12 | ref = data.js_let.num.id 13 | type = "postfix" 14 | } 15 | # => i++ 16 | 17 | data "js_increment" "i_prefix" { 18 | ref = data.js_let.num.id 19 | type = "prefix" 20 | } 21 | # => ++i 22 | -------------------------------------------------------------------------------- /examples/data-sources/js_increment/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "i" { 2 | assert { 3 | condition = data.js_increment.i.statement == "@js/raw:i++" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "i_postfix" { 9 | assert { 10 | condition = data.js_increment.i_postfix.statement == "@js/raw:i++" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "i_prefix" { 16 | assert { 17 | condition = data.js_increment.i_prefix.statement == "@js/raw:++i" 18 | error_message = "" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/data-sources/js_increment/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_index/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_const" "arr" { 2 | name = "arr" 3 | value = [1, 2, 3] 4 | } 5 | 6 | data "js_index" "arr_1" { 7 | ref = data.js_const.arr.id 8 | value = 1 9 | } 10 | # => arr[1] 11 | 12 | data "js_const" "obj" { 13 | name = "obj" 14 | value = { 15 | foo = "bar" 16 | } 17 | } 18 | 19 | data "js_index" "obj_foo" { 20 | ref = data.js_const.obj.id 21 | value = "foo" 22 | } 23 | # => obj["foo"] 24 | -------------------------------------------------------------------------------- /examples/data-sources/js_index/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "arr_1" { 2 | assert { 3 | condition = data.js_index.arr_1.statement == "@js/raw:arr[1]" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "obj_foo" { 9 | assert { 10 | condition = data.js_index.obj_foo.statement == "@js/raw:obj[\"foo\"]" 11 | error_message = "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/data-sources/js_index/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_let/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "str" { 2 | name = "str" 3 | value = "hello" 4 | } 5 | # => let str = "hello"; 6 | 7 | data "js_let" "num" { 8 | name = "num" 9 | value = 10 10 | } 11 | # => let num = 10; 12 | 13 | data "js_let" "bool" { 14 | name = "bool" 15 | value = true 16 | } 17 | # => let bool = true; 18 | 19 | data "js_let" "arr" { 20 | name = "arr" 21 | value = [1, 2, 3] 22 | } 23 | # => let arr = [1, 2, 3]; 24 | 25 | data "js_let" "obj" { 26 | name = "obj" 27 | value = { 28 | hoge = "fuga" 29 | foo = 3 30 | } 31 | } 32 | # => let obj = { "hoge": "fuga", "foo": 3 }; 33 | -------------------------------------------------------------------------------- /examples/data-sources/js_let/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "str" { 2 | assert { 3 | condition = data.js_let.str.statement == "@js/raw:let str=\"hello\"" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "num" { 9 | assert { 10 | condition = data.js_let.num.statement == "@js/raw:let num=10" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "bool" { 16 | assert { 17 | condition = data.js_let.bool.statement == "@js/raw:let bool=true" 18 | error_message = "" 19 | } 20 | } 21 | 22 | run "arr" { 23 | assert { 24 | condition = data.js_let.arr.statement == "@js/raw:let arr=[1,2,3]" 25 | error_message = "" 26 | } 27 | } 28 | 29 | run "obj" { 30 | assert { 31 | condition = data.js_let.obj.statement == "@js/raw:let obj={\"foo\":3,\"hoge\":\"fuga\"}" 32 | error_message = "" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/data-sources/js_let/provider.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | js = { 4 | source = "registry.terraform.io/koki-develop/js" 5 | } 6 | } 7 | } 8 | 9 | provider "js" {} 10 | -------------------------------------------------------------------------------- /examples/data-sources/js_new/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_new" "error" { 2 | constructor = "Error" 3 | args = ["something went wrong"] 4 | } 5 | # => new Error("something went wrong") 6 | -------------------------------------------------------------------------------- /examples/data-sources/js_new/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "error" { 2 | assert { 3 | condition = data.js_new.error.statement == "@js/raw:new Error(\"something went wrong\")" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_new/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_operation/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "a" { 2 | name = "a" 3 | value = 0 4 | } 5 | 6 | data "js_let" "b" { 7 | name = "b" 8 | value = 10 9 | } 10 | 11 | data "js_operation" "a_plus_b" { 12 | left = data.js_let.a.id 13 | operator = "+" 14 | right = data.js_let.b.id 15 | } 16 | # => a + b 17 | 18 | data "js_operation" "a_minus_b" { 19 | left = data.js_let.a.id 20 | operator = "-" 21 | right = data.js_let.b.id 22 | } 23 | # => a - b 24 | 25 | data "js_operation" "a_times_b" { 26 | left = data.js_let.a.id 27 | operator = "*" 28 | right = data.js_let.b.id 29 | } 30 | # => a * b 31 | 32 | data "js_operation" "a_div_b" { 33 | left = data.js_let.a.id 34 | operator = "/" 35 | right = data.js_let.b.id 36 | } 37 | # => a / b 38 | 39 | data "js_operation" "a_mod_b" { 40 | left = data.js_let.a.id 41 | operator = "%" 42 | right = data.js_let.b.id 43 | } 44 | # => a % b 45 | 46 | data "js_operation" "a_lt_b" { 47 | left = data.js_let.a.id 48 | operator = "<" 49 | right = data.js_let.b.id 50 | } 51 | # => a < b 52 | 53 | data "js_operation" "a_lte_b" { 54 | left = data.js_let.a.id 55 | operator = "<=" 56 | right = data.js_let.b.id 57 | } 58 | # => a <= b 59 | 60 | data "js_operation" "a_gt_b" { 61 | left = data.js_let.a.id 62 | operator = ">" 63 | right = data.js_let.b.id 64 | } 65 | # => a > b 66 | 67 | data "js_operation" "a_gte_b" { 68 | left = data.js_let.a.id 69 | operator = ">=" 70 | right = data.js_let.b.id 71 | } 72 | # => a > b 73 | 74 | data "js_operation" "a_eq_b" { 75 | left = data.js_let.a.id 76 | operator = "===" 77 | right = data.js_let.b.id 78 | } 79 | # => a === b 80 | 81 | data "js_operation" "assign_a_to_b" { 82 | left = data.js_let.a.id 83 | operator = "=" 84 | right = data.js_let.b.id 85 | } 86 | # => a = b 87 | -------------------------------------------------------------------------------- /examples/data-sources/js_operation/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "a_plus_b" { 2 | assert { 3 | condition = data.js_operation.a_plus_b.statement == "@js/raw:(a+b)" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "a_minus_b" { 9 | assert { 10 | condition = data.js_operation.a_minus_b.statement == "@js/raw:(a-b)" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "a_times_b" { 16 | assert { 17 | condition = data.js_operation.a_times_b.statement == "@js/raw:(a*b)" 18 | error_message = "" 19 | } 20 | } 21 | 22 | run "a_div_b" { 23 | assert { 24 | condition = data.js_operation.a_div_b.statement == "@js/raw:(a/b)" 25 | error_message = "" 26 | } 27 | } 28 | 29 | run "a_mod_b" { 30 | assert { 31 | condition = data.js_operation.a_mod_b.statement == "@js/raw:(a%b)" 32 | error_message = "" 33 | } 34 | } 35 | 36 | run "a_lt_b" { 37 | assert { 38 | condition = data.js_operation.a_lt_b.statement == "@js/raw:(a const message = "hello world"; 19 | # console.log(message); 20 | -------------------------------------------------------------------------------- /examples/data-sources/js_program/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main" { 2 | assert { 3 | condition = data.js_program.main.content == chomp( 4 | <<-EOT 5 | // Code generated by JS.tf vdev (https://registry.terraform.io/providers/koki-develop/js/dev) 6 | const message="hello world";console.log(message) 7 | EOT 8 | ) 9 | 10 | error_message = "" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/data-sources/js_program/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_raw/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_raw" "example" { 2 | value = "console.log('Hello, World!');" 3 | } 4 | -------------------------------------------------------------------------------- /examples/data-sources/js_raw/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "example" { 2 | assert { 3 | condition = data.js_raw.example.content == "@js/raw:console.log('Hello, World!');" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_raw/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_return/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_return" "hello" { 2 | value = "hello world" 3 | } 4 | 5 | data "js_function" "hello" { 6 | name = "hello" 7 | body = [data.js_return.hello.statement] 8 | } 9 | # => function hello() { 10 | # return "hello world" 11 | # } 12 | -------------------------------------------------------------------------------- /examples/data-sources/js_return/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "hello" { 2 | assert { 3 | condition = data.js_function.hello.statement == "@js/raw:function hello(){return \"hello world\"}" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_return/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_throw/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_new" "error" { 2 | constructor = "Error" 3 | args = ["something went wrong"] 4 | } 5 | 6 | data "js_throw" "error" { 7 | value = data.js_new.error.expression 8 | } 9 | # => throw new Error("something went wrong") 10 | -------------------------------------------------------------------------------- /examples/data-sources/js_throw/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "error" { 2 | assert { 3 | condition = data.js_throw.error.statement == "@js/raw:throw new Error(\"something went wrong\")" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_throw/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_var/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_var" "str" { 2 | name = "str" 3 | value = "hello" 4 | } 5 | # => var str = "hello"; 6 | 7 | data "js_var" "num" { 8 | name = "num" 9 | value = 10 10 | } 11 | # => var num = 10; 12 | 13 | data "js_var" "bool" { 14 | name = "bool" 15 | value = true 16 | } 17 | # => var bool = true; 18 | 19 | data "js_var" "arr" { 20 | name = "arr" 21 | value = [1, 2, 3] 22 | } 23 | # => var arr = [1, 2, 3]; 24 | 25 | data "js_var" "obj" { 26 | name = "obj" 27 | value = { 28 | hoge = "fuga" 29 | foo = 3 30 | } 31 | } 32 | # => var obj = { "hoge": "fuga", "foo": 3 }; 33 | -------------------------------------------------------------------------------- /examples/data-sources/js_var/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "str" { 2 | assert { 3 | condition = data.js_var.str.statement == "@js/raw:var str=\"hello\"" 4 | error_message = "" 5 | } 6 | } 7 | 8 | run "num" { 9 | assert { 10 | condition = data.js_var.num.statement == "@js/raw:var num=10" 11 | error_message = "" 12 | } 13 | } 14 | 15 | run "bool" { 16 | assert { 17 | condition = data.js_var.bool.statement == "@js/raw:var bool=true" 18 | error_message = "" 19 | } 20 | } 21 | 22 | run "arr" { 23 | assert { 24 | condition = data.js_var.arr.statement == "@js/raw:var arr=[1,2,3]" 25 | error_message = "" 26 | } 27 | } 28 | 29 | run "obj" { 30 | assert { 31 | condition = data.js_var.obj.statement == "@js/raw:var obj={\"foo\":3,\"hoge\":\"fuga\"}" 32 | error_message = "" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/data-sources/js_var/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/data-sources/js_while/data-source.tf: -------------------------------------------------------------------------------- 1 | data "js_let" "i" { 2 | name = "i" 3 | value = 0 4 | } 5 | 6 | data "js_operation" "i_lt_10" { 7 | left = data.js_let.i.id 8 | operator = "<" 9 | right = 10 10 | } 11 | 12 | data "js_function_call" "log_i" { 13 | caller = "console" 14 | function = "log" 15 | args = [data.js_let.i.id] 16 | } 17 | 18 | data "js_increment" "i" { 19 | ref = data.js_let.i.id 20 | } 21 | 22 | data "js_while" "main" { 23 | condition = data.js_operation.i_lt_10.expression 24 | body = [data.js_function_call.log_i.statement, data.js_increment.i.statement] 25 | } 26 | # => while (i < 10) { 27 | # console.log(i); 28 | # i++; 29 | # } 30 | -------------------------------------------------------------------------------- /examples/data-sources/js_while/data-source.tftest.hcl: -------------------------------------------------------------------------------- 1 | run "main" { 2 | assert { 3 | condition = data.js_while.main.statement == "@js/raw:while((i<10)){(console.log)(i);i++}" 4 | error_message = "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/data-sources/js_while/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/others/aws_lambda/.gitignore: -------------------------------------------------------------------------------- 1 | /index.zip 2 | -------------------------------------------------------------------------------- /examples/others/aws_lambda/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lambda_function" "main" { 2 | function_name = "hello-jstf" 3 | role = aws_iam_role.assume_role.arn 4 | publish = true 5 | 6 | runtime = "nodejs20.x" 7 | source_code_hash = data.archive_file.source_code.output_base64sha256 8 | filename = data.archive_file.source_code.output_path 9 | handler = "index.handler" 10 | } 11 | 12 | resource "aws_iam_role" "assume_role" { 13 | name = "iam_for_lambda" 14 | assume_role_policy = data.aws_iam_policy_document.assume_role.json 15 | } 16 | 17 | data "aws_iam_policy_document" "assume_role" { 18 | statement { 19 | effect = "Allow" 20 | actions = ["sts:AssumeRole"] 21 | 22 | principals { 23 | type = "Service" 24 | identifiers = ["lambda.amazonaws.com"] 25 | } 26 | } 27 | } 28 | 29 | data "archive_file" "source_code" { 30 | type = "zip" 31 | output_path = "index.zip" 32 | source_content_filename = "index.mjs" 33 | source_content = data.js_program.main.content 34 | } 35 | 36 | data "js_program" "main" { 37 | statements = [data.js_export.handler.statement] 38 | } 39 | 40 | data "js_function" "handler" { 41 | name = "handler" 42 | async = true 43 | params = [data.js_function_param.event.id] 44 | body = [ 45 | data.js_function_call.log_event.statement, 46 | data.js_return.handler.statement, 47 | ] 48 | } 49 | 50 | data "js_function_param" "event" { 51 | name = "event" 52 | } 53 | 54 | data "js_function_call" "log_event" { 55 | caller = "console" 56 | function = "log" 57 | args = ["event:", data.js_function_param.event.id] 58 | } 59 | 60 | data "js_return" "handler" { 61 | value = { 62 | message = "Hello JS.tf!" 63 | } 64 | } 65 | 66 | data "js_export" "handler" { 67 | value = data.js_function.handler.statement 68 | } 69 | -------------------------------------------------------------------------------- /examples/others/aws_lambda/provider.tf: -------------------------------------------------------------------------------- 1 | ../../provider.tf -------------------------------------------------------------------------------- /examples/provider.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | js = { 4 | source = "registry.terraform.io/koki-develop/js" 5 | } 6 | } 7 | } 8 | 9 | provider "js" {} 10 | -------------------------------------------------------------------------------- /examples/provider/provider.tf: -------------------------------------------------------------------------------- 1 | data "js_function_call" "hello_world" { 2 | caller = "console" 3 | function = "log" 4 | args = ["hello world"] 5 | } 6 | 7 | data "js_program" "main" { 8 | statements = [data.js_function_call.hello_world.statement] 9 | } 10 | 11 | resource "local_file" "main" { 12 | filename = "index.js" 13 | content = data.js_program.main.content 14 | } 15 | -------------------------------------------------------------------------------- /examples/provider/terraform.tf: -------------------------------------------------------------------------------- 1 | ../provider.tf -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/koki-develop/terraform-provider-js 2 | 3 | go 1.22.5 4 | 5 | require ( 6 | github.com/hashicorp/terraform-plugin-docs v0.19.4 7 | github.com/hashicorp/terraform-plugin-framework v1.10.0 8 | github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 9 | github.com/stretchr/testify v1.8.2 10 | github.com/tdewolff/minify/v2 v2.21.2 11 | ) 12 | 13 | require ( 14 | github.com/BurntSushi/toml v1.2.1 // indirect 15 | github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect 16 | github.com/Masterminds/goutils v1.1.1 // indirect 17 | github.com/Masterminds/semver/v3 v3.2.0 // indirect 18 | github.com/Masterminds/sprig/v3 v3.2.3 // indirect 19 | github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect 20 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 21 | github.com/armon/go-radix v1.0.0 // indirect 22 | github.com/bgentry/speakeasy v0.1.0 // indirect 23 | github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect 24 | github.com/cloudflare/circl v1.3.7 // indirect 25 | github.com/davecgh/go-spew v1.1.1 // indirect 26 | github.com/fatih/color v1.16.0 // indirect 27 | github.com/golang/protobuf v1.5.4 // indirect 28 | github.com/google/uuid v1.6.0 // indirect 29 | github.com/hashicorp/cli v1.1.6 // indirect 30 | github.com/hashicorp/errwrap v1.1.0 // indirect 31 | github.com/hashicorp/go-checkpoint v0.5.0 // indirect 32 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 33 | github.com/hashicorp/go-hclog v1.5.0 // indirect 34 | github.com/hashicorp/go-multierror v1.1.1 // indirect 35 | github.com/hashicorp/go-plugin v1.6.0 // indirect 36 | github.com/hashicorp/go-uuid v1.0.3 // indirect 37 | github.com/hashicorp/go-version v1.7.0 // indirect 38 | github.com/hashicorp/hc-install v0.7.0 // indirect 39 | github.com/hashicorp/terraform-exec v0.21.0 // indirect 40 | github.com/hashicorp/terraform-json v0.22.1 // indirect 41 | github.com/hashicorp/terraform-plugin-go v0.23.0 // indirect 42 | github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect 43 | github.com/hashicorp/terraform-registry-address v0.2.3 // indirect 44 | github.com/hashicorp/terraform-svchost v0.1.1 // indirect 45 | github.com/hashicorp/yamux v0.1.1 // indirect 46 | github.com/huandu/xstrings v1.3.3 // indirect 47 | github.com/imdario/mergo v0.3.15 // indirect 48 | github.com/mattn/go-colorable v0.1.13 // indirect 49 | github.com/mattn/go-isatty v0.0.20 // indirect 50 | github.com/mattn/go-runewidth v0.0.9 // indirect 51 | github.com/mitchellh/copystructure v1.2.0 // indirect 52 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 53 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 54 | github.com/oklog/run v1.0.0 // indirect 55 | github.com/pmezard/go-difflib v1.0.0 // indirect 56 | github.com/posener/complete v1.2.3 // indirect 57 | github.com/shopspring/decimal v1.3.1 // indirect 58 | github.com/spf13/cast v1.5.0 // indirect 59 | github.com/tdewolff/parse/v2 v2.7.19 // indirect 60 | github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 61 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 62 | github.com/yuin/goldmark v1.7.1 // indirect 63 | github.com/yuin/goldmark-meta v1.1.0 // indirect 64 | github.com/zclconf/go-cty v1.14.4 // indirect 65 | go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect 66 | golang.org/x/crypto v0.21.0 // indirect 67 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect 68 | golang.org/x/mod v0.17.0 // indirect 69 | golang.org/x/net v0.23.0 // indirect 70 | golang.org/x/sys v0.25.0 // indirect 71 | golang.org/x/text v0.15.0 // indirect 72 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect 73 | google.golang.org/grpc v1.63.2 // indirect 74 | google.golang.org/protobuf v1.34.0 // indirect 75 | gopkg.in/yaml.v2 v2.3.0 // indirect 76 | gopkg.in/yaml.v3 v3.0.1 // indirect 77 | ) 78 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= 2 | dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= 3 | github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= 4 | github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 5 | github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= 6 | github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= 7 | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= 8 | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= 9 | github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= 10 | github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= 11 | github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= 12 | github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= 13 | github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= 14 | github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= 15 | github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= 16 | github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= 17 | github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= 18 | github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= 19 | github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= 20 | github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 21 | github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= 22 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 23 | github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= 24 | github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= 25 | github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= 26 | github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= 27 | github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= 28 | github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= 29 | github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= 30 | github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 31 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 32 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 33 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 34 | github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= 35 | github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= 36 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 37 | github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= 38 | github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 39 | github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= 40 | github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= 41 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= 42 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= 43 | github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= 44 | github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= 45 | github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= 46 | github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= 47 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 48 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 49 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 50 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 51 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 52 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 53 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 54 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 55 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 56 | github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8= 57 | github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4= 58 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 59 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= 60 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 61 | github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= 62 | github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= 63 | github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 64 | github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= 65 | github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= 66 | github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= 67 | github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 68 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 69 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 70 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 71 | github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= 72 | github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= 73 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 74 | github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= 75 | github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 76 | github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= 77 | github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 78 | github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= 79 | github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= 80 | github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= 81 | github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= 82 | github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= 83 | github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= 84 | github.com/hashicorp/terraform-plugin-docs v0.19.4 h1:G3Bgo7J22OMtegIgn8Cd/CaSeyEljqjH3G39w28JK4c= 85 | github.com/hashicorp/terraform-plugin-docs v0.19.4/go.mod h1:4pLASsatTmRynVzsjEhbXZ6s7xBlUw/2Kt0zfrq8HxA= 86 | github.com/hashicorp/terraform-plugin-framework v1.10.0 h1:xXhICE2Fns1RYZxEQebwkB2+kXouLC932Li9qelozrc= 87 | github.com/hashicorp/terraform-plugin-framework v1.10.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM= 88 | github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E= 89 | github.com/hashicorp/terraform-plugin-framework-validators v0.13.0/go.mod h1:wGeI02gEhj9nPANU62F2jCaHjXulejm/X+af4PdZaNo= 90 | github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= 91 | github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= 92 | github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= 93 | github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= 94 | github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= 95 | github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= 96 | github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= 97 | github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= 98 | github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= 99 | github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= 100 | github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= 101 | github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 102 | github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 103 | github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= 104 | github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= 105 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 106 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 107 | github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= 108 | github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= 109 | github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= 110 | github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 111 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 112 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 113 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 114 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 115 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 116 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 117 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 118 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 119 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 120 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 121 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 122 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 123 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 124 | github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= 125 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 126 | github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 127 | github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= 128 | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= 129 | github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= 130 | github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= 131 | github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 132 | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= 133 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 134 | github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= 135 | github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= 136 | github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= 137 | github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= 138 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 139 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 140 | github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= 141 | github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= 142 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 143 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 144 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= 145 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 146 | github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 147 | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= 148 | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 149 | github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= 150 | github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= 151 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 152 | github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= 153 | github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 154 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 155 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 156 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 157 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 158 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 159 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 160 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 161 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 162 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 163 | github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= 164 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 165 | github.com/tdewolff/minify/v2 v2.21.2 h1:VfTvmGVtBYhMTlUAeHtXM7XOsW0JT/6uMwUPPqgUs9k= 166 | github.com/tdewolff/minify/v2 v2.21.2/go.mod h1:Olje3eHdBnrMjINKffDsil/3NV98Iv7MhWf7556WQVg= 167 | github.com/tdewolff/parse/v2 v2.7.19 h1:7Ljh26yj+gdLFEq/7q9LT4SYyKtwQX4ocNrj45UCePg= 168 | github.com/tdewolff/parse/v2 v2.7.19/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= 169 | github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= 170 | github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= 171 | github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= 172 | github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= 173 | github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= 174 | github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= 175 | github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= 176 | github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= 177 | github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 178 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 179 | github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= 180 | github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= 181 | github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= 182 | github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= 183 | github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= 184 | github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= 185 | go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= 186 | go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= 187 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 188 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 189 | golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= 190 | golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= 191 | golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 192 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= 193 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= 194 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 195 | golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= 196 | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 197 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 198 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 199 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 200 | golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= 201 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 202 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 203 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 204 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 205 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 206 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 207 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 208 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 209 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 210 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 211 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 212 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 213 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 214 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 215 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 216 | golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 217 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 218 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 219 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 220 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 221 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 222 | golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 223 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 224 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 225 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 226 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 227 | golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= 228 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 229 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 230 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 231 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 232 | golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= 233 | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 234 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 235 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= 236 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= 237 | google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= 238 | google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= 239 | google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= 240 | google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 241 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 242 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 243 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 244 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 245 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 246 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 247 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 248 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 249 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 250 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 251 | -------------------------------------------------------------------------------- /internal/datasources/await.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataSourceAwait{} 15 | ) 16 | 17 | func NewDataAwait() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataSourceAwait{} 20 | } 21 | } 22 | 23 | type dataSourceAwait struct{} 24 | 25 | func (d *dataSourceAwait) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_await" 27 | } 28 | 29 | func (d *dataSourceAwait) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "value": schema.DynamicAttribute{ 33 | Description: "A Promise, a thenable object, or any value to wait for.", 34 | Required: true, 35 | }, 36 | 37 | "expression": schema.StringAttribute{ 38 | Computed: true, 39 | }, 40 | "statement": schema.StringAttribute{ 41 | Computed: true, 42 | }, 43 | }, 44 | } 45 | } 46 | 47 | type dataSourceAwaitModel struct { 48 | Value types.Dynamic `tfsdk:"value"` 49 | 50 | Expression types.String `tfsdk:"expression"` 51 | Statement types.String `tfsdk:"statement"` 52 | } 53 | 54 | func (d *dataSourceAwait) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 55 | util.HandleRequest( 56 | ctx, 57 | &dataSourceAwaitModel{}, 58 | &req.Config, 59 | &resp.State, 60 | &resp.Diagnostics, 61 | func(m *dataSourceAwaitModel) bool { 62 | c := new(strings.Builder) 63 | c.WriteString("await ") 64 | c.WriteString(util.StringifyValue(m.Value)) 65 | 66 | m.Expression = util.Raw(types.StringValue(c.String())) 67 | m.Statement = m.Expression 68 | return true 69 | }, 70 | ) 71 | } 72 | -------------------------------------------------------------------------------- /internal/datasources/conditional_operation.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataConditionalOperation{} 15 | ) 16 | 17 | func NewDataConditionalOperation() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataConditionalOperation{} 20 | } 21 | } 22 | 23 | type dataConditionalOperation struct{} 24 | 25 | func (d *dataConditionalOperation) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_conditional_operation" 27 | } 28 | 29 | func (d *dataConditionalOperation) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "condition": schema.DynamicAttribute{ 33 | Description: "An expression whose value is used as a condition. ", 34 | Required: true, 35 | }, 36 | "if_true": schema.DynamicAttribute{ 37 | Description: "An expression which is executed if the condition evaluates to a truthy value.", 38 | Required: true, 39 | }, 40 | "if_false": schema.DynamicAttribute{ 41 | Description: "An expression which is executed if the condition is falsy.", 42 | Required: true, 43 | }, 44 | 45 | "expression": schema.StringAttribute{ 46 | Computed: true, 47 | }, 48 | "statement": schema.StringAttribute{ 49 | Computed: true, 50 | }, 51 | }, 52 | } 53 | } 54 | 55 | type dataConditionalOperationModel struct { 56 | Condition types.Dynamic `tfsdk:"condition"` 57 | IfTrue types.Dynamic `tfsdk:"if_true"` 58 | IfFalse types.Dynamic `tfsdk:"if_false"` 59 | 60 | Expression types.String `tfsdk:"expression"` 61 | Statement types.String `tfsdk:"statement"` 62 | } 63 | 64 | func (d *dataConditionalOperation) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 65 | util.HandleRequest( 66 | ctx, 67 | &dataConditionalOperationModel{}, 68 | &req.Config, 69 | &resp.State, 70 | &resp.Diagnostics, 71 | func(m *dataConditionalOperationModel) bool { 72 | c := new(strings.Builder) 73 | c.WriteString("(") 74 | c.WriteString(util.StringifyValue(m.Condition)) 75 | c.WriteString("?") 76 | c.WriteString(util.StringifyValue(m.IfTrue)) 77 | c.WriteString(":") 78 | c.WriteString(util.StringifyValue(m.IfFalse)) 79 | c.WriteString(")") 80 | 81 | m.Expression = util.Raw(types.StringValue(c.String())) 82 | m.Statement = m.Expression 83 | return true 84 | }, 85 | ) 86 | } 87 | -------------------------------------------------------------------------------- /internal/datasources/const.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataConst{} 15 | ) 16 | 17 | func NewDataConst() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataConst{} 20 | } 21 | } 22 | 23 | type dataConst struct{} 24 | 25 | func (d *dataConst) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_const" 27 | } 28 | 29 | func (d *dataConst) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "name": schema.StringAttribute{ 33 | Description: "Name of variable to declare.", 34 | Required: true, 35 | }, 36 | "value": schema.DynamicAttribute{ 37 | Description: "Initial value of the variable.", 38 | Required: true, 39 | }, 40 | 41 | "id": schema.StringAttribute{ 42 | Computed: true, 43 | }, 44 | "expression": schema.StringAttribute{ 45 | Computed: true, 46 | }, 47 | "statement": schema.StringAttribute{ 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | type dataConstModel struct { 55 | Name types.String `tfsdk:"name"` 56 | Value types.Dynamic `tfsdk:"value"` 57 | 58 | ID types.String `tfsdk:"id"` 59 | Expression types.String `tfsdk:"expression"` 60 | Statement types.String `tfsdk:"statement"` 61 | } 62 | 63 | func (d *dataConst) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 64 | util.HandleRequest( 65 | ctx, 66 | &dataConstModel{}, 67 | &req.Config, 68 | &resp.State, 69 | &resp.Diagnostics, 70 | func(m *dataConstModel) bool { 71 | m.ID = util.Raw(m.Name) 72 | m.Expression = m.ID 73 | m.Statement = util.Raw(types.StringValue(fmt.Sprintf("const %s=%s", util.RawString(m.Name), util.StringifyValue(m.Value)))) 74 | return true 75 | }, 76 | ) 77 | } 78 | -------------------------------------------------------------------------------- /internal/datasources/decrement.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 10 | "github.com/hashicorp/terraform-plugin-framework/schema/validator" 11 | "github.com/hashicorp/terraform-plugin-framework/types" 12 | "github.com/koki-develop/terraform-provider-js/internal/util" 13 | ) 14 | 15 | var ( 16 | _ datasource.DataSource = &dataDecrement{} 17 | ) 18 | 19 | func NewDataDecrement() func() datasource.DataSource { 20 | return func() datasource.DataSource { 21 | return &dataDecrement{} 22 | } 23 | } 24 | 25 | type dataDecrement struct{} 26 | 27 | func (d *dataDecrement) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 28 | resp.TypeName = req.ProviderTypeName + "_decrement" 29 | } 30 | 31 | func (d *dataDecrement) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 32 | resp.Schema = schema.Schema{ 33 | Attributes: map[string]schema.Attribute{ 34 | "ref": schema.StringAttribute{ 35 | Description: "Reference to decrement.", 36 | Required: true, 37 | }, 38 | "type": schema.StringAttribute{ 39 | Description: "Type of decrement to perform. (Valid values: `prefix`, `postfix`)", 40 | Optional: true, 41 | Validators: []validator.String{ 42 | stringvalidator.OneOf("prefix", "postfix"), 43 | }, 44 | }, 45 | 46 | "expression": schema.StringAttribute{ 47 | Computed: true, 48 | }, 49 | "statement": schema.StringAttribute{ 50 | Computed: true, 51 | }, 52 | }, 53 | } 54 | } 55 | 56 | type dataDecrementModel struct { 57 | Ref types.String `tfsdk:"ref"` 58 | Type types.String `tfsdk:"type"` 59 | 60 | Expression types.String `tfsdk:"expression"` 61 | Statement types.String `tfsdk:"statement"` 62 | } 63 | 64 | func (d *dataDecrement) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 65 | util.HandleRequest( 66 | ctx, 67 | &dataDecrementModel{}, 68 | &req.Config, 69 | &resp.State, 70 | &resp.Diagnostics, 71 | func(m *dataDecrementModel) bool { 72 | c := new(strings.Builder) 73 | tp := m.Type.ValueString() 74 | 75 | if tp == "prefix" { 76 | c.WriteString("--") 77 | } 78 | c.WriteString(util.RawString(m.Ref)) 79 | if m.Type.IsNull() || tp == "postfix" { 80 | c.WriteString("--") 81 | } 82 | 83 | m.Expression = util.Raw(types.StringValue(c.String())) 84 | m.Statement = m.Expression 85 | return true 86 | }, 87 | ) 88 | } 89 | -------------------------------------------------------------------------------- /internal/datasources/export.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataExport{} 15 | ) 16 | 17 | func NewDataExport() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataExport{} 20 | } 21 | } 22 | 23 | type dataExport struct{} 24 | 25 | func (d *dataExport) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_export" 27 | } 28 | 29 | func (d *dataExport) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "value": schema.DynamicAttribute{ 33 | Description: "Value to be exported", 34 | Required: true, 35 | }, 36 | 37 | "statement": schema.StringAttribute{ 38 | Computed: true, 39 | }, 40 | }, 41 | } 42 | } 43 | 44 | type dataExportModel struct { 45 | Value types.Dynamic `tfsdk:"value"` 46 | 47 | Statement types.String `tfsdk:"statement"` 48 | } 49 | 50 | func (d *dataExport) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 51 | util.HandleRequest( 52 | ctx, 53 | &dataExportModel{}, 54 | &req.Config, 55 | &resp.State, 56 | &resp.Diagnostics, 57 | func(m *dataExportModel) bool { 58 | c := new(strings.Builder) 59 | c.WriteString("export ") 60 | c.WriteString(util.StringifyValue(m.Value)) 61 | 62 | m.Statement = util.Raw(types.StringValue(c.String())) 63 | return true 64 | }, 65 | ) 66 | } 67 | -------------------------------------------------------------------------------- /internal/datasources/for.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataFor{} 15 | ) 16 | 17 | func NewDataFor() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataFor{} 20 | } 21 | } 22 | 23 | type dataFor struct{} 24 | 25 | func (d *dataFor) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_for" 27 | } 28 | 29 | func (d *dataFor) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "init": schema.StringAttribute{ 33 | Description: "An expression or variable declaration evaluated once before the loop begins.", 34 | Optional: true, 35 | }, 36 | "condition": schema.StringAttribute{ 37 | Description: "An expression to be evaluated before each loop iteration.", 38 | Optional: true, 39 | }, 40 | "update": schema.StringAttribute{ 41 | Description: "An expression to be evaluated at the end of each loop iteration.", 42 | Optional: true, 43 | }, 44 | "body": schema.ListAttribute{ 45 | Description: "Statements that is executed as long as the condition evaluates to true.", 46 | ElementType: types.StringType, 47 | Optional: true, 48 | }, 49 | 50 | "statement": schema.StringAttribute{ 51 | Computed: true, 52 | }, 53 | }, 54 | } 55 | } 56 | 57 | type dataForModel struct { 58 | Init types.String `tfsdk:"init"` 59 | Condition types.String `tfsdk:"condition"` 60 | Update types.String `tfsdk:"update"` 61 | Body types.List `tfsdk:"body"` 62 | 63 | Statement types.String `tfsdk:"statement"` 64 | } 65 | 66 | func (d *dataFor) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 67 | util.HandleRequest( 68 | ctx, 69 | &dataForModel{}, 70 | &req.Config, 71 | &resp.State, 72 | &resp.Diagnostics, 73 | func(m *dataForModel) bool { 74 | c := new(strings.Builder) 75 | c.WriteString("for(") 76 | if !m.Init.IsNull() { 77 | c.WriteString(util.StringifyValue(m.Init)) 78 | } 79 | c.WriteString(";") 80 | 81 | if !m.Condition.IsNull() { 82 | c.WriteString(util.StringifyValue(m.Condition)) 83 | } 84 | c.WriteString(";") 85 | 86 | if !m.Update.IsNull() { 87 | c.WriteString(util.StringifyValue(m.Update)) 88 | } 89 | 90 | c.WriteString("){") 91 | 92 | if !m.Body.IsNull() { 93 | c.WriteString(util.StringifyStatements(m.Body.Elements())) 94 | } 95 | c.WriteString("}") 96 | 97 | m.Statement = util.Raw(types.StringValue(c.String())) 98 | return true 99 | }, 100 | ) 101 | } 102 | -------------------------------------------------------------------------------- /internal/datasources/function.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/diag" 10 | "github.com/hashicorp/terraform-plugin-framework/types" 11 | "github.com/koki-develop/terraform-provider-js/internal/util" 12 | ) 13 | 14 | var ( 15 | _ datasource.DataSource = &dataFunction{} 16 | ) 17 | 18 | func NewDataFunction() func() datasource.DataSource { 19 | return func() datasource.DataSource { 20 | return &dataFunction{} 21 | } 22 | } 23 | 24 | type dataFunction struct{} 25 | 26 | func (d *dataFunction) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 27 | resp.TypeName = req.ProviderTypeName + "_function" 28 | } 29 | 30 | func (d *dataFunction) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 31 | resp.Schema = schema.Schema{ 32 | Attributes: map[string]schema.Attribute{ 33 | "name": schema.StringAttribute{ 34 | Description: "Name of function.", 35 | Optional: true, 36 | }, 37 | "params": schema.ListAttribute{ 38 | Description: "Parameters of function.", 39 | ElementType: types.StringType, 40 | Optional: true, 41 | }, 42 | "body": schema.ListAttribute{ 43 | Description: "Body of function.", 44 | ElementType: types.StringType, 45 | Optional: true, 46 | }, 47 | "async": schema.BoolAttribute{ 48 | Description: "Whether function is async.", 49 | Optional: true, 50 | }, 51 | 52 | "id": schema.StringAttribute{ 53 | Computed: true, 54 | }, 55 | "expression": schema.StringAttribute{ 56 | Computed: true, 57 | }, 58 | "statement": schema.StringAttribute{ 59 | Computed: true, 60 | }, 61 | }, 62 | } 63 | } 64 | 65 | type dataFunctionModel struct { 66 | Name types.String `tfsdk:"name"` 67 | Params types.List `tfsdk:"params"` 68 | Body types.List `tfsdk:"body"` 69 | Async types.Bool `tfsdk:"async"` 70 | 71 | ID types.String `tfsdk:"id"` 72 | Expression types.String `tfsdk:"expression"` 73 | Statement types.String `tfsdk:"statement"` 74 | } 75 | 76 | func (d *dataFunction) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 77 | d.handleRequest(ctx, &req.Config, &resp.State, &resp.Diagnostics) 78 | } 79 | 80 | func (d *dataFunction) handleRequest(ctx context.Context, g util.ModelGetter, s util.ModelSetter, diags *diag.Diagnostics) { 81 | util.HandleRequest( 82 | ctx, 83 | &dataFunctionModel{}, 84 | g, 85 | s, 86 | diags, 87 | func(m *dataFunctionModel) bool { 88 | c := new(strings.Builder) 89 | if !m.Async.IsNull() && m.Async.ValueBool() { 90 | c.WriteString("async ") 91 | } 92 | 93 | c.WriteString("function") 94 | if !m.Name.IsNull() { 95 | c.WriteString(" ") 96 | c.WriteString(util.RawString(m.Name)) 97 | } 98 | c.WriteString("(") 99 | 100 | if !m.Params.IsNull() { 101 | ps := make([]string, len(m.Params.Elements())) 102 | for i, p := range m.Params.Elements() { 103 | ps[i] = util.RawString(p.(types.String)) 104 | } 105 | c.WriteString(strings.Join(ps, ",")) 106 | } 107 | c.WriteString("){") 108 | c.WriteString(util.StringifyStatements(m.Body.Elements())) 109 | c.WriteString("}") 110 | 111 | m.ID = util.Raw(m.Name) 112 | m.Statement = util.Raw(types.StringValue(c.String())) 113 | m.Expression = m.Statement 114 | 115 | return true 116 | }, 117 | ) 118 | } 119 | -------------------------------------------------------------------------------- /internal/datasources/function_call.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/hashicorp/terraform-plugin-framework/attr" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource" 10 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 11 | "github.com/hashicorp/terraform-plugin-framework/diag" 12 | "github.com/hashicorp/terraform-plugin-framework/types" 13 | "github.com/hashicorp/terraform-plugin-framework/types/basetypes" 14 | "github.com/koki-develop/terraform-provider-js/internal/util" 15 | ) 16 | 17 | var ( 18 | _ datasource.DataSource = &dataFunctionCall{} 19 | ) 20 | 21 | func NewDataFunctionCall() func() datasource.DataSource { 22 | return func() datasource.DataSource { 23 | return &dataFunctionCall{} 24 | } 25 | } 26 | 27 | type dataFunctionCall struct{} 28 | 29 | func (d *dataFunctionCall) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 30 | resp.TypeName = req.ProviderTypeName + "_function_call" 31 | } 32 | 33 | func (d *dataFunctionCall) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 34 | resp.Schema = schema.Schema{ 35 | Attributes: map[string]schema.Attribute{ 36 | "caller": schema.StringAttribute{ 37 | Description: "Function caller.", 38 | Optional: true, 39 | }, 40 | "function": schema.StringAttribute{ 41 | Description: "Name of function to call.", 42 | Required: true, 43 | }, 44 | "args": schema.DynamicAttribute{ 45 | Description: "Arguments to pass to function.", 46 | Optional: true, 47 | }, 48 | 49 | "expression": schema.StringAttribute{ 50 | Computed: true, 51 | }, 52 | "statement": schema.StringAttribute{ 53 | Computed: true, 54 | }, 55 | }, 56 | } 57 | } 58 | 59 | type dataFunctionCallModel struct { 60 | Caller types.String `tfsdk:"caller"` 61 | Function types.String `tfsdk:"function"` 62 | Args types.Dynamic `tfsdk:"args"` 63 | 64 | Expression types.String `tfsdk:"expression"` 65 | Statement types.String `tfsdk:"statement"` 66 | } 67 | 68 | func (d *dataFunctionCall) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 69 | d.handleRequest(ctx, &req.Config, &resp.State, &resp.Diagnostics) 70 | } 71 | 72 | func (d *dataFunctionCall) handleRequest(ctx context.Context, g util.ModelGetter, s util.ModelSetter, diags *diag.Diagnostics) { 73 | util.HandleRequest( 74 | ctx, 75 | &dataFunctionCallModel{}, 76 | g, 77 | s, 78 | diags, 79 | func(m *dataFunctionCallModel) bool { 80 | c := new(strings.Builder) 81 | 82 | c.WriteString("(") 83 | if !m.Caller.IsNull() { 84 | c.WriteString(fmt.Sprintf("%s.", util.RawString(m.Caller))) 85 | } 86 | c.WriteString(util.RawString(m.Function)) 87 | c.WriteString(")") 88 | 89 | c.WriteString("(") 90 | 91 | if !m.Args.IsNull() { 92 | var elms []attr.Value 93 | switch v := m.Args.UnderlyingValue().(type) { 94 | case basetypes.ListValue: 95 | elms = v.Elements() 96 | case basetypes.TupleValue: 97 | elms = v.Elements() 98 | case basetypes.SetValue: 99 | elms = v.Elements() 100 | default: 101 | diags.AddError("Invalid type of args", "args must be a list, tuple or set") 102 | return false 103 | } 104 | 105 | args := util.StringifyValues(elms) 106 | c.WriteString(strings.Join(args, ",")) 107 | } 108 | 109 | c.WriteString(")") 110 | 111 | m.Expression = util.Raw(types.StringValue(c.String())) 112 | m.Statement = m.Expression 113 | return true 114 | }, 115 | ) 116 | } 117 | -------------------------------------------------------------------------------- /internal/datasources/function_param.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/hashicorp/terraform-plugin-framework/datasource" 7 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 8 | "github.com/hashicorp/terraform-plugin-framework/types" 9 | "github.com/koki-develop/terraform-provider-js/internal/util" 10 | ) 11 | 12 | var ( 13 | _ datasource.DataSource = &dataFunctionParam{} 14 | ) 15 | 16 | func NewDataFunctionParam() func() datasource.DataSource { 17 | return func() datasource.DataSource { 18 | return &dataFunctionParam{} 19 | } 20 | } 21 | 22 | type dataFunctionParam struct{} 23 | 24 | func (d *dataFunctionParam) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 25 | resp.TypeName = req.ProviderTypeName + "_function_param" 26 | } 27 | 28 | func (d *dataFunctionParam) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 29 | resp.Schema = schema.Schema{ 30 | Attributes: map[string]schema.Attribute{ 31 | "name": schema.StringAttribute{ 32 | Description: "Name of parameter.", 33 | Required: true, 34 | }, 35 | 36 | "id": schema.StringAttribute{ 37 | Computed: true, 38 | }, 39 | "expression": schema.StringAttribute{ 40 | Computed: true, 41 | }, 42 | }, 43 | } 44 | } 45 | 46 | type dataFunctionParamModel struct { 47 | Name types.String `tfsdk:"name"` 48 | 49 | ID types.String `tfsdk:"id"` 50 | Expression types.String `tfsdk:"expression"` 51 | } 52 | 53 | func (d *dataFunctionParam) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 54 | util.HandleRequest( 55 | ctx, 56 | &dataFunctionParamModel{}, 57 | &req.Config, 58 | &resp.State, 59 | &resp.Diagnostics, 60 | func(m *dataFunctionParamModel) bool { 61 | m.ID = util.Raw(m.Name) 62 | m.Expression = m.ID 63 | return true 64 | }, 65 | ) 66 | } 67 | -------------------------------------------------------------------------------- /internal/datasources/if.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataIf{} 15 | ) 16 | 17 | func NewDataIf() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataIf{} 20 | } 21 | } 22 | 23 | type dataIf struct{} 24 | 25 | func (d *dataIf) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_if" 27 | } 28 | 29 | func (d *dataIf) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "condition": schema.StringAttribute{ 33 | Description: "An expression that is considered to be either truthy or falsy.", 34 | Required: true, 35 | }, 36 | "then": schema.ListAttribute{ 37 | Description: "Statements that are executed if condition is truthy.", 38 | ElementType: types.StringType, 39 | Optional: true, 40 | }, 41 | "else": schema.ListAttribute{ 42 | Description: "Statements that are executed if condition is falsy.", 43 | ElementType: types.StringType, 44 | Optional: true, 45 | }, 46 | 47 | "statement": schema.StringAttribute{ 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | type dataIfModel struct { 55 | Condition types.String `tfsdk:"condition"` 56 | Then types.List `tfsdk:"then"` 57 | Else types.List `tfsdk:"else"` 58 | 59 | Statement types.String `tfsdk:"statement"` 60 | } 61 | 62 | func (d *dataIf) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 63 | util.HandleRequest( 64 | ctx, 65 | &dataIfModel{}, 66 | &req.Config, 67 | &resp.State, 68 | &resp.Diagnostics, 69 | func(m *dataIfModel) bool { 70 | c := new(strings.Builder) 71 | c.WriteString("if(") 72 | c.WriteString(util.StringifyValue(m.Condition)) 73 | c.WriteString("){") 74 | if !m.Then.IsNull() { 75 | c.WriteString(util.StringifyStatements(m.Then.Elements())) 76 | } 77 | c.WriteString("}") 78 | if !m.Else.IsNull() { 79 | c.WriteString("else{") 80 | c.WriteString(util.StringifyStatements(m.Else.Elements())) 81 | c.WriteString("}") 82 | } 83 | 84 | m.Statement = util.Raw(types.StringValue(c.String())) 85 | return true 86 | }, 87 | ) 88 | } 89 | -------------------------------------------------------------------------------- /internal/datasources/import.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 10 | "github.com/hashicorp/terraform-plugin-framework/types" 11 | "github.com/koki-develop/terraform-provider-js/internal/util" 12 | ) 13 | 14 | func NewDataImport() func() datasource.DataSource { 15 | return func() datasource.DataSource { 16 | return &dataImport{} 17 | } 18 | } 19 | 20 | type dataImport struct{} 21 | 22 | func (d *dataImport) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 23 | resp.TypeName = req.ProviderTypeName + "_import" 24 | } 25 | 26 | func (d *dataImport) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 27 | resp.Schema = schema.Schema{ 28 | Attributes: map[string]schema.Attribute{ 29 | "from": schema.StringAttribute{ 30 | Description: "The module to import from.", 31 | Required: true, 32 | }, 33 | "as": schema.StringAttribute{ 34 | Description: "Name of the module object that will be used as a kind of namespace when referring to the imports.", 35 | Required: true, 36 | }, 37 | "default": schema.BoolAttribute{ 38 | Description: "Whether the import is default.", 39 | Optional: true, 40 | }, 41 | 42 | "id": schema.StringAttribute{ 43 | Computed: true, 44 | }, 45 | "statement": schema.StringAttribute{ 46 | Computed: true, 47 | }, 48 | }, 49 | } 50 | } 51 | 52 | type dataImportModel struct { 53 | From types.String `tfsdk:"from"` 54 | As types.String `tfsdk:"as"` 55 | Default types.Bool `tfsdk:"default"` 56 | 57 | ID types.String `tfsdk:"id"` 58 | Statement types.String `tfsdk:"statement"` 59 | } 60 | 61 | func (d *dataImport) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 62 | util.HandleRequest( 63 | ctx, 64 | &dataImportModel{}, 65 | &req.Config, 66 | &resp.State, 67 | &resp.Diagnostics, 68 | func(m *dataImportModel) bool { 69 | c := new(strings.Builder) 70 | c.WriteString("import ") 71 | 72 | if m.Default.IsNull() || !m.Default.ValueBool() { 73 | c.WriteString("* as ") 74 | } 75 | c.WriteString(util.RawString(m.As)) 76 | 77 | c.WriteString(fmt.Sprintf(" from %q", util.RawString(m.From))) 78 | 79 | m.ID = util.Raw(m.As) 80 | m.Statement = util.Raw(types.StringValue(c.String())) 81 | return true 82 | }, 83 | ) 84 | } 85 | -------------------------------------------------------------------------------- /internal/datasources/increment.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 10 | "github.com/hashicorp/terraform-plugin-framework/schema/validator" 11 | "github.com/hashicorp/terraform-plugin-framework/types" 12 | "github.com/koki-develop/terraform-provider-js/internal/util" 13 | ) 14 | 15 | var ( 16 | _ datasource.DataSource = &dataIncrement{} 17 | ) 18 | 19 | func NewDataIncrement() func() datasource.DataSource { 20 | return func() datasource.DataSource { 21 | return &dataIncrement{} 22 | } 23 | } 24 | 25 | type dataIncrement struct{} 26 | 27 | func (d *dataIncrement) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 28 | resp.TypeName = req.ProviderTypeName + "_increment" 29 | } 30 | 31 | func (d *dataIncrement) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 32 | resp.Schema = schema.Schema{ 33 | Attributes: map[string]schema.Attribute{ 34 | "ref": schema.StringAttribute{ 35 | Description: "Reference to increment.", 36 | Required: true, 37 | }, 38 | "type": schema.StringAttribute{ 39 | Description: "Type of increment to perform. (Valid values: `prefix`, `postfix`)", 40 | Optional: true, 41 | Validators: []validator.String{ 42 | stringvalidator.OneOf("prefix", "postfix"), 43 | }, 44 | }, 45 | 46 | "expression": schema.StringAttribute{ 47 | Computed: true, 48 | }, 49 | "statement": schema.StringAttribute{ 50 | Computed: true, 51 | }, 52 | }, 53 | } 54 | } 55 | 56 | type dataIncrementModel struct { 57 | Ref types.String `tfsdk:"ref"` 58 | Type types.String `tfsdk:"type"` 59 | 60 | Expression types.String `tfsdk:"expression"` 61 | Statement types.String `tfsdk:"statement"` 62 | } 63 | 64 | func (d *dataIncrement) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 65 | util.HandleRequest( 66 | ctx, 67 | &dataIncrementModel{}, 68 | &req.Config, 69 | &resp.State, 70 | &resp.Diagnostics, 71 | func(m *dataIncrementModel) bool { 72 | c := new(strings.Builder) 73 | tp := m.Type.ValueString() 74 | 75 | if tp == "prefix" { 76 | c.WriteString("++") 77 | } 78 | c.WriteString(util.RawString(m.Ref)) 79 | if m.Type.IsNull() || tp == "postfix" { 80 | c.WriteString("++") 81 | } 82 | 83 | m.Expression = util.Raw(types.StringValue(c.String())) 84 | m.Statement = m.Expression 85 | return true 86 | }, 87 | ) 88 | } 89 | -------------------------------------------------------------------------------- /internal/datasources/index.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = (*dataIndex)(nil) 15 | ) 16 | 17 | type dataIndex struct{} 18 | 19 | func NewDataIndex() func() datasource.DataSource { 20 | return func() datasource.DataSource { 21 | return &dataIndex{} 22 | } 23 | } 24 | 25 | func (d *dataIndex) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_index" 27 | } 28 | 29 | func (d *dataIndex) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "ref": schema.StringAttribute{ 33 | Required: true, 34 | Description: "Referenced JavaScript object.", 35 | }, 36 | "value": schema.DynamicAttribute{ 37 | Required: true, 38 | Description: "Index or property name within referenced object.", 39 | }, 40 | 41 | "id": schema.StringAttribute{ 42 | Computed: true, 43 | }, 44 | "expression": schema.StringAttribute{ 45 | Computed: true, 46 | }, 47 | "statement": schema.StringAttribute{ 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | type dataIndexModel struct { 55 | Ref types.String `tfsdk:"ref"` 56 | Value types.Dynamic `tfsdk:"value"` 57 | 58 | ID types.String `tfsdk:"id"` 59 | Expression types.String `tfsdk:"expression"` 60 | Statement types.String `tfsdk:"statement"` 61 | } 62 | 63 | func (d *dataIndex) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 64 | util.HandleRequest( 65 | ctx, 66 | &dataIndexModel{}, 67 | &req.Config, 68 | &resp.State, 69 | &resp.Diagnostics, 70 | func(m *dataIndexModel) bool { 71 | c := new(strings.Builder) 72 | c.WriteString(util.RawString(m.Ref)) 73 | c.WriteRune('[') 74 | c.WriteString(util.StringifyValue(m.Value)) 75 | c.WriteRune(']') 76 | 77 | m.ID = util.Raw(types.StringValue(c.String())) 78 | m.Expression = m.ID 79 | m.Statement = m.ID 80 | 81 | return true 82 | }, 83 | ) 84 | } 85 | -------------------------------------------------------------------------------- /internal/datasources/let.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataLet{} 15 | ) 16 | 17 | func NewDataLet() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataLet{} 20 | } 21 | } 22 | 23 | type dataLet struct{} 24 | 25 | func (d *dataLet) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_let" 27 | } 28 | 29 | func (d *dataLet) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "name": schema.StringAttribute{ 33 | Description: "Name of variable to declare.", 34 | Required: true, 35 | }, 36 | "value": schema.DynamicAttribute{ 37 | Description: "Initial value of the variable.", 38 | Optional: true, 39 | }, 40 | 41 | "id": schema.StringAttribute{ 42 | Computed: true, 43 | }, 44 | "expression": schema.StringAttribute{ 45 | Computed: true, 46 | }, 47 | "statement": schema.StringAttribute{ 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | type dataLetModel struct { 55 | Name types.String `tfsdk:"name"` 56 | Value types.Dynamic `tfsdk:"value"` 57 | 58 | ID types.String `tfsdk:"id"` 59 | Expression types.String `tfsdk:"expression"` 60 | Statement types.String `tfsdk:"statement"` 61 | } 62 | 63 | func (d *dataLet) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 64 | util.HandleRequest( 65 | ctx, 66 | &dataLetModel{}, 67 | &req.Config, 68 | &resp.State, 69 | &resp.Diagnostics, 70 | func(m *dataLetModel) bool { 71 | m.ID = util.Raw(m.Name) 72 | m.Expression = m.ID 73 | 74 | c := new(strings.Builder) 75 | c.WriteString("let ") 76 | c.WriteString(util.RawString(m.Name)) 77 | if !m.Value.IsNull() { 78 | c.WriteString("=") 79 | c.WriteString(util.StringifyValue(m.Value)) 80 | } 81 | 82 | m.Statement = util.Raw(types.StringValue(c.String())) 83 | return true 84 | }, 85 | ) 86 | } 87 | -------------------------------------------------------------------------------- /internal/datasources/new.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/attr" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 10 | "github.com/hashicorp/terraform-plugin-framework/types" 11 | "github.com/hashicorp/terraform-plugin-framework/types/basetypes" 12 | "github.com/koki-develop/terraform-provider-js/internal/util" 13 | ) 14 | 15 | var ( 16 | _ datasource.DataSource = &dataNew{} 17 | ) 18 | 19 | func NewDataNew() func() datasource.DataSource { 20 | return func() datasource.DataSource { 21 | return &dataNew{} 22 | } 23 | } 24 | 25 | type dataNew struct{} 26 | 27 | func (d *dataNew) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 28 | resp.TypeName = req.ProviderTypeName + "_new" 29 | } 30 | 31 | func (d *dataNew) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 32 | resp.Schema = schema.Schema{ 33 | Attributes: map[string]schema.Attribute{ 34 | "constructor": schema.StringAttribute{ 35 | Description: "A class or function that specifies the type of the object instance.", 36 | Required: true, 37 | }, 38 | "args": schema.DynamicAttribute{ 39 | Description: "A list of values that the constructor will be called with.", 40 | Optional: true, 41 | }, 42 | 43 | "expression": schema.StringAttribute{ 44 | Computed: true, 45 | }, 46 | "statement": schema.StringAttribute{ 47 | Computed: true, 48 | }, 49 | }, 50 | } 51 | } 52 | 53 | type dataNewModel struct { 54 | Constructor types.String `tfsdk:"constructor"` 55 | Args types.Dynamic `tfsdk:"args"` 56 | 57 | Expression types.String `tfsdk:"expression"` 58 | Statement types.String `tfsdk:"statement"` 59 | } 60 | 61 | func (d *dataNew) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 62 | util.HandleRequest( 63 | ctx, 64 | &dataNewModel{}, 65 | &req.Config, 66 | &resp.State, 67 | &resp.Diagnostics, 68 | func(m *dataNewModel) bool { 69 | c := new(strings.Builder) 70 | 71 | c.WriteString("new ") 72 | c.WriteString(util.RawString(m.Constructor)) 73 | 74 | c.WriteString("(") 75 | 76 | if !m.Args.IsNull() { 77 | var elms []attr.Value 78 | switch v := m.Args.UnderlyingValue().(type) { 79 | case basetypes.ListValue: 80 | elms = v.Elements() 81 | case basetypes.TupleValue: 82 | elms = v.Elements() 83 | case basetypes.SetValue: 84 | elms = v.Elements() 85 | default: 86 | resp.Diagnostics.AddError("Invalid type of args", "args must be a list, tuple or set") 87 | return false 88 | } 89 | 90 | args := util.StringifyValues(elms) 91 | c.WriteString(strings.Join(args, ",")) 92 | } 93 | 94 | c.WriteString(")") 95 | 96 | m.Expression = util.Raw(types.StringValue(c.String())) 97 | m.Statement = m.Expression 98 | return true 99 | }, 100 | ) 101 | } 102 | -------------------------------------------------------------------------------- /internal/datasources/operation.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataOperation{} 15 | ) 16 | 17 | func NewDataOperation() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataOperation{} 20 | } 21 | } 22 | 23 | type dataOperation struct{} 24 | 25 | func (d *dataOperation) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_operation" 27 | } 28 | 29 | func (d *dataOperation) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "operator": schema.StringAttribute{ 33 | Description: "Operator to use in operation.", 34 | Required: true, 35 | }, 36 | "left": schema.DynamicAttribute{ 37 | Description: "Left operand.", 38 | Required: true, 39 | }, 40 | "right": schema.DynamicAttribute{ 41 | Description: "Right operand.", 42 | Required: true, 43 | }, 44 | 45 | "expression": schema.StringAttribute{ 46 | Computed: true, 47 | }, 48 | "statement": schema.StringAttribute{ 49 | Computed: true, 50 | }, 51 | }, 52 | } 53 | } 54 | 55 | type dataOperationModel struct { 56 | Operator types.String `tfsdk:"operator"` 57 | Left types.Dynamic `tfsdk:"left"` 58 | Right types.Dynamic `tfsdk:"right"` 59 | 60 | Expression types.String `tfsdk:"expression"` 61 | Statement types.String `tfsdk:"statement"` 62 | } 63 | 64 | func (d *dataOperation) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 65 | util.HandleRequest( 66 | ctx, 67 | &dataOperationModel{}, 68 | &req.Config, 69 | &resp.State, 70 | &resp.Diagnostics, 71 | func(m *dataOperationModel) bool { 72 | c := new(strings.Builder) 73 | c.WriteString("(") 74 | c.WriteString(util.StringifyValue(m.Left)) 75 | c.WriteString(util.RawString(m.Operator)) 76 | c.WriteString(util.StringifyValue(m.Right)) 77 | c.WriteString(")") 78 | 79 | m.Expression = util.Raw(types.StringValue(c.String())) 80 | m.Statement = m.Expression 81 | return true 82 | }, 83 | ) 84 | } 85 | -------------------------------------------------------------------------------- /internal/datasources/program.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/hashicorp/terraform-plugin-framework/datasource" 9 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 10 | "github.com/hashicorp/terraform-plugin-framework/types" 11 | "github.com/koki-develop/terraform-provider-js/internal/util" 12 | "github.com/tdewolff/minify/v2" 13 | "github.com/tdewolff/minify/v2/js" 14 | ) 15 | 16 | var ( 17 | _ datasource.DataSource = &dataProgram{} 18 | ) 19 | 20 | func NewDataProgram(version string) func() datasource.DataSource { 21 | return func() datasource.DataSource { 22 | m := minify.New() 23 | m.AddFunc("js", js.Minify) 24 | return &dataProgram{ProviderVersion: version, Minifier: m} 25 | } 26 | } 27 | 28 | type dataProgram struct { 29 | ProviderVersion string 30 | Minifier *minify.M 31 | } 32 | 33 | func (d *dataProgram) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 34 | resp.TypeName = req.ProviderTypeName + "_program" 35 | } 36 | 37 | func (d *dataProgram) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 38 | resp.Schema = schema.Schema{ 39 | Attributes: map[string]schema.Attribute{ 40 | "statements": schema.ListAttribute{ 41 | Description: "Statements that are executed in the program.", 42 | ElementType: types.StringType, 43 | Required: true, 44 | }, 45 | 46 | "content": schema.StringAttribute{ 47 | Computed: true, 48 | }, 49 | }, 50 | } 51 | } 52 | 53 | type dataProgramModel struct { 54 | Statements types.List `tfsdk:"statements"` 55 | 56 | Content types.String `tfsdk:"content"` 57 | } 58 | 59 | func (d *dataProgram) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 60 | util.HandleRequest( 61 | ctx, 62 | &dataProgramModel{}, 63 | &req.Config, 64 | &resp.State, 65 | &resp.Diagnostics, 66 | func(m *dataProgramModel) bool { 67 | header := fmt.Sprintf("// Code generated by JS.tf v%[1]s (https://registry.terraform.io/providers/koki-develop/js/%[1]s)", d.ProviderVersion) 68 | 69 | s := new(strings.Builder) 70 | s.WriteString(util.StringifyStatements(m.Statements.Elements())) 71 | content, err := d.Minifier.String("js", s.String()) 72 | if err != nil { 73 | resp.Diagnostics.AddError("Failed to minify JavaScript", err.Error()) 74 | return false 75 | } 76 | m.Content = types.StringValue(fmt.Sprintf("%s\n%s", header, content)) 77 | return true 78 | }, 79 | ) 80 | } 81 | -------------------------------------------------------------------------------- /internal/datasources/raw.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/hashicorp/terraform-plugin-framework/datasource" 7 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 8 | "github.com/hashicorp/terraform-plugin-framework/types" 9 | "github.com/koki-develop/terraform-provider-js/internal/util" 10 | ) 11 | 12 | var ( 13 | _ datasource.DataSource = (*dataRaw)(nil) 14 | ) 15 | 16 | type dataRaw struct{} 17 | 18 | func NewDataRaw() func() datasource.DataSource { 19 | return func() datasource.DataSource { 20 | return &dataRaw{} 21 | } 22 | } 23 | 24 | func (d *dataRaw) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 25 | resp.TypeName = req.ProviderTypeName + "_raw" 26 | } 27 | 28 | func (d *dataRaw) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 29 | resp.Schema = schema.Schema{ 30 | Attributes: map[string]schema.Attribute{ 31 | "value": schema.StringAttribute{ 32 | Description: "Raw JavaScript code.", 33 | Required: true, 34 | }, 35 | 36 | "content": schema.StringAttribute{ 37 | Computed: true, 38 | }, 39 | }, 40 | } 41 | } 42 | 43 | type dataRawModel struct { 44 | Value types.String `tfsdk:"value"` 45 | 46 | Content types.String `tfsdk:"content"` 47 | } 48 | 49 | func (d *dataRaw) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 50 | util.HandleRequest( 51 | ctx, 52 | &dataRawModel{}, 53 | &req.Config, 54 | &resp.State, 55 | &resp.Diagnostics, 56 | func(m *dataRawModel) bool { 57 | m.Content = util.Raw(m.Value) 58 | return true 59 | }, 60 | ) 61 | } 62 | -------------------------------------------------------------------------------- /internal/datasources/return.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataReturn{} 15 | ) 16 | 17 | func NewDataReturn() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataReturn{} 20 | } 21 | } 22 | 23 | type dataReturn struct{} 24 | 25 | func (d *dataReturn) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_return" 27 | } 28 | 29 | func (d *dataReturn) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "value": schema.DynamicAttribute{ 33 | Description: "Expression whose value is to be returned.", 34 | Optional: true, 35 | }, 36 | 37 | "statement": schema.StringAttribute{ 38 | Computed: true, 39 | }, 40 | }, 41 | } 42 | } 43 | 44 | type dataReturnModel struct { 45 | Value types.Dynamic `tfsdk:"value"` 46 | 47 | Statement types.String `tfsdk:"statement"` 48 | } 49 | 50 | func (d *dataReturn) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 51 | util.HandleRequest( 52 | ctx, 53 | &dataReturnModel{}, 54 | &req.Config, 55 | &resp.State, 56 | &resp.Diagnostics, 57 | func(m *dataReturnModel) bool { 58 | c := new(strings.Builder) 59 | c.WriteString("return") 60 | if !m.Value.IsNull() { 61 | c.WriteString(" ") 62 | c.WriteString(util.StringifyValue(m.Value)) 63 | } 64 | 65 | m.Statement = util.Raw(types.StringValue(c.String())) 66 | return true 67 | }, 68 | ) 69 | } 70 | -------------------------------------------------------------------------------- /internal/datasources/throw.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataThrow{} 15 | ) 16 | 17 | func NewDataThrow() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataThrow{} 20 | } 21 | } 22 | 23 | type dataThrow struct{} 24 | 25 | func (d *dataThrow) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_throw" 27 | } 28 | 29 | func (d *dataThrow) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "value": schema.StringAttribute{ 33 | Description: "Expression to throw.", 34 | Required: true, 35 | }, 36 | 37 | "statement": schema.StringAttribute{ 38 | Computed: true, 39 | }, 40 | }, 41 | } 42 | } 43 | 44 | type dataThrowModel struct { 45 | Value types.String `tfsdk:"value"` 46 | 47 | Statement types.String `tfsdk:"statement"` 48 | } 49 | 50 | func (d *dataThrow) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 51 | util.HandleRequest( 52 | ctx, 53 | &dataThrowModel{}, 54 | &req.Config, 55 | &resp.State, 56 | &resp.Diagnostics, 57 | func(m *dataThrowModel) bool { 58 | m.Statement = util.Raw(types.StringValue(fmt.Sprintf("throw %s", util.StringifyValue(m.Value)))) 59 | return true 60 | }, 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /internal/datasources/var.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataVar{} 15 | ) 16 | 17 | func NewDataVar() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataVar{} 20 | } 21 | } 22 | 23 | type dataVar struct{} 24 | 25 | func (d *dataVar) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_var" 27 | } 28 | 29 | func (d *dataVar) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "name": schema.StringAttribute{ 33 | Description: "Name of variable to declare.", 34 | Required: true, 35 | }, 36 | "value": schema.DynamicAttribute{ 37 | Description: "Initial value of variable.", 38 | Optional: true, 39 | }, 40 | 41 | "id": schema.StringAttribute{ 42 | Computed: true, 43 | }, 44 | "expression": schema.StringAttribute{ 45 | Computed: true, 46 | }, 47 | "statement": schema.StringAttribute{ 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | type dataVarModel struct { 55 | Name types.String `tfsdk:"name"` 56 | Value types.Dynamic `tfsdk:"value"` 57 | 58 | ID types.String `tfsdk:"id"` 59 | Expression types.String `tfsdk:"expression"` 60 | Statement types.String `tfsdk:"statement"` 61 | } 62 | 63 | func (d *dataVar) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 64 | util.HandleRequest( 65 | ctx, 66 | &dataVarModel{}, 67 | &req.Config, 68 | &resp.State, 69 | &resp.Diagnostics, 70 | func(m *dataVarModel) bool { 71 | m.ID = util.Raw(m.Name) 72 | m.Expression = m.ID 73 | c := new(strings.Builder) 74 | c.WriteString("var ") 75 | c.WriteString(util.RawString(m.Name)) 76 | if !m.Value.IsNull() { 77 | c.WriteString("=") 78 | c.WriteString(util.StringifyValue(m.Value)) 79 | } 80 | 81 | m.Statement = util.Raw(types.StringValue(c.String())) 82 | return true 83 | }, 84 | ) 85 | } 86 | -------------------------------------------------------------------------------- /internal/datasources/while.go: -------------------------------------------------------------------------------- 1 | package datasources 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | 7 | "github.com/hashicorp/terraform-plugin-framework/datasource" 8 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/koki-develop/terraform-provider-js/internal/util" 11 | ) 12 | 13 | var ( 14 | _ datasource.DataSource = &dataWhile{} 15 | ) 16 | 17 | func NewDataWhile() func() datasource.DataSource { 18 | return func() datasource.DataSource { 19 | return &dataWhile{} 20 | } 21 | } 22 | 23 | type dataWhile struct{} 24 | 25 | func (d *dataWhile) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 26 | resp.TypeName = req.ProviderTypeName + "_while" 27 | } 28 | 29 | func (d *dataWhile) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { 30 | resp.Schema = schema.Schema{ 31 | Attributes: map[string]schema.Attribute{ 32 | "condition": schema.StringAttribute{ 33 | Description: "An expression evaluated before each pass through the loop.", 34 | Required: true, 35 | }, 36 | "body": schema.ListAttribute{ 37 | Description: "Statements that are executed as long as the condition evaluates to true.", 38 | ElementType: types.StringType, 39 | Optional: true, 40 | }, 41 | 42 | "statement": schema.StringAttribute{ 43 | Computed: true, 44 | }, 45 | }, 46 | } 47 | } 48 | 49 | type dataWhileModel struct { 50 | Condition types.String `tfsdk:"condition"` 51 | Body types.List `tfsdk:"body"` 52 | 53 | Statement types.String `tfsdk:"statement"` 54 | } 55 | 56 | func (d *dataWhile) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 57 | util.HandleRequest( 58 | ctx, 59 | &dataWhileModel{}, 60 | &req.Config, 61 | &resp.State, 62 | &resp.Diagnostics, 63 | func(m *dataWhileModel) bool { 64 | c := new(strings.Builder) 65 | c.WriteString("while(") 66 | c.WriteString(util.StringifyValue(m.Condition)) 67 | c.WriteString("){") 68 | if !m.Body.IsNull() { 69 | c.WriteString(util.StringifyStatements(m.Body.Elements())) 70 | } 71 | c.WriteString("}") 72 | 73 | m.Statement = util.Raw(types.StringValue(c.String())) 74 | return true 75 | }, 76 | ) 77 | } 78 | -------------------------------------------------------------------------------- /internal/provider/provider.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/hashicorp/terraform-plugin-framework/datasource" 7 | "github.com/hashicorp/terraform-plugin-framework/provider" 8 | "github.com/hashicorp/terraform-plugin-framework/provider/schema" 9 | "github.com/hashicorp/terraform-plugin-framework/resource" 10 | "github.com/koki-develop/terraform-provider-js/internal/datasources" 11 | ) 12 | 13 | var ( 14 | _ provider.Provider = (*jsProvider)(nil) 15 | ) 16 | 17 | type jsProvider struct { 18 | version string 19 | } 20 | 21 | func New(version string) func() provider.Provider { 22 | return func() provider.Provider { 23 | return &jsProvider{ 24 | version: version, 25 | } 26 | } 27 | } 28 | 29 | func (p *jsProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) { 30 | resp.TypeName = "js" 31 | resp.Version = p.version 32 | } 33 | 34 | func (p *jsProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) { 35 | resp.Schema = schema.Schema{ 36 | Description: "The Next Generation AltJS.", 37 | } 38 | } 39 | 40 | func (p *jsProvider) Configure(_ context.Context, _ provider.ConfigureRequest, _ *provider.ConfigureResponse) { 41 | } 42 | 43 | func (p *jsProvider) DataSources(_ context.Context) []func() datasource.DataSource { 44 | return []func() datasource.DataSource{ 45 | datasources.NewDataAwait(), 46 | datasources.NewDataConditionalOperation(), 47 | datasources.NewDataConst(), 48 | datasources.NewDataDecrement(), 49 | datasources.NewDataExport(), 50 | datasources.NewDataFor(), 51 | datasources.NewDataFunction(), 52 | datasources.NewDataFunctionCall(), 53 | datasources.NewDataFunctionParam(), 54 | datasources.NewDataIf(), 55 | datasources.NewDataImport(), 56 | datasources.NewDataIncrement(), 57 | datasources.NewDataIndex(), 58 | datasources.NewDataLet(), 59 | datasources.NewDataNew(), 60 | datasources.NewDataOperation(), 61 | datasources.NewDataProgram(p.version), 62 | datasources.NewDataRaw(), 63 | datasources.NewDataReturn(), 64 | datasources.NewDataThrow(), 65 | datasources.NewDataVar(), 66 | datasources.NewDataWhile(), 67 | } 68 | } 69 | 70 | func (p *jsProvider) Resources(_ context.Context) []func() resource.Resource { 71 | return []func() resource.Resource{} 72 | } 73 | -------------------------------------------------------------------------------- /internal/util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sort" 7 | "strings" 8 | 9 | "github.com/hashicorp/terraform-plugin-framework/attr" 10 | "github.com/hashicorp/terraform-plugin-framework/diag" 11 | "github.com/hashicorp/terraform-plugin-framework/types" 12 | "github.com/hashicorp/terraform-plugin-framework/types/basetypes" 13 | ) 14 | 15 | const prefix = "@js/" 16 | const RawPrefix = prefix + "raw:" 17 | 18 | // Raw returns the value with the raw prefix. 19 | // e.g. "foo" -> "@js/raw:foo" 20 | func Raw(v basetypes.StringValue) basetypes.StringValue { 21 | if v.IsNull() || v.IsUnknown() { 22 | return v 23 | } 24 | if hasRawPrefix(v) { 25 | return v 26 | } 27 | 28 | return types.StringValue(RawPrefix + v.ValueString()) 29 | } 30 | 31 | // RawString returns the string value without the raw prefix. 32 | // e.g. "@js/raw:foo" -> "foo" 33 | func RawString(v basetypes.StringValue) string { 34 | return strings.TrimPrefix(v.ValueString(), RawPrefix) 35 | } 36 | 37 | func hasRawPrefix(v basetypes.StringValue) bool { 38 | return strings.HasPrefix(v.ValueString(), RawPrefix) 39 | } 40 | 41 | func StringifyValue(v attr.Value) string { 42 | if v.IsNull() { 43 | return "null" 44 | } 45 | 46 | switch v := v.(type) { 47 | case basetypes.StringValue: 48 | if hasRawPrefix(v) { 49 | return RawString(v) 50 | } 51 | case basetypes.ListValue, basetypes.TupleValue, basetypes.SetValue: 52 | var elms []attr.Value 53 | if v, ok := v.(basetypes.ListValue); ok { 54 | elms = v.Elements() 55 | } 56 | if v, ok := v.(basetypes.TupleValue); ok { 57 | elms = v.Elements() 58 | } 59 | if v, ok := v.(basetypes.SetValue); ok { 60 | elms = v.Elements() 61 | } 62 | return "[" + strings.Join(StringifyValues(elms), ",") + "]" 63 | case basetypes.ObjectValue, basetypes.MapValue: 64 | var elms map[string]attr.Value 65 | if v, ok := v.(basetypes.ObjectValue); ok { 66 | elms = v.Attributes() 67 | } 68 | if v, ok := v.(basetypes.MapValue); ok { 69 | elms = v.Elements() 70 | } 71 | 72 | c := new(strings.Builder) 73 | c.WriteString("{") 74 | first := true 75 | for _, k := range SortedKeys(elms) { 76 | v := elms[k] 77 | if first { 78 | first = false 79 | } else { 80 | c.WriteString(",") 81 | } 82 | c.WriteString(fmt.Sprintf("%q", k)) 83 | c.WriteString(":") 84 | c.WriteString(StringifyValue(v)) 85 | } 86 | 87 | c.WriteString("}") 88 | return c.String() 89 | case basetypes.DynamicValue: 90 | return StringifyValue(v.UnderlyingValue()) 91 | } 92 | 93 | return v.String() 94 | } 95 | 96 | func StringifyValues(vs []attr.Value) []string { 97 | strs := make([]string, len(vs)) 98 | for i, v := range vs { 99 | strs[i] = StringifyValue(v) 100 | } 101 | 102 | return strs 103 | } 104 | 105 | func StringifyStatements(vs []attr.Value) string { 106 | c := new(strings.Builder) 107 | 108 | for i, v := range vs { 109 | if i > 0 { 110 | ch := c.String()[c.Len()-1:] 111 | if ch != ";" { 112 | c.WriteString(";") 113 | } 114 | } 115 | c.WriteString(StringifyValue(v)) 116 | } 117 | 118 | return c.String() 119 | } 120 | 121 | type ModelGetter interface { 122 | Get(ctx context.Context, target any) diag.Diagnostics 123 | } 124 | 125 | type ModelSetter interface { 126 | Set(ctx context.Context, val any) diag.Diagnostics 127 | } 128 | 129 | func HandleRequest[T any](ctx context.Context, model T, g ModelGetter, s ModelSetter, diags *diag.Diagnostics, h func(m T) bool) { 130 | diags.Append(g.Get(ctx, model)...) 131 | if diags.HasError() { 132 | return 133 | } 134 | 135 | if !h(model) { 136 | return 137 | } 138 | 139 | diags.Append(s.Set(ctx, model)...) 140 | if diags.HasError() { 141 | return 142 | } 143 | } 144 | 145 | func SortedKeys(m map[string]attr.Value) []string { 146 | keys := make([]string, 0, len(m)) 147 | for k := range m { 148 | keys = append(keys, k) 149 | } 150 | 151 | sort.SliceStable(keys, func(i, j int) bool { 152 | return keys[i] < keys[j] 153 | }) 154 | return keys 155 | } 156 | -------------------------------------------------------------------------------- /internal/util/util_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "testing" 7 | 8 | "github.com/hashicorp/terraform-plugin-framework/attr" 9 | "github.com/hashicorp/terraform-plugin-framework/types" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func Test_StringifyValue(t *testing.T) { 14 | tests := []struct { 15 | v attr.Value 16 | json bool 17 | want string 18 | }{ 19 | // raw 20 | {v: types.StringValue("@js/raw:foo"), want: "foo"}, 21 | {v: types.StringValue("@js/raw:1"), want: "1"}, 22 | {v: types.StringValue("@js/raw:true"), want: "true"}, 23 | {v: types.StringValue("@js/raw:[1,2,3]"), want: "[1,2,3]"}, 24 | {v: types.StringValue(`@js/raw:{"a":1}`), want: `{"a":1}`}, 25 | {v: types.StringValue("@js/raw:null"), want: "null"}, 26 | 27 | // string 28 | {v: types.StringValue("foo"), want: `"foo"`}, 29 | {v: types.StringValue(""), want: `""`}, 30 | {v: types.StringNull(), want: "null"}, 31 | {v: types.DynamicValue(types.StringValue("foo")), want: `"foo"`}, 32 | 33 | // number 34 | {v: types.NumberValue(big.NewFloat(1)), want: "1"}, 35 | {v: types.NumberValue(big.NewFloat(0)), want: "0"}, 36 | {v: types.NumberNull(), want: "null"}, 37 | {v: types.DynamicValue(types.NumberValue(big.NewFloat(1))), want: "1"}, 38 | 39 | // bool 40 | {v: types.BoolValue(true), want: "true"}, 41 | {v: types.BoolValue(false), want: "false"}, 42 | {v: types.BoolNull(), want: "null"}, 43 | {v: types.DynamicValue(types.BoolValue(true)), want: "true"}, 44 | 45 | // list 46 | { 47 | v: types.ListValueMust(types.StringType, []attr.Value{ 48 | types.StringValue("@js/raw:\"baz\""), 49 | types.StringValue("foo"), 50 | types.StringValue("bar"), 51 | }), 52 | want: `["baz","foo","bar"]`, 53 | }, 54 | { 55 | v: types.ListValueMust(types.NumberType, []attr.Value{types.NumberValue(big.NewFloat(1)), types.NumberValue(big.NewFloat(2))}), 56 | want: `[1,2]`, 57 | }, 58 | 59 | // tuple 60 | { 61 | v: types.TupleValueMust( 62 | []attr.Type{ 63 | types.StringType, 64 | types.StringType, 65 | types.NumberType, 66 | types.BoolType, 67 | types.TupleType{ElemTypes: []attr.Type{types.NumberType, types.NumberType}}, 68 | }, 69 | []attr.Value{ 70 | types.StringValue("@js/raw:\"bar\""), 71 | types.StringValue("foo"), 72 | types.NumberValue(big.NewFloat(1)), 73 | types.BoolValue(true), 74 | types.TupleValueMust([]attr.Type{types.NumberType, types.NumberType}, []attr.Value{types.NumberValue(big.NewFloat(1)), types.NumberValue(big.NewFloat(2))}), 75 | }, 76 | ), 77 | want: `["bar","foo",1,true,[1,2]]`, 78 | }, 79 | 80 | // object 81 | { 82 | json: true, 83 | v: types.ObjectValueMust( 84 | map[string]attr.Type{ 85 | "raw": types.StringType, 86 | "string": types.StringType, 87 | "number": types.NumberType, 88 | "bool": types.BoolType, 89 | "tuple": types.TupleType{ElemTypes: []attr.Type{types.NumberType, types.NumberType}}, 90 | "object": types.ObjectType{ 91 | AttrTypes: map[string]attr.Type{ 92 | "string": types.StringType, 93 | }, 94 | }, 95 | }, 96 | map[string]attr.Value{ 97 | "raw": types.StringValue("@js/raw:\"bar\""), 98 | "string": types.StringValue("foo"), 99 | "number": types.NumberValue(big.NewFloat(1)), 100 | "bool": types.BoolValue(true), 101 | "tuple": types.TupleValueMust([]attr.Type{types.NumberType, types.NumberType}, []attr.Value{types.NumberValue(big.NewFloat(1)), types.NumberValue(big.NewFloat(2))}), 102 | "object": types.ObjectValueMust( 103 | map[string]attr.Type{ 104 | "string": types.StringType, 105 | }, 106 | map[string]attr.Value{ 107 | "string": types.StringValue("foo"), 108 | }, 109 | ), 110 | }, 111 | ), 112 | want: `{"raw":"bar","string":"foo","number":1,"bool":true,"tuple":[1,2],"object":{"string":"foo"}}`, 113 | }, 114 | {v: types.ObjectNull(map[string]attr.Type{}), want: "null"}, 115 | 116 | // map 117 | { 118 | json: true, 119 | v: types.MapValueMust( 120 | types.StringType, 121 | map[string]attr.Value{ 122 | "raw": types.StringValue("@js/raw:\"baz\""), 123 | "foo": types.StringValue("bar"), 124 | "baz": types.StringValue("qux"), 125 | }, 126 | ), 127 | want: `{"raw":"baz","foo":"bar","baz":"qux"}`, 128 | }, 129 | {v: types.MapNull(types.StringType), want: "null"}, 130 | 131 | // other 132 | {v: types.DynamicNull(), want: "null"}, 133 | } 134 | 135 | for i, tt := range tests { 136 | t.Run(fmt.Sprint(i), func(t *testing.T) { 137 | got := StringifyValue(tt.v) 138 | if tt.json { 139 | assert.JSONEq(t, tt.want, got) 140 | } else { 141 | assert.Equal(t, tt.want, got) 142 | } 143 | }) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs 2 | 3 | package main 4 | 5 | import ( 6 | "context" 7 | "flag" 8 | "log" 9 | 10 | "github.com/hashicorp/terraform-plugin-framework/providerserver" 11 | "github.com/koki-develop/terraform-provider-js/internal/provider" 12 | ) 13 | 14 | var ( 15 | version string = "dev" 16 | ) 17 | 18 | func main() { 19 | var debug bool 20 | 21 | flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") 22 | flag.Parse() 23 | 24 | opts := providerserver.ServeOpts{ 25 | Address: "registry.terraform.io/koki-develop/js", 26 | Debug: debug, 27 | } 28 | 29 | if err := providerserver.Serve(context.Background(), provider.New(version), opts); err != nil { 30 | log.Fatal(err.Error()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["6.0"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package tools 4 | 5 | import ( 6 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 7 | ) 8 | --------------------------------------------------------------------------------